📄 jit3-powerpc.def
字号:
/* This is -*- C -*- *//* * jit3-powerpc.def * * Copyright (c) 2002, 2004 The University of Utah and the Flux Group. * All rights reserved. * * @JANOSVM_KAFFE_JANOSVM_LICENSE@ */#include "jit.h"#include "jit-labels.h"#include "icode.h"#include "ppc_isa.h"#include "code-analyse.h"#include "constpool.h"#include "ppc_macros.h"/* * I just stole the arm jit3 files edited them, so some of that cruft is left * over. *//* * debugging stuff. * XXX clean me. */#if 1#undef ppc_op_ctxt#define ppc_op_ctxt CODEPC#undef ppc_op_debug#define ppc_op_debug(args) (jit_debug ? (my_op_debug args) : 0)int my_op_debug(int ctxt, const char *fmt, ...){ va_list args; va_start(args, fmt); fprintf(stderr, "%d\t", ctxt); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); return( 0 );}#define DBOUT stderr#define debug(x) (jit_debug ? (fprintf x) : 0 )#else#define debug(x)#endifint jit_debug;/* --------------------------------------------------------------------- */define_insn(unimplemented, unimplemented){ abort();}define_insn(nop, nop){ LOUT (ppc_op_nop());}/* --------------------------------------------------------------------- *//* XXX */int r31FunctionStartOffset;define_insn(prologue, prologue_xxx){ int has_pool = 0; Method* meth; label *pl; pl = const_label(1); meth = const_method(2); /* * Either, this method is not a leaf or we have a constpool and need * to overwrite LR to get at it. */ if( (KaffeJIT3_getFirstConst() != KaffeJIT3_getCurrConst()) || maxLocal || maxTemp ) { has_pool = 1; } if( has_pool ) { int localRegs; /* * We'll be overwriting the LR in a bit, move it out so we can * save it later. */ LOUT(ppc_op_mflr(PPC_R0)); localRegs = maxLocal + maxTemp + 1; /* * We atleast need to save R31 because it's used to hold the * function base and thus the base for the constpool. */ if( localRegs == 1 ) { LOUT(ppc_op_stw(PPC_R31, PPC_RSP, -SLOTSIZE-72)); } else { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Labsolute | Lgeneral; l->at = CODEPC; l->to = 0; l = KaffeJIT3_newLabel(); l->type = Lreg_s | Labsolute | Lgeneral; l->at = CODEPC; LOUT(ppc_op_stmw(0, PPC_RSP, 0)); } /* Stuff the LR in the caller's linkage area. */ LOUT(ppc_op_stw(PPC_R0, PPC_RSP, PPC_FRAME_LR)); pl->type = Lnegframe | Labsolute | Lgeneral; pl->at = CODEPC; /* * Only update the stack pointer if we're not a * leaf. */ LOUT(ppc_op_stwu(PPC_RSP, PPC_RSP, 0)); // XXX /* Branch to the next instruction (no cost... i think) */ LOUT(ppc_op_bc(PPC_BO_ALWAYS, 0, ppc_bd16(sizeof(ppc_code_t))) | PPC_OPTION_LK); /* * The link register points to the internals of this method * save it and the offset from the start of the function. */ r31FunctionStartOffset = CODEPC; LOUT(ppc_op_mflr(PPC_RFUNCTION_BASE)); } else { r31FunctionStartOffset = -1; } /* If we have arguments we need to tell the register allocator. */ if( maxArgs ) { int dbl_skip = 0, limit = PPC_ARG_REGISTER_COUNT; int lpc, gpr_off = 0, fpr_off; { void printSlots(FILE *file); // printSlots(stderr); } if( !isStatic ) { /* Prepend "this" argument. */ gpr_off += 1; dbl_skip += 1; limit -= 1; preloadRegister(localinfo[0].slot, Rref, PPC_RARG0); } /* Figure out the number of arguments in registers. */ if( METHOD_NARGS(meth) < limit ) limit = METHOD_NARGS(meth);#if defined(__APPLE__) /* * Force argument slots to correspond to the appropriate * registers. On darwin, this means we skip gpr's when floats * and doubles are also passed in. */ for( lpc = 0, fpr_off = 0; lpc < limit; gpr_off++, lpc++ ) { switch( *METHOD_ARG_TYPE(meth, lpc) ) { case 'D': /* Double's correspond to two gpr's. */ gpr_off++; preloadRegister(localinfo[lpc + dbl_skip].slot, Rdouble, PPC_FPRARG0 + fpr_off); dbl_skip++; fpr_off++; break; case 'F': preloadRegister(localinfo[lpc + dbl_skip].slot, Rfloat, PPC_FPRARG0 + fpr_off); fpr_off++; break; case 'L': case '[': preloadRegister(localinfo[lpc + dbl_skip].slot, Rref, PPC_RARG0 + gpr_off); break; case 'J': preloadRegister(localinfo[lpc + dbl_skip].slot, Rint, PPC_RARG0 + gpr_off); gpr_off++; dbl_skip++; /* FALLTHROUGH */ default: preloadRegister(localinfo[lpc + dbl_skip].slot, Rint, PPC_RARG0 + gpr_off); break; } }#else for( lpc = 0, fpr_off = 0; lpc < limit; lpc++ ) { switch( *METHOD_ARG_TYPE(meth, lpc) ) { case 'D': preloadRegister(localinfo[lpc + dbl_skip].slot, Rdouble, PPC_FPRARG0 + fpr_off); dbl_skip++; fpr_off++; break; case 'F': preloadRegister(localinfo[lpc + dbl_skip].slot, Rfloat, PPC_FPRARG0 + fpr_off); fpr_off++; break; case 'L': case '[': preloadRegister(localinfo[lpc + dbl_skip].slot, Rref, PPC_RARG0 + gpr_off); gpr_off++; break; case 'J': preloadRegister(localinfo[lpc + dbl_skip].slot, Rint, PPC_RARG0 + gpr_off); gpr_off++; dbl_skip++; /* FALLTHROUGH */ default: preloadRegister(localinfo[lpc + dbl_skip].slot, Rint, PPC_RARG0 + gpr_off); gpr_off++; break; } }#endif { void printSlots(FILE *file); // printSlots(stderr); } }}define_insn(exception_prologue, eprologue_xxx){ if( r31FunctionStartOffset > 0 ) {#if 1#elif 1 label *l = KaffeJIT3_newLabel(); l->type = Lframe | Labsolute | Lgeneral; l->at = CODEPC; LOUT(ppc_op_lmw(14, PPC_RSP, 0));#else label *l = const_label(1); l->type = Linternal | Labsolute | Llong16x16; l->from = 0; l->at = CODEPC; l->to = r31FunctionStartOffset; LOUT(ppc_op_li(PPC_RCONST_POOL, 0)); LOUT(ppc_op_addis(PPC_RCONST_POOL, PPC_RCONST_POOL, 0));#endif // debug((DBOUT,"exception_prologue %s\n",KaffeJIT3_getLabelName(l))); }}define_insn(epilogue, epilogue_xxx){ label *el; if( (el = KaffeJIT3_getLastEpilogueLabel()) && (el->at == (CODEPC - 4)) ) { /* * Nothing to jump over to get to the epilogue... Replace * the jump code with regular epilogue. */ el->type = Lnull; CODEPC -= 4; } else if( el && (el->at != (CODEPC - 4)) ) { /* The function ends with a throw, not a return. */ } KaffeJIT3_setEpilogueLabel(CODEPC); if( (KaffeJIT3_getFirstConst() != KaffeJIT3_getCurrConst()) || maxLocal || maxTemp ) { int lrOffset = 0, localRegs; label *fl; fl = KaffeJIT3_newLabel(); fl->type = Lframe | Lrelative | Lgeneral; fl->at = CODEPC; fl->from = PPC_FRAME_LR; fl->to = 0; /* * Load the original LR back into R0. * * Note: We do the load early so it can run in parallel while * we readjust the stack pointer. */ LOUT(ppc_op_lwz(PPC_R0, PPC_RSP, lrOffset)); fl = KaffeJIT3_newLabel(); fl->type = Lframe | Labsolute | Lgeneral; fl->at = (uintp)CODEPC; LOUT(ppc_op_addi(PPC_RSP, PPC_RSP, 0)); LOUT(ppc_op_mtlr(PPC_R0)); /* Restore and local registers. */ localRegs = maxLocal + maxTemp + 1; if( localRegs == 1 ) { LOUT(ppc_op_lwz(PPC_R31, PPC_RSP, -4-72)); } else { label *l; l = KaffeJIT3_newLabel(); l->type = Lsavedregs | Labsolute | Lgeneral; l->at = CODEPC; l->to = 0; l = KaffeJIT3_newLabel(); l->type = Lreg_s | Labsolute | Lgeneral; l->at = CODEPC; LOUT(ppc_op_lmw(0, PPC_RSP, 0)); } } /* Branch back to the caller. */ LOUT(ppc_op_blr());}#if defined(STACK_LIMIT)define_insn(check_stack_limit, check_stack_limit_xRC){ int r = rreg_int(1); label* l = const_label(2);#if 1#else op_cmp(SP, r); op_branch(CC_HI, 8); l->type = Lconstant | Labsolute | Loffset12; l->at = CODEPC; op_load_offset(r, CONSTPOOL_BASE, -128); debug((DBOUT,"load_label_const r%d, ?\n", r)); op_mov(LR, PC); op_mov(PC, r);#endif debug((DBOUT,"load_label_const r%d, ?\n", r));}#endif/* --------------------------------------------------------------------- */define_insn(spill_int, spill_Rxx){ int r = sreg_int(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; LOUT(ppc_op_stw(r, PPC_RSP, 0)); { void printSlots(FILE *file); // printSlots(stderr); } debug((DBOUT,"spill_int %d, [FP, %d(%p)]\n", r, o, seq_slot(s, 1)));}define_insn(spill_float, fspill_Rxx){ int r = sreg_float(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; LOUT(ppc_op_stfs(r, PPC_RSP, 0)); debug((DBOUT,"spill_float %d, [FP, %d]\n", r, o));}define_insn(spill_double, fspilll_Rxx){ int r = sreg_double(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; /* XXX Alignment needed here? e.g. o >> 2 */ LOUT(ppc_op_stfd(r, PPC_RSP, 0)); debug((DBOUT,"spill_double %d, [FP, %d]\n", r, o));}define_insn(reload_int, reload_Rxx){ int r = lreg_int(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; LOUT(ppc_op_lwz(r, PPC_RSP, 0)); debug((DBOUT,"reload_int %d, [FP, %d(%p)]\n", r, o, seq_slot(s, 1)));}define_insn(reload_float, freload_Rxx){ int r = lreg_float(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; LOUT(ppc_op_lfs(r, PPC_RSP, 0)); debug((DBOUT,"reload_float %d, [FP, %d]\n", r, o));}define_insn(reload_double, freloadl_Rxx){ int r = lreg_double(0); int o = const_int(1); label *l; l = KaffeJIT3_newLabel(); l->type = Llong16noalign | Lexternal | Labsolute; l->at = CODEPC; l->to = o; LOUT(ppc_op_lfd(r, PPC_RSP, 0)); debug((DBOUT,"reload_double %d, [FP, %d]\n", r, o));}voidmovereg_RR(int toreg, int fromreg){ if( toreg != fromreg ) LOUT(ppc_op_mr(toreg, fromreg));}voidfmovereg_RR(int toreg, int fromreg){ if( toreg != fromreg ) LOUT(ppc_op_fmr(toreg, fromreg));}/* --------------------------------------------------------------------- */define_insn(move_int_const, move_RxC){ int val = const_int(2); int w = wreg_int(0); /* cwg 3.2.3.1 */ switch( val & 0xffff8000 ) { case 0xffff8000: /* Its a negative 16 bit number. */ case 0x00000000: /* Its a positive 16 bit number. */ LOUT(ppc_op_li(w, val)); break; default: /* Its a full 32 bit number. */ /* * In reality, this won't get used at the moment, but its nice * to have as a reference. */ LOUT(ppc_op_li(w, ppc_lo16(val))); LOUT(ppc_op_addis(w, w, (val & 0x00008000) ? ppc_ha16(val) : ppc_hi16(val))); break; }}//// This doesn't get used as much as it used to// since most constants are stored in the// constant pool and referenced via load_constpool_<type>//// However, this is still needed to assemble a 32-bit// constant inline.//define_insn(move_label_const, move_RxL){ label* l = const_label(2); int w = wreg_int(0); l->type |= Llong16x16|Labsolute; l->at = CODEPC; LOUT(ppc_op_li(w, 0)); LOUT(ppc_op_addis(w, w, 0)); debug((DBOUT,"move_label_const %d, ?\n", w));}define_insn(load_constpool_int, ld_RxL){ label* l = const_label(2); int w = wreg_int(0); l->type = Lconstant | Lrelative | Llong16noalign; l->from = r31FunctionStartOffset; l->at = CODEPC; LOUT(ppc_op_lwz(w, PPC_RCONST_POOL, 0)); debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(load_constpool_float, fld_RxL){ label* l = const_label(2); int w = wreg_float(0); l->type = Lconstant | Lrelative | Llong16noalign; l->from = r31FunctionStartOffset; l->at = CODEPC; LOUT(ppc_op_lfs(w, PPC_RCONST_POOL, 0)); debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(load_constpool_double, fldl_RxL){ label* l = const_label(2); int w = wreg_double(0); l->type = Lconstant | Lrelative | Llong16noalign; l->from = r31FunctionStartOffset; l->at = CODEPC; LOUT(ppc_op_lfd(w, PPC_RCONST_POOL, 0)); debug((DBOUT,"load_label_const %d, ?\n", w));}define_insn(move_int, move_RxR){ int r = rreg_int(2); int w = wreg_int(0); LOUT(ppc_op_mr(w, r)); debug((DBOUT,"move_int %d, %d\n", w, r));}define_insn(move_float, fmove_RxR){ int r = rreg_float(2); int w = wreg_float(0); LOUT(ppc_op_fmr(w, r)); debug((DBOUT,"move_float %d, %d\n", w, r));}define_insn(move_double, fmovel_RxR){ int r = rreg_double(2); int w = wreg_double(0); LOUT(ppc_op_fmr(w, r)); debug((DBOUT,"move_double %d, %d\n", w, r));}/* --------------------------------------------------------------------- */define_insn(neg_int, neg_RxR){ int r = rreg_int(2); int w = wreg_int(0); LOUT(ppc_op_neg(w, r)); debug((DBOUT,"neg_int %d, %d\n", w, r));}define_insn(neg_float, fneg_RxR){ int r = rreg_float(2); int w = wreg_float(0); LOUT(ppc_op_fneg(w, r)); debug((DBOUT,"neg_float %d, %d\n", w, r));}define_insn(neg_double, fnegl_RxR){ int r = rreg_double(2); int w = wreg_double(0); LOUT(ppc_op_fneg(w, r)); debug((DBOUT,"neg_double %d, %d\n", w, r));}define_insn(add_int, add_RRR){ int r2 = rreg_int(2); int r1 = rreg_int(1); int w = wreg_int(0); LOUT(ppc_op_add(w, r1, r2)); debug((DBOUT,"add_int %d, %d, %d\n", w, r1, r2));}define_insn(add_int_const, add_RRC){ int o = const_int(2); int r1 = rreg_int(1); int w = wreg_int(0); if ( o < 0 ) { debug((DBOUT,"sub_int_const %d, %d, %d\n", w, r1, -o)); } else { debug((DBOUT,"add_int_const %d, %d, %d\n", w, r1, o)); } LOUT(ppc_op_addi(w, r1, o));}define_insn(adc_int, adc_RRR){ int r2 = rreg_int(2); int r1 = rreg_int(1); int w = wreg_int(0); LOUT(ppc_op_addc(w, r1, r2)); debug((DBOUT,"adc_int %d, %d, %d\n", w, r1, r2));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -