106 |
val dblTy = 64 (* MLRISC type of double *) |
val dblTy = 64 (* MLRISC type of double *) |
107 |
|
|
108 |
(* stack pointer *) |
(* stack pointer *) |
109 |
val sp = C.GPReg 1 |
val spReg = T.REG(wordTy, C.GPReg 1) |
|
val spR = T.REG(wordTy, sp) |
|
110 |
|
|
111 |
(* registers used for parameter passing *) |
(* registers used for parameter passing *) |
112 |
val argGPRs = List.map C.GPReg [3, 4, 5, 6, 7, 8, 9, 10] |
val argGPRs = List.map C.GPReg [3, 4, 5, 6, 7, 8, 9, 10] |
113 |
val argFPRs = List.map C.FPReg [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] |
val argFPRs = List.map C.FPReg [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] |
114 |
val resRegLoc = Reg(wordTy, C.GPReg 3, NONE) |
val resGPR = C.GPReg 3 |
115 |
|
val resRegLoc = Reg(wordTy, resGPR, NONE) |
116 |
val resFPR = C.FPReg 1 |
val resFPR = C.FPReg 1 |
117 |
|
|
118 |
(* C callee-save registers *) |
(* C callee-save registers *) |
243 |
in { |
in { |
244 |
argLocs = assign (paramTys, 0, argGPRs, argFPRs, []), |
argLocs = assign (paramTys, 0, argGPRs, argFPRs, []), |
245 |
resLoc = resLoc, |
resLoc = resLoc, |
246 |
structRet = structRet |
structRetLoc = structRet |
247 |
} end |
} end |
248 |
|
|
249 |
datatype c_arg |
datatype c_arg |
255 |
val stkRg = T.Region.memory |
val stkRg = T.Region.memory |
256 |
|
|
257 |
(* SP-based address of parameter at given offset *) |
(* SP-based address of parameter at given offset *) |
258 |
fun paramAddr off = T.ADD(wordTy, spR, T.LI(off + IntInf.fromInt paramAreaOffset)) |
fun paramAddr off = |
259 |
|
T.ADD(wordTy, spReg, T.LI(off + IntInf.fromInt paramAreaOffset)) |
260 |
|
|
261 |
fun genCall { |
fun genCall { |
262 |
name, proto, paramAlloc, structRet, saveRestoreDedicated, |
name, proto, paramAlloc, structRet, saveRestoreDedicated, |
263 |
callComment, args |
callComment, args |
264 |
} = let |
} = let |
265 |
val {conv, retTy, paramTys} = proto |
val {conv, retTy, paramTys} = proto |
266 |
val {argLocs, resLoc, structRet} = layout proto |
val {argLocs, resLoc, structRetLoc} = layout proto |
267 |
(* generate code to assign the arguments to their locations *) |
(* generate code to assign the arguments to their locations *) |
268 |
fun assignArgs ([], [], stms) = stms |
fun assignArgs ([], [], stms) = stms |
269 |
| assignArgs (Reg(ty, r, _) :: locs, ARG exp :: args, stms) = |
| assignArgs (Reg(ty, r, _) :: locs, ARG exp :: args, stms) = |
285 |
| SOME(FReg(ty, r, _)) => [T.FPR(T.FREG(ty, r))] |
| SOME(FReg(ty, r, _)) => [T.FPR(T.FREG(ty, r))] |
286 |
| SOME _ => raise Fail "bogus result location" |
| SOME _ => raise Fail "bogus result location" |
287 |
(* end case *)) |
(* end case *)) |
288 |
|
(* make struct return-area setup (if necessary) *) |
289 |
|
val setupStructRet = (case structRetLoc |
290 |
|
of NONE => [] |
291 |
|
| SOME loc => let |
292 |
|
val structAddr = structRet loc |
293 |
|
in |
294 |
|
[T.MV(wordTy, resGPR, structAddr)] |
295 |
|
end |
296 |
|
(* end case *)) |
297 |
(* determine the registers used and defined by this call *) |
(* determine the registers used and defined by this call *) |
298 |
val (uses, defs) = let |
val (uses, defs) = let |
299 |
val locs = (case resLoc |
val locs = (case resLoc |
323 |
of NONE => callStm |
of NONE => callStm |
324 |
| SOME c => T.ANNOTATION(callStm, #create MLRiscAnnotations.COMMENT c) |
| SOME c => T.ANNOTATION(callStm, #create MLRiscAnnotations.COMMENT c) |
325 |
(* end case *)) |
(* end case *)) |
326 |
|
(* take care of dedicated client registers *) |
327 |
|
val {save, restore} = saveRestoreDedicated defs |
328 |
val callseq = List.concat [ |
val callseq = List.concat [ |
329 |
|
setupStructRet, |
330 |
argSetupCode, |
argSetupCode, |
331 |
[callStm] |
save, |
332 |
|
[callStm], |
333 |
|
restore |
334 |
] |
] |
335 |
in |
in |
336 |
(* check calling convention *) |
(* check calling convention *) |