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