summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-08 23:49:02 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-12-02 18:13:30 -0500
commit7094f4faeb78a3ffda98c44700b4addba3f5b951 (patch)
tree36ef988cff377843a701a836b1a9b3b40c839a43
parent2f6565cf5edd1d8b2d95f7c97d5875c05939c0ed (diff)
downloadhaskell-7094f4faeb78a3ffda98c44700b4addba3f5b951.tar.gz
nativeGen/aarch64: Don't rely on register width to determine amode
We might be loading, e.g., a 16- or 8-bit value, in which case the register width is not reflective of the loaded element size.
-rw-r--r--compiler/GHC/CmmToAsm/AArch64/CodeGen.hs28
1 files changed, 16 insertions, 12 deletions
diff --git a/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs b/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
index 57da087f2b..c5171a0419 100644
--- a/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
+++ b/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
@@ -550,7 +550,7 @@ getRegister' config plat expr
CmmBlock _ -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr)
CmmHighStackMark -> pprPanic "getRegister' (CmmLit:CmmLabelOff): " (pdoc plat expr)
CmmLoad mem rep -> do
- Amode addr addr_code <- getAmode plat mem
+ Amode addr addr_code <- getAmode plat (typeWidth rep) mem
let format = cmmTypeFormat rep
return (Any format (\dst -> addr_code `snocOL` LDR format (OpReg (formatToWidth format) dst) (OpAddr addr)))
CmmStackSlot _ _
@@ -897,25 +897,28 @@ getRegister' config plat expr
-- The 'Amode' type: Memory addressing modes passed up the tree.
data Amode = Amode AddrMode InstrBlock
-getAmode :: Platform -> CmmExpr -> NatM Amode
+getAmode :: Platform
+ -> Width -- ^ width of loaded value
+ -> CmmExpr
+ -> NatM Amode
-- TODO: Specialize stuff we can destructure here.
-- OPTIMIZATION WARNING: Addressing modes.
-- Addressing options:
-- LDUR/STUR: imm9: -256 - 255
-getAmode platform (CmmRegOff reg off) | -256 <= off, off <= 255
+getAmode platform w (CmmRegOff reg off) | -256 <= off, off <= 255
= return $ Amode (AddrRegImm reg' off') nilOL
where reg' = getRegisterReg platform reg
off' = ImmInt off
-- LDR/STR: imm12: if reg is 32bit: 0 -- 16380 in multiples of 4
-getAmode platform (CmmRegOff reg off)
- | typeWidth (cmmRegType platform reg) == W32, 0 <= off, off <= 16380, off `mod` 4 == 0
+getAmode platform W32 (CmmRegOff reg off)
+ | 0 <= off, off <= 16380, off `mod` 4 == 0
= return $ Amode (AddrRegImm reg' off') nilOL
where reg' = getRegisterReg platform reg
off' = ImmInt off
-- LDR/STR: imm12: if reg is 64bit: 0 -- 32760 in multiples of 8
-getAmode platform (CmmRegOff reg off)
- | typeWidth (cmmRegType platform reg) == W64, 0 <= off, off <= 32760, off `mod` 8 == 0
+getAmode platform W64 (CmmRegOff reg off)
+ | 0 <= off, off <= 32760, off `mod` 8 == 0
= return $ Amode (AddrRegImm reg' off') nilOL
where reg' = getRegisterReg platform reg
off' = ImmInt off
@@ -924,18 +927,18 @@ getAmode platform (CmmRegOff reg off)
-- CmmStore (CmmMachOp (MO_Add w) [CmmLoad expr, CmmLit (CmmInt n w')]) (expr2)
-- E.g. a CmmStoreOff really. This can be translated to `str $expr2, [$expr, #n ]
-- for `n` in range.
-getAmode _platform (CmmMachOp (MO_Add _w) [expr, CmmLit (CmmInt off _w')])
+getAmode _platform _ (CmmMachOp (MO_Add _w) [expr, CmmLit (CmmInt off _w')])
| -256 <= off, off <= 255
= do (reg, _format, code) <- getSomeReg expr
return $ Amode (AddrRegImm reg (ImmInteger off)) code
-getAmode _platform (CmmMachOp (MO_Sub _w) [expr, CmmLit (CmmInt off _w')])
+getAmode _platform _ (CmmMachOp (MO_Sub _w) [expr, CmmLit (CmmInt off _w')])
| -256 <= -off, -off <= 255
= do (reg, _format, code) <- getSomeReg expr
return $ Amode (AddrRegImm reg (ImmInteger (-off))) code
-- Generic case
-getAmode _platform expr
+getAmode _platform _ expr
= do (reg, _format, code) <- getSomeReg expr
return $ Amode (AddrReg reg) code
@@ -961,11 +964,12 @@ assignMem_IntCode rep addrE srcE
= do
(src_reg, _format, code) <- getSomeReg srcE
platform <- getPlatform
- Amode addr addr_code <- getAmode platform addrE
+ let w = formatToWidth rep
+ Amode addr addr_code <- getAmode platform w addrE
return $ COMMENT (text "CmmStore" <+> parens (text (show addrE)) <+> parens (text (show srcE)))
`consOL` (code
`appOL` addr_code
- `snocOL` STR rep (OpReg (formatToWidth rep) src_reg) (OpAddr addr))
+ `snocOL` STR rep (OpReg w src_reg) (OpAddr addr))
assignReg_IntCode _ reg src
= do