Merge in new code generator branch.
[ghc-hetmet.git] / compiler / nativeGen / SPARC / CodeGen / CondCode.hs
1
2 module SPARC.CodeGen.CondCode (
3         getCondCode,
4         condIntCode,
5         condFltCode
6 )
7
8 where
9
10 import {-# SOURCE #-} SPARC.CodeGen.Gen32
11 import SPARC.CodeGen.Base
12 import SPARC.Instr
13 import SPARC.Regs
14 import SPARC.Cond
15 import SPARC.Imm
16 import SPARC.Base
17 import NCGMonad
18 import Size
19
20 import OldCmm
21
22 import OrdList
23 import Outputable
24
25
26 getCondCode :: CmmExpr -> NatM CondCode
27 getCondCode (CmmMachOp mop [x, y])
28   = 
29     case mop of
30       MO_F_Eq W32 -> condFltCode EQQ x y
31       MO_F_Ne W32 -> condFltCode NE  x y
32       MO_F_Gt W32 -> condFltCode GTT x y
33       MO_F_Ge W32 -> condFltCode GE  x y
34       MO_F_Lt W32 -> condFltCode LTT x y
35       MO_F_Le W32 -> condFltCode LE  x y
36
37       MO_F_Eq W64 -> condFltCode EQQ x y
38       MO_F_Ne W64 -> condFltCode NE  x y
39       MO_F_Gt W64 -> condFltCode GTT x y
40       MO_F_Ge W64 -> condFltCode GE  x y
41       MO_F_Lt W64 -> condFltCode LTT x y
42       MO_F_Le W64 -> condFltCode LE  x y
43
44       MO_Eq   _   -> condIntCode EQQ  x y
45       MO_Ne   _   -> condIntCode NE   x y
46
47       MO_S_Gt _   -> condIntCode GTT  x y
48       MO_S_Ge _   -> condIntCode GE   x y
49       MO_S_Lt _   -> condIntCode LTT  x y
50       MO_S_Le _   -> condIntCode LE   x y
51
52       MO_U_Gt _   -> condIntCode GU   x y
53       MO_U_Ge _   -> condIntCode GEU  x y
54       MO_U_Lt _   -> condIntCode LU   x y
55       MO_U_Le _   -> condIntCode LEU  x y
56
57       _           -> pprPanic "SPARC.CodeGen.CondCode.getCondCode" (ppr (CmmMachOp mop [x,y]))
58
59 getCondCode other =  pprPanic "SPARC.CodeGen.CondCode.getCondCode" (ppr other)
60
61
62
63
64
65 -- @cond(Int|Flt)Code@: Turn a boolean expression into a condition, to be
66 -- passed back up the tree.
67
68 condIntCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode
69 condIntCode cond x (CmmLit (CmmInt y _))
70   | fits13Bits y
71   = do
72        (src1, code) <- getSomeReg x
73        let
74            src2 = ImmInt (fromInteger y)
75            code' = code `snocOL` SUB False True src1 (RIImm src2) g0
76        return (CondCode False cond code')
77
78 condIntCode cond x y = do
79     (src1, code1) <- getSomeReg x
80     (src2, code2) <- getSomeReg y
81     let
82         code__2 = code1 `appOL` code2 `snocOL`
83                   SUB False True src1 (RIReg src2) g0
84     return (CondCode False cond code__2)
85
86
87 condFltCode :: Cond -> CmmExpr -> CmmExpr -> NatM CondCode
88 condFltCode cond x y = do
89     (src1, code1) <- getSomeReg x
90     (src2, code2) <- getSomeReg y
91     tmp <- getNewRegNat FF64
92     let
93         promote x = FxTOy FF32 FF64 x tmp
94
95         pk1   = cmmExprType x
96         pk2   = cmmExprType y
97
98         code__2 =
99                 if pk1 `cmmEqType` pk2 then
100                     code1 `appOL` code2 `snocOL`
101                     FCMP True (cmmTypeSize pk1) src1 src2
102                 else if typeWidth pk1 == W32 then
103                     code1 `snocOL` promote src1 `appOL` code2 `snocOL`
104                     FCMP True FF64 tmp src2
105                 else
106                     code1 `appOL` code2 `snocOL` promote src2 `snocOL`
107                     FCMP True FF64 src1 tmp
108     return (CondCode True cond code__2)