1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
signature AMD64STACKSPILLS = sig
structure I : AMD64INSTR
val init : unit -> unit
(* FIXME: this should be removed *)
val setAvailableOffsets : I.operand list -> unit
val setAvailableFPOffsets : I.operand list -> unit
val getRegLoc : int -> I.operand
val getFregLoc : int -> I.operand
end
structure AMD64StackSpills : AMD64STACKSPILLS =
struct
exception RegSpills
structure I = AMD64Instr
fun error msg = ErrorMsg.impossible ("AMD64StackSpills." ^ msg)
val initialSpillOffset = AMD64Runtime.spillStart
val spillOffset = ref initialSpillOffset
val spillAreaSz = AMD64Runtime.spillAreaSz
val availableOffsets = ref [] : I.operand list ref
val availableFPOffsets = ref [] : I.operand list ref
(* Indicate that some memory registers are not used and
* can be used for spilling.
*)
fun setAvailableOffsets offsets = availableOffsets := offsets
fun setAvailableFPOffsets offsets = availableFPOffsets := offsets
fun newOffset n =
if (n > spillAreaSz) then error "newOffset - spill area is too small"
else spillOffset := n
val spillTbl : I.operand IntHashTable.hash_table =
IntHashTable.mkTable(0, RegSpills)
val lookupTbl = IntHashTable.lookup spillTbl
val addTbl = IntHashTable.insert spillTbl
fun init () =
(spillOffset:=initialSpillOffset;
availableOffsets := [];
availableFPOffsets := [];
IntHashTable.clear spillTbl
)
val toInt32 = Int32.fromInt
fun getRegLoc reg =
lookupTbl reg
handle _ =>
let val operand =
case !availableOffsets of
[] => let val offset = !spillOffset
val i32 = toInt32 offset
in newOffset(offset+4); I.Immed i32 end
| off::offs => (availableOffsets := offs; off)
in addTbl (reg,operand);
operand
end
fun getFregLoc freg =
lookupTbl freg
handle _ =>
let val operand =
case !availableFPOffsets of
[] =>
let val offset = !spillOffset
val fromInt = Word.fromInt
val aligned = Word.toIntX(Word.andb(fromInt offset+0w7, fromInt ~8))
in newOffset(aligned+8); I.Immed(toInt32 aligned)
end
| off::offs => (availableFPOffsets := offs; off)
in addTbl (freg, operand);
operand
end
end
|