From 64732bae2740fde32c8641fb855e6fbea91236cc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alex=20R=C3=B8nne=20Petersen?= Date: Sat, 23 Nov 2013 12:09:47 +0100 Subject: [PATCH] Use d14 and d15 as scratch VFP registers. Using d0 and d1 is problematic because they're argument registers and so can end up being clobbered by instructions inserted in the middle of a call sequence. d14 and d15 on the other hand are OK because they don't have any particular meaning in the ABI, and we don't even use them in the register allocator at the moment anyway. --- mono/mini/mini-arm.c | 35 +++++++++++++++++++---------------- mono/mini/mini-arm.h | 8 ++++---- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index df30a679bc7..8359482df6a 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -119,6 +119,9 @@ static gboolean iphone_abi = FALSE; */ static MonoArmFPU arm_fpu; +static int vfp_scratch1 = ARM_VFP_F28; +static int vfp_scratch2 = ARM_VFP_F30; + static int i8_align; static volatile int ss_trigger_var = 0; @@ -3397,10 +3400,10 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, /* sreg is a float, dreg is an integer reg */ if (IS_VFP) { if (is_signed) - ARM_TOSIZD (code, ARM_VFP_F0, sreg); + ARM_TOSIZD (code, vfp_scratch1, sreg); else - ARM_TOUIZD (code, ARM_VFP_F0, sreg); - ARM_FMRS (code, dreg, ARM_VFP_F0); + ARM_TOUIZD (code, vfp_scratch1, sreg); + ARM_FMRS (code, dreg, vfp_scratch1); } if (!is_signed) { if (size == 1) @@ -4975,26 +4978,26 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; case OP_STORER4_MEMBASE_REG: g_assert (arm_is_fpimm8 (ins->inst_offset)); - ARM_CVTD (code, ARM_VFP_F0, ins->sreg1); - ARM_FSTS (code, ARM_VFP_F0, ins->inst_destbasereg, ins->inst_offset); + ARM_CVTD (code, vfp_scratch1, ins->sreg1); + ARM_FSTS (code, vfp_scratch1, ins->inst_destbasereg, ins->inst_offset); break; case OP_LOADR4_MEMBASE: g_assert (arm_is_fpimm8 (ins->inst_offset)); - ARM_FLDS (code, ARM_VFP_F0, ins->inst_basereg, ins->inst_offset); - ARM_CVTS (code, ins->dreg, ARM_VFP_F0); + ARM_FLDS (code, vfp_scratch1, ins->inst_basereg, ins->inst_offset); + ARM_CVTS (code, ins->dreg, vfp_scratch1); break; case OP_ICONV_TO_R_UN: { g_assert_not_reached (); break; } case OP_ICONV_TO_R4: - ARM_FMSR (code, ARM_VFP_F0, ins->sreg1); - ARM_FSITOS (code, ARM_VFP_F0, ARM_VFP_F0); - ARM_CVTS (code, ins->dreg, ARM_VFP_F0); + ARM_FMSR (code, vfp_scratch1, ins->sreg1); + ARM_FSITOS (code, vfp_scratch1, vfp_scratch1); + ARM_CVTS (code, ins->dreg, vfp_scratch1); break; case OP_ICONV_TO_R8: - ARM_FMSR (code, ARM_VFP_F0, ins->sreg1); - ARM_FSITOD (code, ins->dreg, ARM_VFP_F0); + ARM_FMSR (code, vfp_scratch1, ins->sreg1); + ARM_FSITOD (code, ins->dreg, vfp_scratch1); break; case OP_SETFRET: @@ -5187,18 +5190,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) jte [0] = GUINT_TO_POINTER (0xffffffff); jte [1] = GUINT_TO_POINTER (0x7fefffff); code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP); - ARM_FLDD (code, ARM_VFP_D0, ARMREG_IP, 0); + ARM_FLDD (code, vfp_scratch1, ARMREG_IP, 0); } #else - ARM_ABSD (code, ARM_VFP_D1, ins->sreg1); - ARM_FLDD (code, ARM_VFP_D0, ARMREG_PC, 0); + ARM_ABSD (code, vfp_scratch2, ins->sreg1); + ARM_FLDD (code, vfp_scratch1, ARMREG_PC, 0); ARM_B (code, 1); *(guint32*)code = 0xffffffff; code += 4; *(guint32*)code = 0x7fefffff; code += 4; #endif - ARM_CMPD (code, ARM_VFP_D1, ARM_VFP_D0); + ARM_CMPD (code, vfp_scratch2, vfp_scratch1); ARM_FMSTAT (code); EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_GT, "ArithmeticException"); ARM_CMPD (code, ins->sreg1, ins->sreg1); diff --git a/mono/mini/mini-arm.h b/mono/mini/mini-arm.h index 4b63b89ea2e..ed0a4ed5bbc 100644 --- a/mono/mini/mini-arm.h +++ b/mono/mini/mini-arm.h @@ -72,15 +72,15 @@ #if defined(ARM_FPU_VFP_HARD) #define MONO_SAVED_FREGS 16 -/* d8-d15 must be preserved across function calls. We use d0-d1 as +/* d8-d15 must be preserved across function calls. We use d14-d15 as * scratch registers in the JIT. The rest have no meaning tied to them. */ -#define MONO_ARCH_CALLEE_FREGS 0x00005550 +#define MONO_ARCH_CALLEE_FREGS 0x00005555 #define MONO_ARCH_CALLEE_SAVED_FREGS 0x55550000 #else #define MONO_SAVED_FREGS 0 -/* No registers need to be preserved across function calls. We use d0-d1 +/* No registers need to be preserved across function calls. We use d14-d15 * as scratch registers in the JIT. The rest have no meaning tied to them. */ -#define MONO_ARCH_CALLEE_FREGS 0x55555550 +#define MONO_ARCH_CALLEE_FREGS 0x05555555 #define MONO_ARCH_CALLEE_SAVED_FREGS 0x00000000 #endif -- 2.25.1