The JIT Icode Insn Set (200K HTML)
Samuel Sanseri
sanseri at cs.pdx.edu
Mon Jan 3 11:26:54 PST 2000
Hello,
On the Kaffe website, particularly in relation to porting Kaffe to new
architectures, it states "that documentation would be welcome here."
I am working with my advisor on porting the Kaffe JIT to IA-64 and have
written a tabular summary of the icode instruction set in order to help
myself understand the workings of Kaffe. This document is chapter 1,
called "The JIT icode instruction set" and is attached in HTML format.
As we proceed in development, further chapters will likely be written and
posted to this list. Any comments or corrections to this document will be
useful to us in our development, and thus appreciated.
For best reading of this document, you will require a large screen, with
your browser stretched to maximum width. This document can also be found
at my homepage at http://www.cs.pdx.edu/~sanseri
To read this file, save it to your local drive and delete all lines
preceding the html tag.
Regards,
Samuel Sanseri
Computer Science Graduate Research Assistant
Portland State University
sanseri at cs.pdx.edu
=====================================================================
delete all lines before&including this one and read this file w/a browser
<html>
<head>
<title>Porting Kaffe to a New Architecture</title>
<a name="Top"></a>
<h1 align="center">Porting Kaffe to a New Architecture</h1>
<h2 align="center">Chapter 1: The Kaffe JIT icode Instruction Set</h2>
<p align="center">Copyright(c) 1999, Samuel K. Sanseri --
<a href="mailto:sanseri at cs.pdx.edu">sanseri at cs.pdx.edu</a>
</p>
</head>
<body>
<a href="#Intro">Introduction</a><br>
<a href="#Register loads and spills">Register loads and spills</a><br>
<a href="#Prologues and epilogues">Prologues and epilogues</a><br>
<a href="#Conditional monitor management">Conditional monitor management</a><br>
<a href="#Moves">Moves</a><br>
<a href="#Arithmetic">Arithmetic ops</a><br>
<a href="#Logical">Logical ops</a><br>
<a href="#Load and store">Load and store</a><br>
<a href="#Function argument management">Function argument management</a><br>
<a href="#Control flow changes">Control flow changes</a><br>
<a href="#Labels">Labels</a><br>
<a href="#Comparisons">Comparisons</a><br>
<a href="#Conversions">Conversions</a><br>
<a href="#Breakpoints">Breakpoints</a><br>
<a href="#Build call frame">Build call frame</a><br>
<a href="#Soft calls">Soft calls</a><br>
<a href="#BB and instruction management">BB and instruction management</a><br>
<a href="#Appendix A">Appendix A -- Important Kaffe JIT files and funcs</a>
<p><h3 align="center">
<a name="Intro">Introduction</a></h3>
<p>
Abstract: The Kaffe just-in-time compiler (call it the JIT for short)
uses one level of intermediate code between the Java bytecode and machine
code. This intermediate code is called icode. Having intermediate
instruction set allows software reuse when porting existing compiler code
to a new arch, which results in more rapid and cost-effective
code development. Prior to using the icode instruction set in a port to a
new arch, it is essential that the software engineer have a basic
understanding of how the icode works. This document attempts to accelerate
the acquisition of that understanding by describing the requirements for
porting the Kaffe JIT icode intermediate instruction set to a new arch.
<p>
Introduction: A JIT compiler typically compiles a procedure at a time as it
sees them, using a method called a trampoline. The 1st time a procedure
is called in the bytecode, the trampoline requests the method to be
translated into native code and cached; subsequent times, the trampoline
updates the dispatch table so the program can jump directly to the previously
translated native code (see soft.c).
<p>
Kaffe currently does not perform any global (i.e. whole-func)
optimizations; all optimizations are local per BB. Kaffe loads
all virtual regs when entering a BB and spills all regs
when leaving. When the translator is invoked, it generates and stores the
instruction sequence for the start of the method, then it generates
instruction sequences for each BB of bytecode instructions. Each
bytecode instruction is translated into icode instructions and result is
stored (see machine.c). These icode instructions are described in Table 1.
Ideally the icode instructions will not require any modification in the new
arch (see icode.c). The arch-specific modifications will be
placed in files in the arch-specific config directory
(e.g.kaffe/config/ia64/jit-ia64.def and kaffe/config/ia64/jit-icode.h).
<p>
The table below is organized as follows. The first column (icode insn) gives
the name of the Kaffe icode instruction in icode.c. All information in icode.c
is machine-independent. The argument types and names to this icode instruction
are found in the second column. The third column gives a short description and
algorithm for the machine-independent implementation of the icode instruction.
Often this icode instruction will then make a function call to the
machine-dependent portion of the instruction. The name of this function is
found in the fourth column called func name; sometimes this function will have
different names depending on the architecture; this usually reflects that port
of kaffe being written at a different time, but sometimes it reveals actual
differences between architectures. The fifth column gives the arguments to
this function and in which seq slots they are found. The sixth column gives an
algorithm (or requirement description) for the machine-dependent function, and
the last column tells whether the machine-dependent function is required for
some or all ports of Kaffe. This table requires a big screen with the
browser window stretched to maximum width.
<p>
[<a href="#Top">Index</a>]
[<a href="#Top">Prev</a>]
[<a href="#Intro">This</a>]
[<a href="#Table 1">Next</a>]
<p>
<h2 align="center">
<a name="Table 1">Table 1 -- The Kaffe JIT icode Instruction Set</a>
</h2>
<em>Instructions are listed in the order given in jit3/icode.c.</em>
This table is based on the Kaffe pre-release version 1.0b4.
<p>
[<a href="#Top">Index</a>]
[<a href="#Intro">Prev</a>]
[<a href="#Register loads and spills">Next</a>]
<p><h3 align="center">
<a name="Register loads and spills">Register loads and spills.</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd</tr>
</thead>
<tbody>
<tr>
<td valign="top"><tt>spill int
<td valign="top"><tt>SlotData *src
<td valign="top">spill int reg into its assigned frame loc
<pre>sslot0=src
sslot1=offset of src slot in current frame</pre>
<td valign="top"><tt>spill Rxx (i386), spilli RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store val(r)->mem(frame[o])</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>reload int
<td valign="top"><tt>SlotData *dst
<td valign="top">reload int reg from given frame loc
<pre>sslot0=dst
sslot1=abs offset of dst slot in current frame</pre>
<td valign="top"><tt>reload Rxx (i386), reloadi RCx (alpha)
<td valign="top"><tt>SlotData *dst (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>convert sslot0 into reg r,
spilling and loading as necessary
get stack frame offset o from sslot1
emit load reg(r)<-val(mem(frame[o]))</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>spill ref
<td valign="top"><tt>SlotData *src
<td valign="top">spill obj ref into assigned frame loc
<pre>sslot0=src
sslot1=offset of src slot in current frame</pre>
<td valign="top"><tt>spill Rxx (i386), spillr RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store val(r)->mem(frame[o])</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>reload ref
<td valign="top"><tt>SlotData *dst
<td valign="top">reload ref reg from given frame loc
<pre>sslot0=dst
sslot1=abs offset of dst slot in current frame</pre>
<td valign="top"><tt>reload Rxx (i386), reloadr RCx (alpha)
<td valign="top"><tt>SlotData *dst (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>convert sslot0 into reg r,
spilling and loading as necessary
get stack frame offset o from sslot1
emit load reg(r)<-val(mem(frame[o]))</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>spill long
<td valign="top"><tt>SlotData* src
<td valign="top">spill long reg into assigned frame loc
<pre>sslot0=src
sslot1=offset of src slot in current frame</pre>
<td valign="top"><tt>spilll RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store long val(r)->mem(frame[o])</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>reload long
<td valign="top"><tt>SlotData *dst
<td valign="top">reload ref reg from given frame loc
<pre>sslot0=dst
sslot1=abs offset of dst slot in current frame</pre>
<td valign="top"><tt>reloadl RCx (alpha)
<td valign="top"><tt>SlotData *dst (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>convert sslot0 into reg r,
spilling and loading as necessary
get stack frame offset o from sslot1
emit load reg(r)<-long val(mem(frame[o]))</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>spill float
<td valign="top"><tt>SlotData *src
<td valign="top">spill float reg into assigned frame loc
<pre>sslot0=src
sslot1=offset of src slot in current frame</pre>
<td valign="top"><tt>fspill Rxx (i386), spillf RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store float val(r)->mem(frame[o])</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>reload float
<td valign="top"><tt>SlotData *dst
<td valign="top">reload float reg from given frame loc
<pre>sslot0=dst
sslot1=abs offset of dst slot in current frame</pre>
<td valign="top"><tt>freload Rxx (i386), reloadf RCx (alpha)
<td valign="top"><tt>SlotData *dst (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>convert sslot0 into reg r,
spilling and loading as necessary
get stack frame offset o from sslot1
emit load reg(r)<-float val(mem(frame[o]))</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>spill double
<td valign="top"><tt>SlotData *src
<td valign="top">spill double-precision reg into assigned frame loc
<pre>sslot0=src
sslot1=offset of src slot in current frame</pre>
<td valign="top"><tt>fspilll Rxx (i386), spilld RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store double val(r)->mem(frame[o])</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>reload double
<td valign="top"><tt>SlotData *dst
<td valign="top">reload double-precision reg into assigned frame loc
<pre>sslot0=dst
sslot1=abs offset of dst slot in current frame</pre>
<td valign="top"><tt>freloadl Rxx (i386), reloadd RCx (alpha)
<td valign="top"><tt>SlotData *src (sslot0), int offset (sslot1)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get stack frame offset o from sslot1
emit store double val(r)->mem(frame[o])</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Table 1">Prev</a>]
[<a href="#Prologues and epilogues">Next</a>]
<p><h3 align="center">
<a name="Prologues and epilogues">Prologues and epilogues</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>prologue
<td valign="top"><tt>Method *meth
<td valign="top">func prologue
<pre>create new label at current pc
set up slots for a new BB
set up global regs
set up argument regs
emit prologue code
reload some regs</pre>
<td valign="top"><tt>prologue xxx (i386), prologue xxC (alpha), prologue xLC (sparc)
<td valign="top"><tt>label *l (sslot1--i386,alpha), Method *meth (sslot2--alpha)
<td valign="top"><tt>
<pre>(this method is highly arch-dependent)
calculate frame size
save frame or stack ptr
alloc stack space for current method
save callee-save regs
set up regs for arch-specific calling convention</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>check stack limit
<td valign="top">none
<td valign="top">check for a stack overflow
<pre>pass ptr to stack overflow
exception routine to func</pre>
<td valign="top"><tt>check stack limit xRC
<td valign="top"><tt>SlotInfo *stack limit (sslot1), label *l (sslot2) ptr to exception routine
<td valign="top"><tt>
<pre>invoke exception routine if stack overflow detected
compare stack ptr with stack limit
if stack ptr beyond stack limit, invoke exception routine
(setting up something for some later code to take over?)
note: stack limit code was recent addition.</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>exception prologue
<td valign="top">none
<td valign="top">set up exception handling block
<pre>create new label at current pc
pass the label to eprologue xLx
reload spilled regs after
exception call returns</pre>
<td valign="top"><tt>eprologue xLx
<td valign="top"><tt>label *l (sslot1)
<td valign="top"><tt>
<pre>this seems to do slightly less work than prologue()
calc framesize and leave room for backpatch
modify stack ptr to alloc framesize for exception call
(this code is called by start exception block()
which 1st starts a basic block,
then calls the exception prologue,
and finally returns a ref to the exception obj.
See machine.c).</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>epilogue
<td valign="top"><tt>Method *meth
<td valign="top">func epilogue
<pre>create new label at current pc
(where is this label used?)
(for quick return or
to calc size of func?)
call the epilogue xxx func</pre>
<td valign="top"><tt>epilogue xxx
<td valign="top"><tt>label *l (sslot1)
<td valign="top"><tt>
<pre>restore callee-save regs & stack ptr
(also frame ptr and return jump reg,
if arch requires it)</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Register loads and spills">Prev</a>]
[<a href="#Prologues and epilogues">This</a>]
[<a href="#Conditional monitor management">Next</a>]
<p><h3 align="center">
<a name="Conditional monitor management">Conditional monitor management</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>mon enter
<td valign="top"><tt>methods *meth, SlotInfo *obj
<td valign="top">conditional monitor entry
(for synchronized classes/methods)
<pre>if method is not synchronized, don't monitor
begin func synchronization
(perform necessary spills and
mark writes if exceptions can occur)
create new label l pointing to slowLockobj
if method is static
monitor the class
else
monitor the obj
call monenter xxRCC func
end func synchronization
(spill and reloads necessary)</pre>
<td valign="top"><tt>monenter xxRCC (i386)
<td valign="top"><tt>SlotInfo *obj (sslot2) ptr to obj being monitored,
methods *meth(sslot3) ptr to obj's method being synchronized,
label *l (sslot4) ptr to softLockobj label
<td valign="top"><tt>
<pre>handle conditional monitor entry
(the i386 pseudo-code looks wrong)
spill a couple of work regs
for reloading after completion
if meth==0
do compare-and-swap on 2nd word
(semaphore) in obj
save some regs
do long call to softLockobj label l
(actual loc will be backpatched later)
increment stack ptr?
else
do compare-and-swap on method's class
save some regs
do long call to softLockobj label l after
increment stack ptr?
endif</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>mon exit
<td valign="top"><tt>methods* meth, SlotInfo* obj
<td valign="top">conditional monitor exit (for synchronized classes/methods)
<pre>if method is not synchronized, don't monitor
begin func synchronization
(perform necessary spills and
mark writes if exceptions can occur)
create new label l pointing to slowUnlockobj
if method is static
monitor the class,
else
monitor the obj
call monexit xxRCC
end func synchronization
(spill and reloads necessary)</pre>
<td valign="top"><tt>monexit xxRCC (i386)
<td valign="top"><tt>SlotInfo *obj (sslot2) ptr to obj being monitored,
methods *meth(sslot3) ptr to obj's method being synchronized,
label *l (sslot4) ptr to softLockobj label
<td valign="top"><tt>
<pre>handle conditional monitor exit
spill a couple of work regs
for reloading after completion
if meth==0
do compare-and-swap on 2nd word
(semaphore) in obj
save some regs
do long call to softUnlockobj label l
increment stack ptr?
else
do compare-and-swap on method's class
save some regs
do long call to softUnlockobj label l
increment stack ptr?
endif</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>softcall monitorenter
<td valign="top"><tt>SlotInfo *mon
<td valign="top">software call to monitor entry (only one in at a time)
<pre>create new label l pointing to slowLockobj
call monenter xxRCC</pre>
<td valign="top"><tt>monenter xxRCC (i386)
<td valign="top"><tt>SlotInfo *mon (sslot2), label *l (sslot4)
<td valign="top"><tt>
<pre>spill a couple of work regs
for reloading after completion
do compare-and-swap on the 2nd word
(semaphore) in mon
save some regs
do long call to softLockobj label l
(actual loc will be backpatched later)
increment stack ptr?</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>softcall monitorexit
<td valign="top"><tt>SlotInfo *mon
<td valign="top">software call to monitor exit (only one in at a time)
<pre>create new label l pointing to slowUnlockobj
call monexit xxRCC</pre>
<td valign="top"><tt>monexit xxRCC (i386)
<td valign="top"><tt>SlotInfo *mon (sslot2), label *l (sslot4)
<td valign="top"><tt>
<pre>spill a couple of work regs
for reloading after completion
do a compare-and-swap on the 2nd word
(semaphore) in mon
save some regs
do long call to softUnlockobj label l
(actual loc will be backpatched later)
increment stack ptr?</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Prologues and epilogues">Prev</a>]
[<a href="#Conditional monitor management">This</a>]
[<a href="#Moves">Next</a>]
<p><h3 align="center">
<a name="Moves">Moves</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>move int const
<td valign="top"><tt>SlotInfo *dst, jint val
<td valign="top">move int const into given slot
<pre>if int const is in range for simple move
(all 6 arch define this trivally true)
move int directly to slot using move RxC
else
add int const to const pool
load int from const pool into the slot
endif</pre>
<td valign="top"><tt>move RxC (i386), movei RxC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), jint val (sslot2)
<td valign="top"><tt>
<pre>get val from sslot2
get dst from sslot0 into reg w,
spilling that reg if necessary
(if val==0)
can do optimization here using xor
emit move val into reg w</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move ref const
<td valign="top"><tt>SlotInfo *dst, void *val
<td valign="top">move ptr to an obj into given slot
<pre>if ref const is in range for move
(all but mips define this trivially true)
move ref directly to slot using move RxC
else
add ref const to const pool
load ref from const pool into slot
endif</pre>
<td valign="top"><tt>move RxC (i386), mover RxC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *val (sslot2)
<td valign="top"><tt>
<pre>get val from sslot2
get dst from sslot0 into reg w,
spilling that reg if necessary
if val==0
can possibly optimize using xor
emit move val into reg w
if val is too big,
may need to use const pool & load
(see alpha code)</pre>
<td valign="top">yes (but not implemented yet in mips)
<tr>
<td valign="top"><tt>move string const
<td valign="top"><tt>SlotInfo *dst, void *val
<td valign="top">same as move ref const
<td valign="top"><tt>move RxC (i386), mover RxC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *val (sslot2)
<td valign="top"><tt><pre>same as move RxC</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move long const
<td valign="top"><tt>SlotInfo *dst (occupies 2 slots), jlong val
<td valign="top">move long const into slot pair
<pre>if movel RxC defined
if move long const rangecheck(val)
call movel RxC(dst, val)
else
alloc a new long in const pool
load long dst from const pool
endif
else
move int const of low 32-bits to LSLOT(dst)
move int const of high 32-bits to HSLOT(dst)
endif</pre>
<td valign="top"><tt>movel RxC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), jlong val (sslot2)
<td valign="top"><tt>
<pre>(compilation of this func requires C compiler
which supports right shift on a 64-bit datatype or
obj-oriented C++code which handles this specially)
(only implemented for alpha which has 64-bit regs)
get val from sslot2
get dst from sslot0 into reg w,
spilling if necessary
if val is small enough to fit into an insn
move it directly
else
copy long const into const pool
emit insn to load it into reg w
endif</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>move float const
<td valign="top"><tt>SlotInfo *dst, float val
<td valign="top">move float const into slot
<pre>if movef RxC (or similar) func defined and
val is in range
(i386 code only supports 0.0 and
1.0 directly w/o using const pool)
call movef RxC (or similar) func
else
put float const in const pool
load float const from const pool to dst slot
endif</pre>
<td valign="top"><tt>movef RxC (alpha), fmove RxC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), float val (sslot2)
<td valign="top"><tt>
<pre>(if val is 0.0 or 1.0,
there may be an optimization here)
put the float const in const pool
load the float const from const pool to dst slot
(alpha uses double here--
are all alphfloats doubles?)
(some argument widening going on)</pre>
<td valign="top">yes, but not implemented in all
<tr>
<td valign="top"><tt>move double const
<td valign="top"><tt>SlotInfo *dst, jdouble val
<td valign="top">move double const into slot pair
<pre>if moved RxC (or similar) func defined and
val is in range
(i386 code only supports 0.0 and
1.0 directly w/o using const pool)
call moved RxC (or similar) func
else
put double const in const pool
load double const from const pool
to dst slot pair
endif</pre>
<td valign="top"><tt>moved RxC (alpha), fmovel RxC (i386)
<td valign="top"><tt>SlotInfo *dst, jdouble val
<td valign="top"><tt>
<pre>(if val is 0.0 or 1.0,
there may be an optimization here)
put double const in const pool
load double const from const pool to dst slot pair</pre>
<td valign="top">yes, but not implemented in all
<tr>
<td valign="top"><tt>move any
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">move the data from one slot to another (32-bit types only)
<pre>if dst==src
do nothing
else if dst is a global slot
(i.e. used outside this BB)
call mover RxR (or similar func)
else
alias dst slot's reg to ref src's reg
(this part I don't understand)
endif</pre>
<td valign="top"><tt>mover RxR (alpha), move RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc reg to it for read
get dst from sslot0 and
alloc reg to it for write
if src!=dst
emit move val from src to dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy int from one slot to another
<pre>if dst==src
do nothing
else if src is a const slot
call move int const (dst, src val)
else if dst is a global slot
(i.e. used outside this BB)
call movei RxR (or similar func)
else
alias dst slot's reg to ref src's reg
(this part I don't understand)
endif</pre>
<td valign="top"><tt>movei RxR (alpha), move RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc reg to it for read
get dst from sslot0 and
alloc reg to it for write
if src!=dst
emit move val from src to dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy a ref from one slot to another
<pre>if dst==src
do nothing
else if src is a const slot
call move ref const (dst, src val)
else if dst is a global slot
(i.e. used outside this BB)
call mover RxR (or similar func)
else
alias dst slot's reg to ref src's reg
(this part I don't understand)
endif</pre>
<td valign="top"><tt>mover RxR (alpha), move RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc reg to it for read
get dst from sslot0 and
alloc reg to it for write
if src!=dst
emit move val from src to dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move anylong
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy long from one slot to another
<pre>if movel RxR defined
movel RxR(dst,src)
else
move any(LSLOT(dst), LSLOT(src));
move any(HSLOT(dst), HSLOT(src));
endif</pre>
<td valign="top"><tt>movel RxR (not implemented in any arch)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc long reg to it for read
get dst from sslot0 and
alloc long reg to it for write
if src!=dst
emit move val from src to dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>move long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy long from one slot to another
<pre>if movel RxR defined
movel RxR(dst,src)
else
move any(LSLOT(dst), LSLOT(src));
move any(HSLOT(dst), HSLOT(src));
endif</pre>
<td valign="top"><tt>movel RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc long reg to it for read
get dst from sslot0 and
alloc long reg to it for write
if src!=dst
emit move val from src to dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>move float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy float from one slot to another
<pre>call movef RxR or fmove RxR</pre>
<td valign="top"><tt>movef RxR (alpha), fmove RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc float reg to it for read
get dst from sslot0 and
alloc float reg to it for write
if src!=dst
emit copy val from src reg to dst reg
(i386 code is different because
i386 has only one float reg,
so it must copy data from reg to stack)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">copy double from one slot to another
<pre>call moved RxR or fmovel RxR</pre>
<td valign="top"><tt>moved RxR (alpha), fmovel RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 and
alloc double reg to it for read
get dst from sslot0 and
alloc double reg to it for write
if src!=dst
emit copy val from src reg to dst reg
(i386 code is different because
i386 has only one float reg,
so it must copy data from reg to stack)
(arch may require using consecutive
pair of float regs)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>move label const
<td valign="top"><tt>SlotInfo *dst, label *lab
<td valign="top">copy a label's address into a slot (backpatch needed)
<pre>call move RxL</pre>
<td valign="top"><tt>move RxL
<td valign="top"><tt>SlotInfo *dst (sslot0), label *l (sslot2)
<td valign="top"><tt>
<pre>get l from sslot2
alloc reg w for write
emit copy val of l to reg w (backpatching?)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>swap any
<td valign="top"><tt>SlotInfo *src, SlotInfo *src2
<td valign="top">swap vals of two slots
<pre>if swap RxR defined
swap RxR(src,src2)
else
alloc tmp slot tmp
copy src to tmp (ref type)
copy src2 to src
copy tmp to src
dealloc tmp
endif</pre>
<td valign="top"><tt>swap RxR (m68)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src2 into reg r2 (of the correct type)
for read & write
get src into reg r1 (of the correct type)
for read & write
emit exchange the vals</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Conditional monitor management">Prev</a>]
[<a href="#Moves">This</a>]
[<a href="#Arithmetic">Next</a>]
<p><h3 align="center">
<a name="Arithmetic">Arithmetic ops</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>adc int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=src+src2+Carry Flag
<pre>call adc RRR</pre>
<td valign="top"><tt>adc RRR (i386), adci RRR (m68k)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>must be defined if icode insn defined
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
if only two operands are supported
assert dst==src
emit src+src2+Carry Flag
emit store result in dst</pre>
<td valign="top">not if long ops are defined
<tr>
<td valign="top"><tt>add int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=src+src2
<pre>if src and src2 are both consts
compute the sum at compile time
move int const(dst, sum)
else if src is a const
add int const(dst, src2, src)
else if src2 is a const
add int const(dst, src, src2)
else
add RRR(dst, src, src2)
endif</pre>
<td valign="top"><tt>addi RRR (alpha), add RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit add src+src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>add int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">dst=src+val
<pre>if add RRC exists and
val is in range for int addition
call add RRC
else
alloc tmp slot tmp
move int const from val to tmp
add RRR dst=src+tmp
dealloc tmp
endif</pre>
<td valign="top"><tt>addi RRC (alpha), add RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit add src+val
emit store result in dst</pre>
<td valign="top">optional (helps optimization)
<tr>
<td valign="top"><tt>add ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=src+src2 (unsigned addition)
<pre>call add RRR</pre>
<td valign="top"><tt>addr RRR (alpha), add RRR (i386), addu RRR (mips)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>must be defined if icode insn defined
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit add (unsigned) src+src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>add ref const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">dst=src+val (unsigned addition)
<pre>if add RRC exists and
val is in range for int addition
call add RRC
else
alloc tmp slot tmp
move int const from val to tmp
add RRR dst=src+tmp
dealloc tmp
endif</pre>
<td valign="top"><tt>addr RRC (alpha), add RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2 into reg for read
alloc reg for write to dst
emit add (unsigned) src+src2
emit store result in dst</pre>
<td valign="top">optional (helps optimization)
<tr>
<td valign="top"><tt>set lt int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">set dst=1 if src<src2 else set dst=0
<pre>call sltu RRR</pre>
<td valign="top"><tt>sltu RRR (mips)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>must be defined if icode insn defined
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit if src-src2<0
set dst=1 else set dst=0</pre>
<td valign="top">only if HAVE add long and HAVE adc int are not defined
<tr>
<td valign="top"><tt>set lt int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">set dst=1 if src<src2 else set dst=0
<pre>call sltu RRC</pre>
<td valign="top"><tt>sltu RRC (mips)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>must be defined if icode insn defined
(range check on const val?
mips doesn't--is this a pseudo-op?)
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit if src-val<0
set dst=1 else set dst=0</pre>
<td valign="top">optional (helps optimization)
<tr>
<td valign="top"><tt>add long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=src+src2 (long addition)
<pre>requires addl RRR or adc RRR or sltu RRR
if addl RRR defined
call addl RRR
else if adc RRR defined
call add RRR LSLOT(dst)=
LSLOT(src)+LSLOT(src2)
call adc RRR HSLOT(dst)=
HSLOT(src)+HSLOT(src2)
else if sltu RRR defined
(icode.c code appears
less efficient than this)
alloc temp slot carry
add RRR LSLOT(dst)=
LSLOT(src)+LSLOT(src2)
if LSLOT(dst)<LSLOT(src2)
sltu RRR carry=1 else carry=0
add RRR HSLOT(dst)=
HSLOT(src)+HSLOT(src2)
add RRR HSLOT(dst)=
HSLOT(dst)+carry
dealloc temp slot carry
else
abort
endif</pre>
<td valign="top"><tt>addl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>dst, src, and src2 are slot pairs
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit add long dst=src+src2</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>add long const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jlong val
<td valign="top">dst=src+val (long addition)
<pre>requires addl RRC and
HAVE add long const rangecheck
if addl RRC defined and
val in range for direct long addition
call addl RRC
else
alloc temp slot tmp
move long const tmp=val
add long dst=src+tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>addl RRC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jlong val
<td valign="top"><tt>
<pre>dst, src, and src2 are slot pairs
get src from sslot1 into long reg for read
get val from sslot2
(alpha gets int because its rangecheck
can only handle small ints)
alloc long reg for write to dst
emit add long dst=src+val
(add immediate val)</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>add float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">add two float vals dst=src+src2
<pre>requires addf RRR</pre>
<td valign="top"><tt>addf RRR (alpha), fadd RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc float reg for write to dst
emit add float dst=src+src2
(special handling needed
if only one float reg
or if ieee supported)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>add double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">add two double vals dst=src+src2
<pre>requires addd RRR</pre>
<td valign="top"><tt>addf RRR (alpha), faddl RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into double reg for read
(uses 2 slots)
get src2 from sslot2 into double reg for read
(uses 2 slots)
alloc double reg for write to dst
(uses 2 slots)
emit add double dst=src+src2
(special handling needed
if only one double reg
or if ieee supported)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>sbc int
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">subtract int with borrow dst=src-src2-borrow
<pre>requires sbc RRR
call sbc RRR</pre>
<td valign="top"><tt>sbc RRR (i386), not defined on alpha or mips
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>must be implemented
if sbc int icode insn defined
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit sub int dst=src-src2-carry flag
(carry flag contains result of previous sub)</pre>
<td valign="top">if long ops not defined
<tr>
<td valign="top"><tt>sub int const
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, jint val
<td valign="top">subtract int const from int val
<pre>if sub RRC exists and
val in range for int sub
call sub RRC
else
alloc tmp slot tmp
move int const from val to tmp
sub RRR dst=src-tmp
dealloc tmp
endif</pre>
<td valign="top"><tt>subi RRC (alpha), sub RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit sub src-val
emit store result in dst</pre>
<td valign="top">optional (helps optimization)
<tr>
<td valign="top"><tt>sub int
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">subtract int dst=src-src2
<pre>if sub RRC defined and
src2 is a const
sub RRC dst=src-src2
else
sub RRR (dst, src2, src)
endif</pre>
<td valign="top"><tt>subi RRR (alpha), sub RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>must be implemented
if sub int icode insn defined
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit sub int dst=src-src2</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>sub long
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">subtract long dst=src-src2 (each uses 2 slots)
<pre>requires subl RRR or sbc RRR or sltu RRR
if subl RRR defined
subl RRR
else if sbc RRR defined
sub LSLOT(dst)=
LSLOT(src)-LSLOT(src2)
sbc HSLOT(dst)=
HSLOT(src)-HSLOT(src2)
else if sltu RRR defined
alloc temp slot carry
if LSLOT(src)<LSLOT(src2)
sltu RRR carry=1 else carry=0
sub RRR carry=HSLOT(src)-carry
sub RRR HSLOT(dst)=
carry-HSLOT(src2)
sub RRR LSLOT(dst)=
LSLOT(src)-LSLOT(src2)
dealloc temp slot carry
else
abort
endif</pre>
<td valign="top"><tt>subl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into long reg for read
(uses 2 slots)
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit sub long dst=src-src2</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>sub long const
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, jlong val
<td valign="top">subtract long dst=src-val (each uses 2 slots)
<pre>requires subl RRC and sub long const rangecheck
if val in range for immediate sub
call subl RRC
else
alloc temp slot tmp
move long const tmp=val
sub long dst=src-tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>subl RRC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jlong val
<td valign="top"><tt>
<pre>dst, src, and src2 are slot pairs
get src from sslot1 into long reg for read
get val from sslot2
(alpha gets int because its rangecheck
can only handle small ints)
alloc long reg for write to dst
emit sub long dst=src-val
(sub immediate val)</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>sub float
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">subtract float dst=src-val
<pre>call subf RRR</pre>
<td valign="top"><tt>subf RRR (alpha), fsub RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc float reg for write to dst
emit sub float dst=src-src2</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>sub double
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">subtract double dst=src-val
<pre>call subf RRR</pre>
<td valign="top"><tt>subd RRR (alpha), fsubl RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into double reg for read
(uses 2 slots)
get src2 from sslot2 into double reg for read
alloc double reg for write to dst
emit sub double dst=src-src2</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>mul int const
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, jint val
<td valign="top">multiply int reg by a const dst=src*val
<pre>requires lshl int const
if mul is equivalent to simple left shift
lshl int const to perform equivalent mul
else if muli RRC defined and
const is in range
call muli RRC dst=src*val
else
alloc temp slot tmp
move int const tmp<-val
mul int dst=src*tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>muli RRC (alpha), mul RRC (i386)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit mul src*val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>mul int
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">multiply two int slots
<pre>requires lshl int const
if src2 is const and
simple left shift will be equivalent
lshl int const to perform equivalent mul
endif
if mul RRR defined
if mul RRC defined and
src or src2 is const
call mul RRC dst=src*src2
(immediate val)
else
call mul RRR dst=src*src2
endif
else
begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft mul func
pop args
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>muli RRR (alpha), mul RRR (i386)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>(possibly do arch-specific optimizations)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit mul src*src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>mul long
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">multiply two long slot pairs
<pre>if mull RRR defined
call mull RRR
else
begin func synchronization (spill)
push args src and src2 in arch-specific order,
handling ratio of sizeof long to sizeof int
call soft mull
pop args
end func synchronization (do reload)
return long dst
endif</pre>
<td valign="top"><tt>mull RRR (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(possibly do some arch-specific optimizations)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
(uses 2 slots)
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit mul src*src2
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>mul long const
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, jlong val
<td valign="top">multiply long by const long
<pre>requires mull RRC
if val in range for direct long mul
call mull RRC
else
alloc temp slot tmp
move long const tmp=val
mul long dst=src*tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>mull RRC (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>must be supported if mul long const defined
(possibly do some arch-specific optimizations)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit mul src*val
emit store result in dst</pre>
<td valign="top">optional 64-bit arch
<tr>
<td valign="top"><tt>mul float
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">multiply two floats
<pre>requires mulf RRR
call mulf RRR</pre>
<td valign="top"><tt>mulf RRR (alpha), fmul RRR (i386)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>must be implemented if mul float insn defined
get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc float reg for write to dst
emit mul float dst=src*src2
special handling is needed
if only one float reg
or if ieee supported</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>mul double
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">multiply two doubles
<pre>requires muld RRR
call muld RRR</pre>
<td valign="top"><tt>muld RRR (alpha), fmull RRR (i386)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>must be implemented if mul double insn defined
get src from sslot1 into double reg for read
get src2 from sslot2 into double reg for read
alloc double reg for write to dst
emit mul double dst=src*src2
special handling is needed
if only one double reg
or if ieee supported</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>div int const
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, jint val
<td valign="top">divide int reg by a const dst=src/val
<pre>requires ashr int const
if div is equivalent to simple right shift
ashr int const to perform equivalent div
else if divi RRC defined and
const in range
call divi RRC dst=src*val
else
alloc temp slot tmp
move int const tmp<-val
div int dst=src/tmp
dealloc temp slot tmp
endif</pre>
<td valign="top">not implemented in any arch yet
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit div src/val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>div int
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">divide two int slots
<pre>requires ashr int const
(can only be used for positive divisors)
if src2 is const and
simple right shift will be equivalent
ashr int const to perform equivalent div
endif
if div RRR defined
if div RRC defined and
src or src2 is const
call div RRC dst=src/src2
(immediate val)
else
call div RRR dst=src/src2
endif
else
begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft div func
pop args
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>divi RRR (alpha), div RRR (i386)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(possibly do some arch-specific optimizations)
if only two operands are supported
assert dst==src
(may need special code if particular regs
are needed as src or dst of div -- e.g.
see i386 code)
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit div src/src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>div long
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">divide two long slot pairs
<pre>if divl RRR defined
call divl RRR
else
begin func synchronization (spill)
push args src and src2
in arch-specific order,
handling ratio of sizeof
long to sizeof int
call soft divl
pop args
end func synchronization (do reload)
return long dst
endif</pre>
<td valign="top"><tt>divl RRR (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(possibly do some arch-specific optimizations)
if only two operands are supported
assert dst==src
(may need special code if particular regs
are needed as src or dst of div -- e.g.
see i386 code)
get src from sslot1 into reg for read
(uses 2 slots)
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit div src/src2
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>div float
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">divide two floats
<pre>if divf RRR defined
call divf RRR
else
begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft fdiv
pop args
end func synchronization (reload)
return float dst
endif</pre>
<td valign="top"><tt>divf RRR (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>must be implemented if div float insn defined
(special code needed if only one float reg
or if ieee supported)
get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc float reg for write to dst
emit div float dst=src/src2</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>div double
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src, SlotInfo* src2
<td valign="top">divide two doubles
<pre>if divd RRR defined
call divd RRR
else
begin func synchronization (spill)
push args src and src2 in arch-specific order,
handling ratio of sizeof double to sizeof int
call soft fdivl
pop args
end func synchronization (reload)
return double dst
endif</pre>
<td valign="top"><tt>divf RRR (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>must be implemented if div double insn defined
(special code needed
if only one float reg or
if ieee supported)
get src from sslot1 into double reg for read
(takes 2 slots)
get src2 from sslot2 into double reg for read
alloc double reg for write to dst
emit div double dst=src/src2</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>rem int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">computer remainder of int div src/val (modulus)
<pre>if HAVE rem int const defined and
val in range
call HAVE rem int const
else
alloc temp slot tmp
move int const tmp=val
rem int dst=src%tmp
dealloc temp slot tmp
endif</pre>
<td valign="top">not defined on any arch yet
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>requires rem int const rangecheck
(may need special code if particular regs
are needed as src or dst of div -- e.g.
see i386 code)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit compute src%val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>rem int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">remainder of int div src/src2 (modulus)
<pre>if HAVE rem int defined
call HAVE rem int
else
begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft soft rem
pop args
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>remi RRR (alpha), rem RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>(may need special code if particular
regs are needed as src or dst of div --
e.g. see i386 code)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit compute src%val
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>rem long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">remainder of long div src/src2 (modulus)
<pre>if HAVE rem long defined
call HAVE rem long
else
begin func synchronization (spill)
push args src and src2
in arch-specific order,
handling ratio of sizeof
long to sizeof int
call soft soft rem
pop args
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>reml RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>(may need special code if particular
regs are needed as src or dst of div --
e.g. see i386 code)
if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit compute src%val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>rem float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">floating-ptr remainder?
<pre>begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft soft frem
pop args
end func synchronization (reload)
return float dst</pre>
<td valign="top">none, implemented in software
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>rem double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">double-prevision floating-ptr remainder?
<pre>begin func synchronization (spill)
push args src and src2
in arch-specific order
call soft soft freml
pop args
end func synchronization (reload)
return double dst</pre>
<td valign="top">none, implemented in software
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>neg int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">int negation
<pre>if negi RxR defined
call negi RxR
else
alloc temp slot zero
move int const 0 to zero
sub int dst=zero-src
dealloc temp slot zero
endif</pre>
<td valign="top"><tt>negi RxR (alpha), neg RxR (i386), neg RRR (mips)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into reg for read
alloc reg for write to dst
emit compute -src
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>ngc int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">int negation with carry
<pre>if negi RxR defined
call negi RxR
else
alloc temp slot zero
move int const 0 to zero
sub int dst=zero-src
dealloc temp slot zero
endif</pre>
<td valign="top"><tt>ngci RxR (m68k)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>required if ngc int insn defined
get src from sslot2 into reg for read
alloc reg for write to dst
emit compute -src+Carry Flag
emit store result in dst</pre>
<td valign="top"><tt>if long ops are not defined
<tr>
<td valign="top"><tt>neg long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">long negation
<pre>if negl RxR defined
call negl RxR
else if ngc int defined
call neg int
LSLOT(dst)=-LSLOT(src)
call ngc int
HSLOT(dst)=-HSLOT(src)
else if sbc int defined
alloc temp slot zero
move int const zero=0
call sub int
LSLOT(dst)=zero-LSLOT(src)
call sbc int
HSLOT(dst)=zero-HSLOT(src)
dealloc temp slot zero
else if adc int const defined
call neg int
LSLOT(dst)=-LSLOT(src)
call adc int const
HSLOT(dst)=HSLOT(src)+0+carry flag
call neg int
HSLOT(dst)=-HSLOT(dst)
else if set lt int const and
nor int are defined
alloc temp slots zero and carry
move int const zero=0
if LSLOT(src)<1
set lt int const carry=1 else carry=0
sub int LSLOT(dst)=
zero-LSLOT(src)
nor int HSLOT(dst)=
zero NOR HSLOT(src)
add int HSLOT(dst)=
HSLOT(dst)+carry
dealloc temp slots zero and carry
else
abort
endif</pre>
<td valign="top"><tt>negl RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into long reg for read
alloc long reg for write to dst
emit compute -src
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>neg float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">float negation
<pre>if negf RxR defined
call negf RxR
else
alloc temp slot zero
move float const zero=0
sub int dst=zero-src
dealloc temp slot zero
endif</pre>
<td valign="top"><tt>negf RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into float reg for read
alloc float reg for write to dst
emit compute -src
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>neg double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">double-precision float negation
<pre>if negd RxR defined
call negd RxR
else
alloc temp slot pair zero
move double const zero=0
sub int dst=zero-src
dealloc temp slot pair zero
endif</pre>
<td valign="top"><tt>negd RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into double reg for read
alloc double reg for write to dst
emit compute -src
emit store result in dst</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Moves">Prev</a>]
[<a href="#Arithmetic">This</a>]
[<a href="#Logical">Next</a>]
<p><h3 align="center">
<a name="Logical">Logical ops</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>and int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-and operation
<pre>and RRR is required
if and int const defined and
src or src2 is a const slot
call and int const
else
call and RRR
endif</pre>
<td valign="top"><tt>andi RRR (alpha), and RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit and src & src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>and int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int logical-and operation
<pre>and RRR is required
if val is -1
move int dst=src
else if val is 0
move int const dst=0
else if and RRC defined and
val is in range
call and RRC
else
alloc temp slot tmp
move int const tmp=val
and int dst=src & tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>andi RRC (alpha), and RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit and src & val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>and long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long logical-and operation
<pre>if andl RRR defined
call andl RRR
else
and int LSLOT(dst)=LSLOT(src) & LSLOT(src2)
and int HSLOT(dst)=HSLOT(src) & HSLOT(src2)
endif</pre>
<td valign="top"><tt>andl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit and src & src2
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>and long const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jlong val
<td valign="top">long logical-and operation
<pre>andl RRC & and long const rangecheck are required
if val is in range
call andl RRC
else
alloc temp slot tmp
move long tmp=val
and long dst=src & tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>andl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jlong val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get val from sslot2
alloc long reg for write to dst
emit and src & val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>or int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-or operation
<pre>or RRR is required
if or int const defined and
src or src2 is a const slot
call or int const
else
call or RRR
endif</pre>
<td valign="top"><tt>ori RRR (alpha), or RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit or src | src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>or int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int logical-or operation
<pre>or RRR is required
if val is -1
move int const dst=-1
else if val is 0
move int const dst=src
else if or RRC defined and
val is in range
call or RRC
else
alloc temp slot tmp
move int const tmp=val
or int dst=src | tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>ori RRC (alpha), or RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit or src | val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top">nor int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-nor operation
<pre>nor RRR is required
call nor RRR</pre>
<td valign="top">nor RRR (mips)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit nor !(src | src2)
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>or long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long logical-or operation
<pre>if orl RRR defined
call orl RRR
else
or int LSLOT(dst)=
LSLOT(src) | LSLOT(src2)
or int HSLOT(dst)=
HSLOT(src) | HSLOT(src2)
endif</pre>
<td valign="top"><tt>orl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit or src | src2
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>xor int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-xor operation
<pre>xor RRR is required
if xor int const defined and
src xor src2 is a const slot
call xor int const
else
call xor RRR</pre>
endif
<td valign="top"><tt>xori RRR (alpha), xor RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
alloc reg for write to dst
emit xor src ^ src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>xor int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int logical-xor operation
<pre>xor RRR is required
if xor RRC defined and
val is in range
call xor RRC
else
alloc temp slot tmp
move int const tmp=val
xor int dst=src ^ tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>xori RRC (alpha), xor RRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into reg for read
get val from sslot2
alloc reg for write to dst
emit xor src ^ val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>xor long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long logical-xor operation
<pre>if xorl RRR defined
call xorl RRR
else
xor int LSLOT(dst)=
LSLOT(src) ^ LSLOT(src2)
xor int HSLOT(dst)=
HSLOT(src) ^ HSLOT(src2)
endif</pre>
<td valign="top"><tt>xorl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit or src ^ src2
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>lshl int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-left-shift operation
<pre>lshl RRR is required
if src2 is a const and
lshl RRC defined
call lshl RRC
else
call lshl RRR
endif</pre>
<td valign="top"><tt>lshli RRR (alpha), lshl RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit left-shift src<<src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>lshl int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int logical-left-shift operation
<pre>if lshl RRC defined and
val is in range
call lshl RRC
else
alloc temp slot tmp
move int const tmp=val
lshl int dst=src<<tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>lshli RRR (alpha), lshl RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit left-shift src<<val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>lshl long const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jlong val
<td valign="top">long logical-left-shift operation
<pre>if lshll RRC defined and
val is in range
call lshll RRC
else
alloc temp slot tmp
move long const tmp=val
lshl long dst=src<<tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>lshll RRC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jlong val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit left-shift src<<val
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>lshl long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long logical-left-shift operation
<pre>if lshll RRR defined
call lshll RRR
else
begin func synchronization (spill)
push args src and src2 in arch-specific order,
accounting for size difference of int and long
call soft soft lshll
pop args
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>lshll RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit left-shift src<<src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>ashr int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int arithmetic-right-shift operation
<pre>ashr RRR is required
if src2 is a const and
ashr RRC defined
call ashr RRC
else
call ashr RRR
endif</pre>
<td valign="top"><tt>ashri RRR (alpha), ashr RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit right-shift src>>src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>ashr int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int arithmetic-right-shift operation
<pre>if ashr RRC defined and
val is in range
call ashr RRC
else
alloc temp slot tmp
move int const tmp=val
ashr int dst=src>>tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>ashri RRR (alpha), ashr RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit right-shift src>>val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>ashr long const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jlong val
<td valign="top">long arithmetic-right-shift operation
<pre>if ashrl RRC defined and
val is in range
call ashrl RRC
else
alloc temp slot tmp
move long const tmp=val
ashr long dst=src>>tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>ashrl RRC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jlong val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit right-shift src>>val
emit store result in dst</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>ashr long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long arithmetic-right-shift operation
<pre>if ashrl RRR defined
call ashrl RRR
else
begin func synchronization (spill)
push args src and src2 in arch-specific order,
accounting for size difference of int and long
call soft soft ashrl
pop args
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>ashrl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit right-shift src>>src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>lshr int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">int logical-right-shift operation
<pre>lshr RRR is required
if src2 is a const and
lshr RRC defined
call lshr RRC
else
call lshr RRR
endif</pre>
<td valign="top"><tt>lshri RRR (alpha), ashr RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit right-shift src>>src2
emit store result in dst</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>lshr int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">int logical-right-shift operation
<pre>if lshr RRC defined and
val is in range
call lshr RRC
else
alloc temp slot tmp
move int const tmp=val
lshr int dst=src>>tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>lshri RRR (alpha), lshr RRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into int reg for read
get src2 from sslot2 into int reg for read
alloc int reg for write to dst
emit right-shift src>>val
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>lshr long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">long logical-right-shift operation
<pre>if lshrl RRR defined
call lshrl RRR
else
begin func synchronization (spill)
push args src and src2 in arch-specific order,
accounting for size difference of int and long
call soft soft lshrl
pop args
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>lshrl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>if only two operands are supported
assert dst==src
get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc long reg for write to dst
emit right-shift src>>src2
emit store result in dst</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Arithmetic">Prev</a>]
[<a href="#Logical">This</a>]
[<a href="#Load and store">Next</a>]
<p><h3 align="center">
<a name="Load and store">Load and store</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>load int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load int from mem
<pre>load RxR is required
call load RxR</pre>
<td valign="top"><tt>loadi RxR (alpha), load RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load offset int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load int from mem+offset
<pre>if offset is 0
call loadi RxR
else if loadi RRC defined
call loadi RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load int dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadi RRC (alpha), load RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem m from sslot1
get the offset o from sslot2
emit load r<-mem[m+o]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load addr int
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load int from mem address
<pre>if load RxA defined
call load RxA
else
alloc temp slot tmp
move ref const tmp=addr
load int dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RxA (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem address m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load int from mem address
<pre>loadr RxR is required
call loadr RxR</pre>
<td valign="top"><tt>loadr RxR (alpha), load RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load offset ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load obj ptr from mem+offset
<pre>if offset is 0
call loadr RxR
else if loadr RRC defined
call loadr RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load int dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadr RRC (alpha), load RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem m from sslot1
get the offset o from sslot2
emit load r<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load addr ref
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load int from mem address
<pre>if load RxA defined
call load RxA
else
alloc temp slot tmp
move ref const tmp=addr
load ref dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RxA (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem address m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load int from mem
<pre>if loadl RxR defined
call loadl RxR
else
alloc temp slot tmp
add ref const tmp=src+4 ?
load int dst=[src]
load int dst+1=[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadl RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load addr long
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load long from mem address
<pre>if loadl RxA defined
call loadl RxA
else
load addr int dst=mem[addr]
load addr int dst+1=mem[addr+4]
endif</pre>
<td valign="top"><tt>loadl RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the long reg r from sslot0
get the mem address m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load float from mem
<pre>loadf RxR is required
call loadf RxR</pre>
<td valign="top"><tt>loadf RxR (alpha), fload RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into float reg for read
alloc float reg for write to dst
emit load r<-mem[m]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load addr float
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load float from mem address
<pre>if loadf RxA defined
call loadf RxA
else
alloc temp slot tmp
move ref const tmp=addr
load float dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the float reg r from sslot0
get the mem address m from sslot2
emit load r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load double from mem
<pre>loadd RxR is required
call loadd RxR</pre>
<td valign="top"><tt>loadd RxR (alpha), floadl RxR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into double reg m for read
alloc double reg w for write to dst
emit load w<-mem[m]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>load addr double
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load double from mem address
<pre>if loadf RxA defined
call loadf RxA
else
alloc temp slot tmp
move ref const tmp=addr
load double dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the double reg w from sslot0
get the mem address m from sslot2
emit load w<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load byte from mem
<pre>if loadb RxR defined
call loadb RxR
else
load int dst=src
logical right shift dst by
8*(sizeof jint-sizeof jbyte)
left shift dst by
8*(sizeof jint-sizeof jbyte)
endif</pre>
<td valign="top"><tt>loadb RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the mem m from sslot2 into int reg for read
alloc int reg w for write to dst
emit load byte w<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load char from mem
<pre>if loadc RxR defined
call loadc RxR
else
load int dst=src
and int const dst=
dst & ((1<<(8*sizeof(jchar))) -1)
endif</pre>
<td valign="top"><tt>loadc RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the mem m from sslot2 into int reg for read
alloc int reg w for write to dst
emit load char w<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">load short from mem
<pre>if loads RxR defined
call loads RxR
else
load int dst=src
logical right shift dst by
8*(sizeof jint-sizeof jshort)
left shift dst by
8*(sizeof jint-sizeof jshort)
endif</pre>
<td valign="top"><tt>loads RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the mem m from sslot2 into int reg for read
alloc int reg w for write to dst
emit load short w<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load addr char
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load char from mem address
<pre>if load RxA defined
call load RxA
else
alloc temp slot tmp
move ref const tmp=addr
load char dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadc RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem address m from sslot2
emit load char r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load addr byte
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load byte from mem address
<pre>if load RxA defined
call load RxA
else
alloc temp slot tmp
move ref const tmp=addr
load byte dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadb RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem address m from sslot2
emit load byte r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load addr short
<td valign="top"><tt>SlotInfo *dst, void *addr
<td valign="top">load short from mem address
<pre>if load RxA defined
call load RxA
else
alloc temp slot tmp
move ref const tmp=addr
load short dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loads RxA (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0
get the mem address m from sslot2
emit load short r<-mem[m]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load long from mem+offset
<pre>if offset is 0
call loadl RxR
else if loadl RRC defined and
offset is in range
call loadl RRC
else
load offset int dst=src+offset
load offset int dst+1=src+offset+4
endif</pre>
<td valign="top"><tt>loadl RRC (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into long reg
emit load w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load byte from mem+offset
<pre>if offset is 0
call loadb RxR
else if loadb RRC defined and
offset is in range
call loadb RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load byte dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadb RRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into int reg
emit load byte w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load char from mem+offset
<pre>if offset is 0
call loadc RxR
else if loadc RRC defined and
offset is in range
call loadc RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load char dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadc RRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into int reg
emit load char w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load short from mem+offset
<pre>if offset is 0
call loads RxR
else if loads RRC defined and
offset is in range
call loads RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load short dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loads RRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into int reg
emit load short w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load float from mem+offset
<pre>if offset is 0
call loads RxR
else if loads RRC defined and
offset is in range
call loads RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load float dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadf RRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into float reg
emit load float w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint offset
<td valign="top">load double from mem+offset
<pre>if offset is 0
call loads RxR
else if loads RRC defined and
offset is in range
call loads RRC
else
alloc temp slot tmp
add ref const tmp=src+offset
load double dst=mem[tmp]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadf RRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the offset o from sslot2
get the mem m from sslot1 into a ref reg
get the reg w from sslot0 into double reg
emit load double w<-mem[m+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load int from mem+idx*sizeof(jint)+offset
<pre>if idx is a const
call load offset int dst=
mem[src+idx*sizeof(jint)+offset]
else if load RRRC defined
call load RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jint
add ref tmp=tmp+src
load offset int dst=mem[tmp+offset]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jint)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, jint offset
<td valign="top">load obj ptr from mem+offset
<pre>if idx is a const
call load offset int dst=
mem[src+idx*sizeof(jint)+offset]
else if load RRRC defined
call load RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jint
add ref tmp=tmp+src
load offset ref dst=mem[tmp+offset]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>load RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jint)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load long from mem+idx*sizeof(jlong)+offset
<pre>if idx is a const
call load offset long dst=
mem[src+idx*sizeof(jlong)+offset]
else if loadl RRRC defined
call loadl RRRC
else
alloc temp slot nidx
lshl int const nidx=idx<<1
if LSLOT(dst) & src don't collide
load offset scaled int LSLOT(dst)=
mem[src+nidx*sizeof(jint)+offset]
load offset scaled int HSLOT(dst)=
mem[src+nidx*sizeof(jint)+offset+4]
else
load offset scaled int LSLOT(dst)=
mem[src+nidx*sizeof(jint)+offset]
load offset scaled int HSLOT(dst)=
mem[src+nidx*sizeof(jint)+offset+4]
endif
dealloc temp slot nidx
endif</pre>
<td valign="top"><tt>loadl RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jlong)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load float from mem+idx*sizeof(jfloat)+offset
<pre>if idx is a const
call load offset float dst=
mem[src+idx*sizeof(jfloat)+offset]
else if loadf RRRC defined
call loadf RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jfloat
add ref tmp=tmp+src
load offset float dst=tmp+offset
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadf RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jfloat)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load double from mem+idx*sizeof(jdouble)+offset
<pre>if idx is a const
call load offset double dst=
mem[src+idx*sizeof(jdouble)+offset]
else if loadf RRRC defined
call loadf RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jdouble
add ref tmp=tmp+src
load offset double dst=tmp+offset
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadd RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jdouble)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load byte from mem+idx*sizeof(jbyte)+offset
<pre>if idx is a const
call load offset byte dst=
mem[src+idx*sizeof(jbyte)+offset]
else if loadb RRRC defined
call loadb RRRC
else
alloc temp slot tmp
add ref tmp=idx+src
load offset byte dst=tmp+offset
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadb RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jbyte)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load char from mem+idx*sizeof(jchar)+offset
<pre>if idx is a const
call load offset char dst=
mem[src+idx*sizeof(jchar)+offset]
else if loadc RRRC defined
call loadc RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jchar
add ref tmp=tmp+src
load offset char dst=tmp+offset
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loadc RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jchar)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load offset scaled short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *idx, int offset
<td valign="top">load short from mem+idx*sizeof(jshort)+offset
<pre>if idx is a const
call load offset short dst=
mem[src+idx*sizeof(jshort)+offset]
else if loads RRRC defined
call loads RRRC
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jshort
add ref tmp=tmp+src
load offset short dst=tmp+offset
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>loads RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the reg w from sslot0
get the mem m from sslot1
get the scaled offset s from sslot2
get the offset o from sslot3
emit load w<-mem[m+s*sizeof(jshort)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>load code ref
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src
<td valign="top">dst=pc+mem[src]
<pre>if loadpc RxR defined
call loadpc RxR
else
call load ref dst=mem[src]
endif</pre>
<td valign="top"><tt>loadpc RxR (alpha)
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot2)
<td valign="top"><tt>
<pre>get long reg r from sslot2 for read
get long reg w from sslot0 for write
emit load w=mem[r]
emit add w=
w+REG gp (program counter?)</pre>
<td valign="top">"yes" (alpha)
<tr>
<td valign="top"><tt>load key
<td valign="top"><tt>SlotInfo* dst, SlotInfo* src
<td valign="top">same as load int
<td valign="top"><tt>same as load int
<td valign="top"><tt>SlotInfo* dst (sslot0), SlotInfo* src (sslot2)
<td valign="top"><tt>
<pre>call load int dst=mem[src]</pre>
<td valign="top">same as load int
<tr>
<td valign="top"><tt>store int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store int into mem[dst]=src
<pre>store xRR is required
call store xRR</pre>
<td valign="top"><tt>storei xRR (alpha), store xRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot2 for read
get the reg w from sslot1 for read
emit store r->mem[w]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>store offset int
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store int into mem[dst+offset]=src
<pre>if offset is 0
call store int mem[dst]=src
else if src is a const and
store const offset int defined
call store const offset int
mem[dst+offset]=src
else if store xRRC defined
call store xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store int mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storei xRRC (alpha), store xRRC (i386), store RRC (mips)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
get the reg w from sslot1 for read
get the offset o from sslot2
emit store r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr int
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store int into mem[addr]=src
<pre>if store xRA defined
call store xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store int mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>store xRA (i386)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot1 for read
get the address addr from sslot2
emit store r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store obj ref into mem[dst]=src
<pre>storer xRR is required
call storer xRR</pre>
<td valign="top"><tt>storer xRR (alpha), store xRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot2 for read
get the reg w from sslot1 for read
emit store r->mem[w]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>store offset ref
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store obj ref into mem[dst+offset]=src
<pre>if offset is 0
call store ref mem[dst+offset]=src
else if store xRRC defined and
offset is in range
call store xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store ref mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storer xRRC (alpha), store xRRC (i386), store RRC (mips)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
get the reg w from sslot1 for read
get the offset o from sslot2
emit store r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr ref
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store obj ref into mem[addr]=src
<pre>if store xRA defined
call store xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store ref mem[addr]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>store xRA (i386)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg w from sslot1 for read
get the addr o from sslot2
emit store r->mem[o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store long into mem[dst]=src
<pre>if storel xRR defined
call store xRR mem[dst]=src
else
alloc temp slot tmp
add ref const tmp=dst+4
store int mem[dst]=src
store int mem[tmp]=src+1
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storel xRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot2 for read
get the reg w from sslot1 for read
emit store r->mem[w]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>store offset long
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store long into mem[dst+offset]=src
<pre>if offset is 0
call store long mem[dst]=src
else if store xRRC defined and
offset is in range
call store xRRC mem[dst+offset]=src
else
store offset int mem[dst+offset]=src
store offset int mem[dst+offset+4]=src+1
endif</pre>
<td valign="top"><tt>storei xRRC (alpha), store xRRC (i386), store RRC (mips)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
get the reg w from sslot1 for read
get the offset o from sslot2
emit store r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr long
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store long into mem[addr]=src
<pre>if storel xRA defined
call storel xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store long mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storel xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot1 for read
get the address addr from sslot2
emit store r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store float into mem[dst]=src
<pre>storef xRR is required
call storef xRR mem[dst]=src</pre>
<td valign="top"><tt>storef xRR (alpha), fstore RxR (i386), fstore RRx (mips), fstore xRR (sparc)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the float reg r from sslot2 for read
get the ref reg w from sslot1 for read
emit store r->mem[w]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>store offset float
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store float into mem[dst+offset]=src
<pre>if offset is 0
call store float mem[dst]=src
else if storef xRRC defined and
offset is in range
call storef xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store float mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storef xRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the float reg r from sslot0 for read
get the ref reg w from sslot1 for read
get the offset o from sslot2
emit store r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr float
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store float into mem[addr]=src
<pre>if storef xRA defined
call storef xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store float mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storef xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the float reg r from sslot1 for read
get the address addr from sslot2
emit store r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store double into mem[dst]=src
<pre>stored xRR is required
call stored xRR mem[dst]=src</pre>
<td valign="top"><tt>
stored xRR (alpha), fstorel RxR (i386), fstorel RRx (mips), fstorel xRR (sparc)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the double reg r from sslot2 for read
get the ref reg w from sslot1 for read
emit store r->mem[w]</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>store offset double
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store double into mem[dst+offset]=src
<pre>if offset is 0
call store double mem[dst]=src
else if stored xRRC defined and
offset is in range
call stored xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store double mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stored xRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the double reg r from sslot0 for read
get the ref reg w from sslot1 for read
get the offset o from sslot2
emit store r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr double
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store double into mem[addr]=src
<pre>if stored xRA defined
call stored xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store double mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stored xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the double reg r from sslot1 for read
get the address addr from sslot2
emit store r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store byte into mem[dst]=src
<pre>if storeb xRR defined
call storeb xRR
else
** FIXME CODE **
alloc temp slots tmp and tmp2
and int const tmp=
src & (1<<(8*sizeof(jbyte)))-1
load int tmp2=mem[dst]
and int const tmp2=
tmp2 & -(1<<(8*sizeof(jbyte)))
or int tmp2=tmp2 | tmp
store int mem[dst]=tmp2
dealloc temp slots tmp and temp2
endif</pre>
<td valign="top"><tt>storeb xRR (alpha), store xRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the int reg r from sslot2 for read
get the ref reg w from sslot1 for read
into reg that can be stored as a byte
emit store byte r->mem[w]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset byte
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store byte into mem[dst+offset]=src
<pre>if offset is 0
call store byte mem[dst]=src
else if src is a const and
store const offset byte defined
call store const offset byte
mem[dst+offset]=src const val
else if storeb xRRC defined
call storeb xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store byte mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storeb xRRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
into reg that can be stored as a byte
get the ref reg w from sslot1 for read
get the offset o from sslot2
emit store byte r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr byte
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store byte into mem[addr]=src
<pre>if storeb xRA defined
call storeb xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store byte mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storeb xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot1 for read
into reg that can be stored as a byte
get the address addr from sslot2
emit store byte r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store char into mem[dst]=src
<pre>if stores xRR defined
call stores xRR mem[dst]=src
else
** FIXME CODE **
alloc temp slots tmp and tmp2
and int const tmp=
src & (1<<(8*sizeof(jchar)))-1
load int tmp2=mem[dst]
and int const tmp2=
tmp2 & -(1<<(8*sizeof(jchar)))
or int tmp2=tmp2 | tmp
store int mem[dst]=tmp2
dealloc temp slots tmp and temp2
endif</pre>
<td valign="top"><tt>stores xRR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the int reg r from sslot2 for read
get the ref reg w from sslot1 for read
into reg that can be stored as a char
emit store char r->mem[w]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset char
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store char into mem[dst+offset]=src
<pre>if offset is 0
call store char mem[dst]=src
else if stores xRRC defined
call stores xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store char mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores xRRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
into reg that can be stored as a char
get the ref reg w from sslot1 for read
get the offset o from sslot2
emit store char r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr char
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store char into mem[addr]=src
<pre>if stores xRA defined
call stores xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store char mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot1 for read
into reg that can be stored as a char
get the address addr from sslot2
emit store char r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">store short into mem[dst]=src
<pre>if stores xRR defined
call stores xRR mem[dst]=src
else
** FIXME CODE **
alloc temp slots tmp and tmp2
and int const tmp=
src & (1<<(8*sizeof(jshort)))-1
load int tmp2=mem[dst]
and int const tmp2=
tmp2 & -(1<<(8*sizeof(jshort)))
or int tmp2=tmp2 | tmp
store int mem[dst]=tmp2
dealloc temp slots tmp and temp2
endif</pre>
<td valign="top"><tt>stores xRR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get the int reg r from sslot2 for read
get the ref reg w from sslot1 for read
into reg that can be stored as a short
emit store short r->mem[w]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset short
<td valign="top"><tt>SlotInfo *dst, int offset, SlotInfo *src
<td valign="top">store short into mem[dst+offset]=src
<pre>if offset is 0
call store short mem[dst]=src
else if stores xRRC defined
call stores xRRC mem[dst+offset]=src
else
alloc temp slot tmp
add ref const tmp=dst+offset
store short mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores xRRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot0), SlotInfo *dst (sslot1), int offset (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot0 for read
into reg that can be stored as a short
get the ref reg w from sslot1 for read
get the offset o from sslot2
emit store short r->mem[w+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store addr short
<td valign="top"><tt>void *addr, SlotInfo *src
<td valign="top">store short into mem[addr]=src
<pre>if stores xRA defined
call stores xRA mem[addr]=src
else
alloc temp slot tmp
move ref const tmp=addr
store short mem[tmp]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores xRA (nowhere defined)
<td valign="top"><tt>SlotInfo *src (sslot1), void *addr (sslot2)
<td valign="top"><tt>
<pre>get the reg r from sslot1 for read
into reg that can be stored as a short
get the address addr from sslot2
emit store short r->mem[addr]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store int to mem+idx*sizeof(jint)+offset
<pre>if idx is a const
call store offset int
mem[dst+idx*sizeof(jint)+offset]=src
else if store RRRC defined
call store RRRC
mem[dst+idx*sizeof(jint)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jint
add ref tmp=tmp+dst
store offset int mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>store RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), SlotInfo *src (sslot3),
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the int reg r from sslot3
emit store r->mem[m+s*sizeof(jint)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store obj ref to mem+idx*sizeof(jref)+offset
<pre>if idx is a const
call store offset ref
mem[dst+idx*sizeof(jref)+offset]=src
else if store RRRC defined
call store RRRC
mem[dst+idx*sizeof(jref)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jref
add ref tmp=tmp+src
store offset ref dst=mem[tmp+offset]
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>store RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the ref reg r from sslot3
emit store r->mem[m+s*sizeof(jref)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store long to mem+idx*sizeof(jint)+offset
<pre>if idx is a const
call store offset long
mem[dst+idx*sizeof(jlong)+offset]=src
else if store RRRC defined
call store RRRC
mem[dst+idx*sizeof(jlong)+offset]=src
else
alloc temp slot nidx
lshl int const nidx=idx<<1
store offset scaled int
mem[dst+sizeof(jint)*nidx+offset]=
LSLOT(src)
store offset scaled int
mem[dst+sizeof(jint)*nidx+offset+4]=
HSLOT(src)
dealloc temp slot nidx
endif</pre>
<td valign="top"><tt>store RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), SlotInfo *idx (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the long reg r from sslot3
emit store r->mem[m+s*sizeof(jlong)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store float to mem+idx*sizeof(jfloat)+offset
<pre>if idx is a const
call store offset float
mem[dst+idx*sizeof(jfloat)+offset]=src
else if store RRRC defined
call store RRRC
mem[dst+idx*sizeof(jfloat)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jfloat
add ref tmp=tmp+dst
store offset float mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storef RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), SlotInfo *src (sslot3),
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the float reg r from sslot3
emit store r->mem[m+s*sizeof(jfloat)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store double to mem+idx*sizeof(jdouble)+offset
<pre>if idx is a const
call store offset double
mem[dst+idx*sizeof(jdouble)+offset]=src
else if store RRRC defined
call store RRRC
mem[dst+idx*sizeof(jdouble)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jdouble
add ref tmp=tmp+dst
store offset double mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storef RRRC (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), SlotInfo *src (sslot3),
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the double reg r from sslot3
emit store r->mem[m+s*sizeof(jdouble)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store byte to mem+idx*sizeof(jbyte)+offset
<pre>if idx is a const
call store offset byte
mem[dst+idx+offset]=src
else if storeb RRRC defined
if storeb RRCC defined and
src is a const
call storeb RRCC
mem[dst+idx+offset]=
src const val
else
call storeb RRRC
mem[dst+idx+offset]=src
endif
else
alloc temp slot tmp
add ref tmp=tmp+dst
store offset byte
mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>storeb RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), SlotInfo *src (sslot2), int offset (sslot3)
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the byte reg r from sslot3
emit store r->mem[m+s+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store const offset scaled byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, jint src
<td valign="top">store byte const to mem+idx+offset
<pre>storeb RRCC is required
call storeb RRCC mem[dst+idx+offset]=
src const val</pre>
<td valign="top"><tt>storeb RRCC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), jint src (sslot3)
<td valign="top"><tt>
<pre>required if store const offset scaled byte icode impl.
get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the byte b from sslot3
emit store b->mem[m+s+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store char to mem+idx*sizeof(jchar)+offset
<pre>if idx is a const
call store offset char
mem[dst+idx*sizeof(jchar)+offset]=src
else if stores RRRC defined
call stores RRRC
mem[dst+idx*sizeof(jchar)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jchar
add ref tmp=tmp+dst
store offset char mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), SlotInfo *src (sslot3)
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the char reg r from sslot3
emit store r->mem[m+s*sizeof(jchar)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store offset scaled short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *idx, int offset, SlotInfo *src
<td valign="top">store short to mem+idx*sizeof(jshort)+offset
<pre>if idx is a const
call store offset short
mem[dst+idx*sizeof(jshort)+offset]=src
else if stores RRRC defined
call stores RRRC
mem[dst+idx*sizeof(jshort)+offset]=src
else
alloc temp slot tmp
lshl int const tmp=idx<<SHIFT jshort
add ref tmp=tmp+dst
store offset short mem[tmp+offset]=src
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>stores RRRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *idx (sslot1), int offset (sslot2), SlotInfo *src (sslot3)
<td valign="top"><tt>
<pre>get the ref reg m from sslot0
get the scaled offset s from sslot1
get the offset o from sslot2
get the short reg r from sslot3
emit store r->mem[m+s*sizeof(jshort)+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store const offset int
<td valign="top"><tt>SlotInfo *dst, int offset, jint val
<td valign="top">store int into mem[dst+offset]=val
<pre>store xRCC is required
if offset is in range
call store xRCC mem[dst+offset]=val
else
alloc temp slots tmp and tmp2
add ref const tmp=dst+offset
move int const tmp2=val
store int mem[tmp]=tmp2
dealloc temp slots tmp and tmp2
endif</pre>
<td valign="top"><tt>store xRCC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), int offset (sslot1), jint val
<td valign="top"><tt>
<pre>get the ref reg r from sslot0 for read
get the offset o from sslot1 for read
get the int val v from sslot2
emit store v->mem[r+o]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>store const offset byte
<td valign="top"><tt>SlotInfo *dst, int offset, jint val
<td valign="top">store byte into mem[dst+offset]=val
<pre>storeb xRCC is required
if offset is in range
call storeb xRCC mem[dst+offset]=val
else
alloc temp slots tmp and tmp2
add ref const tmp=dst+offset
move int const tmp2=val
store byte mem[tmp]=tmp2
dealloc temp slots tmp and tmp2
endif</pre>
<td valign="top"><tt>storeb xRCC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), int offset (sslot1), jint val
<td valign="top"><tt>
<pre>get the ref reg r from sslot0 for read
get the offset o from sslot1 for read
get the byte val v from sslot2
emit store v->mem[r+o]</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Logical">Prev</a>]
[<a href="#Load and store">This</a>]
[<a href="#Function argument management">Next</a>]
<p><h3 align="center">
<a name="Function argument management">Function argument management</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>pusharg int const
<td valign="top"><tt>int val, int idx
<td valign="top">push const int actual argument onto func call stack
<pre>if pushi xCC defined
call pushi xCC
increment argcount
else
alloc temp slot tmp
move int const tmp=val
pusharg int stack[idx]=tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>pushi xCC (alpha), push xCC (i386),
<td valign="top"><tt>int val (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>if arch always uses stack for args
get val from sslot1
emit push val onto stack
(idx may be needed)
else
if idx<maxArgregs
w=getArgreg(idx)
spill reg w
if val is in range for move
emit move val to reg w
else
add val to const pool
emit load val
from const pool into w
endif
else
o=stackFrameOffset(idx)
if val is 0 and
arch has zero reg
store zero reg into mem[sp+o]
else if val is in range for move
alloc tmp reg r for write
emit move val into r
emit store r into mem[sp+o]
else
alloc tmp reg r for write
emit add val to const pool
emit load it into r
emit store r into mem[sp+o]
endif
endif
endif</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>pusharg int
<td valign="top"><tt>SlotInfo *src, int idx
<td valign="top">push int actual argument onto func call stack
<pre>if pusharg int const defined and
src is a const
call pusharg int const
else
call pusharg int
increment argcount
endif</pre>
<td valign="top"><tt>pushi xRC (alpha), push xRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>required if pusharg int icode insn defined
if arch always uses stack for args
if sslot1 is in int or ref reg
get int reg r from sslot0 for read
emit push reg r onto stack
else
get abs offset o of sslot1 on stack
emit push val of mem[o] onto stack
endif
else
if idx<maxArgregs
(there are still regs left)
w=getIdealArgreg(idx)
if sslot1 is in int reg
get int reg r from sslot1 for read
if w!=r
clobber reg w (spill)
emit move reg r into reg w
endif
else
get abs offset o of sslot1 on stack
clobber reg w (spill)
emit load w<-mem[sp+o]
endif
reserve reg r
increment reserved reg count
else (arg is destined for stack)
w=stackFrameOffset(idx)
if sslot1 is in int reg
get reg r from sslot1 for read
else
get slot offset r from sslot1 for read
load mem[fp+r] into tmp reg r
endif
store r->mem[sp+w]
endif
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>pusharg ref
<td valign="top"><tt>SlotInfo *src, int idx
<td valign="top">push obj ref actual argument onto func call stack
<pre>if pusharg ref const defined and
src is a const
call pusharg ref const
else
call pusharg ref
increment argcount
endif</pre>
<td valign="top"><tt>pushr xRC (alpha), push xRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>required if pusharg ref icode insn defined
if arch always uses stack for args
if sslot1 is in int or ref reg
get ref reg r from sslot0 for read
emit push reg r onto stack
else
get abs offset o of sslot1 on stack
emit push val of mem[o] onto stack
endif
else
if idx<maxArgregs
(there are still regs left)
w=getArgreg(idx)
if sslot1 is in ref reg
get ref reg r from sslot1 for read
if w!=r
spill reg w
emit move reg r into reg w
endif
else
get abs offset o of sslot1 on stack
spill reg w
emit load w<-mem[o]
endif
else
w=stackFrameOffset(idx)
if sslot1 is in ref reg
get reg r from sslot1 for read
else
get slot offset r from sslot1 for read
load mem[fp+r] into tmp reg r
endif
store r->mem[sp+w]
endif
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>pusharg ref const
<td valign="top"><tt>void* val, int idx
<td valign="top">push const obj ref actual arg onto func call stack
<pre>if pushr xCC defined
call pushr xCC
increment argcount
else
alloc temp slot tmp
move ref const tmp=val
pusharg ref stack[idx]=tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>pushr xCC (alpha), push xCC (i386),
<td valign="top"><tt>jword val (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>if arch always uses stack for args
get val from sslot1
emit push val onto stack
(idx may be needed)
else
if idx<maxArgregs
w=getArgreg(idx)
spill reg w
if val is in range for move
emit move val to ref reg w
else
add val to const pool
emit load val
from const pool into w
endif
else
o=stackFrameOffset(idx)
if val is 0 and arch has zero reg
store zero reg into mem[sp+o]
else if val is in range for move
alloc tmp ref reg r for write
emit move val into r
emit store r into mem[sp+o]
else
alloc tmp ref reg r for write
emit add val to const pool
emit load it into r
emit store r into mem[sp+o]
endif
endif
endif</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>pusharg class const
<td valign="top"><tt>Hjava lang class* cls, int idx
<td valign="top">push const obj ref actual arg onto func call stack
<pre>call pusharg ref const</pre>
<td valign="top"><tt>pushr xCC (alpha), push xCC (i386),
<td valign="top"><tt>void *cls (sslot1), int idx (sslot2)
<td valign="top"><tt>see pusharg ref const
<td valign="top">no
<tr>
<td valign="top"><tt>pusharg utf8 const
<td valign="top"><tt>Utf8Const* val, int idx
<td valign="top">push const obj ref actual arg onto func call stack
<pre>call pusharg ref const</pre>
<td valign="top"><tt>pushr xCC (alpha), push xCC (i386),
<td valign="top"><tt>void* val (sslot1), int idx (sslot2)
<td valign="top"><tt>see pusharg ref const
<td valign="top">no
<tr>
<td valign="top"><tt>pusharg float
<td valign="top"><tt>SlotInfo *src, int idx
<td valign="top">push float actual argument onto func call stack
<pre>call pusharg float
increment argcount</pre>
<td valign="top"><tt>pushf xRC (alpha), fpush xRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>required if pusharg float icode insn defined
if arch always uses stack for args
get sslot1 into int! reg r for read
emit push reg r onto stack
else
if idx<maxArgregs
(there are still regs left)
w=getArgreg(idx)
(special code needed
if ints and floats can share regs)
if sslot1 is in float reg
get float reg r from sslot1 for read
if w!=r
spill reg w
emit move reg r into reg w
endif
else
get abs offset o of sslot1 on stack
spill reg w
emit load w<-mem[sp+o]
endif
else
w=stackFrameOffset(idx)
get float reg r from sslot1 for read
store r->mem[sp+w]
endif
endif
increment count of floats/ints we've pushed</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>pusharg double
<td valign="top"><tt>SlotInfo *src, int idx
<td valign="top">push double actual argument onto func call stack
<pre>call pusharg double
increment argcount </pre>
<td valign="top"><tt>pushf xRC (alpha), fpush xRC (i386)
<td valign="top"><tt>SlotInfo *src (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>required if pusharg double icode insn defined
if arch always uses stack for args
force sslot1 back into slot mem at offset o
emit push mem[o] and mem[o+4]
in arch-specific order
else
if idx<maxArgregs
(there are still regs left)
w=getArgreg(idx)
(might need alignment if arch uses reg pair)
(special code needed
if ints and floats can share regs)
if sslot1 is in double reg
get double reg r from sslot1 for read
if w!=r
spill reg w
emit move reg r into reg w
endif
else
get abs offset o of sslot1 on stack
spill reg w
emit load w<-mem[o]
endif
else
w=stackFrameOffset(idx)
get double reg r from sslot1 for read
store r->mem[sp+w]
endif
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>pusharg long
<td valign="top"><tt>SlotInfo *src, int idx
<td valign="top">push long actual argument onto func call stack
<pre>if pusharg long defined
call pusharg long
increment argcount by ratio of long to int
else
(order of next two insns is arch-dependent)
pusharg int src idx
pusharg int src+1 idx+1
endif</pre>
<td valign="top"><tt>pushl xRC (alpha)
<td valign="top"><tt>SlotInfo *src (sslot1), int idx (sslot2)
<td valign="top"><tt>
<pre>if arch always uses stack for args
if sslot1 is in long reg
get long reg r from sslot0 for read
emit push reg r onto stack
else
get abs offset o of sslot1 on stack
emit push val of mem[o] onto stack
endif
else
if idx<maxArgregs
(there are still regs left)
w=getArgreg(idx)
(might need alignment if arch uses reg pair)
if sslot1 is in long reg
get long reg r from sslot1 for read
if w!=r
spill reg w
emit move reg r into reg w
endif
else
get abs offset o of sslot1 on stack
spill reg w
emit load w<-mem[o]
endif
else
w=stackFrameOffset(idx)
if sslot1 is in long reg
get reg r from sslot1 for read
else
get slot offset r from sslot1 for read
load mem[fp+r] into tmp reg r
endif
store r->mem[sp+w]
endif
endif</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>popargs
<td valign="top">none (global variables argcount & maxPush are implicit)
<td valign="top">pop actual args off call stack after func return
<pre>if argcount is non-zero
if popargs xxC defined
call popargs xxC argcount
endif
if argcount>maxPush
maxPush=argcount
endif
argcount=0
endif</pre>
<td valign="top"><tt>popargs xxC (alpha, i386)
<td valign="top"><tt>int argcount (sslot2)
<td valign="top"><tt>
<pre>(interesting: alpha does nothing here)
get argcount from sslot2
o=argcount*sizeof arg
(a per-arch const)
if stack grows downward
emit add o to stack ptr
else if stack grows upward
emit subtract o from stack ptr
endif
unreserve all reserved argument regs
(using a for loop)
if arg idx>max args
max args=arg idx
endif
set all arg counters to 0
set all special arg pushing flags to 0</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Load and store">Prev</a>]
[<a href="#Function argument management">This</a>]
[<a href="#Control flow changes">Next</a>]
<p><h3 align="center">
<a name="Control flow changes">Control flow changes</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>branch
<td valign="top"><tt>label *dst, int type
<td valign="top">unconditionally or conditionally branch to a label
<pre>branch xCC is required
call branch xCC</pre>
<td valign="top"><tt>branch xCC (alpha, i386)
<td valign="top"><tt>jword dst (sslot1), int type (sslot2)
<td valign="top"><tt>
<pre>required if branch icode insn defined
get label l from sslot1
get int branchtype from sslot2
patch l->type set flags Llong and Lrelative
patch l->at=CODEPC
patch l->from=CODEPC
emit perform unconditional branch
(or optionally emit code to branch based on type
(ba, beq, ble, etc.), leaving branch offset as 0
(offset will be backpatched later)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>cbranch int
<td valign="top"><tt>SlotInfo *s1, SlotInfo *s2, label *dst, int type
<td valign="top">compare two vals and conditionally branch to a label
<pre>if cbranchi xRRLC defined
call cbranchi xRRLC
else
cmp int 0 s1 s2
branch dst type
endif</pre>
<td valign="top"><tt>cbranchi xRRLC (alpha), cbranch RRC (mips)
<td valign="top"><tt>SlotInfo *s1 (sslot1), SlotInfo *s2 (sslot2), jword dst (sslot3), int type (sslot4)
<td valign="top"><tt>
<pre>(branch type cannot be set to unconditional branch)
get label l from sslot1
get int branchtype from sslot2
patch l->type set flags Llong (or Llong21) and
Lrelative (and possibly Lrangecheck)
patch l->at=CODEPC
patch l->from=CODEPC
emit perform a conditional branch based on the type
(ba, beq, ble, etc.), leaving branch offset as 0
(branch offset will be backpatched later)</pre>
<td valign="top">yes (for alpha), no (for all others)
<tr>
<td valign="top"><tt>cbranch offset int
<td valign="top"><tt>SlotInfo *s1, SlotInfo *s2, jint s3, label *dst, int type
<td valign="top">compare two vals and conditionally branch to a label
<pre>if cmp xRR defined
cmp offset int s1 ~type s2[s3]
branch dst type
else
alloc temp slot tmp
load offset int tmp=s2[s3]
cbranch int if s1 ~type tmp branch to dst
dealloc temp slot tmp
endif</pre>
<td valign="top">none
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>cbranch int const
<td valign="top"><tt>SlotInfo *s1, jint val, label *dst, int type
<td valign="top">compare slot with const val and cbranch to a label
<pre>if cbranchi xRCLC defined
cbranchi xRCLC to dst if s1 ~type val
else
alloc temp slot tmp
move int const tmp=val
cbranch int if s1 ~type tmp branch to dst
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>cbranchi xRCLC (alpha), cbranch RRCC (mips)
<td valign="top"><tt>SlotInfo *s1 (sslot1), jint val (sslot2), label *dst (sslot3), int type (sslot4)
<td valign="top"><tt>
<pre>patch l->at to point to CODEPC
patch l->type set flags Llong (or Llong21, etc.) and
Lrelative (and possibly Lrangecheck)
emit compare s1 with val and branch if s1 ~type val
patch l->from to point to CODEPC</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cbranch ref
<td valign="top"><tt>SlotInfo *s1, SlotInfo *s2, label *dst, int type
<td valign="top">compare two vals and conditionally branch to a label
<pre>if cbranchr xRRLC defined
call cbranchr xRRLC
else
cmp ref 0 s1 s2
branch dst type
endif</pre>
<td valign="top"><tt>cbranchr xRRLC (alpha), cbranch RRC (mips)
<td valign="top"><tt>SlotInfo *s1 (sslot1), SlotInfo *s2 (sslot2), jword dst (sslot3), int type (sslot4)
<td valign="top"><tt>
<pre>(branch type cannot be set to unconditional branch)
get label l from sslot1
get int branchtype from sslot2
patch l->type set flags Llong (or Llong21) and
Lrelative (and possibly Lrangecheck)
patch l->at=CODEPC
patch l->from=CODEPC
emit perform conditional branch based on type
(ba, beq, ble, etc.), leaving branch offset as 0
(branch offset will be backpatched later)</pre>
<td valign="top">64-bit arch
<tr>
<td valign="top"><tt>cbranch ref const
<td valign="top"><tt>SlotInfo *s1, void *val, label *dst, int type
<td valign="top">compare slot with const val and cbranch to a label
<pre>if cbranchr xRCLC defined
if val is in range
cbranchr xRCLC
to dst if s1 ~type val
else
alloc temp slot tmp
move ref const tmp=val
cbranch ref
if s1 ~type tmp branch to dst
dealloc temp slot tmp
endif
else
cmp ref const s1 val
branch to dst
if ~type is satisfied
endif</pre>
<td valign="top"><tt>cbranchr xRCLC (alpha), cbranch RRCC (mips)
<td valign="top"><tt>SlotInfo *s1 (sslot1), jint val (sslot2), label *dst (sslot3), int type (sslot4)
<td valign="top"><tt>
<pre>patch l->at to point to CODEPC
patch l->type set flags Llong (or Llong21, etc.) and
Lrelative (and possibly Lrangecheck)
emit compare s1 with val
and branch if s1 ~type val
patch l->from to point to CODEPC</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>branch indirect
<td valign="top"><tt>SlotInfo *dst
<td valign="top">unconditionally branch to a loc specified by dst slot
<pre>if branch indirect xRC defined
call branch indirect xRC
else
load ref dst=mem[dst]
call dst (this looks wrong)
endif</pre>
<td valign="top"><tt>branch indirect xRC (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), int type=branch always (sslot2)
<td valign="top"><tt>
<pre>get dst from sslot1
get type from sslot2
(assert it is branch always)
emit unconditionally indirect branch to dst
(no backpatch is needed)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>call
<td valign="top"><tt>SlotInfo *dst
<td valign="top">call a func whose loc is specified by dst slot
<pre>call xRC is required
call call xRC dst</pre>
<td valign="top"><tt>call xRC (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot1), int type=branch always (sslot2)
<td valign="top"><tt>
<pre>required if call icode insn defined
get dst from sslot1
get type from sslot2
(assert it is branch always)
if particular call and
ret regs are used
may need special code
emit call dst
(no backpatch is needed)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>call indirect method
<td valign="top"><tt>Method *meth
<td valign="top">this is a trampoline insn
<pre>if method already translated
call soft method-native-code
else
ptr=ptr to method native code
if call ind xCC defined
call call ind xCC ptr
branch always
else
alloc temp slot tmp
move ref const tmp=ptr
load ref tmp=mem[tmp]
call tmp
dealloc temp slot tmp
endif
endif</pre>
<td valign="top"><tt>call ind xCC (i386)
<td valign="top"><tt>jword ptr (sslot1), int type=branch always (sslot2)
<td valign="top"><tt>
<pre>get ptr from sslot1
get type from sslot2
(assert it is branch always)
if particular call and
ret regs are used
may need special code
emit call mem[ptr]
(no backpatch is needed)</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>call soft
<td valign="top"><tt>void *routine
<td valign="top">call a func whose loc is specified by dst slot
<pre>if call soft xCC defined
create new label l
of type abs and external
make l point to the routine
call soft l branch-always
else if call ref defined
create a new label l
of type external
make l point to the routine
call ref l branch-always
else
create a new label l
of type const
make a new ref const c
point to routine
make label l point to c
alloc temp slot tmp
if ld RxL defined (only on mips)
call ld RxL tmp=mem[l]
else
move label const tmp=l
load ref tmp=mem[tmp]
endif
call tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>call soft xCC (alpha)
<td valign="top"><tt>label *l (sslot1), int type=branch always (sslot2)
<td valign="top"><tt>
<pre>required if call icode insn defined
get l from sslot1
get type from sslot2
(assert it is branch always)
patch label l->to to point to c
patch label l->at to point to CODEPC
patch l->type to be const,
relative, long and rangecheck
emit dereference and call c</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>ret
<td valign="top">none
<td valign="top">return from a func call with no ret val expected
<pre>ret xxx is required
call ret xxx</pre>
<td valign="top"><tt>ret xxx (alpha, i386)
<td valign="top">none
<td valign="top"><tt>emit the arch-specific ret insn
<td valign="top">yes
<tr>
<td valign="top"><tt>return int
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put int ret val in the proper place for a return
<pre>returni Rxx is required
call returni Rxx</pre>
<td valign="top"><tt>returni Rxx (alpha), return Rxx (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0)
<td valign="top"><tt>
<pre>if there is specific int ret reg
force val of sslot0 into ret reg
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>return ref
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put ref ret val in the proper place for a ret
<pre>returnr Rxx is required
call returnr Rxx</pre>
<td valign="top"><tt>returnr Rxx (alpha), return Rxx (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0)
<td valign="top"><tt>
<pre>if there is a specific ref ret reg
force val of sslot0 into ret reg
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>return long
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put long ret val in the proper place for a return
<pre>returnl Rxx is required
call returnl Rxx</pre>
<td valign="top"><tt>returnl Rxx (alpha), return Rxx (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0)
<td valign="top"><tt>
<pre>if the arch supports a specific long ret reg
force val of sslot0 into ret reg
else if the arch supports a specific pair of int regs
(the order may be reversed in different arch)
force the val of sslot0 into the 1st ret reg
force the val of sslot0+1 into the 2nd ret reg
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>return float
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put float ret val in the proper place for a return
<pre>returnf Rxx is required
call returnf Rxx</pre>
<td valign="top"><tt>returnf Rxx (alpha), freturn Rxx (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0)
<td valign="top"><tt>
<pre>if arch supports specific float ret reg
force val of sslot0 into ret reg
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>return double
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put double ret val in the proper place for a return
<pre>returnl Rxx is required
call returnl Rxx</pre>
<td valign="top"><tt>returnd Rxx (alpha), freturnl Rxx (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0)
<td valign="top"><tt>
<pre>if arch supports specific double ret reg
force val of sslot0 into ret reg
else if arch supports specific pair of float regs
(order may be reversed in different arch)
force val of sslot0 into 1st ret reg
force val of sslot0+1 into 2nd ret reg
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>returnarg int
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put int ret val in proper place for a return
<pre>returnargi xxR is required
call returnargi xxR</pre>
<td valign="top"><tt>returnargi xxR (alpha), returnarg xxR (i386)
<td valign="top"><tt>SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>if there is specific int ret reg
spill ret reg if necessary
emit force val of sslot2 into ret reg
(might currently be in mem or in reg)
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>returnarg ref
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put ref ret val in the proper place for a return
<pre>returnargr xxR is required
call returnargr xxR</pre>
<td valign="top"><tt>returnargr xxR (alpha), returnarg xxR (i386)
<td valign="top"><tt>SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>if there is a specific ref ret reg
spill ret reg if necessary
emit force val of sslot2 into ret reg
(might currently be in mem or in reg)
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>returnarg long
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put long ret val in the proper place for a return
<pre>returnargl xxR is required
call returnargl xxR</pre>
<td valign="top"><tt>returnargl xxR (alpha, i386)
<td valign="top"><tt>SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>if there is a specific long ret reg
spill ret reg if necessary
emit force val of sslot2 into the ret reg
(might currently be in mem or in reg)
else if arch requires two regs for long ret reg
force sslot2 into reg r1
force sslot2+1 into reg r2
carefully move r1 into the 1st ret reg
(don't overwrite r2)
carefully move r2 into the 2nd ret reg
(don't overwrite r1)
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>returnarg float
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put float ret val in the proper place for a return
<pre>returnargf xxR is required
call returnargf xxR</pre>
<td valign="top"><tt>returnargf xxR (alpha), freturnarg xxR (i386)
<td valign="top"><tt>SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>if there is a specific float ret reg
spill ret reg if necessary
emit force val of sslot2 into the ret reg
(might currently be in mem or in reg)
endif</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>returnarg double
<td valign="top"><tt>SlotInfo *dst
<td valign="top">put double ret val in the proper place for a return
<pre>returnargd xxR is required
call returnargd xxR</pre>
<td valign="top"><tt>returnargd xxR (alpha), freturnargl xxR (i386)
<td valign="top"><tt>SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>if there is a specific double ret reg
spill ret reg if necessary
emit force val of sslot2 into the ret reg
(might currently be in mem or in reg)
else if it requires two regs to returnarg double
force sslot2 into reg r1
force sslot2+1 into reg r2
carefully emit move r1 into 1st ret reg
(don't overwrite r2)
carefully emit move r2 into 2nd ret reg
(don't overwrite r1)
endif</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Function argument management">Prev</a>]
[<a href="#Control flow changes">This</a>]
[<a href="#Labels">Next</a>]
<p><h3 align="center">
<a name="Labels">Labels</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>ref label
<td valign="top"><tt>int32 i, int32 n
<td valign="top">get/create ref label at label-table position n
<pre>if label-table position has a label,
remove it from that label-table position and
return it
else
create it at that label-table position and
return it
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ref code label
<td valign="top"><tt>uintp offset
<td valign="top">create new ref code label pointing to offset of jump
<pre>create a new label l
set l->type to Lcode
set l->to to offset</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ref table label
<td valign="top"><tt>int32 n
<td valign="top"><tt>
<pre>same as ref label
if label-table position has a label,
remove it from that label-table position and
return it
else
create it at that label-table position and
return it
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>stored code label
<td valign="top"><tt>SlotInfo *dst
<td valign="top">return dst
<pre>return dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>table code label
<td valign="top"><tt>SlotInfo *dst
<td valign="top">return dst
<pre>return dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>set label
<td valign="top"><tt>int i (not used), int n (index into label table)
<td valign="top">requires set label xxC
<pre>if label at label-table position n does not exist
create it with type Linternal
call set label xxC labtab[n]
else
assert label-table position n has type Lnull
set its type to Linternal
call set label xxC
remove label-table position n from the label table
endif</pre>
<td valign="top"><tt>set label xxC (alpha, i386)
<td valign="top"><tt>label *l (sslot2)
<td valign="top"><tt>
<pre>required if set label icode insn defined
patch l->to to point to CODEPC</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>build code ref
<td valign="top"><tt>uint8 *pos (ptr to array of 4 chars), uintp pc
<td valign="top">requires set wordpc xxC
<pre>convert pos (array of 4-byte in arch-specific order)
into a jint offset
create a ref code label l from pc+offset
call set wordpc xxC with label l
return l</pre>
<td valign="top"><tt>set wordpc xxC (alpha, i386)
<td valign="top"><tt>label *l (sslot2)
<td valign="top"><tt>
<pre>required if build code ref icode insn defined
get l from sslot2
patch l->at to point to CODEPC
patch l->type to add types (Lrelative or Labs) and
Llong and possibly Lrangecheck (alpha)
patch l->from to either point to 0 or to CODEPC
emit 0 32-bit word
(will be backpatched later)</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>build key
<td valign="top"><tt>uint8 *pos (ptr to array of 4 chars)
<td valign="top">requires set word xxC
<pre>convert pos (array of 4-byte in arch-specific order)
into a jint val
call set word xxC with jint val</pre>
<td valign="top"><tt>set word xxC (alpha, i386)
<td valign="top"><tt>jint val (sslot2)
<td valign="top"><tt>
<pre>required if build key icode insn defined
get val from sslot2
emit val in a 32-bit word
(some appear to emit 8 digits?)</pre>
<td valign="top">yes
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Control flow changes">Prev</a>]
[<a href="#Labels">This</a>]
[<a href="#Comparisons">Next</a>]
<p><h3 align="center">
<a name="Comparisons">Comparisons</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>cmp int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing src and src2
<pre>requires cmp xRR
if src2 is a const
cmp int const(dst, src, src2)
else
cmp RRR(dst, src, src2)
endif</pre>
<td valign="top"><tt>cmp xRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
dst is usually ignored
emit cmp src & src2</pre>
<td valign="top">yes (not for alpha)
<tr>
<td valign="top"><tt>cmp int const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">compare int slot with const
<pre>if cmp xRC defined and
val is in range
call cmp xRC src val
else
alloc temp slot tmp
move int const tmp=val
cmp xRR dst src tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>cmp xRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint val (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into reg for read
get val from sslot2
dst is usually ignored
emit cmp src & val</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmp offset int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2, jint offset
<td valign="top">compare int slot with a const
<pre>if cmp xRRC defined and
val is in range
call cmp xRRC
dst src src2 offset
else if cmp xRR if defined
alloc temp slot tmp
load offset int
tmp src2[offset]
cmp xRR dst src tmp
dealloc temp slot tmp
else
abort
endif</pre>
<td valign="top"><tt>cmp xRRC (i386 only)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot1), jint offset (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
get offset from sslot3
dst is usually ignored
emit cmp src and src2[offset]</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmp ref const
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, jint val
<td valign="top">compare int slot with a const
<pre>if cmp xRC defined and
val is in range
call cmp xRC src val
else
alloc temp slot tmp
move ref const tmp=val
cmp xRR dst src tmp
dealloc temp slot tmp
endif</pre>
<td valign="top"><tt>cmp xRC (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), jref val (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into reg for read
get val from sslot2
dst is usually ignored
emit cmp src and val</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmp ref
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing src with src2
<pre>requires cmp xRR
if src is a const
(this assumes we only check ptr inequality)
cmp ref const(dst, src2, src)
else if src2 is a const
cmp ref const(dst, src, src2)
else
cmp RRR(dst, src, src2)
endif</pre>
<td valign="top"><tt>cmp xRR (i386)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into reg for read
get src2 from sslot2 into reg for read
dst is usually ignored
emit cmp src and src2</pre>
<td valign="top">yes (not for alpha)
<tr>
<td valign="top"><tt>lcmp
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing long src with long src2
<pre>requires cmpl RRR
if cmpl RRR defined
call cmpl RRR dst src src2
else
begin func synchronization (spill)
pusharg long src & src2
in arch-specific order,
accounting for size ratio
between long and int
call soft soft lcmp
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>cmpl RRR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into long reg for read
get src2 from sslot2 into long reg for read
alloc int reg for write to dst
emit cmp long src and src2
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmpl float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing float src<float src2
<pre>requires fcmpl RRR
if fcmpl RRR defined
call fcmpl RRR
dst src src2
else
begin func synchronization (spill)
pusharg float src and src2
in arch-specific order,
accounting for size ratio
between float and int, if any
call soft soft fcmpl
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>fcmpl RRR (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc int reg for write to dst
emit cmp float src<src2
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmpl double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing double src<float src2
<pre>requires dcmpl RRR
if dcmpl RRR defined
call dcmpl RRR
dst src src2
else
begin func synchronization (spill)
pusharg double src and src2
in arch-specific order,
accounting for size ratio
between double and int, if any
call soft soft fcmpl
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>dcmpl RRR (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into double reg for read
get src2 from sslot2 into double reg for read
alloc int reg for write to dst
emit cmp double src<src2
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmpg float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing float src>float src2
<pre>requires fcmpg RRR
if fcmpg RRR defined
call fcmpg RRR
dst src src2
else
begin func synchronization (spill)
pusharg float src and src2
in arch-specific order,
accounting for size ratio
between float and int
call soft soft fcmpl
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>fcmpg RRR (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into float reg for read
get src2 from sslot2 into float reg for read
alloc int reg for write to dst
emit cmp float src<src2
emit store result in dst</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cmpg double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src, SlotInfo *src2
<td valign="top">dst=result of comparing double src>float src2
<pre>requires dcmpg RRR
if dcmpg RRR defined
call dcmpg RRR
dst src src2
else
begin func synchronization (spill)
pusharg double src and src2
in arch-specific order,
accounting for size ratio
between double and int
call soft soft fcmpl
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>dcmpg RRR (nowhere defined)
<td valign="top"><tt>SlotInfo *dst (sslot0) SlotInfo *src (sslot1), SlotInfo *src2 (sslot2)
<td valign="top"><tt>
<pre>get src from sslot1 into double reg for read
get src2 from sslot2 into double reg for read
alloc int reg for write to dst
emit cmp double src<src2
emit store result in dst</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Labels">Prev</a>]
[<a href="#Comparisons">This</a>]
[<a href="#Conversions">Next</a>]
<p><h3 align="center">
<a name="Conversions">Conversions</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>cvt int long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert int to long
<pre>if cvtil RxR defined
call cvtil RxR dst src
else
move int LSLOT(dst)=src
ashr int const HSLOT(dst)=
src>>((8*sizeof(jint))-1)
(this shift sign-extends dst)
endif</pre>
<td valign="top"><tt>cvtil RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into int reg r for read
alloc long reg w for write to dst sslot0
emit copy r into w
(and sign-extend w in high bits)</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt int float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert int to float
<pre>if cvtif RxR defined
call cvtif RxR dst src
else
begin func synchronization (spill)
pusharg int src
call soft soft cvtif
popargs
end func synchronization (reload)
return float dst
endif</pre>
<td valign="top"><tt>cvtif RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into int reg r for read
alloc float reg w for write to dst sslot0
emit convert r into float
emit store it in w</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>cvt int double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert int to double
<pre>if cvtid RxR defined
call cvtid RxR dst src
else
begin func synchronization (spill)
pusharg int src
call soft soft cvtid
popargs
end func synchronization (reload)
return double dst
endif</pre>
<td valign="top"><tt>cvtid RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into int reg r for read
alloc double reg w for write to dst sslot0
emit convert r into double
emit store it in w</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>cvt long int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert long to int
<pre>move int dst=LSLOT(src)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>cvt long float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top"><tt>convert long to float
<pre>if cvtlf RxR defined
call cvtlf RxR dst src
else
begin func synchronization (spill)
pusharg long src
call soft soft cvtlf
popargs
end func synchronization (reload)
return float dst
endif</pre>
<td valign="top"><tt>cvtlf RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into long reg r for read
alloc float reg w for write to dst sslot0
emit convert r into float
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt long double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert long to double
<pre>if cvtld RxR defined
call cvtld RxR dst src
else
begin func synchronization (spill)
pusharg long src
call soft soft cvtld
popargs
end func synchronization (reload)
return double dst
endif</pre>
<td valign="top"><tt>cvtld RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into long reg r for read
alloc double reg w for write to dst sslot0
emit convert r into double
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt float int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert float to int
<pre>if cvtfi RxR defined
call cvtfi RxR dst src
else
begin func synchronization (spill)
pusharg float src
call soft soft cvtfi
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>cvtfi RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into float reg r for read
alloc int reg w for write to dst sslot0
emit convert r into int
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt float long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert float to long
<pre>if cvtfl RxR defined
call cvtfl RxR dst src
else
func synchronization (spill)
pusharg float src
call soft soft cvtfl
popargs
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>cvtfl RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into float reg r for read
alloc long reg w for write to dst sslot0
emit convert r into long
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt float double
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert float to double
<pre>if cvtfd RxR defined
call cvtfd RxR dst src
else
begin func synchronization (spill)
pusharg float src
call soft soft cvtfd
popargs
end func synchronization (reload)
return double dst
endif</pre>
<td valign="top"><tt>cvtfd RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into float reg r for read
alloc double reg w for write to dst sslot0
emit convert r into double
emit store it in w</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>cvt double int
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert double to int
<pre>if cvtdi RxR defined
call cvtdi RxR dst src
else
begin func synchronization (spill)
pusharg double src
call soft soft cvtdi
popargs
end func synchronization (reload)
return int dst
endif</pre>
<td valign="top"><tt>cvtdi RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into double reg r for read
alloc int reg w for write to dst sslot0
emit convert r into int
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt double long
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert double to long
<pre>if cvtdl RxR defined
call cvtdl RxR dst src
else
begin func synchronization (spill)
pusharg double src
call soft soft cvtdl
popargs
end func synchronization (reload)
return long dst
endif</pre>
<td valign="top"><tt>cvtdl RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into double reg r for read
alloc long reg w for write to dst sslot0
emit convert r into long
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt double float
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert double to float
<pre>if cvtdf RxR defined
call cvtdf RxR dst src
else
begin func synchronization (spill)
pusharg double src
call soft soft cvtdf
popargs
end func synchronization (reload)
return float dst
endif</pre>
<td valign="top"><tt>cvtdf RxR (alpha, i386)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>(some arch may use stack
instead of one or both regs)
get src from sslot2 into double reg r for read
alloc float reg w for write to dst sslot0
emit convert r into float
emit store it in w</pre>
<td valign="top">yes
<tr>
<td valign="top"><tt>cvt int byte
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert int to byte
<pre>if cvtib RxR defined
call cvtib RxR dst src
else
logical shift left dst=
src<<(sizeof(jint)-sizeof(jbyte))
arithmetic shift right dst=
dst<<(sizeof(jint)-sizeof(jbyte))
endif</pre>
<td valign="top"><tt>cvtib RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into int reg r for read
alloc int reg w for write to dst sslot0
emit convert r into byte
emit store it in w</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>cvt int char
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top">convert int to char
<pre>and int const dst=
src & ((1<<8*sizeof(jchar))-1)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">no
<tr>
<td valign="top"><tt>cvt int short
<td valign="top"><tt>SlotInfo *dst, SlotInfo *src
<td valign="top"><tt>convert int to short
<pre>if cvtis RxR defined
call cvtis RxR dst src
else
logical shift left dst=
src<<(sizeof(jint)-sizeof(jshort))
arithmetic shift right dst=
dst<<(sizeof(jint)-sizeof(jshort))
endif</pre>
<td valign="top"><tt>cvtis RxR (alpha)
<td valign="top"><tt>SlotInfo *dst (sslot0), SlotInfo *src (sslot2)
<td valign="top"><tt>
<pre>get src from sslot2 into int reg r for read
alloc int reg w for write to dst sslot0
emit convert r into short
emit store it in w</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Comparisons">Prev</a>]
[<a href="#Conversions">This</a>]
[<a href="#Breakpoints">Next</a>]
<p><h3 align="center">
<a name="Breakpoints">Breakpoints</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>breakpoint
<td valign="top">none
<td valign="top">abort
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Conversions">Prev</a>]
[<a href="#Breakpoints">This</a>]
[<a href="#Build call frame">Next</a>]
<p><h3 align="center">
<a name="Build call frame">Build call frame</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>build call frame
<td valign="top"><tt>
<pre>Utf8Const *sig
(JVM bytecode signature for current method),
the method signature looks as follows:
'(<argument types>)<return type>'
Individual argument types or
return types are as follows:
'Z' means boolean
'B' means byte
'C' means char
'S' means short
'I' means int
'L<fullclassname>;'
'[<type>' means array type
(one '[' for each dimension of array)
'F' means float
'D' means double
'J' means long
SlotInfo *obj
(ptr to slot holding obj, if existent),
int sp idx
(number of JVM slots needed to hold all args)</pre>
<td valign="top"><tt>
<pre>(this func is called from kaffe-jit.def JVM INVOKEVIRTUAL,
INVOKESPECIAL, INVOKEINTERFACE, and INVOKESTATIC bytecodes)
realloc internal args data structure space to assure room for all args
if obj is not NULL
alloc space for it as the 1st argument
endif
for each type descriptor in method's bytecode signature:
set argtype to the type descriptor
set argument's stack ptr index to current sp idx
decrement sp idx by size indictated by current type descriptor
(1 for ints, etc., and 1 or 2 for doubles and longs)
endfor
if STACK LIMIT defined
alloc space for stack limit at end of argument list
this will allow stack limit to be checked at run-time
endif
for each type descriptor in arg internal data structure signature
(in arch-specific order to push args)
if int datatype (ZBCSI) pusharg int
if ref datatype (L[K) pusharg ref (K is for stack limit)
if float datatype (F) pusharg float
if double datatype (D) pusharg double
if long datatype (L) pusharg long
endfor</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Breakpoints">Prev</a>]
[<a href="#Build call frame">This</a>]
[<a href="#Soft calls">Next</a>]
<p><h3 align="center">
<a name="Soft calls">Soft calls</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>softcall lookupmethod
<td valign="top"><tt>SlotInfo *dst, Method *meth, SlotInfo *obj
<td valign="top">called by JVM INVOKEINTERFACE in kaffe-jit.def
<pre>begin func synchronization (spill)
(push args in arch-specific order)
pusharg ref obj at idx 0
pusharg class const meth->class at idx 1
pusharg ref const meth->idx at idx 2
call soft soft lookupmethod
popargs
end func synchronization (reload)
return ref dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>check array index
<td valign="top"><tt>SlotInfo *obj, SlotInfo *idx
<td valign="top"><tt>
<pre>if no array bounds checking flag is set
return
endif
if HAVE ccall defined
(currently no arch define it)
alloc temp slot tmp
(the following looks like broken code
deref null ptr)
load offset int tmp=
mem[obj+obj array length]
ccall soft int ugt
if tmp>idx throw
arrayIndexOutOfBoundsException
else if (fakecall xxC||fakecall xCC defined) and
can't catch bad array index
(fake call has ret addr different
from where it is called)
cbranch offset int
if idx>=obj+obj array length
make newFakeCall
softBadArrayIndex at current pc
else (can check bad array index)
end sub block
(mark all writes and spill-subBB)
cbranch offset int
if idx<obj+obj array length
goto ref label 1,1
call soft soft badArrayIndex
start sub block
(reload-subBB,
setup slots for BB)
set label 1,1
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>check array store
<td valign="top"><tt>SlotInfo *array, SlotInfo *obj
<td valign="top">check a store into an array
<pre>begin func synchronization (spill)
pusharg array and obj
(@ indexes 0 and 1 respectively)
in arch-specific order
call soft soft checkarraystore
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>check null
<td valign="top"><tt>int x, SlotInfo *obj, int y
<td valign="top">check whether obj is a null ptr
<pre>if arch needs compiler to create null ptr check
if fakecall xxC or fakecall xCC defined and
can't catch any exception
cbranch ref const
if obj==0 to newFakeCall soft nullptr @pc
else
end sub block
(mark all writes and spill-subBB)
cbranch ref const
if obj!=0 goto ref label x,y
softcall nullptr
start sub block
(reload-subBB,
setup slots for BB)
set label x,y
endif
else
if can catch any exception
begin func synchronization (spill)
end func synchronization (reload)
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>check div
<td valign="top"><tt>int x, SlotInfo *obj, int y
<td valign="top">check whether obj is 0
<pre>if arch needs compiler to create null ptr checks
if fakecall xxC or fakecall xCC defined and
can't catch any exception
cbranch ref const
if obj==0 to
newFakeCall soft divzero @pc
else
end sub block
(mark all writes and spill-subBB)
cbranch ref const
if obj!=0 goto ref label x,y
softcall divzero
start sub block
(reload-subBB,
setup slots for BB)
set label x,y
endif
else
if can catch any exception
begin func synchronization (spill)
end func synchronization (reload)
endif
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>check div long
<td valign="top"><tt>int x, SlotInfo *obj, int y
<td valign="top">check whether obj is 0
<pre>if arch needs compiler to create nullptr checks
if fakecall xxC or fakecall xCC defined and
can't catch any exception
cbranch ref const
if LSLOT(obj)==0 to
newFakeCall soft divzero at pc
cbranch ref const
if HSLOT(obj)==0 to
newFakeCall soft divzero at pc
(the above looks like a bug...
should only call if both are 0)
else
end sub block
(mark all writes and spill-subBB)
cbranch ref const
if LSLOT(obj)!=0
goto ref label x,y+0
cbranch ref const
if HSLOT(obj)!=0
goto ref label x,y+1
softcall divzero
start sub block
(reload-subBB,
setup slots for BB)
set label x,y+1
set label x,y+0
endif
else
if can catch any exception
(what differs between this and check div?)
begin BB synchronization (spill)
end BB synchronization (reload)
endif
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ccall ugt
<td valign="top"><tt>SlotInfo *dst
<td valign="top">branch to dst if ugt flag is set
<pre>requires ccall xRC
call ccall xRC dst bugt</pre>
<td valign="top"><tt>ccall xRC (nowhere defined)
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ccall soft ugt
<td valign="top"><tt>void *routine
<td valign="top">call routine if ugt flag is set
<pre>create a new label l
create new ref const c pointing to routine
make l->type be const
make l->to point to c
alloc temp slot tmp
if (load constpool ref defined)
call load constpool ref tmp=mem[mem[l]]
else
move label const tmp=mem[l]
load ref tmp=mem[tmp]
endif
ccall tmp
dealloc temp slot tmp</pre>
<td valign="top"><tt>ccall xRC (nowhere defined)
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ccall soft int ugt
<td valign="top"><tt>SlotInfo* s1, SlotInfo* s2, void* func
<td valign="top">call func if s1<s2
<pre>cmp int s1~s2
ccall soft ugt func</pre>
<td valign="top"><tt>ccall xRC (nowhere defined)
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>ccall int const ugt
<td valign="top"><tt>SlotInfo* s1, jint s2, void* func
<td valign="top">call func if s1<s2
<pre>cmp int const s1~s2
ccall ugt func</pre>
<td valign="top"><tt>ccall xRC (nowhere defined)
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall nullptr
<td valign="top">none
<td valign="top">raise null ptr exception
<pre>if can catch any exception
begin func synchronization (spill)
end func synchronization (reload)
endif
call soft soft nullptr</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall divzero
<td valign="top">none
<td valign="top">raise div by zero exception
<pre>if can catch any exception
begin func synchronization (spill)
end func synchronization (reload)
endif
call soft soft divzero</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall fakecall
<td valign="top"><tt>label* from, label* to, void* func
<td valign="top">perform a fake call
<pre>if fakecall xCC defined
call set label to->to=pc
put from in a const so
it won't be aliases with the others
build a label l to hold the fake call
l->to=constpool-const func
make the fake call,
passing the call label and
the label we got here from
else if fakecall xxC defined
call set label to->to=pc
build a label l to hold the fake call
l->to=func
make the fake call,
passing the call label and
the label we got here from
endif</pre>
<td valign="top"><tt>HAVE fakecall constpool = fakecall xCC (mips), HAVE fakecall = fakecall xCC (i386)
<td valign="top"><tt>HAVE fakecall label *from (sslot1), label *to (sslot2), HAVE fakecall constpool label *to (sslot2)
<td valign="top"><tt>
<pre>HAVE fakecall constpool:
get label *to from sslot2
get label *from from sslot1
patch from->type to include
Lrelative and Llong and from->at=CODEPC
emit load ret addr reg
from some offset in data seg
(0 is emitted for offset,
will backpatch later)
patch to->type to include
Lrelative and Llong and to->at=CODEPC
emit load temp reg t
from another offset in data seg
(a 0 is emitted for actual offset,
will backpatch later)
emit uncond jump to insn at t
(we won't return here, so don't
store the ret addr from this jump)
HAVE fakecall:
get label *to from sslot2
get label *from from sslot1
emit push the return address
backpatch from->type=Llong and
Labs and from->at=CODEPC
(0 is emitted for actual addr,
will backpatch later)
emit jmp to perform Llong and
Lrelative jump to to from CODEPC
(0 is emitted for actual offset,
will backpatch later)</pre>
<td valign="top">no
<tr>
<td valign="top"><tt>softcall nosuchmethod
<td valign="top"><tt>struct Hjava lang Class* cls, Utf8Const* name, Utf8Const* sig
<td valign="top">report that there is no such method in current class
<pre>begin func synchronization (spill)
pusharg cls, name, sig
in arch-specific order
(at indices 0,1,2)
call soft soft nosuchmethod
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall nosuchfield
<td valign="top"><tt>struct Hjava lang Class* cls, Utf8Const* name
<td valign="top">report that there is no such field in current class
<pre>begin func synchronization (spill)
pusharg cls, name
in arch-specific order
(at indices 0,1)
call soft soft nosuchmethod
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall new
<td valign="top"><tt>SlotInfo* dst, Hjava lang Class* classobj
<td valign="top">alloc a new obj and return a ref to it
<pre>begin func synchronization (spill)
pusharg classobj at index 0
call soft soft new
popargs
end func synchronization (reload)
return ref dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall newarray
<td valign="top"><tt>SlotInfo* dst, SlotInfo* size, int type
<td valign="top">alloc new array of primitive objs & return ref to them
<pre>begin func synchronization (spill)
pushargs type and size
(at indices 0,1)
in arch-specific order
call soft soft newarray
popargs
//pop incoming args from stack
pop(1)
end func synchronization (reload)
//make room on stack for the ret val
push(1)
return ref dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall anewarray
<td valign="top"><tt>SlotInfo* dst, SlotInfo*size, Hjava lang Class* type
<td valign="top">alloc new array of arbitrary objs & return ref to them
<pre>begin func synchronization (spill)
pushargs type and size
(at indices 0,1)
in arch-specific order
call soft soft anewarray
popargs
//pop incoming args from stack
pop(1)
end func synchronization (reload)
//make room on stack for ret val
push(1)
return ref dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall multianewarray
<td valign="top"><tt>SlotInfo* dst, int size, SlotInfo* stktop, Hjava lang Class* classobj
<td valign="top">alloc new multi-dim array of arbitrary objs
<pre>begin func synchronization (spill)
pushargs type and size
(at indices 0,1)
in arch-specific order
call soft soft multianewarray
(pushargs may be in reverse
order, but indexes are same)
pusharg the classobj and size
at indices 0,1
for i=0 to size-1 (or from size-1 to 0)
pusharg stacktop[i]
at index 1+size-i
end loop
call soft soft multinewarray
popargs
//pop incoming args from stack
pop(size)
end func synchronization (reload)
//make room on stack for ret val
push(1)
return ref dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall athrow
<td valign="top"><tt>SlotInfo* obj
<td valign="top">throw an exception from obj
<pre>begin func synchronization (spill)
pusharg obj at index 0
call soft soft athrow
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall checkcast
<td valign="top"><tt>SlotInfo* objw (dst), SlotInfo* objr (src), Hjava lang Class* class
<td valign="top">check an obj type cast
<pre>begin func synchronization (spill)
pusharg class, objr
(at indices 0,1)
in arch-specific order
call soft soft checkcast
popargs
end func synchronization (reload)
if (dst!=src)
move ref dst=src
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall instanceof
<td valign="top"><tt>SlotInfo* dst, SlotInfo* obj, Hjava lang Class* class
<td valign="top">dst=(bool) is obj is an instance of type class?
<pre>begin func synchronization (spill)
pusharg class, obj
(at indices 0,1)
in arch-specific order
call soft soft instanceof
popargs
//pop incoming args from stack
pop(1)
end func synchronization (reload)
//make room on stack for ret val
push(1)
return int dst</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall initialise class
<td valign="top"><tt>Hjava lang Class* class
<td valign="top">initialize the class
<pre>if class is not NULL and
it has not been initialized before
begin func synchronization (spill)
pusharg class (at index 0)
call soft soft initialise class
popargs
end func synchronization (reload)
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall debug1
<td valign="top"><tt>void* a0, void* a1, void* a2
<td valign="top">debug func 1
<pre>begin func synchronization (spill)
pushargs a0,a1,a2
(at indices 0,1,2)
in arch-specific order
call soft soft debug1
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall debug2
<td valign="top"><tt>void* a0, void* a1, void* a2
<td valign="top">debug func 2
<pre>begin func synchronization (spill)
pushargs a0,a1,a2
(at indices 0,1,2)
in arch-specific order
call soft soft debug2
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall trace
<td valign="top"><tt>Method *meth
<td valign="top">trace a method
<pre>if get arg ptr defined
alloc temp slot tmp
tmp=get arg ptr
begin func synchronization (spill)
pushargs meth,tmp
(at indices 0,1)
in arch-specific order
call soft soft trace
popargs
end func synchronization (reload)
dealloc temp slot tmp
else
begin func synchronization (spill)
pushargs meth,0
(at indices 0,1)
in arch-specific order
call soft soft trace
popargs
end func synchronization (reload)
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall addref
<td valign="top"><tt>SlotInfo* from, SlotInfo* to
<td valign="top">add ref for incremental garbage collection
<pre>(not supported)
begin func synchronization (spill)
pushargs from,to
(at indices 0,1)
in arch-specific order
call soft soft addreference
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>softcall addreference static
<td valign="top"><tt>SlotInfo* from, SlotInfo* to
<td valign="top">add static ref for incremental garbage collection
<pre>(not supported)
begin func synchronization (spill)
pushargs from,to
(at indices 0,1)
in arch-specific order
call soft soft addreference
popargs
end func synchronization (reload)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>get arg ptr
<td valign="top"><tt>SlotInfo* dst
<td valign="top">get arg ptr
<pre>requires get arg ptr R
call get arg ptr R</pre>
<td valign="top"><tt>get arg ptr R (i386, mips)
<td valign="top"><tt>SlotInfo* dst (sslot0)
<td valign="top"><tt>
<pre>clobber argument regs
(spill them to stack)
alloc ref reg rw for write to dst sslot0
emit move base ptr (or frame ptr) into rw
?emit add rw=rw+4
(looks like bug in i386 debug code)</pre>
<td valign="top">no
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Build call frame">Prev</a>]
[<a href="#Soft calls">This</a>]
[<a href="#BB and instruction management">Next</a>]
<p><h3 align="center">
<a name="BB and instruction management">BB and instruction management</a>
</h3>
<table border>
<thead>
<tr><th><tt>icode insn<th><tt>icode args<th>icode desc/<tt>algorithm<th><tt>func name<th><tt>func args<th><tt>func algorithm<th>func req'd
</thead>
<tbody>
<tr>
<td valign="top"><tt>mark all writes
<td valign="top">none
<td valign="top">mark all slots which have write seqs
<pre>for all slots
if currentslot->list of write sequences exists
currentslot->list of write sequences->referenced=TRUE
endif
end for</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> start sub block
<td valign="top">none
<td valign="top">start sub-block (basically same as start basic-block)
<pre>mask=createSpillMask()
reloadType=ReloadSubbasicBlock
call doReload (mask, reloadType)
setup slots for BB
(init all readseqlists & writeseqlists to empty)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> start basic block
<td valign="top">none
<td valign="top">start basic-block (all regs spilled @BB boundaries)
<pre>mask=createSpillMask()
reloadType=ReloadBasicBlock
call doReload (mask, reloadType)
setup slots for BB
(init all readseqlists & writeseqlists to empty)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> end sub block
<td valign="top">none
<td valign="top"><tt>
<pre>mark all writes()
mask=createSpillMask()
spillType=SpillSubbasicBlock
call doSpill (mask, spillType)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> end basic block
<td valign="top">none
<td valign="top"><tt>
<pre>mark all writes()
mask=createSpillMask()
spillType=SpillBasicBlock
call doSpill (mask, spillType)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> syncregs
<td valign="top"><tt>uintp stk, uintp temp (unused)
<td valign="top">flush reg vals to slots
<pre>mask=createSpillMask()
spillType=SpillSync
call doSpill (mask, spillType)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> start instruction
<td valign="top"><tt>uintp pc
<td valign="top">start a new JVM instruction
<pre>set pc in the instruction's data structure
to the current pc</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt> start exception block
<td valign="top"><tt>uintp stk
<td valign="top">start an exception block
<pre>start BB
call exception prologue
(exception blocks act like func returns--
ret val is exception obj)
return ref &localinfo[stk]</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>begin sync
<td valign="top">none
<td valign="top">begin reg/slot synchronization
<pre>spillMask=0//spill all slots
spillType=spillBasicBlock
doSpill (spillMask, spillType)
set lastSpill=activeSeq (current seq instruction)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>end sync
<td valign="top">none
<td valign="top">end reg/slot synchronization
<pre>//figure out which slots to spill
spillMask=createSpillMask
set lastSpill->...mask=spillMask
(the prev activeSeq points to this)
set lastSpill=0
doSpill (spillMask, spillType)
mark all writes</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>begin func sync
<td valign="top">none
<td valign="top">begin reg/slot synchronization
<pre>spillMask=0//spill all slots
spillType=spillfunc
doSpill (spillMask, spillType)
set lastSpill=activeSeq (current seq instruction)
if this func can throw and catch an exception
mark all writes
endif</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<tr>
<td valign="top"><tt>end func sync
<td valign="top">none
<td valign="top">end reg/slot synchronization
<pre>//build a mask of which slots to reload
mask=createSpillMask
reloadType=reloadfunc
set lastSpill->...mask=mask
(the prev activeSeq points to this)
set lastSpill=NULL
doReload (mask, reloadType)</pre>
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
<td valign="top">n/a
</tbody>
</table>
<p>
[<a href="#Top">Index</a>]
[<a href="#Soft calls">Prev</a>]
[<a href="#BB and instruction management">This</a>]
[<a href="#Appendix A">Next</a>]
<h1 align="center">
<a name="Appendix A">Appendix A -- Important Kaffe JIT files and funcs</a>
</h1>
<p>kaffe/soft.c -- trampoline code
<p>kaffe/icode.c -- arch-independent part of each insn (icode insn)
<p>i386/jit3-icode.h -- icode insn mapped to func name
<p>i386/jit3-i386.def -- arch-specific part of each insn (func name)
<p>slotreg(slot,type,use,idealreg) transforms a slot number into areg, performing the necessary spills and reloads to make this happen
<p>
[<a href="#Top">Index</a>]
[<a href="#BB and instruction management">Prev</a>]
[<a href="#Appendix A">This</a>]
</body></html>
More information about the kaffe
mailing list