-
Wilke Pierre authoredWilke Pierre authored
ltl.ml 3.83 KiB
open Batteries
open BatList
open BatBuffer
open Elang
open Rtl
open Regalloc
open Linear
open Linear_liveness
open Prog
open Utils
(* LTL/Risc-V registers *)
type ltl_reg = int
let reg_zero = 0
let reg_ra = 1
let reg_sp = 2
let reg_gp = 3
let reg_tp = 4
let reg_t0 = 5
let reg_t1 = 6
let reg_t2 = 7
let reg_s0 = 8
let reg_s1 = 9
let reg_a0 = 10
let reg_a1 = 11
let reg_a2 = 12
let reg_a3 = 13
let reg_a4 = 14
let reg_a5 = 15
let reg_a6 = 16
let reg_a7 = 17
let reg_s2 = 18
let reg_s3 = 19
let reg_s4 = 20
let reg_s5 = 21
let reg_s6 = 22
let reg_s7 = 23
let reg_s8 = 24
let reg_s9 = 25
let reg_s10 = 26
let reg_s11 = 27
let reg_t3 = 28
let reg_t4 = 29
let reg_t5 = 30
let reg_t6 = 31
let reg_tmp = [reg_t0; reg_t1; reg_t2; reg_t3; reg_t4; reg_t5; reg_t6]
let reg_tmp1 = reg_t0
let reg_tmp2 = reg_t1
let reg_fp = reg_s0
let reg_ret = reg_a0
type ltl_instr =
LAddi of ltl_reg * ltl_reg * int
| LSubi of ltl_reg * ltl_reg * int
| LStore of ltl_reg * int * ltl_reg * int (* LStore(rd, rofs, rs, sz) : store
value in [rs] on [sz] bytes at
address [rd+rofs] *)
| LLoad of ltl_reg * ltl_reg * int * int (* LLoad(rd, rs, rofs, sz) : load
value at address [rs+rofs] on [sz]
bytes in register [rd]. *)
| LMov of ltl_reg * ltl_reg (* LMov(rd, rs) : move value of [rs] into [rd].
*)
| LLabel of string
| LJmp of string
| LBinop of binop * ltl_reg * ltl_reg * ltl_reg (* LBinop(b, rd, rs1, rs2) :
performs binary operation
[b] on values in registers
[rs1] and [rs2]. Stores the
result in [rd]. *)
| LUnop of unop * ltl_reg * ltl_reg (* LUnop(u,rd,rs) : performs unary
operation [u] on register [rs]. Stores
the result in [rd]. *)
| LConst of ltl_reg * int (* LConst(rd,i) : load immediate value [i] in
register [rd]. *)
| LComment of string
| LCall of string (* LCall(f) : calls function [f]. *)
| LBranch of rtl_cmp * ltl_reg * ltl_reg * string (* LBranch(cmp, rs1, rs2,
label): compares [rs1]
and [rs2] according to
comparison [cmp]. If
true, jump to [label]. *)
| LJmpr of ltl_reg (* LJmpr(r) : jumps to address in [r]. *)
| LHalt (* Stops the program. *)
(* An LTL function is essentially a list of instructions (field [ltlfunbody]).
The other fields are mainly here for debugging and statistics :
- [ltlfunargs] gives the number of arguments that the function takes;
- [ltlfuninfo] is a mapping from source variable names to the RTL register
they're allocated in;
- [ltlregalloc] is a mapping from RTL registers to LTL locations.
*)
type ltl_fun =
{ ltlfunargs: int;
ltlfunbody: ltl_instr list;
ltlfuninfo: (string*reg) list;
ltlregalloc: (reg*loc) list;
}
(* Lists of caller-save and callee-save registers *)
let caller_saved = [
reg_a0; reg_a1; reg_a2; reg_a3; reg_a4; reg_a5; reg_a6; reg_a7;
reg_t0; reg_t1; reg_t2; reg_t3; reg_t4; reg_t5; reg_t6; reg_ra;
]
let callee_saved = [
reg_s0; reg_s1; reg_s2; reg_s3; reg_s4; reg_s5; reg_s6; reg_s7;
reg_s8; reg_s9; reg_s10; reg_s11; reg_sp; reg_ra
]
(* We pass 8 arguments in registers (a0-a7). *)
let number_of_arguments_passed_in_registers = 8
let starting_arg_register = reg_a0