97a92bb27f2a7ae81904aef7610999c210c0998a
[ghc-hetmet.git] / ghc / compiler / absCSyn / CallConv.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 \section[Calling conventions]{External calling conventions}
5
6 \begin{code}
7 module CallConv
8        (
9          CallConv
10        , pprCallConv
11
12        , stdCallConv
13        , cCallConv
14        , defaultCallConv
15        , callConvAttribute
16        , decorateExtName
17        ) where
18
19 #include "HsVersions.h"
20
21 import Outputable
22 import PrimRep     ( PrimRep, getPrimRepSizeInBytes )
23 \end{code}
24
25 \begin{code}
26 type CallConv = Int
27
28 pprCallConv :: CallConv -> SDoc
29 pprCallConv 0 = ptext SLIT("_stdcall")
30 pprCallConv _ = ptext SLIT("_ccall")
31
32 stdCallConv :: CallConv
33 stdCallConv = 0
34
35 cCallConv  :: CallConv
36 cCallConv = 1
37
38 defaultCallConv :: CallConv
39 defaultCallConv = cCallConv
40 \end{code}
41
42 Generate the gcc attribute corresponding to the given
43 calling convention (used by PprAbsC):
44
45 ToDo: The stdcall calling convention is x86 (win32) specific,
46 so perhaps we should emit a warning if it's being used on other
47 platforms.
48
49 \begin{code}
50 callConvAttribute :: CallConv -> String
51 callConvAttribute cc
52  | cc == stdCallConv   = "__attribute__((stdcall))"
53  | cc == cCallConv     = ""
54  | otherwise           = panic ("callConvAttribute: cannot handle" ++ showSDoc (pprCallConv cc))
55
56 \end{code}
57
58 For stdcall and Win32, the linker expects to see names of the form 
59  
60    "f@n"
61
62 where n is the size (in 8-bit bytes) of the parameter area
63 that is pushed onto the stack before invocation. We take
64 care of mangling the function name here. 
65
66 This name mangler is only used by the x86 native code generator.
67
68 \begin{code}
69 decorateExtName :: CallConv -> FAST_STRING -> [PrimRep] -> FAST_STRING
70 decorateExtName cc fs ps
71 {- ifdef COMPILING_WIN32 -}
72  | cc /= stdCallConv = fs
73  | otherwise         = fs _APPEND_ (_PK_ ('@':show (size::Int)))
74 {- else
75  = fs
76 -}
77  where
78   size = sum (map (adjustParamSize.getPrimRepSizeInBytes) ps)
79
80   adjustParamSize sz =  paramBoundary * ((sz + paramBoundary - 1) `div` paramBoundary)
81
82   paramBoundary = 4
83
84 \end{code}