From d55c71417b3764f04c793c146a1defc1f32ff17c Mon Sep 17 00:00:00 2001 From: cacao Date: Mon, 30 Nov 1998 22:52:58 +0000 Subject: [PATCH] First working mips code --- mips/asmpart.c | 932 +++++++++++++++++++++++++++++++++++++++++++++ mips/calling.doc | 9 +- mips/defines.h | 18 + mips/disass.c | 25 +- mips/native-math.h | 38 ++ mips/ngen.c | 370 +++++++++++++----- mips/ngen.h | 57 +-- mips/types.h | 58 +++ 8 files changed, 1384 insertions(+), 123 deletions(-) create mode 100644 mips/asmpart.c create mode 100644 mips/defines.h create mode 100644 mips/native-math.h create mode 100644 mips/types.h diff --git a/mips/asmpart.c b/mips/asmpart.c new file mode 100644 index 000000000..95c153443 --- /dev/null +++ b/mips/asmpart.c @@ -0,0 +1,932 @@ +/* -*- mode: asm; tab-width: 4 -*- */ +/****************************** asmpart.c ************************************** +* * +* is an assembly language file, but called .c to fake the preprocessor. * +* It contains the Java-C interface functions for Alpha processors. * +* * +* Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst * +* * +* See file COPYRIGHT for information on usage and disclaimer of warranties * +* * +* Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at * +* * +* Last Change: 1998/11/23 * +* * +*******************************************************************************/ + +#include "offsets.h" + +#define zero $0 +#define itmp1 $1 +#define v0 $2 +#define itmp2 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 + +#define a4 $8 +#define a5 $9 +#define a6 $10 +#define a7 $11 +#define t0 $12 +#define t1 $13 +#define t2 $14 +#define t3 $15 + +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 + +#define t4 $24 +#define itmp3 $25 +#define k0 $26 +#define k1 $27 + +#define gp $28 +#define sp $29 +#define s8 $30 +#define ra $31 + +#define pv s8 + +#define xptr itmp1 +#define xpc itmp2 +#define mptr itmp3 +#define mptrreg 25 + +#define fv0 $f0 +#define ft0 $f1 +#define ft1 $f2 +#define ft2 $f3 +#define ft3 $f4 +#define ft4 $f5 +#define ft5 $f6 +#define ft6 $f7 + +#define ft7 $f8 +#define ft8 $f9 +#define ft9 $f10 +#define ft10 $f11 +#define fa0 $f12 +#define fa1 $f13 +#define fa2 $f14 +#define fa3 $f15 + +#define fa4 $f16 +#define fa5 $f17 +#define fa6 $f18 +#define fa7 $f19 +#define ft11 $f20 +#define ft12 $f21 +#define ft13 $f22 +#define ft14 $f23 + +#define fs0 $f24 +#define ft15 $f25 +#define fs1 $f26 +#define ft16 $f27 +#define fs2 $f28 +#define ft17 $f29 +#define fs3 $f30 +#define ft18 $f31 + +#define fss0 $f20 +#define fss1 $f22 +#define fss2 $f25 +#define fss3 $f27 +#define fss4 $f29 +#define fss5 $f31 + +#define aaddu daddu +#define asubu dsubu +#define aaddiu daddiu +#define ald ld +#define ast sd +#define ala dla +#define asll dsll +#define ashift 3 + +#define MethodPointer -8 +#define FrameSize -12 +#define IsSync -16 +#define IsLeaf -20 +#define IntSave -24 +#define FltSave -28 +#define ExTableSize -32 +#define ExTableStart -32 + +#define ExEntrySize -32 +#define ExStartPC -8 +#define ExEndPC -16 +#define ExHandlerPC -24 +#define ExCatchType -32 + + + .text + .set noat + + +/********************* exported functions and variables ***********************/ + + .globl has_no_x_instr_set + .globl synchronize_caches + .globl asm_calljavamethod + .globl asm_call_jit_compiler + .globl asm_dumpregistersandcall + .globl asm_handle_exception + .globl asm_handle_nat_exception + .globl asm_builtin_checkarraycast + .globl asm_builtin_aastore + .globl asm_builtin_monitorenter + .globl asm_builtin_monitorexit + .globl asm_builtin_idiv + .globl asm_builtin_irem + .globl asm_builtin_ldiv + .globl asm_builtin_lrem + .globl asm_perform_threadswitch + .globl asm_initialize_thread_stack + .globl asm_switchstackandcall + + +/*************************** imported functions *******************************/ + + .globl jit_compile + .globl builtin_monitorexit + .globl builtin_throw_exception + .globl builtin_trace_exception + .globl class_java_lang_Object + + +/*********************** function has_no_x_instr_set *************************** +* * +* determines if the byte support instruction set (21164a and higher) * +* is available. * +* * +*******************************************************************************/ + + .ent has_no_x_instr_set +has_no_x_instr_set: + + move v0,zero /* result code 0 (not used for MIPS) */ + j ra /* return */ + + .end has_no_x_instr_set + + +/********************* function synchronize_caches ****************************/ + + .ent synchronize_caches +synchronize_caches: + +/* li a0,BCACHE */ /* flush both caches */ +/* li v0,SYS_cacheflush */ /* Syscall number for cacheflush() */ +/* syscall */ /* call cacheflush() */ + j ra /* return */ + + .end synchronize_caches + + +#if 0 + +/********************* function asm_calljavamethod ***************************** +* * +* This function calls a Java-method (which possibly needs compilation) * +* with up to 4 address parameters. * +* * +* This functions calls the JIT-compiler which eventually translates the * +* method into machine code. * +* * +* A possibly throwed exception will be returned to the caller as function * +* return value, so the java method cannot return a fucntion value (this * +* function usually calls 'main' and '' which do not return a * +* function value). * +* * +* C-prototype: * +* javaobject_header *asm_calljavamethod (methodinfo *m, * +* void *arg1, void *arg2, void *arg3, void *arg4); * +* * +*******************************************************************************/ + + .ent asm_calljavamethod + +call_name: + + .ascii "calljavamethod\0\0" + + .align 3 + .dword 0 /* catch type all */ + .dword calljava_xhandler /* handler pc */ + .dword calljava_xhandler /* end pc */ + .dword asm_calljavamethod /* start pc */ + .word 1 /* extable size */ + .word 0 /* fltsave */ + .word 0 /* intsave */ + .word 0 /* isleaf */ + .word 0 /* IsSync */ + .word 80 /* frame size */ + .dword 0 /* method pointer (pointer to name) */ + +asm_calljavamethod: + + aaddiu sp,sp,-10*8 /* allocate stack space */ + sd ra,0(sp) /* save return address */ + + .set noreorder + bal call_java_pc + sd pv,3*8(sp) /* procedure vector */ +call_java_pc: + aaddiu pv,ra,-4*4 + + .set reorder + + sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */ + sdc1 fss1,5*8(sp) + sdc1 fss2,6*8(sp) + sdc1 fss3,7*8(sp) + sdc1 fss4,8*8(sp) + sdc1 fss5,9*8(sp) + sd a0,2*8(sp) /* save method pointer for compiler */ + aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */ + + move a0,a1 /* pass the remaining parameters */ + move a1,a2 + move a2,a3 + move a3,a4 + + ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */ + ast mptr,1*8(sp) /* store function address */ + move mptr,sp /* set method pointer */ + + .set noreorder + + ald pv,1*8(mptr) /* method call as in Java */ + jalr pv /* call JIT compiler */ + nop + aaddiu pv,ra,-23*4 /* recompute procedure vector */ + move v0,zero /* clear return value (exception ptr) */ + + .set reorder + +calljava_return: + + ld ra,0(sp) /* restore return address */ + ld pv,3*8(sp) /* restore procedure vector */ + + ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */ + ldc1 fss1,5*8(sp) + ldc1 fss2,6*8(sp) + ldc1 fss3,7*8(sp) + ldc1 fss4,8*8(sp) + ldc1 fss5,9*8(sp) + aaddiu sp,sp,10*8 /* free stack space */ + j ra /* return */ + +calljava_xhandler: + + move a0,itmp1 + jal builtin_throw_exception + b calljava_return + + .end asm_calljavamethod + +#endif + + +/****************** function asm_call_jit_compiler ***************************** +* * +* invokes the compiler for untranslated JavaVM methods. * +* * +* Register REG_ITEMP1 contains a pointer to the method info structure * +* (prepared by createcompilerstub). Using the return address in R31 and the * +* offset in the LDA instruction or using the value in methodptr R25 the * +* patching address for storing the method address can be computed: * +* * +* method address was either loaded using * +* M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) * +* M_JSR (REG_RA, REG_PV); * +* M_NOP * +* M_LDA (REG_PV, REG_RA, val) * +* or * +* M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) * +* M_JSR (REG_RA, REG_PV); * +* M_NOP * +* in the static case the method pointer can be computed using the * +* return address and the lda function following the jmp instruction * +* * +*******************************************************************************/ + + + .ent asm_call_jit_compiler +asm_call_jit_compiler: + + lw t0,-12(ra) /* load instruction LD PV,xxx($y) */ + srl t0,t0,21 /* shift right register number $y */ + and t0,t0,31 /* isolate register number */ + addiu t0,t0,-mptrreg /* test for REG_METHODPTR */ + beqz t0,noregchange + + lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */ + sll t0,t0,16 + sra t0,t0,16 /* isolate offset */ + aaddu mptr,t0,ra /* compute update address */ + +noregchange: + + aaddiu sp,sp,-18*8 /* allocate stack space */ + sd a0,0*8(sp) /* save all argument registers */ + sd a1,1*8(sp) /* they could be used by method */ + sd a2,2*8(sp) + sd a3,3*8(sp) + sd a4,4*8(sp) + sd a5,5*8(sp) + sd a6,6*8(sp) + sd a7,7*8(sp) + sdc1 fa0,8*8(sp) + sdc1 fa1,9*8(sp) + sdc1 fa2,10*8(sp) + sdc1 fa3,11*8(sp) + sdc1 fa4,12*8(sp) + sdc1 fa5,13*8(sp) + sdc1 fa6,14*8(sp) + sdc1 fa7,15*8(sp) + sd mptr,16*8(sp) /* save method pointer */ + sd ra,17*8(sp) /* save return address */ + + ald a0,0(itmp1) /* pass 'methodinfo' pointer to */ + jal jit_compile /* jit compiler */ + + ld a0,0*8(sp) /* restore argument registers */ + ld a1,1*8(sp) /* they could be used by method */ + ld a2,2*8(sp) + ld a3,3*8(sp) + ld a4,4*8(sp) + ld a5,5*8(sp) + ld a6,6*8(sp) + ld a7,7*8(sp) + ldc1 fa0,8*8(sp) + ldc1 fa1,9*8(sp) + ldc1 fa2,10*8(sp) + ldc1 fa3,11*8(sp) + ldc1 fa4,12*8(sp) + ldc1 fa5,13*8(sp) + ldc1 fa6,14*8(sp) + ldc1 fa7,15*8(sp) + ld mptr,16*8(sp) /* restore method pointer */ + ld ra,17*8(sp) /* restore return address */ + aaddiu sp,sp,18*8 /* deallocate stack area */ + + lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */ + sll t0,t0,16 + sra t0,t0,16 /* isolate offset */ + + aaddu t0,t0,mptr /* compute update address via method pointer*/ + ast v0,0(t0) /* save new method address there */ + + move pv,v0 /* move method address into pv */ + + jr pv /* and call method. The method returns */ + /* directly to the caller (ra). */ + + .end asm_call_jit_compiler + + +/****************** function asm_dumpregistersandcall ************************** +* * +* This funtion saves all callee saved (address) registers and calls the * +* function which is passed as parameter. * +* * +* This function is needed by the garbage collector, which needs to access * +* all registers which are stored on the stack. Unused registers are * +* cleared to avoid interferances with the GC. * +* * +* void asm_dumpregistersandcall (functionptr f); * +* * +*******************************************************************************/ + + .ent asm_dumpregistersandcall +asm_dumpregistersandcall: + aaddiu sp,sp,-10*8 /* allocate stack */ + sd ra,0(sp) /* save return address */ + + sd s0,1*8(sp) /* save all callee saved registers */ + sd s1,2*8(sp) + sd s2,3*8(sp) + sd s3,4*8(sp) + sd s4,5*8(sp) + sd s5,6*8(sp) + sd s6,7*8(sp) + sd s7,8*8(sp) + sd s8,9*8(sp) + + move itmp3,a0 + jalr itmp3 /* and call function */ + + ld ra,0(sp) /* restore return address */ + aaddiu sp,sp,10*8 /* deallocate stack */ + j ra /* return */ + + .end asm_dumpregistersandcall + + +/********************* function asm_handle_exception *************************** +* * +* This function handles an exception. It does not use the usual calling * +* conventions. The exception pointer is passed in REG_ITMP1 and the * +* pc from the exception raising position is passed in REG_ITMP2. It searches * +* the local exception table for a handler. If no one is found, it unwinds * +* stacks and continues searching the callers. * +* * +* void asm_handle_exception (exceptionptr, exceptionpc); * +* * +*******************************************************************************/ + + .ent asm_handle_nat_exception +asm_handle_nat_exception: + + lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */ + sll t0,t0,16 + sra t0,t0,16 /* isolate offset */ + aaddu pv,t0,ra /* compute update address */ + + .aent asm_handle_exception +asm_handle_exception: + + aaddiu sp,sp,-14*8 /* allocate stack */ + sd v0,0*8(sp) /* save possible used registers */ + sd t0,1*8(sp) /* also registers used by trace_exception */ + sd t1,2*8(sp) + sd t2,3*8(sp) + sd t3,4*8(sp) + sd t4,5*8(sp) + sd a0,6*8(sp) + sd a1,7*8(sp) + sd a2,8*8(sp) + sd a3,9*8(sp) + sd a4,10*8(sp) + sd a5,11*8(sp) + sd a6,12*8(sp) + sd a7,13*8(sp) + + addu t3,zero,1 /* set no unwind flag */ +ex_stack_loop: + aaddiu sp,sp,-6*8 /* allocate stack */ + sd xptr,0*8(sp) /* save used registers */ + sd xpc,1*8(sp) + sd pv,2*8(sp) + sd ra,3*8(sp) + sd t3,4*8(sp) + + move a0,xptr + ald a1,MethodPointer(pv) + move a2,xpc + move a3,t3 + jal builtin_trace_exception /* trace_exception(xptr,methodptr) */ + + ld xptr,0*8(sp) /* restore used register */ + ld xpc,1*8(sp) + ld pv,2*8(sp) + ld ra,3*8(sp) + ld t3,4*8(sp) + aaddiu sp,sp,6*8 /* deallocate stack */ + + lw t0,ExTableSize(pv) /* t0 = exception table size */ + beqz t0,empty_table /* if empty table skip */ + aaddiu t1,pv,ExTableStart /* t1 = start of exception table */ + +ex_table_loop: + ald t2,ExStartPC(t1) /* t2 = exception start pc */ + slt t2,xpc,t2 /* t2 = (xpc < startpc) */ + bnez t2,ex_table_cont /* if (true) continue */ + ald t2,ExEndPC(t1) /* t2 = exception end pc */ + slt t2,xpc,t2 /* t2 = (xpc < endpc) */ + beqz t2,ex_table_cont /* if (false) continue */ + ald a1,ExCatchType(t1) /* arg1 = exception catch type */ + beqz a1,ex_handle_it /* NULL catches everything */ + + ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */ + ald a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */ + lw a0,offbaseval(a0) /* a0 = baseval(xptr) */ + lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */ + lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */ + subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */ + sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */ + bnez v0,ex_table_cont /* if (false) continue */ + +ex_handle_it: + + ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */ + + beqz t3,ex_jump /* if (!(no stack unwinding) skip */ + + ld v0,0*8(sp) /* restore possible used registers */ + ld t0,1*8(sp) /* also registers used by trace_exception */ + ld t1,2*8(sp) + ld t2,3*8(sp) + ld t3,4*8(sp) + ld t4,5*8(sp) + ld a0,6*8(sp) + ld a1,7*8(sp) + ld a2,8*8(sp) + ld a3,9*8(sp) + ld a4,10*8(sp) + ld a5,11*8(sp) + ld a6,12*8(sp) + ld a7,13*8(sp) + + aaddiu sp,sp,14*8 /* deallocate stack */ + +ex_jump: + jr xpc /* jump to the handler */ + +ex_table_cont: + aaddiu t1,t1,ExEntrySize /* next exception table entry */ + addiu t0,t0,-1 /* decrement entry counter */ + bgtz t0,ex_table_loop /* if (t0 > 0) next entry */ + +empty_table: + beqz t3,ex_already_cleared /* if here the first time, then */ + aaddiu sp,sp,14*8 /* deallocate stack and */ + move t3,zero /* clear the no unwind flag */ +ex_already_cleared: + lw t0,IsSync(pv) /* t0 = SyncOffset */ + beqz t0,no_monitor_exit /* if zero no monitorexit */ + aaddu t0,sp,t0 /* add stackptr to Offset */ + ald a0,-8(t0) /* load monitorexit pointer */ + + aaddiu sp,sp,-8*8 /* allocate stack */ + sd t0,0*8(sp) /* save used register */ + sd t1,1*8(sp) + sd t3,2*8(sp) + sd xptr,3*8(sp) + sd xpc,4*8(sp) + sd pv,5*8(sp) + sd ra,6*8(sp) + + jal builtin_monitorexit /* builtin_monitorexit(objectptr) */ + + ld t0,0*8(sp) /* restore used register */ + ld t1,1*8(sp) + ld t3,2*8(sp) + ld xptr,3*8(sp) + ld xpc,4*8(sp) + ld pv,5*8(sp) + ld ra,6*8(sp) + aaddiu sp,sp,8*8 /* deallocate stack */ + +no_monitor_exit: + lw t0,FrameSize(pv) /* t0 = frame size */ + aaddu sp,sp,t0 /* unwind stack */ + move t0,sp /* t0 = pointer to save area */ + lw t1,IsLeaf(pv) /* t1 = is leaf procedure */ + bnez t1,ex_no_restore /* if (leaf) skip */ + ld ra,-8(t0) /* restore ra */ + aaddiu t0,t0,-8 /* t0-- */ +ex_no_restore: + move xpc,ra /* the new xpc is ra */ + lw t1,IntSave(pv) /* t1 = saved int register count */ + ala t2,ex_int2 /* t2 = current pc */ + sll t1,t1,2 /* t1 = register count * 4 */ + asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */ + jr t2 /* jump to save position */ + ld s0,-8*8(t0) + ld s1,-7*8(t0) + ld s2,-6*8(t0) + ld s3,-5*8(t0) + ld s4,-4*8(t0) + ld s5,-3*8(t0) + ld s6,-2*8(t0) + ld s7,-1*8(t0) +ex_int2: + sll t1,t1,1 /* t1 = register count * 4 * 2 */ + asubu t0,t0,t1 /* t0 = t0 - 8 * register count */ + + lw t1,FltSave(pv) /* t1 = saved flt register count */ + ala t2,ex_flt2 /* t2 = current pc */ + sll t1,t1,2 /* t1 = register count * 4 */ + asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */ + jr t2 /* jump to save position */ + ldc1 fs0,-4*8(t0) + ldc1 fs1,-3*8(t0) + ldc1 fs2,-2*8(t0) + ldc1 fs3,-1*8(t0) +ex_flt2: + lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */ + sll t0,t0,16 + sra t0,t0,16 /* isolate offset */ + aaddu pv,t0,ra /* compute update address */ + b ex_stack_loop + + .end asm_handle_nat_exception + + +/********************* function asm_builtin_monitorenter *********************** +* * +* Does null check and calls monitorenter or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_monitorenter +asm_builtin_monitorenter: + + beqz a0,nb_monitorenter /* if (null) throw exception */ + ala v0,builtin_monitorenter /* else call builtin_monitorenter */ + j v0 + +nb_monitorenter: + ald xptr,proto_java_lang_NullPointerException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_monitorenter + + +/********************* function asm_builtin_monitorexit ************************ +* * +* Does null check and calls monitorexit or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_monitorexit +asm_builtin_monitorexit: + + beqz a0,nb_monitorexit /* if (null) throw exception */ + ala v0,builtin_monitorexit /* else call builtin_monitorexit */ + j v0 + +nb_monitorexit: + ald xptr,proto_java_lang_NullPointerException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_monitorexit + + +/************************ function asm_builtin_idiv **************************** +* * +* Does null check and calls idiv or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_idiv +asm_builtin_idiv: + + beqz a1,nb_idiv /* if (null) throw exception */ + ala v0,builtin_idiv /* else call builtin_idiv */ + j v0 + +nb_idiv: + ald xptr,proto_java_lang_ArithmeticException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_idiv + + +/************************ function asm_builtin_ldiv **************************** +* * +* Does null check and calls ldiv or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_ldiv +asm_builtin_ldiv: + + beqz a1,nb_ldiv /* if (null) throw exception */ + ala v0,builtin_ldiv /* else call builtin_ldiv */ + j v0 + +nb_ldiv: + ald xptr,proto_java_lang_ArithmeticException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_ldiv + + +/************************ function asm_builtin_irem **************************** +* * +* Does null check and calls irem or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_irem +asm_builtin_irem: + + beqz a1,nb_irem /* if (null) throw exception */ + ala v0,builtin_irem /* else call builtin_irem */ + j v0 + +nb_irem: + ald xptr,proto_java_lang_ArithmeticException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_irem + + +/************************ function asm_builtin_lrem **************************** +* * +* Does null check and calls lrem or throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_lrem +asm_builtin_lrem: + + beqz a1,nb_lrem /* if (null) throw exception */ + ala v0,builtin_lrem /* else call builtin_lrem */ + j v0 + +nb_lrem: + ald xptr,proto_java_lang_ArithmeticException + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_lrem + + +/******************* function asm_builtin_checkarraycast *********************** +* * +* Does the cast check and eventually throws an exception * +* * +*******************************************************************************/ + + .ent asm_builtin_checkarraycast +asm_builtin_checkarraycast: + + aaddiu sp,sp,-16 /* allocate stack space */ + sd ra,0(sp) /* save return address */ + sd a0,8(sp) /* save object pointer */ + jal builtin_checkarraycast /* builtin_checkarraycast */ + beqz v0,nb_carray_throw /* if (false) throw exception */ + ld ra,0(sp) /* restore return address */ + ld v0,8(sp) /* return object pointer */ + aaddiu sp,sp,16 /* deallocate stack */ + j ra /* return */ + +nb_carray_throw: + ald xptr,proto_java_lang_ClassCastException + ld ra,0(sp) /* restore return address */ + aaddiu sp,sp,16 /* free stack space */ + aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/ + b asm_handle_nat_exception + .end asm_builtin_checkarraycast + + +/******************* function asm_builtin_aastore ****************************** +* * +* Does the cast check and eventually throws an exception * +* a0 = arrayref, a1 = index, a2 = value * +* * +*******************************************************************************/ + + .ent asm_builtin_aastore +asm_builtin_aastore: + + beqz a0,nb_aastore_null /* if null pointer throw exception */ + lw t0,offarraysize(a0) /* load size */ + aaddiu sp,sp,-32 /* allocate stack space */ + sd ra,0(sp) /* save return address */ + asll t1,a1,ashift /* add index*8 to arrayref */ + aaddu t1,a0,t1 /* add index * ashift to arrayref */ + sltu t0,a1,t0 /* do bound check */ + beqz t0,nb_aastore_bound /* if out of bounds throw exception */ + move a1,a2 /* object is second argument */ + sd t1,8(sp) /* save store position */ + sd a1,16(sp) /* save object */ + jal builtin_canstore /* builtin_canstore(arrayref,object) */ + ld ra,0(sp) /* restore return address */ + ld a0,8(sp) /* restore store position */ + ld a1,16(sp) /* restore object */ + aaddiu sp,sp,32 /* free stack space */ + beqz v0,nb_aastore_throw /* if (false) throw exception */ + ast a1,offobjarrdata(a0) /* store objectptr in array */ + j ra /* return */ + +nb_aastore_null: + ald xptr,proto_java_lang_NullPointerException + move xpc,ra /* faulting address is return adress */ + b asm_handle_nat_exception + +nb_aastore_bound: + ald xptr,proto_java_lang_ArrayIndexOutOfBoundsException + aaddiu sp,sp,32 /* free stack space */ + move xpc,ra /* faulting address is return adress */ + b asm_handle_nat_exception + +nb_aastore_throw: + ald xptr,proto_java_lang_ArrayStoreException + move xpc,ra /* faulting address is return adress */ + b asm_handle_nat_exception + + .end asm_builtin_aastore + + +/******************* function asm_initialize_thread_stack ********************** +* * +* u1* asm_initialize_thread_stack (void *func, u1 *stack); * +* * +* initialize a thread stack * +* * +*******************************************************************************/ + + .ent asm_initialize_thread_stack +asm_initialize_thread_stack: + + aaddiu a1,a1,-14*8 /* allocate save area */ + sd zero, 0*8(a1) /* s0 initalize thread area */ + sd zero, 1*8(a1) /* s1 */ + sd zero, 2*8(a1) /* s2 */ + sd zero, 3*8(a1) /* s3 */ + sd zero, 4*8(a1) /* s4 */ + sd zero, 5*8(a1) /* s5 */ + sd zero, 6*8(a1) /* s6 */ + sd zero, 7*8(a1) /* s7 */ + sd zero, 8*8(a1) /* s8 */ + sd zero, 9*8(a1) /* fs0 */ + sd zero,10*8(a1) /* fs1 */ + sd zero,11*8(a1) /* fs2 */ + sd zero,12*8(a1) /* fs3 */ + sd a0, 13*8(a1) + move v0,a1 + j ra /* return */ + .end asm_initialize_thread_stack + + +/******************* function asm_perform_threadswitch ************************* +* * +* void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); * +* * +* performs a threadswitch * +* * +*******************************************************************************/ + + .ent asm_perform_threadswitch +asm_perform_threadswitch: + + aaddiu sp,sp,-14*8 /* allocate new stack */ + sd s0, 0*8(sp) /* save saved registers of old thread */ + sd s1, 1*8(sp) + sd s2, 2*8(sp) + sd s3, 3*8(sp) + sd s4, 4*8(sp) + sd s5, 5*8(sp) + sd s6, 6*8(sp) + sd s7, 7*8(sp) +/* sd s8, 8*8(sp) */ + sdc1 fs0, 9*8(sp) + sdc1 fs1,10*8(sp) + sdc1 fs2,11*8(sp) + sdc1 fs3,12*8(sp) + sd ra, 13*8(sp) + ast sp,0(a0) /* save old stack pointer */ + ast sp,0(a2) /* stackTop = old stack pointer */ + ald sp,0(a1) /* load new stack pointer */ + ld s0, 0*8(sp) /* load saved registers of new thread */ + ld s1, 1*8(sp) + ld s2, 2*8(sp) + ld s3, 3*8(sp) + ld s4, 4*8(sp) + ld s5, 5*8(sp) + ld s6, 6*8(sp) + ld s7, 7*8(sp) +/* ld s8, 8*8(sp) */ + ldc1 fs0, 9*8(sp) + ldc1 fs1,10*8(sp) + ldc1 fs2,11*8(sp) + ldc1 fs3,12*8(sp) + ld ra, 13*8(sp) + aaddiu sp,sp,14*8 /* deallocate new stack */ + j ra /* return */ + .end asm_perform_threadswitch + + +/********************* function asm_switchstackandcall ************************* +* * +* void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); * +* * +* Switches to a new stack, calls a function and switches back. * +* a0 new stack pointer * +* a1 function pointer * +* a2 pointer to variable where stack top should be stored * +* * +*******************************************************************************/ + + + .ent asm_switchstackandcall +asm_switchstackandcall: + aaddiu a0,a0,-16 /* allocate new stack */ + sd ra,0(a0) /* save return address on new stack */ + sd sp,8(a0) /* save old stack pointer on new stack */ + sd sp,0(a2) /* save old stack pointer to variable */ + move sp,a0 /* switch to new stack */ + + move itmp3,a1 + jalr itmp3 /* and call function */ + + ld ra,0(sp) /* load return address */ + ld sp,8(sp) /* switch to old stack */ + + j ra /* return */ + + .end asm_switchstackandcall diff --git a/mips/calling.doc b/mips/calling.doc index 59d7a0125..f3840ff9d 100644 --- a/mips/calling.doc +++ b/mips/calling.doc @@ -62,6 +62,11 @@ R25 ....... pointer to 'methodinfo' structure. This register has to be set R26-R27 ... reserved register (reserved for kernel) +R28 (gp) .. global pointer (left unchanged by called method). Used for the + addressing of global variables in C functions. + +R29 (sp) .. stack pointer. The stack grows from high to low. + R28 (pv) .. procedure vector, points to the first instruction of the called method. This vector is used for addressing the entries in the data segment. The pv of the caller is recomputed from the ra in @@ -69,10 +74,6 @@ R28 (pv) .. procedure vector, points to the first instruction of the called recomputed if builtin functions are called. For Java methods it is necessary that a return is always done using ra. -R29 (sp) .. stack pointer. The stack grows from high to low. - -R30 ....... saved registers (left unchanged by called method) - R31 (ra) .. return address (left unchanged by called method) diff --git a/mips/defines.h b/mips/defines.h new file mode 100644 index 000000000..dc60708b5 --- /dev/null +++ b/mips/defines.h @@ -0,0 +1,18 @@ +/* alpha/defines.h ************************************************************* + + Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + + See file COPYRIGHT for information on usage and disclaimer of warranties + + system-dependent definitions + + Authors: Mark Probst EMAIL: cacao@complang.tuwien.ac.at + + Last Change: 1997/09/11 + +*******************************************************************************/ + +#define USE_INTERNAL_THREADS + +#define HAVE_FCNTL +#define HAVE_IOCTL diff --git a/mips/disass.c b/mips/disass.c index d2dc344a2..1f1c9e344 100644 --- a/mips/disass.c +++ b/mips/disass.c @@ -185,11 +185,11 @@ static struct {char *name; int ftype;} regops[] = { /* 0x38 */ {"dsll ", ITYPE_IMM}, /* 0x39 */ {"" , ITYPE_UNDEF}, - /* 0x3a */ {"dslr ", ITYPE_IMM}, + /* 0x3a */ {"dsrl ", ITYPE_IMM}, /* 0x3b */ {"dsra ", ITYPE_IMM}, /* 0x3c */ {"dsll32 ", ITYPE_IMM}, /* 0x3d */ {"" , ITYPE_UNDEF}, - /* 0x3e */ {"dslr32 ", ITYPE_IMM}, + /* 0x3e */ {"dsrl32 ", ITYPE_IMM}, /* 0x3f */ {"dsra32 ", ITYPE_IMM} }; @@ -355,10 +355,10 @@ static char *regs[] = { /* 0x09 */ "a5", /* "$9", */ /* 0x0a */ "a6", /* "$10", */ /* 0x0b */ "a7", /* "$11", */ - /* 0x0c */ "t0", /* "$12", */ - /* 0x0d */ "t1", /* "$13", */ - /* 0x0e */ "t2", /* "$14", */ - /* 0x0f */ "t3", /* "$15", */ + /* 0x0c */ "t4", /* "$12", */ + /* 0x0d */ "t5", /* "$13", */ + /* 0x0e */ "t6", /* "$14", */ + /* 0x0f */ "t7", /* "$15", */ /* 0x10 */ "s0", /* "$16", */ /* 0x11 */ "s1", /* "$17", */ @@ -550,11 +550,21 @@ static void disassinstr(int c, int pos) break; } + if (rs == 0) { /* move from */ + printf("mfc1 %s,$f%d\n", regs[rt], fs); + break; + } + if (rs == 1) { /* double move from */ printf("dmfc1 %s,$f%d\n", regs[rt], fs); break; } + if (rs == 4) { /* move to */ + printf("mtc1 %s,$f%d\n", regs[rt], fs); + break; + } + if (rs == 5) { /* double move to */ printf("dmtc1 %s,$f%d\n", regs[rt], fs); break; @@ -568,6 +578,9 @@ static void disassinstr(int c, int pos) else if (fops[opfun].ftype == ITYPE_FOP2) printf("%s%s%s $f%d,$f%d\n", fops[opfun].name, fmt[rs], fops[opfun].fill, fd, fs); + else if (fops[opfun].ftype == ITYPE_FCMP) + printf("%s%s%s $f%d,$f%d\n", fops[opfun].name, fmt[rs], + fops[opfun].fill, fs, ft); else printf("cop1 (%#04x) $f%d,$f%d,$f%d\n", opfun, fd, fs, ft); diff --git a/mips/native-math.h b/mips/native-math.h new file mode 100644 index 000000000..1c0193af3 --- /dev/null +++ b/mips/native-math.h @@ -0,0 +1,38 @@ +/* alpha/native-math.h ********************************************************* + + Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + + See file COPYRIGHT for information on usage and disclaimer of warranties + + Contains the machine-specific floating point definitions. + + Authors: Michael Gschwind EMAIL: cacao@complang.tuwien.ac.at + Andreas Krall EMAIL: cacao@complang.tuwien.ac.at + + Last Change: 1997/10/21 + +*******************************************************************************/ + +/* include machine-specific math.h */ + +#include + +/* define infinity for floating point numbers */ + +u4 flt_nan = 0xffffffff; +u4 flt_posinf = 0x7f800000; +u4 flt_neginf = 0xff800000; + +#define FLT_NAN (*((float*) (&flt_nan))) +#define FLT_POSINF (*((float*) (&flt_posinf))) +#define FLT_NEGINF (*((float*) (&flt_neginf))) + +/* define infinity for double floating point numbers */ + +u8 dbl_nan = 0xffffffffffffffffL ; +u8 dbl_posinf = 0x7ff0000000000000L ; +u8 dbl_neginf = 0xfff0000000000000L ; + +#define DBL_NAN (*((double*) (&dbl_nan))) +#define DBL_POSINF (*((double*) (&dbl_posinf))) +#define DBL_NEGINF (*((double*) (&dbl_neginf))) diff --git a/mips/ngen.c b/mips/ngen.c index 58c181279..f3c31a7e3 100644 --- a/mips/ngen.c +++ b/mips/ngen.c @@ -22,7 +22,7 @@ Datatypes and Register Allocations: ----------------------------------- On 64-bit-machines (like the MIPS) all operands are stored in the -registers in a 64-bit form, even when the correspondig JavaVM operands +registers in a 64-bit form, even when the correspondig JavaVM operands only need 32 bits. This is done by a canonical representation: 32-bit integers are allways stored as sign-extended 64-bit values (this @@ -226,9 +226,14 @@ void catch_NullPointerException(int sig, int code, struct sigcontext *sigctx) } } +void createcalljava (); + void init_exceptions(void) { + + createcalljava(); + /* install signal handlers we need to convert to exceptions */ if (!checknull) { @@ -259,11 +264,19 @@ void init_exceptions(void) #define ExTableSize -32 #define ExTableStart -32 +#if POINTERSIZE==8 #define ExEntrySize -32 #define ExStartPC -8 #define ExEndPC -16 #define ExHandlerPC -24 #define ExCatchType -32 +#else +#define ExEntrySize -16 +#define ExStartPC -4 +#define ExEndPC -8 +#define ExHandlerPC -12 +#define ExCatchType -16 +#endif static void gen_mcode() { @@ -294,8 +307,16 @@ static void gen_mcode() #endif + /* adjust frame size for 16 byte alignment */ + + if (parentargs_base & 1) + parentargs_base++; + /* create method header */ +#if POINTERSIZE==4 + (void) dseg_addaddress(method); /* Filler */ +#endif (void) dseg_addaddress(method); /* MethodPointer */ (void) dseg_adds4(parentargs_base * 8); /* FrameSize */ @@ -344,7 +365,7 @@ static void gen_mcode() p = parentargs_base; if (!isleafmethod) - {p--; M_AST (REG_RA, REG_SP, 8*p);} + {p--; M_LST (REG_RA, REG_SP, 8*p);} for (r = savintregcnt - 1; r >= maxsavintreguse; r--) {p--; M_LST (savintregs[r], REG_SP, 8 * p);} for (r = savfltregcnt - 1; r >= maxsavfltreguse; r--) @@ -372,7 +393,7 @@ static void gen_mcode() if (runverbose && isleafmethod) { M_LDA (REG_SP, REG_SP, -(18*8)); - M_AST(REG_RA, REG_SP, 1*8); + M_LST(REG_RA, REG_SP, 1*8); M_LST(argintregs[0], REG_SP, 2*8); M_LST(argintregs[1], REG_SP, 3*8); @@ -396,11 +417,11 @@ static void gen_mcode() M_ALD(REG_ITMP1, REG_PV, p); M_LST(REG_ITMP1, REG_SP, 0); p = dseg_addaddress ((void*) (builtin_trace_args)); - M_ALD(REG_ITMP1, REG_PV, p); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, p); + M_JSR(REG_RA, REG_ITMP3); M_NOP; - M_ALD(REG_RA, REG_SP, 1*8); + M_LLD(REG_RA, REG_SP, 1*8); M_LLD(argintregs[0], REG_SP, 2*8); M_LLD(argintregs[1], REG_SP, 3*8); @@ -478,8 +499,8 @@ static void gen_mcode() M_ALD(REG_ITMP1, REG_PV, p); M_AST(REG_ITMP1, REG_SP, 0); p = dseg_addaddress ((void*) (builtin_trace_args)); - M_ALD(REG_ITMP1, REG_PV, p); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, p); + M_JSR(REG_RA, REG_ITMP3); M_NOP; M_LDA(REG_SP, REG_SP, 8); } @@ -489,8 +510,8 @@ static void gen_mcode() #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { p = dseg_addaddress ((void*) (builtin_monitorenter)); - M_ALD(REG_ITMP1, REG_PV, p); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, p); + M_JSR(REG_RA, REG_ITMP3); M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); } #endif @@ -1588,7 +1609,7 @@ static void gen_mcode() var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_ITMP3); M_CVTFI(s1, REG_FTMP1); - M_MOVDL(REG_FTMP1, d); + M_MOVDI(REG_FTMP1, d); store_reg_to_var_int(iptr->dst, d); break; @@ -1597,7 +1618,7 @@ static void gen_mcode() var_to_reg_flt(s1, src, REG_FTMP1); d = reg_of_var(iptr->dst, REG_ITMP3); M_CVTDI(s1, REG_FTMP1); - M_MOVDL(REG_FTMP1, d); + M_MOVDI(REG_FTMP1, d); store_reg_to_var_int(iptr->dst, d); break; @@ -1641,10 +1662,12 @@ static void gen_mcode() var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); M_FCMPUEQF(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instructions */ - M_LSUB_IMM(REG_ZERO, 1, d); + M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */ M_CLR(d); M_FCMPULTF(s2, s1); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ M_NOP; M_LADD_IMM(REG_ZERO, 1, d); @@ -1657,10 +1680,12 @@ static void gen_mcode() var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); M_FCMPUEQD(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instructions */ - M_LSUB_IMM(REG_ZERO, 1, d); + M_LSUB_IMM(REG_ZERO, 1, d); /* delay slot */ M_CLR(d); M_FCMPULTD(s2, s1); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ M_NOP; M_LADD_IMM(REG_ZERO, 1, d); @@ -1673,10 +1698,12 @@ static void gen_mcode() var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); M_FCMPUEQF(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ - M_LADD_IMM(REG_ZERO, 1, d); + M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */ M_CLR(d); M_FCMPULTF(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ M_NOP; M_LSUB_IMM(REG_ZERO, 1, d); @@ -1689,10 +1716,12 @@ static void gen_mcode() var_to_reg_flt(s2, src, REG_FTMP2); d = reg_of_var(iptr->dst, REG_ITMP3); M_FCMPUEQD(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ - M_LADD_IMM(REG_ZERO, 1, d); + M_LADD_IMM(REG_ZERO, 1, d); /* delay slot */ M_CLR(d); M_FCMPULTD(s1, s2); + M_NOP; /* compare delay */ M_FBF(2); /* jump over next instruction */ M_NOP; M_LSUB_IMM(REG_ZERO, 1, d); @@ -1725,8 +1754,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0])); @@ -1738,8 +1769,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0])); @@ -1751,8 +1784,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0])); @@ -1764,8 +1799,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_FTMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0])); @@ -1777,8 +1814,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_FTMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0])); @@ -1790,8 +1829,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0])); @@ -1803,8 +1844,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); M_SLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0])); @@ -1816,8 +1859,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev, REG_ITMP1); var_to_reg_int(s2, src, REG_ITMP2); d = reg_of_var(iptr->dst, REG_ITMP3); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } M_AADD(s2, s1, REG_ITMP1); M_BLDS(d, REG_ITMP1, OFFSET(java_chararray, data[0])); store_reg_to_var_int(iptr->dst, d); @@ -1828,8 +1873,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); @@ -1840,8 +1887,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); @@ -1852,8 +1901,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); @@ -1864,8 +1915,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_flt(s3, src, REG_FTMP3); M_ASLL_IMM(s2, 2, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); @@ -1876,8 +1929,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_flt(s3, src, REG_FTMP3); M_ASLL_IMM(s2, 3, REG_ITMP2); M_AADD(REG_ITMP2, s1, REG_ITMP1); @@ -1889,8 +1944,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); M_AADD(s2, s1, REG_ITMP1); M_AADD(s2, REG_ITMP1, REG_ITMP1); @@ -1901,8 +1958,10 @@ static void gen_mcode() var_to_reg_int(s1, src->prev->prev, REG_ITMP1); var_to_reg_int(s2, src->prev, REG_ITMP2); - gen_nullptr_check(s1); - gen_bound_check; + if (iptr->op1 == 0) { + gen_nullptr_check(s1); + gen_bound_check; + } var_to_reg_int(s3, src, REG_ITMP3); M_AADD(s2, s1, REG_ITMP1); M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0])); @@ -2636,8 +2695,8 @@ static void gen_mcode() #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_ALD(REG_ITMP1, REG_PV, a); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); + M_JSR(REG_RA, REG_ITMP3); M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */ } #endif @@ -2651,8 +2710,8 @@ static void gen_mcode() #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_ALD(REG_ITMP1, REG_PV, a); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); + M_JSR(REG_RA, REG_ITMP3); M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */ } #endif @@ -2665,8 +2724,8 @@ static void gen_mcode() #ifdef USE_THREADS if (checksync && (method->flags & ACC_SYNCHRONIZED)) { a = dseg_addaddress ((void*) (builtin_monitorexit)); - M_ALD(REG_ITMP1, REG_PV, a); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); + M_JSR(REG_RA, REG_ITMP3); M_ALD(argintregs[0], REG_SP, 8 * maxmemuse); /* delay slot */ } #endif @@ -2693,18 +2752,18 @@ nowperformreturn: if (runverbose) { M_LDA (REG_SP, REG_SP, -24); - M_AST(REG_RA, REG_SP, 0); + M_LST(REG_RA, REG_SP, 0); M_LST(REG_RESULT, REG_SP, 8); M_DST(REG_FRESULT, REG_SP,16); a = dseg_addaddress (method); M_ALD(argintregs[0], REG_PV, a); M_MOV(REG_RESULT, argintregs[1]); a = dseg_addaddress ((void*) (builtin_displaymethodstop)); - M_ALD(REG_ITMP1, REG_PV, a); - M_JSR (REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); + M_JSR (REG_RA, REG_ITMP3); M_FLTMOVE(REG_FRESULT, argfltregs[2]); /* delay slot */ - M_ALD(REG_RA, REG_SP, 0); + M_LLD(REG_RA, REG_SP, 0); M_LLD(REG_RESULT, REG_SP, 8); M_DLD(REG_FRESULT, REG_SP,16); M_LDA (REG_SP, REG_SP, 24); @@ -2871,8 +2930,8 @@ gen_method: { case ICMD_BUILTIN2: case ICMD_BUILTIN1: a = dseg_addaddress ((void*) (m)); - M_ALD(REG_ITMP1, REG_PV, a); /* built-in-function pointer */ - M_JSR (REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); /* built-in-function pointer */ + M_JSR (REG_RA, REG_ITMP3); M_NOP; d = iptr->op1; /* return type */ goto afteractualcall; @@ -2925,14 +2984,14 @@ makeactualcall: /* recompute pv */ +afteractualcall: + s1 = (int)((u1*) mcodeptr - mcodebase); if (s1<=32768) M_LDA (REG_PV, REG_RA, -s1); else { panic("method to big"); } -afteractualcall: - /* d contains return type */ if (d != TYPE_VOID) { @@ -3116,8 +3175,8 @@ afteractualcall: M_INTMOVE(REG_SP, argintregs[2]); a = dseg_addaddress((void*) (builtin_nmultianewarray)); - M_ALD(REG_ITMP1, REG_PV, a); - M_JSR(REG_RA, REG_ITMP1); + M_ALD(REG_ITMP3, REG_PV, a); + M_JSR(REG_RA, REG_ITMP3); M_NOP; s1 = reg_of_var(iptr->dst, REG_RESULT); M_INTMOVE(REG_RESULT, s1); @@ -3182,23 +3241,21 @@ afteractualcall: MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xboundrefs->branchpos - 4); if (xcodeptr != NULL) { - M_BR((xcodeptr-mcodeptr)-1); + M_BR((xcodeptr-mcodeptr)); M_NOP; } else { xcodeptr = mcodeptr; - a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException); - M_ALD(REG_ITMP1_XPTR, REG_PV, a); - a = dseg_addaddress(asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ITMP3); - M_NOP; + a = dseg_addaddress(proto_java_lang_ArrayIndexOutOfBoundsException); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); } } @@ -3218,23 +3275,21 @@ afteractualcall: MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xcheckarefs->branchpos - 4); if (xcodeptr != NULL) { - M_BR((xcodeptr-mcodeptr)-1); + M_BR((xcodeptr-mcodeptr)); M_NOP; } else { xcodeptr = mcodeptr; - a = dseg_addaddress(proto_java_lang_NegativeArraySizeException); - M_ALD(REG_ITMP1_XPTR, REG_PV, a); - a = dseg_addaddress(asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ITMP3); - M_NOP; + a = dseg_addaddress(proto_java_lang_NegativeArraySizeException); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); } } @@ -3254,23 +3309,21 @@ afteractualcall: MCODECHECK(8); - M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos); + M_LDA(REG_ITMP2_XPC, REG_PV, xcastrefs->branchpos - 4); if (xcodeptr != NULL) { - M_BR((xcodeptr-mcodeptr)-1); + M_BR((xcodeptr-mcodeptr)); M_NOP; } else { xcodeptr = mcodeptr; - a = dseg_addaddress(proto_java_lang_ClassCastException); - M_ALD(REG_ITMP1_XPTR, REG_PV, a); - a = dseg_addaddress(asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ITMP3); - M_NOP; + a = dseg_addaddress(proto_java_lang_ClassCastException); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); } } @@ -3296,20 +3349,18 @@ afteractualcall: M_LDA(REG_ITMP2_XPC, REG_PV, xnullrefs->branchpos - 4); if (xcodeptr != NULL) { - M_BR((xcodeptr-mcodeptr)-1); + M_BR((xcodeptr-mcodeptr)); M_NOP; } else { xcodeptr = mcodeptr; - a = dseg_addaddress(proto_java_lang_NullPointerException); - M_ALD(REG_ITMP1_XPTR, REG_PV, a); - a = dseg_addaddress(asm_handle_exception); M_ALD(REG_ITMP3, REG_PV, a); M_JMP(REG_ITMP3); - M_NOP; + a = dseg_addaddress(proto_java_lang_NullPointerException); + M_ALD(REG_ITMP1_XPTR, REG_PV, a); } } @@ -3317,6 +3368,9 @@ afteractualcall: } mcode_finish((int)((u1*) mcodeptr - mcodebase)); + + (void) cacheflush((void*) method->entrypoint, + (int)((u1*) mcodeptr - mcodebase), ICACHE); } @@ -3361,11 +3415,13 @@ u1 *createcompilerstub (methodinfo *m) s4 *p = (s4*) s; /* code generation pointer */ /* code for the stub */ - M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */ + M_ALD(REG_PV, REG_PV, 24); /* load pointer to the compiler */ + M_NOP; M_JSR(REG_ITMP1, REG_PV); /* jump to the compiler, return address in itmp1 is used as method pointer */ M_NOP; - M_NOP; + + (void) cacheflush((void*) s, (char*) p - (char*) s, ICACHE); s[2] = (u8) m; /* literals to be adressed */ s[3] = (u8) asm_call_jit_compiler; /* jump directly via PV from above */ @@ -3403,16 +3459,16 @@ u1 *createnativestub (functionptr f, methodinfo *m) u8 *s = CNEW (u8, NATIVESTUBSIZE); /* memory to hold the stub */ s4 *p = (s4*) s; /* code generation pointer */ - M_ALD (REG_ITMP1, REG_PV, 8*8); /* load adress of native method */ + M_ALD (REG_ITMP3, REG_PV, 8*8); /* load adress of native method */ M_LDA (REG_SP, REG_SP, -8); /* build up stackframe */ - M_AST (REG_RA, REG_SP, 0); /* store return address */ - M_JSR (REG_RA, REG_ITMP1); /* call native method */ + M_LST (REG_RA, REG_SP, 0); /* store return address */ + M_JSR (REG_RA, REG_ITMP3); /* call native method */ M_NOP; /* delay slot */ M_ALD (REG_ITMP3, REG_PV, 9*8); /* get address of exceptionptr */ - M_ALD (REG_RA, REG_SP, 0); /* load return address */ + M_LLD (REG_RA, REG_SP, 0); /* load return address */ M_ALD (REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */ M_BNEZ (REG_ITMP1, 2); /* if no exception then return */ @@ -3428,6 +3484,8 @@ u1 *createnativestub (functionptr f, methodinfo *m) M_LDA (REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */ /* delay slot */ + (void) cacheflush((void*) s, (char*) p - (char*) s, ICACHE); + s[8] = (u8) f; /* address of native method */ s[9] = (u8) (&exceptionptr); /* address of exceptionptr */ s[10]= (u8) (asm_handle_nat_exception); /* addr of asm exception handler */ @@ -3452,6 +3510,136 @@ void removenativestub (u1 *stub) } +/* function: createcalljava **************************************************** + + creates the asm_calljavamethod (MIPS assembler does not like data in the + text segment). Documentation can be found in asmpart.c. + +*******************************************************************************/ + +#define REG_FSS0 20 +#define REG_FSS1 22 +#define REG_FSS2 25 +#define REG_FSS3 27 +#define REG_FSS4 29 +#define REG_FSS5 31 + +#define CALL_JAVA_MEM_SIZE 60 +#define CALL_JAVA_ENTRY 20 +#define CALL_JAVA_XHANDLER 55 + +static s4 calljavamem[CALL_JAVA_MEM_SIZE]; + +void createcalljava () +{ + s4 *p; + + *((void**)(calljavamem + 0)) = (void*) asm_call_jit_compiler; + *((void**)(calljavamem + 2)) = (void*) builtin_throw_exception; +#if POINTERSIZE==8 + *((void**)(calljavamem + 4)) = NULL; + *((void**)(calljavamem + 6)) = (void*) (calljavamem + CALL_JAVA_XHANDLER); + *((void**)(calljavamem + 8)) = (void*) (calljavamem + CALL_JAVA_XHANDLER); + *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_ENTRY); +#else + *((void**)(calljavamem + 8)) = NULL; + *((void**)(calljavamem + 9)) = (void*) (calljavamem + CALL_JAVA_XHANDLER); + *((void**)(calljavamem +10)) = (void*) (calljavamem + CALL_JAVA_XHANDLER); + *((void**)(calljavamem +11)) = (void*) (calljavamem + CALL_JAVA_ENTRY); +#endif + + calljavamem[12] = 1; /* extable size */ + calljavamem[13] = 0; /* fltsave */ + calljavamem[14] = 0; /* intsave */ + calljavamem[15] = 0; /* isleaf */ + calljavamem[16] = 0; /* IsSync */ + calljavamem[17] = 80; /* frame size */ + calljavamem[18] = 0; /* method pointer (NULL) */ + calljavamem[19] = 0; /* method pointer (NULL) */ + + p = calljavamem + CALL_JAVA_ENTRY; /* code generation pointer */ + +/* 20 */ + M_LDA (REG_SP, REG_SP, -10*8); /* allocate stackframe */ + M_LST (REG_RA, REG_SP, 0); /* save return address */ + + M_BRS(1); /* compute current program counter */ + M_LST (REG_PV, REG_SP, 3*8); /* save procedure vector */ +/* 24 */ + M_LDA (REG_PV, REG_RA, -4*4); /* compute procedure vector */ + M_DST (REG_FSS0, REG_SP, 4*8); /* save non JavaABI saved flt regs */ + + M_DST (REG_FSS1, REG_SP, 5*8); + M_DST (REG_FSS2, REG_SP, 6*8); +/* 28 */ + M_DST (REG_FSS3, REG_SP, 7*8); + M_DST (REG_FSS4, REG_SP, 8*8); + + M_DST (REG_FSS5, REG_SP, 9*8); + M_LST (REG_ARG_0, REG_SP, 2*8); /* save method pointer for compiler */ +/* 32 */ + M_LDA (REG_ITMP1, REG_SP, 2*8); /* pass pointer to methodptr via itmp1*/ + M_MOV (REG_ARG_1, REG_ARG_0); /* pass the remaining parameters */ + + M_MOV (REG_ARG_2, REG_ARG_1); + M_MOV (REG_ARG_3, REG_ARG_2); +/* 36 */ + M_MOV (REG_ARG_4, REG_ARG_3); + M_ALD (REG_METHODPTR, REG_PV, -80); /* address of asm_call_jit_compiler */ + + M_AST (REG_METHODPTR, REG_SP, 8); /* store function address */ + M_MOV (REG_SP, REG_METHODPTR); /* set method pointer */ +/* 40 */ + M_ALD (REG_PV, REG_METHODPTR, 8); /* method call as in Java */ + M_JSR (REG_RA, REG_PV); /* call JIT compiler */ + + M_NOP; /* delay slot */ + M_LDA (REG_PV, REG_RA, -23*4); /* recompute procedure vector */ + +/* 44 */ + M_CLR (REG_RESULT); /* clear return value (exception ptr) */ +/* calljava_return: */ + M_LLD (REG_RA, REG_SP, 0); /* restore return address */ + + M_LLD (REG_PV, REG_SP, 3*8); /* restore procedure vector */ + M_DLD (REG_FSS0, REG_SP, 4*8); /* restore non JavaABI saved flt regs */ +/* 48 */ + M_DLD (REG_FSS1, REG_SP, 5*8); + M_DLD (REG_FSS2, REG_SP, 6*8); + + M_DLD (REG_FSS3, REG_SP, 7*8); + M_DLD (REG_FSS4, REG_SP, 8*8); +/* 52 */ + M_DLD (REG_FSS5, REG_SP, 9*8); + M_RET(REG_RA); /* return */ + + M_LDA (REG_SP, REG_SP, 10*8); /* deallocate stackframe (delay slot) */ + +/* 55 */ +/* calljava_xhandler: */ + + M_ALD (REG_ITMP3, REG_PV, -72); /* address of builtin_throw_exception */ + + M_JSR (REG_RA, REG_ITMP3); /* call builtin */ + M_MOV (REG_ITMP1, REG_ARG_0); /* pass parameter (delay slot) */ +/* 58 */ + M_BR(-14); /* branch calljava_return */ + M_NOP; /* delay slot */ + + (void) cacheflush((void*)(calljavamem + CALL_JAVA_ENTRY), + (CALL_JAVA_MEM_SIZE - CALL_JAVA_ENTRY) * (int) sizeof(s4), ICACHE); +} + + +typedef java_objectheader* (*asm_fptr)(methodinfo*, void*, void*, void*, void*); + +java_objectheader *asm_calljavamethod (methodinfo *m, void *arg1, void *arg2, + void *arg3, void *arg4) +{ +return ((asm_fptr)(calljavamem + 20))(m, arg1, arg2, arg3, arg4); +} + + /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where diff --git a/mips/ngen.h b/mips/ngen.h index 89dd712d2..23bb62e38 100644 --- a/mips/ngen.h +++ b/mips/ngen.h @@ -13,6 +13,8 @@ *******************************************************************************/ +#include + /* see also file calling.doc for explanation of calling conventions */ /* preallocated registers *****************************************************/ @@ -25,12 +27,20 @@ #define REG_ITMP1 1 /* temporary register */ #define REG_ITMP2 3 /* temporary register and method pointer */ -#define REG_ITMP3 24 /* temporary register */ +#define REG_ITMP3 25 /* temporary register */ + +#define REG_ARG_0 4 /* argument register */ +#define REG_ARG_1 5 /* argument register */ +#define REG_ARG_2 6 /* argument register */ +#define REG_ARG_3 7 /* argument register */ +#define REG_ARG_4 8 /* argument register */ +#define REG_ARG_5 9 /* argument register */ #define REG_RA 31 /* return address */ #define REG_SP 29 /* stack pointer */ +#define REG_GP 28 /* global pointer */ -#define REG_PV 28 /* procedure vector, must be provided by caller */ +#define REG_PV 30 /* procedure vector, must be provided by caller */ #define REG_METHODPTR 25 /* pointer to the place from where the procedure */ /* vector has been fetched */ #define REG_ITMP1_XPTR 1 /* exception pointer = temporary register 1 */ @@ -60,10 +70,10 @@ int nregdescint[] = { REG_RES, REG_RES, REG_RET, REG_RES, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_ARG, REG_TMP, REG_TMP, REG_TMP, REG_TMP, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, REG_SAV, - REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_SAV, REG_RES, + REG_TMP, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_RES, REG_END }; -#define INT_SAV_CNT 9 /* number of int callee saved registers */ +#define INT_SAV_CNT 8 /* number of int callee saved registers */ #define INT_ARG_CNT 8 /* number of int argument registers */ /* for use of reserved registers, see comment above */ @@ -168,6 +178,7 @@ int parentargs_base; /* offset in stackframe for the parameter from the caller*/ #define M_BGTZL(a,disp) M_ITYPE(0x17,a,0,disp) /* br a > 0 */ #define M_BR(disp) M_ITYPE(0x04,0,0,disp) /* branch */ +#define M_BRS(disp) M_ITYPE(0x01,0,17,disp) /* branch sbr */ #define M_JMP(a) M_RTYPE(0,a,0,0,0,0x08) /* jump */ #define M_JSR(r,a) M_RTYPE(0,a,0,r,0,0x09) /* call */ @@ -205,7 +216,7 @@ int parentargs_base; /* offset in stackframe for the parameter from the caller*/ #define M_LSUB(a,b,c) M_RTYPE(0,a,b,c,0,0x2f) /* 64 sub */ #define M_IMUL(a,b) M_ITYPE(0,a,b,0x18) /* 32 mul */ #define M_LMUL(a,b) M_ITYPE(0,a,b,0x1c) /* 64 mul */ -#define M_IDIV(a,b) M_ITYPE(0,a,b,0x1b) /* 32 div */ +#define M_IDIV(a,b) M_ITYPE(0,a,b,0x1a) /* 32 div */ #define M_LDIV(a,b) M_ITYPE(0,a,b,0x1e) /* 64 div */ #define M_MFLO(a) M_RTYPE(0,0,0,a,0,0x12) /* quotient */ @@ -247,9 +258,9 @@ int parentargs_base; /* offset in stackframe for the parameter from the caller*/ #define M_ISLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x00) /* c = a << b */ #define M_ISRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x02) /* c = a >>>b */ #define M_ISRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x03) /* c = a >> b */ -#define M_LSLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x38+4*((b)&32)) /*c = a << b*/ -#define M_LSRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3a+4*((b)&32)) /*c = a >>>b*/ -#define M_LSRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3b+4*((b)&32)) /*c = a >> b*/ +#define M_LSLL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x38+((b)>>3&4)) /*c = a << b*/ +#define M_LSRL_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3a+((b)>>3&4)) /*c = a >>>b*/ +#define M_LSRA_IMM(a,b,c) M_RTYPE(0,0,a,c,(b)&31,0x3b+((b)>>3&4)) /*c = a >> b*/ #define M_MOV(a,c) M_OR(a,0,c) /* c = a */ #define M_CLR(c) M_OR(0,0,c) /* c = 0 */ @@ -304,25 +315,27 @@ int parentargs_base; /* offset in stackframe for the parameter from the caller*/ #define M_CVTFL(a,c) M_FP2(0x25,FMT_F,a,c) /* flt2long */ #define M_CVTDL(a,c) M_FP2(0x25,FMT_D,a,c) /* dbl2long */ +#define M_MOVDI(d,i) M_FP3(0,0,d,i,0) /* i = d */ #define M_MOVDL(d,l) M_FP3(0,1,d,l,0) /* l = d */ +#define M_MOVID(i,d) M_FP3(0,4,d,i,0) /* d = i */ #define M_MOVLD(l,d) M_FP3(0,5,d,l,0) /* d = l */ #define M_FCMPFF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a == b */ #define M_FCMPFD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a == b */ -#define M_FCMPUNF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a == b */ -#define M_FCMPUND(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a == b */ -#define M_FCMPEQF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a == b */ -#define M_FCMPEQD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a == b */ -#define M_FCMPUEQF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a == b */ -#define M_FCMPUEQD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a == b */ -#define M_FCMPOLTF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a < b */ -#define M_FCMPOLTD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a < b */ -#define M_FCMPULTF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a < b */ -#define M_FCMPULTD(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a < b */ -#define M_FCMPOLEF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a <= b */ -#define M_FCMPOLED(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a <= b */ -#define M_FCMPULEF(a,b) M_FP3(0x30,FMT_F,a,b,0) /* c = a <= b */ -#define M_FCMPULE(a,b) M_FP3(0x30,FMT_D,a,b,0) /* c = a <= b */ +#define M_FCMPUNF(a,b) M_FP3(0x31,FMT_F,a,b,0) /* c = a == b */ +#define M_FCMPUND(a,b) M_FP3(0x31,FMT_D,a,b,0) /* c = a == b */ +#define M_FCMPEQF(a,b) M_FP3(0x32,FMT_F,a,b,0) /* c = a == b */ +#define M_FCMPEQD(a,b) M_FP3(0x32,FMT_D,a,b,0) /* c = a == b */ +#define M_FCMPUEQF(a,b) M_FP3(0x33,FMT_F,a,b,0) /* c = a == b */ +#define M_FCMPUEQD(a,b) M_FP3(0x33,FMT_D,a,b,0) /* c = a == b */ +#define M_FCMPOLTF(a,b) M_FP3(0x34,FMT_F,a,b,0) /* c = a < b */ +#define M_FCMPOLTD(a,b) M_FP3(0x34,FMT_D,a,b,0) /* c = a < b */ +#define M_FCMPULTF(a,b) M_FP3(0x35,FMT_F,a,b,0) /* c = a < b */ +#define M_FCMPULTD(a,b) M_FP3(0x35,FMT_D,a,b,0) /* c = a < b */ +#define M_FCMPOLEF(a,b) M_FP3(0x36,FMT_F,a,b,0) /* c = a <= b */ +#define M_FCMPOLED(a,b) M_FP3(0x36,FMT_D,a,b,0) /* c = a <= b */ +#define M_FCMPULEF(a,b) M_FP3(0x37,FMT_F,a,b,0) /* c = a <= b */ +#define M_FCMPULE(a,b) M_FP3(0x37,FMT_D,a,b,0) /* c = a <= b */ #define M_FBF(disp) M_ITYPE(0x11,8,0,disp) /* br false */ #define M_FBT(disp) M_ITYPE(0x11,8,1,disp) /* br true */ diff --git a/mips/types.h b/mips/types.h new file mode 100644 index 000000000..4ade23770 --- /dev/null +++ b/mips/types.h @@ -0,0 +1,58 @@ +/* alpha/types.h *************************************************************** + + Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + + See file COPYRIGHT for information on usage and disclaimer of warranties + + machine specific definitions for the Alpha processor + + Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at + Andreas Krall EMAIL: cacao@complang.tuwien.ac.at + Michael Gschwind EMAIL: cacao@complang.tuwien.ac.at + + Last Change: 1997/09/22 + +*******************************************************************************/ + +#ifndef _CACAO_TYPES_H + +#define _CACAO_TYPES_H + +#define POINTERSIZE 8 +#define WORDS_BIGENDIAN 1 + +#define SUPPORT_DIVISION 0 +#define SUPPORT_LONG 1 +#define SUPPORT_FLOAT 1 +#define SUPPORT_DOUBLE 1 + +#define SUPPORT_LONG_ADD 1 +#define SUPPORT_LONG_CMP 1 +#define SUPPORT_LONG_LOG 1 +#define SUPPORT_LONG_SHIFT 1 +#define SUPPORT_LONG_MULDIV 1 +#define SUPPORT_LONG_ICVT 1 +#define SUPPORT_LONG_FCVT 1 + +#define U8_AVAILABLE 1 + + +typedef signed char s1; +typedef unsigned char u1; + +typedef signed short int s2; +typedef unsigned short int u2; + +typedef signed int s4; +typedef unsigned int u4; + +#if U8_AVAILABLE +typedef signed long int s8; +typedef unsigned long int u8; +#else +typedef struct {u4 low, high;} u8; +#define s8 u8 +#endif + +#endif + -- 2.25.1