Pass 512-bit-wide vectors in registers.
[ghc.git] / compiler / llvmGen / LlvmCodeGen / Regs.hs
1 --------------------------------------------------------------------------------
2 -- | Deal with Cmm registers
3 --
4
5 module LlvmCodeGen.Regs (
6 lmGlobalRegArg, lmGlobalRegVar, alwaysLive,
7 stgTBAA, baseN, stackN, heapN, rxN, otherN, tbaa, getTBAA
8 ) where
9
10 #include "HsVersions.h"
11
12 import Llvm
13
14 import CmmExpr
15 import DynFlags
16 import FastString
17 import Outputable ( panic )
18 import Unique
19
20 -- | Get the LlvmVar function variable storing the real register
21 lmGlobalRegVar :: DynFlags -> GlobalReg -> LlvmVar
22 lmGlobalRegVar dflags = pVarLift . lmGlobalReg dflags "_Var"
23
24 -- | Get the LlvmVar function argument storing the real register
25 lmGlobalRegArg :: DynFlags -> GlobalReg -> LlvmVar
26 lmGlobalRegArg dflags = lmGlobalReg dflags "_Arg"
27
28 {- Need to make sure the names here can't conflict with the unique generated
29 names. Uniques generated names containing only base62 chars. So using say
30 the '_' char guarantees this.
31 -}
32 lmGlobalReg :: DynFlags -> String -> GlobalReg -> LlvmVar
33 lmGlobalReg dflags suf reg
34 = case reg of
35 BaseReg -> ptrGlobal $ "Base" ++ suf
36 Sp -> ptrGlobal $ "Sp" ++ suf
37 Hp -> ptrGlobal $ "Hp" ++ suf
38 VanillaReg 1 _ -> wordGlobal $ "R1" ++ suf
39 VanillaReg 2 _ -> wordGlobal $ "R2" ++ suf
40 VanillaReg 3 _ -> wordGlobal $ "R3" ++ suf
41 VanillaReg 4 _ -> wordGlobal $ "R4" ++ suf
42 VanillaReg 5 _ -> wordGlobal $ "R5" ++ suf
43 VanillaReg 6 _ -> wordGlobal $ "R6" ++ suf
44 VanillaReg 7 _ -> wordGlobal $ "R7" ++ suf
45 VanillaReg 8 _ -> wordGlobal $ "R8" ++ suf
46 SpLim -> wordGlobal $ "SpLim" ++ suf
47 FloatReg 1 -> floatGlobal $"F1" ++ suf
48 FloatReg 2 -> floatGlobal $"F2" ++ suf
49 FloatReg 3 -> floatGlobal $"F3" ++ suf
50 FloatReg 4 -> floatGlobal $"F4" ++ suf
51 FloatReg 5 -> floatGlobal $"F5" ++ suf
52 FloatReg 6 -> floatGlobal $"F6" ++ suf
53 DoubleReg 1 -> doubleGlobal $ "D1" ++ suf
54 DoubleReg 2 -> doubleGlobal $ "D2" ++ suf
55 DoubleReg 3 -> doubleGlobal $ "D3" ++ suf
56 DoubleReg 4 -> doubleGlobal $ "D4" ++ suf
57 DoubleReg 5 -> doubleGlobal $ "D5" ++ suf
58 DoubleReg 6 -> doubleGlobal $ "D6" ++ suf
59 XmmReg 1 -> xmmGlobal $ "XMM1" ++ suf
60 XmmReg 2 -> xmmGlobal $ "XMM2" ++ suf
61 XmmReg 3 -> xmmGlobal $ "XMM3" ++ suf
62 XmmReg 4 -> xmmGlobal $ "XMM4" ++ suf
63 XmmReg 5 -> xmmGlobal $ "XMM5" ++ suf
64 XmmReg 6 -> xmmGlobal $ "XMM6" ++ suf
65 YmmReg 1 -> ymmGlobal $ "YMM1" ++ suf
66 YmmReg 2 -> ymmGlobal $ "YMM2" ++ suf
67 YmmReg 3 -> ymmGlobal $ "YMM3" ++ suf
68 YmmReg 4 -> ymmGlobal $ "YMM4" ++ suf
69 YmmReg 5 -> ymmGlobal $ "YMM5" ++ suf
70 YmmReg 6 -> ymmGlobal $ "YMM6" ++ suf
71 ZmmReg 1 -> zmmGlobal $ "ZMM1" ++ suf
72 ZmmReg 2 -> zmmGlobal $ "ZMM2" ++ suf
73 ZmmReg 3 -> zmmGlobal $ "ZMM3" ++ suf
74 ZmmReg 4 -> zmmGlobal $ "ZMM4" ++ suf
75 ZmmReg 5 -> zmmGlobal $ "ZMM5" ++ suf
76 ZmmReg 6 -> zmmGlobal $ "ZMM6" ++ suf
77 _other -> panic $ "LlvmCodeGen.Reg: GlobalReg (" ++ (show reg)
78 ++ ") not supported!"
79 -- LongReg, HpLim, CCSS, CurrentTSO, CurrentNusery, HpAlloc
80 -- EagerBlackholeInfo, GCEnter1, GCFun, BaseReg, PicBaseReg
81 where
82 wordGlobal name = LMNLocalVar (fsLit name) (llvmWord dflags)
83 ptrGlobal name = LMNLocalVar (fsLit name) (llvmWordPtr dflags)
84 floatGlobal name = LMNLocalVar (fsLit name) LMFloat
85 doubleGlobal name = LMNLocalVar (fsLit name) LMDouble
86 xmmGlobal name = LMNLocalVar (fsLit name) (LMVector 4 (LMInt 32))
87 ymmGlobal name = LMNLocalVar (fsLit name) (LMVector 8 (LMInt 32))
88 zmmGlobal name = LMNLocalVar (fsLit name) (LMVector 16 (LMInt 32))
89
90 -- | A list of STG Registers that should always be considered alive
91 alwaysLive :: [GlobalReg]
92 alwaysLive = [BaseReg, Sp, Hp, SpLim, HpLim, node]
93
94 -- | STG Type Based Alias Analysis hierarchy
95 stgTBAA :: [(Unique, LMString, Maybe Unique)]
96 stgTBAA
97 = [ (topN, fsLit "top", Nothing)
98 , (stackN, fsLit "stack", Just topN)
99 , (heapN, fsLit "heap", Just topN)
100 , (rxN, fsLit "rx", Just heapN)
101 , (baseN, fsLit "base", Just topN)
102 -- FIX: Not 100% sure about 'others' place. Might need to be under 'heap'.
103 -- OR I think the big thing is Sp is never aliased, so might want
104 -- to change the hieracy to have Sp on its own branch that is never
105 -- aliased (e.g never use top as a TBAA node).
106 , (otherN, fsLit "other", Just topN)
107 ]
108
109 -- | Id values
110 topN, stackN, heapN, rxN, baseN, otherN :: Unique
111 topN = getUnique (fsLit "LlvmCodeGen.Regs.topN")
112 stackN = getUnique (fsLit "LlvmCodeGen.Regs.stackN")
113 heapN = getUnique (fsLit "LlvmCodeGen.Regs.heapN")
114 rxN = getUnique (fsLit "LlvmCodeGen.Regs.rxN")
115 baseN = getUnique (fsLit "LlvmCodeGen.Regs.baseN")
116 otherN = getUnique (fsLit "LlvmCodeGen.Regs.otherN")
117
118 -- | The TBAA metadata identifier
119 tbaa :: LMString
120 tbaa = fsLit "tbaa"
121
122 -- | Get the correct TBAA metadata information for this register type
123 getTBAA :: GlobalReg -> Unique
124 getTBAA BaseReg = baseN
125 getTBAA Sp = stackN
126 getTBAA Hp = heapN
127 getTBAA (VanillaReg _ _) = rxN
128 getTBAA _ = topN