-
Wilke Pierre authoredWilke Pierre authored
ltl_gen.ml 15.90 KiB
open Batteries
open Rtl
open Linear
open Ltl
open Ltl_print
open Prog
open Utils
open Regalloc
open Linear_liveness
(* list of registers used to store arguments. [a0-a7] *)
let arg_registers =
range ~start:starting_arg_register 8
(* Helpers to build pseudo-instructions.
** [push x] is compiled into [sub sp, sp, 8; sd r, 0(sp)]
** [pop x] is compiled into [ld r, 0(sp); add sp, sp, 8]
*)
let make_push r =
[LSubi(reg_sp, reg_sp, !Archi.wordsize);
LStore(reg_sp, 0, r, !Archi.wordsize)]
let make_pop r =
[LLoad(r, reg_sp, 0, !Archi.wordsize);
LAddi(reg_sp, reg_sp, !Archi.wordsize)]
let make_sp_sub v =
[LSubi(reg_sp, reg_sp, v)]
let make_sp_add v =
[LAddi(reg_sp, reg_sp, v)]
(* Moving between locations. [src] and [dst] are locations. [make_loc_mov src
dst] generates instructions so that the value in [src] ends up in [dst],
where [src] and [dst] can be registers [Reg r] or stack offsets [Stk o].
*)
let make_loc_mov src dst =
match src, dst with
| Stk osrc , Stk odst ->
let rtmp = reg_tmp1 in
[LLoad(rtmp, reg_fp, !Archi.wordsize * osrc, !Archi.wordsize);
LStore(reg_fp, !Archi.wordsize * odst, rtmp, !Archi.wordsize)]
| Stk osrc, Reg rdst ->
[LLoad(rdst, reg_fp, !Archi.wordsize * osrc, !Archi.wordsize)]
| Reg rsrc, Stk ofst ->
[LStore(reg_fp, !Archi.wordsize * ofst, rsrc, !Archi.wordsize)]
| Reg rsrc, Reg rdst ->
[LMov(rdst,rsrc)]
(* load_loc tmp allocation r = (l, r'). Loads the equivalent of RTL register r
in a LTL register r'. tmpis used if necessary. *)
let load_loc tmp allocation r =
match Hashtbl.find_option allocation r with
| None ->
Error (Format.sprintf "Unable to allocate RTL register r%d." r)
| Some (Stk o) -> OK ([LLoad(tmp, reg_fp, !Archi.wordsize * o, !Archi.wordsize)], tmp)
| Some (Reg r) -> OK ([], r)
(* store_loc tmp allocation r = (l, r'). I want to write in RTL register r.
Tells me that I just have to write to LTL register r' and execute l. *)
let store_loc tmp allocation r =
match Hashtbl.find_option allocation r with
| None ->
Error (Format.sprintf "Unable to allocate RTL register r%d." r)
| Some (Stk o) -> OK ([LStore(reg_fp, !Archi.wordsize * o, tmp, !Archi.wordsize)], tmp)
| Some (Reg r) -> OK ([], r)
(* saves registers in [to_save] on the stack at offsets [fp + 8 * o, fp + 8 * (o
- 1), fp + 8 * (o - 2)...]. Returns: