diff options
Diffstat (limited to 'CodeGen.hs')
-rw-r--r-- | CodeGen.hs | 10 |
1 files changed, 9 insertions, 1 deletions
@@ -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) |