6 let insts = [AST.IOp_notbool]
9 (* Adapted from Pottier's PP compiler *)
11 (* A machine word is 4 bytes. *)
16 (* The MIPS CPU contains 32 general-purpose 32-bit registers
17 that are numbered 0 to 31.
19 Register 0, known as [$0], always contains the hardwired value 0.
21 Register 1, known as [$at], is conventionally reserved for use by
22 the assembler for expanding certain pseudo-instructions into actual
23 hardware instructions. This means that we cannot use it.
25 Registers 2 and 3, known as [$v0] and [$v1], are normally used to
26 return values from functions. In our compiler, only [$v0] is used
27 for this purpose. We use [$v1] as a reserved register for spilling
28 and refer to it as [$st0].
30 Registers 4 to 7, known as [$a0] to [$a3], are used to pass the
31 first four arguments to functions. Remaining arguments are passed
34 Registers 8 to 15, 24 and 25, known as [$t0] to [$t9], are
35 caller-saved registers.
37 Registers 16 to 23, known as [$s0] to [$s7], are callee-saved
40 Registers 26 and 27, known as [$k0] and [$k1], are reserved for use
41 by the operating system kernel.
43 Register 28, known as [$gp] for global pointer, points into the
44 middle of a 64K block of memory in the heap that holds constants
47 Register 29, known as [$sp] for stack pointer, points to the last
48 location in use on the stack.
50 Register 30, known as [$fp] for frame pointer, is used in our
51 compiler as a reserved register for spilling. We refer to it as
54 Register 31, known as [$ra], contains the return address for the
55 current function. It is written by the [jal] instruction. *)
60 let equal : register -> register -> bool = (=)
62 module RegisterSet = struct
64 include Set.Make (struct
70 is_empty (inter s1 s2)
73 List.fold_right add rs empty
77 module RegisterMap = struct
79 include Map.Make (struct
85 RegisterSet.fold (fun x m ->
91 (* Naming convention. *)
96 let v0, v1, a0, a1, a2, a3 =
99 let t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 =
100 8, 9, 10, 11, 12, 13, 14, 15, 24, 25
102 let s0, s1, s2, s3, s4, s5, s6 =
103 16, 17, 18, 19, 20, 21, 22
184 let print2 r = string_of_int r
186 (* Calling convention. *)
195 RegisterSet.of_list (
196 [ v0; a0; a1; a2; a3; t0; t1; t2; t3; t4; t5; t6; t7; t8; t9; ra ]
200 RegisterSet.of_list (
201 [ s0; s1; s2; s3; s4; s5; s6 ]
205 (* The register [$zero] can be viewed as allocatable, but this requires building
206 ad hoc interference edges -- see [Build]. In TD7, in order to simplify things,
207 this register is made non-allocatable. *)
208 RegisterSet.add zero (RegisterSet.union caller_saved callee_saved)
211 RegisterSet.union allocatable
212 (RegisterSet.of_list [ gp_mips; gp_gnu; sp; st0; st1 ])