Fix additional constants embedded in instruction stream on AMD64. (#33682)
authormonojenkins <jo.shields+jenkins@xamarin.com>
Wed, 18 Mar 2020 12:50:46 +0000 (08:50 -0400)
committerGitHub <noreply@github.com>
Wed, 18 Mar 2020 12:50:46 +0000 (13:50 +0100)
A couple of more op codes embedded constant values in instruction stream. When using MONO_ARCH_CODE_EXEC_ONLY these needs to be moved into GOT slots.

Thanks @buggeststar for bring the issues to our attention.

Co-authored-by: lateralusX <lateralusX@users.noreply.github.com>
src/mono/mono/mini/mini-amd64.c

index b1068df..4ea484f 100644 (file)
@@ -6048,19 +6048,33 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        static double r8_0 = -0.0;
 
                        g_assert (ins->sreg1 == ins->dreg);
-                                       
-                       mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, &r8_0);
-                       amd64_sse_xorpd_reg_membase (code, ins->dreg, AMD64_RIP, 0);
+
+                       if (cfg->compile_aot && cfg->code_exec_only) {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8_GOT, &r8_0);
+                               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, sizeof (target_mgreg_t));
+                               amd64_sse_movsd_reg_membase (code, MONO_ARCH_FP_SCRATCH_REG, AMD64_R11, 0);
+                               amd64_sse_xorpd_reg_reg (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG);
+                       } else {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, &r8_0);
+                               amd64_sse_xorpd_reg_membase (code, ins->dreg, AMD64_RIP, 0);
+                       }
                        break;
                }
                case OP_ABS: {
                        static guint64 d = 0x7fffffffffffffffUL;
 
                        g_assert (ins->sreg1 == ins->dreg);
-                                       
-                       mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, &d);
-                       amd64_sse_andpd_reg_membase (code, ins->dreg, AMD64_RIP, 0);
-                       break;          
+
+                       if (cfg->compile_aot && cfg->code_exec_only) {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8_GOT, &d);
+                               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, sizeof (target_mgreg_t));
+                               amd64_sse_movsd_reg_membase (code, MONO_ARCH_FP_SCRATCH_REG, AMD64_R11, 0);
+                               amd64_sse_andpd_reg_reg (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG);
+                       } else {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, &d);
+                               amd64_sse_andpd_reg_membase (code, ins->dreg, AMD64_RIP, 0);
+                       }
+                       break;
                }
                case OP_SQRT:
                        EMIT_SSE2_FPFUNC (code, fsqrt, ins->dreg, ins->sreg1);
@@ -6083,8 +6097,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        g_assert (ins->sreg1 == ins->dreg);
 
-                       mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4, &r4_0);
-                       amd64_sse_movss_reg_membase (code, MONO_ARCH_FP_SCRATCH_REG, AMD64_RIP, 0);
+                       if (cfg->compile_aot && cfg->code_exec_only) {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4_GOT, &r4_0);
+                               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, sizeof (target_mgreg_t));
+                               amd64_sse_movss_reg_membase (code, MONO_ARCH_FP_SCRATCH_REG, AMD64_R11, 0);
+                       } else {
+                               mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4, &r4_0);
+                               amd64_sse_movss_reg_membase (code, MONO_ARCH_FP_SCRATCH_REG, AMD64_RIP, 0);
+                       }
+
                        amd64_sse_xorps_reg_reg (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG);
                        break;
                }