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