(PA_SIZE_IN_POINTERS): Removed.
(PA_SIZE): Removed.
(LA_LR_OFFSET): Removed.
(LA_SIZE_ALIGNED): Removed.
* src/vm/jit/m68k/emit.c (emit_verbosecall_enter): Removed
linking instructions, save only used registers.
(emit_verbosecall_exit): Likewise.
* src/vm/jit/m68k/arch.h (SUPPORT_FLOAT): Depends on
configure option ENABLE_SOFTFLOAT.
* src/vm/jit/m68k/codegen.c (codegen_emit): Use M_FSTORE/M_FLOAT
to save/restore float registers without converting any values.
Fixed offset of IsSync.
(codegen_emit_stub_native): Move floating point return values
into floating point registers.
* src/vm/jit/m68k/asmpart.S (asm_vm_call_method): Save/restore
floating point registers.
(asm_call_jit_compiler): Save/restore volatile floating point
registers.
(asm_patcher_wrapper): Likewise.
(asm_handle_exception): Use fmovemd instructions to restore
floatng point registers without converting.
* src/vm/jit/m68k/codegen.h (M_FSTORE): Added.
(M_FLOAT): Added.
/* float **********************************************************************/
-#define SUPPORT_FLOAT 1
-
-#if defined(ENABLE_SOFT_FLOAT_CMP)
-# define SUPPORT_FLOAT_CMP 0
+#if defined(ENABLE_SOFTFLOAT)
+ #define SUPPORT_FLOAT 0
+ #define SUPPORT_DOUBLE 0
+ #define SUPPORT_FLOAT_CMP 0
+ #define SUPPORT_DOUBLE_CMP 0
#else
-# define SUPPORT_FLOAT_CMP 1
+ #define SUPPORT_FLOAT 1
+ #define SUPPORT_DOUBLE 1
+
+ #if defined(ENABLE_SOFT_FLOAT_CMP)
+ #define SUPPORT_FLOAT_CMP 0
+ #else
+ #define SUPPORT_FLOAT_CMP 1
+ #endif
+
+ #if defined(ENABLE_SOFT_DOUBLE_CMP)
+ #define SUPPORT_DOUBLE_CMP 0
+ #else
+ #define SUPPORT_DOUBLE_CMP 1
+ #endif
+
#endif
/* double *********************************************************************/
-#define SUPPORT_DOUBLE 1
-
-#if defined(ENABLE_SOFT_FLOAT_CMP)
-# define SUPPORT_DOUBLE_CMP 0
-#else
-# define SUPPORT_DOUBLE_CMP 1
-#endif
#define HAS_ADDRESS_REGISTER_FILE 1
asm_vm_call_method_long:
asm_vm_call_method_float:
asm_vm_call_method_double:
+
+#if defined(ENABLE_SOFTFLOAT)
addal #(-11*4),%sp /* create stackframe to save registers */
moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
movel %sp@(11*4+1*4),%a2 /* methodinfo argument in atmp1 */
movel %sp@(11*4+3*4),%a3 /* args block */
movel %sp@(11*4+2*4),%d2 /* arg count */
+#else
+ addal #(-11*4-6*8), %sp
+ moveml %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@ /* save registers */
+ fmovemd %fp2/%fp3/%fp4/%fp5/%fp6/%fp7,%sp@(11*4) /* save registers */
+
+ /* fetch arguments from vmargs data structure */
+ movel %sp@(11*4+6*8+1*4),%a2 /* methodinfo argument in atmp1 */
+ movel %sp@(11*4+6*8+3*4),%a3 /* args block */
+ movel %sp@(11*4+6*8+2*4),%d2 /* arg count */
+#endif
+
moveal %sp, %a5 /* memorize stack */
tstl %d2 /* do we have arguments ? */
L_asm_vm_call_method_return:
movel %a5, %sp /* pop arguments off stack */
+
+#if defined(ENABLE_SOFTFLOAT)
moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
addal #(11*4),%sp /* restore stack */
+#else
+ fmovemd %sp@(11*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7 /* restore registers */
+ moveml %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp /* restore registers */
+ addal #(11*4+6*8),%sp /* restore stack */
+#endif
moveal %d0, %a0 /* return value in %a0, too */
asm_vm_call_method_end: /* symbol needed to insert method into avl tree */
rts /* return to c code */
addal #(-4*4),%sp /* create stackframe to save registers */
moveml %a0/%a1/%d0/%d1,%sp@ /* save volatile registers */
#if !defined(ENABLE_SOFTFLOAT)
- fmoved %fp0, %sp@-
- fmoved %fp1, %sp@-
+ addal #-8*2, %sp
+ fmovemd %fp0/%fp1, %sp@
movel %sp@(8*4), %sp@-
pea %sp@(8*4+8)
#else
moveal %d0, %a2 /* to tmp register */
#if !defined(ENABLE_SOFTFLOAT)
- fdmoved %sp@+, %fp1
- fdmoved %sp@+, %fp0
+ fmovemd %sp@, %fp0/%fp1
+ addal #8*2, %sp
#endif
moveml %sp@,%a0/%a1/%d0/%d1 /* restore volatile registers */
movel %sp, %d0
addil #4*4, %d0
#else
- fmoved %fp0, %sp@-
- fmoved %fp1, %sp@-
+ addal #-8*2, %sp
+ fmovemd %fp0/%fp1, %sp@
movel %sp, %d0
addil #8*4, %d0
bne L_asm_patcher_wrapper_exception
#if !defined(ENABLE_SOFTFLOAT)
- fdmoved %sp@+, %fp1
- fdmoved %sp@+, %fp0
+ fmovemd %sp@, %fp0/%fp1
+ addal #8*2, %sp
#endif
movel %sp@+, %d1
movel %sp@+, %d0
/* WARNING: the stack is still disturbed, look at asm_patcher_wrapper for details */
/* we do not need to restore the content of the registers, I hope */
#if !defined(ENABLE_SOFTFLOAT)
- lea %sp@(6*4), %sp
+ lea %sp@(8*4), %sp
#else
lea %sp@(4*4), %sp
#endif
movel %a3@(FltSave), %d0
cmpb #0,%d0
beq L_asm_handle_ex_flt_done
- fdmoved -(%a0), %fp7
+ fmovemd %a0@(-8), %fp7
cmpb #1,%d0
beq L_asm_handle_ex_flt_done
- fdmoved -(%a0), %fp6
+ fdmoved %a0@(-16), %fp6
cmpb #2,%d0
beq L_asm_handle_ex_flt_done
- fdmoved -(%a0), %fp5
+ fdmoved %a0@(-24), %fp5
L_asm_handle_ex_flt_done:
#else
(void) dseg_add_unique_s4(cd, 0); /* IsSync */
(void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
- /* XXX we use the IntSAce a split field for the adr now */
+ /* XXX we use the IntSave a split field for the adr now */
(void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
(void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
}
#if !defined(ENABLE_SOFTFLOAT)
for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
- p-=2; M_DST(rd->savfltregs[i], REG_SP, p*4);
+ p-=2; M_FSTORE(rd->savfltregs[i], REG_SP, p*4);
}
#else
assert(FLT_SAV_CNT == 0);
M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
}
- M_AST(REG_ATMP1, REG_SP, rd->memuse * 4 + 2*4);
+ M_AST(REG_ATMP1, REG_SP, rd->memuse * 4);
M_AST(REG_ATMP1, REG_SP, 0 * 4);
M_JSR_IMM(LOCK_monitor_enter);
}
case TYPE_DBL:
s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
if (iptr->opc == ICMD_BUILTIN) {
- M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
- M_DLD(s1, REG_SP, rd->memuse * 4);
+ M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
+ M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
} else {
M_DBLMOVE(REG_FRESULT, s1);
}
#if defined(ENABLE_THREADS)
/* call lock_monitor_exit */
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
- M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4 + 2*4);
+ M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4);
/* we need to save the proper return value */
/* we do not care for the long -> doubel convert space here */
case ICMD_DRETURN:
#endif
case ICMD_LRETURN:
- M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
+ M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
break;
#if defined(ENABLE_SOFTFLOAT)
case ICMD_FRETURN:
#endif
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_IST(REG_RESULT , REG_SP, rd->memuse * 4);
+ M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
break;
#if !defined(ENABLE_SOFTFLOAT)
case ICMD_FRETURN:
- M_FST(REG_FRESULT, REG_SP, rd->memuse * 4);
+ M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
case ICMD_DRETURN:
- M_DST(REG_FRESULT, REG_SP, rd->memuse * 4);
+ M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
#endif
}
case ICMD_DRETURN:
#endif
case ICMD_LRETURN:
- M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4);
+ M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
break;
#if defined(ENABLE_SOFTFLOAT)
case ICMD_FRETURN:
#endif
case ICMD_IRETURN:
case ICMD_ARETURN:
- M_ILD(REG_RESULT , REG_SP, rd->memuse * 4);
+ M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
break;
#if !defined(ENABLE_SOFTFLOAT)
case ICMD_FRETURN:
- M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4);
+ M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
case ICMD_DRETURN:
- M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4);
+ M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
break;
#endif
}
}
#if !defined(ENABLE_SOFTFLOAT)
for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
- p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
+ p -= 2; M_FLOAD(rd->savfltregs[i], REG_SP, p * 4);
}
#endif
/* deallocate stack */
switch (md->returntype.type) {
case TYPE_VOID: break;
-#if defined(ENABLE_SOFTFLOAT)
+ /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
case TYPE_DBL:
-#endif
case TYPE_LNG:
M_IST(REG_D1, REG_SP, 2 * 4);
/* fall through */
-#if defined(ENABLE_SOFTFLOAT)
case TYPE_FLT:
-#endif
case TYPE_INT:
case TYPE_ADR:
M_IST(REG_D0, REG_SP, 1 * 4);
break;
-#if !defined(ENABLE_SOFTFLOAT)
- /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
- case TYPE_FLT:
- M_INT2FLTMOVE(REG_D0, REG_D0);
- M_FST(REG_D0, REG_SP, 1 * 4);
- break;
- case TYPE_DBL:
- /* to convert %d0, %d1 to dbl we need 2 memory slots
- * it is safe reuse argument stack slots here */
- M_IST(REG_D0, REG_SP, 1 * 4);
- M_IST(REG_D1, REG_SP, 2 * 4);
- /*M_DST(REG_D0, REG_SP, 1 * 4);*/
- break;
-#endif
default: assert(0);
}
switch (md->returntype.type) {
case TYPE_VOID: break;
-#if defined(ENABLE_SOFTFLOAT)
case TYPE_DBL:
-#endif
case TYPE_LNG:
M_ILD(REG_D1, REG_SP, 2 * 4);
/* fall through */
-#if defined(ENABLE_SOFTFLOAT)
case TYPE_FLT:
-#endif
case TYPE_INT:
case TYPE_ADR:
M_ILD(REG_D0, REG_SP, 1 * 4);
break;
+ default: assert(0);
+ }
#if !defined(ENABLE_SOFTFLOAT)
+ /* additionally load values into floating points registers
+ * as cacao jit code expects them there */
+ switch (md->returntype.type) {
case TYPE_FLT:
M_FLD(REG_D0, REG_SP, 1 * 4);
break;
case TYPE_DBL:
M_DLD(REG_D0, REG_SP, 1 * 4);
break;
-#endif
- default: assert(0);
}
+#endif
/* restore saved registers */
M_AADD_IMM(cd->stackframesize*4, REG_SP);
#define M_IPUSH_IMM(a) OPWORD_IMM32(0x121,7,1, (a)) /* pea.l */
+#if 0
#define M_PUSHALL OPWORD_IMM16(0x123,2,REG_SP,0xFFFF) /* A0-A7, D0-D7 pushed onto stack */
#define M_POPALL OPWORD_IMM16(0x133,2,REG_SP,0xFFFF) /* A0-A7, D0-D7 poped off stack */
+#endif
/* M_XLD(a,b,c)....M_XLD(destinationreg, addressbase, offset) */
#define M_ILD(a,b,c) OPWORD_IMM16( ( (2<<6) | ((a) << 3) | 0), 5, (b), (c))
#if !defined(ENABLE_SOFTFLOAT)
#define M_FST(a,b,c) OPWORD_IMM32( 0x3c8, 5, (b), ( (( (0x19 <<10) | ((a)<<7) | 0 )<<16) | (((int16_t)(c)) & 0x0000ffff)) )
#define M_DST(a,b,c) OPWORD_IMM32( 0x3c8, 5, (b), ( (( (0x1d <<10) | ((a)<<7) | 0 )<<16) | (((int16_t)(c)) & 0x0000ffff)) )
+ #define M_FSTORE(a,b,c) OPWORD_IMM32( 0x3c8, 5, (b), ( ( (0xf << 12) | (1 << (7-(a))) ) <<16) | (((int16_t)(c)) & 0x0000ffff))
+ #define M_FLOAD(a,b,c) OPWORD_IMM32( 0x3c8, 5, (b), ( ( (0xd << 12) | (1 << (7-(a))) ) <<16) | (((int16_t)(c)) & 0x0000ffff))
#endif
/*M_XADD_IMM(a,b)...M_XADD_IMM(offset, reg) */
/* mark trace code */
M_NOP;
- M_LINK(REG_FP, -16*4);
+/*
+ M_AADD_IMM(-16*4, REG_SP);
M_PUSHALL;
+*/
+ M_IPUSH(REG_D0);
+ M_IPUSH(REG_D1);
+ M_APUSH(REG_A0);
+ M_APUSH(REG_A1);
+ M_AADD_IMM(-8*2, REG_SP);
+ M_FSTORE(REG_F0, REG_SP, 8);
+ M_FSTORE(REG_F1, REG_SP, 0);
/* builtin_verbosecall_enter takes all args as s8 type */
/* TRACE_ARGS_NUM is the number of args the builtin_verbosecall_enter expects */
M_IPUSH_IMM(m);
- disp = 16*4 + 4 + 4; /* points to old argument stack initially */
+ disp = 4*4 + 8*2 + 4; /* points to old argument stack initially */
/* travel up stack to the first argument of the function which needs to be copied */
for (i=0; (i < md->paramcount) && (i < TRACE_ARGS_NUM); i++) {
/* pop arguments off stack */
M_AADD_IMM(TRACE_ARGS_NUM*8+4, REG_SP);
- M_POPALL;
- M_UNLK(REG_FP);
+ M_FSTORE(REG_F1, REG_SP, 0);
+ M_FSTORE(REG_F0, REG_SP, 8);
+ M_AADD_IMM(8*2, REG_SP);
+ M_APOP(REG_A1);
+ M_APOP(REG_A0);
+ M_IPOP(REG_D1);
+ M_IPOP(REG_D0);
+
M_NOP;
}
void emit_verbosecall_exit(jitdata* jd)
/* mark trace code */
M_NOP;
- M_LINK(REG_FP, 0);
M_IPUSH_IMM(m); /* push methodinfo */
- M_IPUSH_IMM(0); /* TODO push float result */
-
- M_IPUSH_IMM(0); /* TODO push double result */
- M_IPUSH_IMM(0); /* TODO push double result */
+ M_AADD_IMM(-3*4, REG_SP);
+ M_FST(REG_D0, REG_SP, 8);
+ M_DST(REG_D0, REG_SP, 0);
M_IPUSH(GET_HIGH_REG(REG_RESULT_PACKED))
M_IPUSH(GET_LOW_REG(REG_RESULT_PACKED)) /* push long result */
M_IPOP(GET_LOW_REG(REG_RESULT_PACKED))
M_IPOP(GET_HIGH_REG(REG_RESULT_PACKED))
-#if 0
- /* that is wrong of course, overwrites registers and stuff */
- M_IPOP(0); /* TODO: pop double result */
- M_IPOP(0); /* TODO: pop double result */
+ M_DLD(REG_D0, REG_SP, 0)
+ M_FLD(REG_D0, REG_SP, 8)
- M_IPOP(0); /* TODO: pop float result */
-#else
- M_AADD_IMM(3*4, REG_SP);
-#endif
- M_AADD_IMM(4, REG_SP); /* remove rest of stack */
- M_UNLK(REG_FP);
+ M_AADD_IMM(3*4 + 4, REG_SP);
M_NOP;
}
#endif
/* TODO */
+#define LA_SIZE_IN_POINTERS 0
+#if 0
#define LA_SIZE 48 /* linkage area size */
#define LA_SIZE_ALIGNED 16 /* linkage area size aligned to 16-byte */
#define LA_SIZE_IN_POINTERS (LA_SIZE / SIZEOF_VOID_P)
#define LA_LR_OFFSET 16 /* link register offset in linkage area */
#define PA_SIZE (PA_SIZE_IN_POINTERS*8)
#define PA_SIZE_IN_POINTERS 8 /* linux/ppc64 has a minimun parameter save area size, XXX:darwin? */
-
+#endif
/* #define ALIGN_FRAME_SIZE(sp) (sp) */
#endif /* _MD_ABI_H */