]> matita.cs.unibo.it Git - pkg-cerco/acc.git/blob - src/ASM/MIPS.ml
first version of the package
[pkg-cerco/acc.git] / src / ASM / MIPS.ml
1
2 let int_size = 4
3 let ptr_size = 4
4 let alignment = Some 4
5
6 let insts = [AST.IOp_notbool]
7
8 (*
9 (* Adapted from Pottier's PP compiler *)
10
11 (* A machine word is 4 bytes. *)
12
13 let word =
14   4l
15
16 (* The MIPS CPU contains 32 general-purpose 32-bit registers
17    that are numbered 0 to 31.
18
19    Register 0, known as [$0], always contains the hardwired value 0.
20
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.
24
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].
29
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
32    on the stack.
33
34    Registers 8 to 15, 24 and 25, known as [$t0] to [$t9], are
35    caller-saved registers.
36
37    Registers 16 to 23, known as [$s0] to [$s7], are callee-saved
38    registers.
39
40    Registers 26 and 27, known as [$k0] and [$k1], are reserved for use
41    by the operating system kernel.
42
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
45    and global variables.
46
47    Register 29, known as [$sp] for stack pointer, points to the last
48    location in use on the stack.
49
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
52    [$st1].
53
54    Register 31, known as [$ra], contains the return address for the
55    current function. It is written by the [jal] instruction. *)
56
57 type register =
58     int
59
60 let equal : register -> register -> bool = (=)
61
62 module RegisterSet = struct
63
64   include Set.Make (struct
65     type t = register
66     let compare = (-)
67   end)
68
69   let disjoint s1 s2 =
70     is_empty (inter s1 s2)
71
72   let of_list rs =
73     List.fold_right add rs empty
74
75 end
76
77 module RegisterMap = struct
78
79   include Map.Make (struct
80     type t = register
81     let compare = (-)
82   end)
83
84   let lift f s =
85     RegisterSet.fold (fun x m ->
86       add x (f x) m
87     ) s empty
88
89 end
90
91 (* Naming convention. *)
92
93 let zero =
94   0
95
96 let v0, v1, a0, a1, a2, a3 =
97   2, 3, 4, 5, 6, 7
98
99 let t0, t1, t2, t3, t4, t5, t6, t7, t8, t9 =
100   8, 9, 10, 11, 12, 13, 14, 15, 24, 25
101
102 let s0, s1, s2, s3, s4, s5, s6 =
103   16, 17, 18, 19, 20, 21, 22
104
105 let gp_mips =
106   23 (* s7 *)
107
108 let gp_gnu =
109   28
110
111 let sp, fp =
112   29, 30
113
114 let ra =
115   31
116
117 let st0, st1 =
118   v1, fp
119
120 let print = function
121   | 0 ->
122       "zero"
123   | 1 ->
124       "at"
125   | 2 ->
126       "v0"
127   | 3 ->
128       "v1"
129   | 4 ->
130       "a0"
131   | 5 ->
132       "a1"
133   | 6 ->
134       "a2"
135   | 7 ->
136       "a3"
137   | 8 ->
138       "t0"
139   | 9 ->
140       "t1"
141   | 10 ->
142       "t2"
143   | 11 ->
144       "t3"
145   | 12 ->
146       "t4"
147   | 13 ->
148       "t5"
149   | 14 ->
150       "t6"
151   | 15 ->
152       "t7"
153   | 24 ->
154       "t8"
155   | 25 ->
156       "t9"
157   | 16 ->
158       "s0"
159   | 17 ->
160       "s1"
161   | 18 ->
162       "s2"
163   | 19 ->
164       "s3"
165   | 20 ->
166       "s4"
167   | 21 ->
168       "s5"
169   | 22 ->
170       "s6"
171   | 23 ->
172       "s7"
173   | 28 ->
174       "gp"
175   | 29 ->
176       "sp"
177   | 30 ->
178       "fp"
179   | 31 ->
180       "ra"
181   | _ ->
182       assert false
183
184 let print2 r = string_of_int r
185
186 (* Calling convention. *)
187
188 let parameters =
189   [ a0; a1; a2; a3 ]
190
191 let result =
192   v0
193
194 let caller_saved =
195   RegisterSet.of_list (
196     [ v0; a0; a1; a2; a3; t0; t1; t2; t3; t4; t5; t6; t7; t8; t9; ra ]
197   )
198
199 let callee_saved =
200   RegisterSet.of_list (
201     [ s0; s1; s2; s3; s4; s5; s6 ]
202   )
203
204 let allocatable =
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)
209
210 let registers =
211   RegisterSet.union allocatable
212     (RegisterSet.of_list [ gp_mips; gp_gnu; sp; st0; st1 ])
213
214 *)