}
} else {
if (*gr > ARMREG_R2) {
- *stack_size += 7;
- *stack_size &= ~7;
+ /**stack_size += 7;
+ *stack_size &= ~7;*/
ainfo->offset = *stack_size;
ainfo->reg = ARMREG_SP; /* in the caller */
ainfo->regtype = RegTypeBase;
/* allow room for the vararg method args: void* and long/double */
if (mono_jit_trace_calls != NULL && mono_trace_eval (m->method))
m->param_area = MAX (m->param_area, sizeof (gpointer)*8);
- /* this is bug #60332: remove when #59509 is fixed, so no weird vararg
- * call convs needs to be handled this way.
- */
- if (m->flags & MONO_CFG_HAS_VARARGS)
- m->param_area = MAX (m->param_area, sizeof (gpointer)*8);
- /* gtk-sharp and other broken code will dllimport vararg functions even with
- * non-varargs signatures. Since there is little hope people will get this right
- * we assume they won't.
- */
- if (m->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE)
- m->param_area = MAX (m->param_area, sizeof (gpointer)*8);
header = mono_method_get_header (m->method);
else
size = mono_type_size (inst->inst_vtype, &align);
+ /* FIXME: if a structure is misaligned, our memcpy doesn't work,
+ * since it loads/stores misaligned words, which don't do the right thing.
+ */
+ if (align < 4 && size >= 4)
+ align = 4;
offset += align - 1;
offset &= ~(align - 1);
inst->inst_offset = offset;
inst->opcode = OP_REGOFFSET;
inst->inst_basereg = frame_reg;
size = mono_type_size (sig->params [i], &align);
+ /* FIXME: if a structure is misaligned, our memcpy doesn't work,
+ * since it loads/stores misaligned words, which don't do the right thing.
+ */
+ if (align < 4 && size >= 4)
+ align = 4;
offset += align - 1;
offset &= ~(align - 1);
inst->inst_offset = offset;
/* branch and exchange: the address is constructed in a reg */
g_assert_not_reached ();
} else {
+ guint32 ccode [3];
+ guint32 *tmp = ccode;
+ ARM_LDR_IMM (tmp, ARMREG_IP, ARMREG_PC, 0);
+ ARM_MOV_REG_REG (tmp, ARMREG_LR, ARMREG_PC);
+ ARM_MOV_REG_REG (tmp, ARMREG_PC, ARMREG_IP);
+ if (ins == ccode [2]) {
+ tmp = (guint32*)code;
+ tmp [-1] = (guint32)target;
+ return;
+ }
+ if (ins == ccode [0]) {
+ tmp = (guint32*)code;
+ tmp [2] = (guint32)target;
+ return;
+ }
g_assert_not_reached ();
}
// g_print ("patched with 0x%08x\n", ins);
mono_arm_emit_load_imm (guint8 *code, int dreg, guint32 val)
{
int imm8, rot_amount;
+#if 0
+ ARM_LDR_IMM (code, dreg, ARMREG_PC, 0);
+ /* skip the constant pool */
+ ARM_B (code, 0);
+ *(int*)code = val;
+ code += 4;
+ return code;
+#endif
if ((imm8 = mono_arm_is_rotated_imm8 (val, &rot_amount)) >= 0) {
ARM_MOV_REG_IMM (code, dreg, imm8, rot_amount);
} else if ((imm8 = mono_arm_is_rotated_imm8 (~val, &rot_amount)) >= 0) {
ARM_LDR_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
break;
case OP_LOADI1_MEMINDEX:
- ARM_LDRSB_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
+ /* note: the args are reversed in the macro */
+ ARM_LDRSB_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOADU1_MEMINDEX:
ARM_LDRB_REG_REG (code, ins->dreg, ins->inst_basereg, ins->sreg2);
break;
case OP_LOADI2_MEMINDEX:
- ARM_LDRSH_REG_REG (code, ins->inst_basereg, ins->sreg2, ins->dreg);
+ /* note: the args are reversed in the macro */
+ ARM_LDRSH_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOADU2_MEMINDEX:
- ARM_LDRH_REG_REG (code, ins->inst_basereg, ins->sreg2, ins->dreg);
+ /* note: the args are reversed in the macro */
+ ARM_LDRH_REG_REG (code, ins->inst_basereg, ins->dreg, ins->sreg2);
break;
case OP_LOAD_MEMBASE:
case OP_LOADI4_MEMBASE:
ARM_SHL_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_SHL_IMM:
- ARM_SHL_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
+ if (ins->inst_imm)
+ ARM_SHL_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
break;
case CEE_SHR:
ARM_SAR_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_SHR_IMM:
- ARM_SAR_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
+ if (ins->inst_imm)
+ ARM_SAR_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
break;
case OP_SHR_UN_IMM:
- ARM_SHR_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
+ if (ins->inst_imm)
+ ARM_SHR_IMM (code, ins->dreg, ins->sreg1, (ins->inst_imm & 0x1f));
break;
case CEE_SHR_UN:
ARM_SHR_REG (code, ins->dreg, ins->sreg1, ins->sreg2);
break;
case OP_SETLRET: {
int saved = ins->sreg2;
- if (ins->sreg2 == ARMREG_R0) {
+ if (ins->sreg2 == ARM_LSW_REG) {
ARM_MOV_REG_REG (code, ARMREG_LR, ins->sreg2);
saved = ARMREG_LR;
}
- if (ins->sreg1 != ARMREG_R0)
- ARM_MOV_REG_REG (code, ARMREG_R0, ins->sreg1);
- if (saved != ARMREG_R1)
- ARM_MOV_REG_REG (code, ARMREG_R1, saved);
+ if (ins->sreg1 != ARM_LSW_REG)
+ ARM_MOV_REG_REG (code, ARM_LSW_REG, ins->sreg1);
+ if (saved != ARM_MSW_REG)
+ ARM_MOV_REG_REG (code, ARM_MSW_REG, saved);
break;
}
case OP_SETFREG:
*/
g_assert (!cfg->method->save_lmf);
code = emit_big_add (code, ARMREG_SP, cfg->frame_reg, cfg->stack_usage);
- ARM_ADD_REG_IMM8 (code, ARMREG_SP, cfg->frame_reg, cfg->stack_usage);
ARM_POP_NWB (code, cfg->used_int_regs | ((1 << ARMREG_SP)) | ((1 << ARMREG_LR)));
mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
ARM_B (code, 0);
/* save the temp register */
ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8);
ARM_STFD (code, tmpreg, ARMREG_SP, 0);
- ARM_LDFD (code, tmpreg, ARMREG_PC, 4);
+ ARM_LDFD (code, tmpreg, ARMREG_PC, 12);
ARM_FPA_ADFD (code, ins->dreg, ins->dreg, tmpreg);
ARM_LDFD (code, tmpreg, ARMREG_SP, 0);
ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8);
/* skip the constant pool */
- ARM_B (code, 4);
+ ARM_B (code, 8);
+ code += 4;
*(int*)code = 0x41f00000;
code += 4;
*(int*)code = 0;
case OP_FBGE_UN:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg1, ins->sreg2);
EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_VS); /* V set */
- EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_CS);
+ EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_GE);
break;
case OP_FBLE:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
case OP_FBLE_UN:
ARM_FCMP (code, ARM_FPA_CMF, ins->sreg2, ins->sreg1);
EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_VS); /* V set */
- EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_CS); /* swapped */
+ EMIT_COND_BRANCH_FLAGS (ins, ARMCOND_GE); /* swapped */
break;
case CEE_CKFINITE: {
/*ppc_stfd (code, ins->sreg1, -8, ppc_sp);
switch (patch_info->type) {
case MONO_PATCH_INFO_EXC: {
unsigned char *ip = patch_info->ip.i + cfg->native_code;
+ const char *ex_name = patch_info->data.target;
i = exception_id_by_name (patch_info->data.target);
if (exc_throw_pos [i]) {
arm_patch (ip, exc_throw_pos [i]);
exc_throw_pos [i] = code;
}
arm_patch (ip, code);
+ //*(int*)code = 0xef9f0001;
+ code += 4;
/*mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_EXC_NAME, patch_info->data.target);*/
ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0);
/* we got here from a conditional call, so the calling ip is set in lr already */
patch_info->data.name = "mono_arch_throw_exception_by_name";
patch_info->ip.i = code - cfg->native_code;
ARM_B (code, 0);
- *(gpointer*)code = patch_info->data.target;
+ *(gpointer*)code = ex_name;
code += 4;
break;
}
{
}
+void
+mono_arch_fixup_jinfo (MonoCompile *cfg)
+{
+ /* max encoded stack usage is 64KB * 4 */
+ g_assert ((cfg->stack_usage & ~(0xffff << 2)) == 0);
+ cfg->jit_info->used_regs |= cfg->stack_usage << 14;
+}
+