📄 jit3-powerpc.def
字号:
l->type = Lsavedregs | Lrelative | Lgeneral; l->from = -8; l->to = 0; l->at = CODEPC; } LOUT(ppc_op_lfd(w, PPC_RSP, hi_offset)); LOUT(ppc_op_lfd(j, i, 0)); LOUT(ppc_op_fsub(w, w, j)); slot_free2tmp(tmp_si_gpr); slot_free2tmp(tmp_si_fpr); debug((DBOUT,"cvt_int_double %d, %d\n", w, r));}define_insn(cvt_float_int, cvtfi_RxR){ int r = rreg_float(2); int i; // intermediate int w = wreg_int(0); SlotInfo *tmp_si; SlotData *tmp; int hi_offset, lo_offset; /* cwg 3.3.8.1 */ /* Allocate a temporary float to store the converted number. */ slot_alloc2tmp(tmp_si); tmp = tmp_si->slot; hi_offset = -8; lo_offset = -4; /* Bind to a register. */ i = slotRegister(tmp, Rdouble, rwrite, NOREG); LOUT(ppc_op_frsp(i, r)); /* Convert the float and put it in our intermediate register. */ LOUT(ppc_op_fctiw(i, i)); /* Trigger a spill to the stack so that we can load it into a gpr. */ if( !hi_offset ) { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Lrelative | Lgeneral; l->from = -8; l->to = 0; l->at = CODEPC; } LOUT(ppc_op_stfd(i, PPC_RSP, hi_offset)); /* * Load least significant 32 bits of the number. (use Rint instead of * Rdouble) */ if( !hi_offset ) { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Lrelative | Lgeneral; l->from = -4; l->to = 0; l->at = CODEPC; } LOUT(ppc_op_lwz(w, PPC_RSP, lo_offset)); /* Free our temp. */ slot_free2tmp(tmp_si); debug((DBOUT,"cvt_float_int r%d, f%d\n", w, r));}define_insn(cvt_double_int, cvtdi_RxR){ int r = rreg_double(2); int i; // intermediate int w = wreg_int(0); SlotInfo *tmp_si; SlotData *tmp; int hi_offset, lo_offset; /* Allocate a temporary float to store the converted number. */ slot_alloc2tmp(tmp_si); tmp = tmp_si->slot; hi_offset = -8; lo_offset = -4; /* Bind to a register. */ i = slotRegister(tmp, Rdouble, rwrite, NOREG); /* Convert the float and put it in our intermediate register. */ LOUT(ppc_op_fctiw(i, r)); /* Trigger a spill to the stack so that we can load it into a gpr. */ if( !hi_offset ) { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Lrelative | Lgeneral; l->from = -8; l->to = 0; l->at = CODEPC; } LOUT(ppc_op_stfd(i, PPC_RSP, hi_offset)); /* * Load least significant 32 bits of the number. (use Rint instead of * Rdouble) */ if( !hi_offset ) { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Lrelative | Lgeneral; l->from = -4; l->to = 0; l->at = CODEPC; } LOUT(ppc_op_lwz(w, PPC_RSP, lo_offset)); /* Free our temp. */ slot_free2tmp(tmp_si); debug((DBOUT,"cvt_double_int %d, %d\n", w, r));}/* these aren't being used */define_insn(cvt_long_float, cvtlf_RxR){ /* Is a long a 64-bit quantity? */ debug((DBOUT,"NOT IMPLEMENTED: cvt_long_float\n"));}define_insn(cvt_long_double, cvtld_RxR){ debug((DBOUT,"NOT IMPLEMENTED: cvt_long_double\n"));}define_insn(cvt_float_double, cvtfd_RxR){ int r = rreg_float(2); int w = wreg_double(0); if( w != r ) LOUT(ppc_op_fmr(w, r)); debug((DBOUT,"cvt_float_double f%d, f%d\n",w,r));}define_insn(cvt_double_float, cvtdf_RxR){ int r = rreg_double(2); int w = wreg_float(0); LOUT(ppc_op_frsp(w, r)); debug((DBOUT,"cvt_double_float f%d, f%d\n",w,r));}/* --------------------------------------------------------------------- */define_insn(build_key, set_word_xxC){ jint val = const_int(2); LOUT(val); debug((DBOUT,"build_key %d", val));}define_insn(build_code_ref, set_wordpc_xxC){ label* l = const_label(2); l->type |= Llong|Labsolute; l->at = CODEPC; l->from = CODEPC; LOUT(0); debug((DBOUT,"build_code_ref (@0x%x to %s)\n", l->at, KaffeJIT3_getLabelName(l)));}/* --------------------------------------------------------------------- */define_insn(set_label, set_label_xxC){ label* l = const_label(2); l->to = CODEPC; debug((DBOUT,"set_label (@0x%x to 0x%x)\n", l->at, l->to));}define_insn(branch, branch_xCC){ label* l = const_label(1); int bt = const_int(2); l->type |= Llong16 | Lrelative; l->at = CODEPC; l->from = CODEPC; switch( bt ) { case ba: l->type &= ~Llong16; l->type |= Llong26; LOUT(ppc_op_b(0)); break; case beq: LOUT(ppc_op_bc(PPC_BO_TRUE(1), PPC_BI_CR_0 | PPC_BI_EQ, 0)); break; case bne: LOUT(ppc_op_bc(PPC_BO_FALSE(1), PPC_BI_CR_0 | PPC_BI_EQ, 0)); break; case blt: case bult: LOUT(ppc_op_bc(PPC_BO_TRUE(1), PPC_BI_CR_0 | PPC_BI_LT, 0)); break; case ble: LOUT(ppc_op_bc(PPC_BO_FALSE(1), PPC_BI_CR_0 | PPC_BI_GT, 0)); break; case bgt: case bugt: LOUT(ppc_op_bc(PPC_BO_TRUE(1), PPC_BI_CR_0 | PPC_BI_GT, 0)); break; case bge: case buge: LOUT(ppc_op_bc(PPC_BO_FALSE(1), PPC_BI_CR_0 | PPC_BI_LT, 0)); break; default: KAFFEVM_ABORT(); break; } debug((DBOUT,"branch type %d at 0x%x to %s\n", bt, l -> at, KaffeJIT3_getLabelName(l)));}define_insn(branch_and_link, branchl_xCC){ label* l = const_label(1); int bt = const_int(2); l->type |= Llong16 | Lrelative; l->at = CODEPC; l->from = CODEPC; switch( bt ) { case ba: l->type &= ~Llong16; l->type |= Llong26; LOUT(ppc_op_b(0) | PPC_OPTION_LK); break; case beq: /* * XXX We change the branch likely to be taken flag here * assuming this is a fake call branch. That may not always * be the case. */ LOUT(ppc_op_bc(PPC_BO_TRUE(0), PPC_BI_CR_0 | PPC_BI_EQ, 0) | PPC_OPTION_LK); break; case bne: LOUT(ppc_op_bc(PPC_BO_FALSE(0), PPC_BI_CR_0 | PPC_BI_EQ, 0) | PPC_OPTION_LK); break; case blt: case bult: LOUT(ppc_op_bc(PPC_BO_TRUE(0), PPC_BI_CR_0 | PPC_BI_LT, 0) | PPC_OPTION_LK); break; case ble: LOUT(ppc_op_bc(PPC_BO_FALSE(0), PPC_BI_CR_0 | PPC_BI_GT, 0) | PPC_OPTION_LK); break; case bgt: case bugt: LOUT(ppc_op_bc(PPC_BO_TRUE(0), PPC_BI_CR_0 | PPC_BI_GT, 0) | PPC_OPTION_LK); break; case bge: case buge: LOUT(ppc_op_bc(PPC_BO_FALSE(0), PPC_BI_CR_0 | PPC_BI_LT, 0) | PPC_OPTION_LK); break; default: KAFFEVM_ABORT(); break; } debug((DBOUT,"branch type %d at 0x%x to %s\n", bt, l -> at, KaffeJIT3_getLabelName(l)));}//// This is currently not used..//define_insn(call_ref, call_xCC){ label *sl, *l = const_label(1); sl = KaffeJIT3_newLabel(); sl->type = Lframe | Lrelative | Lgeneral; sl->at = CODEPC; sl->from = -72; LOUT(ppc_op_stmw(14, PPC_RSP, 0)); l->type |= Lrelative | Llong26; l->at = CODEPC; l->from = CODEPC; LOUT(ppc_op_b(0) | PPC_OPTION_LK); debug((DBOUT,"call_ref %p\n",(void *)l->to));}define_insn(call, call_xRC){ label *l = KaffeJIT3_newLabel(); int r = rreg_int(1); assert(const_int(2) == ba); l->type = Lframe | Lrelative | Lgeneral; l->at = CODEPC; l->from = -72; LOUT(ppc_op_stmw(14, PPC_RSP, 0)); LOUT(ppc_op_mtctr(r)); LOUT(ppc_op_bctrl()); debug((DBOUT,"call [%d]\n", r));}define_insn(branch_indirect, branch_indirect_xRC){ label *l = KaffeJIT3_newLabel(); int r = rreg_int(1); assert(const_int(2) == ba); l->type = Lframe | Lrelative | Lgeneral; l->at = CODEPC; l->from = -72; LOUT(ppc_op_stmw(14, PPC_RSP, 0)); LOUT(ppc_op_mtctr(r)); LOUT(ppc_op_bctr()); debug((DBOUT,"branch_indirect [r%d]\n", r));}struct _ppc_args { int next_register; int next_fregister; /* XXX */#define PPC_MAX_ARGS 32 int map[PPC_MAX_ARGS]; SlotData *source[PPC_MAX_ARGS]; int count;} ppc_args;int next_arg_register(int arg_index, int type, int *out_reserve_count){ int retval = -1; if( arg_index == 0 ) { ppc_args.next_register = PPC_RARG0; ppc_args.next_fregister = PPC_FPRARG0; } if( (ppc_args.next_register < (PPC_RARG0 + PPC_ARG_REGISTER_COUNT)) && (ppc_args.next_fregister < (PPC_FPRARG0 + PPC_FARG_REGISTER_COUNT)) ) { switch( type ) { case Rint: retval = ppc_args.next_register; ppc_args.next_register += 1; (*out_reserve_count) = 0; break; case Rfloat: retval = ppc_args.next_fregister; ppc_args.next_fregister++; (*out_reserve_count) = 1; break; case Rdouble: retval = ppc_args.next_fregister; ppc_args.next_fregister++; (*out_reserve_count) = 2; break; } } return( retval );}void ppc_push_arg(int type, SlotData *source){ int slot; slot = ppc_args.count++; ppc_args.map[slot] = type; ppc_args.source[slot] = source;}void ppc_finalize_args(void){ int lpc; ppc_args.next_register = PPC_RARG0; ppc_args.next_fregister = PPC_FPRARG0; for( lpc = (ppc_args.count - 1); lpc >= 0; lpc-- ) { int r, w, r_count; r = slotRegister(ppc_args.source[lpc], ppc_args.map[lpc], rread, NOREG); if( (w = next_arg_register(1, ppc_args.map[lpc], &r_count)) != -1 ) { int skip; if( r != w ) { clobberRegister(w); switch( ppc_args.map[lpc] ) { case Rint: LOUT(ppc_op_mr(w, r)); break; default: LOUT(ppc_op_fmr(w, r)); break; } } for( skip = 0; skip < r_count; skip++ ) { ppc_args.next_register += 1; register_reserve(w); } } else { /* XXX */ } } ppc_args.count = 0;}define_insn(pusharg_int, push_xRC){ int a = const_int(2); int r, w, r_count; if( (w = next_arg_register(a, Rint, &r_count)) != -1 ) { /* * can't use rreg_ideal_int because of brokeness. its possible * for this to create a move between a callee saved register * and a caller saved regsiter. And, since the pushargs are * run after the function_sync that does the spill, we can lose * the data in the register. */ r = rreg_int(1); if( r != w ) { clobberRegister(w); LOUT(ppc_op_mr(w, r)); } register_reserve(w); debug((DBOUT,"pusharg_int %d, %d\n", w, r)); } else { /* Out of argument registers, need to use the stack. */ r = rreg_int(1); LOUT(ppc_op_stw(r, PPC_RSP, PPC_FRAME_ARGS + (a * sizeof(register_storage_t)))); }}define_insn(push_float, fpush_xRC){ int a = const_int(2); int r_count, r, w; if( (w = next_arg_register(a, Rfloat, &r_count)) != -1 ) { int lpc; r = rreg_float(1); if( r != w ) { clobberRegister(w); LOUT(ppc_op_fmr(w, r)); } for( lpc = 0; lpc < r_count; lpc++ ) { ppc_args.next_register += 1; } register_reserve(w); } else { r = rreg_float(1); LOUT(ppc_op_stfs(r, PPC_RSP, PPC_FRAME_ARGS + (a * sizeof(register_storage_t)))); }}define_insn(push_double, fpushl_xRC){ int a = const_int(2); int r_count, r, w; if( (w = next_arg_register(a, Rdouble, &r_count)) != -1 ) { int lpc; r = rreg_double(1); if( r != w ) { clobberRegister(w); LOUT(ppc_op_fmr(w, r)); } for( lpc = 0; lpc < r_count; lpc++ ) { ppc_args.next_register += 1; } register_reserve(w); } else { r = rreg_double(1); LOUT(ppc_op_stfd(r, PPC_RSP, PPC_FRAME_ARGS + (a * sizeof(register_storage_t)))); }}define_insn(popargs, popargs_xxC){ int o = const_int(2); int lpc; /* Reset reserve bit for all register arguments */ for (lpc = 0; lpc < 4 && lpc < o; lpc++) { register_unreserve(PPC_RARG0 + lpc); }}define_insn(returnarg_int, returnarg_xxR){ int r = rreg_int(2); if( r != PPC_RRET ) LOUT(ppc_op_mr(PPC_RRET, r)); debug((DBOUT,"returnarg_int PPC_RRET,%d\n", r));}define_insn(returnarg_long, returnargl_xxR){ int rhi, rlo; REGSLOT* r; r = seq_slot(s, 2); rhi = _slowSlotRegister(r, Rint, rread); rlo = _slowSlotRegister(r+1, Rint, rread); debug((DBOUT,"returnarg_long R0,%d,%d\n", rhi, rlo)); /* * Return long is a bit complicated since part of the source may * be the destination. * * First we get the hi value in position. */ if( PPC_RRETHI != rhi ) { if( PPC_RRETHI == rlo ) { /* * Bah, the lo value occupies our destination, do a * quick register value exchange. */ LOUT(ppc_op_xor(rhi, rhi, rlo)); LOUT(ppc_op_xor(rlo, rlo, rhi)); LOUT(ppc_op_xor(rhi, rhi, rlo)); rlo = rhi; } else { /* Its garbage, overwrite it. */ LOUT(ppc_op_mr(PPC_RRETHI, rhi)); } } if( PPC_RRETLO != rlo ) { /* Finally, move the lo register into place. */ LOUT(ppc_op_mr(PPC_RRETLO, rlo)); }}define_insn(returnarg_float, freturnarg_xxR){ int r = rreg_float(2); if( PPC_FPRRET != r ) LOUT(ppc_op_fmr(PPC_FPRRET, r)); debug((DBOUT,"returnarg_float PPC_FPRRET,%d\n", r));}define_insn(returnarg_double, freturnargl_xxR){ int r = rreg_double(2); if( PPC_FPRRET != r ) LOUT(ppc_op_fmr(PPC_FPRRET, r)); debug((DBOUT,"returnarg_double R0,%d\n", r));}define_insn(return_int, return_Rxx){ forceRegister(seq_dst(s), PPC_RRET, Rint); debug((DBOUT,"return_int R0\n"));}define_insn(return_long, returnl_Rxx){ forceRegister(seq_dst(s), PPC_RRETHI, Rint); forceRegister(seq_dst(s)+1, PPC_RRETLO, Rint); debug((DBOUT,"return_long R0,R1\n"));}define_insn(return_float, freturn_Rxx){ forceRegister(seq_dst(s), PPC_FPRRET, Rfloat); debug((DBOUT,"return_float F0\n"));}define_insn(return_double, freturnl_Rxx){ forceRegister(seq_dst(s), PPC_FPRRET, Rdouble); debug((DBOUT,"return_double F0\n"));}/* --------------------------------------------------------------------- */define_insn(fake_call, fakecall_xCC){ label *tol = const_label(2); label *froml = const_label(1); froml->type = Lnull; tol->type |= Llong16x16 | Labsolute; tol->at = CODEPC; tol->from = 0; LOUT(ppc_op_li(PPC_R3, 0)); LOUT(ppc_op_addis(PPC_R3, PPC_R3, 0)); LOUT(ppc_op_mtctr(PPC_R3)); LOUT(ppc_op_bctr()); debug((DBOUT,"fake_call\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -