summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2012-08-29 07:35:23 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2012-08-29 07:35:23 +0100
commit72e46baf25f757b24e3eb9ebb8f5694d8ca8722e (patch)
tree64aff42bcfb92a5b6894ee5098d40b010227ca7e /compiler
parent1bbdbe55970310f92122fb5321b65705646835b4 (diff)
parent41448969dad90e479e4eac3721fc5d5dd4968885 (diff)
downloadhaskell-72e46baf25f757b24e3eb9ebb8f5694d8ca8722e.tar.gz
Merge branch 'master' of http://darcs.haskell.org/ghc
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cmm/CmmParse.y1096
-rw-r--r--compiler/codeGen/CodeGen/Platform.hs40
-rw-r--r--compiler/codeGen/CodeGen/Platform/ARM.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/NoRegs.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/PPC.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/PPC_Darwin.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/SPARC.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/X86.hs2
-rw-r--r--compiler/codeGen/CodeGen/Platform/X86_64.hs2
-rw-r--r--compiler/coreSyn/CorePrep.lhs46
-rw-r--r--compiler/coreSyn/CoreUtils.lhs10
-rw-r--r--compiler/ghc.cabal.in1
-rw-r--r--compiler/ghci/Linker.lhs67
-rw-r--r--compiler/llvmGen/LlvmCodeGen/Ppr.hs59
-rw-r--r--compiler/main/DriverPhases.hs41
-rw-r--r--compiler/main/TidyPgm.lhs23
-rw-r--r--compiler/nativeGen/AsmCodeGen.lhs2
-rw-r--r--compiler/nativeGen/PPC/CodeGen.hs38
-rw-r--r--compiler/nativeGen/PPC/Instr.hs23
-rw-r--r--compiler/nativeGen/PPC/Regs.hs326
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/FreeRegs.hs16
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/JoinToTargets.hs2
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/Main.hs33
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/PPC/FreeRegs.hs5
-rw-r--r--compiler/nativeGen/RegAlloc/Linear/SPARC/FreeRegs.hs25
-rw-r--r--compiler/nativeGen/SPARC/CodeGen.hs10
-rw-r--r--compiler/nativeGen/SPARC/CodeGen/Base.hs11
-rw-r--r--compiler/nativeGen/SPARC/CodeGen/Gen32.hs7
-rw-r--r--compiler/nativeGen/SPARC/Instr.hs15
-rw-r--r--compiler/nativeGen/SPARC/RegPlate.hs318
-rw-r--r--compiler/nativeGen/SPARC/Regs.hs130
-rw-r--r--compiler/nativeGen/X86/CodeGen.hs157
-rw-r--r--compiler/nativeGen/X86/Instr.hs24
-rw-r--r--compiler/nativeGen/X86/Regs.hs214
-rw-r--r--compiler/utils/Util.lhs17
35 files changed, 945 insertions, 1825 deletions
diff --git a/compiler/cmm/CmmParse.y b/compiler/cmm/CmmParse.y
index cd8dc6c711..8a10724524 100644
--- a/compiler/cmm/CmmParse.y
+++ b/compiler/cmm/CmmParse.y
@@ -47,6 +47,7 @@ import Lexer
import ForeignCall
import Module
+import Platform
import Literal
import Unique
import UniqFM
@@ -65,7 +66,7 @@ import Var
import Control.Monad
import Data.Array
-import Data.Char ( ord )
+import Data.Char ( ord )
import System.Exit
#include "HsVersions.h"
@@ -74,76 +75,76 @@ import System.Exit
%expect 0
%token
- ':' { L _ (CmmT_SpecChar ':') }
- ';' { L _ (CmmT_SpecChar ';') }
- '{' { L _ (CmmT_SpecChar '{') }
- '}' { L _ (CmmT_SpecChar '}') }
- '[' { L _ (CmmT_SpecChar '[') }
- ']' { L _ (CmmT_SpecChar ']') }
- '(' { L _ (CmmT_SpecChar '(') }
- ')' { L _ (CmmT_SpecChar ')') }
- '=' { L _ (CmmT_SpecChar '=') }
- '`' { L _ (CmmT_SpecChar '`') }
- '~' { L _ (CmmT_SpecChar '~') }
- '/' { L _ (CmmT_SpecChar '/') }
- '*' { L _ (CmmT_SpecChar '*') }
- '%' { L _ (CmmT_SpecChar '%') }
- '-' { L _ (CmmT_SpecChar '-') }
- '+' { L _ (CmmT_SpecChar '+') }
- '&' { L _ (CmmT_SpecChar '&') }
- '^' { L _ (CmmT_SpecChar '^') }
- '|' { L _ (CmmT_SpecChar '|') }
- '>' { L _ (CmmT_SpecChar '>') }
- '<' { L _ (CmmT_SpecChar '<') }
- ',' { L _ (CmmT_SpecChar ',') }
- '!' { L _ (CmmT_SpecChar '!') }
-
- '..' { L _ (CmmT_DotDot) }
- '::' { L _ (CmmT_DoubleColon) }
- '>>' { L _ (CmmT_Shr) }
- '<<' { L _ (CmmT_Shl) }
- '>=' { L _ (CmmT_Ge) }
- '<=' { L _ (CmmT_Le) }
- '==' { L _ (CmmT_Eq) }
- '!=' { L _ (CmmT_Ne) }
+ ':' { L _ (CmmT_SpecChar ':') }
+ ';' { L _ (CmmT_SpecChar ';') }
+ '{' { L _ (CmmT_SpecChar '{') }
+ '}' { L _ (CmmT_SpecChar '}') }
+ '[' { L _ (CmmT_SpecChar '[') }
+ ']' { L _ (CmmT_SpecChar ']') }
+ '(' { L _ (CmmT_SpecChar '(') }
+ ')' { L _ (CmmT_SpecChar ')') }
+ '=' { L _ (CmmT_SpecChar '=') }
+ '`' { L _ (CmmT_SpecChar '`') }
+ '~' { L _ (CmmT_SpecChar '~') }
+ '/' { L _ (CmmT_SpecChar '/') }
+ '*' { L _ (CmmT_SpecChar '*') }
+ '%' { L _ (CmmT_SpecChar '%') }
+ '-' { L _ (CmmT_SpecChar '-') }
+ '+' { L _ (CmmT_SpecChar '+') }
+ '&' { L _ (CmmT_SpecChar '&') }
+ '^' { L _ (CmmT_SpecChar '^') }
+ '|' { L _ (CmmT_SpecChar '|') }
+ '>' { L _ (CmmT_SpecChar '>') }
+ '<' { L _ (CmmT_SpecChar '<') }
+ ',' { L _ (CmmT_SpecChar ',') }
+ '!' { L _ (CmmT_SpecChar '!') }
+
+ '..' { L _ (CmmT_DotDot) }
+ '::' { L _ (CmmT_DoubleColon) }
+ '>>' { L _ (CmmT_Shr) }
+ '<<' { L _ (CmmT_Shl) }
+ '>=' { L _ (CmmT_Ge) }
+ '<=' { L _ (CmmT_Le) }
+ '==' { L _ (CmmT_Eq) }
+ '!=' { L _ (CmmT_Ne) }
'&&' { L _ (CmmT_BoolAnd) }
'||' { L _ (CmmT_BoolOr) }
- 'CLOSURE' { L _ (CmmT_CLOSURE) }
- 'INFO_TABLE' { L _ (CmmT_INFO_TABLE) }
- 'INFO_TABLE_RET'{ L _ (CmmT_INFO_TABLE_RET) }
- 'INFO_TABLE_FUN'{ L _ (CmmT_INFO_TABLE_FUN) }
- 'INFO_TABLE_CONSTR'{ L _ (CmmT_INFO_TABLE_CONSTR) }
- 'INFO_TABLE_SELECTOR'{ L _ (CmmT_INFO_TABLE_SELECTOR) }
- 'else' { L _ (CmmT_else) }
- 'export' { L _ (CmmT_export) }
- 'section' { L _ (CmmT_section) }
- 'align' { L _ (CmmT_align) }
- 'goto' { L _ (CmmT_goto) }
- 'if' { L _ (CmmT_if) }
- 'jump' { L _ (CmmT_jump) }
- 'foreign' { L _ (CmmT_foreign) }
- 'never' { L _ (CmmT_never) }
- 'prim' { L _ (CmmT_prim) }
- 'return' { L _ (CmmT_return) }
- 'returns' { L _ (CmmT_returns) }
- 'import' { L _ (CmmT_import) }
- 'switch' { L _ (CmmT_switch) }
- 'case' { L _ (CmmT_case) }
- 'default' { L _ (CmmT_default) }
- 'bits8' { L _ (CmmT_bits8) }
- 'bits16' { L _ (CmmT_bits16) }
- 'bits32' { L _ (CmmT_bits32) }
- 'bits64' { L _ (CmmT_bits64) }
- 'float32' { L _ (CmmT_float32) }
- 'float64' { L _ (CmmT_float64) }
- 'gcptr' { L _ (CmmT_gcptr) }
-
- GLOBALREG { L _ (CmmT_GlobalReg $$) }
- NAME { L _ (CmmT_Name $$) }
- STRING { L _ (CmmT_String $$) }
- INT { L _ (CmmT_Int $$) }
- FLOAT { L _ (CmmT_Float $$) }
+ 'CLOSURE' { L _ (CmmT_CLOSURE) }
+ 'INFO_TABLE' { L _ (CmmT_INFO_TABLE) }
+ 'INFO_TABLE_RET' { L _ (CmmT_INFO_TABLE_RET) }
+ 'INFO_TABLE_FUN' { L _ (CmmT_INFO_TABLE_FUN) }
+ 'INFO_TABLE_CONSTR' { L _ (CmmT_INFO_TABLE_CONSTR) }
+ 'INFO_TABLE_SELECTOR' { L _ (CmmT_INFO_TABLE_SELECTOR) }
+ 'else' { L _ (CmmT_else) }
+ 'export' { L _ (CmmT_export) }
+ 'section' { L _ (CmmT_section) }
+ 'align' { L _ (CmmT_align) }
+ 'goto' { L _ (CmmT_goto) }
+ 'if' { L _ (CmmT_if) }
+ 'jump' { L _ (CmmT_jump) }
+ 'foreign' { L _ (CmmT_foreign) }
+ 'never' { L _ (CmmT_never) }
+ 'prim' { L _ (CmmT_prim) }
+ 'return' { L _ (CmmT_return) }
+ 'returns' { L _ (CmmT_returns) }
+ 'import' { L _ (CmmT_import) }
+ 'switch' { L _ (CmmT_switch) }
+ 'case' { L _ (CmmT_case) }
+ 'default' { L _ (CmmT_default) }
+ 'bits8' { L _ (CmmT_bits8) }
+ 'bits16' { L _ (CmmT_bits16) }
+ 'bits32' { L _ (CmmT_bits32) }
+ 'bits64' { L _ (CmmT_bits64) }
+ 'float32' { L _ (CmmT_float32) }
+ 'float64' { L _ (CmmT_float64) }
+ 'gcptr' { L _ (CmmT_gcptr) }
+
+ GLOBALREG { L _ (CmmT_GlobalReg $$) }
+ NAME { L _ (CmmT_Name $$) }
+ STRING { L _ (CmmT_String $$) }
+ INT { L _ (CmmT_Int $$) }
+ FLOAT { L _ (CmmT_Float $$) }
%monad { P } { >>= } { return }
%lexer { cmmlex } { L _ CmmT_EOF }
@@ -151,8 +152,8 @@ import System.Exit
%tokentype { Located CmmToken }
-- C-- operator precedences, taken from the C-- spec
-%right '||' -- non-std extension, called %disjoin in C--
-%right '&&' -- non-std extension, called %conjoin in C--
+%right '||' -- non-std extension, called %disjoin in C--
+%right '&&' -- non-std extension, called %conjoin in C--
%right '!'
%nonassoc '>=' '>' '<=' '<' '!=' '=='
%left '|'
@@ -165,102 +166,102 @@ import System.Exit
%%
-cmm :: { ExtCode }
- : {- empty -} { return () }
- | cmmtop cmm { do $1; $2 }
+cmm :: { ExtCode }
+ : {- empty -} { return () }
+ | cmmtop cmm { do $1; $2 }
-cmmtop :: { ExtCode }
- : cmmproc { $1 }
- | cmmdata { $1 }
- | decl { $1 }
- | 'CLOSURE' '(' NAME ',' NAME lits ')' ';'
- {% withThisPackage $ \pkg ->
- do lits <- sequence $6;
- staticClosure pkg $3 $5 (map getLit lits) }
+cmmtop :: { ExtCode }
+ : cmmproc { $1 }
+ | cmmdata { $1 }
+ | decl { $1 }
+ | 'CLOSURE' '(' NAME ',' NAME lits ')' ';'
+ {% withThisPackage $ \pkg ->
+ do lits <- sequence $6;
+ staticClosure pkg $3 $5 (map getLit lits) }
-- The only static closures in the RTS are dummy closures like
-- stg_END_TSO_QUEUE_closure and stg_dummy_ret. We don't need
-- to provide the full generality of static closures here.
-- In particular:
--- * CCS can always be CCS_DONT_CARE
--- * closure is always extern
--- * payload is always empty
--- * we can derive closure and info table labels from a single NAME
+-- * CCS can always be CCS_DONT_CARE
+-- * closure is always extern
+-- * payload is always empty
+-- * we can derive closure and info table labels from a single NAME
cmmdata :: { ExtCode }
- : 'section' STRING '{' data_label statics '}'
- { do lbl <- $4;
- ss <- sequence $5;
- code (emitDecl (CmmData (section $2) (Statics lbl $ concat ss))) }
+ : 'section' STRING '{' data_label statics '}'
+ { do lbl <- $4;
+ ss <- sequence $5;
+ code (emitDecl (CmmData (section $2) (Statics lbl $ concat ss))) }
data_label :: { ExtFCode CLabel }
- : NAME ':'
- {% withThisPackage $ \pkg ->
- return (mkCmmDataLabel pkg $1) }
-
-statics :: { [ExtFCode [CmmStatic]] }
- : {- empty -} { [] }
- | static statics { $1 : $2 }
-
+ : NAME ':'
+ {% withThisPackage $ \pkg ->
+ return (mkCmmDataLabel pkg $1) }
+
+statics :: { [ExtFCode [CmmStatic]] }
+ : {- empty -} { [] }
+ | static statics { $1 : $2 }
+
-- Strings aren't used much in the RTS HC code, so it doesn't seem
-- worth allowing inline strings. C-- doesn't allow them anyway.
-static :: { ExtFCode [CmmStatic] }
- : type expr ';' { do e <- $2;
- return [CmmStaticLit (getLit e)] }
- | type ';' { return [CmmUninitialised
- (widthInBytes (typeWidth $1))] }
- | 'bits8' '[' ']' STRING ';' { return [mkString $4] }
- | 'bits8' '[' INT ']' ';' { return [CmmUninitialised
- (fromIntegral $3)] }
- | typenot8 '[' INT ']' ';' { return [CmmUninitialised
- (widthInBytes (typeWidth $1) *
- fromIntegral $3)] }
- | 'CLOSURE' '(' NAME lits ')'
- { do { lits <- sequence $4
+static :: { ExtFCode [CmmStatic] }
+ : type expr ';' { do e <- $2;
+ return [CmmStaticLit (getLit e)] }
+ | type ';' { return [CmmUninitialised
+ (widthInBytes (typeWidth $1))] }
+ | 'bits8' '[' ']' STRING ';' { return [mkString $4] }
+ | 'bits8' '[' INT ']' ';' { return [CmmUninitialised
+ (fromIntegral $3)] }
+ | typenot8 '[' INT ']' ';' { return [CmmUninitialised
+ (widthInBytes (typeWidth $1) *
+ fromIntegral $3)] }
+ | 'CLOSURE' '(' NAME lits ')'
+ { do { lits <- sequence $4
; dflags <- getDynFlags
- ; return $ map CmmStaticLit $
+ ; return $ map CmmStaticLit $
mkStaticClosure dflags (mkForeignLabel $3 Nothing ForeignLabelInExternalPackage IsData)
-- mkForeignLabel because these are only used
-- for CHARLIKE and INTLIKE closures in the RTS.
dontCareCCS (map getLit lits) [] [] [] } }
- -- arrays of closures required for the CHARLIKE & INTLIKE arrays
+ -- arrays of closures required for the CHARLIKE & INTLIKE arrays
-lits :: { [ExtFCode CmmExpr] }
- : {- empty -} { [] }
- | ',' expr lits { $2 : $3 }
+lits :: { [ExtFCode CmmExpr] }
+ : {- empty -} { [] }
+ | ',' expr lits { $2 : $3 }
cmmproc :: { ExtCode }
-- TODO: add real SRT/info tables to parsed Cmm
: info maybe_formals_without_hints '{' body '}'
{ do ((entry_ret_label, info, live, formals), stmts) <-
- getCgStmtsEC' $ loopDecls $ do {
- (entry_ret_label, info, live) <- $1;
- formals <- sequence $2;
+ getCgStmtsEC' $ loopDecls $ do {
+ (entry_ret_label, info, live) <- $1;
+ formals <- sequence $2;
$4;
return (entry_ret_label, info, live, formals) }
- blks <- code (cgStmtsToBlocks stmts)
+ blks <- code (cgStmtsToBlocks stmts)
code (emitInfoTableAndCode entry_ret_label info formals blks) }
- | info maybe_formals_without_hints ';'
- { do (entry_ret_label, info, live) <- $1;
- formals <- sequence $2;
+ | info maybe_formals_without_hints ';'
+ { do (entry_ret_label, info, live) <- $1;
+ formals <- sequence $2;
code (emitInfoTableAndCode entry_ret_label info formals []) }
| NAME maybe_formals_without_hints '{' body '}'
- {% withThisPackage $ \pkg ->
- do newFunctionName $1 pkg
+ {% withThisPackage $ \pkg ->
+ do newFunctionName $1 pkg
(formals, stmts) <-
- getCgStmtsEC' $ loopDecls $ do {
- formals <- sequence $2;
+ getCgStmtsEC' $ loopDecls $ do {
+ formals <- sequence $2;
$4;
return formals }
- blks <- code (cgStmtsToBlocks stmts)
+ blks <- code (cgStmtsToBlocks stmts)
code (emitProc Nothing (mkCmmCodeLabel pkg $1) formals blks) }
-info :: { ExtFCode (CLabel, CmmInfoTable, [Maybe LocalReg]) }
- : 'INFO_TABLE' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ')'
- -- ptrs, nptrs, closure type, description, type
- {% withThisPackage $ \pkg ->
+info :: { ExtFCode (CLabel, CmmInfoTable, [Maybe LocalReg]) }
+ : 'INFO_TABLE' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ')'
+ -- ptrs, nptrs, closure type, description, type
+ {% withThisPackage $ \pkg ->
do dflags <- getDynFlags
let prof = profilingInfo dflags $11 $13
rep = mkRTSRep (fromIntegral $9) $
@@ -269,14 +270,14 @@ info :: { ExtFCode (CLabel, CmmInfoTable, [Maybe LocalReg]) }
-- not really Thunk, but that makes the info table
-- we want.
return (mkCmmEntryLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
-
- | 'INFO_TABLE_FUN' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ',' INT ')'
- -- ptrs, nptrs, closure type, description, type, fun type
- {% withThisPackage $ \pkg ->
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
+
+ | 'INFO_TABLE_FUN' '(' NAME ',' INT ',' INT ',' INT ',' STRING ',' STRING ',' INT ')'
+ -- ptrs, nptrs, closure type, description, type, fun type
+ {% withThisPackage $ \pkg ->
do dflags <- getDynFlags
let prof = profilingInfo dflags $11 $13
ty = Fun 0 (ArgSpec (fromIntegral $15))
@@ -285,340 +286,340 @@ info :: { ExtFCode (CLabel, CmmInfoTable, [Maybe LocalReg]) }
mkHeapRep dflags False (fromIntegral $5)
(fromIntegral $7) ty
return (mkCmmEntryLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
- -- we leave most of the fields zero here. This is only used
- -- to generate the BCO info table in the RTS at the moment.
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
+ -- we leave most of the fields zero here. This is only used
+ -- to generate the BCO info table in the RTS at the moment.
| 'INFO_TABLE_CONSTR' '(' NAME ',' INT ',' INT ',' INT ',' INT ',' STRING ',' STRING ')'
- -- ptrs, nptrs, tag, closure type, description, type
- {% withThisPackage $ \pkg ->
+ -- ptrs, nptrs, tag, closure type, description, type
+ {% withThisPackage $ \pkg ->
do dflags <- getDynFlags
let prof = profilingInfo dflags $13 $15
ty = Constr (fromIntegral $9) -- Tag
- (stringToWord8s $13)
+ (stringToWord8s $13)
rep = mkRTSRep (fromIntegral $11) $
mkHeapRep dflags False (fromIntegral $5)
(fromIntegral $7) ty
return (mkCmmEntryLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
-
- -- If profiling is on, this string gets duplicated,
- -- but that's the way the old code did it we can fix it some other time.
-
- | 'INFO_TABLE_SELECTOR' '(' NAME ',' INT ',' INT ',' STRING ',' STRING ')'
- -- selector, closure type, description, type
- {% withThisPackage $ \pkg ->
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
+
+ -- If profiling is on, this string gets duplicated,
+ -- but that's the way the old code did it we can fix it some other time.
+
+ | 'INFO_TABLE_SELECTOR' '(' NAME ',' INT ',' INT ',' STRING ',' STRING ')'
+ -- selector, closure type, description, type
+ {% withThisPackage $ \pkg ->
do dflags <- getDynFlags
let prof = profilingInfo dflags $9 $11
ty = ThunkSelector (fromIntegral $5)
rep = mkRTSRep (fromIntegral $7) $
mkHeapRep dflags False 0 0 ty
return (mkCmmEntryLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
-
- | 'INFO_TABLE_RET' '(' NAME ',' INT ')'
- -- closure type (no live regs)
- {% withThisPackage $ \pkg ->
- do let prof = NoProfilingInfo
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
+
+ | 'INFO_TABLE_RET' '(' NAME ',' INT ')'
+ -- closure type (no live regs)
+ {% withThisPackage $ \pkg ->
+ do let prof = NoProfilingInfo
rep = mkRTSRep (fromIntegral $5) $ mkStackRep []
return (mkCmmRetLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
-
- | 'INFO_TABLE_RET' '(' NAME ',' INT ',' formals_without_hints0 ')'
- -- closure type, live regs
- {% withThisPackage $ \pkg ->
- do live <- sequence (map (liftM Just) $7)
- let prof = NoProfilingInfo
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
+
+ | 'INFO_TABLE_RET' '(' NAME ',' INT ',' formals_without_hints0 ')'
+ -- closure type, live regs
+ {% withThisPackage $ \pkg ->
+ do live <- sequence (map (liftM Just) $7)
+ let prof = NoProfilingInfo
bitmap = mkLiveness live
rep = mkRTSRep (fromIntegral $5) $ mkStackRep bitmap
return (mkCmmRetLabel pkg $3,
- CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
- , cit_rep = rep
- , cit_prof = prof, cit_srt = NoC_SRT },
- []) }
+ CmmInfoTable { cit_lbl = mkCmmInfoLabel pkg $3
+ , cit_rep = rep
+ , cit_prof = prof, cit_srt = NoC_SRT },
+ []) }
-body :: { ExtCode }
- : {- empty -} { return () }
- | decl body { do $1; $2 }
- | stmt body { do $1; $2 }
+body :: { ExtCode }
+ : {- empty -} { return () }
+ | decl body { do $1; $2 }
+ | stmt body { do $1; $2 }
-decl :: { ExtCode }
- : type names ';' { mapM_ (newLocal $1) $2 }
- | 'import' importNames ';' { mapM_ newImport $2 }
- | 'export' names ';' { return () } -- ignore exports
+decl :: { ExtCode }
+ : type names ';' { mapM_ (newLocal $1) $2 }
+ | 'import' importNames ';' { mapM_ newImport $2 }
+ | 'export' names ';' { return () } -- ignore exports
-- an imported function name, with optional packageId
-importNames
- :: { [(FastString, CLabel)] }
- : importName { [$1] }
- | importName ',' importNames { $1 : $3 }
-
+importNames
+ :: { [(FastString, CLabel)] }
+ : importName { [$1] }
+ | importName ',' importNames { $1 : $3 }
+
importName
- :: { (FastString, CLabel) }
-
- -- A label imported without an explicit packageId.
- -- These are taken to come frome some foreign, unnamed package.
- : NAME
- { ($1, mkForeignLabel $1 Nothing ForeignLabelInExternalPackage IsFunction) }
-
- -- A label imported with an explicit packageId.
- | STRING NAME
- { ($2, mkCmmCodeLabel (fsToPackageId (mkFastString $1)) $2) }
-
-
-names :: { [FastString] }
- : NAME { [$1] }
- | NAME ',' names { $1 : $3 }
-
-stmt :: { ExtCode }
- : ';' { nopEC }
-
- | NAME ':'
- { do l <- newLabel $1; code (labelC l) }
-
- | lreg '=' expr ';'
- { do reg <- $1; e <- $3; stmtEC (CmmAssign reg e) }
- | type '[' expr ']' '=' expr ';'
- { doStore $1 $3 $6 }
-
- -- Gah! We really want to say "maybe_results" but that causes
- -- a shift/reduce conflict with assignment. We either
- -- we expand out the no-result and single result cases or
- -- we tweak the syntax to avoid the conflict. The later
- -- option is taken here because the other way would require
- -- multiple levels of expanding and get unwieldy.
- | maybe_results 'foreign' STRING expr '(' cmm_hint_exprs0 ')' safety vols opt_never_returns ';'
- {% foreignCall $3 $1 $4 $6 $9 $8 $10 }
- | maybe_results 'prim' '%' NAME '(' cmm_hint_exprs0 ')' safety vols ';'
- {% primCall $1 $4 $6 $9 $8 }
- -- stmt-level macros, stealing syntax from ordinary C-- function calls.
- -- Perhaps we ought to use the %%-form?
- | NAME '(' exprs0 ')' ';'
- {% stmtMacro $1 $3 }
- | 'switch' maybe_range expr '{' arms default '}'
- { do as <- sequence $5; doSwitch $2 $3 as $6 }
- | 'goto' NAME ';'
- { do l <- lookupLabel $2; stmtEC (CmmBranch l) }
- | 'jump' expr vols ';'
- { do e <- $2; stmtEC (CmmJump e $3) }
+ :: { (FastString, CLabel) }
+
+ -- A label imported without an explicit packageId.
+ -- These are taken to come frome some foreign, unnamed package.
+ : NAME
+ { ($1, mkForeignLabel $1 Nothing ForeignLabelInExternalPackage IsFunction) }
+
+ -- A label imported with an explicit packageId.
+ | STRING NAME
+ { ($2, mkCmmCodeLabel (fsToPackageId (mkFastString $1)) $2) }
+
+
+names :: { [FastString] }
+ : NAME { [$1] }
+ | NAME ',' names { $1 : $3 }
+
+stmt :: { ExtCode }
+ : ';' { nopEC }
+
+ | NAME ':'
+ { do l <- newLabel $1; code (labelC l) }
+
+ | lreg '=' expr ';'
+ { do reg <- $1; e <- $3; stmtEC (CmmAssign reg e) }
+ | type '[' expr ']' '=' expr ';'
+ { doStore $1 $3 $6 }
+
+ -- Gah! We really want to say "maybe_results" but that causes
+ -- a shift/reduce conflict with assignment. We either
+ -- we expand out the no-result and single result cases or
+ -- we tweak the syntax to avoid the conflict. The later
+ -- option is taken here because the other way would require
+ -- multiple levels of expanding and get unwieldy.
+ | maybe_results 'foreign' STRING expr '(' cmm_hint_exprs0 ')' safety vols opt_never_returns ';'
+ {% foreignCall $3 $1 $4 $6 $9 $8 $10 }
+ | maybe_results 'prim' '%' NAME '(' cmm_hint_exprs0 ')' safety vols ';'
+ {% primCall $1 $4 $6 $9 $8 }
+ -- stmt-level macros, stealing syntax from ordinary C-- function calls.
+ -- Perhaps we ought to use the %%-form?
+ | NAME '(' exprs0 ')' ';'
+ {% stmtMacro $1 $3 }
+ | 'switch' maybe_range expr '{' arms default '}'
+ { do as <- sequence $5; doSwitch $2 $3 as $6 }
+ | 'goto' NAME ';'
+ { do l <- lookupLabel $2; stmtEC (CmmBranch l) }
+ | 'jump' expr vols ';'
+ { do e <- $2; stmtEC (CmmJump e $3) }
| 'return' ';'
- { stmtEC CmmReturn }
- | 'if' bool_expr 'goto' NAME
- { do l <- lookupLabel $4; cmmRawIf $2 l }
- | 'if' bool_expr '{' body '}' else
- { cmmIfThenElse $2 $4 $6 }
+ { stmtEC CmmReturn }
+ | 'if' bool_expr 'goto' NAME
+ { do l <- lookupLabel $4; cmmRawIf $2 l }
+ | 'if' bool_expr '{' body '}' else
+ { cmmIfThenElse $2 $4 $6 }
opt_never_returns :: { CmmReturnInfo }
: { CmmMayReturn }
| 'never' 'returns' { CmmNeverReturns }
bool_expr :: { ExtFCode BoolExpr }
- : bool_op { $1 }
- | expr { do e <- $1; return (BoolTest e) }
+ : bool_op { $1 }
+ | expr { do e <- $1; return (BoolTest e) }
bool_op :: { ExtFCode BoolExpr }
- : bool_expr '&&' bool_expr { do e1 <- $1; e2 <- $3;
- return (BoolAnd e1 e2) }
- | bool_expr '||' bool_expr { do e1 <- $1; e2 <- $3;
- return (BoolOr e1 e2) }
- | '!' bool_expr { do e <- $2; return (BoolNot e) }
- | '(' bool_op ')' { $2 }
+ : bool_expr '&&' bool_expr { do e1 <- $1; e2 <- $3;
+ return (BoolAnd e1 e2) }
+ | bool_expr '||' bool_expr { do e1 <- $1; e2 <- $3;
+ return (BoolOr e1 e2) }
+ | '!' bool_expr { do e <- $2; return (BoolNot e) }
+ | '(' bool_op ')' { $2 }
-- This is not C-- syntax. What to do?
safety :: { CmmSafety }
- : {- empty -} { CmmUnsafe } -- Default may change soon
- | STRING {% parseSafety $1 }
+ : {- empty -} { CmmUnsafe } -- Default may change soon
+ | STRING {% parseSafety $1 }
-- This is not C-- syntax. What to do?
-vols :: { Maybe [GlobalReg] }
- : {- empty -} { Nothing }
- | '[' ']' { Just [] }
- | '[' globals ']' { Just $2 }
+vols :: { Maybe [GlobalReg] }
+ : {- empty -} { Nothing }
+ | '[' ']' { Just [] }
+ | '[' globals ']' { Just $2 }
globals :: { [GlobalReg] }
- : GLOBALREG { [$1] }
- | GLOBALREG ',' globals { $1 : $3 }
+ : GLOBALREG { [$1] }
+ | GLOBALREG ',' globals { $1 : $3 }
maybe_range :: { Maybe (Int,Int) }
- : '[' INT '..' INT ']' { Just (fromIntegral $2, fromIntegral $4) }
- | {- empty -} { Nothing }
+ : '[' INT '..' INT ']' { Just (fromIntegral $2, fromIntegral $4) }
+ | {- empty -} { Nothing }
-arms :: { [ExtFCode ([Int],Either BlockId ExtCode)] }
- : {- empty -} { [] }
- | arm arms { $1 : $2 }
+arms :: { [ExtFCode ([Int],Either BlockId ExtCode)] }
+ : {- empty -} { [] }
+ | arm arms { $1 : $2 }
-arm :: { ExtFCode ([Int],Either BlockId ExtCode) }
- : 'case' ints ':' arm_body { do b <- $4; return ($2, b) }
+arm :: { ExtFCode ([Int],Either BlockId ExtCode) }
+ : 'case' ints ':' arm_body { do b <- $4; return ($2, b) }
arm_body :: { ExtFCode (Either BlockId ExtCode) }
- : '{' body '}' { return (Right $2) }
- | 'goto' NAME ';' { do l <- lookupLabel $2; return (Left l) }
+ : '{' body '}' { return (Right $2) }
+ | 'goto' NAME ';' { do l <- lookupLabel $2; return (Left l) }
-ints :: { [Int] }
- : INT { [ fromIntegral $1 ] }
- | INT ',' ints { fromIntegral $1 : $3 }
+ints :: { [Int] }
+ : INT { [ fromIntegral $1 ] }
+ | INT ',' ints { fromIntegral $1 : $3 }
default :: { Maybe ExtCode }
- : 'default' ':' '{' body '}' { Just $4 }
- -- taking a few liberties with the C-- syntax here; C-- doesn't have
- -- 'default' branches
- | {- empty -} { Nothing }
+ : 'default' ':' '{' body '}' { Just $4 }
+ -- taking a few liberties with the C-- syntax here; C-- doesn't have
+ -- 'default' branches
+ | {- empty -} { Nothing }
-- Note: OldCmm doesn't support a first class 'else' statement, though
-- CmmNode does.
-else :: { ExtCode }
- : {- empty -} { nopEC }
- | 'else' '{' body '}' { $3 }
+else :: { ExtCode }
+ : {- empty -} { nopEC }
+ | 'else' '{' body '}' { $3 }
-- we have to write this out longhand so that Happy's precedence rules
-- can kick in.
-expr :: { ExtFCode CmmExpr }
- : expr '/' expr { mkMachOp MO_U_Quot [$1,$3] }
- | expr '*' expr { mkMachOp MO_Mul [$1,$3] }
- | expr '%' expr { mkMachOp MO_U_Rem [$1,$3] }
- | expr '-' expr { mkMachOp MO_Sub [$1,$3] }
- | expr '+' expr { mkMachOp MO_Add [$1,$3] }
- | expr '>>' expr { mkMachOp MO_U_Shr [$1,$3] }
- | expr '<<' expr { mkMachOp MO_Shl [$1,$3] }
- | expr '&' expr { mkMachOp MO_And [$1,$3] }
- | expr '^' expr { mkMachOp MO_Xor [$1,$3] }
- | expr '|' expr { mkMachOp MO_Or [$1,$3] }
- | expr '>=' expr { mkMachOp MO_U_Ge [$1,$3] }
- | expr '>' expr { mkMachOp MO_U_Gt [$1,$3] }
- | expr '<=' expr { mkMachOp MO_U_Le [$1,$3] }
- | expr '<' expr { mkMachOp MO_U_Lt [$1,$3] }
- | expr '!=' expr { mkMachOp MO_Ne [$1,$3] }
- | expr '==' expr { mkMachOp MO_Eq [$1,$3] }
- | '~' expr { mkMachOp MO_Not [$2] }
- | '-' expr { mkMachOp MO_S_Neg [$2] }
- | expr0 '`' NAME '`' expr0 {% do { mo <- nameToMachOp $3 ;
- return (mkMachOp mo [$1,$5]) } }
- | expr0 { $1 }
-
-expr0 :: { ExtFCode CmmExpr }
- : INT maybe_ty { return (CmmLit (CmmInt $1 (typeWidth $2))) }
- | FLOAT maybe_ty { return (CmmLit (CmmFloat $1 (typeWidth $2))) }
- | STRING { do s <- code (newStringCLit $1);
- return (CmmLit s) }
- | reg { $1 }
- | type '[' expr ']' { do e <- $3; return (CmmLoad e $1) }
- | '%' NAME '(' exprs0 ')' {% exprOp $2 $4 }
- | '(' expr ')' { $2 }
+expr :: { ExtFCode CmmExpr }
+ : expr '/' expr { mkMachOp MO_U_Quot [$1,$3] }
+ | expr '*' expr { mkMachOp MO_Mul [$1,$3] }
+ | expr '%' expr { mkMachOp MO_U_Rem [$1,$3] }
+ | expr '-' expr { mkMachOp MO_Sub [$1,$3] }
+ | expr '+' expr { mkMachOp MO_Add [$1,$3] }
+ | expr '>>' expr { mkMachOp MO_U_Shr [$1,$3] }
+ | expr '<<' expr { mkMachOp MO_Shl [$1,$3] }
+ | expr '&' expr { mkMachOp MO_And [$1,$3] }
+ | expr '^' expr { mkMachOp MO_Xor [$1,$3] }
+ | expr '|' expr { mkMachOp MO_Or [$1,$3] }
+ | expr '>=' expr { mkMachOp MO_U_Ge [$1,$3] }
+ | expr '>' expr { mkMachOp MO_U_Gt [$1,$3] }
+ | expr '<=' expr { mkMachOp MO_U_Le [$1,$3] }
+ | expr '<' expr { mkMachOp MO_U_Lt [$1,$3] }
+ | expr '!=' expr { mkMachOp MO_Ne [$1,$3] }
+ | expr '==' expr { mkMachOp MO_Eq [$1,$3] }
+ | '~' expr { mkMachOp MO_Not [$2] }
+ | '-' expr { mkMachOp MO_S_Neg [$2] }
+ | expr0 '`' NAME '`' expr0 {% do { mo <- nameToMachOp $3 ;
+ return (mkMachOp mo [$1,$5]) } }
+ | expr0 { $1 }
+
+expr0 :: { ExtFCode CmmExpr }
+ : INT maybe_ty { return (CmmLit (CmmInt $1 (typeWidth $2))) }
+ | FLOAT maybe_ty { return (CmmLit (CmmFloat $1 (typeWidth $2))) }
+ | STRING { do s <- code (newStringCLit $1);
+ return (CmmLit s) }
+ | reg { $1 }
+ | type '[' expr ']' { do e <- $3; return (CmmLoad e $1) }
+ | '%' NAME '(' exprs0 ')' {% exprOp $2 $4 }
+ | '(' expr ')' { $2 }
-- leaving out the type of a literal gives you the native word size in C--
maybe_ty :: { CmmType }
- : {- empty -} { bWord }
- | '::' type { $2 }
+ : {- empty -} { bWord }
+ | '::' type { $2 }
maybe_actuals :: { [ExtFCode HintedCmmActual] }
- : {- empty -} { [] }
- | '(' cmm_hint_exprs0 ')' { $2 }
+ : {- empty -} { [] }
+ | '(' cmm_hint_exprs0 ')' { $2 }
cmm_hint_exprs0 :: { [ExtFCode HintedCmmActual] }
- : {- empty -} { [] }
- | cmm_hint_exprs { $1 }
+ : {- empty -} { [] }
+ | cmm_hint_exprs { $1 }
cmm_hint_exprs :: { [ExtFCode HintedCmmActual] }
- : cmm_hint_expr { [$1] }
- | cmm_hint_expr ',' cmm_hint_exprs { $1 : $3 }
+ : cmm_hint_expr { [$1] }
+ | cmm_hint_expr ',' cmm_hint_exprs { $1 : $3 }
cmm_hint_expr :: { ExtFCode HintedCmmActual }
- : expr { do e <- $1; return (CmmHinted e (inferCmmHint e)) }
- | expr STRING {% do h <- parseCmmHint $2;
- return $ do
- e <- $1; return (CmmHinted e h) }
+ : expr { do e <- $1; return (CmmHinted e (inferCmmHint e)) }
+ | expr STRING {% do h <- parseCmmHint $2;
+ return $ do
+ e <- $1; return (CmmHinted e h) }
exprs0 :: { [ExtFCode CmmExpr] }
- : {- empty -} { [] }
- | exprs { $1 }
+ : {- empty -} { [] }
+ | exprs { $1 }
-exprs :: { [ExtFCode CmmExpr] }
- : expr { [ $1 ] }
- | expr ',' exprs { $1 : $3 }
+exprs :: { [ExtFCode CmmExpr] }
+ : expr { [ $1 ] }
+ | expr ',' exprs { $1 : $3 }
-reg :: { ExtFCode CmmExpr }
- : NAME { lookupName $1 }
- | GLOBALREG { return (CmmReg (CmmGlobal $1)) }
+reg :: { ExtFCode CmmExpr }
+ : NAME { lookupName $1 }
+ | GLOBALREG { return (CmmReg (CmmGlobal $1)) }
maybe_results :: { [ExtFCode HintedCmmFormal] }
- : {- empty -} { [] }
- | '(' cmm_formals ')' '=' { $2 }
+ : {- empty -} { [] }
+ | '(' cmm_formals ')' '=' { $2 }
cmm_formals :: { [ExtFCode HintedCmmFormal] }
- : cmm_formal { [$1] }
- | cmm_formal ',' { [$1] }
- | cmm_formal ',' cmm_formals { $1 : $3 }
+ : cmm_formal { [$1] }
+ | cmm_formal ',' { [$1] }
+ | cmm_formal ',' cmm_formals { $1 : $3 }
cmm_formal :: { ExtFCode HintedCmmFormal }
- : local_lreg { do e <- $1; return (CmmHinted e (inferCmmHint (CmmReg (CmmLocal e)))) }
- | STRING local_lreg {% do h <- parseCmmHint $1;
- return $ do
- e <- $2; return (CmmHinted e h) }
+ : local_lreg { do e <- $1; return (CmmHinted e (inferCmmHint (CmmReg (CmmLocal e)))) }
+ | STRING local_lreg {% do h <- parseCmmHint $1;
+ return $ do
+ e <- $2; return (CmmHinted e h) }
local_lreg :: { ExtFCode LocalReg }
- : NAME { do e <- lookupName $1;
- return $
- case e of
- CmmReg (CmmLocal r) -> r
- other -> pprPanic "CmmParse:" (ftext $1 <> text " not a local register") }
-
-lreg :: { ExtFCode CmmReg }
- : NAME { do e <- lookupName $1;
- return $
- case e of
- CmmReg r -> r
- other -> pprPanic "CmmParse:" (ftext $1 <> text " not a register") }
- | GLOBALREG { return (CmmGlobal $1) }
+ : NAME { do e <- lookupName $1;
+ return $
+ case e of
+ CmmReg (CmmLocal r) -> r
+ other -> pprPanic "CmmParse:" (ftext $1 <> text " not a local register") }
+
+lreg :: { ExtFCode CmmReg }
+ : NAME { do e <- lookupName $1;
+ return $
+ case e of
+ CmmReg r -> r
+ other -> pprPanic "CmmParse:" (ftext $1 <> text " not a register") }
+ | GLOBALREG { return (CmmGlobal $1) }
maybe_formals_without_hints :: { [ExtFCode LocalReg] }
- : {- empty -} { [] }
- | '(' formals_without_hints0 ')' { $2 }
+ : {- empty -} { [] }
+ | '(' formals_without_hints0 ')' { $2 }
formals_without_hints0 :: { [ExtFCode LocalReg] }
- : {- empty -} { [] }
- | formals_without_hints { $1 }
+ : {- empty -} { [] }
+ | formals_without_hints { $1 }
formals_without_hints :: { [ExtFCode LocalReg] }
- : formal_without_hint ',' { [$1] }
- | formal_without_hint { [$1] }
- | formal_without_hint ',' formals_without_hints { $1 : $3 }
+ : formal_without_hint ',' { [$1] }
+ | formal_without_hint { [$1] }
+ | formal_without_hint ',' formals_without_hints { $1 : $3 }
formal_without_hint :: { ExtFCode LocalReg }
- : type NAME { newLocal $1 $2 }
+ : type NAME { newLocal $1 $2 }
type :: { CmmType }
- : 'bits8' { b8 }
- | typenot8 { $1 }
+ : 'bits8' { b8 }
+ | typenot8 { $1 }
typenot8 :: { CmmType }
- : 'bits16' { b16 }
- | 'bits32' { b32 }
- | 'bits64' { b64 }
- | 'float32' { f32 }
- | 'float64' { f64 }
- | 'gcptr' { gcWord }
+ : 'bits16' { b16 }
+ | 'bits32' { b32 }
+ | 'bits64' { b64 }
+ | 'float32' { f32 }
+ | 'float64' { f64 }
+ | 'gcptr' { gcWord }
{
section :: String -> Section
-section "text" = Text
-section "data" = Data
-section "rodata" = ReadOnlyData
+section "text" = Text
+section "data" = Data
+section "rodata" = ReadOnlyData
section "relrodata" = RelocatableReadOnlyData
-section "bss" = UninitialisedData
-section s = OtherSection s
+section "bss" = UninitialisedData
+section s = OtherSection s
mkString :: String -> CmmStatic
mkString s = CmmString (map (fromIntegral.ord) s)
@@ -638,10 +639,10 @@ getLit (CmmMachOp (MO_S_Neg _) [CmmLit (CmmInt i r)]) = CmmInt (negate i) r
getLit _ = panic "invalid literal" -- TODO messy failure
nameToMachOp :: FastString -> P (Width -> MachOp)
-nameToMachOp name =
+nameToMachOp name =
case lookupUFM machOps name of
- Nothing -> fail ("unknown primitive " ++ unpackFS name)
- Just m -> return m
+ Nothing -> fail ("unknown primitive " ++ unpackFS name)
+ Just m -> return m
exprOp :: FastString -> [ExtFCode CmmExpr] -> P (ExtFCode CmmExpr)
exprOp name args_code = do
@@ -649,10 +650,10 @@ exprOp name args_code = do
case lookupUFM (exprMacros dflags) name of
Just f -> return $ do
args <- sequence args_code
- return (f args)
+ return (f args)
Nothing -> do
- mo <- nameToMachOp name
- return $ mkMachOp mo args_code
+ mo <- nameToMachOp name
+ return $ mkMachOp mo args_code
exprMacros :: DynFlags -> UniqFM ([CmmExpr] -> CmmExpr)
exprMacros dflags = listToUFM [
@@ -670,35 +671,35 @@ exprMacros dflags = listToUFM [
-- we understand a subset of C-- primitives:
machOps = listToUFM $
- map (\(x, y) -> (mkFastString x, y)) [
- ( "add", MO_Add ),
- ( "sub", MO_Sub ),
- ( "eq", MO_Eq ),
- ( "ne", MO_Ne ),
- ( "mul", MO_Mul ),
- ( "neg", MO_S_Neg ),
- ( "quot", MO_S_Quot ),
- ( "rem", MO_S_Rem ),
- ( "divu", MO_U_Quot ),
- ( "modu", MO_U_Rem ),
-
- ( "ge", MO_S_Ge ),
- ( "le", MO_S_Le ),
- ( "gt", MO_S_Gt ),
- ( "lt", MO_S_Lt ),
-
- ( "geu", MO_U_Ge ),
- ( "leu", MO_U_Le ),
- ( "gtu", MO_U_Gt ),
- ( "ltu", MO_U_Lt ),
+ map (\(x, y) -> (mkFastString x, y)) [
+ ( "add", MO_Add ),
+ ( "sub", MO_Sub ),
+ ( "eq", MO_Eq ),
+ ( "ne", MO_Ne ),
+ ( "mul", MO_Mul ),
+ ( "neg", MO_S_Neg ),
+ ( "quot", MO_S_Quot ),
+ ( "rem", MO_S_Rem ),
+ ( "divu", MO_U_Quot ),
+ ( "modu", MO_U_Rem ),
+
+ ( "ge", MO_S_Ge ),
+ ( "le", MO_S_Le ),
+ ( "gt", MO_S_Gt ),
+ ( "lt", MO_S_Lt ),
+
+ ( "geu", MO_U_Ge ),
+ ( "leu", MO_U_Le ),
+ ( "gtu", MO_U_Gt ),
+ ( "ltu", MO_U_Lt ),
( "and", MO_And ),
- ( "or", MO_Or ),
- ( "xor", MO_Xor ),
- ( "com", MO_Not ),
- ( "shl", MO_Shl ),
- ( "shrl", MO_U_Shr ),
- ( "shra", MO_S_Shr ),
+ ( "or", MO_Or ),
+ ( "xor", MO_Xor ),
+ ( "com", MO_Not ),
+ ( "shl", MO_Shl ),
+ ( "shrl", MO_U_Shr ),
+ ( "shra", MO_S_Shr ),
( "fadd", MO_F_Add ),
( "fsub", MO_F_Sub ),
@@ -714,30 +715,30 @@ machOps = listToUFM $
( "flt", MO_F_Lt ),
( "lobits8", flip MO_UU_Conv W8 ),
- ( "lobits16", flip MO_UU_Conv W16 ),
- ( "lobits32", flip MO_UU_Conv W32 ),
- ( "lobits64", flip MO_UU_Conv W64 ),
-
- ( "zx16", flip MO_UU_Conv W16 ),
- ( "zx32", flip MO_UU_Conv W32 ),
- ( "zx64", flip MO_UU_Conv W64 ),
-
- ( "sx16", flip MO_SS_Conv W16 ),
- ( "sx32", flip MO_SS_Conv W32 ),
- ( "sx64", flip MO_SS_Conv W64 ),
-
- ( "f2f32", flip MO_FF_Conv W32 ), -- TODO; rounding mode
- ( "f2f64", flip MO_FF_Conv W64 ), -- TODO; rounding mode
- ( "f2i8", flip MO_FS_Conv W8 ),
- ( "f2i16", flip MO_FS_Conv W16 ),
- ( "f2i32", flip MO_FS_Conv W32 ),
- ( "f2i64", flip MO_FS_Conv W64 ),
- ( "i2f32", flip MO_SF_Conv W32 ),
- ( "i2f64", flip MO_SF_Conv W64 )
- ]
+ ( "lobits16", flip MO_UU_Conv W16 ),
+ ( "lobits32", flip MO_UU_Conv W32 ),
+ ( "lobits64", flip MO_UU_Conv W64 ),
+
+ ( "zx16", flip MO_UU_Conv W16 ),
+ ( "zx32", flip MO_UU_Conv W32 ),
+ ( "zx64", flip MO_UU_Conv W64 ),
+
+ ( "sx16", flip MO_SS_Conv W16 ),
+ ( "sx32", flip MO_SS_Conv W32 ),
+ ( "sx64", flip MO_SS_Conv W64 ),
+
+ ( "f2f32", flip MO_FF_Conv W32 ), -- TODO; rounding mode
+ ( "f2f64", flip MO_FF_Conv W64 ), -- TODO; rounding mode
+ ( "f2i8", flip MO_FS_Conv W8 ),
+ ( "f2i16", flip MO_FS_Conv W16 ),
+ ( "f2i32", flip MO_FS_Conv W32 ),
+ ( "f2i64", flip MO_FS_Conv W64 ),
+ ( "i2f32", flip MO_SF_Conv W32 ),
+ ( "i2f64", flip MO_SF_Conv W64 )
+ ]
callishMachOps = listToUFM $
- map (\(x, y) -> (mkFastString x, y)) [
+ map (\(x, y) -> (mkFastString x, y)) [
( "write_barrier", MO_WriteBarrier ),
( "memcpy", MO_Memcpy ),
( "memset", MO_Memset ),
@@ -762,15 +763,15 @@ inferCmmHint (CmmLit (CmmLabel _)) = AddrHint
inferCmmHint (CmmReg (CmmGlobal g)) | isPtrGlobalReg g = AddrHint
inferCmmHint _ = NoHint
-isPtrGlobalReg Sp = True
-isPtrGlobalReg SpLim = True
-isPtrGlobalReg Hp = True
-isPtrGlobalReg HpLim = True
+isPtrGlobalReg Sp = True
+isPtrGlobalReg SpLim = True
+isPtrGlobalReg Hp = True
+isPtrGlobalReg HpLim = True
isPtrGlobalReg CCCS = True
isPtrGlobalReg CurrentTSO = True
isPtrGlobalReg CurrentNursery = True
isPtrGlobalReg (VanillaReg _ VGcPtr) = True
-isPtrGlobalReg _ = False
+isPtrGlobalReg _ = False
happyError :: P a
happyError = srcParseFail
@@ -783,54 +784,54 @@ stmtMacro fun args_code = do
case lookupUFM stmtMacros fun of
Nothing -> fail ("unknown macro: " ++ unpackFS fun)
Just fcode -> return $ do
- args <- sequence args_code
- code (fcode args)
+ args <- sequence args_code
+ code (fcode args)
stmtMacros :: UniqFM ([CmmExpr] -> Code)
stmtMacros = listToUFM [
- ( fsLit "CCS_ALLOC", \[words,ccs] -> profAlloc words ccs ),
- ( fsLit "CLOSE_NURSERY", \[] -> emitCloseNursery ),
+ ( fsLit "CCS_ALLOC", \[words,ccs] -> profAlloc words ccs ),
+ ( fsLit "CLOSE_NURSERY", \[] -> emitCloseNursery ),
( fsLit "ENTER_CCS_THUNK", \[e] -> enterCostCentreThunk e ),
- ( fsLit "HP_CHK_GEN", \[words,liveness,reentry] ->
+ ( fsLit "HP_CHK_GEN", \[words,liveness,reentry] ->
hpChkGen words liveness reentry ),
( fsLit "HP_CHK_NP_ASSIGN_SP0", \[e,f] -> hpChkNodePointsAssignSp0 e f ),
( fsLit "LOAD_THREAD_STATE", \[] -> emitLoadThreadState ),
( fsLit "LDV_ENTER", \[e] -> ldvEnter e ),
( fsLit "LDV_RECORD_CREATE", \[e] -> ldvRecordCreate e ),
- ( fsLit "OPEN_NURSERY", \[] -> emitOpenNursery ),
- ( fsLit "PUSH_UPD_FRAME", \[sp,e] -> emitPushUpdateFrame sp e ),
+ ( fsLit "OPEN_NURSERY", \[] -> emitOpenNursery ),
+ ( fsLit "PUSH_UPD_FRAME", \[sp,e] -> emitPushUpdateFrame sp e ),
( fsLit "SAVE_THREAD_STATE", \[] -> emitSaveThreadState ),
- ( fsLit "SET_HDR", \[ptr,info,ccs] ->
- emitSetDynHdr ptr info ccs ),
- ( fsLit "STK_CHK_GEN", \[words,liveness,reentry] ->
+ ( fsLit "SET_HDR", \[ptr,info,ccs] ->
+ emitSetDynHdr ptr info ccs ),
+ ( fsLit "STK_CHK_GEN", \[words,liveness,reentry] ->
stkChkGen words liveness reentry ),
- ( fsLit "STK_CHK_NP", \[e] -> stkChkNodePoints e ),
- ( fsLit "TICK_ALLOC_PRIM", \[hdr,goods,slop] ->
- tickyAllocPrim hdr goods slop ),
- ( fsLit "TICK_ALLOC_PAP", \[goods,slop] ->
- tickyAllocPAP goods slop ),
- ( fsLit "TICK_ALLOC_UP_THK", \[goods,slop] ->
- tickyAllocThunk goods slop ),
+ ( fsLit "STK_CHK_NP", \[e] -> stkChkNodePoints e ),
+ ( fsLit "TICK_ALLOC_PRIM", \[hdr,goods,slop] ->
+ tickyAllocPrim hdr goods slop ),
+ ( fsLit "TICK_ALLOC_PAP", \[goods,slop] ->
+ tickyAllocPAP goods slop ),
+ ( fsLit "TICK_ALLOC_UP_THK", \[goods,slop] ->
+ tickyAllocThunk goods slop ),
( fsLit "UPD_BH_UPDATABLE", \[] -> emitBlackHoleCode False ),
( fsLit "UPD_BH_SINGLE_ENTRY", \[] -> emitBlackHoleCode True ),
- ( fsLit "RET_P", \[a] -> emitRetUT [(PtrArg,a)]),
- ( fsLit "RET_N", \[a] -> emitRetUT [(NonPtrArg,a)]),
- ( fsLit "RET_PP", \[a,b] -> emitRetUT [(PtrArg,a),(PtrArg,b)]),
- ( fsLit "RET_NN", \[a,b] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b)]),
- ( fsLit "RET_NP", \[a,b] -> emitRetUT [(NonPtrArg,a),(PtrArg,b)]),
- ( fsLit "RET_PPP", \[a,b,c] -> emitRetUT [(PtrArg,a),(PtrArg,b),(PtrArg,c)]),
- ( fsLit "RET_NPP", \[a,b,c] -> emitRetUT [(NonPtrArg,a),(PtrArg,b),(PtrArg,c)]),
- ( fsLit "RET_NNP", \[a,b,c] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(PtrArg,c)]),
+ ( fsLit "RET_P", \[a] -> emitRetUT [(PtrArg,a)]),
+ ( fsLit "RET_N", \[a] -> emitRetUT [(NonPtrArg,a)]),
+ ( fsLit "RET_PP", \[a,b] -> emitRetUT [(PtrArg,a),(PtrArg,b)]),
+ ( fsLit "RET_NN", \[a,b] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b)]),
+ ( fsLit "RET_NP", \[a,b] -> emitRetUT [(NonPtrArg,a),(PtrArg,b)]),
+ ( fsLit "RET_PPP", \[a,b,c] -> emitRetUT [(PtrArg,a),(PtrArg,b),(PtrArg,c)]),
+ ( fsLit "RET_NPP", \[a,b,c] -> emitRetUT [(NonPtrArg,a),(PtrArg,b),(PtrArg,c)]),
+ ( fsLit "RET_NNP", \[a,b,c] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(PtrArg,c)]),
( fsLit "RET_NNN", \[a,b,c] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(NonPtrArg,c)]),
( fsLit "RET_NNNN", \[a,b,c,d] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(NonPtrArg,c),(NonPtrArg,d)]),
- ( fsLit "RET_NNNP", \[a,b,c,d] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(NonPtrArg,c),(PtrArg,d)]),
- ( fsLit "RET_NPNP", \[a,b,c,d] -> emitRetUT [(NonPtrArg,a),(PtrArg,b),(NonPtrArg,c),(PtrArg,d)])
+ ( fsLit "RET_NNNP", \[a,b,c,d] -> emitRetUT [(NonPtrArg,a),(NonPtrArg,b),(NonPtrArg,c),(PtrArg,d)]),
+ ( fsLit "RET_NPNP", \[a,b,c,d] -> emitRetUT [(NonPtrArg,a),(PtrArg,b),(NonPtrArg,c),(PtrArg,d)])
]
-profilingInfo dflags desc_str ty_str
+profilingInfo dflags desc_str ty_str
= if not (dopt Opt_SccProfilingOn dflags)
then NoProfilingInfo
else ProfilingInfo (stringToWord8s desc_str)
@@ -843,11 +844,11 @@ staticClosure pkg cl_label info payload
code $ emitDataLits (mkCmmDataLabel pkg cl_label) lits
foreignCall
- :: String
- -> [ExtFCode HintedCmmFormal]
- -> ExtFCode CmmExpr
- -> [ExtFCode HintedCmmActual]
- -> Maybe [GlobalReg]
+ :: String
+ -> [ExtFCode HintedCmmFormal]
+ -> ExtFCode CmmExpr
+ -> [ExtFCode HintedCmmActual]
+ -> Maybe [GlobalReg]
-> CmmSafety
-> CmmReturnInfo
-> P ExtCode
@@ -857,76 +858,77 @@ foreignCall conv_string results_code expr_code args_code vols safety ret
"stdcall" -> return StdCallConv
"C--" -> return CmmCallConv
_ -> fail ("unknown calling convention: " ++ conv_string)
- return $ do
- results <- sequence results_code
- expr <- expr_code
- args <- sequence args_code
+ return $ do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ results <- sequence results_code
+ expr <- expr_code
+ args <- sequence args_code
case convention of
-- Temporary hack so at least some functions are CmmSafe
CmmCallConv -> code (stmtC (CmmCall (CmmCallee expr convention) results args ret))
_ ->
- let expr' = adjCallTarget convention expr args in
+ let expr' = adjCallTarget platform convention expr args in
case safety of
- CmmUnsafe ->
- code (emitForeignCall' PlayRisky results
+ CmmUnsafe ->
+ code (emitForeignCall' PlayRisky results
(CmmCallee expr' convention) args vols NoC_SRT ret)
CmmSafe srt ->
- code (emitForeignCall' PlaySafe results
+ code (emitForeignCall' PlaySafe results
(CmmCallee expr' convention) args vols NoC_SRT ret) where
CmmInterruptible ->
- code (emitForeignCall' PlayInterruptible results
+ code (emitForeignCall' PlayInterruptible results
(CmmCallee expr' convention) args vols NoC_SRT ret)
-adjCallTarget :: CCallConv -> CmmExpr -> [CmmHinted CmmExpr] -> CmmExpr
-#ifdef mingw32_TARGET_OS
+adjCallTarget :: Platform -> CCallConv -> CmmExpr -> [CmmHinted CmmExpr]
+ -> CmmExpr
-- On Windows, we have to add the '@N' suffix to the label when making
-- a call with the stdcall calling convention.
-adjCallTarget StdCallConv (CmmLit (CmmLabel lbl)) args
+adjCallTarget (Platform { platformOS = OSMinGW32 }) StdCallConv (CmmLit (CmmLabel lbl)) args
= CmmLit (CmmLabel (addLabelSize lbl (sum (map size args))))
where size (CmmHinted e _) = max wORD_SIZE (widthInBytes (typeWidth (cmmExprType e)))
-- c.f. CgForeignCall.emitForeignCall
-#endif
-adjCallTarget _ expr _
+adjCallTarget _ _ expr _
= expr
primCall
- :: [ExtFCode HintedCmmFormal]
- -> FastString
- -> [ExtFCode HintedCmmActual]
- -> Maybe [GlobalReg]
+ :: [ExtFCode HintedCmmFormal]
+ -> FastString
+ -> [ExtFCode HintedCmmActual]
+ -> Maybe [GlobalReg]
-> CmmSafety
-> P ExtCode
primCall results_code name args_code vols safety
= case lookupUFM callishMachOps name of
- Nothing -> fail ("unknown primitive " ++ unpackFS name)
- Just p -> return $ do
- results <- sequence results_code
- args <- sequence args_code
- case safety of
- CmmUnsafe ->
- code (emitForeignCall' PlayRisky results
- (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn)
- CmmSafe srt ->
- code (emitForeignCall' PlaySafe results
- (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn) where
- CmmInterruptible ->
- code (emitForeignCall' PlayInterruptible results
- (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn)
+ Nothing -> fail ("unknown primitive " ++ unpackFS name)
+ Just p -> return $ do
+ results <- sequence results_code
+ args <- sequence args_code
+ case safety of
+ CmmUnsafe ->
+ code (emitForeignCall' PlayRisky results
+ (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn)
+ CmmSafe srt ->
+ code (emitForeignCall' PlaySafe results
+ (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn) where
+ CmmInterruptible ->
+ code (emitForeignCall' PlayInterruptible results
+ (CmmPrim p Nothing) args vols NoC_SRT CmmMayReturn)
doStore :: CmmType -> ExtFCode CmmExpr -> ExtFCode CmmExpr -> ExtCode
doStore rep addr_code val_code
= do addr <- addr_code
val <- val_code
- -- if the specified store type does not match the type of the expr
- -- on the rhs, then we insert a coercion that will cause the type
- -- mismatch to be flagged by cmm-lint. If we don't do this, then
- -- the store will happen at the wrong type, and the error will not
- -- be noticed.
+ -- if the specified store type does not match the type of the expr
+ -- on the rhs, then we insert a coercion that will cause the type
+ -- mismatch to be flagged by cmm-lint. If we don't do this, then
+ -- the store will happen at the wrong type, and the error will not
+ -- be noticed.
let val_width = typeWidth (cmmExprType val)
rep_width = typeWidth rep
- let coerce_val
- | val_width /= rep_width = CmmMachOp (MO_UU_Conv val_width rep_width) [val]
- | otherwise = val
+ let coerce_val
+ | val_width /= rep_width = CmmMachOp (MO_UU_Conv val_width rep_width) [val]
+ | otherwise = val
stmtEC (CmmStore addr coerce_val)
-- Return an unboxed tuple.
@@ -984,10 +986,10 @@ emitCond (e1 `BoolOr` e2) then_id = do
emitCond e1 then_id
emitCond e2 then_id
emitCond (e1 `BoolAnd` e2) then_id = do
- -- we'd like to invert one of the conditionals here to avoid an
- -- extra branch instruction, but we can't use maybeInvertComparison
- -- here because we can't look too closely at the expression since
- -- we're in a loop.
+ -- we'd like to invert one of the conditionals here to avoid an
+ -- extra branch instruction, but we can't use maybeInvertComparison
+ -- here because we can't look too closely at the expression since
+ -- we're in a loop.
and_id <- code newLabelC
else_id <- code newLabelC
emitCond e1 and_id
@@ -1010,35 +1012,35 @@ emitCond (e1 `BoolAnd` e2) then_id = do
doSwitch :: Maybe (Int,Int) -> ExtFCode CmmExpr -> [([Int],Either BlockId ExtCode)]
-> Maybe ExtCode -> ExtCode
doSwitch mb_range scrut arms deflt
- = do
- -- Compile code for the default branch
- dflt_entry <-
- case deflt of
- Nothing -> return Nothing
- Just e -> do b <- forkLabelledCodeEC e; return (Just b)
-
- -- Compile each case branch
- table_entries <- mapM emitArm arms
-
- -- Construct the table
- let
- all_entries = concat table_entries
- ixs = map fst all_entries
- (min,max)
- | Just (l,u) <- mb_range = (l,u)
- | otherwise = (minimum ixs, maximum ixs)
-
- entries = elems (accumArray (\_ a -> Just a) dflt_entry (min,max)
- all_entries)
- expr <- scrut
- -- ToDo: check for out of range and jump to default if necessary
+ = do
+ -- Compile code for the default branch
+ dflt_entry <-
+ case deflt of
+ Nothing -> return Nothing
+ Just e -> do b <- forkLabelledCodeEC e; return (Just b)
+
+ -- Compile each case branch
+ table_entries <- mapM emitArm arms
+
+ -- Construct the table
+ let
+ all_entries = concat table_entries
+ ixs = map fst all_entries
+ (min,max)
+ | Just (l,u) <- mb_range = (l,u)
+ | otherwise = (minimum ixs, maximum ixs)
+
+ entries = elems (accumArray (\_ a -> Just a) dflt_entry (min,max)
+ all_entries)
+ expr <- scrut
+ -- ToDo: check for out of range and jump to default if necessary
stmtEC (CmmSwitch expr entries)
where
- emitArm :: ([Int],Either BlockId ExtCode) -> ExtFCode [(Int,BlockId)]
- emitArm (ints,Left blockid) = return [ (i,blockid) | i <- ints ]
- emitArm (ints,Right code) = do
- blockid <- forkLabelledCodeEC code
- return [ (i,blockid) | i <- ints ]
+ emitArm :: ([Int],Either BlockId ExtCode) -> ExtFCode [(Int,BlockId)]
+ emitArm (ints,Left blockid) = return [ (i,blockid) | i <- ints ]
+ emitArm (ints,Right code) = do
+ blockid <- forkLabelledCodeEC code
+ return [ (i,blockid) | i <- ints ]
-- -----------------------------------------------------------------------------
-- Putting it all together
@@ -1047,7 +1049,7 @@ doSwitch mb_range scrut arms deflt
-- knows about here.
initEnv :: DynFlags -> Env
initEnv dflags = listToUFM [
- ( fsLit "SIZEOF_StgHeader",
+ ( fsLit "SIZEOF_StgHeader",
VarN (CmmLit (CmmInt (fromIntegral (fixedHdrSize dflags * wORD_SIZE)) wordWidth) )),
( fsLit "SIZEOF_StgInfoTable",
VarN (CmmLit (CmmInt (fromIntegral (stdInfoTableSizeB dflags)) wordWidth) ))
@@ -1058,10 +1060,10 @@ parseCmmFile dflags filename = do
showPass dflags "ParseCmm"
buf <- hGetStringBuffer filename
let
- init_loc = mkRealSrcLoc (mkFastString filename) 1 1
- init_state = (mkPState dflags buf init_loc) { lex_state = [0] }
- -- reset the lex_state: the Lexer monad leaves some stuff
- -- in there we don't want.
+ init_loc = mkRealSrcLoc (mkFastString filename) 1 1
+ init_state = (mkPState dflags buf init_loc) { lex_state = [0] }
+ -- reset the lex_state: the Lexer monad leaves some stuff
+ -- in there we don't want.
case unP cmmParse init_state of
PFailed span err -> do
let msg = mkPlainErrMsg dflags span err
@@ -1076,5 +1078,5 @@ parseCmmFile dflags filename = do
dumpIfSet_dyn dflags Opt_D_dump_cmm "Cmm" (ppr cmm)
return (ms, Just cmm)
where
- no_module = panic "parseCmmFile: no module"
+ no_module = panic "parseCmmFile: no module"
}
diff --git a/compiler/codeGen/CodeGen/Platform.hs b/compiler/codeGen/CodeGen/Platform.hs
index 78fba978ec..ca3bafb8de 100644
--- a/compiler/codeGen/CodeGen/Platform.hs
+++ b/compiler/codeGen/CodeGen/Platform.hs
@@ -1,8 +1,12 @@
-module CodeGen.Platform (callerSaves, activeStgRegs, haveRegBase) where
+module CodeGen.Platform
+ (callerSaves, activeStgRegs, haveRegBase, globalRegMaybe, freeReg)
+ where
import CmmExpr
+import FastBool
import Platform
+import Reg
import qualified CodeGen.Platform.ARM as ARM
import qualified CodeGen.Platform.PPC as PPC
@@ -71,3 +75,37 @@ haveRegBase platform
| otherwise -> NoRegs.haveRegBase
+globalRegMaybe :: Platform -> GlobalReg -> Maybe RealReg
+globalRegMaybe platform
+ | platformUnregisterised platform = NoRegs.globalRegMaybe
+ | otherwise
+ = case platformArch platform of
+ ArchX86 -> X86.globalRegMaybe
+ ArchX86_64 -> X86_64.globalRegMaybe
+ ArchSPARC -> SPARC.globalRegMaybe
+ ArchARM {} -> ARM.globalRegMaybe
+ arch
+ | arch `elem` [ArchPPC, ArchPPC_64] ->
+ case platformOS platform of
+ OSDarwin -> PPC_Darwin.globalRegMaybe
+ _ -> PPC.globalRegMaybe
+
+ | otherwise -> NoRegs.globalRegMaybe
+
+freeReg :: Platform -> RegNo -> FastBool
+freeReg platform
+ | platformUnregisterised platform = NoRegs.freeReg
+ | otherwise
+ = case platformArch platform of
+ ArchX86 -> X86.freeReg
+ ArchX86_64 -> X86_64.freeReg
+ ArchSPARC -> SPARC.freeReg
+ ArchARM {} -> ARM.freeReg
+ arch
+ | arch `elem` [ArchPPC, ArchPPC_64] ->
+ case platformOS platform of
+ OSDarwin -> PPC_Darwin.freeReg
+ _ -> PPC.freeReg
+
+ | otherwise -> NoRegs.freeReg
+
diff --git a/compiler/codeGen/CodeGen/Platform/ARM.hs b/compiler/codeGen/CodeGen/Platform/ARM.hs
index cad3eb7f50..727a43561f 100644
--- a/compiler/codeGen/CodeGen/Platform/ARM.hs
+++ b/compiler/codeGen/CodeGen/Platform/ARM.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.ARM where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_arm 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/codeGen/CodeGen/Platform/NoRegs.hs b/compiler/codeGen/CodeGen/Platform/NoRegs.hs
index 6d7c3342d0..c4c63b7572 100644
--- a/compiler/codeGen/CodeGen/Platform/NoRegs.hs
+++ b/compiler/codeGen/CodeGen/Platform/NoRegs.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.NoRegs where
-import CmmExpr
-
#define MACHREGS_NO_REGS 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/codeGen/CodeGen/Platform/PPC.hs b/compiler/codeGen/CodeGen/Platform/PPC.hs
index 19d0609ae2..bcbdfe244b 100644
--- a/compiler/codeGen/CodeGen/Platform/PPC.hs
+++ b/compiler/codeGen/CodeGen/Platform/PPC.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.PPC where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_powerpc 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/codeGen/CodeGen/Platform/PPC_Darwin.hs b/compiler/codeGen/CodeGen/Platform/PPC_Darwin.hs
index a53ee06cc2..42bf22f26c 100644
--- a/compiler/codeGen/CodeGen/Platform/PPC_Darwin.hs
+++ b/compiler/codeGen/CodeGen/Platform/PPC_Darwin.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.PPC_Darwin where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_powerpc 1
#define MACHREGS_darwin 1
diff --git a/compiler/codeGen/CodeGen/Platform/SPARC.hs b/compiler/codeGen/CodeGen/Platform/SPARC.hs
index 391d6c8086..b49af14409 100644
--- a/compiler/codeGen/CodeGen/Platform/SPARC.hs
+++ b/compiler/codeGen/CodeGen/Platform/SPARC.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.SPARC where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_sparc 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/codeGen/CodeGen/Platform/X86.hs b/compiler/codeGen/CodeGen/Platform/X86.hs
index c5ea94f68c..6dd74df130 100644
--- a/compiler/codeGen/CodeGen/Platform/X86.hs
+++ b/compiler/codeGen/CodeGen/Platform/X86.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.X86 where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_i386 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/codeGen/CodeGen/Platform/X86_64.hs b/compiler/codeGen/CodeGen/Platform/X86_64.hs
index c5aa0808b6..190d642ea6 100644
--- a/compiler/codeGen/CodeGen/Platform/X86_64.hs
+++ b/compiler/codeGen/CodeGen/Platform/X86_64.hs
@@ -1,8 +1,6 @@
module CodeGen.Platform.X86_64 where
-import CmmExpr
-
#define MACHREGS_NO_REGS 0
#define MACHREGS_x86_64 1
#include "../../../../includes/CodeGen.Platform.hs"
diff --git a/compiler/coreSyn/CorePrep.lhs b/compiler/coreSyn/CorePrep.lhs
index 7680bab292..0bd199ff18 100644
--- a/compiler/coreSyn/CorePrep.lhs
+++ b/compiler/coreSyn/CorePrep.lhs
@@ -46,6 +46,7 @@ import DynFlags
import Util
import Pair
import Outputable
+import Platform
import FastString
import Config
import Data.Bits
@@ -156,7 +157,7 @@ corePrepPgm :: DynFlags -> HscEnv -> CoreProgram -> [TyCon] -> IO CoreProgram
corePrepPgm dflags hsc_env binds data_tycons = do
showPass dflags "CorePrep"
us <- mkSplitUniqSupply 's'
- initialCorePrepEnv <- mkInitialCorePrepEnv hsc_env
+ initialCorePrepEnv <- mkInitialCorePrepEnv dflags hsc_env
let implicit_binds = mkDataConWorkers data_tycons
-- NB: we must feed mkImplicitBinds through corePrep too
@@ -174,7 +175,7 @@ corePrepExpr :: DynFlags -> HscEnv -> CoreExpr -> IO CoreExpr
corePrepExpr dflags hsc_env expr = do
showPass dflags "CorePrep"
us <- mkSplitUniqSupply 's'
- initialCorePrepEnv <- mkInitialCorePrepEnv hsc_env
+ initialCorePrepEnv <- mkInitialCorePrepEnv dflags hsc_env
let new_expr = initUs_ us (cpeBodyNF initialCorePrepEnv expr)
dumpIfSet_dyn dflags Opt_D_dump_prep "CorePrep" (ppr new_expr)
return new_expr
@@ -401,6 +402,8 @@ cpePair top_lvl is_rec is_strict_or_unlifted env bndr rhs
; return (floats3, bndr', rhs') }
where
+ platform = targetPlatform (cpe_dynFlags env)
+
arity = idArity bndr -- We must match this arity
---------------------
@@ -422,7 +425,7 @@ cpePair top_lvl is_rec is_strict_or_unlifted env bndr rhs
= return (floats, rhs)
-- So the top-level binding is marked NoCafRefs
- | Just (floats', rhs') <- canFloatFromNoCaf floats rhs
+ | Just (floats', rhs') <- canFloatFromNoCaf platform floats rhs
= return (floats', rhs')
| otherwise
@@ -1069,9 +1072,9 @@ dropDeadCodeAlts alts = (alts', unionVarSets fvss)
where !(e', fvs) = dropDeadCode e
-------------------------------------------
-canFloatFromNoCaf :: Floats -> CpeRhs -> Maybe (Floats, CpeRhs)
+canFloatFromNoCaf :: Platform -> Floats -> CpeRhs -> Maybe (Floats, CpeRhs)
-- Note [CafInfo and floating]
-canFloatFromNoCaf (Floats ok_to_spec fs) rhs
+canFloatFromNoCaf platform (Floats ok_to_spec fs) rhs
| OkToSpec <- ok_to_spec -- Worth trying
, Just (subst, fs') <- go (emptySubst, nilOL) (fromOL fs)
= Just (Floats OkToSpec fs', subst_expr subst rhs)
@@ -1114,7 +1117,7 @@ canFloatFromNoCaf (Floats ok_to_spec fs) rhs
-- We can only float to top level from a NoCaf thing if
-- the new binding is static. However it can't mention
-- any non-static things or it would *already* be Caffy
- rhs_ok = rhsIsStatic (\_ -> False)
+ rhs_ok = rhsIsStatic platform (\_ -> False)
wantFloatNested :: RecFlag -> Bool -> Floats -> CpeRhs -> Bool
wantFloatNested is_rec strict_or_unlifted floats rhs
@@ -1148,31 +1151,38 @@ allLazyNested is_rec (Floats IfUnboxedOk _) = isNonRec is_rec
-- The environment
-- ---------------------------------------------------------------------------
-data CorePrepEnv = CPE (IdEnv Id) -- Clone local Ids
- Id -- mkIntegerId
+data CorePrepEnv = CPE {
+ cpe_dynFlags :: DynFlags,
+ cpe_env :: (IdEnv Id), -- Clone local Ids
+ cpe_mkIntegerId :: Id
+ }
-mkInitialCorePrepEnv :: HscEnv -> IO CorePrepEnv
-mkInitialCorePrepEnv hsc_env
+mkInitialCorePrepEnv :: DynFlags -> HscEnv -> IO CorePrepEnv
+mkInitialCorePrepEnv dflags hsc_env
= do mkIntegerId <- liftM tyThingId
$ initTcForLookup hsc_env (tcLookupGlobal mkIntegerName)
- return $ CPE emptyVarEnv mkIntegerId
+ return $ CPE {
+ cpe_dynFlags = dflags,
+ cpe_env = emptyVarEnv,
+ cpe_mkIntegerId = mkIntegerId
+ }
extendCorePrepEnv :: CorePrepEnv -> Id -> Id -> CorePrepEnv
-extendCorePrepEnv (CPE env mkIntegerId) id id'
- = CPE (extendVarEnv env id id') mkIntegerId
+extendCorePrepEnv cpe id id'
+ = cpe { cpe_env = extendVarEnv (cpe_env cpe) id id' }
extendCorePrepEnvList :: CorePrepEnv -> [(Id,Id)] -> CorePrepEnv
-extendCorePrepEnvList (CPE env mkIntegerId) prs
- = CPE (extendVarEnvList env prs) mkIntegerId
+extendCorePrepEnvList cpe prs
+ = cpe { cpe_env = extendVarEnvList (cpe_env cpe) prs }
lookupCorePrepEnv :: CorePrepEnv -> Id -> Id
-lookupCorePrepEnv (CPE env _) id
- = case lookupVarEnv env id of
+lookupCorePrepEnv cpe id
+ = case lookupVarEnv (cpe_env cpe) id of
Nothing -> id
Just id' -> id'
getMkIntegerId :: CorePrepEnv -> Id
-getMkIntegerId (CPE _ mkIntegerId) = mkIntegerId
+getMkIntegerId = cpe_mkIntegerId
------------------------------------------------------------------------------
-- Cloning binders
diff --git a/compiler/coreSyn/CoreUtils.lhs b/compiler/coreSyn/CoreUtils.lhs
index 12a3fb3491..f15c648694 100644
--- a/compiler/coreSyn/CoreUtils.lhs
+++ b/compiler/coreSyn/CoreUtils.lhs
@@ -66,6 +66,7 @@ import Outputable
import TysPrim
import FastString
import Maybes
+import Platform
import Util
import Pair
import Data.Word
@@ -1733,7 +1734,7 @@ and 'execute' it rather than allocating it statically.
-- | This function is called only on *top-level* right-hand sides.
-- Returns @True@ if the RHS can be allocated statically in the output,
-- with no thunks involved at all.
-rhsIsStatic :: (Name -> Bool) -> CoreExpr -> Bool
+rhsIsStatic :: Platform -> (Name -> Bool) -> CoreExpr -> Bool
-- It's called (i) in TidyPgm.hasCafRefs to decide if the rhs is, or
-- refers to, CAFs; (ii) in CoreToStg to decide whether to put an
-- update flag on it and (iii) in DsExpr to decide how to expand
@@ -1788,7 +1789,7 @@ rhsIsStatic :: (Name -> Bool) -> CoreExpr -> Bool
--
-- c) don't look through unfolding of f in (f x).
-rhsIsStatic _is_dynamic_name rhs = is_static False rhs
+rhsIsStatic platform is_dynamic_name rhs = is_static False rhs
where
is_static :: Bool -- True <=> in a constructor argument; must be atomic
-> CoreExpr -> Bool
@@ -1813,9 +1814,8 @@ rhsIsStatic _is_dynamic_name rhs = is_static False rhs
is_static in_arg other_expr = go other_expr 0
where
go (Var f) n_val_args
-#if mingw32_TARGET_OS
- | not (_is_dynamic_name (idName f))
-#endif
+ | (platformOS platform /= OSMinGW32) ||
+ not (is_dynamic_name (idName f))
= saturated_data_con f n_val_args
|| (in_arg && n_val_args == 0)
-- A naked un-applied variable is *not* deemed a static RHS
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index 12ed631f0f..e02e9d9869 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -509,7 +509,6 @@ Library
PPC.CodeGen
SPARC.Base
SPARC.Regs
- SPARC.RegPlate
SPARC.Imm
SPARC.AddrMode
SPARC.Cond
diff --git a/compiler/ghci/Linker.lhs b/compiler/ghci/Linker.lhs
index 06096c3579..7a5ca901bc 100644
--- a/compiler/ghci/Linker.lhs
+++ b/compiler/ghci/Linker.lhs
@@ -51,6 +51,7 @@ import qualified Maybes
import UniqSet
import FastString
import Config
+import Platform
import SysTools
import PrelNames
@@ -302,12 +303,13 @@ reallyInitDynLinker dflags =
; classified_ld_inputs <- mapM (classifyLdInput dflags) cmdline_ld_inputs
-- (e) Link any MacOS frameworks
- ; let framework_paths
- | isDarwinTarget = frameworkPaths dflags
- | otherwise = []
- ; let frameworks
- | isDarwinTarget = cmdlineFrameworks dflags
- | otherwise = []
+ ; let platform = targetPlatform dflags
+ ; let framework_paths = case platformOS platform of
+ OSDarwin -> frameworkPaths dflags
+ _ -> []
+ ; let frameworks = case platformOS platform of
+ OSDarwin -> cmdlineFrameworks dflags
+ _ -> []
-- Finally do (c),(d),(e)
; let cmdline_lib_specs = [ l | Just l <- classified_ld_inputs ]
++ libspecs
@@ -353,12 +355,13 @@ users?
classifyLdInput :: DynFlags -> FilePath -> IO (Maybe LibrarySpec)
classifyLdInput dflags f
- | isObjectFilename f = return (Just (Object f))
- | isDynLibFilename f = return (Just (DLLPath f))
+ | isObjectFilename platform f = return (Just (Object f))
+ | isDynLibFilename platform f = return (Just (DLLPath f))
| otherwise = do
log_action dflags dflags SevInfo noSrcSpan defaultUserStyle
(text ("Warning: ignoring unrecognised input `" ++ f ++ "'"))
return Nothing
+ where platform = targetPlatform dflags
preloadLib :: DynFlags -> [String] -> [String] -> LibrarySpec -> IO ()
preloadLib dflags lib_paths framework_paths lib_spec
@@ -375,7 +378,7 @@ preloadLib dflags lib_paths framework_paths lib_spec
else "not found")
DLL dll_unadorned
- -> do maybe_errstr <- loadDLL (mkSOName dll_unadorned)
+ -> do maybe_errstr <- loadDLL (mkSOName platform dll_unadorned)
case maybe_errstr of
Nothing -> maybePutStrLn dflags "done"
Just mm -> preloadFailed mm lib_paths lib_spec
@@ -386,15 +389,18 @@ preloadLib dflags lib_paths framework_paths lib_spec
Nothing -> maybePutStrLn dflags "done"
Just mm -> preloadFailed mm lib_paths lib_spec
- Framework framework
- | isDarwinTarget
- -> do maybe_errstr <- loadFramework framework_paths framework
+ Framework framework ->
+ case platformOS (targetPlatform dflags) of
+ OSDarwin ->
+ do maybe_errstr <- loadFramework framework_paths framework
case maybe_errstr of
Nothing -> maybePutStrLn dflags "done"
Just mm -> preloadFailed mm framework_paths lib_spec
- | otherwise -> panic "preloadLib Framework"
+ _ -> panic "preloadLib Framework"
where
+ platform = targetPlatform dflags
+
preloadFailed :: String -> [String] -> LibrarySpec -> IO ()
preloadFailed sys_errmsg paths spec
= do maybePutStr dflags "failed.\n"
@@ -968,7 +974,7 @@ data LibrarySpec
-- just to get the DLL handle into the list.
partOfGHCi :: [PackageName]
partOfGHCi
- | isWindowsTarget || isDarwinTarget = []
+ | isWindowsHost || isDarwinHost = []
| otherwise = map PackageName
["base", "template-haskell", "editline"]
@@ -1033,7 +1039,8 @@ linkPackages' dflags new_pks pls = do
linkPackage :: DynFlags -> PackageConfig -> IO ()
linkPackage dflags pkg
= do
- let dirs = Packages.libraryDirs pkg
+ let platform = targetPlatform dflags
+ dirs = Packages.libraryDirs pkg
let hs_libs = Packages.hsLibraries pkg
-- The FFI GHCi import lib isn't needed as
@@ -1070,8 +1077,8 @@ linkPackage dflags pkg
-- See comments with partOfGHCi
when (packageName pkg `notElem` partOfGHCi) $ do
- loadFrameworks pkg
- mapM_ load_dyn (known_dlls ++ map mkSOName dlls)
+ loadFrameworks platform pkg
+ mapM_ load_dyn (known_dlls ++ map (mkSOName platform) dlls)
-- After loading all the DLLs, we can load the static objects.
-- Ordering isn't important here, because we do one final link
@@ -1096,10 +1103,11 @@ load_dyn dll = do r <- loadDLL dll
Just err -> ghcError (CmdLineError ("can't load .so/.DLL for: "
++ dll ++ " (" ++ err ++ ")" ))
-loadFrameworks :: InstalledPackageInfo_ ModuleName -> IO ()
-loadFrameworks pkg
- | isDarwinTarget = mapM_ load frameworks
- | otherwise = return ()
+loadFrameworks :: Platform -> InstalledPackageInfo_ ModuleName -> IO ()
+loadFrameworks platform pkg
+ = case platformOS platform of
+ OSDarwin -> mapM_ load frameworks
+ _ -> return ()
where
fw_dirs = Packages.frameworkDirs pkg
frameworks = Packages.frameworks pkg
@@ -1142,9 +1150,9 @@ locateLib dflags is_hs dirs lib
mk_arch_path dir = dir </> ("lib" ++ lib <.> "a")
hs_dyn_lib_name = lib ++ "-ghc" ++ cProjectVersion
- mk_hs_dyn_lib_path dir = dir </> mkSOName hs_dyn_lib_name
+ mk_hs_dyn_lib_path dir = dir </> mkSOName platform hs_dyn_lib_name
- so_name = mkSOName lib
+ so_name = mkSOName platform lib
mk_dyn_lib_path dir = dir </> so_name
findObject = liftM (fmap Object) $ findFile mk_obj_path dirs
@@ -1160,6 +1168,8 @@ locateLib dflags is_hs dirs lib
Just x -> return x
Nothing -> g
+ platform = targetPlatform dflags
+
searchForLibUsingGcc :: DynFlags -> String -> [FilePath] -> IO (Maybe FilePath)
searchForLibUsingGcc dflags so dirs = do
str <- askCc dflags (map (FileOption "-L") dirs
@@ -1174,11 +1184,12 @@ searchForLibUsingGcc dflags so dirs = do
-- ----------------------------------------------------------------------------
-- Loading a dyanmic library (dlopen()-ish on Unix, LoadLibrary-ish on Win32)
-mkSOName :: FilePath -> FilePath
-mkSOName root
- | isDarwinTarget = ("lib" ++ root) <.> "dylib"
- | isWindowsTarget = root <.> "dll"
- | otherwise = ("lib" ++ root) <.> "so"
+mkSOName :: Platform -> FilePath -> FilePath
+mkSOName platform root
+ = case platformOS platform of
+ OSDarwin -> ("lib" ++ root) <.> "dylib"
+ OSMinGW32 -> root <.> "dll"
+ _ -> ("lib" ++ root) <.> "so"
-- Darwin / MacOS X only: load a framework
-- a framework is a dynamic library packaged inside a directory of the same
diff --git a/compiler/llvmGen/LlvmCodeGen/Ppr.hs b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
index 1c715989a8..cf78b3730a 100644
--- a/compiler/llvmGen/LlvmCodeGen/Ppr.hs
+++ b/compiler/llvmGen/LlvmCodeGen/Ppr.hs
@@ -15,6 +15,7 @@ import LlvmCodeGen.Regs
import CLabel
import OldCmm
+import Platform
import FastString
import Outputable
@@ -37,41 +38,29 @@ pprLlvmHeader =
-- | LLVM module layout description for the host target
moduleLayout :: SDoc
-moduleLayout =
-#if i386_TARGET_ARCH
-
-#if darwin_TARGET_OS
- text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32\""
- $+$ text "target triple = \"i386-apple-darwin9.8\""
-#elif mingw32_TARGET_OS
- text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32\""
- $+$ text "target triple = \"i686-pc-win32\""
-#else /* Linux */
- text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32\""
- $+$ text "target triple = \"i386-pc-linux-gnu\""
-#endif
-
-#elif x86_64_TARGET_ARCH
-
-#if darwin_TARGET_OS
- text "target datalayout = \"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64\""
- $+$ text "target triple = \"x86_64-apple-darwin10.0.0\""
-#else /* Linux */
- text "target datalayout = \"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64\""
- $+$ text "target triple = \"x86_64-linux-gnu\""
-#endif
-
-#elif defined (arm_TARGET_ARCH)
-
-#if linux_TARGET_OS
- text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32\""
- $+$ text "target triple = \"arm-unknown-linux-gnueabi\""
-#endif
-
-#else
- -- FIX: Other targets
- empty
-#endif
+moduleLayout = sdocWithPlatform $ \platform ->
+ case platform of
+ Platform { platformArch = ArchX86, platformOS = OSDarwin } ->
+ text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32\""
+ $+$ text "target triple = \"i386-apple-darwin9.8\""
+ Platform { platformArch = ArchX86, platformOS = OSMinGW32 } ->
+ text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32\""
+ $+$ text "target triple = \"i686-pc-win32\""
+ Platform { platformArch = ArchX86, platformOS = OSLinux } ->
+ text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32\""
+ $+$ text "target triple = \"i386-pc-linux-gnu\""
+ Platform { platformArch = ArchX86_64, platformOS = OSDarwin } ->
+ text "target datalayout = \"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64\""
+ $+$ text "target triple = \"x86_64-apple-darwin10.0.0\""
+ Platform { platformArch = ArchX86_64, platformOS = OSLinux } ->
+ text "target datalayout = \"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64\""
+ $+$ text "target triple = \"x86_64-linux-gnu\""
+ Platform { platformArch = ArchARM {}, platformOS = OSLinux } ->
+ text "target datalayout = \"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32\""
+ $+$ text "target triple = \"arm-unknown-linux-gnueabi\""
+ _ ->
+ -- FIX: Other targets
+ empty
-- | Pretty print LLVM data code
diff --git a/compiler/main/DriverPhases.hs b/compiler/main/DriverPhases.hs
index 29dbb58413..a1eac536b6 100644
--- a/compiler/main/DriverPhases.hs
+++ b/compiler/main/DriverPhases.hs
@@ -36,6 +36,7 @@ module DriverPhases (
#include "HsVersions.h"
import Outputable
+import Platform
import System.FilePath
-----------------------------------------------------------------------------
@@ -228,49 +229,47 @@ extcoreish_suffixes = [ "hcr" ]
-- Will not be deleted as temp files:
haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
-objish_suffixes :: [String]
+objish_suffixes :: Platform -> [String]
-- Use the appropriate suffix for the system on which
-- the GHC-compiled code will run
-#if mingw32_TARGET_OS || cygwin32_TARGET_OS
-objish_suffixes = [ "o", "O", "obj", "OBJ" ]
-#else
-objish_suffixes = [ "o" ]
-#endif
+objish_suffixes platform = case platformOS platform of
+ OSMinGW32 -> [ "o", "O", "obj", "OBJ" ]
+ _ -> [ "o" ]
-dynlib_suffixes :: [String]
-#ifdef mingw32_TARGET_OS
-dynlib_suffixes = ["dll", "DLL"]
-#elif defined(darwin_TARGET_OS)
-dynlib_suffixes = ["dylib"]
-#else
-dynlib_suffixes = ["so"]
-#endif
+dynlib_suffixes :: Platform -> [String]
+dynlib_suffixes platform = case platformOS platform of
+ OSMinGW32 -> ["dll", "DLL"]
+ OSDarwin -> ["dylib"]
+ _ -> ["so"]
isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix, isExtCoreSuffix,
- isObjectSuffix, isHaskellUserSrcSuffix, isDynLibSuffix
+ isHaskellUserSrcSuffix
:: String -> Bool
isHaskellishSuffix s = s `elem` haskellish_suffixes
isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes
isCishSuffix s = s `elem` cish_suffixes
isExtCoreSuffix s = s `elem` extcoreish_suffixes
-isObjectSuffix s = s `elem` objish_suffixes
isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
-isDynLibSuffix s = s `elem` dynlib_suffixes
+
+isObjectSuffix, isDynLibSuffix :: Platform -> String -> Bool
+isObjectSuffix platform s = s `elem` objish_suffixes platform
+isDynLibSuffix platform s = s `elem` dynlib_suffixes platform
isSourceSuffix :: String -> Bool
isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff
isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
- isExtCoreFilename, isObjectFilename, isHaskellUserSrcFilename,
- isDynLibFilename, isSourceFilename
+ isExtCoreFilename, isHaskellUserSrcFilename, isSourceFilename
:: FilePath -> Bool
-- takeExtension return .foo, so we drop 1 to get rid of the .
isHaskellishFilename f = isHaskellishSuffix (drop 1 $ takeExtension f)
isHaskellSrcFilename f = isHaskellSrcSuffix (drop 1 $ takeExtension f)
isCishFilename f = isCishSuffix (drop 1 $ takeExtension f)
isExtCoreFilename f = isExtCoreSuffix (drop 1 $ takeExtension f)
-isObjectFilename f = isObjectSuffix (drop 1 $ takeExtension f)
isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
-isDynLibFilename f = isDynLibSuffix (drop 1 $ takeExtension f)
isSourceFilename f = isSourceSuffix (drop 1 $ takeExtension f)
+isObjectFilename, isDynLibFilename :: Platform -> FilePath -> Bool
+isObjectFilename platform f = isObjectSuffix platform (drop 1 $ takeExtension f)
+isDynLibFilename platform f = isDynLibSuffix platform (drop 1 $ takeExtension f)
+
diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index 85127e63f6..bea9f14ee6 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -47,6 +47,7 @@ import Module
import Packages( isDllName )
import HscTypes
import Maybes
+import Platform
import UniqSupply
import ErrUtils (Severity(..))
import Outputable
@@ -1048,34 +1049,37 @@ tidyTopBinds hsc_env unfold_env init_occ_env binds
$ initTcForLookup hsc_env (tcLookupGlobal mkIntegerName)
return $ tidy mkIntegerId init_env binds
where
+ platform = targetPlatform (hsc_dflags hsc_env)
+
init_env = (init_occ_env, emptyVarEnv)
this_pkg = thisPackage (hsc_dflags hsc_env)
tidy _ env [] = (env, [])
- tidy mkIntegerId env (b:bs) = let (env1, b') = tidyTopBind this_pkg mkIntegerId unfold_env env b
+ tidy mkIntegerId env (b:bs) = let (env1, b') = tidyTopBind platform this_pkg mkIntegerId unfold_env env b
(env2, bs') = tidy mkIntegerId env1 bs
in
(env2, b':bs')
------------------------
-tidyTopBind :: PackageId
+tidyTopBind :: Platform
+ -> PackageId
-> Id
-> UnfoldEnv
-> TidyEnv
-> CoreBind
-> (TidyEnv, CoreBind)
-tidyTopBind this_pkg mkIntegerId unfold_env (occ_env,subst1) (NonRec bndr rhs)
+tidyTopBind platform this_pkg mkIntegerId unfold_env (occ_env,subst1) (NonRec bndr rhs)
= (tidy_env2, NonRec bndr' rhs')
where
Just (name',show_unfold) = lookupVarEnv unfold_env bndr
- caf_info = hasCafRefs this_pkg (mkIntegerId, subst1) (idArity bndr) rhs
+ caf_info = hasCafRefs platform this_pkg (mkIntegerId, subst1) (idArity bndr) rhs
(bndr', rhs') = tidyTopPair show_unfold tidy_env2 caf_info name' (bndr, rhs)
subst2 = extendVarEnv subst1 bndr bndr'
tidy_env2 = (occ_env, subst2)
-tidyTopBind this_pkg mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
+tidyTopBind platform this_pkg mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
= (tidy_env2, Rec prs')
where
prs' = [ tidyTopPair show_unfold tidy_env2 caf_info name' (id,rhs)
@@ -1092,7 +1096,7 @@ tidyTopBind this_pkg mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
-- the CafInfo for a recursive group says whether *any* rhs in
-- the group may refer indirectly to a CAF (because then, they all do).
caf_info
- | or [ mayHaveCafRefs (hasCafRefs this_pkg (mkIntegerId, subst1) (idArity bndr) rhs)
+ | or [ mayHaveCafRefs (hasCafRefs platform this_pkg (mkIntegerId, subst1) (idArity bndr) rhs)
| (bndr,rhs) <- prs ] = MayHaveCafRefs
| otherwise = NoCafRefs
@@ -1229,14 +1233,15 @@ it as a CAF. In these cases however, we would need to use an additional
CAF list to keep track of non-collectable CAFs.
\begin{code}
-hasCafRefs :: PackageId -> (Id, VarEnv Var) -> Arity -> CoreExpr -> CafInfo
-hasCafRefs this_pkg p arity expr
+hasCafRefs :: Platform -> PackageId -> (Id, VarEnv Var) -> Arity -> CoreExpr
+ -> CafInfo
+hasCafRefs platform this_pkg p arity expr
| is_caf || mentions_cafs = MayHaveCafRefs
| otherwise = NoCafRefs
where
mentions_cafs = isFastTrue (cafRefsE p expr)
is_dynamic_name = isDllName this_pkg
- is_caf = not (arity > 0 || rhsIsStatic is_dynamic_name expr)
+ is_caf = not (arity > 0 || rhsIsStatic platform is_dynamic_name expr)
-- NB. we pass in the arity of the expression, which is expected
-- to be calculated by exprArity. This is because exprArity
diff --git a/compiler/nativeGen/AsmCodeGen.lhs b/compiler/nativeGen/AsmCodeGen.lhs
index 65fc4e339c..6b1e93f271 100644
--- a/compiler/nativeGen/AsmCodeGen.lhs
+++ b/compiler/nativeGen/AsmCodeGen.lhs
@@ -179,7 +179,7 @@ nativeCodeGen dflags h us cmms
,shortcutJump = PPC.RegInfo.shortcutJump
,pprNatCmmDecl = PPC.Ppr.pprNatCmmDecl
,maxSpillSlots = PPC.Instr.maxSpillSlots
- ,allocatableRegs = \_ -> PPC.Regs.allocatableRegs
+ ,allocatableRegs = PPC.Regs.allocatableRegs
,ncg_x86fp_kludge = id
,ncgExpandTop = id
,ncgMakeFarBranches = makeFarBranches
diff --git a/compiler/nativeGen/PPC/CodeGen.hs b/compiler/nativeGen/PPC/CodeGen.hs
index b6c83eec0a..ce4a54ca9b 100644
--- a/compiler/nativeGen/PPC/CodeGen.hs
+++ b/compiler/nativeGen/PPC/CodeGen.hs
@@ -25,6 +25,7 @@ where
#include "../includes/MachDeps.h"
-- NCG stuff:
+import CodeGen.Platform
import PPC.Instr
import PPC.Cond
import PPC.Regs
@@ -171,13 +172,13 @@ swizzleRegisterRep (Any _ codefn) size = Any size codefn
-- | Grab the Reg for a CmmReg
-getRegisterReg :: CmmReg -> Reg
+getRegisterReg :: Platform -> CmmReg -> Reg
-getRegisterReg (CmmLocal (LocalReg u pk))
+getRegisterReg _ (CmmLocal (LocalReg u pk))
= RegVirtual $ mkVirtualReg u (cmmTypeSize pk)
-getRegisterReg (CmmGlobal mid)
- = case globalRegMaybe mid of
+getRegisterReg platform (CmmGlobal mid)
+ = case globalRegMaybe platform mid of
Just reg -> RegReal reg
Nothing -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal mid)
-- By this stage, the only MagicIds remaining should be the
@@ -368,9 +369,9 @@ getRegister' _ (CmmReg (CmmGlobal PicBaseReg))
reg <- getPicBaseNat archWordSize
return (Fixed archWordSize reg nilOL)
-getRegister' _ (CmmReg reg)
+getRegister' dflags (CmmReg reg)
= return (Fixed (cmmTypeSize (cmmRegType reg))
- (getRegisterReg reg) nilOL)
+ (getRegisterReg (targetPlatform dflags) reg) nilOL)
getRegister' dflags tree@(CmmRegOff _ _)
= getRegister' dflags (mangleIndexTree tree)
@@ -763,12 +764,12 @@ assignMem_IntCode pk addr src = do
-- dst is a reg, but src could be anything
assignReg_IntCode _ reg src
= do
+ dflags <- getDynFlags
+ let dst = getRegisterReg (targetPlatform dflags) reg
r <- getRegister src
return $ case r of
Any _ code -> code dst
Fixed _ freg fcode -> fcode `snocOL` MR dst freg
- where
- dst = getRegisterReg reg
@@ -841,15 +842,17 @@ genCCall :: CmmCallTarget -- function to call
-> NatM InstrBlock
genCCall target dest_regs argsAndHints
= do dflags <- getDynFlags
- case platformOS (targetPlatform dflags) of
- OSLinux -> genCCall' GCPLinux target dest_regs argsAndHints
- OSDarwin -> genCCall' GCPDarwin target dest_regs argsAndHints
+ let platform = targetPlatform dflags
+ case platformOS platform of
+ OSLinux -> genCCall' platform GCPLinux target dest_regs argsAndHints
+ OSDarwin -> genCCall' platform GCPDarwin target dest_regs argsAndHints
_ -> panic "PPC.CodeGen.genCCall: not defined for this os"
data GenCCallPlatform = GCPLinux | GCPDarwin
genCCall'
- :: GenCCallPlatform
+ :: Platform
+ -> GenCCallPlatform
-> CmmCallTarget -- function to call
-> [HintedCmmFormal] -- where to put the result
-> [HintedCmmActual] -- arguments (of mixed type)
@@ -893,19 +896,20 @@ genCCall'
-}
-genCCall' _ (CmmPrim MO_WriteBarrier _) _ _
+genCCall' _ _ (CmmPrim MO_WriteBarrier _) _ _
= return $ unitOL LWSYNC
-genCCall' _ (CmmPrim _ (Just stmts)) _ _
+genCCall' _ _ (CmmPrim _ (Just stmts)) _ _
= stmtsToInstrs stmts
-genCCall' gcp target dest_regs argsAndHints
+genCCall' platform gcp target dest_regs argsAndHints
= ASSERT (not $ any (`elem` [II16]) $ map cmmTypeSize argReps)
-- we rely on argument promotion in the codeGen
do
(finalStack,passArgumentsCode,usedRegs) <- passArguments
(zip args argReps)
- allArgRegs allFPArgRegs
+ allArgRegs
+ (allFPArgRegs platform)
initialStackOffset
(toOL []) []
@@ -1086,7 +1090,7 @@ genCCall' gcp target dest_regs argsAndHints
MR r_dest r4]
| otherwise -> unitOL (MR r_dest r3)
where rep = cmmRegType (CmmLocal dest)
- r_dest = getRegisterReg (CmmLocal dest)
+ r_dest = getRegisterReg platform (CmmLocal dest)
_ -> panic "genCCall' moveResult: Bad dest_regs"
outOfLineMachOp mop =
diff --git a/compiler/nativeGen/PPC/Instr.hs b/compiler/nativeGen/PPC/Instr.hs
index 2e25bd5b16..1af08a6076 100644
--- a/compiler/nativeGen/PPC/Instr.hs
+++ b/compiler/nativeGen/PPC/Instr.hs
@@ -33,6 +33,7 @@ import TargetReg
import RegClass
import Reg
+import CodeGen.Platform
import Constants (rESERVED_C_STACK_BYTES)
import BlockId
import OldCmm
@@ -178,7 +179,7 @@ data Instr
-- allocation goes, are taken care of by the register allocator.
--
ppc_regUsageOfInstr :: Platform -> Instr -> RegUsage
-ppc_regUsageOfInstr _ instr
+ppc_regUsageOfInstr platform instr
= case instr of
LD _ reg addr -> usage (regAddr addr, [reg])
LA _ reg addr -> usage (regAddr addr, [reg])
@@ -193,8 +194,8 @@ ppc_regUsageOfInstr _ instr
BCCFAR _ _ -> noUsage
MTCTR reg -> usage ([reg],[])
BCTR _ _ -> noUsage
- BL _ params -> usage (params, callClobberedRegs)
- BCTRL params -> usage (params, callClobberedRegs)
+ BL _ params -> usage (params, callClobberedRegs platform)
+ BCTRL params -> usage (params, callClobberedRegs platform)
ADD reg1 reg2 ri -> usage (reg2 : regRI ri, [reg1])
ADDC reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
ADDE reg1 reg2 reg3-> usage ([reg2,reg3], [reg1])
@@ -230,21 +231,21 @@ ppc_regUsageOfInstr _ instr
FETCHPC reg -> usage ([], [reg])
_ -> noUsage
where
- usage (src, dst) = RU (filter interesting src)
- (filter interesting dst)
+ usage (src, dst) = RU (filter (interesting platform) src)
+ (filter (interesting platform) dst)
regAddr (AddrRegReg r1 r2) = [r1, r2]
regAddr (AddrRegImm r1 _) = [r1]
regRI (RIReg r) = [r]
regRI _ = []
-interesting :: Reg -> Bool
-interesting (RegVirtual _) = True
-interesting (RegReal (RealRegSingle i))
- = isFastTrue (freeReg i)
+interesting :: Platform -> Reg -> Bool
+interesting _ (RegVirtual _) = True
+interesting platform (RegReal (RealRegSingle i))
+ = isFastTrue (freeReg platform i)
-interesting (RegReal (RealRegPair{}))
- = panic "PPC.Instr.interesting: no reg pairs on this arch"
+interesting _ (RegReal (RealRegPair{}))
+ = panic "PPC.Instr.interesting: no reg pairs on this arch"
diff --git a/compiler/nativeGen/PPC/Regs.hs b/compiler/nativeGen/PPC/Regs.hs
index b86df54b1e..7dccb6040e 100644
--- a/compiler/nativeGen/PPC/Regs.hs
+++ b/compiler/nativeGen/PPC/Regs.hs
@@ -37,9 +37,6 @@ module PPC.Regs (
fReg,
sp, r3, r4, r27, r28, f1, f20, f21,
- -- horrow show
- freeReg,
- globalRegMaybe,
allocatableRegs
)
@@ -48,7 +45,6 @@ where
#include "nativeGen/NCG.h"
#include "HsVersions.h"
-#include "../includes/stg/HaskellMachRegs.h"
import Reg
import RegClass
@@ -58,10 +54,12 @@ import OldCmm
import CLabel ( CLabel )
import Unique
+import CodeGen.Platform
import Outputable
import Constants
import FastBool
import FastTypes
+import Platform
import Data.Word ( Word8, Word16, Word32 )
import Data.Int ( Int8, Int16, Int32 )
@@ -223,19 +221,12 @@ allArgRegs = map regSingle [3..10]
-- these are the regs which we cannot assume stay alive over a C call.
-callClobberedRegs :: [Reg]
-#if defined(darwin_TARGET_OS)
-callClobberedRegs
- = map regSingle (0:[2..12] ++ map fReg [0..13])
-
-#elif defined(linux_TARGET_OS)
-callClobberedRegs
- = map regSingle (0:[2..13] ++ map fReg [0..13])
-
-#else
-callClobberedRegs
- = panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
-#endif
+callClobberedRegs :: Platform -> [Reg]
+callClobberedRegs platform
+ = case platformOS platform of
+ OSDarwin -> map regSingle (0:[2..12] ++ map fReg [0..13])
+ OSLinux -> map regSingle (0:[2..13] ++ map fReg [0..13])
+ _ -> panic "PPC.Regs.callClobberedRegs: not defined for this architecture"
allMachRegNos :: [RegNo]
@@ -261,17 +252,12 @@ showReg n
-- machine specific ------------------------------------------------------------
-allFPArgRegs :: [Reg]
-#if defined(darwin_TARGET_OS)
-allFPArgRegs = map (regSingle . fReg) [1..13]
-
-#elif defined(linux_TARGET_OS)
-allFPArgRegs = map (regSingle . fReg) [1..8]
-
-#else
-allFPArgRegs = panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
-
-#endif
+allFPArgRegs :: Platform -> [Reg]
+allFPArgRegs platform
+ = case platformOS platform of
+ OSDarwin -> map (regSingle . fReg) [1..13]
+ OSLinux -> map (regSingle . fReg) [1..8]
+ _ -> panic "PPC.Regs.allFPArgRegs: not defined for this architecture"
fits16Bits :: Integral a => a -> Bool
fits16Bits x = x >= -32768 && x < 32768
@@ -316,288 +302,10 @@ f1 = regSingle $ fReg 1
f20 = regSingle $ fReg 20
f21 = regSingle $ fReg 21
-
-
--- horror show -----------------------------------------------------------------
-freeReg :: RegNo -> FastBool
-globalRegMaybe :: GlobalReg -> Maybe RealReg
-
-
-#if powerpc_TARGET_ARCH
-#define r0 0
-#define r1 1
-#define r2 2
-#define r3 3
-#define r4 4
-#define r5 5
-#define r6 6
-#define r7 7
-#define r8 8
-#define r9 9
-#define r10 10
-#define r11 11
-#define r12 12
-#define r13 13
-#define r14 14
-#define r15 15
-#define r16 16
-#define r17 17
-#define r18 18
-#define r19 19
-#define r20 20
-#define r21 21
-#define r22 22
-#define r23 23
-#define r24 24
-#define r25 25
-#define r26 26
-#define r27 27
-#define r28 28
-#define r29 29
-#define r30 30
-#define r31 31
-
-#ifdef darwin_TARGET_OS
-#define f0 32
-#define f1 33
-#define f2 34
-#define f3 35
-#define f4 36
-#define f5 37
-#define f6 38
-#define f7 39
-#define f8 40
-#define f9 41
-#define f10 42
-#define f11 43
-#define f12 44
-#define f13 45
-#define f14 46
-#define f15 47
-#define f16 48
-#define f17 49
-#define f18 50
-#define f19 51
-#define f20 52
-#define f21 53
-#define f22 54
-#define f23 55
-#define f24 56
-#define f25 57
-#define f26 58
-#define f27 59
-#define f28 60
-#define f29 61
-#define f30 62
-#define f31 63
-#else
-#define fr0 32
-#define fr1 33
-#define fr2 34
-#define fr3 35
-#define fr4 36
-#define fr5 37
-#define fr6 38
-#define fr7 39
-#define fr8 40
-#define fr9 41
-#define fr10 42
-#define fr11 43
-#define fr12 44
-#define fr13 45
-#define fr14 46
-#define fr15 47
-#define fr16 48
-#define fr17 49
-#define fr18 50
-#define fr19 51
-#define fr20 52
-#define fr21 53
-#define fr22 54
-#define fr23 55
-#define fr24 56
-#define fr25 57
-#define fr26 58
-#define fr27 59
-#define fr28 60
-#define fr29 61
-#define fr30 62
-#define fr31 63
-#endif
-
-
-
-freeReg 0 = fastBool False -- Hack: r0 can't be used in all insns, but it's actually free
-freeReg 1 = fastBool False -- The Stack Pointer
-#if !darwin_TARGET_OS
- -- most non-darwin powerpc OSes use r2 as a TOC pointer or something like that
-freeReg 2 = fastBool False
-#endif
-
-#ifdef REG_Base
-freeReg REG_Base = fastBool False
-#endif
-#ifdef REG_R1
-freeReg REG_R1 = fastBool False
-#endif
-#ifdef REG_R2
-freeReg REG_R2 = fastBool False
-#endif
-#ifdef REG_R3
-freeReg REG_R3 = fastBool False
-#endif
-#ifdef REG_R4
-freeReg REG_R4 = fastBool False
-#endif
-#ifdef REG_R5
-freeReg REG_R5 = fastBool False
-#endif
-#ifdef REG_R6
-freeReg REG_R6 = fastBool False
-#endif
-#ifdef REG_R7
-freeReg REG_R7 = fastBool False
-#endif
-#ifdef REG_R8
-freeReg REG_R8 = fastBool False
-#endif
-#ifdef REG_R9
-freeReg REG_R9 = fastBool False
-#endif
-#ifdef REG_R10
-freeReg REG_R10 = fastBool False
-#endif
-#ifdef REG_F1
-freeReg REG_F1 = fastBool False
-#endif
-#ifdef REG_F2
-freeReg REG_F2 = fastBool False
-#endif
-#ifdef REG_F3
-freeReg REG_F3 = fastBool False
-#endif
-#ifdef REG_F4
-freeReg REG_F4 = fastBool False
-#endif
-#ifdef REG_D1
-freeReg REG_D1 = fastBool False
-#endif
-#ifdef REG_D2
-freeReg REG_D2 = fastBool False
-#endif
-#ifdef REG_Sp
-freeReg REG_Sp = fastBool False
-#endif
-#ifdef REG_Su
-freeReg REG_Su = fastBool False
-#endif
-#ifdef REG_SpLim
-freeReg REG_SpLim = fastBool False
-#endif
-#ifdef REG_Hp
-freeReg REG_Hp = fastBool False
-#endif
-#ifdef REG_HpLim
-freeReg REG_HpLim = fastBool False
-#endif
-freeReg _ = fastBool True
-
-
--- | Returns 'Nothing' if this global register is not stored
--- in a real machine register, otherwise returns @'Just' reg@, where
--- reg is the machine register it is stored in.
-
-
-#ifdef REG_Base
-globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
-#endif
-#ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
-#endif
-#ifdef REG_R2
-globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
-#endif
-#ifdef REG_R3
-globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
-#endif
-#ifdef REG_R4
-globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
-#endif
-#ifdef REG_R5
-globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
-#endif
-#ifdef REG_R6
-globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
-#endif
-#ifdef REG_R7
-globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
-#endif
-#ifdef REG_R8
-globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
-#endif
-#ifdef REG_R9
-globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
-#endif
-#ifdef REG_R10
-globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
-#endif
-#ifdef REG_F1
-globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
-#endif
-#ifdef REG_F2
-globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
-#endif
-#ifdef REG_F3
-globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
-#endif
-#ifdef REG_F4
-globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
-#endif
-#ifdef REG_D1
-globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
-#endif
-#ifdef REG_D2
-globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
-#endif
-#ifdef REG_Sp
-globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
-#endif
-#ifdef REG_Lng1
-globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
-#endif
-#ifdef REG_Lng2
-globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
-#endif
-#ifdef REG_SpLim
-globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
-#endif
-#ifdef REG_Hp
-globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
-#endif
-#ifdef REG_HpLim
-globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
-#endif
-#ifdef REG_CurrentTSO
-globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
-#endif
-#ifdef REG_CurrentNursery
-globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
-#endif
-globalRegMaybe _ = Nothing
-
-
-#else /* powerpc_TARGET_ARCH */
-
-freeReg _ = 0#
-globalRegMaybe _ = panic "PPC.Regs.globalRegMaybe: not defined"
-
-#endif /* powerpc_TARGET_ARCH */
-
-
-- allocatableRegs is allMachRegNos with the fixed-use regs removed.
-- i.e., these are the regs for which we are prepared to allow the
-- register allocator to attempt to map VRegs to.
-allocatableRegs :: [RealReg]
-allocatableRegs
- = let isFree i = isFastTrue (freeReg i)
+allocatableRegs :: Platform -> [RealReg]
+allocatableRegs platform
+ = let isFree i = isFastTrue (freeReg platform i)
in map RealRegSingle $ filter isFree allMachRegNos
diff --git a/compiler/nativeGen/RegAlloc/Linear/FreeRegs.hs b/compiler/nativeGen/RegAlloc/Linear/FreeRegs.hs
index 724d7d6b25..887af1758a 100644
--- a/compiler/nativeGen/RegAlloc/Linear/FreeRegs.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/FreeRegs.hs
@@ -42,27 +42,27 @@ import qualified SPARC.Instr
import qualified X86.Instr
class Show freeRegs => FR freeRegs where
- frAllocateReg :: RealReg -> freeRegs -> freeRegs
+ frAllocateReg :: Platform -> RealReg -> freeRegs -> freeRegs
frGetFreeRegs :: Platform -> RegClass -> freeRegs -> [RealReg]
frInitFreeRegs :: Platform -> freeRegs
- frReleaseReg :: RealReg -> freeRegs -> freeRegs
+ frReleaseReg :: Platform -> RealReg -> freeRegs -> freeRegs
instance FR X86.FreeRegs where
- frAllocateReg = X86.allocateReg
+ frAllocateReg = \_ -> X86.allocateReg
frGetFreeRegs = X86.getFreeRegs
frInitFreeRegs = X86.initFreeRegs
- frReleaseReg = X86.releaseReg
+ frReleaseReg = \_ -> X86.releaseReg
instance FR PPC.FreeRegs where
- frAllocateReg = PPC.allocateReg
+ frAllocateReg = \_ -> PPC.allocateReg
frGetFreeRegs = \_ -> PPC.getFreeRegs
- frInitFreeRegs = \_ -> PPC.initFreeRegs
- frReleaseReg = PPC.releaseReg
+ frInitFreeRegs = PPC.initFreeRegs
+ frReleaseReg = \_ -> PPC.releaseReg
instance FR SPARC.FreeRegs where
frAllocateReg = SPARC.allocateReg
frGetFreeRegs = \_ -> SPARC.getFreeRegs
- frInitFreeRegs = \_ -> SPARC.initFreeRegs
+ frInitFreeRegs = SPARC.initFreeRegs
frReleaseReg = SPARC.releaseReg
maxSpillSlots :: Platform -> Int
diff --git a/compiler/nativeGen/RegAlloc/Linear/JoinToTargets.hs b/compiler/nativeGen/RegAlloc/Linear/JoinToTargets.hs
index c17b65d6e2..ea415e2661 100644
--- a/compiler/nativeGen/RegAlloc/Linear/JoinToTargets.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/JoinToTargets.hs
@@ -135,7 +135,7 @@ joinToTargets_first platform block_live new_blocks block_id instr dest dests
= do -- free up the regs that are not live on entry to this block.
freeregs <- getFreeRegsR
- let freeregs' = foldr frReleaseReg freeregs to_free
+ let freeregs' = foldr (frReleaseReg platform) freeregs to_free
-- remember the current assignment on entry to this block.
setBlockAssigR (mapInsert dest (freeregs', src_assig) block_assig)
diff --git a/compiler/nativeGen/RegAlloc/Linear/Main.hs b/compiler/nativeGen/RegAlloc/Linear/Main.hs
index 54c6990948..c2f89de641 100644
--- a/compiler/nativeGen/RegAlloc/Linear/Main.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/Main.hs
@@ -130,9 +130,6 @@ import Data.Maybe
import Data.List
import Control.Monad
-#include "../includes/stg/HaskellMachRegs.h"
-
-
-- -----------------------------------------------------------------------------
-- Top level of the register allocator
@@ -328,7 +325,7 @@ initBlock platform id block_live
Nothing ->
setFreeRegsR (frInitFreeRegs platform)
Just live ->
- setFreeRegsR $ foldr frAllocateReg (frInitFreeRegs platform) [ r | RegReal r <- uniqSetToList live ]
+ setFreeRegsR $ foldr (frAllocateReg platform) (frInitFreeRegs platform) [ r | RegReal r <- uniqSetToList live ]
setAssigR emptyRegMap
-- load info about register assignments leading into this block.
@@ -488,10 +485,10 @@ genRaInsn platform block_live new_instrs block_id instr r_dying w_dying =
-- (e) Delete all register assignments for temps which are read
-- (only) and die here. Update the free register list.
- releaseRegs r_dying
+ releaseRegs platform r_dying
-- (f) Mark regs which are clobbered as unallocatable
- clobberRegs real_written
+ clobberRegs platform real_written
-- (g) Allocate registers for temporaries *written* (only)
(w_spills, w_allocd) <-
@@ -499,7 +496,7 @@ genRaInsn platform block_live new_instrs block_id instr r_dying w_dying =
-- (h) Release registers for temps which are written here and not
-- used again.
- releaseRegs w_dying
+ releaseRegs platform w_dying
let
-- (i) Patch the instruction
@@ -542,19 +539,19 @@ genRaInsn platform block_live new_instrs block_id instr r_dying w_dying =
-- -----------------------------------------------------------------------------
-- releaseRegs
-releaseRegs :: FR freeRegs => [Reg] -> RegM freeRegs ()
-releaseRegs regs = do
+releaseRegs :: FR freeRegs => Platform -> [Reg] -> RegM freeRegs ()
+releaseRegs platform regs = do
assig <- getAssigR
free <- getFreeRegsR
loop assig free regs
where
loop _ free _ | free `seq` False = undefined
loop assig free [] = do setAssigR assig; setFreeRegsR free; return ()
- loop assig free (RegReal rr : rs) = loop assig (frReleaseReg rr free) rs
+ loop assig free (RegReal rr : rs) = loop assig (frReleaseReg platform rr free) rs
loop assig free (r:rs) =
case lookupUFM assig r of
- Just (InBoth real _) -> loop (delFromUFM assig r) (frReleaseReg real free) rs
- Just (InReg real) -> loop (delFromUFM assig r) (frReleaseReg real free) rs
+ Just (InBoth real _) -> loop (delFromUFM assig r) (frReleaseReg platform real free) rs
+ Just (InReg real) -> loop (delFromUFM assig r) (frReleaseReg platform real free) rs
_other -> loop (delFromUFM assig r) free rs
@@ -612,7 +609,7 @@ saveClobberedTemps platform clobbered dying
-- clobbered by this instruction; use it to save the
-- clobbered value.
(my_reg : _) -> do
- setFreeRegsR (frAllocateReg my_reg freeRegs)
+ setFreeRegsR (frAllocateReg platform my_reg freeRegs)
let new_assign = addToUFM assig temp (InReg my_reg)
let instr = mkRegRegMoveInstr platform
@@ -636,14 +633,14 @@ saveClobberedTemps platform clobbered dying
-- | Mark all these real regs as allocated,
-- and kick out their vreg assignments.
--
-clobberRegs :: FR freeRegs => [RealReg] -> RegM freeRegs ()
-clobberRegs []
+clobberRegs :: FR freeRegs => Platform -> [RealReg] -> RegM freeRegs ()
+clobberRegs _ []
= return ()
-clobberRegs clobbered
+clobberRegs platform clobbered
= do
freeregs <- getFreeRegsR
- setFreeRegsR $! foldr frAllocateReg freeregs clobbered
+ setFreeRegsR $! foldr (frAllocateReg platform) freeregs clobbered
assig <- getAssigR
setAssigR $! clobber assig (ufmToList assig)
@@ -754,7 +751,7 @@ allocRegsAndSpill_spill platform reading keep spills alloc r rs assig spill_loc
do spills' <- loadTemp platform r spill_loc my_reg spills
setAssigR (addToUFM assig r $! newLocation spill_loc my_reg)
- setFreeRegsR $ frAllocateReg my_reg freeRegs
+ setFreeRegsR $ frAllocateReg platform my_reg freeRegs
allocateRegsAndSpill platform reading keep spills' (my_reg : alloc) rs
diff --git a/compiler/nativeGen/RegAlloc/Linear/PPC/FreeRegs.hs b/compiler/nativeGen/RegAlloc/Linear/PPC/FreeRegs.hs
index 10726cd4b4..2c83481f6c 100644
--- a/compiler/nativeGen/RegAlloc/Linear/PPC/FreeRegs.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/PPC/FreeRegs.hs
@@ -15,6 +15,7 @@ import RegClass
import Reg
import Outputable
+import Platform
import Data.Word
import Data.Bits
@@ -45,8 +46,8 @@ releaseReg (RealRegSingle r) (FreeRegs g f)
releaseReg _ _
= panic "RegAlloc.Linear.PPC.releaseReg: bad reg"
-initFreeRegs :: FreeRegs
-initFreeRegs = foldr releaseReg noFreeRegs allocatableRegs
+initFreeRegs :: Platform -> FreeRegs
+initFreeRegs platform = foldr releaseReg noFreeRegs (allocatableRegs platform)
getFreeRegs :: RegClass -> FreeRegs -> [RealReg] -- lazilly
getFreeRegs cls (FreeRegs g f)
diff --git a/compiler/nativeGen/RegAlloc/Linear/SPARC/FreeRegs.hs b/compiler/nativeGen/RegAlloc/Linear/SPARC/FreeRegs.hs
index d3bc88c09f..d15ad07898 100644
--- a/compiler/nativeGen/RegAlloc/Linear/SPARC/FreeRegs.hs
+++ b/compiler/nativeGen/RegAlloc/Linear/SPARC/FreeRegs.hs
@@ -11,11 +11,12 @@ module RegAlloc.Linear.SPARC.FreeRegs
where
import SPARC.Regs
-import SPARC.RegPlate
import RegClass
import Reg
+import CodeGen.Platform
import Outputable
+import Platform
import FastBool
import Data.Word
@@ -50,9 +51,9 @@ noFreeRegs = FreeRegs 0 0 0
-- | The initial set of free regs.
-initFreeRegs :: FreeRegs
-initFreeRegs
- = foldr releaseReg noFreeRegs allocatableRegs
+initFreeRegs :: Platform -> FreeRegs
+initFreeRegs platform
+ = foldr (releaseReg platform) noFreeRegs allocatableRegs
-- | Get all the free registers of this class.
@@ -75,13 +76,13 @@ getFreeRegs cls (FreeRegs g f d)
-- | Grab a register.
-allocateReg :: RealReg -> FreeRegs -> FreeRegs
-allocateReg
+allocateReg :: Platform -> RealReg -> FreeRegs -> FreeRegs
+allocateReg platform
reg@(RealRegSingle r)
(FreeRegs g f d)
-- can't allocate free regs
- | not $ isFastTrue (freeReg r)
+ | not $ isFastTrue (freeReg platform r)
= pprPanic "SPARC.FreeRegs.allocateReg: not allocating pinned reg" (ppr reg)
-- a general purpose reg
@@ -108,7 +109,7 @@ allocateReg
| otherwise
= pprPanic "SPARC.FreeRegs.releaseReg: not allocating bad reg" (ppr reg)
-allocateReg
+allocateReg _
reg@(RealRegPair r1 r2)
(FreeRegs g f d)
@@ -131,13 +132,13 @@ allocateReg
-- The register liveness information says that most regs die after a C call,
-- but we still don't want to allocate to some of them.
--
-releaseReg :: RealReg -> FreeRegs -> FreeRegs
-releaseReg
+releaseReg :: Platform -> RealReg -> FreeRegs -> FreeRegs
+releaseReg platform
reg@(RealRegSingle r)
regs@(FreeRegs g f d)
-- don't release pinned reg
- | not $ isFastTrue (freeReg r)
+ | not $ isFastTrue (freeReg platform r)
= regs
-- a general purpose reg
@@ -161,7 +162,7 @@ releaseReg
| otherwise
= pprPanic "SPARC.FreeRegs.releaseReg: not releasing bad reg" (ppr reg)
-releaseReg
+releaseReg _
reg@(RealRegPair r1 r2)
(FreeRegs g f d)
diff --git a/compiler/nativeGen/SPARC/CodeGen.hs b/compiler/nativeGen/SPARC/CodeGen.hs
index 840918281f..a3409dd28b 100644
--- a/compiler/nativeGen/SPARC/CodeGen.hs
+++ b/compiler/nativeGen/SPARC/CodeGen.hs
@@ -191,12 +191,12 @@ assignMem_IntCode pk addr src = do
assignReg_IntCode :: Size -> CmmReg -> CmmExpr -> NatM InstrBlock
assignReg_IntCode _ reg src = do
+ dflags <- getDynFlags
r <- getRegister src
+ let dst = getRegisterReg (targetPlatform dflags) reg
return $ case r of
Any _ code -> code dst
Fixed _ freg fcode -> fcode `snocOL` OR False g0 (RIReg freg) dst
- where
- dst = getRegisterReg reg
@@ -218,8 +218,10 @@ assignMem_FltCode pk addr src = do
-- Floating point assignment to a register/temporary
assignReg_FltCode :: Size -> CmmReg -> CmmExpr -> NatM InstrBlock
assignReg_FltCode pk dstCmmReg srcCmmExpr = do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
srcRegister <- getRegister srcCmmExpr
- let dstReg = getRegisterReg dstCmmReg
+ let dstReg = getRegisterReg platform dstCmmReg
return $ case srcRegister of
Any _ code -> code dstReg
@@ -537,7 +539,7 @@ assign_code _ [] = nilOL
assign_code platform [CmmHinted dest _hint]
= let rep = localRegType dest
width = typeWidth rep
- r_dest = getRegisterReg (CmmLocal dest)
+ r_dest = getRegisterReg platform (CmmLocal dest)
result
| isFloatType rep
diff --git a/compiler/nativeGen/SPARC/CodeGen/Base.hs b/compiler/nativeGen/SPARC/CodeGen/Base.hs
index 8990072c3f..469361139b 100644
--- a/compiler/nativeGen/SPARC/CodeGen/Base.hs
+++ b/compiler/nativeGen/SPARC/CodeGen/Base.hs
@@ -25,12 +25,13 @@ import SPARC.Instr
import SPARC.Cond
import SPARC.AddrMode
import SPARC.Regs
-import SPARC.RegPlate
import Size
import Reg
+import CodeGen.Platform
import OldCmm
import OldPprCmm ()
+import Platform
import Outputable
import OrdList
@@ -98,13 +99,13 @@ setSizeOfRegister reg size
--------------------------------------------------------------------------------
-- | Grab the Reg for a CmmReg
-getRegisterReg :: CmmReg -> Reg
+getRegisterReg :: Platform -> CmmReg -> Reg
-getRegisterReg (CmmLocal (LocalReg u pk))
+getRegisterReg _ (CmmLocal (LocalReg u pk))
= RegVirtual $ mkVirtualReg u (cmmTypeSize pk)
-getRegisterReg (CmmGlobal mid)
- = case globalRegMaybe mid of
+getRegisterReg platform (CmmGlobal mid)
+ = case globalRegMaybe platform mid of
Just reg -> RegReal reg
Nothing -> pprPanic
"SPARC.CodeGen.Base.getRegisterReg: global is in memory"
diff --git a/compiler/nativeGen/SPARC/CodeGen/Gen32.hs b/compiler/nativeGen/SPARC/CodeGen/Gen32.hs
index 454e786f1a..c2c47e99aa 100644
--- a/compiler/nativeGen/SPARC/CodeGen/Gen32.hs
+++ b/compiler/nativeGen/SPARC/CodeGen/Gen32.hs
@@ -32,6 +32,7 @@ import Reg
import OldCmm
import Control.Monad (liftM)
+import DynFlags
import OrdList
import Outputable
@@ -54,8 +55,10 @@ getSomeReg expr = do
getRegister :: CmmExpr -> NatM Register
getRegister (CmmReg reg)
- = return (Fixed (cmmTypeSize (cmmRegType reg))
- (getRegisterReg reg) nilOL)
+ = do dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ return (Fixed (cmmTypeSize (cmmRegType reg))
+ (getRegisterReg platform reg) nilOL)
getRegister tree@(CmmRegOff _ _)
= getRegister (mangleIndexTree tree)
diff --git a/compiler/nativeGen/SPARC/Instr.hs b/compiler/nativeGen/SPARC/Instr.hs
index b3429f7587..021b2fb772 100644
--- a/compiler/nativeGen/SPARC/Instr.hs
+++ b/compiler/nativeGen/SPARC/Instr.hs
@@ -36,7 +36,6 @@ import SPARC.Imm
import SPARC.AddrMode
import SPARC.Cond
import SPARC.Regs
-import SPARC.RegPlate
import SPARC.Base
import TargetReg
import Instruction
@@ -45,6 +44,7 @@ import Reg
import Size
import CLabel
+import CodeGen.Platform
import BlockId
import OldCmm
import FastString
@@ -222,7 +222,7 @@ data Instr
-- allocation goes, are taken care of by the register allocator.
--
sparc_regUsageOfInstr :: Platform -> Instr -> RegUsage
-sparc_regUsageOfInstr _ instr
+sparc_regUsageOfInstr platform instr
= case instr of
LD _ addr reg -> usage (regAddr addr, [reg])
ST _ reg addr -> usage (reg : regAddr addr, [])
@@ -266,7 +266,8 @@ sparc_regUsageOfInstr _ instr
where
usage (src, dst)
- = RU (filter interesting src) (filter interesting dst)
+ = RU (filter (interesting platform) src)
+ (filter (interesting platform) dst)
regAddr (AddrRegReg r1 r2) = [r1, r2]
regAddr (AddrRegImm r1 _) = [r1]
@@ -277,12 +278,12 @@ sparc_regUsageOfInstr _ instr
-- | Interesting regs are virtuals, or ones that are allocatable
-- by the register allocator.
-interesting :: Reg -> Bool
-interesting reg
+interesting :: Platform -> Reg -> Bool
+interesting platform reg
= case reg of
RegVirtual _ -> True
- RegReal (RealRegSingle r1) -> isFastTrue (freeReg r1)
- RegReal (RealRegPair r1 _) -> isFastTrue (freeReg r1)
+ RegReal (RealRegSingle r1) -> isFastTrue (freeReg platform r1)
+ RegReal (RealRegPair r1 _) -> isFastTrue (freeReg platform r1)
diff --git a/compiler/nativeGen/SPARC/RegPlate.hs b/compiler/nativeGen/SPARC/RegPlate.hs
deleted file mode 100644
index be638a934b..0000000000
--- a/compiler/nativeGen/SPARC/RegPlate.hs
+++ /dev/null
@@ -1,318 +0,0 @@
-
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
--- | Nasty #ifdefery that generates the definitions for
--- freeReg and globalRegMaybe from the information in includes/MachRegs.h.
---
--- If the current TARGET_ARCH isn't sparc then these functions will be wrong.
---
-module SPARC.RegPlate (
- freeReg,
- globalRegMaybe
-)
-
-where
-
-#include "HsVersions.h"
-
-import Reg
-import CmmExpr
-import FastBool
-
--- Register numbers for SPARC hardware registers.
--- These names are the same as the ones in Regs.hs, but those have
--- type Reg and not RegNo.
---
-#ifdef sparc_TARGET_ARCH
-
-#define g0 0
-#define g1 1
-#define g2 2
-#define g3 3
-#define g4 4
-#define g5 5
-#define g6 6
-#define g7 7
-
-#define o0 8
-#define o1 9
-#define o2 10
-#define o3 11
-#define o4 12
-#define o5 13
-#define o6 14
-#define o7 15
-
-#define l0 16
-#define l1 17
-#define l2 18
-#define l3 19
-#define l4 20
-#define l5 21
-#define l6 22
-#define l7 23
-
-#define i0 24
-#define i1 25
-#define i2 26
-#define i3 27
-#define i4 28
-#define i5 29
-#define i6 30
-#define i7 31
-
-#define f0 32
-#define f1 33
-#define f2 34
-#define f3 35
-#define f4 36
-#define f5 37
-#define f6 38
-#define f7 39
-#define f8 40
-#define f9 41
-#define f10 42
-#define f11 43
-#define f12 44
-#define f13 45
-#define f14 46
-#define f15 47
-#define f16 48
-#define f17 49
-#define f18 50
-#define f19 51
-#define f20 52
-#define f21 53
-#define f22 54
-#define f23 55
-#define f24 56
-#define f25 57
-#define f26 58
-#define f27 59
-#define f28 60
-#define f29 61
-#define f30 62
-#define f31 63
-
-
-#include "../includes/stg/HaskellMachRegs.h"
-
--- | Check whether a machine register is free for allocation.
-freeReg :: RegNo -> FastBool
-
-
--- SPARC regs used by the OS / ABI
--- %g0(r0) is always zero
-freeReg g0 = fastBool False
-
--- %g5(r5) - %g7(r7)
--- are reserved for the OS
-freeReg g5 = fastBool False
-freeReg g6 = fastBool False
-freeReg g7 = fastBool False
-
--- %o6(r14)
--- is the C stack pointer
-freeReg o6 = fastBool False
-
--- %o7(r15)
--- holds the C return address
-freeReg o7 = fastBool False
-
--- %i6(r30)
--- is the C frame pointer
-freeReg i6 = fastBool False
-
--- %i7(r31)
--- is used for C return addresses
-freeReg i7 = fastBool False
-
--- %f0(r32) - %f1(r32)
--- are C floating point return regs
-freeReg f0 = fastBool False
-freeReg f1 = fastBool False
-
-{-
-freeReg regNo
- -- don't release high half of double regs
- | regNo >= f0
- , regNo < NCG_FirstFloatReg
- , regNo `mod` 2 /= 0
- = fastBool False
--}
---------------------------------------
-
-
-#ifdef REG_Base
-freeReg REG_Base = fastBool False
-#endif
-#ifdef REG_R1
-freeReg REG_R1 = fastBool False
-#endif
-#ifdef REG_R2
-freeReg REG_R2 = fastBool False
-#endif
-#ifdef REG_R3
-freeReg REG_R3 = fastBool False
-#endif
-#ifdef REG_R4
-freeReg REG_R4 = fastBool False
-#endif
-#ifdef REG_R5
-freeReg REG_R5 = fastBool False
-#endif
-#ifdef REG_R6
-freeReg REG_R6 = fastBool False
-#endif
-#ifdef REG_R7
-freeReg REG_R7 = fastBool False
-#endif
-#ifdef REG_R8
-freeReg REG_R8 = fastBool False
-#endif
-#ifdef REG_R9
-freeReg REG_R9 = fastBool False
-#endif
-#ifdef REG_R10
-freeReg REG_R10 = fastBool False
-#endif
-#ifdef REG_F1
-freeReg REG_F1 = fastBool False
-#endif
-#ifdef REG_F2
-freeReg REG_F2 = fastBool False
-#endif
-#ifdef REG_F3
-freeReg REG_F3 = fastBool False
-#endif
-#ifdef REG_F4
-freeReg REG_F4 = fastBool False
-#endif
-#ifdef REG_D1
-freeReg REG_D1 = fastBool False
-#endif
-#ifdef REG_D1_2
-freeReg REG_D1_2 = fastBool False
-#endif
-#ifdef REG_D2
-freeReg REG_D2 = fastBool False
-#endif
-#ifdef REG_D2_2
-freeReg REG_D2_2 = fastBool False
-#endif
-#ifdef REG_Sp
-freeReg REG_Sp = fastBool False
-#endif
-#ifdef REG_Su
-freeReg REG_Su = fastBool False
-#endif
-#ifdef REG_SpLim
-freeReg REG_SpLim = fastBool False
-#endif
-#ifdef REG_Hp
-freeReg REG_Hp = fastBool False
-#endif
-#ifdef REG_HpLim
-freeReg REG_HpLim = fastBool False
-#endif
-freeReg _ = fastBool True
-
-
-
--- | Returns 'Nothing' if this global register is not stored
--- in a real machine register, otherwise returns @'Just' reg@, where
--- reg is the machine register it is stored in.
-
-
-globalRegMaybe :: GlobalReg -> Maybe RealReg
-
-#ifdef REG_Base
-globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
-#endif
-#ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
-#endif
-#ifdef REG_R2
-globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
-#endif
-#ifdef REG_R3
-globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
-#endif
-#ifdef REG_R4
-globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
-#endif
-#ifdef REG_R5
-globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
-#endif
-#ifdef REG_R6
-globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
-#endif
-#ifdef REG_R7
-globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
-#endif
-#ifdef REG_R8
-globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
-#endif
-#ifdef REG_R9
-globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
-#endif
-#ifdef REG_R10
-globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
-#endif
-#ifdef REG_F1
-globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
-#endif
-#ifdef REG_F2
-globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
-#endif
-#ifdef REG_F3
-globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
-#endif
-#ifdef REG_F4
-globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
-#endif
-#ifdef REG_D1
-globalRegMaybe (DoubleReg 1) = Just (RealRegPair REG_D1 (REG_D1 + 1))
-#endif
-#ifdef REG_D2
-globalRegMaybe (DoubleReg 2) = Just (RealRegPair REG_D2 (REG_D2 + 1))
-#endif
-#ifdef REG_Sp
-globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
-#endif
-#ifdef REG_Lng1
-globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
-#endif
-#ifdef REG_Lng2
-globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
-#endif
-#ifdef REG_SpLim
-globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
-#endif
-#ifdef REG_Hp
-globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
-#endif
-#ifdef REG_HpLim
-globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
-#endif
-#ifdef REG_CurrentTSO
-globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
-#endif
-#ifdef REG_CurrentNursery
-globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
-#endif
-globalRegMaybe _ = Nothing
-
-#else
-freeReg :: RegNo -> FastBool
-freeReg = error "SPARC.RegPlate.freeReg: not defined"
-
-globalRegMaybe :: GlobalReg -> Maybe RealReg
-globalRegMaybe = error "SPARC.RegPlate.globalRegMaybe: not defined"
-
-#endif
diff --git a/compiler/nativeGen/SPARC/Regs.hs b/compiler/nativeGen/SPARC/Regs.hs
index ff899c24b1..d1ac2b4cb3 100644
--- a/compiler/nativeGen/SPARC/Regs.hs
+++ b/compiler/nativeGen/SPARC/Regs.hs
@@ -39,13 +39,11 @@ module SPARC.Regs (
where
-import SPARC.RegPlate
+import CodeGen.Platform.SPARC
import Reg
import RegClass
import Size
--- import PprCmm ()
-
import Unique
import Outputable
import FastTypes
@@ -274,129 +272,3 @@ regDotColor reg
RcFloat -> text "red"
_other -> text "green"
-
-
-
--- Hard coded freeReg / globalRegMaybe -----------------------------------------
--- This isn't being used at the moment because we're generating
--- these functions from the information in
--- includes/stg/MachRegs.hs via RegPlate.hs
-
--- | Check whether a machine register is free for allocation.
--- This needs to match the info in includes/stg/MachRegs.h
--- otherwise modules compiled with the NCG won't be compatible
--- with via-C ones.
---
-{-
-freeReg :: RegNo -> FastBool
-freeReg regno
- = case regno of
- -- %g0(r0) is always 0.
- 0 -> fastBool False
-
- -- %g1(r1) - %g4(r4) are allocable -----------------
-
- -- %g5(r5) - %g7(r7)
- -- are reserved for the OS
- 5 -> fastBool False
- 6 -> fastBool False
- 7 -> fastBool False
-
- -- %o0(r8) - %o5(r13) are allocable ----------------
-
- -- %o6(r14)
- -- is the C stack pointer
- 14 -> fastBool False
-
- -- %o7(r15)
- -- holds C return addresses (???)
- 15 -> fastBool False
-
- -- %l0(r16) is allocable ---------------------------
-
- -- %l1(r17) - %l5(r21)
- -- are STG regs R1 - R5
- 17 -> fastBool False
- 18 -> fastBool False
- 19 -> fastBool False
- 20 -> fastBool False
- 21 -> fastBool False
-
- -- %l6(r22) - %l7(r23) are allocable --------------
-
- -- %i0(r24) - %i5(r29)
- -- are STG regs Sp, Base, SpLim, Hp, R6
- 24 -> fastBool False
- 25 -> fastBool False
- 26 -> fastBool False
- 27 -> fastBool False
-
- -- %i5(r28) is allocable --------------------------
-
- 29 -> fastBool False
-
- -- %i6(r30)
- -- is the C frame pointer
- 30 -> fastBool False
-
- -- %i7(r31)
- -- is used for C return addresses
- 31 -> fastBool False
-
- -- %f0(r32) - %f1(r33)
- -- are C fp return registers
- 32 -> fastBool False
- 33 -> fastBool False
-
- -- %f2(r34) - %f5(r37)
- -- are STG regs D1 - D2
- 34 -> fastBool False
- 35 -> fastBool False
- 36 -> fastBool False
- 37 -> fastBool False
-
- -- %f22(r54) - %f25(r57)
- -- are STG regs F1 - F4
- 54 -> fastBool False
- 55 -> fastBool False
- 56 -> fastBool False
- 57 -> fastBool False
-
- -- regs not matched above are allocable.
- _ -> fastBool True
-
--}
-
--- | Returns Just the real register that a global register is stored in.
--- Returns Nothing if the global has no real register, and is stored
--- in the in-memory register table instead.
---
-{-
-globalRegMaybe :: GlobalReg -> Maybe Reg
-globalRegMaybe gg
- = case gg of
- -- Argument and return regs
- VanillaReg 1 _ -> Just (RealReg 17) -- %l1
- VanillaReg 2 _ -> Just (RealReg 18) -- %l2
- VanillaReg 3 _ -> Just (RealReg 19) -- %l3
- VanillaReg 4 _ -> Just (RealReg 20) -- %l4
- VanillaReg 5 _ -> Just (RealReg 21) -- %l5
- VanillaReg 6 _ -> Just (RealReg 29) -- %i5
-
- FloatReg 1 -> Just (RealReg 54) -- %f22
- FloatReg 2 -> Just (RealReg 55) -- %f23
- FloatReg 3 -> Just (RealReg 56) -- %f24
- FloatReg 4 -> Just (RealReg 57) -- %f25
-
- DoubleReg 1 -> Just (RealReg 34) -- %f2
- DoubleReg 2 -> Just (RealReg 36) -- %f4
-
- -- STG Regs
- Sp -> Just (RealReg 24) -- %i0
- SpLim -> Just (RealReg 26) -- %i2
- Hp -> Just (RealReg 27) -- %i3
-
- BaseReg -> Just (RealReg 25) -- %i1
-
- _ -> Nothing
--}
diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index c00a0d544a..e8f2eccd6b 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -27,6 +27,7 @@ import X86.Instr
import X86.Cond
import X86.Regs
import X86.RegInfo
+import CodeGen.Platform
import CPrim
import Instruction
import PIC
@@ -166,14 +167,16 @@ stmtToInstrs stmt = do
CmmCondBranch arg id -> genCondJump id arg
CmmSwitch arg ids -> do dflags <- getDynFlags
genSwitch dflags arg ids
- CmmJump arg gregs -> genJump arg (jumpRegs gregs)
+ CmmJump arg gregs -> do dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ genJump arg (jumpRegs platform gregs)
CmmReturn ->
panic "stmtToInstrs: return statement should have been cps'd away"
-jumpRegs :: Maybe [GlobalReg] -> [Reg]
-jumpRegs Nothing = allHaskellArgRegs
-jumpRegs (Just gregs) = [ RegReal r | Just r <- map globalRegMaybe gregs ]
+jumpRegs :: Platform -> Maybe [GlobalReg] -> [Reg]
+jumpRegs platform Nothing = allHaskellArgRegs platform
+jumpRegs platform (Just gregs) = [ RegReal r | Just r <- map (globalRegMaybe platform) gregs ]
--------------------------------------------------------------------------------
-- | 'InstrBlock's are the insn sequences generated by the insn selectors.
@@ -219,16 +222,16 @@ swizzleRegisterRep (Any _ codefn) size = Any size codefn
-- | Grab the Reg for a CmmReg
-getRegisterReg :: Bool -> CmmReg -> Reg
+getRegisterReg :: Platform -> Bool -> CmmReg -> Reg
-getRegisterReg use_sse2 (CmmLocal (LocalReg u pk))
+getRegisterReg _ use_sse2 (CmmLocal (LocalReg u pk))
= let sz = cmmTypeSize pk in
if isFloatSize sz && not use_sse2
then RegVirtual (mkVirtualReg u FF80)
else RegVirtual (mkVirtualReg u sz)
-getRegisterReg _ (CmmGlobal mid)
- = case globalRegMaybe mid of
+getRegisterReg platform _ (CmmGlobal mid)
+ = case globalRegMaybe platform mid of
Just reg -> RegReal $ reg
Nothing -> pprPanic "getRegisterReg-memory" (ppr $ CmmGlobal mid)
-- By this stage, the only MagicIds remaining should be the
@@ -424,7 +427,9 @@ getRegister' is32Bit (CmmReg reg)
size | not use_sse2 && isFloatSize sz = FF80
| otherwise = sz
--
- return (Fixed size (getRegisterReg use_sse2 reg) nilOL)
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ return (Fixed size (getRegisterReg platform use_sse2 reg) nilOL)
getRegister' is32Bit (CmmRegOff r n)
@@ -1052,9 +1057,11 @@ getNonClobberedOperand (CmmLoad mem pk) = do
if (not (isFloatType pk) || use_sse2)
&& (if is32Bit then not (isWord64 pk) else True)
then do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
Amode src mem_code <- getAmode mem
(src',save_code) <-
- if (amodeCouldBeClobbered src)
+ if (amodeCouldBeClobbered platform src)
then do
tmp <- getNewRegNat (archWordSize is32Bit)
return (AddrBaseIndex (EABaseReg tmp) EAIndexNone (ImmInt 0),
@@ -1072,12 +1079,12 @@ getNonClobberedOperand_generic e = do
(reg, code) <- getNonClobberedReg e
return (OpReg reg, code)
-amodeCouldBeClobbered :: AddrMode -> Bool
-amodeCouldBeClobbered amode = any regClobbered (addrModeRegs amode)
+amodeCouldBeClobbered :: Platform -> AddrMode -> Bool
+amodeCouldBeClobbered platform amode = any (regClobbered platform) (addrModeRegs amode)
-regClobbered :: Reg -> Bool
-regClobbered (RegReal (RealRegSingle rr)) = isFastTrue (freeReg rr)
-regClobbered _ = False
+regClobbered :: Platform -> Reg -> Bool
+regClobbered platform (RegReal (RealRegSingle rr)) = isFastTrue (freeReg platform rr)
+regClobbered _ _ = False
-- getOperand: the operand is not required to remain valid across the
-- computation of an arbitrary expression.
@@ -1385,12 +1392,16 @@ assignMem_IntCode pk addr src = do
-- Assign; dst is a reg, rhs is mem
assignReg_IntCode pk reg (CmmLoad src _) = do
load_code <- intLoadCode (MOV pk) src
- return (load_code (getRegisterReg False{-no sse2-} reg))
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ return (load_code (getRegisterReg platform False{-no sse2-} reg))
-- dst is a reg, but src could be anything
assignReg_IntCode _ reg src = do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
code <- getAnyReg src
- return (code (getRegisterReg False{-no sse2-} reg))
+ return (code (getRegisterReg platform False{-no sse2-} reg))
-- Floating point assignment to memory
@@ -1409,7 +1420,9 @@ assignMem_FltCode pk addr src = do
assignReg_FltCode _ reg src = do
use_sse2 <- sse2Enabled
src_code <- getAnyReg src
- return (src_code (getRegisterReg use_sse2 reg))
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ return (src_code (getRegisterReg platform use_sse2 reg))
genJump :: CmmExpr{-the branch target-} -> [Reg] -> NatM InstrBlock
@@ -1594,6 +1607,8 @@ genCCall _ (CmmPrim MO_WriteBarrier _) _ _ = return nilOL
genCCall is32Bit (CmmPrim (MO_PopCnt width) _) dest_regs@[CmmHinted dst _]
args@[CmmHinted src _] = do
sse4_2 <- sse4_2Enabled
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
if sse4_2
then do code_src <- getAnyReg src
src_r <- getNewRegNat size
@@ -1602,12 +1617,11 @@ genCCall is32Bit (CmmPrim (MO_PopCnt width) _) dest_regs@[CmmHinted dst _]
-- The POPCNT instruction doesn't take a r/m8
unitOL (MOVZxL II8 (OpReg src_r) (OpReg src_r)) `appOL`
unitOL (POPCNT II16 (OpReg src_r)
- (getRegisterReg False (CmmLocal dst)))
+ (getRegisterReg platform False (CmmLocal dst)))
else
unitOL (POPCNT size (OpReg src_r)
- (getRegisterReg False (CmmLocal dst))))
+ (getRegisterReg platform False (CmmLocal dst))))
else do
- dflags <- getDynFlags
targetExpr <- cmmMakeDynamicReference dflags addImportNat
CallReference lbl
let target = CmmCallee targetExpr CCallConv
@@ -1624,8 +1638,10 @@ genCCall32 :: CmmCallTarget -- function to call
-> [HintedCmmFormal] -- where to put the result
-> [HintedCmmActual] -- arguments (of mixed type)
-> NatM InstrBlock
-genCCall32 target dest_regs args =
- case (target, dest_regs) of
+genCCall32 target dest_regs args = do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ case (target, dest_regs) of
-- void return type prim op
(CmmPrim op _, []) ->
outOfLineCmmOp op Nothing args
@@ -1656,23 +1672,23 @@ genCCall32 target dest_regs args =
actuallyInlineFloatOp instr size [CmmHinted x _]
= do res <- trivialUFCode size (instr size) x
any <- anyReg res
- return (any (getRegisterReg False (CmmLocal r)))
+ return (any (getRegisterReg platform False (CmmLocal r)))
actuallyInlineFloatOp _ _ args
= panic $ "genCCall32.actuallyInlineFloatOp: bad number of arguments! ("
++ show (length args) ++ ")"
- (CmmPrim (MO_S_QuotRem width) _, _) -> divOp1 True width dest_regs args
- (CmmPrim (MO_U_QuotRem width) _, _) -> divOp1 False width dest_regs args
- (CmmPrim (MO_U_QuotRem2 width) _, _) -> divOp2 False width dest_regs args
+ (CmmPrim (MO_S_QuotRem width) _, _) -> divOp1 platform True width dest_regs args
+ (CmmPrim (MO_U_QuotRem width) _, _) -> divOp1 platform False width dest_regs args
+ (CmmPrim (MO_U_QuotRem2 width) _, _) -> divOp2 platform False width dest_regs args
(CmmPrim (MO_Add2 width) _, [CmmHinted res_h _, CmmHinted res_l _]) ->
case args of
[CmmHinted arg_x _, CmmHinted arg_y _] ->
do hCode <- getAnyReg (CmmLit (CmmInt 0 width))
lCode <- getAnyReg (CmmMachOp (MO_Add width) [arg_x, arg_y])
let size = intSize width
- reg_l = getRegisterReg True (CmmLocal res_l)
- reg_h = getRegisterReg True (CmmLocal res_h)
+ reg_l = getRegisterReg platform True (CmmLocal res_l)
+ reg_h = getRegisterReg platform True (CmmLocal res_h)
code = hCode reg_h `appOL`
lCode reg_l `snocOL`
ADC size (OpImm (ImmInteger 0)) (OpReg reg_h)
@@ -1684,8 +1700,8 @@ genCCall32 target dest_regs args =
do (y_reg, y_code) <- getRegOrMem arg_y
x_code <- getAnyReg arg_x
let size = intSize width
- reg_h = getRegisterReg True (CmmLocal res_h)
- reg_l = getRegisterReg True (CmmLocal res_l)
+ reg_h = getRegisterReg platform True (CmmLocal res_h)
+ reg_l = getRegisterReg platform True (CmmLocal res_l)
code = y_code `appOL`
x_code rax `appOL`
toOL [MUL2 size y_reg,
@@ -1699,21 +1715,21 @@ genCCall32 target dest_regs args =
_ -> genCCall32' target dest_regs args
- where divOp1 signed width results [CmmHinted arg_x _, CmmHinted arg_y _]
- = divOp signed width results Nothing arg_x arg_y
- divOp1 _ _ _ _
+ where divOp1 platform signed width results [CmmHinted arg_x _, CmmHinted arg_y _]
+ = divOp platform signed width results Nothing arg_x arg_y
+ divOp1 _ _ _ _ _
= panic "genCCall32: Wrong number of arguments for divOp1"
- divOp2 signed width results [CmmHinted arg_x_high _,
- CmmHinted arg_x_low _,
- CmmHinted arg_y _]
- = divOp signed width results (Just arg_x_high) arg_x_low arg_y
- divOp2 _ _ _ _
+ divOp2 platform signed width results [CmmHinted arg_x_high _,
+ CmmHinted arg_x_low _,
+ CmmHinted arg_y _]
+ = divOp platform signed width results (Just arg_x_high) arg_x_low arg_y
+ divOp2 _ _ _ _ _
= panic "genCCall64: Wrong number of arguments for divOp2"
- divOp signed width [CmmHinted res_q _, CmmHinted res_r _]
- m_arg_x_high arg_x_low arg_y
+ divOp platform signed width [CmmHinted res_q _, CmmHinted res_r _]
+ m_arg_x_high arg_x_low arg_y
= do let size = intSize width
- reg_q = getRegisterReg True (CmmLocal res_q)
- reg_r = getRegisterReg True (CmmLocal res_r)
+ reg_q = getRegisterReg platform True (CmmLocal res_q)
+ reg_r = getRegisterReg platform True (CmmLocal res_r)
widen | signed = CLTD size
| otherwise = XOR size (OpReg rdx) (OpReg rdx)
instr | signed = IDIV
@@ -1731,7 +1747,7 @@ genCCall32 target dest_regs args =
toOL [instr size y_reg,
MOV size (OpReg rax) (OpReg reg_q),
MOV size (OpReg rdx) (OpReg reg_r)]
- divOp _ _ _ _ _ _
+ divOp _ _ _ _ _ _ _
= panic "genCCall32: Wrong number of results for divOp"
genCCall32' :: CmmCallTarget -- function to call
@@ -1795,6 +1811,9 @@ genCCall32' target dest_regs args = do
)
setDeltaNat delta0
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+
let
-- assign the results, if necessary
assign_code [] = nilOL
@@ -1820,7 +1839,7 @@ genCCall32' target dest_regs args = do
w = typeWidth ty
b = widthInBytes w
r_dest_hi = getHiVRegFromLo r_dest
- r_dest = getRegisterReg use_sse2 (CmmLocal dest)
+ r_dest = getRegisterReg platform use_sse2 (CmmLocal dest)
assign_code many = pprPanic "genCCall.assign_code - too many return values:" (ppr many)
return (push_code `appOL`
@@ -1884,8 +1903,10 @@ genCCall64 :: CmmCallTarget -- function to call
-> [HintedCmmFormal] -- where to put the result
-> [HintedCmmActual] -- arguments (of mixed type)
-> NatM InstrBlock
-genCCall64 target dest_regs args =
- case (target, dest_regs) of
+genCCall64 target dest_regs args = do
+ dflags <- getDynFlags
+ let platform = targetPlatform dflags
+ case (target, dest_regs) of
(CmmPrim op _, []) ->
-- void return type prim op
@@ -1895,17 +1916,17 @@ genCCall64 target dest_regs args =
-- we only cope with a single result for foreign calls
outOfLineCmmOp op (Just res) args
- (CmmPrim (MO_S_QuotRem width) _, _) -> divOp1 True width dest_regs args
- (CmmPrim (MO_U_QuotRem width) _, _) -> divOp1 False width dest_regs args
- (CmmPrim (MO_U_QuotRem2 width) _, _) -> divOp2 False width dest_regs args
+ (CmmPrim (MO_S_QuotRem width) _, _) -> divOp1 platform True width dest_regs args
+ (CmmPrim (MO_U_QuotRem width) _, _) -> divOp1 platform False width dest_regs args
+ (CmmPrim (MO_U_QuotRem2 width) _, _) -> divOp2 platform False width dest_regs args
(CmmPrim (MO_Add2 width) _, [CmmHinted res_h _, CmmHinted res_l _]) ->
case args of
[CmmHinted arg_x _, CmmHinted arg_y _] ->
do hCode <- getAnyReg (CmmLit (CmmInt 0 width))
lCode <- getAnyReg (CmmMachOp (MO_Add width) [arg_x, arg_y])
let size = intSize width
- reg_l = getRegisterReg True (CmmLocal res_l)
- reg_h = getRegisterReg True (CmmLocal res_h)
+ reg_l = getRegisterReg platform True (CmmLocal res_l)
+ reg_h = getRegisterReg platform True (CmmLocal res_h)
code = hCode reg_h `appOL`
lCode reg_l `snocOL`
ADC size (OpImm (ImmInteger 0)) (OpReg reg_h)
@@ -1917,8 +1938,8 @@ genCCall64 target dest_regs args =
do (y_reg, y_code) <- getRegOrMem arg_y
x_code <- getAnyReg arg_x
let size = intSize width
- reg_h = getRegisterReg True (CmmLocal res_h)
- reg_l = getRegisterReg True (CmmLocal res_l)
+ reg_h = getRegisterReg platform True (CmmLocal res_h)
+ reg_l = getRegisterReg platform True (CmmLocal res_l)
code = y_code `appOL`
x_code rax `appOL`
toOL [MUL2 size y_reg,
@@ -1935,21 +1956,21 @@ genCCall64 target dest_regs args =
let platform = targetPlatform dflags
genCCall64' platform target dest_regs args
- where divOp1 signed width results [CmmHinted arg_x _, CmmHinted arg_y _]
- = divOp signed width results Nothing arg_x arg_y
- divOp1 _ _ _ _
+ where divOp1 platform signed width results [CmmHinted arg_x _, CmmHinted arg_y _]
+ = divOp platform signed width results Nothing arg_x arg_y
+ divOp1 _ _ _ _ _
= panic "genCCall64: Wrong number of arguments for divOp1"
- divOp2 signed width results [CmmHinted arg_x_high _,
- CmmHinted arg_x_low _,
- CmmHinted arg_y _]
- = divOp signed width results (Just arg_x_high) arg_x_low arg_y
- divOp2 _ _ _ _
+ divOp2 platform signed width results [CmmHinted arg_x_high _,
+ CmmHinted arg_x_low _,
+ CmmHinted arg_y _]
+ = divOp platform signed width results (Just arg_x_high) arg_x_low arg_y
+ divOp2 _ _ _ _ _
= panic "genCCall64: Wrong number of arguments for divOp2"
- divOp signed width [CmmHinted res_q _, CmmHinted res_r _]
- m_arg_x_high arg_x_low arg_y
+ divOp platform signed width [CmmHinted res_q _, CmmHinted res_r _]
+ m_arg_x_high arg_x_low arg_y
= do let size = intSize width
- reg_q = getRegisterReg True (CmmLocal res_q)
- reg_r = getRegisterReg True (CmmLocal res_r)
+ reg_q = getRegisterReg platform True (CmmLocal res_q)
+ reg_r = getRegisterReg platform True (CmmLocal res_r)
widen | signed = CLTD size
| otherwise = XOR size (OpReg rdx) (OpReg rdx)
instr | signed = IDIV
@@ -1965,7 +1986,7 @@ genCCall64 target dest_regs args =
toOL [instr size y_reg,
MOV size (OpReg rax) (OpReg reg_q),
MOV size (OpReg rdx) (OpReg reg_r)]
- divOp _ _ _ _ _ _
+ divOp _ _ _ _ _ _ _
= panic "genCCall64: Wrong number of results for divOp"
genCCall64' :: Platform
@@ -2065,7 +2086,7 @@ genCCall64' platform target dest_regs args = do
_ -> unitOL (MOV (cmmTypeSize rep) (OpReg rax) (OpReg r_dest))
where
rep = localRegType dest
- r_dest = getRegisterReg True (CmmLocal dest)
+ r_dest = getRegisterReg platform True (CmmLocal dest)
assign_code _many = panic "genCCall.assign_code many"
return (load_args_code `appOL`
diff --git a/compiler/nativeGen/X86/Instr.hs b/compiler/nativeGen/X86/Instr.hs
index 91d6ae4479..a2263b3116 100644
--- a/compiler/nativeGen/X86/Instr.hs
+++ b/compiler/nativeGen/X86/Instr.hs
@@ -24,6 +24,7 @@ import Reg
import TargetReg
import BlockId
+import CodeGen.Platform
import OldCmm
import FastString
import FastBool
@@ -449,16 +450,16 @@ x86_regUsageOfInstr platform instr
use_index (EAIndex i _) tl = i : tl
mkRUR src = src' `seq` RU src' []
- where src' = filter interesting src
+ where src' = filter (interesting platform) src
mkRU src dst = src' `seq` dst' `seq` RU src' dst'
- where src' = filter interesting src
- dst' = filter interesting dst
+ where src' = filter (interesting platform) src
+ dst' = filter (interesting platform) dst
-interesting :: Reg -> Bool
-interesting (RegVirtual _) = True
-interesting (RegReal (RealRegSingle i)) = isFastTrue (freeReg i)
-interesting (RegReal (RealRegPair{})) = panic "X86.interesting: no reg pairs on this arch"
+interesting :: Platform -> Reg -> Bool
+interesting _ (RegVirtual _) = True
+interesting platform (RegReal (RealRegSingle i)) = isFastTrue (freeReg platform i)
+interesting _ (RegReal (RealRegPair{})) = panic "X86.interesting: no reg pairs on this arch"
@@ -709,11 +710,10 @@ x86_mkRegRegMoveInstr
x86_mkRegRegMoveInstr platform src dst
= case targetClassOfReg platform src of
-#if i386_TARGET_ARCH
- RcInteger -> MOV II32 (OpReg src) (OpReg dst)
-#else
- RcInteger -> MOV II64 (OpReg src) (OpReg dst)
-#endif
+ RcInteger -> case platformArch platform of
+ ArchX86 -> MOV II32 (OpReg src) (OpReg dst)
+ ArchX86_64 -> MOV II64 (OpReg src) (OpReg dst)
+ _ -> panic "x86_mkRegRegMoveInstr: Bad arch"
RcDouble -> GMOV src dst
RcDoubleSSE -> MOV FF64 (OpReg src) (OpReg dst)
_ -> panic "X86.RegInfo.mkRegRegMoveInstr: no match"
diff --git a/compiler/nativeGen/X86/Regs.hs b/compiler/nativeGen/X86/Regs.hs
index a53c4fcbf7..16938a8f15 100644
--- a/compiler/nativeGen/X86/Regs.hs
+++ b/compiler/nativeGen/X86/Regs.hs
@@ -39,10 +39,6 @@ module X86.Regs (
ripRel,
allFPArgRegs,
- -- horror show
- freeReg,
- globalRegMaybe,
-
allocatableRegs
)
@@ -51,19 +47,7 @@ where
#include "nativeGen/NCG.h"
#include "HsVersions.h"
-#if i386_TARGET_ARCH == 0 && x86_64_TARGET_ARCH == 0
--- Compiling for some arch other than Intel so we choose x86-64 as default.
-#undef arm_TARGET_ARCH
-#undef powerpc_TARGET_ARCH
-#undef powerpc64_TARGET_ARCH
-#undef sparc_TARGET_ARCH
-
-#undef x86_64_TARGET_ARCH
-#define x86_64_TARGET_ARCH 1
-#endif
-
-#include "../includes/stg/HaskellMachRegs.h"
-
+import CodeGen.Platform
import Reg
import RegClass
@@ -416,10 +400,6 @@ xmm n = regSingle (firstxmm+n)
--- horror show -----------------------------------------------------------------
-freeReg :: RegNo -> FastBool
-globalRegMaybe :: GlobalReg -> Maybe RealReg
-
-- | these are the regs which we cannot assume stay alive over a C call.
callClobberedRegs :: Platform -> [Reg]
-- caller-saves registers
@@ -457,203 +437,17 @@ instrClobberedRegs platform
| target32Bit platform = [ eax, ecx, edx ]
| otherwise = [ rax, rcx, rdx ]
-#if i386_TARGET_ARCH
-#define eax 0
-#define ebx 1
-#define ecx 2
-#define edx 3
-#define esi 4
-#define edi 5
-#define ebp 6
-#define esp 7
-#endif
-
-#if x86_64_TARGET_ARCH
-#define rax 0
-#define rbx 1
-#define rcx 2
-#define rdx 3
-#define rsi 4
-#define rdi 5
-#define rbp 6
-#define rsp 7
-#define r8 8
-#define r9 9
-#define r10 10
-#define r11 11
-#define r12 12
-#define r13 13
-#define r14 14
-#define r15 15
-#endif
-
-#define fake0 16
-#define fake1 17
-#define fake2 18
-#define fake3 19
-#define fake4 20
-#define fake5 21
-
-#define xmm0 24
-#define xmm1 25
-#define xmm2 26
-#define xmm3 27
-#define xmm4 28
-#define xmm5 29
-#define xmm6 30
-#define xmm7 31
-#define xmm8 32
-#define xmm9 33
-#define xmm10 34
-#define xmm11 35
-#define xmm12 36
-#define xmm13 37
-#define xmm14 38
-#define xmm15 39
-
-#if i386_TARGET_ARCH
-freeReg esp = fastBool False -- %esp is the C stack pointer
-#endif
-
-#if i386_TARGET_ARCH
-freeReg esi = fastBool False -- Note [esi/edi not allocatable]
-freeReg edi = fastBool False
-#endif
-
-#if x86_64_TARGET_ARCH
-freeReg rsp = fastBool False -- %rsp is the C stack pointer
-#endif
-
--- split patterns in two functions to prevent overlaps
-freeReg r = freeRegBase r
-
-freeRegBase :: RegNo -> FastBool
-
-#ifdef REG_Base
-freeRegBase REG_Base = fastBool False
-#endif
-#ifdef REG_Sp
-freeRegBase REG_Sp = fastBool False
-#endif
-#ifdef REG_SpLim
-freeRegBase REG_SpLim = fastBool False
-#endif
-#ifdef REG_Hp
-freeRegBase REG_Hp = fastBool False
-#endif
-#ifdef REG_HpLim
-freeRegBase REG_HpLim = fastBool False
-#endif
-
--- All other regs are considered to be "free", because we can track
--- their liveness accurately.
-freeRegBase _ = fastBool True
-
--- | Returns 'Nothing' if this global register is not stored
--- in a real machine register, otherwise returns @'Just' reg@, where
--- reg is the machine register it is stored in.
-
-#ifdef REG_Base
-globalRegMaybe BaseReg = Just (RealRegSingle REG_Base)
-#endif
-#ifdef REG_R1
-globalRegMaybe (VanillaReg 1 _) = Just (RealRegSingle REG_R1)
-#endif
-#ifdef REG_R2
-globalRegMaybe (VanillaReg 2 _) = Just (RealRegSingle REG_R2)
-#endif
-#ifdef REG_R3
-globalRegMaybe (VanillaReg 3 _) = Just (RealRegSingle REG_R3)
-#endif
-#ifdef REG_R4
-globalRegMaybe (VanillaReg 4 _) = Just (RealRegSingle REG_R4)
-#endif
-#ifdef REG_R5
-globalRegMaybe (VanillaReg 5 _) = Just (RealRegSingle REG_R5)
-#endif
-#ifdef REG_R6
-globalRegMaybe (VanillaReg 6 _) = Just (RealRegSingle REG_R6)
-#endif
-#ifdef REG_R7
-globalRegMaybe (VanillaReg 7 _) = Just (RealRegSingle REG_R7)
-#endif
-#ifdef REG_R8
-globalRegMaybe (VanillaReg 8 _) = Just (RealRegSingle REG_R8)
-#endif
-#ifdef REG_R9
-globalRegMaybe (VanillaReg 9 _) = Just (RealRegSingle REG_R9)
-#endif
-#ifdef REG_R10
-globalRegMaybe (VanillaReg 10 _) = Just (RealRegSingle REG_R10)
-#endif
-#ifdef REG_F1
-globalRegMaybe (FloatReg 1) = Just (RealRegSingle REG_F1)
-#endif
-#ifdef REG_F2
-globalRegMaybe (FloatReg 2) = Just (RealRegSingle REG_F2)
-#endif
-#ifdef REG_F3
-globalRegMaybe (FloatReg 3) = Just (RealRegSingle REG_F3)
-#endif
-#ifdef REG_F4
-globalRegMaybe (FloatReg 4) = Just (RealRegSingle REG_F4)
-#endif
-#ifdef REG_D1
-globalRegMaybe (DoubleReg 1) = Just (RealRegSingle REG_D1)
-#endif
-#ifdef REG_D2
-globalRegMaybe (DoubleReg 2) = Just (RealRegSingle REG_D2)
-#endif
-#ifdef REG_Sp
-globalRegMaybe Sp = Just (RealRegSingle REG_Sp)
-#endif
-#ifdef REG_Lng1
-globalRegMaybe (LongReg 1) = Just (RealRegSingle REG_Lng1)
-#endif
-#ifdef REG_Lng2
-globalRegMaybe (LongReg 2) = Just (RealRegSingle REG_Lng2)
-#endif
-#ifdef REG_SpLim
-globalRegMaybe SpLim = Just (RealRegSingle REG_SpLim)
-#endif
-#ifdef REG_Hp
-globalRegMaybe Hp = Just (RealRegSingle REG_Hp)
-#endif
-#ifdef REG_HpLim
-globalRegMaybe HpLim = Just (RealRegSingle REG_HpLim)
-#endif
-#ifdef REG_CurrentTSO
-globalRegMaybe CurrentTSO = Just (RealRegSingle REG_CurrentTSO)
-#endif
-#ifdef REG_CurrentNursery
-globalRegMaybe CurrentNursery = Just (RealRegSingle REG_CurrentNursery)
-#endif
-globalRegMaybe _ = Nothing
-
--
-- All machine registers that are used for argument-passing to Haskell functions
-allHaskellArgRegs :: [Reg]
-allHaskellArgRegs = [ RegReal r | Just r <- map globalRegMaybe globalArgRegs ]
+allHaskellArgRegs :: Platform -> [Reg]
+allHaskellArgRegs platform = [ RegReal r | Just r <- map (globalRegMaybe platform) globalArgRegs ]
-- allocatableRegs is allMachRegNos with the fixed-use regs removed.
-- i.e., these are the regs for which we are prepared to allow the
-- register allocator to attempt to map VRegs to.
allocatableRegs :: Platform -> [RealReg]
allocatableRegs platform
- = let isFree i = isFastTrue (freeReg i)
+ = let isFree i = isFastTrue (freeReg platform i)
in map RealRegSingle $ filter isFree (allMachRegNos platform)
-{-
-Note [esi/edi not allocatable]
-
-%esi is mapped to R1, so %esi would normally be allocatable while it
-is not being used for R1. However, %esi has no 8-bit version on x86,
-and the linear register allocator is not sophisticated enough to
-handle this irregularity (we need more RegClasses). The
-graph-colouring allocator also cannot handle this - it was designed
-with more flexibility in mind, but the current implementation is
-restricted to the same set of classes as the linear allocator.
-
-Hence, on x86 esi and edi are treated as not allocatable.
--}
diff --git a/compiler/utils/Util.lhs b/compiler/utils/Util.lhs
index 9d12946052..87171545f8 100644
--- a/compiler/utils/Util.lhs
+++ b/compiler/utils/Util.lhs
@@ -10,7 +10,7 @@ module Util (
-- * Flags dependent on the compiler build
ghciSupported, debugIsOn, ncgDebugIsOn,
ghciTablesNextToCode, isDynamicGhcLib,
- isWindowsHost, isWindowsTarget, isDarwinTarget,
+ isWindowsHost, isDarwinHost,
-- * General list processing
zipEqual, zipWithEqual, zipWith3Equal, zipWith4Equal,
@@ -192,18 +192,11 @@ isWindowsHost = True
isWindowsHost = False
#endif
-isWindowsTarget :: Bool
-#ifdef mingw32_TARGET_OS
-isWindowsTarget = True
+isDarwinHost :: Bool
+#ifdef darwin_HOST_OS
+isDarwinHost = True
#else
-isWindowsTarget = False
-#endif
-
-isDarwinTarget :: Bool
-#ifdef darwin_TARGET_OS
-isDarwinTarget = True
-#else
-isDarwinTarget = False
+isDarwinHost = False
#endif
\end{code}