📄 jit3-mips.def
字号:
/* jit-mips.def * MIPS instruction definition. * * Copyright (c) 1996, 1997 * Transvirtual Technologies, Inc. All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. * * Written by Christian Krusel <chrkr@uni-paderborn.de>, 1997. * Modified by Michael Chen <mikey@hydra.stanford.edu>, 1998. * last changed 2.15.98 */#if defined(WORDS_BIGENDIAN)#define LSLOT(_s) ((_s)+1)#define HSLOT(_s) (_s)#define LOFFSET 4#define HOFFSET 0#else#define LSLOT(_s) (_s)#define HSLOT(_s) ((_s)+1)#define LOFFSET 0#define HOFFSET 4#endif#ifdef KAFFE_VMDEBUGextern uint pc;int jit_debug = 0;/* int dbmsg = 0; */#define debug_name(x) debug(x)#define debug(x) if (jit_debug) printf##x;fflush(stdout)static char* rnames[] = { "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i10", "i11", "i12", "i13", "i14", "i15", "i16", "i17", "i18", "i19", "i20", "i21", "i22", "i23", "i24", "i25", "i26", "i27", "gp", "sp", "fp", "ra", "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" };#define regname(n) rnames[n]#define fregname(n) rnames[(n)+32]#else#define debug_name(x)#define debug(x)#endif#if defined(TRACE_METHOD_END)uint v0,v1;float f0,f1;#endif#include "classMethod.h"#include "access.h"#define return_dst() slot_return(seq_dst(s))#define REG_i0 0#define REG_i1 1#define REG_cmp 1#define REG_i2 2#define REG_i3 3#define REG_i4 4#define REG_i5 5#define REG_i6 6#define REG_i7 7#define REG_s0 16#define REG_i25 25#define REG_gp 28#define REG_sp 29#define REG_fp 30#define REG_ra 31#define REG_f0 32#define REG_f12 44#define CONSTPOOL_BASE REG_gp#define None 0 /* register not used */#define COP1 021#define REGIMM 0x1#define _ADD 041 /* 040 (w/overflow exception) */#define _ADDI 011 /* 010 (w/overflow exception) */#define _ADDU 041 #define _ADDIU 011#define _SUB 043 /* 042 (w/overflow exception) */#define _SUBU 043 #define _LUI 017#define _MULT 030#define _DIV 032#define _MFLO 022#define _MFHI 020#define _AND 044#define _ANDI 014#define _OR 045#define _ORI 015#define _XOR 046#define _NOR 047#define _SRAV 007#define _SRA 003#define _SRLV 006#define _SRL 002#define _SLLV 004#define _SLL 000#define _LW 043#define _SW 053#define _LB 040#define _SB 050#define _LHU 045#define _LH 041#define _SH 051#define _LWC1 061#define _SWC1 071#define _LDC1 065#define _SDC1 075#define _JR 010#define _JALR 011#define _LWC2 062#define _SWC2 072#define _COP2 022#define _SLT 052#define _SLTU 053#define _SLTIU 013#define _BEQ 004#define _BNE 005#define _BGEZ 001 /* regimm */#define _BGTZ 007#define _BLEZ 006#define _BLTZ 000 /* regimm */#define _FADD 000#define _FSUB 001#define _FMULT 002#define _FDIV 003#define _FMOV 006#define _FNEG 007#define _FCVT_S 040#define _FCVT_D 041#define _FCVT_W 044#define _FCVT_L 045#define _FFLOOR_W 017#define _FFLOOR_L 013/* format for float.point registers. table:html 464*/#define WORD_FORMAT 20#define LONG_FORMAT 21#define SINGLE_FORMAT 16#define DOUBLE_FORMAT 17/* --------------------------------------------------------------------- *//* Various masks *//* MIPS: */#define MASKL5BITS 0x0000001F /* for lshl_int, RRR */#define MASKL15BITS 0x00007FFF /* 2 ^ 15 (prologue, move_int_const */#define MASKL16BITS 0x0000FFFF#define MASKL26BITS 0x03FFFFFF#define NMASKL5BITS (~MASKL5BITS)#define NMASKL15BITS (~MASKL15BITS)#define NMASKL16BITS (~MASKL16BITS)/* -------------------------------------------------------------------- *//* MIPS Instruction formats */#define insn_RRR(op, rd, rs, rt) \ LOUT = 0x00000000 | ((rs) << 21) | \ ((rt) << 16) | ((rd) << 11) | (op)#define insn_sRRC(op, rd, rt, sa) \ LOUT = 0x00000000 | ((rt) << 16) | \ ((rd) << 11) | (((sa) & MASKL5BITS ) << 6 ) | (op)#define insn_RRC(op, rt, rs, cnst) \ LOUT = 0x00000000 | ((op) << 26) | \ ((rs) << 21) | ((rt) << 16) | ((cnst) & MASKL16BITS) #define ldst_RRC(op, rt, base, cnst) \ LOUT = 0x00000000 | ((op) << 26) | \ ((base) << 21) | ((rt) << 16) | ((cnst) & MASKL16BITS) #define finsn_RRR(op, fmt, fd, fs, ft, copn) \ LOUT = 0x00000000 | ((copn) << 26) | \ ((fmt) << 21) | ((ft) << 16) | \ ((fs) << 11) | ((fd) << 6) | (op)#define insn_babranch(op, target) \ LOUT = 0x00000000 | ((op) << 26) | ((target) & MASKL26BITS) #define insn_cbr(op, rs, rt, offset) \ LOUT = 0x00000000 | ((op) << 26) | \ ((rs) << 21) | ((rt) << 16) | ((offset) & MASKL16BITS) #define insn_czbr(op, rs, offset) \ LOUT = 0x00000000 | ((op) << 26) | \ ((rs) << 21) | ((0x0) << 16) | ((offset) & MASKL16BITS) #define insn_czbr_ri(regimm_op, rs, offset) \ LOUT = 0x00000000 | ((REGIMM) << 26) | \ ((rs) << 21) | ((regimm_op) << 16) | ((offset) & MASKL16BITS) /* --------------------------------------------------------------------- *//* * Kaffe currently doesn't have enough understanding of the wierd * ways we can push arguments - so we do the handling here. */static int arg_idx = 0;static int fp_idx = 0;static int pushed_int = 0;static int res_idx = 0;static int resreg[4];int max_args;/* --------------------------------------------------------------------- */#define NOP() insn_RRR(0x0, REG_i0, REG_i0, REG_i0); \ debug((" nop\n"));define_insn(unimplemented, unimplemented) { debug_name(("unimplemented:\n")); abort();}define_insn(nop, nop) { NOP();}/* --------------------------------------------------------------------- */define_insn(prologue, prologue_xxC) { label* l; Method* meth; int limit; int haveint; int j; int i; int fi; int a; /* Max_args is the maximum number of arguments this method pushed * onto the stack (allowing for alignment). We always allow for * the 4 argument registers. */ max_args = NR_ARGUMENTS; debug_name(("prologue:\n")); /* Save and move sp, fp & r31 */ insn_RRR(_ADDU, REG_i1, REG_fp, REG_i0); insn_RRR(_ADDU, REG_fp, REG_sp, REG_i0); /* Remember where the framesize should go */ l = (label*)const_int(1); l->type = Lframe|Labsolute|Lgeneral; l->at = (uintp)CODEPC; insn_RRC(_ADDIU, REG_sp, REG_sp, 0); /* framesize */ ldst_RRC(_SW, REG_ra, REG_fp, -4); /* save $ra */ ldst_RRC(_SW, REG_i1, REG_fp, -8); /* save old $fp */ ldst_RRC(_SW, REG_gp, REG_fp, -12); /* save $gp */ debug((" mov i1,fp\n")); debug((" mov fp,sp\n")); debug((" addiu sp,sp,-framesize\n")); debug((" sw ra,-4(fp)\n")); debug((" sw i1,-8(fp)\n")); debug((" sw gp,-12(fp)\n"));#if defined(USE_JIT_CONSTANT_POOL) /* Get pointer to constant pool */ insn_RRR(_ADDU, CONSTPOOL_BASE, REG_i25, REG_i0); ldst_RRC(_SW, REG_gp, REG_fp, -16); debug((" move gp,i25\n")); debug((" sw gp,-16(fp)\n"));#endif /* Save callee save regs */ for (i = 0; i < 8; i++) { ldst_RRC(_SW, REG_s0+i, REG_fp, -SLOTSIZE*(5+i)); debug((" sw %s,%d(fp)\n",regname(REG_s0+i),-SLOTSIZE*(4+i))); } meth = (Method*)const_int(2); limit = maxArgs; if (limit > NR_ARGUMENTS) { limit = NR_ARGUMENTS; } haveint = 0; i = 0; a = 0; fi = 0; /* We must now setup the register for the MIPS calling convention */ if (!isStatic) { preloadRegister(slot_data(localinfo[i]), Rref, REG_i4+a); argMap[i] = a; haveint = 1; i++; a++; /* If this is a sync method then we must write our * object back so we can find it in an exception. */ if ((meth->accflags & ACC_SYNCHRONISED) == ACC_SYNCHRONISED) { ldst_RRC(_SW, REG_i4, REG_fp, 0); debug((" sw i4,0(fp)\n")); } } for (j = 0; i < limit; j++) { char ch = *METHOD_ARG_TYPE(meth, j); /* We must align doubles and longs, and this might take * us past the end of our register arguments so check this. */ if (ch == 'D' || ch == 'J') { a += a % 2; /* Align */ } if (a >= NR_ARGUMENTS) { break; } switch (ch) { case 'D': if (haveint == 0 && fi < 2) { preloadRegister(slot_data(localinfo[i]), Rdouble, REG_f12+2*fi); i += 2; a += 2; fi++; break; } /* Fall through ... */ case 'J': /* dbmsg = 1; */ preloadRegister(slot_data(localinfo[i]), Rint, REG_i4+a); preloadRegister(slot_data(localinfo[i+1]), Rint, REG_i4+a+1); haveint = 1; i += 2; a += 2; break; case 'F': if (haveint == 0 && fi < 2) { preloadRegister(slot_data(localinfo[i]), Rfloat, REG_f12+2*fi); i++; a++; fi++; break; } /* Fall through ... */ default: preloadRegister(slot_data(localinfo[i]), Rint/*?*/, REG_i4+a); haveint = 1; i++; a++; break; } }#if defined(STACK_LIMIT) if (a < NR_ARGUMENTS) { preloadRegister(slot_data(stack_limit[0]), Rref, REG_i4+a); }#endif}define_insn(epilogue, epilogue_xxx) { int i; debug_name(("epilogue:\n")); setEpilogueLabel ((uintp)CODEPC); /* Restore callee save regs */ for (i = 7; i >= 0; i--) { ldst_RRC(_LW, REG_s0+i, REG_fp, -SLOTSIZE*(5+i)); debug((" lw %s,%d(fp)\n",regname(REG_s0+i),-SLOTSIZE*(4+i))); } /* Restore sp, fp & r31 */ ldst_RRC(_LW, REG_gp, REG_fp, -12); ldst_RRC(_LW, REG_i1, REG_fp, -8); ldst_RRC(_LW, REG_ra, REG_fp, -4); insn_RRR(_ADDU, REG_sp, REG_fp, REG_i0); insn_RRR(_ADDU, REG_fp, REG_i1, REG_i0); insn_RRR(_JR, REG_i0, REG_ra, REG_i0); debug((" lw gp,-12(fp)\n")); debug((" lw r1,-8(fp)\n")); debug((" lw ra,-4(fp)\n")); debug((" mov sp,fp\n")); debug((" mov fp,r1\n")); debug((" jr ra\n")); NOP();}define_insn(eprologue, eprologue_xxx) { label* l; /* exception handling */ debug_name(("eprologue:\n")); /* Remember where the framesize should go */ l = (label*)const_int(1); l->type = Lexception|Labsolute|Lgeneral; l->at = (uintp)CODEPC; insn_RRC(_ADDIU, REG_sp, REG_fp, 0); /* framesize */ debug((" addiu sp,fp,-framesize\n"));#if defined(USE_JIT_CONSTANT_POOL) /* * The following opcodes re-establish the CONSTPOOL_BASE * registers. This is filled it in my Lexception. * There should be no space between this code and the frame * setup. */ insn_RRC(_LUI, CONSTPOOL_BASE, REG_i0, 0); insn_RRC(_ORI, CONSTPOOL_BASE, CONSTPOOL_BASE, 0);#endif}define_insn(check_stack_limit, check_stack_limit_xRC) { int r = rreg_int(1); label* l = const_label(2); debug_name(("check_stack_limit:\n")); clobberRegister(REG_i25); insn_RRR(_SLTU,REG_i25,r,REG_sp); insn_cbr(_BNE,REG_i25,REG_i0,3); debug((" sgtu i25,%s,sp\n", regname(r))); debug((" bne i25,zero,+3\n")); NOP(); l->type = Lconstant|Lfuncrelative|Llong16; l->at = CODEPC; ldst_RRC(_LW, REG_i25, CONSTPOOL_BASE, 0); insn_RRR(_JALR, REG_ra, REG_i25, REG_i0); debug((" call [soft_stackoverflow]\n")); NOP();}/* --------------------------------------------------------------------- */define_insn(spill_int, spill_Rxx) { int r = sreg_int(0); int o = const_int(1); debug_name(("spill_int:\n")); ldst_RRC(_SW, r, REG_fp , o); debug((" sw %s,%d(fp)\n", regname(r), o));}define_insn(spill_float, fspill_Rxx) { int r = sreg_float(0); int o = const_int(1); debug_name(("spill_float:\n")); ldst_RRC(_SWC1, r, REG_fp, o); debug((" swc1 %s,%d(fp)\n", fregname(r), o));}define_insn(spill_double, fspilll_Rxx) { int r = sreg_double(0); int o = const_int(1); debug_name(("spill_double:\n")); /* FIX: use ldc1 */ ldst_RRC(_SWC1, r, REG_fp, o+LOFFSET); debug((" swc1 %s,%d(fp)\n", fregname(r), o+LOFFSET)); ldst_RRC(_SWC1, r+1, REG_fp, o+HOFFSET); debug((" swc1 %s,%d(fp)\n", fregname(r+1), o+HOFFSET));}define_insn(reload_int, reload_Rxx) { int r = lreg_int(0); int o = const_int(1); debug_name(("reload_int:\n")); ldst_RRC(_LW, r, REG_fp, o); debug((" lw %s,%d(fp)\n", regname(r), o));}define_insn(reload_float, freload_Rxx) { int r = lreg_float(0); int o = const_int(1); debug_name(("reload_float:\n")); ldst_RRC(_LWC1, r, REG_fp, o); debug((" lwc1 %s,%d(fp)\n", fregname(r), o));}define_insn(reload_double, freloadl_Rxx) { int r = lreg_double(0); int o = const_int(1); debug_name(("reload_double:\n")); /* FIX: use ldc1 */ ldst_RRC(_LWC1, r, REG_fp, o+LOFFSET); debug((" lwc1 %s,%d(fp)\n", fregname(r), o+LOFFSET)); ldst_RRC(_LWC1, r+1, REG_fp, o+HOFFSET); debug((" lwc1 %s,%d(fp)\n", fregname(r+1), o+HOFFSET));}voidmovereg_RR(int toreg, int fromreg){ insn_RRR(_ADDU, toreg, fromreg, REG_i0); debug((" mov %s,%s\n", regname(toreg), regname(fromreg)));}/* --------------------------------------------------------------------- */define_insn(move_int_const, move_RxC) { int val = const_int(2); int w = wreg_int(0); debug_name(("move_int_const:\n")); if (val == 0) { debug((" mov %s,0\n", regname(w))); insn_RRR(_ADDU, w, REG_i0, REG_i0); } else if ((val & NMASKL15BITS) == 0 || (val & NMASKL15BITS) == NMASKL15BITS) { /* constants in [0,32767] or [-32768,0] */ insn_RRC(_ADDIU, w, REG_i0, val & MASKL16BITS); debug((" movi %s,%d\n", regname(w), val & MASKL16BITS)); } else if((val & NMASKL16BITS) == 0) { /* [32768,65535] */ /* cosntants in [32768,65535] */ insn_RRC(_ORI, w, REG_i0, val & MASKL16BITS); debug((" ori %s,%s,%d\n", regname(w), regname(REG_i0), val & MASKL16BITS)); } else { /* constants not in range: [-32768,65535] */ insn_RRC(_LUI, w, REG_i0, (val >> 16) & MASKL16BITS); debug((" lui %s,%d\n", regname(w), (val >> 16) & MASKL16BITS)); if ((val & MASKL16BITS) != 0) { /* load the lower half, if necessary */ insn_RRC(_ORI, w, w, val & MASKL16BITS); debug((" ori %s,%s,%d\n", regname(w), regname(w), val & MASKL16BITS)); } }} define_insn(move_label_const, move_RxL) { label* l = (label*)const_int(2); int w = wreg_int(0); debug_name(("move_label_const:\n")); l->type |= Llong16x16|Labsolute; l->at = (uintp)CODEPC; insn_RRC(_LUI, w, 0, 0); insn_RRC(_ORI, w, w, 0); debug((" lui %s,?\n", regname(w))); debug((" ori %s,%s,?\n", regname(w), regname(w)));}define_insn(load_constpool_int, ld_RxL) { label* l = const_label(2); int w = wreg_int(0); debug_name(("load_constpool_int:\n")); l->type = Lconstant|Lfuncrelative|Llong16; l->at = CODEPC; ldst_RRC(_LW, w, CONSTPOOL_BASE, 0); debug((" lw %s,?(gp)\n", regname(w)));}define_insn(move_int, move_RxR) { int r = rreg_int(2); int w = wreg_int(0); debug_name(("move_int:\n")); if (r != w) { insn_RRR(_ADDU, w, r, REG_i0); debug((" mov %s,%s\n", regname(w), regname(r))); }}define_insn(move_float, fmove_RxR) { int r = rreg_float(2); int w = wreg_float(0); debug_name(("move_float:\n")); if (r != w) { finsn_RRR(_FMOV, SINGLE_FORMAT, w, r, 0, COP1); debug((" mov.s %s,%s\n", fregname(w), fregname(r))); }}define_insn(move_double, fmovel_RxR) { int r = rreg_double(2); int w = wreg_double(0); debug_name(("move_double:\n")); if (r != w) { finsn_RRR(_FMOV, DOUBLE_FORMAT, w, r, 0, COP1); debug((" mov.d %s,%s\n", fregname(w), fregname(r))); }}/* --------------------------------------------------------------------- */define_insn(add_int, add_RRR) { int r1; int r2; int w; debug_name(("add_int:\n")); r2 = rreg_int(2); r1 = rreg_int(1); w = wreg_int(0); insn_RRR(_ADD, w, r1, r2); debug((" add %s,%s,%s\n", regname(w), regname(r1), regname(r2)));}define_insn(add_int_const, add_RRC) { int o; int r; int w; debug_name(("add_int_const:\n")); o = const_int(2); r = rreg_int(1); w = wreg_int(0); insn_RRC(_ADDI, w, r, o); debug((" addi %s,%s,%d\n", regname(w), regname(r), o));}define_insn(add_ref, addu_RRR) { int r1; int r2; int w; debug_name(("add_ref:\n")); r2 = rreg_int(2); r1 = rreg_int(1); w = wreg_int(0); insn_RRR(_ADDU, w, r1, r2); debug((" addu %s,%s,%s\n", regname(w), regname(r1), regname(r2)));}define_insn(add_ref_const, addu_RRC) { int o; int r; int w; debug_name(("add_ref_const:\n")); o = const_int(2); r = rreg_int(1); w = wreg_int(0); insn_RRC(_ADDIU, w, r, o); debug((" addiu %s,%s,%d\n", regname(w), regname(r), o));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -