📄 jit-alpha.def
字号:
* because of optimizations or other considerations. */ /* Calling Standard for Alpha Systems * 3.2.6.2.2 Exit Code Sequence Steps * 1. If the GP register has been modified or a call has been made, * restore the GP register to the GOT segment pointer of the current * procedure. * * NOT NEED, GP is already restored after each subroutine call. * see alpha_division(), call_ref(), call() and call_soft(). */ /* Calling Standard for Alpha Systems * 3.2.6.2.2 Exit Code Sequence Steps * 3. For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0), * reload any saved registers from the register save area as * specified by PDSC_RPD_RSA_OFFSET. Note that, for a variable-size * stack frame procedure (PDSC_FLAGS_BASE_REG_IS_FP is 1), FP is not * reloaded in this step. For a fixed-size stack frame procedure * (PDSC_FLAGS_BASE_REG_IS_FP is 0), $15 is reloaded if it was saved * on entry. * * 4. Reload the register that held the return address on entry with * the saved return address, if necessary. * * For a stack frame procedure (PDSC_FLAGS_REGISTER_FRAME is 0), * load the register designated by PDSC_RPD_ENTRY_RA ($26 in a * standard call) with the return address from the register save * area as specified by PDSC_RPD_RSA_OFFSET. */ /* return address */ l = newLabel(); l->type = Lrsa|Labsolute|Lgeneral; l->at = (uintp)CODEPC; op_ldq(REG_ra, REG_sp, 0); N = 1; /* registers s0 - s5 and fp (also know as s6) */ for (r = 0; r < 7; r++, N++) { l = newLabel(); l->type = Lrsa|Labsolute|Lgeneral; l->at = (uintp)CODEPC; op_ldq(REG_s0+r, REG_sp, SLOTSIZE * N); } /* registers f2 - f9 */ for (r = 0; r < (9 - 2 + 1); r++, N++) { l = newLabel(); l->type = Lrsa|Labsolute|Lgeneral; l->at = (uintp)CODEPC; op_ldt(REG_f2+r, REG_sp, SLOTSIZE * N); } /* Calling Standard for Alpha Systems * 3.2.6.2.2 Exit Code Sequence Steps * 7. If a function value is not being returned on the stack, restore * SP to the value it had at procedure entry by adding the value in * PDSC_RDP_FRAME_SIZE to SP. In some cases, the returning procedure * leaves SP pointing to a lower stack address than it had on entry * to the procedure, as specified in Section 4.1.7. */ l = newLabel(); l->type = Lframe|Labsolute|Lgeneral; l->at = (uintp)CODEPC; op_lda(REG_sp, REG_sp, 0); /* Calling Standard for Alpha Systems * 3.2.6.2.2 Exit Code Sequence Steps * 8. Execute the ret $31,($n),0001 instruction, as described in * Section 3.2.6.2.1, to return control to the calling procedure. * In almost all cases the $n used will be $26 (the return address * register) because its value must be restored before the call * returns. */ op_ret(REG_zero, REG_ra, 1);}define_insn(eprologue, eprologue_xxx){ label *l; /* Reload GP, CALL_KAFFE_EXCEPTION() does jmp ($27) to go here * and FP set. */ alpha_ldgp(REG_pv); l = newLabel(); l->type = Lnegframe|Labsolute|Lgeneral; l->at = (uintp)CODEPC; op_lda(REG_sp, REG_fp, 0);}/* --------------------------------------------------------------------- */define_insn(spill_int, spilli_RCx){ int r = sreg_int(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); /* Always spill integers in wide mode, so that we don't end up with garbage when slots are manipulated in "any" mode, e.g. with dup. */ op_stq(r, REG_fp, o);}define_insn(spill_ref, spillr_RCx){ int r = sreg_ref(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_stq(r, REG_fp, o);}define_insn(spill_long, spilll_RCx){ int r = sreg_long(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_stq(r, REG_fp, o);}define_insn(spill_float, spillf_RCx){ int r = sreg_float(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_sts(r, REG_fp, o);}define_insn(spill_double, spilld_RCx){ int r = sreg_double(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_stt(r, REG_fp, o);}define_insn(reload_int, reloadi_RCx){ int r = lreg_int(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_ldl(r, REG_fp, o);}define_insn(reload_ref, reloadr_RCx){ int r = lreg_ref(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_ldq(r, REG_fp, o);}define_insn(reload_long, reloadl_RCx){ int r = lreg_long(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_ldq(r, REG_fp, o);}define_insn(reload_float, reloadf_RCx){ int r = lreg_float(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_lds(r, REG_fp, o);}define_insn(reload_double, reloadd_RCx){ int r = lreg_double(0); int o = const_int(1); assert(o >= -0x8000 && o < 0x8000); op_ldt(r, REG_fp, o);}/* --------------------------------------------------------------------- */static voidalpha_move_const_32(int w, int val){ long hi, lo, extra, tmp; int b = REG_zero; lo = (short)val; tmp = val - lo; hi = (short)(tmp >> 16); if (tmp - (hi << 16)) { extra = 0x4000; tmp -= 0x40000000; hi = (short)(tmp >> 16); } else { extra = 0; } if (extra) op_ldah(w, b, extra), b = w; if (hi) op_ldah(w, b, hi), b = w; op_lda(w, b, lo);}#define alpha_move_const_pool(w, l, t, d, op) \ do { \ constpool *_c = newConstant((t), (d)); \ label *_l = ((l) ? (l) : newLabel()); \ int _w = (w); \ \ _l->from = 0; \ _l->to = (uintp)_c; \ _l->at = CODEPC; \ \ /* We shouldn't need _this_much gp space per function. \ Hell, we don't allow that much per C object file. \ _l->type = Lconstant|Lrelative|Llong16x16; \ op_ldah(_w, REG_gp, 0); */ \ \ _l->type = Lconstant|Lrelative|Llong16|Lrangecheck; \ op(_w, REG_gp, 0); \ } while (0)define_insn(move_int_const, movei_RxC){ alpha_move_const_32(wreg_int(0), const_int(2));}/* We manipulate the constpool ourselves here so that (1) we don't waste too many registers, and (2) so that we can overlap the long offset addition with the actual load. */define_insn(move_ref_const, mover_RxC){ long r = const_long(2); int w = wreg_ref(0); if (alpha_s32_rangecheck(r)) { alpha_move_const_32(w, r); } else { alpha_move_const_pool(w, NULL, CPref, r, op_ldq); }}define_insn(move_long_const, movel_RxC){ long r = const_long(2); int w = wreg_long(0); if (alpha_s32_rangecheck(r)) { alpha_move_const_32(w, r); } else { alpha_move_const_pool(w, NULL, CPlong, r, op_ldq); }}define_insn(move_label_const, move_RxL){ label* l = const_label(2); int w = wreg_ref(0); l->type |= Lrelative | Llong16x16 | Lrangecheck; l->at = CODEPC; l->from = 0; op_ldah(w, REG_gp, 0); op_lda(w, w, 0);}define_insn(move_float_const, movef_RxC){ jvalue d; int w; d.d = const_double(2); w = wreg_float(0); if (d.d == 0.0) { if (((d.j >> 63) & 1) != 0) { op_cpysn(REG_fzero, REG_fzero, w); } else { op_fmov(REG_fzero, w); } } else { alpha_move_const_pool(w, NULL, CPfloat, d.d, op_lds); }}define_insn(move_double_const, moved_RxC){ jvalue d; int w; d.d = const_double(2); w = wreg_double(0); if (d.d == 0.0) { if (((d.j >> 63) & 1) != 0) { op_cpysn(REG_fzero, REG_fzero, w); } else { op_fmov(REG_fzero, w); } } else { alpha_move_const_pool(w, NULL, CPdouble, d.d, op_ldt); }}define_insn(move_int, movei_RxR){ /* In general, we win by always forcing the source slot into a register so it's there for later. */ int r = rreg_int(2); int w = wreg_int(0); if (r != w) { op_mov(r, w); }}define_insn(move_ref, mover_RxR){ /* In general, we win by always forcing the source slot into a register so it's there for later. */ int r = rreg_ref(2); int w = wreg_ref(0); if (r != w) { op_mov(r, w); }}define_insn(move_long, movel_RxR){ /* In general, we win by always forcing the source slot into a register so it's there for later. */ int r = rreg_long(2); int w = wreg_long(0); if (r != w) { op_mov(r, w); }}define_insn(move_float, movef_RxR){ /* In general, we win by always forcing the source slot into a register so it's there for later. */ int r = rreg_float(2); int w = wreg_float(0); if (r != w) { op_fmov(r, w); }}define_insn(move_double, moved_RxR){ /* In general, we win by always forcing the source slot into a register so it's there for later. */ int r = rreg_double(2); int w = wreg_double(0); if (r != w) { op_fmov(r, w); }}/* --------------------------------------------------------------------- */define_insn(add_int_const, addi_RRC){ int o = const_int(2); int r = rreg_int(1); int w = wreg_int(0); if (o >= 0 && o <= 0xFF) { op_addl_i(r, o, w); } else if (o >= -0xFF && o <= 0) { op_subl_i(r, -o, w); } else { ABORT(); }}define_insn(add_ref_const, addr_RRC){ int o = const_int(2); int r = rreg_ref(1); int w = wreg_ref(0); assert(o >= -0x8000 && o < 0x8000); op_lda(w, r, o);}define_insn(add_long_const, addl_RRC){ int o = const_int(2); int r = rreg_long(1); int w = wreg_long(0); assert(o >= -0x8000 && o < 0x8000); op_lda(w, r, o);}define_insn(add_int, addi_RRR){ int r2 = rreg_int(2); int r1 = rreg_int(1); int w = wreg_int(0); op_addl(r1, r2, w);}define_insn(add_ref, addr_RRR){ int r2 = rreg_int(2); int r1 = rreg_ref(1); int w = wreg_ref(0); op_addq(r1, r2, w);}define_insn(add_long, addl_RRR){ int r2 = rreg_long(2); int r1 = rreg_long(1); int w = wreg_long(0); op_addq(r1, r2, w);}define_insn(add_float, addf_RRR){ int r2 = rreg_float(2); int r1 = rreg_float(1); int w = wreg_float(0); int t = ((r1 == w) || (r2 == w)) ? REG_ft : w; alpha_jit_info.ieee = 1;#ifndef AXP_FULL_IEEE_FP op_adds(r1, r2, t);#else op_adds_su(r1, r2, t); op_trapb();#endif if (t == REG_ft) { op_fmov(t, w); }}define_insn(add_double, addd_RRR){ int r2 = rreg_double(2); int r1 = rreg_double(1); int w = wreg_double(0); int t = ((r1 == w) || (r2 == w)) ? REG_ft : w; alpha_jit_info.ieee = 1;#ifndef AXP_FULL_IEEE_FP op_addt(r1, r2, t);#else op_addt_su(r1, r2, t); op_trapb();#endif if (t == REG_ft) { op_fmov(t, w); }}define_insn(sub_int_const, subi_RRC){ int o = const_int(2); int r = rreg_int(1); int w = wreg_int(0); if (o >= 0 && o <= 0xFF) { op_subl_i(r, o, w); } else if (o >= -0xFF && o <= 0) { op_addl_i(r, -o, w); } else { ABORT(); }}define_insn(sub_long_const, subl_RRC){ int o = const_int(2); int r = rreg_long(1); int w = wreg_long(0); assert(o > -0x8000 && o <= 0x8000); op_lda(w, r, -o);}define_insn(sub_int, subi_RRR){ int r2 = rreg_int(2); int r1 = rreg_int(1); int w = wreg_int(0); op_subl(r1, r2, w);}define_insn(sub_long, subl_RRR){ int r2 = rreg_long(2); int r1 = rreg_long(1); int w = wreg_long(0); op_subq(r1, r2, w);}define_insn(sub_float, subf_RRR){ int r2 = rreg_float(2); int r1 = rreg_float(1); int w = wreg_float(0); int t = ((r1 == w) || (r2 == w)) ? REG_ft : w; alpha_jit_info.ieee = 1;#ifndef AXP_FULL_IEEE_FP op_subs(r1, r2, t);#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -