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
/
kaffe.def
< prev
next >
Wrap
Text File
|
1996-09-28
|
48KB
|
3,033 lines
/*
* kaffe.def
* Kaffe instruction definitions.
*
* 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>, May 1996.
*/
define_insn(NOP)
{
/*
* No operation.
*/
}
define_insn(ACONST_NULL)
{
/*
* ... -> ..., 0
*/
push(1);
move_ref_const(stack(0), 0);
}
define_insn(ICONST_M1)
{
/*
* ... -> ..., -1
*/
push(1);
move_int_const(stack(0), -1);
}
define_insn(ICONST_0)
{
/*
* ... -> ..., 0
*/
push(1);
move_int_const(stack(0), 0);
}
define_insn(ICONST_1)
{
/*
* ... -> ..., 1
*/
push(1);
move_int_const(stack(0), 1);
}
define_insn(ICONST_2)
{
/*
* ... -> ..., 2
*/
push(1);
move_int_const(stack(0), 2);
}
define_insn(ICONST_3)
{
/*
* ... -> ..., 3
*/
push(1);
move_int_const(stack(0), 3);
}
define_insn(ICONST_4)
{
/*
* ... -> ..., 4
*/
push(1);
move_int_const(stack(0), 4);
}
define_insn(ICONST_5)
{
/*
* ... -> ..., 5
*/
push(1);
move_int_const(stack(0), 5);
}
define_insn(LCONST_0)
{
/*
* ... -> ..., 0, 0
*/
push(2);
move_long_const(stack(0), 0);
}
define_insn(LCONST_1)
{
/*
* ... -> ..., 0, 1
*/
push(2);
move_long_const(stack(0), 1);
}
define_insn(FCONST_0)
{
/*
* ... -> ..., 0.0
*/
push(1);
move_float_const(stack(0), 0.0);
}
define_insn(FCONST_1)
{
/*
* ... -> ..., 1.0
*/
push(1);
move_float_const(stack(0), 1.0);
}
define_insn(FCONST_2)
{
/*
* ... -> ..., 2.0
*/
push(1);
move_float_const(stack(0), 2.0);
}
define_insn(DCONST_0)
{
/*
* ... -> ..., 0.0
*/
push(2);
move_double_const(stack(0), 0.0);
}
define_insn(DCONST_1)
{
/*
* ... -> ..., 1.0
*/
push(2);
move_double_const(stack(0), 1.0);
}
define_insn(BIPUSH)
{
/*
* ... -> ..., val
*/
low = (int8)getpc(0);
push(1);
move_int_const(stack(0), low);
}
define_insn(SIPUSH)
{
/*
* ... -> ..., val
*/
low = (int16)((getpc(0) << 8) | getpc(1));
push(1);
move_int_const(stack(0), low);
}
define_insn(LDC1)
{
/*
* ... -> ..., const
*/
idx = (uint8)getpc(0);
cnst = constant(idx);
push(1);
move_any(stack(0), cnst);
}
define_insn(LDC2)
{
/*
* ... -> ..., const
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
cnst = constant(idx);
push(1);
move_any(stack(0), cnst);
}
define_insn(LDC2W)
{
/*
* ... -> ..., long const
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
cnst = constant_long(idx);
push(2);
move_anylong(stack(0), cnst);
}
define_insn(ILOAD)
{
/*
* ..., -> ..., local variable
*/
idx = wide + (uint8)getpc(0);
check_local_int(idx);
push(1);
move_int(stack(0), local(idx));
wide = 0;
}
define_insn(LLOAD)
{
/*
* ..., -> ..., long local variable
*/
idx = wide + (uint8)getpc(0);
check_local_long(idx+1);
push(2);
move_long(stack(0), local_long(idx));
wide = 0;
}
define_insn(FLOAD)
{
/*
* ..., -> ..., local variable
*/
idx = wide + (uint8)getpc(0);
check_local_float(idx);
push(1);
move_float(stack(0), local_float(idx));
wide = 0;
}
define_insn(DLOAD)
{
/*
* ..., -> ..., long local variable
*/
idx = wide + (uint8)getpc(0);
check_local_double(idx+1);
push(2);
move_double(stack(0), local_double(idx));
wide = 0;
}
define_insn(ALOAD)
{
/*
* ..., -> ..., local variable
*/
idx = wide + (uint8)getpc(0);
check_local_ref(idx);
push(1);
move_ref(stack(0), local(idx));
wide = 0;
}
define_insn(ILOAD_0)
{
/*
* ..., -> ..., local variable
*/
check_local_int(0);
push(1);
move_int(stack(0), local(0));
}
define_insn(ILOAD_1)
{
/*
* ..., -> ..., local variable
*/
check_local_int(1);
push(1);
move_int(stack(0), local(1));
}
define_insn(ILOAD_2)
{
/*
* ..., -> ..., local variable
*/
check_local_int(2);
push(1);
move_int(stack(0), local(2));
}
define_insn(ILOAD_3)
{
/*
* ..., -> ..., local variable
*/
check_local_int(3);
push(1);
move_int(stack(0), local(3));
}
define_insn(LLOAD_0)
{
/*
* ..., -> ..., local variable
*/
check_local_long(0+1);
push(2);
move_long(stack(0), local_long(0));
}
define_insn(LLOAD_1)
{
/*
* ..., -> ..., local variable
*/
check_local_long(1+1);
push(2);
move_long(stack(0), local_long(1));
}
define_insn(LLOAD_2)
{
/*
* ..., -> ..., local variable
*/
check_local_long(2+1);
push(2);
move_long(stack(0), local_long(2));
}
define_insn(LLOAD_3)
{
/*
* ..., -> ..., local variable
*/
check_local_long(3+1);
push(2);
move_long(stack(0), local_long(3));
}
define_insn(FLOAD_0)
{
/*
* ..., -> ..., local variable
*/
check_local_float(0);
push(1);
move_float(stack(0), local_float(0));
}
define_insn(FLOAD_1)
{
/*
* ..., -> ..., local variable
*/
check_local_float(1);
push(1);
move_float(stack(0), local_float(1));
}
define_insn(FLOAD_2)
{
/*
* ..., -> ..., local variable
*/
check_local_float(2);
push(1);
move_float(stack(0), local_float(2));
}
define_insn(FLOAD_3)
{
/*
* ..., -> ..., local variable
*/
check_local_float(3);
push(1);
move_float(stack(0), local_float(3));
}
define_insn(DLOAD_0)
{
/*
* ..., -> ..., local variable
*/
check_local_double(0+1);
push(2);
move_double(stack(0), local_double(0));
}
define_insn(DLOAD_1)
{
/*
* ..., -> ..., local variable
*/
check_local_double(1+1);
push(2);
move_double(stack(0), local_double(1));
}
define_insn(DLOAD_2)
{
/*
* ..., -> ..., local variable
*/
check_local_double(2+1);
push(2);
move_double(stack(0), local_double(2));
}
define_insn(DLOAD_3)
{
/*
* ..., -> ..., local variable
*/
check_local_double(3+1);
push(2);
move_double(stack(0), local_double(3));
}
define_insn(ALOAD_0)
{
/*
* ..., -> ..., local variable
*/
check_local_ref(0);
push(1);
move_ref(stack(0), local(0));
}
define_insn(ALOAD_1)
{
/*
* ..., -> ..., local variable
*/
check_local_ref(1);
push(1);
move_ref(stack(0), local(1));
}
define_insn(ALOAD_2)
{
/*
* ..., -> ..., local variable
*/
check_local_ref(2);
push(1);
move_ref(stack(0), local(2));
}
define_insn(ALOAD_3)
{
/*
* ..., -> ..., local variable
*/
check_local_ref(3);
push(1);
move_ref(stack(0), local(3));
}
define_insn(IALOAD)
{
/*
* ..., array ref, index -> ..., value
*/
check_stack_int(0);
check_stack_intarray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(10));
softcall_badarrayindex();
set_label(10);
lshl_int_const(tmp, stack(0), SHIFT_jint);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_int(stack(1), tmp);
pop(1);
}
define_insn(LALOAD)
{
/*
* ..., array ref, index -> ..., long value
*/
check_stack_int(0);
check_stack_longarray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(11));
softcall_badarrayindex();
set_label(11);
lshl_int_const(tmp, stack(0), SHIFT_jlong);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_long(stack(0), tmp);
}
define_insn(FALOAD)
{
/*
* ..., array ref, index -> ..., float value
*/
check_stack_int(0);
check_stack_floatarray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(12));
softcall_badarrayindex();
set_label(12);
lshl_int_const(tmp, stack(0), SHIFT_jfloat);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_float(stack(1), tmp);
pop(1);
}
define_insn(DALOAD)
{
/*
* ..., array ref, index -> ..., double value
*/
check_stack_int(0);
check_stack_doublearray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(13));
softcall_badarrayindex();
set_label(13);
lshl_int_const(tmp, stack(0), SHIFT_jdouble);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_double(stack(0), tmp);
}
define_insn(AALOAD)
{
/*
* ..., array ref, index -> ..., ref value
*/
check_stack_int(0);
check_stack_refarray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(14));
softcall_badarrayindex();
set_label(14);
lshl_int_const(tmp, stack(0), SHIFT_jref);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_ref(stack(1), tmp);
pop(1);
}
define_insn(BALOAD)
{
/*
* ..., array ref, index -> ..., byte value
*/
check_stack_int(0);
check_stack_bytearray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(15));
softcall_badarrayindex();
set_label(15);
if (SHIFT_jbyte > 0) {
lshl_int_const(tmp, stack(0), SHIFT_jbyte);
}
else {
move_int(tmp, stack(0));
}
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_byte(stack(1), tmp);
pop(1);
}
define_insn(CALOAD)
{
/*
* ..., array ref, index -> ..., char value
*/
check_stack_int(0);
check_stack_chararray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(16));
softcall_badarrayindex();
set_label(16);
if (SHIFT_jchar > 0) {
lshl_int_const(tmp, stack(0), SHIFT_jchar);
}
else {
move_int(tmp, stack(0));
}
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_char(stack(1), tmp);
pop(1);
}
define_insn(SALOAD)
{
/*
* ..., array ref, index -> ..., short value
*/
check_stack_int(0);
check_stack_shortarray(1);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(1));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(0), tmp);
branch_lt(reference_label(17));
softcall_badarrayindex();
set_label(17);
lshl_int_const(tmp, stack(0), SHIFT_jshort);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(1));
load_short(stack(1), tmp);
pop(1);
}
define_insn(ISTORE)
{
/*
* ..., var -> ...
*/
check_stack_int(0);
idx = wide + (uint8)getpc(0);
move_int(local(idx), stack(0));
pop(1);
wide = 0;
}
define_insn(LSTORE)
{
/*
* ..., long var -> ...
*/
check_stack_long(0);
idx = wide + (uint8)getpc(0);
move_long(local_long(idx), stack(0));
pop(2);
wide = 0;
}
define_insn(FSTORE)
{
/*
* ..., var -> ...
*/
check_stack_float(0);
idx = wide + (uint8)getpc(0);
move_float(local_float(idx), stack(0));
pop(1);
wide = 0;
}
define_insn(DSTORE)
{
/*
* ..., var -> ...
*/
check_stack_double(0);
idx = wide + (uint8)getpc(0);
move_double(local_double(idx), stack(0));
pop(2);
wide = 0;
}
define_insn(ASTORE)
{
/*
* ..., var -> ...
*/
check_stack_ref(0);
idx = wide + (uint8)getpc(0);
move_ref(local(idx), stack(0));
pop(1);
wide = 0;
}
define_insn(ISTORE_0)
{
/*
* ..., val -> ...
*/
check_stack_int(0);
move_int(local(0), stack(0));
pop(1);
}
define_insn(ISTORE_1)
{
/*
* ..., val -> ...
*/
check_stack_int(0);
move_int(local(1), stack(0));
pop(1);
}
define_insn(ISTORE_2)
{
/*
* ..., val -> ...
*/
check_stack_int(0);
move_int(local(2), stack(0));
pop(1);
}
define_insn(ISTORE_3)
{
/*
* ..., val -> ...
*/
check_stack_int(0);
move_int(local(3), stack(0));
pop(1);
}
define_insn(LSTORE_0)
{
/*
* ..., long val -> ...
*/
check_stack_long(0);
move_long(local_long(0), stack(0));
pop(2);
}
define_insn(LSTORE_1)
{
/*
* ..., long val -> ...
*/
check_stack_long(0);
move_long(local_long(1), stack(0));
pop(2);
}
define_insn(LSTORE_2)
{
/*
* ..., long val -> ...
*/
check_stack_long(0);
move_long(local_long(2), stack(0));
pop(2);
}
define_insn(LSTORE_3)
{
/*
* ..., long val -> ...
*/
check_stack_long(0);
move_long(local_long(3), stack(0));
pop(2);
}
define_insn(FSTORE_0)
{
/*
* ..., val -> ...
*/
check_stack_float(0);
move_float(local_float(0), stack(0));
pop(1);
}
define_insn(FSTORE_1)
{
/*
* ..., val -> ...
*/
check_stack_float(0);
move_float(local_float(1), stack(0));
pop(1);
}
define_insn(FSTORE_2)
{
/*
* ..., val -> ...
*/
check_stack_float(0);
move_float(local_float(2), stack(0));
pop(1);
}
define_insn(FSTORE_3)
{
/*
* ..., val -> ...
*/
check_stack_float(0);
move_float(local_float(3), stack(0));
pop(1);
}
define_insn(DSTORE_0)
{
/*
* ..., long val -> ...
*/
check_stack_double(0);
move_double(local_double(0), stack(0));
pop(2);
}
define_insn(DSTORE_1)
{
/*
* ..., long val -> ...
*/
check_stack_double(0);
move_double(local_double(1), stack(0));
pop(2);
}
define_insn(DSTORE_2)
{
/*
* ..., long val -> ...
*/
check_stack_double(0);
move_double(local_double(2), stack(0));
pop(2);
}
define_insn(DSTORE_3)
{
/*
* ..., long val -> ...
*/
check_stack_double(0);
move_double(local_double(3), stack(0));
pop(2);
}
define_insn(ASTORE_0)
{
/*
* ..., val -> ...
*/
check_stack_ref(0);
move_ref(local(0), stack(0));
pop(1);
}
define_insn(ASTORE_1)
{
/*
* ..., val -> ...
*/
check_stack_ref(0);
move_ref(local(1), stack(0));
pop(1);
}
define_insn(ASTORE_2)
{
/*
* ..., val -> ...
*/
check_stack_ref(0);
move_ref(local(2), stack(0));
pop(1);
}
define_insn(ASTORE_3)
{
/*
* ..., val -> ...
*/
check_stack_ref(0);
move_ref(local(3), stack(0));
pop(1);
}
define_insn(IASTORE)
{
/*
* ..., array ref, index, val -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_intarray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(18));
softcall_badarrayindex();
set_label(18);
lshl_int_const(tmp, stack(1), SHIFT_jint);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_int(tmp, stack(0));
pop(3);
}
define_insn(LASTORE)
{
/*
* ..., array ref, index, long val -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_longarray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(3));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(2), tmp);
branch_lt(reference_label(19));
softcall_badarrayindex();
set_label(19);
lshl_int_const(tmp, stack(2), SHIFT_jlong);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(3));
store_long(tmp, stack(0));
pop(4);
}
define_insn(FASTORE)
{
/*
* ..., array ref, index, float val -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_floatarray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(20));
softcall_badarrayindex();
set_label(20);
lshl_int_const(tmp, stack(1), SHIFT_jfloat);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_float(tmp, stack(0));
pop(3);
}
define_insn(DASTORE)
{
/*
* ..., array ref, index, double val -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_doublearray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(3));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(2), tmp);
branch_lt(reference_label(21));
softcall_badarrayindex();
set_label(21);
lshl_int_const(tmp, stack(2), SHIFT_jdouble);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(3));
store_double(tmp, stack(0));
pop(4);
}
define_insn(AASTORE)
{
/*
* ..., array ref, index, val -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_refarray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(22));
softcall_badarrayindex();
set_label(22);
lshl_int_const(tmp, stack(1), SHIFT_jref);
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_ref(tmp, stack(0));
pop(3);
}
define_insn(BASTORE)
{
/*
* ..., array ref, index, byte value -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_bytearray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(23));
softcall_badarrayindex();
set_label(23);
if (SHIFT_jbyte > 0) {
lshl_int_const(tmp, stack(1), SHIFT_jbyte);
}
else {
move_int(tmp, stack(1));
}
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_byte(tmp, stack(0));
pop(3);
}
define_insn(CASTORE)
{
/*
* ..., array ref, index, char value -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_chararray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(24));
softcall_badarrayindex();
set_label(24);
if (SHIFT_jchar > 0) {
lshl_int_const(tmp, stack(1), SHIFT_jchar);
}
else {
move_int(tmp, stack(1));
}
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_char(tmp, stack(0));
pop(3);
}
define_insn(SASTORE)
{
/*
* ..., array ref, index, short value -> ...
*/
check_stack_int(0);
check_stack_int(1);
check_stack_shortarray(2);
slot_alloctmp(tmp);
/* Check we are within the array bounds */
move_ref(tmp, stack(2));
if (object_array_length != 0) {
add_ref_const(tmp, tmp, object_array_length);
}
load_int(tmp, tmp);
cmp_int(0, stack(1), tmp);
branch_lt(reference_label(25));
softcall_badarrayindex();
set_label(25);
if (SHIFT_jshort > 0) {
lshl_int_const(tmp, stack(1), SHIFT_jshort);
}
else {
move_int(tmp, stack(1));
}
if (object_array_offset != 0) {
add_int_const(tmp, tmp, object_array_offset);
}
add_ref(tmp, tmp, stack(2));
store_short(tmp, stack(0));
pop(3);
}
define_insn(POP)
{
pop(1);
}
define_insn(POP2)
{
pop(2);
}
define_insn(DUP)
{
push(1);
move_any(stack(0), stack(1));
}
define_insn(DUP_X1)
{
push(1);
move_any(stack(0), stack(1));
move_any(stack(1), stack(2));
move_any(stack(2), stack(0));
}
define_insn(DUP_X2)
{
push(1);
move_any(stack(0), stack(1));
move_any(stack(1), stack(2));
move_any(stack(2), stack(3));
move_any(stack(3), stack(0));
}
define_insn(DUP2)
{
push(2);
move_any(stack(0), stack(2));
move_any(stack(1), stack(3));
}
define_insn(DUP2_X1)
{
push(2);
move_any(stack(0), stack(2));
move_any(stack(1), stack(3));
move_any(stack(2), stack(4));
move_any(stack(3), stack(0));
move_any(stack(4), stack(1));
}
define_insn(DUP2_X2)
{
push(2);
move_any(stack(0), stack(2));
move_any(stack(1), stack(3));
move_any(stack(2), stack(4));
move_any(stack(3), stack(5));
move_any(stack(4), stack(0));
move_any(stack(5), stack(1));
}
define_insn(SWAP)
{
/*
* ..., val1, val2 -> ..., val2, val1
*/
swap_int(stack(0), stack(1));
}
define_insn(IADD)
{
/*
* ..., val1, val2 -> ..., val1+val2
*/
check_stack_int(0);
check_stack_int(1);
add_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LADD)
{
/*
* ..., long val1, long val2 -> ..., long val1+val2
*/
check_stack_long(0);
check_stack_long(2);
add_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(FADD)
{
/*
* ..., val1, val2 -> ..., val1+val2
*/
check_stack_float(0);
check_stack_float(1);
add_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DADD)
{
/*
* ..., double val1, long val2 -> ..., double val1+val2
*/
check_stack_double(0);
check_stack_double(2);
add_double(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(ISUB)
{
/*
* ..., val1, val2 -> ..., val1-val2
*/
check_stack_int(0);
check_stack_int(1);
sub_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LSUB)
{
/*
* ..., long val1, long val2 -> ..., long val1-val2
*/
check_stack_long(0);
check_stack_long(2);
sub_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(FSUB)
{
/*
* ..., val1, val2 -> ..., val1-val2
*/
check_stack_float(0);
check_stack_float(1);
sub_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DSUB)
{
/*
* ..., double val1, long val2 -> ..., double val1-val2
*/
check_stack_double(0);
check_stack_double(2);
sub_double(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IMUL)
{
/*
* ..., val1, val2 -> ..., val1*val2
*/
check_stack_int(0);
check_stack_int(1);
mul_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LMUL)
{
/*
* ..., long val1, long val2 -> ..., long val1*val2
*/
check_stack_long(0);
check_stack_long(2);
mul_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(FMUL)
{
/*
* ..., val1, val2 -> ..., val1*val2
*/
check_stack_float(0);
check_stack_float(1);
mul_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DMUL)
{
/*
* ..., double val1, long val2 -> ..., double val1*val2
*/
check_stack_double(0);
check_stack_double(2);
mul_double(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IDIV)
{
/*
* ..., val1, val2 -> ..., val1/val2
*/
check_stack_int(0);
check_stack_int(1);
div_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LDIV)
{
/*
* ..., long val1, long val2 -> ..., long val1/val2
*/
check_stack_long(0);
check_stack_long(2);
div_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(FDIV)
{
/*
* ..., val1, val2 -> ..., val1/val2
*/
check_stack_float(0);
check_stack_float(1);
div_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DDIV)
{
/*
* ..., val1, val2 -> ..., val1/val2
*/
check_stack_double(0);
check_stack_double(2);
div_double(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IREM)
{
/*
* ..., val1, val2 -> ..., val1%val2
*/
check_stack_int(0);
check_stack_int(1);
rem_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LREM)
{
/*
* ..., long val1, long val2 -> ..., long val1%val2
*/
check_stack_long(0);
check_stack_long(2);
rem_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(FREM)
{
/*
* ..., val1, val2 -> ..., val1%val2
*/
check_stack_float(0);
check_stack_float(1);
rem_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DREM)
{
/*
* ..., val1, val2 -> ..., val1%val2
*/
check_stack_double(0);
check_stack_double(2);
rem_double(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(INEG)
{
check_stack_int(0);
neg_int(stack(0), stack(0));
}
define_insn(LNEG)
{
check_stack_long(0);
neg_long(stack(0), stack(0));
}
define_insn(FNEG)
{
check_stack_float(0);
neg_float(stack(0), stack(0));
}
define_insn(DNEG)
{
check_stack_double(0);
neg_double(stack(0), stack(0));
}
define_insn(ISHL)
{
/*
* ..., val1, val2 -> ... val1 << val2
*/
check_stack_int(0);
check_stack_int(1);
lshl_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LSHL)
{
/*
* ..., long val1, val2 -> ... long val1 << val2
*/
check_stack_int(0);
check_stack_long(1);
lshl_long(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(ISHR)
{
/*
* ..., val1, val2 -> ... val1 >> val2
*/
check_stack_int(0);
check_stack_int(1);
ashr_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LSHR)
{
/*
* ..., long val1, val2 -> ... long val1 >> val2
*/
check_stack_int(0);
check_stack_long(1);
ashr_long(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(IUSHR)
{
/*
* ..., val1, val2 -> ... val1 >> val2
*/
check_stack_int(0);
check_stack_int(1);
lshr_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LUSHR)
{
/*
* ..., long val1, val2 -> ... long val1 >> val2
*/
check_stack_int(0);
check_stack_long(1);
lshr_long(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(IAND)
{
/*
* ..., val1, val2 -> ..., val1 & val2
*/
check_stack_int(0);
check_stack_int(1);
and_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LAND)
{
/*
* ..., long val1, long val2 -> ..., long val1 & val2
*/
check_stack_long(0);
check_stack_long(2);
and_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IOR)
{
/*
* ..., val1, val2 -> ..., val1 | val2
*/
check_stack_int(0);
check_stack_int(1);
or_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LOR)
{
/*
* ..., long val1, long val2 -> ..., long val1 | val2
*/
check_stack_long(0);
check_stack_long(2);
or_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IXOR)
{
/*
* ..., val1, val2 -> ..., val1 ^ val2
*/
check_stack_int(0);
check_stack_int(1);
xor_int(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(LXOR)
{
/*
* ..., long val1, long val2 -> ..., long val1 ^ val2
*/
check_stack_long(0);
check_stack_long(2);
xor_long(stack(2), stack(2), stack(0));
pop(2);
}
define_insn(IINC)
{
idx = wide + (uint8)getpc(0);
low = (int8)getpc(1);
check_local_int(idx);
add_int_const(local(idx), local(idx), low);
wide = 0;
}
define_insn(I2L)
{
check_stack_int(0);
push(1);
cvt_int_long(stack(0), stack(1));
}
define_insn(I2F)
{
check_stack_int(0);
cvt_int_float(stack(0), stack(0));
}
define_insn(I2D)
{
check_stack_int(0);
push(1);
cvt_int_double(stack(0), stack(1));
}
define_insn(L2I)
{
check_stack_long(0);
cvt_long_int(stack(1), stack(0));
pop(1);
}
define_insn(L2F)
{
check_stack_long(0);
cvt_long_float(stack(1), stack(0));
pop(1);
}
define_insn(L2D)
{
check_stack_long(0);
cvt_long_double(stack(0), stack(0));
}
define_insn(F2I)
{
check_stack_float(0);
cvt_float_int(stack(0), stack(0));
}
define_insn(F2L)
{
check_stack_float(0);
push(1);
cvt_float_long(stack(0), stack(1));
}
define_insn(F2D)
{
check_stack_float(0);
push(1);
cvt_float_double(stack(0), stack(1));
}
define_insn(D2I)
{
check_stack_double(0);
cvt_double_int(stack(1), stack(0));
pop(1);
}
define_insn(D2L)
{
check_stack_double(0);
cvt_double_long(stack(0), stack(0));
}
define_insn(D2F)
{
check_stack_double(0);
cvt_double_float(stack(1), stack(0));
pop(1);
}
define_insn(INT2BYTE)
{
check_stack_int(0);
cvt_int_byte(stack(0), stack(0));
}
define_insn(INT2CHAR)
{
check_stack_int(0);
cvt_int_char(stack(0), stack(0));
}
define_insn(INT2SHORT)
{
check_stack_int(0);
cvt_int_short(stack(0), stack(0));
}
define_insn(LCMP)
{
/*
* ..., long val1, long val2 -> ..., result
*/
check_stack_long(0);
check_stack_long(2);
cmp_long(stack(3), stack(0), stack(2));
pop(3);
}
define_insn(FCMPL)
{
/*
* ..., float val1, float val2 -> ..., result
*/
check_stack_float(0);
check_stack_float(1);
cmpl_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(FCMPG)
{
/*
* ..., float val1, float val2 -> ..., result
*/
check_stack_float(0);
check_stack_float(1);
cmpg_float(stack(1), stack(1), stack(0));
pop(1);
}
define_insn(DCMPL)
{
/*
* ..., double val1, double val2 -> ..., result
*/
check_stack_double(0);
check_stack_double(2);
cmpl_double(stack(3), stack(2), stack(0));
pop(3);
}
define_insn(DCMPG)
{
/*
* ..., double val1, double val2 -> ..., result
*/
check_stack_double(0);
check_stack_double(2);
cmpg_double(stack(3), stack(2), stack(0));
pop(3);
}
define_insn(IFEQ)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_eq(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFNE)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_ne(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFLT)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_lt(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFGE)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_ge(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFGT)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_gt(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFLE)
{
check_stack_int(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_le(reference_code_label(pc+idx));
pop(1);
}
define_insn(IF_ICMPEQ)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_eq(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ICMPNE)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_ne(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ICMPLT)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_lt(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ICMPGE)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_ge(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ICMPGT)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_gt(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ICMPLE)
{
check_stack_int(0);
check_stack_int(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_int(0, stack(1), stack(0));
branch_le(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ACMPEQ)
{
check_stack_ref(0);
check_stack_ref(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_ref(0, stack(1), stack(0));
branch_eq(reference_code_label(pc+idx));
pop(2);
}
define_insn(IF_ACMPNE)
{
check_stack_ref(0);
check_stack_ref(1);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_ref(0, stack(1), stack(0));
branch_ne(reference_code_label(pc+idx));
pop(2);
}
define_insn(GOTO)
{
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
branch_a(reference_code_label(pc+idx));
}
define_insn(JSR)
{
/*
* ... -> ..., ret-addr
*/
idx = (int16)((getpc(0) << 8) | getpc(1));
push(1);
move_label_const(stack(0), reference_code_label(npc));
end_basic_block();
branch_a(reference_code_label(pc+idx));
}
define_insn(RET)
{
idx = (uint8)getpc(0);
check_local_ref(idx);
end_basic_block();
branch_indirect(stored_code_label(local(idx)));
}
define_insn(TABLESWITCH)
{
/*
* ..., index -> ...
*/
check_stack_int(0);
slot_alloctmp(tmp2);
npc = (pc + 1 + 3) & -4;
low = (int32)((getcode(npc+4) << 24) | (getcode(npc+5) << 16) |
(getcode(npc+6) << 8) | getcode(npc+7));
high = (int32)((getcode(npc+8) << 24) | (getcode(npc+9) << 16) |
(getcode(npc+10) << 8) | getcode(npc+11));
npc = npc + 12;
end_basic_block();
cmp_int_const(0, stack(0), low);
branch_lt(reference_label(8));
if (low != 0) {
start_basic_block();
sub_int_const(stack(0), stack(0), low);
end_basic_block();
}
cmp_int_const(0, stack(0), high-low);
branch_le(reference_label(7));
start_basic_block();
set_label(8);
move_int_const(stack(0), -3); /* Position at default entry */
end_basic_block();
start_basic_block();
set_label(7);
lshl_int_const(stack(0), stack(0), switchtable_shift);
move_label_const(tmp2, reference_table_label(9));
add_ref(stack(0), stack(0), tmp2);
load_code_ref(stack(0), stack(0));
end_basic_block();
branch_indirect(table_code_label(stack(0)));
pop(1);
#if defined(TRANSLATOR)
{
build_code_ref(&getcode(npc-12), pc); /* Default entry */
build_code_ref(&getcode(npc-12), pc); /* Dummy */
build_code_ref(&getcode(npc-12), pc); /* Dummy */
set_label(9);
for (idx = 0; idx < high-low+1; idx++) {
build_code_ref(&getcode(npc + (idx << switchtable_shift)), pc);
}
}
#endif
adjustpc((4 - (pc % 4)) + 12 + (high - low + 1) * 4);
}
define_insn(LOOKUPSWITCH)
{
/*
* ..., key -> ...
*/
check_stack_int(0);
npc = (pc + 1 + 3) & -4;
idx = (int32)((getcode(npc+4) << 24) | (getcode(npc+5) << 16) |
(getcode(npc+6) << 8) | getcode(npc+7));
slot_alloctmp(mtable);
slot_alloctmp(tmp);
slot_alloctmp(tmp2);
move_label_const(tmp2, reference_table_label(7));
move_ref(tmp, tmp2);
add_int_const(tmp, tmp, idx * switchpair_size);
end_basic_block();
set_label(5);
start_basic_block();
load_key(mtable, tmp);
end_basic_block();
cmp_int(0, mtable, stack(0));
branch_eq(reference_label(6));
start_basic_block();
sub_int_const(tmp, tmp, switchpair_size);
end_basic_block();
cmp_int(0, tmp, tmp2);
branch_ne(reference_label(5));
start_basic_block();
sub_int_const(tmp, tmp, switchpair_addr);
end_basic_block();
set_label(6);
start_basic_block();
add_int_const(tmp, tmp, switchpair_addr);
load_code_ref(tmp, tmp);
end_basic_block();
branch_indirect(table_code_label(tmp));
pop(1);
#if defined(TRANSLATOR)
{
set_label(7);
build_code_ref(&getcode(npc), pc);
build_key(&getcode(npc)); /* Dummy key */
for (low = 1; low <= idx; low++) {
build_key(&getcode(npc + (low * switchpair_size)));
build_code_ref(&getcode(npc + (low * switchpair_size) + switchpair_addr), pc);
}
}
#endif
adjustpc((4 - (pc % 4)) + (idx + 1) * 8);
}
define_insn(IRETURN)
{
check_stack_int(0);
monitor_exit();
move_int(returnarg_int(), stack(0));
end_function();
ret();
}
define_insn(LRETURN)
{
check_stack_long(0);
monitor_exit();
move_long(returnarg_long(), stack(0));
end_function();
ret();
}
define_insn(FRETURN)
{
check_stack_float(0);
monitor_exit();
move_float(returnarg_float(), stack(0));
end_function();
ret();
}
define_insn(DRETURN)
{
check_stack_double(0);
monitor_exit();
move_double(returnarg_double(), stack(0));
end_function();
ret();
}
define_insn(ARETURN)
{
check_stack_ref(0);
monitor_exit();
move_ref(returnarg_ref(), stack(0));
end_function();
ret();
}
define_insn(RETURN)
{
monitor_exit();
end_function();
ret();
}
define_insn(GETSTATIC)
{
/*
* ... -> ..., value
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
get_static_field_info(constants(), idx);
move_ref_const(tmp, field_statics() + field_offset());
if (field_size() == 1) {
push(1);
load_any(stack(0), tmp);
}
else {
push(2);
load_anylong(stack(0), tmp);
}
}
define_insn(PUTSTATIC)
{
/*
* ..., value -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
get_static_field_info(constants(), idx);
move_ref_const(tmp, field_statics() + field_offset());
if (field_size() == 1) {
#if defined(GC_INCREMENTAL)
/* If colour of referenced object is white, add it
* to the garbage collector.
*/
if (field_isref()) {
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_eq(reference_label(27));
slot_alloctmp(tmp2);
if (object_colour() == 0) {
move_ref(tmp2, stack(0));
}
else {
add_ref_const(tmp2, stack(0), object_colour());
}
load_int(tmp2, tmp2);
end_basic_block();
cmp_int_const(0, tmp2, object_white());
branch_ne(reference_label(26));
softcall_addtogc(stack(0));
set_label(27);
set_label(26);
}
#endif
store_any(tmp, stack(0));
pop(1);
}
else {
store_anylong(tmp, stack(0));
pop(2);
}
}
define_insn(GETFIELD)
{
/*
* ..., obj-ref -> ..., value
*/
check_stack_ref(0);
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_field_info(constants(), idx);
add_ref_const(stack(0), stack(0), field_data() + field_offset());
if (field_size() == 1) {
load_any(stack(0), stack(0));
}
else {
push(1);
load_anylong(stack(0), stack(1));
}
}
define_insn(PUTFIELD)
{
/*
* ..., obj-ref, value -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_field_info(constants(), idx);
if (field_size() == 1) {
check_stack_ref(1);
#if defined(GC_INCREMENTAL)
/* If colour of referenced object is white, add it
* to the garbage collector.
*/
if (field_isref()) {
end_basic_block();
cmp_int_const(0, stack(0), 0);
branch_eq(reference_label(28));
slot_alloctmp(tmp2);
if (object_colour() == 0) {
move_ref(tmp2, stack(0));
}
else {
add_ref_const(tmp2, stack(0), object_colour());
}
load_int(tmp2, tmp2);
end_basic_block();
cmp_int_const(0, tmp2, object_white());
branch_ne(reference_label(29));
softcall_addtogc(stack(0));
set_label(28);
set_label(29);
}
#endif
add_ref_const(stack(1), stack(1), field_data()+field_offset());
store_any(stack(1), stack(0));
pop(2);
}
else {
check_stack_ref(2);
add_ref_const(stack(2), stack(2), field_data() + field_offset());
store_anylong(stack(2), stack(0));
pop(3);
}
}
#define METHOD_PUSHARGS() \
for (low = 0; low < idx; low++) { \
switch (method_arg(idx-low-1)) { \
case 'L': \
case '[': \
case 'I': \
case 'Z': \
case 'S': \
case 'B': \
case 'C': \
case 'F': \
pusharg_any(stack(low)); \
break; \
case 'J': \
case 'D': \
pusharg_anylong(stack(low)); \
low++; \
break; \
case 'V': \
default: \
abort(); \
} \
}
#define METHOD_RETURN_VALUE() \
/* Store the return type (if necessary) */ \
switch (low) { \
case 'V': \
pop(idx); \
break; \
case 'L': \
case '[': \
pop(idx - 1); \
return_ref(stack(0)); \
break; \
case 'I': \
case 'Z': \
case 'S': \
case 'B': \
case 'C': \
pop(idx - 1); \
return_int(stack(0)); \
break; \
case 'F': \
pop(idx - 1); \
return_float(stack(0)); \
break; \
case 'J': \
pop(idx - 2); \
return_long(stack(0)); \
break; \
case 'D': \
pop(idx - 2); \
return_double(stack(0)); \
break; \
default: \
abort(); \
}
define_insn(INVOKEVIRTUAL)
{
/*
* (*soft_lookupmethod(obj->methodtable, msig))(...);
*
* ..., obj, ..args.., -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
slot_alloctmp(mtable);
get_method_info(constants(), idx);
idx = method_nargs();
check_stack_ref(idx);
/* Find dispatch table in object */
if (method_dtable_offset != 0) {
add_ref_const(mtable, stack(idx), method_dtable_offset);
load_ref(mtable, mtable);
}
else {
load_ref(mtable, stack(idx));
}
/* Check method table for cached entry */
add_ref_const(tmp, mtable, DTABLE_METHODOFFSET + method_idx() * DTABLE_METHODSIZE);
load_ref(tmp, tmp);
end_basic_block();
cmp_ref_const(0, tmp, 0);
branch_ne(reference_label(31));
softcall_lookupmethod(tmp, method_name(), mtable);
slot_nowriteback(mtable);
end_basic_block();
set_label(31);
start_basic_block();
/* Push arguments */
METHOD_PUSHARGS();
/* Push object */
pusharg_ref(stack(idx));
end_basic_block();
/* Call it */
low = method_returntype();
call(tmp);
/* Pop args */
idx++;
popargs(idx);
start_basic_block();
METHOD_RETURN_VALUE();
}
define_insn(INVOKENONVIRTUAL)
{
/*
* (*soft_lookupmethod(class->methodtable, msig))(...);
*
* ..., obj, ..args.., -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
slot_alloctmp(mtable);
get_method_info(constants(), idx);
idx = method_nargs();
check_stack_ref(idx);
get_dispatch_table(mtable);
/* Check dispatch table for entry */
add_ref_const(tmp, mtable, DTABLE_METHODOFFSET + method_idx() * DTABLE_METHODSIZE);
load_ref(tmp, tmp);
end_basic_block();
cmp_ref_const(0, tmp, 0);
branch_ne(reference_label(33));
softcall_lookupmethod(tmp, method_name(), mtable);
slot_nowriteback(mtable);
end_basic_block();
set_label(33);
start_basic_block();
/* Push arguments */
METHOD_PUSHARGS();
/* Push object */
pusharg_ref(stack(idx));
end_basic_block();
/* Call it */
low = method_returntype();
call(tmp);
/* Pop args */
idx++;
popargs(idx);
start_basic_block();
METHOD_RETURN_VALUE();
}
define_insn(INVOKESTATIC)
{
/*
* (*soft_lookupmethod(class->methodtable, msig))(...);
*
* ..., ..args.., -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
slot_alloctmp(mtable);
get_method_info(constants(), idx);
idx = method_nargs();
get_dispatch_table(mtable);
/* Check method table for cached entry */
add_ref_const(tmp, mtable, DTABLE_METHODOFFSET + method_idx() * DTABLE_METHODSIZE);
load_ref(tmp, tmp);
end_basic_block();
cmp_ref_const(0, tmp, 0);
branch_ne(reference_label(35));
softcall_lookupmethod(tmp, method_name(), mtable);
slot_nowriteback(mtable);
end_basic_block();
set_label(35);
start_basic_block();
/* Push arguments */
METHOD_PUSHARGS();
/* Push dummy object */
pusharg_ref_const(0);
end_basic_block();
/* Call it */
low = method_returntype();
call(tmp);
/* Pop args */
popargs(idx+1);
start_basic_block();
METHOD_RETURN_VALUE();
}
define_insn(INVOKEINTERFACE)
{
/*
* (*soft_lookupmethod(class->methodtable, msig))(...);
*
* ..., obj, ..args.., -> ...
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
slot_alloctmp(tmp);
slot_alloctmp(mtable);
get_method_info(constants(), idx);
idx = (uint8)getpc(2) - 1;
check_stack_ref(idx);
/* Find dispatch table in object */
if (method_dtable_offset != 0) {
add_ref_const(mtable, stack(idx), method_dtable_offset);
load_ref(mtable, mtable);
}
else {
load_ref(mtable, stack(idx));
}
/* Find method table in dispatch table */
if (method_mtable_offset != 0) {
add_ref_const(mtable, mtable, method_mtable_offset);
}
load_ref(mtable, mtable);
/* Check method table for cached entry */
low = method_hash() % MAXMETHOD;
add_ref_const(tmp, mtable, MTABLE_TAG + MTABLE_METHODOFFSET + low * MTABLE_METHODSIZE);
load_ref(tmp, tmp);
slot_nowriteback(tmp);
end_basic_block();
cmp_ref_const(0, tmp, method_tag());
branch_ne(reference_label(36));
add_ref_const(tmp, mtable, MTABLE_METHOD + MTABLE_METHODOFFSET + low * MTABLE_METHODSIZE);
slot_nowriteback(mtable);
load_ref(tmp, tmp);
end_basic_block();
branch_a(reference_label(37));
set_label(36);
start_basic_block();
softcall_lookupmethod(tmp, method_name(), mtable);
slot_nowriteback(mtable);
end_basic_block();
set_label(37);
start_basic_block();
/* Push arguments */
METHOD_PUSHARGS();
/* Push object */
pusharg_ref(stack(idx));
end_basic_block();
/* Call it */
low = method_returntype();
call(tmp);
/* Pop args */
idx++;
popargs(idx);
start_basic_block();
METHOD_RETURN_VALUE();
}
define_insn(NEW)
{
/*
* ... -> ..., object ref
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_class_info(constants(), idx);
push(1);
softcall_new(stack(0), class_object());
}
define_insn(NEWARRAY)
{
/*
* ... size -> ..., object ref
*/
check_stack_int(0);
low = (uint8)getpc(0);
softcall_newarray(stack(0), stack(0), low);
}
define_insn(ANEWARRAY)
{
/*
* ... size -> ..., object ref
*/
check_stack_int(0);
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_class_info(constants(), idx);
softcall_anewarray(stack(0), stack(0), class_object());
}
define_insn(ARRAYLENGTH)
{
/*
* ..., obj -> ..., length
*/
check_stack_array(0);
if (object_array_length != 0) {
add_ref_const(stack(0), stack(0), object_array_length);
}
load_int(stack(0), stack(0));
}
define_insn(ATHROW)
{
/*
* ..., obj -> undefined
*/
check_stack_ref(0);
softcall_athrow(stack(0));
}
define_insn(CHECKCAST)
{
/*
* ..., obj -> ..., obj
*/
check_stack_ref(0);
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_class_info(constants(), idx);
softcall_checkcast(stack(0), class_object());
}
define_insn(INSTANCEOF)
{
/*
* ..., obj -> ..., result
*/
check_stack_ref(0);
idx = (uint16)((getpc(0) << 8) | getpc(1));
get_class_info(constants(), idx);
softcall_instanceof(stack(0), stack(0), class_object());
}
define_insn(MONITORENTER)
{
/*
* ... obj -> ...
*/
check_stack_ref(0);
softcall_monitorenter(stack(0));
pop(1);
}
define_insn(MONITOREXIT)
{
/*
* ... obj -> ...
*/
check_stack_ref(0);
softcall_monitorexit(stack(0));
pop(1);
}
define_insn(WIDE)
{
wide = (uint16)(getpc(0) << 8);
}
define_insn(MULTIANEWARRAY)
{
/*
* ... size1, size2, ... sizen -> ..., object ref
*/
idx = (uint16)((getpc(0) << 8) | getpc(1));
low = (uint8)getpc(2);
for (high = 0; high < low; high++) {
check_stack_int(high);
}
get_class_info(constants(), idx);
softcall_multianewarray(stack(low-1), low, stack(0), class_object());
pop(low-1);
}
define_insn(IFNULL)
{
check_stack_ref(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_ref_const(0, stack(0), 0);
branch_eq(reference_code_label(pc+idx));
pop(1);
}
define_insn(IFNONNULL)
{
check_stack_ref(0);
idx = (int16)((getpc(0) << 8) | getpc(1));
end_basic_block();
cmp_ref_const(0, stack(0), 0);
branch_ne(reference_code_label(pc+idx));
pop(1);
}
define_insn(GOTO_W)
{
idx = (int32)((getpc(0) << 24) | (getpc(1) << 16) |
(getpc(2) << 8) | getpc(3));
end_basic_block();
branch_eq(reference_code_label(pc+idx));
}
define_insn(JSR_W)
{
/*
* ... -> ..., ret-addr
*/
idx = (int32)((getpc(0) << 24) | (getpc(1) << 16) |
(getpc(2) << 8) | getpc(3));
push(1);
move_label_const(stack(0), reference_code_label(npc));
end_basic_block();
branch_a(reference_code_label(pc+idx));
}
define_insn(BREAKPOINT)
{
breakpoint();
}
define_insn(RET_W)
{
idx = (uint16)((getpc(0) << 8) | getpc(1));
check_local_ref(idx);
end_basic_block();
branch_indirect(stored_code_label(local(idx)));
}