[commit: ghc] master: X86 codegen: make LOCK a real instruction prefix (23773b2)

git at git.haskell.org git at git.haskell.org
Wed Jul 23 19:47:13 UTC 2014


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/23773b25863a0a439d81332cb8eee14f6f2c0098/ghc

>---------------------------------------------------------------

commit 23773b25863a0a439d81332cb8eee14f6f2c0098
Author: Johan Tibell <johan.tibell at gmail.com>
Date:   Wed Jul 23 12:22:37 2014 +0200

    X86 codegen: make LOCK a real instruction prefix
    
    Before LOCK was a separate instruction and this led to the register
    allocator separating it from the instruction it was supposed to be a
    prefix of, leading to illegal assembly such as
    
        lock mov
    
    Fix contributed by PÁLI Gábor János.


>---------------------------------------------------------------

23773b25863a0a439d81332cb8eee14f6f2c0098
 compiler/nativeGen/X86/CodeGen.hs | 12 ++++--------
 compiler/nativeGen/X86/Instr.hs   |  6 +++---
 compiler/nativeGen/X86/Ppr.hs     |  2 +-
 3 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index 94b4c15..867dbfd 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -1795,13 +1795,11 @@ genCCall dflags is32Bit (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] =
         -- In the common case where dst_r is a virtual register the
         -- final move should go away, because it's the last use of arg
         -- and the first use of dst_r.
-        AMO_Add  -> return $ toOL [ LOCK
-                                  , XADD size (OpReg arg) (OpAddr amode)
+        AMO_Add  -> return $ toOL [ LOCK (XADD size (OpReg arg) (OpAddr amode))
                                   , MOV size (OpReg arg) (OpReg dst_r)
                                   ]
         AMO_Sub  -> return $ toOL [ NEGI size (OpReg arg)
-                                  , LOCK
-                                  , XADD size (OpReg arg) (OpAddr amode)
+                                  , LOCK (XADD size (OpReg arg) (OpAddr amode))
                                   , MOV size (OpReg arg) (OpReg dst_r)
                                   ]
         AMO_And  -> cmpxchg_code (\ src dst -> unitOL $ AND size src dst)
@@ -1827,8 +1825,7 @@ genCCall dflags is32Bit (PrimTarget (MO_AtomicRMW width amop)) [dst] [addr, n] =
                 , MOV size (OpReg eax) (OpReg tmp)
                 ]
                 `appOL` instrs (OpReg arg) (OpReg tmp) `appOL` toOL
-                [ LOCK
-                , CMPXCHG size (OpReg tmp) (OpAddr amode)
+                [ LOCK (CMPXCHG size (OpReg tmp) (OpAddr amode))
                 , JXX NE lbl
                 ]
 
@@ -1857,8 +1854,7 @@ genCCall dflags is32Bit (PrimTarget (MO_Cmpxchg width)) [dst] [addr, old, new] =
         dst_r    = getRegisterReg platform use_sse2 (CmmLocal dst)
         code     = toOL
                    [ MOV size (OpReg oldval) (OpReg eax)
-                   , LOCK
-                   , CMPXCHG size (OpReg newval) (OpAddr amode)
+                   , LOCK (CMPXCHG size (OpReg newval) (OpAddr amode))
                    , MOV size (OpReg eax) (OpReg dst_r)
                    ]
     return $ addr_code `appOL` newval_code newval `appOL` oldval_code oldval
diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs
index ac91747..82e52df 100644
--- a/compiler/nativeGen/X86/Instr.hs
+++ b/compiler/nativeGen/X86/Instr.hs
@@ -327,7 +327,7 @@ data Instr
         | PREFETCH  PrefetchVariant Size Operand -- prefetch Variant, addr size, address to prefetch
                                         -- variant can be NTA, Lvl0, Lvl1, or Lvl2
 
-        | LOCK  -- lock prefix
+        | LOCK        Instr -- lock prefix
         | XADD        Size Operand Operand  -- src (r), dst (r/m)
         | CMPXCHG     Size Operand Operand  -- src (r), dst (r/m), eax implicit
 
@@ -434,7 +434,7 @@ x86_regUsageOfInstr platform instr
 
     -- note: might be a better way to do this
     PREFETCH _  _ src -> mkRU (use_R src []) []
-    LOCK                -> noUsage
+    LOCK i              -> x86_regUsageOfInstr platform i
     XADD _ src dst      -> usageMM src dst
     CMPXCHG _ src dst   -> usageRMM src dst (OpReg eax)
 
@@ -603,7 +603,7 @@ x86_patchRegsOfInstr instr env
 
     PREFETCH lvl size src -> PREFETCH lvl size (patchOp src)
 
-    LOCK                -> instr
+    LOCK i              -> LOCK (x86_patchRegsOfInstr i env)
     XADD sz src dst     -> patch2 (XADD sz) src dst
     CMPXCHG sz src dst  -> patch2 (CMPXCHG sz) src dst
 
diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs
index 7771c02..5ae1b54 100644
--- a/compiler/nativeGen/X86/Ppr.hs
+++ b/compiler/nativeGen/X86/Ppr.hs
@@ -888,7 +888,7 @@ pprInstr GFREE
 
 -- Atomics
 
-pprInstr LOCK = ptext (sLit "\tlock")
+pprInstr (LOCK i) = ptext (sLit "\tlock") $$ pprInstr i
 
 pprInstr (XADD size src dst) = pprSizeOpOp (sLit "xadd") size src dst
 



More information about the ghc-commits mailing list