4 + 2 = 6
This commit is contained in:
@@ -167,6 +167,8 @@ toANF' (Lam.ExpBegin xs) k = ExpBegin <$> traverse anf xs
|
||||
where
|
||||
anf x = toANF' x (pure . ExpVal)
|
||||
|
||||
toANF' (Lam.ExpLet xs e) k = _
|
||||
|
||||
toANF' e k = _
|
||||
|
||||
toANF e = toANF' e (pure . ExpVal)
|
||||
@@ -265,9 +267,12 @@ buildBlock n bb = QBE.Block n [] (is ^.. each) j
|
||||
lowerName :: Name -> QBE.Ident t
|
||||
lowerName = fromString . T.unpack
|
||||
|
||||
lowerInt' = QBE.ValConst . QBE.CInt . fromIntegral
|
||||
|
||||
lowerInt = QBE.ValConst . QBE.CInt
|
||||
. (Data.Bits..|. 2)
|
||||
. (Data.Bits..<<. 2) . fromIntegral
|
||||
. (Data.Bits..<<. 2)
|
||||
. fromIntegral
|
||||
|
||||
lowerVal
|
||||
:: forall es. (GenSym :> es)
|
||||
@@ -298,7 +303,7 @@ lowerArithmetic r p = QBE.BinaryOp r bop x y
|
||||
PrimMul a b -> (QBE.Mul,a,b)
|
||||
_ -> _
|
||||
|
||||
sizeofScm = 16
|
||||
sizeofScm = 8
|
||||
|
||||
lowerCons
|
||||
:: (GenSym :> es)
|
||||
@@ -315,7 +320,7 @@ lowerCons r car cdr e k = do
|
||||
Nothing
|
||||
[ QBE.Arg
|
||||
(QBE.AbiBaseTy QBE.Long)
|
||||
(QBE.ValConst (QBE.CInt sizeofScm)) ]
|
||||
(QBE.ValConst (QBE.CInt (sizeofScm * 2))) ]
|
||||
[]
|
||||
]
|
||||
initialise r1 =
|
||||
@@ -325,32 +330,53 @@ lowerCons r car cdr e k = do
|
||||
, QBE.Store (QBE.BaseTy QBE.Long) cdr (QBE.ValTemporary r1)
|
||||
]
|
||||
|
||||
smallIntHelper'
|
||||
:: GenSym :> es
|
||||
=> QBE.Ident 'QBE.Temporary
|
||||
-> QBE.BinaryOp
|
||||
-> QBE.Val -> QBE.Val
|
||||
-> (QBE.Val -> Eff es BlockBuilder)
|
||||
-> Eff es BlockBuilder
|
||||
smallIntHelper' r bop v1 v2 k = do
|
||||
Emit [ QBE.BinaryOp (r QBE.:= QBE.Long)
|
||||
bop v1 v2 ]
|
||||
<$> k (QBE.ValTemporary r)
|
||||
|
||||
smallIntHelper
|
||||
:: GenSym :> es
|
||||
=> _
|
||||
-> QBE.Val -> (QBE.Val -> Eff es BlockBuilder)
|
||||
=> QBE.BinaryOp
|
||||
-> QBE.Val -> QBE.Val
|
||||
-> (QBE.Val -> Eff es BlockBuilder)
|
||||
-> Eff es BlockBuilder
|
||||
smallIntHelper bop v k = do
|
||||
smallIntHelper bop a b k = do
|
||||
r <- gensym
|
||||
Emit [ QBE.BinaryOp (r QBE.:= QBE.Long)
|
||||
bop v (QBE.ValConst (QBE.CInt 2)) ]
|
||||
<$> k (QBE.ValTemporary r)
|
||||
smallIntHelper' r bop a b k
|
||||
|
||||
makeSmallInt'
|
||||
:: forall es. (GenSym :> es)
|
||||
=> QBE.Ident 'QBE.Temporary
|
||||
-> QBE.Val
|
||||
-> (QBE.Val -> Eff es BlockBuilder)
|
||||
-> Eff es BlockBuilder
|
||||
makeSmallInt' r n k =
|
||||
smallIntHelper QBE.Shl n (lowerInt' 2) \n' ->
|
||||
smallIntHelper' r QBE.Add n' (lowerInt' 2) k
|
||||
|
||||
makeSmallInt
|
||||
:: forall es. (GenSym :> es)
|
||||
=> QBE.Val
|
||||
-> (QBE.Val -> Eff es BlockBuilder)
|
||||
-> Eff es BlockBuilder
|
||||
makeSmallInt n k =
|
||||
smallIntHelper QBE.Shl n \n' ->
|
||||
smallIntHelper QBE.And n' k
|
||||
makeSmallInt n k = do
|
||||
r <- gensym
|
||||
makeSmallInt' r n k
|
||||
|
||||
getSmallInt
|
||||
:: forall es. (GenSym :> es)
|
||||
=> QBE.Val
|
||||
-> (QBE.Val -> Eff es BlockBuilder)
|
||||
-> Eff es BlockBuilder
|
||||
getSmallInt = smallIntHelper QBE.Shr
|
||||
getSmallInt n = smallIntHelper QBE.Shr n (lowerInt' 2)
|
||||
|
||||
lowerWrite
|
||||
:: forall es. (GenSym :> es)
|
||||
@@ -365,6 +391,31 @@ lowerWrite r x e k =
|
||||
]
|
||||
<$> k (QBE.ValTemporary (lowerName r))
|
||||
|
||||
smallIntMask :: Integer
|
||||
smallIntMask = 2 ^ (sizeofScm * 8) - 2
|
||||
|
||||
lowerCar
|
||||
:: GenSym :> es
|
||||
=> Name -> QBE.Val -> _
|
||||
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
||||
lowerCar r x e k = do
|
||||
Emit [ QBE.Load (lowerName r QBE.:= QBE.Long) QBE.Long x
|
||||
]
|
||||
<$> lower' e k
|
||||
|
||||
lowerCdr
|
||||
:: GenSym :> es
|
||||
=> Name -> QBE.Val -> Exp
|
||||
-> (QBE.Val -> Eff es BlockBuilder) -> Eff es BlockBuilder
|
||||
lowerCdr r x e k = do
|
||||
x1 <- gensym
|
||||
Emit [ QBE.BinaryOp (x1 QBE.:= QBE.Long)
|
||||
QBE.Add x (lowerInt' (sizeofScm `quot` 2))
|
||||
, QBE.Load (lowerName r QBE.:= QBE.Long) QBE.Long
|
||||
(QBE.ValTemporary x1)
|
||||
]
|
||||
<$> lower' e k
|
||||
|
||||
lowerPrim
|
||||
:: forall es. (GenSym :> es)
|
||||
=> Name -> Prim Val -> Exp
|
||||
@@ -372,19 +423,15 @@ lowerPrim
|
||||
-> Eff es BlockBuilder
|
||||
lowerPrim r p e k =
|
||||
telescope (lowerVal <$> p) \case
|
||||
(preview binaryPrim -> Just (bop,a,b)) -> do
|
||||
r1 <- gensym
|
||||
r2 <- gensym
|
||||
Emit [ QBE.BinaryOp (r1 QBE.:= QBE.Long) bop a b
|
||||
, QBE.BinaryOp (r2 QBE.:= QBE.Long) QBE.And
|
||||
(QBE.ValTemporary r1)
|
||||
(QBE.ValConst (QBE.CInt 0xffff_ffff_ffff_fffd))
|
||||
, QBE.BinaryOp (lowerName r QBE.:= QBE.Long) QBE.Or
|
||||
(QBE.ValTemporary r2)
|
||||
(QBE.ValConst (QBE.CInt 0b10))
|
||||
]
|
||||
<$> lower' e k
|
||||
(preview binaryPrim -> Just (bop,a,b)) ->
|
||||
getSmallInt a \a' ->
|
||||
getSmallInt b \b' ->
|
||||
smallIntHelper bop a' b' \c ->
|
||||
makeSmallInt' (lowerName r) c \_ ->
|
||||
lower' e k
|
||||
PrimCons x y -> lowerCons r x y e k
|
||||
PrimCar x -> lowerCar r x e k
|
||||
PrimCdr x -> lowerCdr r x e k
|
||||
PrimWrite x -> lowerWrite r x e k
|
||||
|
||||
lower'
|
||||
|
||||
Reference in New Issue
Block a user