1 |
signature X86STACKSPILLS = sig |
signature X86STACKSPILLS = sig |
2 |
structure I : X86INSTR |
structure I : X86INSTR |
3 |
val init : unit -> unit |
val init : unit -> unit |
4 |
|
val setAvailableOffsets : I.operand list -> unit |
5 |
val getRegLoc : int -> I.operand |
val getRegLoc : int -> I.operand |
6 |
val getFregLoc : int -> I.operand |
val getFregLoc : int -> I.operand |
7 |
end |
end |
11 |
exception RegSpills |
exception RegSpills |
12 |
structure I = X86Instr |
structure I = X86Instr |
13 |
|
|
14 |
fun error msg = ErrorMsg.impossible ("X86CG." ^ msg) |
fun error msg = ErrorMsg.impossible ("X86StackSpills." ^ msg) |
15 |
|
|
16 |
val initialSpillOffset = X86Runtime.spillStart |
val initialSpillOffset = X86Runtime.spillStart |
17 |
val spillOffset = ref initialSpillOffset |
val spillOffset = ref initialSpillOffset |
18 |
val spillAreaSz = X86Runtime.spillAreaSz |
val spillAreaSz = X86Runtime.spillAreaSz |
19 |
|
val availableOffsets = ref [] : I.operand list ref |
20 |
|
|
21 |
|
(* Indicate that memory some memory registers are not used and |
22 |
|
* can be used for spilling. |
23 |
|
*) |
24 |
|
fun setAvailableOffsets offsets = availableOffsets := offsets |
25 |
|
|
26 |
fun newOffset n = |
fun newOffset n = |
27 |
if (n > spillAreaSz) then error "newOffset - spill area is too small" |
if (n > spillAreaSz) then error "newOffset - spill area is too small" |
28 |
else spillOffset := n |
else spillOffset := n |
29 |
|
|
30 |
val spillTbl : Int32.int Intmap.intmap ref = ref(Intmap.new(0, RegSpills)) |
val spillTbl : I.operand Intmap.intmap = Intmap.new(0, RegSpills) |
31 |
|
val lookupTbl = Intmap.map spillTbl |
32 |
|
val addTbl = Intmap.add spillTbl |
33 |
|
|
34 |
fun init () = |
fun init () = |
35 |
(spillOffset:=initialSpillOffset; |
(spillOffset:=initialSpillOffset; |
36 |
spillTbl:=Intmap.new(16, RegSpills)) |
availableOffsets := []; |
37 |
|
Intmap.clear spillTbl |
38 |
|
) |
39 |
|
|
40 |
val toInt32 = Int32.fromInt |
val toInt32 = Int32.fromInt |
41 |
|
|
42 |
fun getRegLoc (reg:int) = let |
fun getRegLoc (reg:int) = |
43 |
val tbl = !spillTbl |
lookupTbl reg |
44 |
in |
handle _ => |
45 |
I.Immed |
let val operand = |
46 |
(Intmap.map tbl reg |
case !availableOffsets of |
47 |
handle RegSpills => let |
[] => let val offset = !spillOffset |
|
val offset = !spillOffset |
|
48 |
val i32 = toInt32 offset |
val i32 = toInt32 offset |
49 |
in |
in newOffset(offset+4); I.Immed i32 end |
50 |
newOffset(offset+4); |
| off::offs => (availableOffsets := offs; off) |
51 |
Intmap.add tbl (reg,i32); |
in addTbl (reg,operand); |
52 |
i32 |
operand |
|
end) |
|
53 |
end |
end |
54 |
|
|
55 |
fun getFregLoc freg = let |
fun getFregLoc freg = |
56 |
val tbl = !spillTbl |
lookupTbl freg |
57 |
in |
handle _ => |
58 |
I.Immed |
let val offset = !spillOffset |
|
(Intmap.map tbl freg |
|
|
handle RegSpills => let |
|
|
val offset = !spillOffset |
|
59 |
val fromInt = Word.fromInt |
val fromInt = Word.fromInt |
60 |
val aligned = Word.toIntX(Word.andb(fromInt offset+0w7, fromInt ~8)) |
val aligned = Word.toIntX(Word.andb(fromInt offset+0w7, fromInt ~8)) |
61 |
val i32 = toInt32 aligned |
val operand = I.Immed(toInt32 aligned) |
62 |
in |
in newOffset(aligned+8); |
63 |
newOffset(aligned+8); |
addTbl (freg, operand); |
64 |
Intmap.add tbl (freg, i32); |
operand |
|
i32 |
|
|
end) |
|
65 |
end |
end |
66 |
end |
end |