aboutsummaryrefslogtreecommitdiff
path: root/CodeGen.hs
diff options
context:
space:
mode:
Diffstat (limited to 'CodeGen.hs')
-rw-r--r--CodeGen.hs10
1 files changed, 9 insertions, 1 deletions
diff --git a/CodeGen.hs b/CodeGen.hs
index 8eee371..bf3e477 100644
--- a/CodeGen.hs
+++ b/CodeGen.hs
@@ -64,6 +64,7 @@ codegen (IRProgram vars funcs) = do
x64 <- execCGMonad $ mapM_ codegenFunc funcs
-- traceShowM x64
X64.verify x64
+ -- traceM $ X64.stringify x64
varcg <- liftM unlines $ mapM codegenVar vars
x64opt <- x64Optimise x64
return $ "extern putc, putint, getc, exit, _builtin_malloc, _builtin_outofbounds\n" ++
@@ -109,6 +110,7 @@ codegenFunc (IRFunc _ name al bbs sid) = do
traceM $ "ALLOCATION: " ++ show allocation
let nsaves = length usedregs
+ alignoff = if odd nsaves then 8 else 0
allocationXref = flip Map.mapWithKey allocation $ \ref alloc -> case alloc of
AllocReg reg -> XReg (fromIntegral $ refSize ref) reg
AllocMem -> XMem (fromIntegral $ refSize ref)
@@ -117,7 +119,8 @@ codegenFunc (IRFunc _ name al bbs sid) = do
allocmap = foldl inserter allocationXref (zip al [0::Int ..])
where
inserter m ((t, n), i) =
- let offset = fromIntegral spillsz + 8 * nsaves + 8 {- rbp -} + 8 {- ret addr -} + 8 * i
+ let offset = fromIntegral spillsz + alignoff + 8 * nsaves +
+ 8 {- rbp -} + 8 {- ret addr -} + 8 * i
in Map.insert (Argument (sizeof t) n)
(XMem (fromIntegral $ sizeof t)
(Just RSP) (0, RAX) Nothing
@@ -128,6 +131,7 @@ codegenFunc (IRFunc _ name al bbs sid) = do
addIns $ PUSH (xref $ XReg 8 RBP)
addIns $ MOV (xref $ XReg 8 RBP) (xref $ XReg 8 RSP)
forM_ usedregs $ \reg -> addIns $ PUSH (xref $ XReg 8 reg)
+ when (odd $ length usedregs) $ addIns $ SUB (xref $ XReg 8 RSP) (xref $ XImm 8)
when (spillsz /= 0) $ addIns $ SUB (xref $ XReg 8 RSP) (xref $ XImm $ fromIntegral spillsz)
setRegsToRestore usedregs
setSpillSize spillsz
@@ -291,6 +295,7 @@ codegenIns m (IAri at d s1 s2) = case arithTypeToCondCode at of
s1m = mkxref s1 m
s2m = mkxref s2 m
codegenIns m (ICall n rs) = do
+ when (odd $ length rs) $ addIns $ SUB (xref $ XReg 8 RSP) (xref $ XImm 8)
forM_ (zip (reverse rs) [1::Int ..]) $ \(r, i) ->
let sz = fromIntegral $ refSize r
src = (mkxref r m)
@@ -304,6 +309,7 @@ codegenIns m (ICall n rs) = do
when (length rs > 0) $ addIns $ SUB (xref $ XReg 8 RSP) (xref $ XImm (fromIntegral $ 8 * length rs))
addIns $ CALL n
when (length rs > 0) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm (fromIntegral $ 8 * length rs))
+ when (odd $ length rs) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm 8)
codegenIns m (ICallr d n rs) = do
codegenIns m (ICall n rs)
addIns $ mkmov (mkxref d m) (XReg (fromIntegral $ refSize d) RAX)
@@ -380,6 +386,7 @@ codegenTerm _ IRet = do
spillsz <- gets spillSize
when (spillsz /= 0) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm $ fromIntegral spillsz)
usedregs <- gets regsToRestore
+ when (odd $ length usedregs) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm 8)
forM_ (reverse usedregs) $ \reg -> addIns $ POP (xref $ XReg 8 reg)
addIns $ mkmov (XReg 8 RSP) (XReg 8 RBP)
addIns $ POP (xref $ XReg 8 RBP)
@@ -389,6 +396,7 @@ codegenTerm m (IRetr r) = do
spillsz <- gets spillSize
when (spillsz /= 0) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm $ fromIntegral spillsz)
usedregs <- gets regsToRestore
+ when (odd $ length usedregs) $ addIns $ ADD (xref $ XReg 8 RSP) (xref $ XImm 8)
forM_ (reverse usedregs) $ \reg -> addIns $ POP (xref $ XReg 8 reg)
addIns $ mkmov (XReg 8 RSP) (XReg 8 RBP)
addIns $ POP (xref $ XReg 8 RBP)