diff options
Diffstat (limited to 'compiler/nativeGen/X86')
-rw-r--r-- | compiler/nativeGen/X86/CodeGen.hs | 35 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Instr.hs | 3 | ||||
-rw-r--r-- | compiler/nativeGen/X86/Ppr.hs | 1 |
3 files changed, 33 insertions, 6 deletions
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs index 36aebea2c7..f6143d3fb9 100644 --- a/compiler/nativeGen/X86/CodeGen.hs +++ b/compiler/nativeGen/X86/CodeGen.hs @@ -1170,7 +1170,6 @@ memConstant align lit = do (addr, addr_code) <- if target32Bit (targetPlatform dflags) then do dynRef <- cmmMakeDynamicReference dflags - addImportNat DataReference lbl Amode addr addr_code <- getAmode dynRef @@ -1659,6 +1658,29 @@ genCCall _ (PrimTarget MO_Touch) _ _ = return nilOL genCCall _ (PrimTarget MO_Prefetch_Data) _ _ = return nilOL +genCCall is32Bit (PrimTarget (MO_BSwap width)) [dst] [src] = do + dflags <- getDynFlags + let platform = targetPlatform dflags + let dst_r = getRegisterReg platform False (CmmLocal dst) + case width of + W64 | is32Bit -> do + ChildCode64 vcode rlo <- iselExpr64 src + let dst_rhi = getHiVRegFromLo dst_r + rhi = getHiVRegFromLo rlo + return $ vcode `appOL` + toOL [ MOV II32 (OpReg rlo) (OpReg dst_rhi), + MOV II32 (OpReg rhi) (OpReg dst_r), + BSWAP II32 dst_rhi, + BSWAP II32 dst_r ] + W16 -> do code_src <- getAnyReg src + return $ code_src dst_r `appOL` + unitOL (BSWAP II32 dst_r) `appOL` + unitOL (SHR II32 (OpImm $ ImmInt 16) (OpReg dst_r)) + _ -> do code_src <- getAnyReg src + return $ code_src dst_r `appOL` unitOL (BSWAP size dst_r) + where + size = intSize width + genCCall is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] args@[src] = do sse4_2 <- sse4_2Enabled @@ -1677,7 +1699,7 @@ genCCall is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] unitOL (POPCNT size (OpReg src_r) (getRegisterReg platform False (CmmLocal dst)))) else do - targetExpr <- cmmMakeDynamicReference dflags addImportNat + targetExpr <- cmmMakeDynamicReference dflags CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] @@ -1689,7 +1711,7 @@ genCCall is32Bit (PrimTarget (MO_PopCnt width)) dest_regs@[dst] genCCall is32Bit (PrimTarget (MO_UF_Conv width)) dest_regs args = do dflags <- getDynFlags - targetExpr <- cmmMakeDynamicReference dflags addImportNat + targetExpr <- cmmMakeDynamicReference dflags CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [NoHint] [NoHint] @@ -1835,7 +1857,7 @@ genCCall32' dflags target dest_regs args = do use_sse2 <- sse2Enabled push_codes <- mapM (push_arg use_sse2) (reverse prom_args) delta <- getDeltaNat - MASSERT (delta == delta0 - tot_arg_size) + MASSERT(delta == delta0 - tot_arg_size) -- deal with static vs dynamic call targets (callinsns,cconv) <- @@ -2271,7 +2293,7 @@ outOfLineCmmOp :: CallishMachOp -> Maybe CmmFormal -> [CmmActual] -> NatM InstrB outOfLineCmmOp mop res args = do dflags <- getDynFlags - targetExpr <- cmmMakeDynamicReference dflags addImportNat CallReference lbl + targetExpr <- cmmMakeDynamicReference dflags CallReference lbl let target = ForeignTarget targetExpr (ForeignConvention CCallConv [] [] CmmMayReturn) @@ -2326,6 +2348,7 @@ outOfLineCmmOp mop res args MO_Memmove -> fsLit "memmove" MO_PopCnt _ -> fsLit "popcnt" + MO_BSwap _ -> fsLit "bswap" MO_UF_Conv _ -> unsupported @@ -2351,7 +2374,7 @@ genSwitch dflags expr ids (reg,e_code) <- getSomeReg expr lbl <- getNewLabelNat dflags <- getDynFlags - dynRef <- cmmMakeDynamicReference dflags addImportNat DataReference lbl + dynRef <- cmmMakeDynamicReference dflags DataReference lbl (tableReg,t_code) <- getSomeReg $ dynRef let op = OpAddr (AddrBaseIndex (EABaseReg tableReg) (EAIndex reg (wORD_SIZE dflags)) (ImmInt 0)) diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs index 76f0e8bd91..266a4ea58a 100644 --- a/compiler/nativeGen/X86/Instr.hs +++ b/compiler/nativeGen/X86/Instr.hs @@ -208,6 +208,7 @@ data Instr | XOR Size Operand Operand | NOT Size Operand | NEGI Size Operand -- NEG instruction (name clash with Cond) + | BSWAP Size Reg -- Shifts (amount may be immediate or %cl only) | SHL Size Operand{-amount-} Operand @@ -351,6 +352,7 @@ x86_regUsageOfInstr platform instr XOR _ src dst -> usageRM src dst NOT _ op -> usageM op + BSWAP _ reg -> mkRU [reg] [reg] NEGI _ op -> usageM op SHL _ imm dst -> usageRM imm dst SAR _ imm dst -> usageRM imm dst @@ -489,6 +491,7 @@ x86_patchRegsOfInstr instr env OR sz src dst -> patch2 (OR sz) src dst XOR sz src dst -> patch2 (XOR sz) src dst NOT sz op -> patch1 (NOT sz) op + BSWAP sz reg -> BSWAP sz (env reg) NEGI sz op -> patch1 (NEGI sz) op SHL sz imm dst -> patch1 (SHL sz imm) dst SAR sz imm dst -> patch1 (SAR sz imm) dst diff --git a/compiler/nativeGen/X86/Ppr.hs b/compiler/nativeGen/X86/Ppr.hs index 75d18a1ff4..7f9c6901da 100644 --- a/compiler/nativeGen/X86/Ppr.hs +++ b/compiler/nativeGen/X86/Ppr.hs @@ -578,6 +578,7 @@ pprInstr (XOR size src dst) = pprSizeOpOp (sLit "xor") size src dst pprInstr (POPCNT size src dst) = pprOpOp (sLit "popcnt") size src (OpReg dst) pprInstr (NOT size op) = pprSizeOp (sLit "not") size op +pprInstr (BSWAP size op) = pprSizeOp (sLit "bswap") size (OpReg op) pprInstr (NEGI size op) = pprSizeOp (sLit "neg") size op pprInstr (SHL size src dst) = pprShift (sLit "shl") size src dst |