blob: 02390bc5740a2cb20d0a7684130743bb493f5369 [file] [log] [blame]
! 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