[Git][ghc/ghc][wip/supersven/riscv64-ncg] 3 commits: Add OR and ORI instructions

Sven Tennie (@supersven) gitlab at gitlab.haskell.org
Thu May 18 17:39:15 UTC 2023



Sven Tennie pushed to branch wip/supersven/riscv64-ncg at Glasgow Haskell Compiler / GHC


Commits:
4f22557e by Sven Tennie at 2023-05-18T18:07:30+02:00
Add OR and ORI instructions

ORR doesn't exist on RISCV. OR with register load is used when the
immediate is too big for ORI (i.e. >12bits.)

- - - - -
b877aa85 by Sven Tennie at 2023-05-18T18:09:52+02:00
Refine TODO comment: Stack frame header size is 2 * 8 byte

The stack frame header should contain two registers: ra and previous fp

- - - - -
c8c7bce6 by Sven Tennie at 2023-05-18T19:36:56+02:00
Fix MOV with immediate

There are three cases:
- Fits in a 12bit immediate slot -> ADDI
- Fits in 32bit -> %hi / %lo piecewise loading
- Else: Let the assembler solve this issue for now, LI

- - - - -


3 changed files:

- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs


Changes:

=====================================
compiler/GHC/CmmToAsm/RV64/CodeGen.hs
=====================================
@@ -762,8 +762,8 @@ getRegister' config plat expr
       where w' = formatToWidth (cmmTypeFormat (cmmRegType plat reg))
             r' = getRegisterReg plat reg
 
-    CmmMachOp (MO_Or w) [(CmmReg reg), CmmLit (CmmInt n _)] | isBitMaskImmediate (fromIntegral n) ->
-      return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (ORR (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n))))
+    CmmMachOp (MO_Or w) [(CmmReg reg), CmmLit (CmmInt n _)] | fitsIn12bitImm n ->
+      return $ Any (intFormat w) (\d -> unitOL $ annExpr expr (ORI (OpReg w d) (OpReg w' r') (OpImm (ImmInteger n))))
       where w' = formatToWidth (cmmTypeFormat (cmmRegType plat reg))
             r' = getRegisterReg plat reg
 
@@ -932,7 +932,7 @@ getRegister' config plat expr
 
         -- Bitwise operations
         MO_And   w -> bitOp w (\d x y -> unitOL $ AND d x y)
-        MO_Or    w -> bitOp w (\d x y -> unitOL $ ORR d x y)
+        MO_Or    w -> bitOp w (\d x y -> unitOL $ OR d x y)
         MO_Xor   w -> bitOp w (\d x y -> unitOL $ EOR d x y)
         MO_Shl   w -> intOp False w (\d x y -> unitOL $ LSL d x y)
         MO_U_Shr w -> intOp False w (\d x y -> unitOL $ LSR d x y)
@@ -1070,12 +1070,6 @@ getAmode _platform _ expr
   = do (reg, _format, code) <- getSomeReg expr
        return $ Amode (AddrReg reg) code
 
-fitsIn12bitImm :: (Num a, Ord a) => a -> Bool
-fitsIn12bitImm off = off >= intMin12bit && off <= intMax12bit
-  where
-    intMin12bit = -2048
-    intMax12bit = 2047
-
 -- -----------------------------------------------------------------------------
 -- Generating assignments
 


=====================================
compiler/GHC/CmmToAsm/RV64/Instr.hs
=====================================
@@ -32,7 +32,7 @@ import Data.Maybe (fromMaybe)
 
 import GHC.Stack
 
--- | TODO: verify this!
+-- | TODO: Should be `2 * spillSlotSize = 16`
 stackFrameHeaderSize :: Platform -> Int
 stackFrameHeaderSize _ = 64
 
@@ -102,6 +102,7 @@ regUsageOfInstr platform instr = case instr of
   UXTH dst src             -> usage (regOp src, regOp dst)
   -- 3. Logical and Move Instructions ------------------------------------------
   AND dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)
+  OR dst src1 src2         -> usage (regOp src1 ++ regOp src2, regOp dst)
   ASR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)
   BIC dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)
   BICS dst src1 src2       -> usage (regOp src1 ++ regOp src2, regOp dst)
@@ -112,7 +113,8 @@ regUsageOfInstr platform instr = case instr of
   MOV dst src              -> usage (regOp src, regOp dst)
   MOVK dst src             -> usage (regOp src, regOp dst)
   MVN dst src              -> usage (regOp src, regOp dst)
-  ORR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)
+  -- ORI's third operand is always an immediate
+  ORI dst src1 _           -> usage (regOp src1, regOp dst)
   ROR dst src1 src2        -> usage (regOp src1 ++ regOp src2, regOp dst)
   TST src1 src2            -> usage (regOp src1 ++ regOp src2, [])
   -- 4. Branch Instructions ----------------------------------------------------
@@ -241,6 +243,7 @@ patchRegsOfInstr instr env = case instr of
 
     -- 3. Logical and Move Instructions ----------------------------------------
     AND o1 o2 o3   -> AND  (patchOp o1) (patchOp o2) (patchOp o3)
+    OR o1 o2 o3    -> OR   (patchOp o1) (patchOp o2) (patchOp o3)
     -- ANDS o1 o2 o3  -> ANDS (patchOp o1) (patchOp o2) (patchOp o3)
     ASR o1 o2 o3   -> ASR  (patchOp o1) (patchOp o2) (patchOp o3)
     BIC o1 o2 o3   -> BIC  (patchOp o1) (patchOp o2) (patchOp o3)
@@ -252,7 +255,8 @@ patchRegsOfInstr instr env = case instr of
     MOV o1 o2      -> MOV  (patchOp o1) (patchOp o2)
     MOVK o1 o2     -> MOVK (patchOp o1) (patchOp o2)
     MVN o1 o2      -> MVN  (patchOp o1) (patchOp o2)
-    ORR o1 o2 o3   -> ORR  (patchOp o1) (patchOp o2) (patchOp o3)
+    -- o3 cannot be a register for ORI (always an immediate)
+    ORI o1 o2 o3   -> ORI  (patchOp o1) (patchOp o2) (patchOp o3)
     ROR o1 o2 o3   -> ROR  (patchOp o1) (patchOp o2) (patchOp o3)
     TST o1 o2      -> TST  (patchOp o1) (patchOp o2)
 
@@ -647,7 +651,7 @@ data Instr
     -- | MOVZ Operand Operand
     | MVN Operand Operand -- rd = ~rn
     | ORN Operand Operand Operand -- rd = rn | ~op2
-    | ORR Operand Operand Operand -- rd = rn | op2
+    | ORI Operand Operand Operand -- rd = rn | op2
     | ROR Operand Operand Operand -- rd = rn ≫ rm  or  rd = rn ≫ #i, i is 6 bits
     | TST Operand Operand -- rn & op2
     -- Load and stores.
@@ -700,6 +704,7 @@ instrCon i =
       PUSH_STACK_FRAME{} -> "PUSH_STACK_FRAME"
       POP_STACK_FRAME{} -> "POP_STACK_FRAME"
       ADD{} -> "ADD"
+      OR{} -> "OR"
       -- CMN{} -> "CMN"
       -- CMP{} -> "CMP"
       MSUB{} -> "MSUB"
@@ -727,7 +732,7 @@ instrCon i =
       MOVK{} -> "MOVK"
       MVN{} -> "MVN"
       ORN{} -> "ORN"
-      ORR{} -> "ORR"
+      ORI{} -> "ORI"
       ROR{} -> "ROR"
       TST{} -> "TST"
       STR{} -> "STR"
@@ -892,3 +897,12 @@ opRegSExt W32 r = OpRegExt W32 r ESXTW 0
 opRegSExt W16 r = OpRegExt W16 r ESXTH 0
 opRegSExt W8  r = OpRegExt W8  r ESXTB 0
 opRegSExt w  _r = pprPanic "opRegSExt" (ppr w)
+
+fitsIn12bitImm :: (Num a, Ord a) => a -> Bool
+fitsIn12bitImm off = off >= intMin12bit && off <= intMax12bit
+  where
+    intMin12bit = -2048
+    intMax12bit = 2047
+
+fitsIn32bits  :: (Num a, Ord a, Bits a) => a -> Bool
+fitsIn32bits i = (-1 `shiftL` 31) <= i && i <= (1 `shiftL` 31 -1)


=====================================
compiler/GHC/CmmToAsm/RV64/Ppr.hs
=====================================
@@ -493,6 +493,7 @@ pprInstr platform instr = case instr of
 
   -- 3. Logical and Move Instructions ------------------------------------------
   AND o1 o2 o3  -> op3 (text "\tand") o1 o2 o3
+  OR o1 o2 o3   -> op3 (text "\tor") o1 o2 o3
   -- ANDS o1 o2 o3 -> op3 (text "\tands") o1 o2 o3
   ASR o1 o2 o3  -> op3 (text "\tsra") o1 o2 o3
   BIC o1 o2 o3  -> op3 (text "\tbic") o1 o2 o3
@@ -505,18 +506,21 @@ pprInstr platform instr = case instr of
     | isFloatOp o1 || isFloatOp o2 -> op2 (text "\tfmov") o1 o2
     | isImmOp o2
     , (OpImm (ImmInteger i)) <- o2
-    , (-1 `shiftL` 11) <= i
-    , i <= (1 `shiftL` 11 - 1)     -> lines_ [ text "\taddi" <+> pprOp platform o1 <> comma <+> pprOp platform x0 <> comma <+> pprOp platform o2 ]
+    , fitsIn12bitImm i
+          -> lines_ [ text "\taddi" <+> pprOp platform o1 <> comma <+> pprOp platform x0 <> comma <+> pprOp platform o2 ]
     | isImmOp o2
     , (OpImm (ImmInteger i)) <- o2
-    , (-1 `shiftL` 31) <= i
-    , i <= (1 `shiftL` 31 -1)      -> lines_ [ text "\tlui" <+> pprOp platform o1 <> comma <+> text "%hi(" <> pprOp platform o2 <> text ")"
+    , fitsIn32bits i
+        -> lines_ [ text "\tlui" <+> pprOp platform o1 <> comma <+> text "%hi(" <> pprOp platform o2 <> text ")"
                                              , text "\taddi" <+> pprOp platform o1 <> comma <+> pprOp platform o1 <> comma <+> text "%lo(" <> pprOp platform o2 <> text ")" ]
+    | isImmOp o2
+        -- Surrender! Let the assembler figure out the right expressions with pseudo-op LI.
+        -> lines_ [ text "\tli" <+> pprOp platform o1 <> comma <+>  pprOp platform o2 ]
     | otherwise                    -> op3 (text "\taddi") o1 o2 (OpImm (ImmInt 0))
   MOVK o1 o2    -> op2 (text "\tmovk") o1 o2
   MVN o1 o2     -> op2 (text "\tmvn") o1 o2
   ORN o1 o2 o3  -> op3 (text "\torn") o1 o2 o3
-  ORR o1 o2 o3  -> op3 (text "\torr") o1 o2 o3
+  ORI o1 o2 o3  -> op3 (text "\tori") o1 o2 o3
   ROR o1 o2 o3  -> op3 (text "\tror") o1 o2 o3
   TST o1 o2     -> op2 (text "\ttst") o1 o2
 



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce78097cd4100df76443b8a68ed192f987aa44fe...c8c7bce64d94afd5cf57f7e8f7eae3d1d664eb3f

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ce78097cd4100df76443b8a68ed192f987aa44fe...c8c7bce64d94afd5cf57f7e8f7eae3d1d664eb3f
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230518/76c36a06/attachment-0001.html>


More information about the ghc-commits mailing list