home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffevm
/
jit
/
icode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
34KB
|
1,853 lines
/* icode.c
* Define the instructions.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, June 1996.
*/
#include <assert.h>
#include "gtypes.h"
#include "slots.h"
#include "seq.h"
#include "registers.h"
#include "basecode.h"
#include "labels.h"
#include "icode.h"
#include "codeproto.h"
#include "soft.h"
#include "access.h"
#include "object.h"
#include "constants.h"
#include "classMethod.h"
#include "gc.h"
#include "flags.h"
#include "md.h"
void startBlock(sequence*);
void endBlock(sequence*);
extern uint32 pc;
extern uint32 npc;
#define MAXLABTAB 64
label* labtab[MAXLABTAB];
/* ----------------------------------------------------------------------- */
/* Register loads and spills. */
/* */
#if defined(HAVE_spill_int)
void
spill_int(slots* src)
{
void HAVE_spill(sequence*);
sequence s;
seq_dst(&s) = src;
HAVE_spill_int(&s);
src->modified = 0;
}
#endif
#if defined(HAVE_reload_int)
void
reload_int(slots* dst)
{
void HAVE_reload(sequence*);
sequence s;
seq_dst(&s) = dst;
HAVE_reload_int(&s);
}
#endif
#if defined(HAVE_spill_float)
void
spill_float(slots* src)
{
void HAVE_spill(sequence*);
sequence s;
seq_dst(&s) = src;
HAVE_spill_float(&s);
src->modified = 0;
}
#endif
#if defined(HAVE_reload_float)
void
reload_float(slots* dst)
{
void HAVE_reload(sequence*);
sequence s;
seq_dst(&s) = dst;
HAVE_reload_float(&s);
}
#endif
#if defined(HAVE_spill_double)
void
spill_double(slots* src)
{
void HAVE_spill(sequence*);
sequence s;
seq_dst(&s) = src;
HAVE_spill_double(&s);
src->modified = 0;
}
#endif
#if defined(HAVE_reload_double)
void
reload_double(slots* dst)
{
void HAVE_reload(sequence*);
sequence s;
seq_dst(&s) = dst;
HAVE_reload_double(&s);
}
#endif
/* ----------------------------------------------------------------------- */
/* Prologues and epilogues. */
/* */
void
prologue(void)
{
/* Emit prologue code */
slot_slot_slot(0, 0, 0, HAVE_prologue, Tnull);
}
void
epilogue(void)
{
int i;
slot_slot_slot(0, 0, 0, HAVE_epilogue, Tnull);
/* Mark the return slots as used */
markReturns();
/* All slots are now dead - detach them using overwrite */
if (flag_optimise) {
for (i = MAXSLOT - 1; i >= 0; i--) {
overwrite_optimise(slotinfo[i].insn);
}
}
}
/* ----------------------------------------------------------------------- */
/* Conditional monitor management. */
/* */
void
mon_enter(methods* meth, slots* obj)
{
/* Emit monitor entry if required */
if ((meth->accflags & ACC_SYNCHRONISED) != 0) {
end_basic_block();
if ((meth->accflags & ACC_STATIC) != 0) {
pusharg_ref_const((uintp)meth->class);
}
else {
pusharg_ref(obj);
}
call_ref((uintp)soft_monitorenter);
popargs(1);
start_basic_block();
}
}
void
mon_exit(methods* meth, slots* obj)
{
/* Emit monitor exit if required */
if ((meth->accflags & ACC_SYNCHRONISED) != 0) {
end_basic_block();
if ((meth->accflags & ACC_STATIC) != 0) {
pusharg_ref_const((uintp)meth->class);
}
else {
pusharg_ref(obj);
}
call_ref((uintp)soft_monitorexit);
popargs(1);
start_basic_block();
}
}
/* ----------------------------------------------------------------------- */
/* Basic block and instruction management. */
/* */
void
_start_basic_block(uintp pc, uintp stk)
{
int i;
/* Detach all slots from their creating instructions to
* avoid optimising back across the boundary.
*/
if (flag_optimise) {
for (i = MAXSLOT - 1; i >= 0; i--) {
slotinfo[i].insn = 0;
}
}
_slot_const_const(0, stk, pc, startBlock, Tnull);
}
void
_end_basic_block(uintp stk, uintp temp)
{
_slot_const_const(0, stk, temp, endBlock, Tnull);
}
void
_start_instruction(uintp pc)
{
void startInsn(sequence*);
_slot_const_const(0, 0, pc, startInsn, Tnull);
}
void
_start_exception_block(uintp stk)
{
/* Exception blocks act like function returns - the return
* value is the exception object.
*/
return_ref(&stackinfo[stk]);
}
/* ----------------------------------------------------------------------- */
/* Moves. */
/* */
#if defined(HAVE_move_int_const)
void
move_int_const(slots* dst, jint val)
{
slot_slot_const(dst, 0, val, HAVE_move_int_const, Tconst);
dst->v.tint = val;
}
#endif
void
move_long_const(slots* dst, jlong val)
{
#if defined(HAVE_move_long_const)
lslot_slot_lconst(dst, 0, val, HAVE_move_long_const, Tconst);
dst->v.tint = val;
#else
move_int_const(dst, (jint)(val & 0xFFFFFFFF));
move_int_const(dst+1, (jint)((val >> 32) & 0xFFFFFFFF));
#endif
}
#if defined(HAVE_move_float_const)
void
move_float_const(slots* dst, float val)
{
slot_slot_fconst(dst, 0, val, HAVE_move_float_const, Tconst);
dst->v.tdouble = val;
}
#endif
#if defined(HAVE_move_double_const)
void
move_double_const(slots* dst, jdouble val)
{
lslot_slot_fconst(dst, 0, val, HAVE_move_double_const, Tconst);
dst->v.tdouble = val;
}
#endif
#if defined(HAVE_move_int)
void
move_int(slots* dst, slots* src)
{
slot_slot_slot(dst, 0, src, HAVE_move_int, Tcopy);
}
#endif
void
move_long(slots* dst, slots* src)
{
#if defined(HAVE_move_long)
lslot_lslot_lslot(dst, 0, src, HAVE_move_long, Tcopy);
#else
assert(dst != src+1);
move_int(dst, src);
move_int(dst+1, src+1);
#endif
}
#if defined(HAVE_move_float)
void
move_float(slots* dst, slots* src)
{
slot_slot_slot(dst, 0, src, HAVE_move_float, Tcopy);
}
#endif
#if defined(HAVE_move_double)
void
move_double(slots* dst, slots* src)
{
lslot_lslot_lslot(dst, 0, src, HAVE_move_double, Tcopy);
}
#endif
#if defined(HAVE_move_label_const)
void
move_label_const(slots* dst, label* lab)
{
slot_slot_const(dst, 0, (int)lab, HAVE_move_label_const, Tnull);
}
#endif
void
swap_int(slots* src, slots* src2)
{
#if defined(HAVE_swap_int)
slot_slot_slot(src, 0, src2, HAVE_swap_int, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int(tmp, src);
move_int(src, src2);
move_int(src2, tmp);
#endif
}
void
swap_long(slots* src, slots* src2)
{
#if defined(HAVE_swap_long)
lslot_lslot_lslot(src, 0, src2, HAVE_swap_long, Tcomplex);
#else
swap_int(src, src2);
swap_int(src+1, src2+1);
#endif
}
/* ----------------------------------------------------------------------- */
/* Arithmetic operators - add, sub, etc. */
/* */
#if defined(HAVE_adc_int)
void
adc_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_adc_int, Tcomplex);
}
#endif
void
add_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_add_int_const)
slot_slot_const(dst, src, val, HAVE_add_int_const, Taddregconst);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
add_int(dst, src, tmp);
#endif
}
#if defined(HAVE_add_int)
void
add_int(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_add_int_const)
if (slot_type(src2) == Tconst) {
int ival = slot_value(src2);
add_int_const(dst, src, ival);
}
else if (slot_type(src) == Tconst) {
int ival = slot_value(src);
add_int_const(dst, src2, ival);
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_add_int, Tcomplex);
}
}
#endif
void
add_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_add_long)
#if defined(HAVE_add_long_const)
if (slot_type(src2) == Tconst) {
add_long_const(dst, src, slot_value(src2));
}
else if (slot_type(src) == Tconst) {
add_long_const(dst, src2, slot_value(src));
}
else
#endif
{
lslot_lslot_lslot(dst, src, src2, HAVE_add_long, Tcomplex);
}
#else
add_int(dst, src, src2);
adc_int(dst+1, src+1, src2+1);
#endif
}
#if defined(HAVE_add_float)
void
add_float(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_add_float_const)
if (slot_type(src2) == Tconst) {
add_float_const(dst, src, slot_value(src2));
}
else if (slot_type(src) == Tconst) {
add_float_const(dst, src2, slot_value(src));
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_add_float, Tcomplex);
}
}
#endif
#if defined(HAVE_add_double)
void
add_double(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_add_double_const)
if (slot_type(src2) == Tconst) {
add_double_const(dst, src, slot_value(src2));
}
else if (slot_type(src) == Tconst) {
add_double_const(dst, src2, slot_value(src));
}
else
#endif
{
lslot_lslot_lslot(dst, src, src2, HAVE_add_double, Tcomplex);
}
}
#endif
#if defined(HAVE_sbc_int)
void
sbc_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_sbc_int, Tcomplex);
}
#endif
void
sub_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_sub_int_const)
slot_slot_const(dst, src, val, HAVE_sub_int_const, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
sub_int(dst, src, tmp);
#endif
}
#if defined(HAVE_sub_int)
void
sub_int(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_sub_int_const)
if (slot_type(src2) == Tconst) {
int ival = slot_value(src2);
sub_int_const(dst, src, ival);
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_sub_int, Tcomplex);
}
}
#endif
void
sub_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_sub_long)
#if defined(HAVE_sub_long_const)
if (slot_type(src2) == Tconst) {
sub_long_const(dst, src, slot_value(src2));
}
else
#endif
{
lslot_lslot_lslot(dst, src, src2, HAVE_sub_long, Tcomplex);
}
#else
sub_int(dst, src, src2);
sbc_int(dst+1, src+1, src2+1);
#endif
}
#if defined(HAVE_sub_float)
void
sub_float(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_sub_float_const)
if (slot_type(src2) == Tconst) {
sub_float_const(dst, src, slot_value(src2));
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_sub_float, Tcomplex);
}
}
#endif
#if defined(HAVE_sub_double)
void
sub_double(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_sub_double_const)
if (slot_type(src2) == Tconst) {
sub_double_const(dst, src, slot_value(src2));
}
else
#endif
{
lslot_lslot_lslot(dst, src, src2, HAVE_sub_double, Tcomplex);
}
}
#endif
void
mul_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_mul_int_const)
slot_slot_const(dst, src, val, HAVE_mul_int_const, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
mul_int(dst, src, tmp);
#endif
}
#if defined(HAVE_mul_int)
void
mul_int(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_mul_int_const)
if (slot_type(src2) == Tconst) {
mul_int_const(dst, src, slot_value(src2));
}
else if (slot_type(src) == Tconst) {
mul_int_const(dst, src2, slot_value(src));
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_mul_int, Tcomplex);
}
}
#endif
void
mul_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_mul_long)
lslot_lslot_lslot(dst, src, src2, HAVE_mul_long, Tcomplex);
#else
end_basic_block();
pusharg_long(src2);
pusharg_long(src);
call_ref((uintp)soft_lmul);
popargs(4);
start_basic_block();
return_long(dst);
#endif
}
#if defined(HAVE_mul_float)
void
mul_float(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_mul_float, Tcomplex);
}
#endif
#if defined(HAVE_mul_double)
void
mul_double(slots* dst, slots* src, slots* src2)
{
lslot_lslot_lslot(dst, src, src2, HAVE_mul_double, Tcomplex);
}
#endif
#if defined(HAVE_div_int)
void
div_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_div_int, Tcomplex);
}
#endif
void
div_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_div_long)
lslot_lslot_lslot(dst, src, src2, HAVE_div_long, Tcomplex);
#else
end_basic_block();
pusharg_long(src2);
pusharg_long(src);
call_ref((uintp)soft_ldiv);
popargs(4);
start_basic_block();
return_long(dst);
#endif
}
#if defined(HAVE_div_float)
void
div_float(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_div_float, Tcomplex);
}
#endif
#if defined(HAVE_div_double)
void
div_double(slots* dst, slots* src, slots* src2)
{
lslot_lslot_lslot(dst, src, src2, HAVE_div_double, Tcomplex);
}
#endif
#if defined(HAVE_rem_int)
void
rem_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_rem_int, Tcomplex);
}
#endif
void
rem_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_rem_long)
lslot_lslot_lslot(dst, src, src2, HAVE_rem_long, Tcomplex);
#else
end_basic_block();
pusharg_long(src2);
pusharg_long(src);
call_ref((uintp)soft_lrem);
popargs(4);
start_basic_block();
return_long(dst);
#endif
}
void
rem_float(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_rem_float)
slot_slot_slot(dst, src, src2, HAVE_rem_float, Tcomplex);
#else
end_basic_block();
pusharg_float(src2);
pusharg_float(src);
call_ref((uintp)soft_frem);
popargs(2);
end_basic_block();
return_float(dst);
#endif
}
void
rem_double(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_rem_double)
lslot_lslot_lslot(dst, src, src2, HAVE_rem_double, Tcomplex);
#else
end_basic_block();
pusharg_double(src2);
pusharg_double(src);
call_ref((uintp)soft_freml);
popargs(4);
end_basic_block();
return_double(dst);
#endif
}
void
neg_int(slots* dst, slots* src)
{
#if defined(HAVE_neg_int)
slot_slot_slot(dst, 0, src, HAVE_neg_int);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, 0);
sub_int(dst, tmp, src);
#endif
}
void
neg_long(slots* dst, slots* src)
{
#if defined(HAVE_neg_long)
lslot_lslot_lslot(dst, 0, src, HAVE_neg_long);
#elif defined(HAVE_sbc_int)
slots* zero;
slot_alloctmp(zero);
move_int_const(zero, 0);
sub_int(dst, zero, src);
sbc_int(dst+1, zero, src+1);
#elif defined(HAVE_adc_int_const)
neg_int(dst, src);
adc_int_const(dst+1, src+1, 0);
neg_int(dst+1, dst+1);
#else
abort();
#endif
}
void
neg_float(slots* dst, slots* src)
{
#if defined(HAVE_neg_float)
lslot_lslot_lslot(dst, 0, src, HAVE_neg_float);
#else
slots* tmp;
slot_alloctmp(tmp);
move_float_const(tmp, 0);
sub_float(dst, tmp, src);
#endif
}
void
neg_double(slots* dst, slots* src)
{
#if defined(HAVE_neg_double)
lslot_lslot_lslot(dst, 0, src, HAVE_neg_double);
#else
slots* tmp;
slot_alloc2tmp(tmp);
move_double_const(tmp, 0);
sub_double(dst, tmp, src);
#endif
}
/* ----------------------------------------------------------------------- */
/* Logical operators - and, or, etc. */
/* */
void
and_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_and_int_const)
slot_slot_slot(dst, src, src2, HAVE_and_int_val, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
and_int(dst, src, tmp);
#endif
}
#if defined(HAVE_and_int)
void
and_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_and_int, Tcomplex);
}
#endif
void
and_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_and_long)
lslot_lslot_lslot(dst, src, src2, HAVE_and_long, Tcomplex);
#else
and_int(dst, src, src2);
and_int(dst+1, src+1, src2+1);
#endif
}
#if defined(HAVE_or_int)
void
or_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_or_int, Tcomplex);
}
#endif
void
or_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_or_long)
lslot_lslot_lslot(dst, src, src2, HAVE_or_long, Tcomplex);
#else
or_int(dst, src, src2);
or_int(dst+1, src+1, src2+1);
#endif
}
#if defined(HAVE_xor_int)
void
xor_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_xor_int, Tcomplex);
}
#endif
void
xor_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_xor_long)
lslot_lslot_lslot(dst, src, src2, HAVE_xor_long, Tcomplex);
#else
xor_int(dst, src, src2);
xor_int(dst+1, src+1, src2+1);
#endif
}
void
lshl_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_lshl_int_const)
slot_slot_const(dst, src, val, HAVE_lshl_int_const, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
lshl_int(dst, src, tmp);
#endif
}
#if defined(HAVE_lshl_int)
void
lshl_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_lshl_int, Tcomplex);
}
#endif
void
lshl_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_lshl_long)
lslot_lslot_slot(dst, src, src2, HAVE_lshl_long, Tcomplex);
#else
end_basic_block();
pusharg_int(src2);
pusharg_long(src);
call_ref((uintp)soft_lshll);
popargs(3);
start_basic_block();
return_long(dst);
#endif
}
void
ashr_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_ashr_int_const)
slot_slot_slot(dst, src, src2, HAVE_ashr_int_val, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
ashr_int(dst, src, tmp);
#endif
}
#if defined(HAVE_ashr_int)
void
ashr_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_ashr_int, Tcomplex);
}
#endif
void
ashr_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_ashr_long)
lslot_lslot_slot(dst, src, src2, HAVE_ashr_long, Tcomplex);
#else
end_basic_block();
pusharg_int(src2);
pusharg_long(src);
call_ref((uintp)soft_ashrl);
popargs(3);
start_basic_block();
return_long(dst);
#endif
}
void
lshr_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_lshr_int_const)
slot_slot_slot(dst, src, src2, HAVE_lshr_int_val, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
lshr_int(dst, src, tmp);
#endif
}
#if defined(HAVE_lshr_int)
void
lshr_int(slots* dst, slots* src, slots* src2)
{
slot_slot_slot(dst, src, src2, HAVE_lshr_int, Tcomplex);
}
#endif
void
lshr_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_lshr_long)
lslot_lslot_slot(dst, src, src2, HAVE_lshr_long, Tcomplex);
#else
end_basic_block();
pusharg_int(src2);
pusharg_long(src);
call_ref((uintp)soft_lshrl);
popargs(3);
start_basic_block();
return_long(dst);
#endif
}
/* ----------------------------------------------------------------------- */
/* Load and store. */
/* */
#if defined(HAVE_load_int)
void
load_int(slots* dst, slots* src)
{
#if defined(HAVE_load_int_addregconst)
if (src == dst && slot_type(src) == Taddregconst) {
slots* isrc = seq_slot(slot_insn(src), 1);
int ival = seq_value(slot_insn(src), 2);
slot_pop(src);
slot_slot_const(dst, isrc, ival, HAVE_load_int_addregconst, Tload);
}
else
#endif
{
slot_slot_slot(dst, 0, src, HAVE_load_int, Tload);
}
}
#endif
void
load_long(slots* dst, slots* src)
{
#if defined(HAVE_load_long)
lslot_lslot_lslot(dst, 0, src, HAVE_load_long, Tload);
#else
slots* tmp;
slot_alloctmp(tmp);
add_int_const(tmp, src, 4);
load_int(dst, src);
load_int(dst+1, tmp);
#endif
}
#if defined(HAVE_load_float)
void
load_float(slots* dst, slots* src)
{
slot_slot_slot(dst, 0, src, HAVE_load_float, Tload);
}
#endif
#if defined(HAVE_load_double)
void
load_double(slots* dst, slots* src)
{
lslot_lslot_slot(dst, 0, src, HAVE_load_double, Tload);
}
#endif
void
load_byte(slots* dst, slots* src)
{
#if defined(HAVE_load_byte)
slot_slot_slot(dst, 0, src, HAVE_load_byte, Tload);
#else
load_int(dst, src);
lshl_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jbyte)));
ashr_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jbyte)));
#endif
}
void
load_char(slots* dst, slots* src)
{
#if defined(HAVE_load_char)
slot_slot_slot(dst, 0, src, HAVE_load_char, Tload);
#else
load_int(dst, src);
and_int_const(dst, dst, (1 << (8 * sizeof(jchar))) - 1);
#endif
}
void
load_short(slots* dst, slots* src)
{
#if defined(HAVE_load_short)
slot_slot_slot(dst, 0, src, HAVE_load_short, Tload);
#else
load_int(dst, src);
lshl_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jshort)));
ashr_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jshort)));
#endif
}
void
load_code_ref(slots* dst, slots* src)
{
load_ref(dst, src);
}
void
load_key(slots* dst, slots* src)
{
load_int(dst, src);
}
#if defined(HAVE_store_int)
void
store_int(slots* dst, slots* src)
{
#if defined(HAVE_store_int_addregconst)
if (src == dst && slot_type(dst) == Taddregconst) {
assert(slot_ref(dst) == 1);
slot_slot_const(0, dst, src, HAVE_store_int_addregconst, Tstore);
slot_ref(dst) = 0;
slot_insn(dst) = 0;
}
else
#endif
{
slot_slot_slot(0, dst, src, HAVE_store_int, Tstore);
}
}
#endif
void
store_long(slots* dst, slots* src)
{
#if defined(HAVE_store_long)
lslot_lslot_lslot(0, dst, src, HAVE_store_long, Tstore);
#else
slots* tmp;
slot_alloctmp(tmp);
add_int_const(tmp, dst, 4);
store_int(dst, src);
store_int(tmp, src+1);
#endif
}
#if defined(HAVE_store_float)
void
store_float(slots* dst, slots* src)
{
slot_slot_slot(0, dst, src, HAVE_store_float, Tstore);
}
#endif
#if defined(HAVE_store_double)
void
store_double(slots* dst, slots* src)
{
slot_slot_lslot(0, dst, src, HAVE_store_double, Tstore);
}
#endif
void
store_byte(slots* dst, slots* src)
{
#if defined(HAVE_store_byte)
slot_slot_slot(0, dst, src, HAVE_store_byte, Tstore);
#else
slots* tmp;
slots* tmp2;
slot_alloctmp(tmp);
slot_alloctmp(tmp2);
and_int_const(tmp, src, (1 << (8 * sizeof(jbyte))) - 1);
load_int(tmp2, dst);
and_int_const(tmp2, tmp2, -(1 << (8 * sizeof(jbyte))));
or_int(tmp2, tmp2, tmp);
store_int(dst, tmp2);
#endif
}
void
store_char(slots* dst, slots* src)
{
#if defined(HAVE_store_char)
slot_slot_slot(0, dst, src, HAVE_store_char, Tstore);
#else
slots* tmp;
slots* tmp2;
slot_alloctmp(tmp);
slot_alloctmp(tmp2);
and_int_const(tmp, src, (1 << (8 * sizeof(jchar))) - 1);
load_int(tmp2, dst);
and_int_const(tmp2, tmp2, -(1 << (8 * sizeof(jchar))));
or_int(tmp2, tmp2, tmp);
store_int(dst, tmp2);
#endif
}
void
store_short(slots* dst, slots* src)
{
#if defined(HAVE_store_short)
slot_slot_slot(0, dst, src, HAVE_store_short, Tstore);
#else
slots* tmp;
slots* tmp2;
slot_alloctmp(tmp);
slot_alloctmp(tmp2);
and_int_const(tmp, src, (1 << (8 * sizeof(jshort))) - 1);
load_int(tmp2, dst);
and_int_const(tmp2, tmp2, -(1 << (8 * sizeof(jshort))));
or_int(tmp2, tmp2, tmp);
store_int(dst, tmp2);
#endif
}
/* ----------------------------------------------------------------------- */
/* Function argument management. */
/* */
void
pusharg_int_const(int val)
{
#if defined(HAVE_pusharg_int_const)
slot_slot_const(0, 0, val, HAVE_pusharg_int_const, Tnull);
argcount++;
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
pusharg_int(tmp);
#endif
}
#if defined(HAVE_pusharg_int)
void
pusharg_int(slots* src)
{
#if defined(HAVE_pusharg_int_const)
if (slot_type(src) == Tconst) {
int ival = slot_value(src);
/* This shouldn't be necessary - but it is for now */
slot_pop(src);
pusharg_int_const(ival);
}
else
#endif
{
slot_slot_slot(0, 0, src, HAVE_pusharg_int, Tnull);
argcount += 1;
}
}
#endif
#if defined(HAVE_pusharg_float)
void
pusharg_float(slots* src)
{
slot_slot_slot(0, 0, src, HAVE_pusharg_float, Tnull);
argcount += 1;
}
#endif
#if defined(HAVE_pusharg_double)
void
pusharg_double(slots* src)
{
lslot_lslot_lslot(0, 0, src, HAVE_pusharg_double, Tnull);
argcount += 2;
}
#endif
void
pusharg_long(slots* src)
{
#if defined(HAVE_pusharg_long)
lslot_lslot_lslot(0, 0, src, HAVE_pusharg_long, Tnull);
argcount += 2;
#else
pusharg_int(src+1);
pusharg_int(src);
#endif
}
#if defined(HAVE_popargs)
void
popargs(int args)
{
slot_slot_const(0, 0, argcount, HAVE_popargs, Tnull);
argcount = 0;
}
#endif
/* ----------------------------------------------------------------------- */
/* Control flow changes. */
/* */
#if defined(HAVE_branch)
#define branch_a(l) branch(l, ba)
#define branch_eq(l) branch(l, beq)
#define branch_ne(l) branch(l, bne)
#define branch_lt(l) branch(l, blt)
#define branch_le(l) branch(l, ble)
#define branch_gt(l) branch(l, bgt)
#define branch_ge(l) branch(l, bge)
void
branch(label* dst, int type)
{
slot_const_const(0, (int)dst, type, HAVE_branch, Tnull);
}
#endif
#if defined(HAVE_branch_indirect)
void
branch_indirect(slots* dst)
{
slot_slot_const(0, dst, ba, HAVE_branch_indirect, Tnull);
}
#endif
#if defined(HAVE_call_ref)
void
call_ref(uintp routine)
{
label* l = nextLabel();
l->to = routine; /* What place does it goto */
l->type = Labsolute|Lexternal;
l->at = 0;
l->from = 0;
slot_const_const(0, (int)l, ba, HAVE_call_ref, Tnull);
}
#endif
#if defined(HAVE_call)
void
call(slots* dst)
{
slot_slot_const(0, dst, ba, HAVE_call, Tnull);
}
#endif
#if defined(HAVE_ret)
void
ret(void)
{
slot_slot_slot(0, 0, 0, HAVE_ret, Tnull);
}
#endif
#if defined(HAVE_return_int)
void
return_int(slots* dst)
{
slot_slot_slot(dst, 0, 0, HAVE_return_int, Tnull);
}
#endif
#if defined(HAVE_return_long)
void
return_long(slots* dst)
{
lslot_lslot_lslot(dst, 0, 0, HAVE_return_long, Tnull);
}
#endif
#if defined(HAVE_return_float)
void
return_float(slots* dst)
{
slot_slot_slot(dst, 0, 0, HAVE_return_float, Tnull);
}
#endif
#if defined(HAVE_return_double)
void
return_double(slots* dst)
{
lslot_lslot_lslot(dst, 0, 0, HAVE_return_double, Tnull);
}
#endif
/* ----------------------------------------------------------------------- */
/* Labels. */
/* */
label*
reference_label(int32 n)
{
label* l;
assert(n < MAXLABTAB);
if (labtab[n] == 0) {
l = nextLabel();
labtab[n] = l;
l->type = Lnull;
l->at = 0;
l->from = 0;
l->to = 0;
}
else {
l = labtab[n];
labtab[n] = 0;
}
return (l);
}
label*
reference_code_label(int32 offset)
{
label* l = nextLabel();
l->at = 0; /* Where is the jump */
l->to = offset; /* What place does it goto */
l->from = 0;
l->type = Lcode|Linternal;
return (l);
}
label*
reference_table_label(int32 n)
{
label* l;
assert(n < MAXLABTAB);
if (labtab[n] == 0) {
l = nextLabel();
labtab[n] = l;
l->type = Lnull;
l->at = 0;
l->from = 0;
l->to = 0;
}
else {
l = labtab[n];
labtab[n] = 0;
}
return (l);
}
slots*
stored_code_label(slots* dst)
{
return (dst);
}
slots*
table_code_label(slots* dst)
{
return (dst);
}
#if defined(HAVE_set_label)
void
set_label(int n)
{
assert(n < MAXLABTAB);
if (labtab[n] == 0) {
labtab[n] = nextLabel();
labtab[n]->type = Lgeneral|Linternal;
labtab[n]->at = 0;
labtab[n]->from = 0;
labtab[n]->to = 0;
slot_slot_const(0, 0, (int)labtab[n], HAVE_set_label, Tnull);
}
else {
assert(labtab[n]->type == Lnull);
labtab[n]->type = Lgeneral|Linternal;
slot_slot_const(0, 0, (int)labtab[n], HAVE_set_label, Tnull);
labtab[n] = 0;
}
}
#endif
#if defined(HAVE_build_code_ref)
label*
build_code_ref(uint8* pos, uintp pc)
{
label* l;
int offset;
offset = (int32)(pos[0] * 0x01000000 + pos[1] * 0x00010000 +
pos[2] * 0x00000100 + pos[3] * 0x00000001);
l = reference_code_label(pc+offset);
slot_slot_const(0, 0, (int)l, HAVE_build_code_ref, Tnull);
return (l);
}
#endif
#if defined(HAVE_build_key)
void
build_key(uint8* pos)
{
jint val = pos[0] * 0x01000000 + pos[1] * 0x00010000 +
pos[2] * 0x00000100 + pos[3] * 0x00000001;
slot_slot_const(0, 0, val, HAVE_build_key, Tnull);
}
#endif
/* ----------------------------------------------------------------------- */
/* Comparisons. */
/* */
void
cmp_int_const(slots* dst, slots* src, jint val)
{
#if defined(HAVE_cmp_int_const)
slot_slot_const(dst, src, val, HAVE_cmp_int_const, Tcomplex);
#else
slots* tmp;
slot_alloctmp(tmp);
move_int_const(tmp, val);
cmp_int(dst, src, tmp);
#endif
}
#if defined(HAVE_cmp_int)
void
cmp_int(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmp_int_const)
if (slot_type(src2) == Tconst) {
int ival = slot_value(src2);
cmp_int_const(dst, src, ival);
}
else
#endif
{
slot_slot_slot(dst, src, src2, HAVE_cmp_int, Tcomplex);
}
}
#endif
void
cmp_long(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmp_long)
lslot_lslot_lslot(dst, src, src2, HAVE_cmp_long, Tcomplex);
#else
end_basic_block();
pusharg_long(src2);
pusharg_long(src);
call_ref((uintp)soft_lcmp);
popargs(2);
start_basic_block();
return_int(dst);
#endif
}
void
cmpl_float(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmpl_float)
abort();
#else
end_basic_block();
pusharg_float(src2);
pusharg_float(src);
call_ref((uintp)soft_fcmpl);
popargs(2);
start_basic_block();
return_int(dst);
#endif
}
void
cmpl_double(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmpl_double)
abort();
#else
end_basic_block();
pusharg_double(src2);
pusharg_double(src);
call_ref((uintp)soft_dcmpl);
popargs(4);
start_basic_block();
return_int(dst);
#endif
}
void
cmpg_float(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmpg_float)
abort();
#else
end_basic_block();
pusharg_float(src2);
pusharg_float(src);
call_ref((uintp)soft_fcmpg);
popargs(2);
start_basic_block();
return_int(dst);
#endif
}
void
cmpg_double(slots* dst, slots* src, slots* src2)
{
#if defined(HAVE_cmpg_double)
abort();
#else
end_basic_block();
pusharg_double(src2);
pusharg_double(src);
call_ref((uintp)soft_dcmpg);
popargs(4);
start_basic_block();
return_int(dst);
#endif
}
/* ----------------------------------------------------------------------- */
/* Conversions. */
/* */
void
cvt_int_long(slots* dst, slots* src)
{
#if defined(HAVE_cvt_int_long)
lslot_lslot_slot(dst, 0, src, HAVE_cvt_int_long, Tcomplex);
#else
move_int(dst, src);
ashr_int_const(dst+1, dst, (8 * sizeof(jint)) - 1);
#endif
}
#if defined(HAVE_cvt_int_float)
void
cvt_int_float(slots* dst, slots* src)
{
slot_slot_slot(dst, 0, src, HAVE_cvt_int_float, Tcomplex);
}
#endif
#if defined(HAVE_cvt_int_double)
void
cvt_int_double(slots* dst, slots* src)
{
lslot_lslot_slot(dst, 0, src, HAVE_cvt_int_double, Tcomplex);
}
#endif
void
cvt_long_int(slots* dst, slots* src)
{
move_int(dst, src);
}
#if defined(HAVE_cvt_long_float)
void
cvt_long_float(slots* dst, slots* src)
{
slot_slot_lslot(dst, 0, src, HAVE_cvt_long_float, Tcomplex);
}
#endif
#if defined(HAVE_cvt_long_double)
void
cvt_long_double(slots* dst, slots* src)
{
lslot_lslot_lslot(dst, 0, src, HAVE_cvt_long_double, Tcomplex);
}
#endif
#if defined(HAVE_cvt_float_int)
void
cvt_float_int(slots* dst, slots* src)
{
slot_slot_slot(dst, 0, src, HAVE_cvt_float_int, Tcomplex);
}
#endif
#if defined(HAVE_cvt_float_long)
void
cvt_float_long(slots* dst, slots* src)
{
lslot_lslot_slot(dst, 0, src, HAVE_cvt_float_long, Tcomplex);
}
#endif
#if defined(HAVE_cvt_float_double)
void
cvt_float_double(slots* dst, slots* src)
{
lslot_lslot_slot(dst, 0, src, HAVE_cvt_float_double, Tcomplex);
}
#endif
#if defined(HAVE_cvt_double_int)
void
cvt_double_int(slots* dst, slots* src)
{
slot_slot_lslot(dst, 0, src, HAVE_cvt_double_int, Tcomplex);
}
#endif
#if defined(HAVE_cvt_double_long)
void
cvt_double_long(slots* dst, slots* src)
{
lslot_lslot_lslot(dst, 0, src, HAVE_cvt_double_long, Tcomplex);
}
#endif
#if defined(HAVE_cvt_double_float)
void
cvt_double_float(slots* dst, slots* src)
{
slot_slot_lslot(dst, 0, src, HAVE_cvt_double_float, Tcomplex);
}
#endif
void
cvt_int_byte(slots* dst, slots* src)
{
#if defined(HAVE_cvt_int_byte)
slot_slot_slot(dst, 0, src, HAVE_cvt_int_byte, Tcomplex);
#else
lshl_int_const(dst, src, 8 * (sizeof(jint) - sizeof(jbyte)));
ashr_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jbyte)));
#endif
}
void
cvt_int_char(slots* dst, slots* src)
{
and_int_const(dst, src, (1 << (8 * sizeof(jchar))) - 1);
}
void
cvt_int_short(slots* dst, slots* src)
{
#if defined(HAVE_cvt_int_short)
slot_slot_slot(dst, 0, src, HAVE_cvt_int_short, Tcomplex);
#else
lshl_int_const(dst, src, 8 * (sizeof(jint) - sizeof(jshort)));
ashr_int_const(dst, dst, 8 * (sizeof(jint) - sizeof(jshort)));
#endif
}
/* ----------------------------------------------------------------------- */
/* Breakpoints. */
/* */
void
breakpoint()
{
abort();
}
/* ----------------------------------------------------------------------- */
/* Soft calls. */
/* */
void
softcall_lookupmethod(slots* dst, slots* pair, slots* table)
{
slot_nowriteback(table);
slot_nowriteback(pair);
end_basic_block();
pusharg_ref(pair);
pusharg_ref(table);
call_ref((uintp)soft_lookupmethod);
popargs(2);
start_basic_block();
return_ref(dst);
}
void
softcall_badarrayindex(void)
{
call_ref((uintp)soft_badarrayindex);
}
void
softcall_new(slots* dst, slots* classobj)
{
slot_nowriteback(classobj);
end_basic_block();
pusharg_ref(classobj);
call_ref((uintp)soft_new);
popargs(1);
start_basic_block();
return_ref(dst);
}
void
softcall_newarray(slots* dst, slots* size, int type)
{
slot_nowriteback(size);
end_basic_block();
pusharg_int(size);
pusharg_int_const(type);
call_ref((uintp)soft_newarray);
popargs(2);
start_basic_block();
return_ref(dst);
}
void
softcall_anewarray(slots* dst, slots* size, slots* type)
{
slot_nowriteback(size);
slot_nowriteback(type);
end_basic_block();
pusharg_int(size);
pusharg_ref(type);
call_ref((uintp)soft_anewarray);
popargs(2);
start_basic_block();
return_ref(dst);
}
void
softcall_multianewarray(slots* dst, int size, slots* stktop, slots* classobj)
{
int i;
slot_nowriteback(classobj);
end_basic_block();
for (i = 0; i < size; i++) {
pusharg_int(&stktop[i]);
}
pusharg_int_const(size);
pusharg_ref(classobj);
call_ref((uintp)soft_multianewarray);
popargs(size+2);
start_basic_block();
return_ref(dst);
}
void
softcall_athrow(slots* obj)
{
slot_nowriteback(obj);
end_basic_block();
pusharg_ref(obj);
call_ref((uintp)soft_athrow);
popargs(1);
start_basic_block();
}
void
softcall_checkcast(slots* obj, slots* class)
{
/* Must keep 'obj' */
slot_nowriteback(class);
end_basic_block();
pusharg_ref(obj);
pusharg_ref(class);
call_ref((uintp)soft_checkcast);
popargs(2);
start_basic_block();
}
void
softcall_instanceof(slots* dst, slots* obj, slots* class)
{
slot_nowriteback(obj);
slot_nowriteback(class);
end_basic_block();
pusharg_ref(obj);
pusharg_ref(class);
call_ref((uintp)soft_instanceof);
popargs(2);
start_basic_block();
return_int(dst);
}
void
softcall_monitorenter(slots* mon)
{
slot_nowriteback(mon);
end_basic_block();
pusharg_ref(mon);
call_ref((uintp)soft_monitorenter);
popargs(1);
start_basic_block();
}
void
softcall_monitorexit(slots* mon)
{
slot_nowriteback(mon);
end_basic_block();
pusharg_ref(mon);
call_ref((uintp)soft_monitorexit);
popargs(1);
start_basic_block();
}
#if defined(GC_INCREMENTAL)
void
softcall_addtogc(slots* obj)
{
end_basic_block();
pusharg_ref(obj);
call_ref((uintp)soft_addtogc);
popargs(1);
start_basic_block();
}
#endif