📄 jit3-mips.def
字号:
debug((" cvt.s.d %s,%s\n", fregname(w), fregname(r)));}/* --------------------------------------------------------------------- */define_insn(build_key, set_word_xxC) { jint val = const_int(2); debug_name(("build_key:\n")); LOUT = val; debug((" .word %08x\n", val));}define_insn(build_code_ref, set_wordpc_xxC) { label* l = (label*)const_int(2); debug_name(("build_code_ref:\n")); l->type |= Llong|Labsolute; l->at = (uintp)CODEPC; LOUT = 0; l->from = (uintp)CODEPC; debug((" .word ?\n"));}/* --------------------------------------------------------------------- */define_insn(set_lt_int, sltu_RRR) { int r1 = rreg_int(1); int r2 = rreg_int(2); int w = wreg_int(0); debug_name(("slt_int:\n")); insn_RRR(_SLTU,w,r1,r2); debug((" sltu %s,%s,%s\n",regname(w),regname(r1),regname(r2)));}define_insn(set_lt_int_const, sltu_RRC) { int o = const_int(2); int r = rreg_int(1); int w = wreg_int(0); debug_name(("slt_int_const:\n")); insn_RRC(_SLTIU,w,r,o); debug((" sltiu %s,%s,%d\n",regname(w),regname(r),o));}define_insn(set_label, set_label_xxC) { label* l = (label*)const_int(2); debug_name(("set_label:\n")); l->to = (uint32)CODEPC;}define_insn(cbranch_int, cbranch_RRC) { int r1 = rreg_int(1); int r2 = rreg_int(2); label* l = (label*)const_int(3); int bt = const_int(4); debug_name(("cbranch_int:\n")); l->type |= Llong16b|Lrelative; switch (bt) { case ba: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_i0,REG_i0,0); debug((" b ?\n")); break; case beq: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,r1,r2,0); debug((" beq %s,%s,?\n",regname(r1),regname(r2))); break; case bne: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,r1,r2,0); debug((" bne %s,%s,?\n",regname(r1),regname(r2))); break; case blt: clobberRegister(REG_cmp); insn_RRR(_SLT,REG_cmp,r1,r2); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r1),regname(r2))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case ble: clobberRegister(REG_cmp); insn_RRR(_SLT,REG_cmp,r2,r1); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r2),regname(r1))); debug((" beq %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bgt: clobberRegister(REG_cmp); insn_RRR(_SLT,REG_cmp,r2,r1); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r2),regname(r1))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bge: clobberRegister(REG_cmp); insn_RRR(_SLT,REG_cmp,r1,r2); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r1),regname(r2))); debug((" beq %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bult: clobberRegister(REG_cmp); insn_RRR(_SLTU,REG_cmp,r1,r2); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" sltu %s,%s,%s\n",regname(REG_cmp),regname(r1),regname(r2))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case buge: clobberRegister(REG_cmp); insn_RRR(_SLTU,REG_cmp,r1,r2); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r1),regname(r2))); debug((" beq %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; default: /* Shouldn't get here */ printf ("unimplemented br type\n"); abort(); } NOP();}define_insn(cbranch_int_const, cbranch_RRCC) { int r = rreg_int(1); int val = const_int(2); label* l = (label*)const_int(3); int bt = const_int(4); debug_name(("cbranch_int_const:\n")); /* FIX */ /* check for smaller constants/zero */ clobberRegister(REG_cmp); insn_RRC(_LUI, REG_cmp, REG_i0, (val >> 16) & MASKL16BITS); debug((" lui %s,%d\n", regname(REG_cmp), (val >> 16) & MASKL16BITS)); if ((val & MASKL16BITS) != 0) { /* load the lower half, if necessary */ insn_RRC(_ORI, REG_cmp, REG_cmp, val & MASKL16BITS); debug((" ori %s,%s,%d\n", regname(REG_cmp), regname(REG_cmp), val & MASKL16BITS)); } l->type |= Llong16b|Lrelative; switch (bt) { case ba: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_i0,REG_i0,0); debug((" b ?\n")); break; case beq: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,r,REG_cmp,0); debug((" beq %s,%s,?\n",regname(r),regname(REG_cmp))); break; case bne: l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,r,REG_cmp,0); debug((" bne %s,%s,?\n",regname(r),regname(REG_cmp))); break; case blt: insn_RRR(_SLT,REG_cmp,r,REG_cmp); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r),regname(REG_cmp))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case ble: insn_RRR(_SLT,REG_cmp,REG_cmp,r); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(REG_cmp),regname(r))); debug((" beq %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bgt: insn_RRR(_SLT,REG_cmp,REG_cmp,r); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(REG_cmp),regname(r))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bge: insn_RRR(_SLT,REG_cmp,r,REG_cmp); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BEQ,REG_cmp,REG_i0,0); debug((" slt %s,%s,%s\n",regname(REG_cmp),regname(r),regname(REG_cmp))); debug((" beq %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; case bult: insn_RRR(_SLTU,REG_cmp,r,REG_cmp); l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; insn_cbr(_BNE,REG_cmp,REG_i0,0); debug((" sltu %s,%s,%s\n",regname(REG_cmp),regname(r),regname(REG_cmp))); debug((" bne %s,%s,?\n",regname(REG_cmp),regname(REG_i0))); break; default: /* Shouldn't get here */ printf ("unimplemented br type\n"); abort(); } NOP();}define_insn(branch, branch_xCC) { label* l = (label*)const_int(1); int bt = const_int(2); debug_name(("branch:\n")); l->type |= Llong16b|Lrelative; l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; switch (bt) { case ba: insn_cbr(_BEQ,REG_i0,REG_i0,0); debug((" b ?\n")); break; case beq: case bne: case blt: case ble: case bgt: case bge: case bult: default: /* Shouldn't get here */ printf ("unimplemented br type\n"); abort(); } NOP();}define_insn(branch_indirect, branch_indirect_xRC) { int r = rreg_int(1); assert(const_int(2) == ba); debug_name(("branch_indirect:\n")); insn_RRR(_JR, REG_i0, r, REG_i0); debug((" jr %s\n", regname(r))); NOP();}define_insn(call_ref, call_xCC) { label* l = (label*)const_int(1); assert(const_int(2) == ba); debug_name(("call_ref:\n")); clobberRegister(REG_i25); l->type |= Llong16x16|Labsolute; l->at = (uintp)CODEPC; l->from = (uintp)CODEPC; /* FIX USE JAL, but be sure to SRL by 2 (word address) */ insn_RRC(_LUI, REG_i25, REG_i0, 0); insn_RRC(_ORI, REG_i25, REG_i25, 0); debug((" lui i25,?\n")); debug((" ori i25,i25,?\n")); insn_RRR(_JALR, REG_ra, REG_i25, REG_i0); debug((" jalr %s,%s\n",regname(REG_ra), regname(REG_i25))); NOP();#if defined(USE_JIT_CONSTANT_POOL) /* Restore pointer to constant pool */ ldst_RRC(_LW, REG_gp, REG_fp, -16); /* restore $gp */ debug((" lw gp,-16(fp)\n"));#endif}define_insn(call, call_xRC) { int r = rreg_ideal_int(1, REG_i25); assert(const_int(2) == ba); debug_name(("call:\n")); /* We might not get the ideal register (if the slot is global) * so handle this. */ if (r != REG_i25) { clobberRegister(REG_i25); insn_RRR(_ADDU, REG_i25, r, REG_i0); r = REG_i25; } insn_RRR(_JALR, REG_ra, r, REG_i0); debug((" jalr %s,%s\n",regname(REG_ra), regname(r))); NOP(); #if defined(USE_JIT_CONSTANT_POOL) /* Restore pointer to constant pool */ ldst_RRC(_LW, REG_gp, REG_fp, -16); /* restore $gp */ debug((" lw gp,-16(fp)\n"));#endif}define_insn(push_int, push_xRC) { /* pushes first 4 parameters in registers i4 to i7, rest -> stack */ int r; int o; debug_name(("push_int:\n")); /* This affect how flots are pushed */ pushed_int = 1; debug(("I -> [%d]\n",arg_idx)); if (arg_idx < NR_ARGUMENTS) { o = REG_i4 + arg_idx; r = rreg_ideal_int(1, o); /* We might not get the ideal register (if the slot is global) * so handle this. */ if (r != o) { clobberRegister(o); insn_RRR(_ADDU, o, r, REG_i0); debug((" mov %s,%s\n", regname(o), regname(r))); r = o; } register_reserve(r); resreg[res_idx++] = r; } else { r = rreg_int(1); o = SLOT2PUSHOFFSET(arg_idx); ldst_RRC(_SW, r, REG_sp, o); debug((" sw %s,%d[sp]\n", regname(r), o)); } arg_idx++;}define_insn(push_long, pushl_xRC) { int r, r2; int w; int o; debug_name(("push_long:\n")); /* This affect how floats are pushed */ pushed_int = 1; /* We align arguments onto their natural boundaries */ arg_idx += arg_idx % 2; debug(("J -> [%d]\n",arg_idx)); if (arg_idx < NR_ARGUMENTS) { o = REG_i4 + arg_idx; r = rreg_ideal_int(1, o); /* No macro for the following */ w = slotRegister(seq_slot(s, 1)+1, Rint, rread, o+1); debug(("REG s1:[%d]->%d s2:[%d]->%d\n", slotOffsetNoSpill(seq_slot(s,1),Rint),r, slotOffsetNoSpill(seq_slot(s,1)+1,Rint),w)); /* We might not get the ideal register (if the slot is global) * so handle this. */ if (r != o) { clobberRegister(o); insn_RRR(_ADDU, o, r, REG_i0); debug((" mov %s,%s\n", regname(o), regname(r))); r = o; } if (w != o+1) { clobberRegister(o+1); insn_RRR(_ADDU, o+1, w, REG_i0); debug((" mov %s,%s\n", regname(o+1), regname(w))); w = o+1; } register_reserve(r); register_reserve(w); resreg[res_idx++] = r; resreg[res_idx++] = w; } else { /* dbmsg = 1; */ w = SLOT2PUSHOFFSET(arg_idx); r = rreg_int(1); ldst_RRC(_SW, r, REG_sp, w); debug((" sw %s,%d[sp]\n", regname(r), w)); /* No macro for the following */ r2 = slotRegister(seq_slot(s, 1)+1, Rint, rread, NOREG); debug(("STK s1:%d->[%d] s2:%d->[%d]\n", r,w,r2,w+4)); ldst_RRC(_SW, r2, REG_sp, w+4); debug((" sw %s,%d[sp]\n", regname(r2), w+4)); } arg_idx += 2;}define_insn(push_float, fpush_xRC) { /* pushes the first 4 parameters in registers i4 to i7, rest -> stack */ int r; int w; debug_name(("push_float:\n")); debug(("F -> [%d]\n",arg_idx)); /* If we've beyond NR_ARGUMENTS then it get easy. */ if (arg_idx >= NR_ARGUMENTS) { /* Put in argument stack */ r = rreg_float(1); w = SLOT2PUSHOFFSET(arg_idx); ldst_RRC(_SWC1, r, REG_sp, w); debug((" swc1 %s,%d[sp]\n", fregname(r), w)); } /* If we've pushed ints already or we've pushed more than * two floats then we put it in a0-a3. */ else if (pushed_int || fp_idx >= 2) { r = rreg_ideal_int(1, REG_i4 + arg_idx); assert(r == REG_i4 + arg_idx); register_reserve(r); resreg[res_idx++] = r; } /* Else we actually put the value in a float point register f12-f14. */ else { r = rreg_ideal_float(1, REG_f12+2*fp_idx); assert(r == 12+2*fp_idx); register_reserve(r); resreg[res_idx++] = r; } /* Count the float/ints we pushed */ fp_idx++; arg_idx++;}define_insn(push_double, fpushl_xRC) { /* pushes the first 4 parameters in registers i4 to i7, rest -> stack */ int r; int w; debug_name(("push_double:\n")); arg_idx += arg_idx % 2; debug(("D -> [%d]\n",arg_idx)); /* If we've beyond NR_ARGUMENTS then it get easy. */ if (arg_idx >= NR_ARGUMENTS) { /* Put in argument stack */ r = rreg_double(1); w = SLOT2PUSHOFFSET(arg_idx); /* FIX use sdc1 */ ldst_RRC(_SWC1, r, REG_sp, w+LOFFSET); debug((" swc1 %s,%d[sp]\n", fregname(r), w+LOFFSET)); ldst_RRC(_SWC1, r+1, REG_sp, w+HOFFSET); debug((" swc1 %s,%d[sp]\n", fregname(r+1), w+HOFFSET)); } /* If we've pushed ints already or we've pushed more than * two floats then we put it in a0-a3. Be careful since the * stack is backwards. */ else if (pushed_int || fp_idx >= 2) { /* dbmsg = 1; */ r = rreg_ideal_int(1, REG_i4+arg_idx+1); /* No macro for the following */ w = slotRegister(seq_slot(s, 1)+1, Rint, rread, REG_i4+arg_idx); assert(r == REG_i4+arg_idx+1); assert(w == r - 1); register_reserve(r); register_reserve(w); resreg[res_idx++] = r; resreg[res_idx++] = w; } /* Else we actually put the value in a float point register f12-f14. */ else { r = rreg_ideal_double(1, REG_f12+2*fp_idx); assert(r == 12+2*fp_idx); register_reserve(r); register_reserve(r+1); resreg[res_idx++] = r; resreg[res_idx++] = r+1; } /* Count the double/longs we pushed */ fp_idx++; arg_idx += 2;}define_insn(popargs, popargs_xxC) { int r; debug_name(("popargs:\n")); for (r = 0; r < res_idx; r++) { register_unreserve(resreg[r]); } if (arg_idx > max_args) { max_args = arg_idx; } arg_idx = 0; fp_idx = 0; pushed_int = 0; res_idx = 0;}define_insn(return_int, return_Rxx) { debug_name(("return_int:\n")); forceRegister(seq_dst(s), REG_i2, Rint);}define_insn(return_long, returnl_Rxx) { debug_name(("return_long:\n")); forceRegister(seq_dst(s), REG_i2, Rint); forceRegister(seq_dst(s)+1, REG_i3, Rint);}define_insn(return_float, freturn_Rxx) { debug_name(("return_float:\n")); forceRegister(seq_dst(s), REG_f0, Rfloat);}define_insn(return_double, freturnl_Rxx) { debug_name(("return_double:\n")); forceRegister(seq_dst(s), REG_f0, Rdouble);}define_insn(returnarg_int, returnarg_xxR){ int r = rreg_int(2); debug_name(("returnarg_int:\n")); insn_RRR(_ADDU, REG_i2, r, REG_i0); debug((" mov %s,%s\n", regname(REG_i2), regname(r)));}define_insn(returnarg_long, returnargl_xxR){ int r1; int r2; REGSLOT* r; debug_name(("returnarg_long:\n")); r = seq_slot(s, 2); r1 = _slowSlotRegister(r, Rint, rread); r2 = _slowSlotRegister(r+1, Rint, rread); if (REG_i2 != r2) { insn_RRR(_ADDU, REG_i2, r1, REG_i0); insn_RRR(_ADDU, REG_i3, r2, REG_i0); } else if (REG_i3 != r1) { insn_RRR(_ADDU, REG_i2, r1, REG_i0); insn_RRR(_ADDU, REG_i3, r2, REG_i0); } else { /* gotta implement a swap */ abort(); } debug((" mov %s,%s\n", regname(REG_i2), regname(r1))); debug((" mov %s,%s\n", regname(REG_i3), regname(r2)));}define_insn(returnarg_float, freturnarg_xxR){ int r = rreg_float(2); debug_name(("returnarg_float:\n")); finsn_RRR(_FMOV, SINGLE_FORMAT, 0 /* $f0 */, r, 0, COP1); debug((" mov.s %s,%s\n", fregname(0), fregname(r)));}define_insn(returnarg_double, freturnargl_xxR){ int r = rreg_double(2); debug_name(("returnarg_double:\n")); finsn_RRR(_FMOV, DOUBLE_FORMAT, 0 /* $f0 */, r, 0, COP1); debug((" mov.d %s,%s\n", fregname(0), fregname(r)));}define_insn(get_arg_ptr, get_arg_ptr_R){ int w; debug_name(("get_arg_ptr:\n")); w = wreg_int(0); insn_RRR(_ADDU, w, REG_fp, REG_i0); debug((" mov %s,fp\n", regname(w)));}define_insn(fake_call, fakecall_xCC){ label* tol = const_label(2); label* froml = const_label(1); froml->type |= Lfuncrelative|Llong16; froml->at = CODEPC; ldst_RRC(_LW, REG_ra, REG_gp, 0); debug((" lw ra,?(gp)\n")); tol->type |= Lfuncrelative|Llong16; tol->at = CODEPC; ldst_RRC(_LW, REG_i25, REG_gp, 0); debug((" lw t9,?(gp)\n")); insn_RRR(_JALR, REG_i0, REG_i25, REG_i0); debug((" jr t9\n")); NOP();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -