[Git][ghc/ghc][wip/supersven/ghc-9.10-riscv-ncg] 8 commits: Cleanup register allocation module
Sven Tennie (@supersven)
gitlab at gitlab.haskell.org
Sun Jun 16 12:35:49 UTC 2024
Sven Tennie pushed to branch wip/supersven/ghc-9.10-riscv-ncg at Glasgow Haskell Compiler / GHC
Commits:
aff59a72 by Sven Tennie at 2024-06-15T18:27:48+00:00
Cleanup register allocation module
- - - - -
8fae51e1 by Sven Tennie at 2024-06-16T12:21:19+00:00
Cleanup free register management
- - - - -
dd8b2f27 by Sven Tennie at 2024-06-16T12:22:24+00:00
Delete superfluous $
- - - - -
6818bea8 by Sven Tennie at 2024-06-16T12:23:34+00:00
Reformat
- - - - -
21d10d75 by Sven Tennie at 2024-06-16T12:25:55+00:00
Add RA to the list of potentially clobbered registers
- - - - -
d3dcbac0 by Sven Tennie at 2024-06-16T12:27:04+00:00
Haddock and formatting
- - - - -
1b2787d2 by Sven Tennie at 2024-06-16T12:29:31+00:00
Delete LLVM lit tests
Unfortunately, we aren't using them in the GHC project.
- - - - -
0b64352b by Sven Tennie at 2024-06-16T12:33:07+00:00
Increase C compiler happiness
Mark unused parameter with STG_UNUSED.
- - - - -
9 changed files:
- compiler/GHC/CmmToAsm/RV64.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Regs.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
- compiler/GHC/CmmToAsm/Reg/Linear/RV64.hs
- rts/linker/elf_reloc_aarch64.c
- − tests/compiler/cmm/shift_right.cmm
- − tests/compiler/cmm/zero.cmm
Changes:
=====================================
compiler/GHC/CmmToAsm/RV64.hs
=====================================
@@ -1,61 +1,57 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | Native code generator for RiscV64 architectures
-module GHC.CmmToAsm.RV64
- ( ncgRV64 )
-where
-
-import GHC.Prelude
+module GHC.CmmToAsm.RV64 (ncgRV64) where
+import GHC.CmmToAsm.Config
import GHC.CmmToAsm.Instr
import GHC.CmmToAsm.Monad
-import GHC.CmmToAsm.Config
+import GHC.CmmToAsm.RV64.CodeGen qualified as RV64
+import GHC.CmmToAsm.RV64.Instr qualified as RV64
+import GHC.CmmToAsm.RV64.Ppr qualified as RV64
+import GHC.CmmToAsm.RV64.RegInfo qualified as RV64
+import GHC.CmmToAsm.RV64.Regs qualified as RV64
import GHC.CmmToAsm.Types
+import GHC.Prelude
import GHC.Utils.Outputable (ftext)
-import qualified GHC.CmmToAsm.RV64.Instr as RV64
-import qualified GHC.CmmToAsm.RV64.Ppr as RV64
-import qualified GHC.CmmToAsm.RV64.CodeGen as RV64
-import qualified GHC.CmmToAsm.RV64.Regs as RV64
-import qualified GHC.CmmToAsm.RV64.RegInfo as RV64
-
ncgRV64 :: NCGConfig -> NcgImpl RawCmmStatics RV64.Instr RV64.JumpDest
-ncgRV64 config
- = NcgImpl {
- ncgConfig = config
- ,cmmTopCodeGen = RV64.cmmTopCodeGen
- ,generateJumpTableForInstr = RV64.generateJumpTableForInstr config
- ,getJumpDestBlockId = RV64.getJumpDestBlockId
- ,canShortcut = RV64.canShortcut
- ,shortcutStatics = RV64.shortcutStatics
- ,shortcutJump = RV64.shortcutJump
- ,pprNatCmmDeclS = RV64.pprNatCmmDecl config
- ,pprNatCmmDeclH = RV64.pprNatCmmDecl config
- ,maxSpillSlots = RV64.maxSpillSlots config
- ,allocatableRegs = RV64.allocatableRegs platform
- ,ncgAllocMoreStack = RV64.allocMoreStack platform
- ,ncgMakeFarBranches = RV64.makeFarBranches
- ,extractUnwindPoints = const []
- ,invertCondBranches = \_ _ -> id
- }
- where
- platform = ncgPlatform config
+ncgRV64 config =
+ NcgImpl
+ { ncgConfig = config,
+ cmmTopCodeGen = RV64.cmmTopCodeGen,
+ generateJumpTableForInstr = RV64.generateJumpTableForInstr config,
+ getJumpDestBlockId = RV64.getJumpDestBlockId,
+ canShortcut = RV64.canShortcut,
+ shortcutStatics = RV64.shortcutStatics,
+ shortcutJump = RV64.shortcutJump,
+ pprNatCmmDeclS = RV64.pprNatCmmDecl config,
+ pprNatCmmDeclH = RV64.pprNatCmmDecl config,
+ maxSpillSlots = RV64.maxSpillSlots config,
+ allocatableRegs = RV64.allocatableRegs platform,
+ ncgAllocMoreStack = RV64.allocMoreStack platform,
+ ncgMakeFarBranches = RV64.makeFarBranches,
+ extractUnwindPoints = const [],
+ invertCondBranches = \_ _ -> id
+ }
+ where
+ platform = ncgPlatform config
--- | Instruction instance for RV64
+-- | `Instruction` instance for RV64
instance Instruction RV64.Instr where
- regUsageOfInstr = RV64.regUsageOfInstr
- patchRegsOfInstr = RV64.patchRegsOfInstr
- isJumpishInstr = RV64.isJumpishInstr
- jumpDestsOfInstr = RV64.jumpDestsOfInstr
- patchJumpInstr = RV64.patchJumpInstr
- mkSpillInstr = RV64.mkSpillInstr
- mkLoadInstr = RV64.mkLoadInstr
- takeDeltaInstr = RV64.takeDeltaInstr
- isMetaInstr = RV64.isMetaInstr
- mkRegRegMoveInstr _ = RV64.mkRegRegMoveInstr
- takeRegRegMoveInstr = RV64.takeRegRegMoveInstr
- mkJumpInstr = RV64.mkJumpInstr
- mkStackAllocInstr = RV64.mkStackAllocInstr
- mkStackDeallocInstr = RV64.mkStackDeallocInstr
- mkComment = pure . RV64.COMMENT . ftext
- pprInstr = RV64.pprInstr
+ regUsageOfInstr = RV64.regUsageOfInstr
+ patchRegsOfInstr = RV64.patchRegsOfInstr
+ isJumpishInstr = RV64.isJumpishInstr
+ jumpDestsOfInstr = RV64.jumpDestsOfInstr
+ patchJumpInstr = RV64.patchJumpInstr
+ mkSpillInstr = RV64.mkSpillInstr
+ mkLoadInstr = RV64.mkLoadInstr
+ takeDeltaInstr = RV64.takeDeltaInstr
+ isMetaInstr = RV64.isMetaInstr
+ mkRegRegMoveInstr _ = RV64.mkRegRegMoveInstr
+ takeRegRegMoveInstr = RV64.takeRegRegMoveInstr
+ mkJumpInstr = RV64.mkJumpInstr
+ mkStackAllocInstr = RV64.mkStackAllocInstr
+ mkStackDeallocInstr = RV64.mkStackDeallocInstr
+ mkComment = pure . RV64.COMMENT . ftext
+ pprInstr = RV64.pprInstr
=====================================
compiler/GHC/CmmToAsm/RV64/Instr.hs
=====================================
@@ -1,8 +1,6 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
-module GHC.CmmToAsm.RV64.Instr
-
-where
+module GHC.CmmToAsm.RV64.Instr where
import GHC.Prelude
@@ -49,8 +47,7 @@ stackFrameHeaderSize = 2 * spillSlotSize
spillSlotSize :: Int
spillSlotSize = 8
--- | The number of bytes that the stack pointer should be aligned
--- to.
+-- | The number of bytes that the stack pointer should be aligned to.
stackAlign :: Int
stackAlign = 16
@@ -60,11 +57,14 @@ maxSpillSlots config
= ((ncgSpillPreallocSize config - stackFrameHeaderSize)
`div` spillSlotSize) - 1
--- | Convert a spill slot number to a *byte* offset, with no sign.
+-- | Convert a spill slot number to a *byte* offset.
spillSlotToOffset :: Int -> Int
spillSlotToOffset slot
= stackFrameHeaderSize + spillSlotSize * slot
+instance Outputable RegUsage where
+ ppr (RU reads writes) = text "RegUsage(reads:" <+> ppr reads <> comma <+> text "writes:" <+> ppr writes <> char ')'
+
-- | Get the registers that are being used by this instruction.
-- regUsage doesn't need to do any trickery for jumps and such.
-- Just state precisely the regs read and written by that insn.
@@ -72,12 +72,9 @@ spillSlotToOffset slot
-- allocation goes, are taken care of by the register allocator.
--
-- RegUsage = RU [<read regs>] [<write regs>]
-
-instance Outputable RegUsage where
- ppr (RU reads writes) = text "RegUsage(reads:" <+> ppr reads <> comma <+> text "writes:" <+> ppr writes <> char ')'
-
regUsageOfInstr :: Platform -> Instr -> RegUsage
regUsageOfInstr platform instr = case instr of
+ -- 0. Meta Instructions
ANN _ i -> regUsageOfInstr platform i
COMMENT{} -> usage ([], [])
MULTILINE_COMMENT{} -> usage ([], [])
@@ -122,7 +119,6 @@ regUsageOfInstr platform instr = case instr of
CSET dst l r _ -> usage (regOp l ++ regOp r, regOp dst)
-- 7. Load and Store Instructions --------------------------------------------
STR _ src dst -> usage (regOp src ++ regOp dst, [])
- -- STLR _ src dst L -> usage (regOp src ++ regOp dst, [])
LDR _ dst src -> usage (regOp src, regOp dst)
LDRU _ dst src -> usage (regOp src, regOp dst)
@@ -160,41 +156,21 @@ regUsageOfInstr platform instr = case instr of
-- Is this register interesting for the register allocator?
interesting :: Platform -> Reg -> Bool
interesting _ (RegVirtual _) = True
- interesting _ (RegReal (RealRegSingle (-1))) = False
interesting platform (RegReal (RealRegSingle i)) = freeReg platform i
--- Save caller save registers
--- This is x0-x18
---
--- For SIMD/FP Registers:
--- Registers v8-v15 must be preserved by a callee across subroutine calls;
--- the remaining registers (v0-v7, v16-v31) do not need to be preserved (or
--- should be preserved by the caller). Additionally, only the bottom 64 bits
--- of each value stored in v8-v15 need to be preserved [7]; it is the
--- responsibility of the caller to preserve larger values.
+-- | Caller-saved registers (according to calling convention)
--
--- .---------------------------------------------------------------------------------------------------------------------------------------------------------------.
--- | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
--- | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 42 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
--- |== General Purpose registers ==================================================================================================================================|
--- | ZR | RA | SP | GP | TP | <- tmp r. -> | FP | <- | <---- argument passing -------------> | -- callee saved ------------------------------> | <--- tmp regs --> |
--- | -- | -- | -- | -- | -- | <- free r. > | -- | BR | <---- free registers ---------------> | SP | HP | R1 | R2 | R3 | R4 | R5 | R6 | R7 | SL | <-- free regs --> |
--- |== SIMD/FP Registers ==========================================================================================================================================|
--- | <--- temporary registers -----------> | <------ | <---- argument passing -------------> | -- callee saved ------------------------------> | <--- tmp regs --> |
--- | <---------- free registers ---------> | F1 | F2 | <---- free registers ---------------> | F3 | F4 | F5 | F6 | D1 | D2 | D3 | D4 | D5 | D6 | -- | -- | -- | -- |
--- '---------------------------------------------------------------------------------------------------------------------------------------------------------------'
--- ZR: Zero, RA: Return Address, SP: Stack Pointer, GP: Global Pointer, TP: Thread Pointer, FP: Frame Pointer
--- BR: Base, SL: SpLim
+-- These registers may be clobbered after a jump.
callerSavedRegisters :: [Reg]
callerSavedRegisters =
- map regSingle [t0RegNo .. t2RegNo]
+ [regSingle raRegNo]
+ ++ map regSingle [t0RegNo .. t2RegNo]
++ map regSingle [a0RegNo .. a7RegNo]
++ map regSingle [t3RegNo .. t6RegNo]
++ map regSingle [ft0RegNo .. ft7RegNo]
++ map regSingle [fa0RegNo .. fa7RegNo]
--- | Apply a given mapping to all the register references in this
--- instruction.
+-- | Apply a given mapping to all the register references in this instruction.
patchRegsOfInstr :: Instr -> (Reg -> Reg) -> Instr
patchRegsOfInstr instr env = case instr of
-- 0. Meta Instructions
@@ -525,6 +501,7 @@ allocMoreStack platform slots proc@(CmmProc info lbl live (ListGraph code)) = do
-- This most notably leaves out B. (Bit Manipulation) instructions.
data Instr
+ -- 0. Pseudo Instructions --------------------------------------------------
-- comment pseudo-op
= COMMENT SDoc
| MULTILINE_COMMENT SDoc
@@ -550,7 +527,6 @@ data Instr
-- benefit of subsequent passes
| DELTA Int
- -- 0. Pseudo Instructions --------------------------------------------------
| PUSH_STACK_FRAME
| POP_STACK_FRAME
=====================================
compiler/GHC/CmmToAsm/RV64/Regs.hs
=====================================
@@ -22,6 +22,11 @@ import GHC.Platform
x0RegNo :: RegNo
x0RegNo = 0
+-- | return address register
+x1RegNo, raRegNo :: RegNo
+x1RegNo = 1
+raRegNo = x1RegNo
+
x5RegNo, t0RegNo :: RegNo
x5RegNo = 5
t0RegNo = x5RegNo
=====================================
compiler/GHC/CmmToAsm/Reg/Linear.hs
=====================================
@@ -222,7 +222,7 @@ linearRegAlloc config entry_ids block_live sccs
ArchAlpha -> panic "linearRegAlloc ArchAlpha"
ArchMipseb -> panic "linearRegAlloc ArchMipseb"
ArchMipsel -> panic "linearRegAlloc ArchMipsel"
- ArchRISCV64 -> go $ (frInitFreeRegs platform :: RV64.FreeRegs)
+ ArchRISCV64 -> go (frInitFreeRegs platform :: RV64.FreeRegs)
ArchLoongArch64-> panic "linearRegAlloc ArchLoongArch64"
ArchJavaScript -> panic "linearRegAlloc ArchJavaScript"
ArchWasm32 -> panic "linearRegAlloc ArchWasm32"
=====================================
compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
=====================================
@@ -67,10 +67,10 @@ instance FR AArch64.FreeRegs where
frReleaseReg = \_ -> AArch64.releaseReg
instance FR RV64.FreeRegs where
- frAllocateReg = \_ -> RV64.allocateReg
- frGetFreeRegs = \_ -> RV64.getFreeRegs
+ frAllocateReg = const RV64.allocateReg
+ frGetFreeRegs = const RV64.getFreeRegs
frInitFreeRegs = RV64.initFreeRegs
- frReleaseReg = \_ -> RV64.releaseReg
+ frReleaseReg = const RV64.releaseReg
maxSpillSlots :: NCGConfig -> Int
maxSpillSlots config = case platformArch (ncgPlatform config) of
=====================================
compiler/GHC/CmmToAsm/Reg/Linear/RV64.hs
=====================================
@@ -1,65 +1,96 @@
-module GHC.CmmToAsm.Reg.Linear.RV64 where
-
-import GHC.Prelude
+-- | Functions to implement the @FR@ (as in "free regs") type class.
+--
+-- For LLVM GHC calling convention (used registers), see
+-- https://github.com/llvm/llvm-project/blob/6ab900f8746e7d8e24afafb5886a40801f6799f4/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L13638-L13685
+module GHC.CmmToAsm.Reg.Linear.RV64
+ ( allocateReg,
+ getFreeRegs,
+ initFreeRegs,
+ releaseReg,
+ FreeRegs (..),
+ )
+where
+import Data.Word
import GHC.CmmToAsm.RV64.Regs
-import GHC.Platform.Reg.Class
+import GHC.Platform
import GHC.Platform.Reg
-
+import GHC.Platform.Reg.Class
+import GHC.Prelude
+import GHC.Stack
import GHC.Utils.Outputable
import GHC.Utils.Panic
-import GHC.Platform
-
-import Data.Word
-
-import GHC.Stack
-data FreeRegs = FreeRegs !Word32 !Word32
+-- | Bitmaps to indicate which registers are free (currently unused)
+--
+-- The bit index represents the `RegNo`, in case of floating point registers
+-- with an offset of 32. The register is free when the bit is set.
+data FreeRegs
+ = FreeRegs
+ -- | integer/general purpose registers (`RcInteger`)
+ !Word32
+ -- | floating point registers (`RcDouble`)
+ !Word32
instance Show FreeRegs where
- show (FreeRegs g f) = "FreeRegs: " ++ showBits g ++ "; " ++ showBits f
-
-instance Outputable FreeRegs where
- ppr (FreeRegs g f) = text " " <+> foldr (\i x -> pad_int i <+> x) (text "") [0..31]
- $$ text "GPR" <+> foldr (\i x -> show_bit g i <+> x) (text "") [0..31]
- $$ text "FPR" <+> foldr (\i x -> show_bit f i <+> x) (text "") [0..31]
- where pad_int i | i < 10 = char ' ' <> int i
- pad_int i = int i
- -- remember bit = 1 means it's available.
- show_bit bits bit | testBit bits bit = text " "
- show_bit _ _ = text " x"
-
-noFreeRegs :: FreeRegs
-noFreeRegs = FreeRegs 0 0
+ show (FreeRegs g f) = "FreeRegs 0b" ++ showBits g ++ " 0b" ++ showBits f
+-- | Show bits as a `String` of @1 at s and @0 at s
showBits :: Word32 -> String
-showBits w = map (\i -> if testBit w i then '1' else '0') [0..31]
+showBits w = map (\i -> if testBit w i then '1' else '0') [0 .. 31]
--- FR instance implementation (See Linear.FreeRegs)
-allocateReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
-allocateReg (RealRegSingle r) (FreeRegs g f)
- | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32))
- | r < 32 && testBit g r = FreeRegs (clearBit g r) f
- | r > 31 = panic $ "Linear.RV64.allocReg: double allocation of float reg v" ++ show (r - 32) ++ "; " ++ showBits f
- | otherwise = pprPanic "Linear.RV64.allocReg" $ text ("double allocation of gp reg x" ++ show r ++ "; " ++ showBits g)
-
--- For LLVM Interop, see https://github.com/llvm/llvm-project/blob/6ab900f8746e7d8e24afafb5886a40801f6799f4/llvm/lib/Target/RISCV/RISCVISelLowering.cpp#L13638-L13685
-getFreeRegs :: RegClass -> FreeRegs -> [RealReg]
-getFreeRegs cls (FreeRegs g f)
- | RcFloat <- cls = [] -- For now we only support double and integer registers, floats will need to be promoted.
- | RcDouble <- cls = go 32 f [0..31]
- | RcInteger <- cls = go 0 g ([5..7] ++ [10..17] ++ [28..31])
+instance Outputable FreeRegs where
+ ppr (FreeRegs g f) =
+ text " "
+ <+> foldr (\i x -> pad_int i <+> x) (text "") [0 .. 31]
+ $$ text "GPR"
+ <+> foldr (\i x -> show_bit g i <+> x) (text "") [0 .. 31]
+ $$ text "FPR"
+ <+> foldr (\i x -> show_bit f i <+> x) (text "") [0 .. 31]
where
- go _ _ [] = []
- go off x (i:is) | testBit x i = RealRegSingle (off + i) : (go off x $! is)
- | otherwise = go off x $! is
+ pad_int i | i < 10 = char ' ' <> int i
+ pad_int i = int i
+ -- remember bit = 1 means it's available.
+ show_bit bits bit | testBit bits bit = text " "
+ show_bit _ _ = text " x"
+-- | Set bits of all allocatable registers to 1
initFreeRegs :: Platform -> FreeRegs
initFreeRegs platform = foldl' (flip releaseReg) noFreeRegs (allocatableRegs platform)
+ where
+ noFreeRegs :: FreeRegs
+ noFreeRegs = FreeRegs 0 0
+
+-- | Get all free `RealReg`s (i.e. those where the corresponding bit is 1)
+getFreeRegs :: RegClass -> FreeRegs -> [RealReg]
+getFreeRegs cls (FreeRegs g f)
+ | RcFloat <- cls = [] -- For now we only support double and integer registers, floats will need to be promoted.
+ | RcDouble <- cls = go 32 f allocatableDoubleRegs
+ | RcInteger <- cls = go 0 g allocatableIntRegs
+ where
+ go _ _ [] = []
+ go off x (i : is)
+ | testBit x i = RealRegSingle (off + i) : (go off x $! is)
+ | otherwise = go off x $! is
+ -- The lists of allocatable registers are manually crafted: Register
+ -- allocation is pretty hot code. We don't want to iterate and map like
+ -- `initFreeRegs` all the time! (The register mappings aren't supposed to
+ -- change often.)
+ allocatableIntRegs = [5 .. 7] ++ [10 .. 17] ++ [28 .. 30]
+ allocatableDoubleRegs = [0 .. 7] ++ [10 .. 17] ++ [28 .. 31]
+
+-- | Set corresponding register bit to 0
+allocateReg :: (HasCallStack) => RealReg -> FreeRegs -> FreeRegs
+allocateReg (RealRegSingle r) (FreeRegs g f)
+ | r > 31 && testBit f (r - 32) = FreeRegs g (clearBit f (r - 32))
+ | r < 32 && testBit g r = FreeRegs (clearBit g r) f
+ | r > 31 = panic $ "Linear.RV64.allocReg: double allocation of float reg v" ++ show (r - 32) ++ "; " ++ showBits f
+ | otherwise = pprPanic "Linear.RV64.allocReg" $ text ("double allocation of gp reg x" ++ show r ++ "; " ++ showBits g)
-releaseReg :: HasCallStack => RealReg -> FreeRegs -> FreeRegs
+-- | Set corresponding register bit to 1
+releaseReg :: (HasCallStack) => RealReg -> FreeRegs -> FreeRegs
releaseReg (RealRegSingle r) (FreeRegs g f)
- | r > 31 && testBit f (r - 32) = pprPanic "Linear.RV64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32))
+ | r > 31 && testBit f (r - 32) = pprPanic "Linear.RV64.releaseReg" (text "can't release non-allocated reg v" <> int (r - 32))
| r < 32 && testBit g r = pprPanic "Linear.RV64.releaseReg" (text "can't release non-allocated reg x" <> int r)
| r > 31 = FreeRegs g (setBit f (r - 32))
- | otherwise = FreeRegs (setBit g r) f
\ No newline at end of file
+ | otherwise = FreeRegs (setBit g r) f
=====================================
rts/linker/elf_reloc_aarch64.c
=====================================
@@ -339,7 +339,7 @@ relocateObjectCodeAarch64(ObjectCode * oc) {
return EXIT_SUCCESS;
}
-void flushInstructionCacheAarch64(ObjectCode * oc) {
+void flushInstructionCacheAarch64(ObjectCode * oc STG_UNUSED) {
// Looks like we don't need this on Aarch64.
/* no-op */
}
=====================================
tests/compiler/cmm/shift_right.cmm deleted
=====================================
@@ -1,24 +0,0 @@
-// RUN: "$HC" -debug -dppr-debug -cpp -dcmm-lint -keep-s-file -O0 -c "$1" && cat "${1%%.*}.s" | FileCheck "$1" -check-prefix=CHECK-RV64
-// RUN: "$CC" "${1%%.*}.o" -o "${1%%.*}.exe"
-// RUN: "$EXEC" "${1%%.cmm}.exe"
-
-#include "Cmm.h"
-#include "Types.h"
-
-main() {
- I64 buffer;
- I32 a, b, c, d;
-
- I64 arr;
- (arr) = foreign "C" malloc(1024);
- bits64[arr] = 2;
-
- a = I32[arr];
- b = %mul(a, 32 :: I32);
- c = %neg(b);
- d = %shra(c, 4::I64);
-
- foreign "C" printf("a: %hd b: %hd c: %hd d: %hd", a, b, c, d);
-
- foreign "C" exit(d == -4 :: I32);
-}
=====================================
tests/compiler/cmm/zero.cmm deleted
=====================================
@@ -1,14 +0,0 @@
-// RUN: "$HC" -cpp -dcmm-lint -keep-s-file -c "$1" && cat "${1%%.*}.s" | FileCheck "$1" -check-prefix=CHECK-RV64
-// RUN: "$CC" "${1%%.*}.o" -o "${1%%.*}.exe"
-// RUN: "$EXEC" "${1%%.cmm}.exe"
-
-#include "Cmm.h"
-#include "Types.h"
-
-main(){
- I64 zero;
- // Should refer to the zero register
- // CHECK-RV64: addi t0, zero, 0
- zero = 0;
- foreign "C" exit(zero);
-}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68248914206de3db164c16b15a29d0361fed2802...0b64352ba474f1fe1bab41b6620afdcdd2994d97
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/68248914206de3db164c16b15a29d0361fed2802...0b64352ba474f1fe1bab41b6620afdcdd2994d97
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/20240616/b709b9d7/attachment-0001.html>
More information about the ghc-commits
mailing list