#include "vm/types.h"
#include "md-abi.h"
-
-#include "vm/jit/emit.h"
-#include "vm/jit/jit.h"
#include "vm/jit/powerpc64/codegen.h"
-#include "vm/builtin.h"
+#include "vm/builtin.h"
+#include "vm/jit/emit-common.h"
+#include "vm/jit/jit.h"
-/* code generation functions **************************************************/
/* emit_load *******************************************************************
*******************************************************************************/
-s4 emit_load(jitdata *jd, instruction *iptr, stackptr src, s4 tempreg)
+s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
{
codegendata *cd;
s4 disp;
if (src->flags & INMEMORY) {
COUNT_SPILLS;
- disp = src->regoff * 8;
+ disp = src->vv.regoff * 8;
if (IS_FLT_DBL_TYPE(src->type)) {
if (IS_2_WORD_TYPE(src->type))
M_DLD(tempreg, REG_SP, disp);
else
M_FLD(tempreg, REG_SP, disp);
-
- } else {
- if (IS_2_WORD_TYPE(src->type))
+ }
+ else {
+ /* if (IS_2_WORD_TYPE(src->type))
M_LLD(tempreg, REG_SP, disp);
else
M_ILD(tempreg, REG_SP, disp);
+ */
+ M_LLD(tempreg, REG_SP, disp);
}
reg = tempreg;
- } else
- reg = src->regoff;
-
- return reg;
-}
-
-
-/* emit_load_s1 ****************************************************************
-
- Emits a possible load of the first source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s1(jitdata *jd, instruction *iptr, s4 tempreg)
-{
- stackptr src;
- s4 reg;
-
- src = iptr->s1.var;
-
- reg = emit_load(jd, iptr, src, tempreg);
-
- return reg;
-}
-
-
-/* emit_load_s2 ****************************************************************
-
- Emits a possible load of the second source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s2(jitdata *jd, instruction *iptr, s4 tempreg)
-{
- stackptr src;
- s4 reg;
-
- src = iptr->sx.s23.s2.var;
-
- reg = emit_load(jd, iptr, src, tempreg);
-
- return reg;
-}
-
-
-/* emit_load_s3 ****************************************************************
-
- Emits a possible load of the third source operand.
-
-*******************************************************************************/
-
-s4 emit_load_s3(jitdata *jd, instruction *iptr, s4 tempreg)
-{
- stackptr src;
- s4 reg;
-
- src = iptr->sx.s23.s3.var;
-
- reg = emit_load(jd, iptr, src, tempreg);
+ }
+ else
+ reg = src->vv.regoff;
return reg;
}
-
/* emit_store ******************************************************************
Emits a possible store to a variable.
*******************************************************************************/
-void emit_store(jitdata *jd, instruction *iptr, stackptr dst, s4 d)
+void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
{
codegendata *cd;
if (IS_FLT_DBL_TYPE(dst->type)) {
if (IS_2_WORD_TYPE(dst->type))
- M_DST(d, REG_SP, dst->regoff * 8);
+ M_DST(d, REG_SP, dst->vv.regoff * 8);
else
- M_FST(d, REG_SP, dst->regoff * 8);
-
- } else {
- M_LST(d, REG_SP, dst->regoff * 8);
+ M_FST(d, REG_SP, dst->vv.regoff * 8);
+ }
+ else {
+ M_LST(d, REG_SP, dst->vv.regoff * 8);
}
}
}
-/* emit_store_dst **************************************************************
-
- Emits a possible store to the destination operand of an instruction.
-
-*******************************************************************************/
-
-void emit_store_dst(jitdata *jd, instruction *iptr, s4 d)
-{
- emit_store(jd, iptr, iptr->dst.var, d);
-}
-
-
/* emit_copy *******************************************************************
- XXX
+ Generates a register/memory to register/memory copy.
*******************************************************************************/
-void emit_copy(jitdata *jd, instruction *iptr, stackptr src, stackptr dst)
+void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
{
codegendata *cd;
registerdata *rd;
cd = jd->cd;
rd = jd->rd;
- if ((src->regoff != dst->regoff) ||
- ((src->flags ^ dst->flags) & INMEMORY)) {
+ if ((src->vv.regoff != dst->vv.regoff) ||
+ ((src->flags ^ dst->flags) & INMEMORY)) {
- d = codegen_reg_of_var(rd, iptr->opc, dst, REG_IFTMP);
- s1 = emit_load_s1(jd, iptr, src, d);
+ /* If one of the variables resides in memory, we can eliminate
+ the register move from/to the temporary register with the
+ order of getting the destination register and the load. */
- if (IS_FLT_DBL_TYPE(src->type))
- M_FLTMOVE(s1, d);
- else
- M_INTMOVE(s1, d);
+ if (IS_INMEMORY(src->flags)) {
+ d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
+ s1 = emit_load(jd, iptr, src, d);
+ }
+ else {
+ s1 = emit_load(jd, iptr, src, REG_IFTMP);
+ d = codegen_reg_of_var(iptr->opc, dst, s1);
+ }
+
+ if (s1 != d) {
+ if (IS_FLT_DBL_TYPE(src->type))
+ M_FMOV(s1, d);
+ else
+ M_MOV(s1, d);
+ }
emit_store(jd, iptr, dst, d);
}
codegendata *cd;
registerdata *rd;
s4 s1, p, t, d;
-/* int stack_off; */
int stack_size;
methoddesc *md;
/* mark trace code */
M_NOP;
- /* save up to TRACE_ARGS_NUM arguments into the reserved stack space */
-#if 0
-#if defined(__DARWIN__)
- /* Copy Params starting from first to Stack */
- /* since TRACE_ARGS == INT_ARG_CNT all used integer argument regs */
- /* are saved */
- p = 0;
-#else
- /* Copy Params starting from fifth to Stack (INT_ARG_CNT/2) are in */
- /* integer argument regs */
- /* all integer argument registers have to be saved */
- for (p = 0; p < 8; p++) {
- d = rd->argintregs[p];
- /* save integer argument registers */
- M_LST(d, REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + 8 + p * 8);
- }
- p = 4;
-#endif
-#endif
M_MFLR(REG_ZERO);
M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
M_STDU(REG_SP, REG_SP, -stack_size);
}
}
- /* load first 4 (==INT_ARG_CNT/2) arguments into integer registers */
#if defined(__DARWIN__)
- for (p = 0; p < 8; p++) {
- d = rd->argintregs[p];
- M_ILD(d, REG_SP, LA_SIZE + p * 4);
- }
+ #warning "emit_verbosecall_enter not implemented"
#else
/* LINUX */
/* Set integer and float argument registers for trace_args call */
M_JSR;
#if defined(__DARWIN__)
- /* restore integer argument registers from the reserved stack space */
-
- stack_off = LA_SIZE;
- for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++, stack_off += 8) {
- t = md->paramtypes[p].type;
-
- if (IS_INT_LNG_TYPE(t)) {
- if (!md->params[p].inmemory) {
- M_LLD(rd->argintregs[md->params[p].regoff], REG_SP, stack_off);
- } else {
- assert(0);
- }
- }
- }
+ #warning "emit_verbosecall_enter not implemented"
#else
/* LINUX */
for (p = 0; p < md->paramcount && p < TRACE_ARGS_NUM; p++) {
- d = rd->argintregs[p];
- /* restore integer argument registers */
- M_LLD(d, REG_SP, LA_SIZE + PA_SIZE + 8 + p * 8);
+ t = md->paramtypes[p].type;
+ if (IS_INT_LNG_TYPE(t)) {
+ if (!md->params[p].inmemory) { /* Param in Arg Reg */
+ /* restore integer argument registers */
+ M_LLD(rd->argintregs[p], REG_SP, LA_SIZE + PA_SIZE + 8 + p * 8);
+ } else {
+ assert(0); /* TODO: implement this */
+ }
+ } else { /* FLT/DBL */
+ if (!md->params[p].inmemory) { /* Param in Arg Reg */
+ M_DLD(rd->argfltregs[md->params[p].regoff], REG_SP, LA_SIZE + PA_SIZE + 8 + p * 8);
+ } else {
+ assert(0); /* this shoudl never happen */
+ }
+
+ }
}
#endif
M_ALD(REG_ZERO, REG_SP, stack_size + LA_LR_OFFSET);