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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
-- | Formats on this architecture
-- A Format is a combination of width and class
--
-- TODO: Signed vs unsigned?
--
-- TODO: This module is currently shared by all architectures because
-- NCGMonad need to know about it to make a VReg. It would be better
-- to have architecture specific formats, and do the overloading
-- properly. eg SPARC doesn't care about FF80.
--
module GHC.CmmToAsm.Format (
Format(..),
intFormat,
floatFormat,
isIntFormat,
isFloatFormat,
cmmTypeFormat,
formatToWidth,
formatInBytes
)
where
import GHC.Prelude
import GHC.Cmm
import GHC.Utils.Outputable
import GHC.Utils.Panic
-- It looks very like the old MachRep, but it's now of purely local
-- significance, here in the native code generator. You can change it
-- without global consequences.
--
-- A major use is as an opcode qualifier; thus the opcode
-- mov.l a b
-- might be encoded
-- MOV II32 a b
-- where the Format field encodes the ".l" part.
-- ToDo: it's not clear to me that we need separate signed-vs-unsigned formats
-- here. I've removed them from the x86 version, we'll see what happens --SDM
-- ToDo: quite a few occurrences of Format could usefully be replaced by Width
data Format
= II8
| II16
| II32
| II64
| FF32
| FF64
deriving (Show, Eq)
-- | Get the integer format of this width.
intFormat :: Width -> Format
intFormat width
= case width of
W8 -> II8
W16 -> II16
W32 -> II32
W64 -> II64
other -> sorry $ "The native code generator cannot " ++
"produce code for Format.intFormat " ++ show other
++ "\n\tConsider using the llvm backend with -fllvm"
-- | Get the float format of this width.
floatFormat :: Width -> Format
floatFormat width
= case width of
W32 -> FF32
W64 -> FF64
other -> pprPanic "Format.floatFormat" (ppr other)
-- | Check if a format represent an integer value.
isIntFormat :: Format -> Bool
isIntFormat = not . isFloatFormat
-- | Check if a format represents a floating point value.
isFloatFormat :: Format -> Bool
isFloatFormat format
= case format of
FF32 -> True
FF64 -> True
_ -> False
-- | Convert a Cmm type to a Format.
cmmTypeFormat :: CmmType -> Format
cmmTypeFormat ty
| isFloatType ty = floatFormat (typeWidth ty)
| otherwise = intFormat (typeWidth ty)
-- | Get the Width of a Format.
formatToWidth :: Format -> Width
formatToWidth format
= case format of
II8 -> W8
II16 -> W16
II32 -> W32
II64 -> W64
FF32 -> W32
FF64 -> W64
formatInBytes :: Format -> Int
formatInBytes = widthInBytes . formatToWidth
|