summaryrefslogtreecommitdiff
path: root/compiler/GHC/CmmToAsm/Format.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/CmmToAsm/Format.hs')
-rw-r--r--compiler/GHC/CmmToAsm/Format.hs105
1 files changed, 105 insertions, 0 deletions
diff --git a/compiler/GHC/CmmToAsm/Format.hs b/compiler/GHC/CmmToAsm/Format.hs
new file mode 100644
index 0000000000..446c760939
--- /dev/null
+++ b/compiler/GHC/CmmToAsm/Format.hs
@@ -0,0 +1,105 @@
+-- | 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,
+ isFloatFormat,
+ cmmTypeFormat,
+ formatToWidth,
+ formatInBytes
+)
+
+where
+
+import GhcPrelude
+
+import GHC.Cmm
+import Outputable
+
+-- 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 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