summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Smeding <tom.smeding@gmail.com>2019-04-24 15:17:09 +0200
committerTom Smeding <tom.smeding@gmail.com>2019-04-24 15:17:09 +0200
commit3c40705b60d40f4c863c72091b3b4f30ff79c916 (patch)
tree20708b28a181d766ba669c9feba560badc9fa7b4
parent368c5972b648508d6a07b98b1b883f54a4eddd07 (diff)
Prepare for setting up register spilling
-rw-r--r--Lower.hs49
1 files changed, 25 insertions, 24 deletions
diff --git a/Lower.hs b/Lower.hs
index cde2e2b..778193b 100644
--- a/Lower.hs
+++ b/Lower.hs
@@ -1,13 +1,3 @@
--- TODO
--- Use the link register, R14, for the frame pointer (i.e. points to the
--- link register stack slot, from which argument positions are independent
--- of spill space). Upon a function call, the frame pointer needs to be
--- pushed because R14 is overwritten by the call. The value 8 can be
--- obtained each time through a Li on a new temporary.
--- If that works out to be impossible, use R12 as the constant 8.
-
-
-
{-# LANGUAGE TupleSections, MultiWayIf, GeneralizedNewtypeDeriving #-}
module Lower(lowerIR) where
@@ -23,7 +13,7 @@ data AsmProgram' = AsmProgram' [(Label, [AsmInstr'])]
deriving (Show)
data AsmInstr'
- = Li ARef Int
+ = Li ARef Immediate
| Mv ARef ARef
| Arith Arith ARef ARef ARef
| Not ARef ARef
@@ -33,6 +23,10 @@ data AsmInstr'
-- Load/Store: 'Int' is number of BYTES.
| Load Int ARef ARef
| Store Int ARef ARef
+ -- Macro's that will be instantiated with code to set up and clean up
+ -- the register spill space. Will use R14 as temporary.
+ | SetupSpill
+ | CleanupSpill
deriving (Show)
data ARef
@@ -43,6 +37,11 @@ data ARef
| ANone
deriving (Show)
+data Immediate
+ = Imm Int
+ | FPOffset Int
+ deriving (Show)
+
newtype Label = Label String
deriving (Show)
@@ -148,7 +147,7 @@ lowerIns (dest, instruction) gfds = case instruction of
IParam idx -> do
offsetr <- genTemp
- return [Li offsetr (8 * (idx + 1))
+ return [Li offsetr (FPOffset (8 * (idx + 1)))
,Arith Add offsetr offsetr (ASysReg 15)
,Load 8 (toARefStore dest) offsetr]
@@ -181,12 +180,12 @@ lowerIns (dest, instruction) gfds = case instruction of
-- push arg1
-- call [closurer]
-- add rsp, (8 * N)
- -- add rsp, rcx
+ -- add rsp, [closurer + 8]
-- mov dest, rax
return $
inss1 ++ inss2 ++
- [Li eightr 8
+ [Li eightr (Imm 8)
-- Copy the closure parameters: first make space
,Arith Add walkr closurer eightr
,Load 8 numitemsr walkr
@@ -202,7 +201,7 @@ lowerIns (dest, instruction) gfds = case instruction of
,Arith Sub (ASysReg 15) (ASysReg 15) eightr
,Store 8 (ASysReg 15) closurebufr
,Jcc CCNZ (ASysReg 0) (Label "__builtin_memcpy")
- ,Li twentyfourr 24
+ ,Li twentyfourr (Imm 24)
,Arith Add (ASysReg 15) (ASysReg 15) twentyfourr] ++
-- Copy the function parameters
concat [[Arith Sub (ASysReg 15) (ASysReg 15) eightr
@@ -213,7 +212,7 @@ lowerIns (dest, instruction) gfds = case instruction of
,Arith Add (ASysReg 14) (ASysReg 0) eightr
,JccR CCNZ (ASysReg 0) funptrr
-- Clean up the stack
- ,Li stackshiftr (8 * length argrs)
+ ,Li stackshiftr (Imm (8 * length argrs))
,Arith Add stackshiftr stackshiftr numbytesr
,Arith Add (ASysReg 15) (ASysReg 15) stackshiftr
,Mv (toARefStore dest) (ASysReg 13)]
@@ -234,17 +233,17 @@ lowerIns (dest, instruction) gfds = case instruction of
(inss, refs') <- toARefs refs
return $
inss ++
- [Li eightr 8
+ [Li eightr (Imm 8)
-- First call malloc to obtain an allocation
,Arith Sub (ASysReg 15) (ASysReg 15) eightr
- ,Li allocsizer (16 + 8 * length refs)
+ ,Li allocsizer (Imm (16 + 8 * length refs))
,Store 8 (ASysReg 15) allocsizer
,Jcc CCNZ (ASysReg 0) (Label "__builtin_malloc")
,Mv destr (ASysReg 13)
-- Then put the right data in the closure allocation
,Store 8 destr (ALabel ("BB" ++ show initBId))
,Arith Add itemr destr eightr
- ,Li numitemsr (length refs')
+ ,Li numitemsr (Imm (length refs'))
,Store 8 itemr numitemsr] ++
concat [[Arith Add itemr itemr eightr, Store 8 itemr ref]
| ref <- refs']
@@ -253,12 +252,13 @@ lowerIns (dest, instruction) gfds = case instruction of
return []
IFunctionEntry -> do
- -- We need to push the link register
+ -- We need to push the link register and set up the spill space
eightr <- genTemp
return
- [Li eightr 8
+ [Li eightr (Imm 8)
,Arith Sub (ASysReg 15) (ASysReg 15) eightr
- ,Store 8 (ASysReg 15) (ASysReg 14)]
+ ,Store 8 (ASysReg 15) (ASysReg 14)
+ ,SetupSpill]
lowerTerm :: Terminator -> LM [AsmInstr']
lowerTerm terminator = case terminator of
@@ -279,8 +279,9 @@ lowerTerm terminator = case terminator of
return $
inss ++
[Mv (ASysReg 13) valr
+ ,CleanupSpill
,Load 8 ptrr (ASysReg 15)
- ,Li eightr 8
+ ,Li eightr (Imm 8)
,Arith Add (ASysReg 15) (ASysReg 15) eightr
,JccR CCNZ (ASysReg 0) ptrr]
@@ -300,7 +301,7 @@ lowerBuiltin (RSClo "+") [arg1, arg2] = Just $ do
lowerBuiltin _ _ = Nothing
toARef :: Ref -> LM ([AsmInstr'], ARef)
-toARef (RConst val) = genTemp >>= \r -> return ([Li r val], r)
+toARef (RConst val) = genTemp >>= \r -> return ([Li r (Imm val)], r)
toARef ref = return ([], toARefStore ref)
toARefs :: [Ref] -> LM ([AsmInstr'], [ARef])