-! lib1funcs.S for picoJava.
-! Copyright (C) 2000, 2001 Free Software Foundation, Inc.
-!
-! This file is free software; you can redistribute it and/or modify it
-! under the terms of the GNU General Public License as published by the
-! Free Software Foundation; either version 2, or (at your option) any
-! later version.
-!
-! In addition to the permissions in the GNU General Public License, the
-! Free Software Foundation gives you unlimited permission to link the
-! compiled version of this file into combinations with other programs,
-! and to distribute those combinations without any restriction coming
-! from the use of this file. (The General Public License restrictions
-! do apply in other respects; for example, they cover modification of
-! the file, and distribution when not linked into a combine
-! executable.)
-!
-! This file is distributed in the hope that it will be useful, but
-! WITHOUT ANY WARRANTY; without even the implied warranty of
-! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-! General Public License for more details.
-!
-! You should have received a copy of the GNU General Public License
-! along with this program; see the file COPYING. If not, write to
-! the Free Software Foundation, 59 Temple Place - Suite 330,
-! Boston, MA 02111-1307, USA.
-!
-
-
-#ifdef Lvhelper
-
-! The vhelper copies unnamed args in a varargs function from the
-! opstack onto the aggregate stack. It is a bit tricky since the
-! opstack does not exist in real memory, so can not have its address taken,
-! and since the opstack is being played with, there is nowhere to stick
-! the temporaries.
-
- .globl __vhelper
-__vhelper:
-
-
-! incoming
-! vars-> named0
-! named1
-! ...
-! unnamed0
-! unnamed1
-! ...
-! pc
-! vars
-! #named
-! return pc
-
- ! work out total size everything below the named args and
- ! allocate that space on the aggregate stack + 3 extra words
- ! for some temps.
- ! g0 = old g0
- ! g0+4 = vars
- ! g0+8 = pc
- ! g0+12 = last unnamed arg
- ! ....
-
- write_global1
- write_global2
-
- ! tos = #named args provided by callee.
-
- ! move down the aggstack to make room for all the unnamed args
- ! and the 12 bytes of extra stuff we have to pay attention to.
- ! g0 = old_g0 - ((vars - optop) + named_bytes + 12) - stuff we just pushed
-
- ! build new global0
- read_global0
- read_vars
- read_optop
- isub ! tos = vars - optop (# bytes in all args)
- bipush 4
- isub ! subtract out fudge for current stuff on stack.
- read_global2
- isub ! subtract out # words named.
- isub
-
- dup
- dup
- ! store old global0 in new global0 spot.
-
- read_global0
- swap
- store_word
-
- ! store new global0 value into global0
- write_global0
-
- ! work out address to stop copying, which is vars - #named args bytes
- ! but since we will have pushed stuff onto the stack when the comparison
- ! is made, adjust by the fudge factor.
- read_vars
- read_global2
- bipush 12
- iadd
- isub
-
- ! optop= finish, vars, pc, ...
- ! now pop off args from the opstack and copy to aggstack till all done.
- ! during the loop the opstack looks like
- ! (optop_finish_addr) (destination_addr) (named_n) (named_n-1) ....
- ! each iteration pops off one more element.
-
-
-again:
- dup_x2
- read_optop
- if_icmpeq done
- iconst_4
- iadd
- dup_x2
- store_word
- goto again
-
-done:
- dup2_x1 ; pop2 ; pop !leave pointer on top.
-
- ! return to caller with varargs pointer as
- ! the next argument and the restoring global0 as the next.
-
- read_global0 ; load_word
-
- ! restore returning pc and vars
- read_global0 ; bipush 8; iadd; load_word
- read_global0 ; bipush 4; iadd; load_word
-
- ! return to caller.
- read_global1
- write_pc
-#endif
-
-
-#ifdef __LITTLE_ENDIAN__
-#define AL iload_1
-#define AH iload_0
-#define BL iload_3
-#define BH iload_2
-#else
-#define AL iload_0
-#define AH iload_1
-#define BL iload_2
-#define BH iload_3
-#endif
-#ifdef Lpjucmpdi2
-
-! like ucmpdi2, but returns <0,0,>0 depending on comparison input.
-! and returns answer on the stack, not in global1. - much like an
-! actual lucmp instruction would do if there was one.
-! big little
-!
-! vars-> 0 a low high
-! 1 a high low
-! 2 b low high
-! 3 b high low
-!
-! compares a to b
-! a > b return 1
-! a = b return 0
-! a < b return -1
-
- .globl __pjucmpdi2
-__pjucmpdi2:
-
-! first see if we can compare the numbers using
-! the signed instruction.
-
- AH
- BH
- if_icmpne high_words_diff
- AL
- BL
- iucmp
- return1
-
-! and low word if high word is equal.
-
-high_words_diff:
- AH
- BH
- iucmp
- return1
-#endif