[x86] Implement OP_TLS_SET/OP_TLS_SET_REG opcodes.
authorZoltan Varga <vargaz@gmail.com>
Thu, 28 Nov 2013 12:00:59 +0000 (13:00 +0100)
committerZoltan Varga <vargaz@gmail.com>
Thu, 28 Nov 2013 12:00:59 +0000 (13:00 +0100)
mono/mini/cpu-x86.md
mono/mini/mini-x86.c

index 9f04b4a2c78c3c69724f3509270ceeb8d4b1f66c..93d4404195536434c55648b73791b689b9af3f32 100644 (file)
@@ -303,6 +303,8 @@ sext_i1: dest:i src1:y len:3
 sext_i2: dest:i src1:y len:3
 tls_get: dest:i len:20
 tls_get_reg: dest:i src1:i len:20
+tls_set: src1:i len:20
+tls_set_reg: src1:i src2:i len:20
 atomic_add_i4: src1:b src2:i dest:i len:16
 atomic_add_new_i4: src1:b src2:i dest:i len:16
 atomic_exchange_i4: src1:b src2:i dest:a len:24
index 193db5d33f66c4ff99de4e0f321bc7c448eacce7..a91c8c022b4865b9275756538d8f56aa79b4db2d 100755 (executable)
@@ -2413,6 +2413,27 @@ emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
        return code;
 }
 
+static guint8*
+emit_tls_set_reg (guint8* code, int sreg, int offset_reg)
+{
+#ifdef HOST_WIN32
+       g_assert_not_reached ();
+#elif defined(__APPLE__)
+       // FIXME: tls_gs_offset can change too, do these when calculating the tls offset
+       x86_shift_reg_imm (code, X86_SHL, offset_reg, 2);
+       if (tls_gs_offset)
+               x86_alu_reg_imm (code, X86_ADD, offset_reg, tls_gs_offset);
+       x86_prefix (code, X86_GS_PREFIX);
+       x86_mov_membase_reg (code, offset_reg, 0, sreg, sizeof (mgreg_t));
+#elif defined(__linux__)
+       x86_prefix (code, X86_GS_PREFIX);
+       x86_mov_membase_reg (code, offset_reg, 0, sreg, sizeof (mgreg_t));
+#else
+       g_assert_not_reached ();
+#endif
+       return code;
+}
+
 /*
  * emit_setup_lmf:
  *
@@ -4316,6 +4337,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        code = emit_tls_get_reg (code, ins->dreg, ins->sreg1);
                        break;
                }
+               case OP_TLS_SET: {
+                       code = mono_x86_emit_tls_set (code, ins->sreg1, ins->inst_offset);
+                       break;
+               }
+               case OP_TLS_SET_REG: {
+                       code = emit_tls_set_reg (code, ins->sreg1, ins->sreg2);
+                       break;
+               }
                case OP_MEMORY_BARRIER: {
                        /* x86 only needs barrier for StoreLoad and FullBarrier */
                        switch (ins->backend.memory_barrier_kind) {