]> matita.cs.unibo.it Git - pkg-cerco/acc.git/blob - src/ASM/I8051.ml
first version of the package
[pkg-cerco/acc.git] / src / ASM / I8051.ml
1
2 let int_size = 1
3 let ptr_size = 2
4 let alignment = None
5
6 type opaccs =
7   | Mul
8   | DivuModu
9
10 type op1 =
11   | Cmpl
12   | Inc
13
14 type op2 =
15   | Add
16   | Addc
17   | Sub
18   | And
19   | Or
20   | Xor
21
22 let print_opaccs = function
23   | Mul -> "mul"
24   | DivuModu -> "divu"
25
26 let print_op1 = function
27   | Cmpl -> "cmpl"
28   | Inc -> "inc"
29
30 let print_op2 = function
31   | Add -> "add"
32   | Addc -> "addc"
33   | Sub -> "sub"
34   | And -> "and"
35   | Or -> "or"
36   | Xor -> "xor"
37
38
39 module Eval (Val : Value.S) = struct
40
41   let eval_int_mul size i1 i2 =
42     let module Int = IntValue.Make (struct let size = 2 * size end) in
43     match Int.break (Int.mul i1 i2) 2 with
44       | res1 :: res2 :: _ -> (Val.of_int_repr res1, Val.of_int_repr res2)
45       | _ -> assert false (* should be impossible *)
46
47   let eval_mul v1 v2 =
48     if Val.is_int v1 && Val.is_int v2 then
49       eval_int_mul Val.int_size (Val.to_int_repr v1) (Val.to_int_repr v2)
50     else (Val.undef, Val.undef)
51
52   let opaccs op v1 v2 = match op with
53     | Mul -> eval_mul v1 v2
54     | DivuModu -> (Val.divu v1 v2, Val.modulou v1 v2)
55
56   let op1 = function
57     | Cmpl -> Val.cmpl
58     | Inc -> Val.succ
59
60   let op2 carry op2 v1 v2 = match op2 with
61     | Add -> Val.add_and_of v1 v2
62     | Addc ->
63       let (res1, of1) = Val.add_and_of v1 v2 in
64       let (res2, of2) = Val.add_and_of res1 carry in
65       (res2, Val.or_op of1 of2)
66     | Sub ->
67       let (res1, uf1) = Val.sub_and_uf v1 v2 in
68       let (res2, uf2) = Val.sub_and_uf res1 carry in
69       (res2, Val.or_op uf1 uf2)
70     | And -> (Val.and_op v1 v2, carry)
71     | Or -> (Val.or_op v1 v2, carry)
72     | Xor -> (Val.xor v1 v2, carry)
73
74 end
75
76
77 type register = int
78 let compare_reg = Pervasives.compare
79 let eq_reg r1 r2 = r1 = r2
80
81 module OrdReg = struct type t = register let compare = compare_reg end
82 module RegisterSet = Set.Make (OrdReg)
83 module RegisterMap = Map.Make (OrdReg)
84
85 let r00 = 0
86 let r01 = 1
87 let r02 = 2
88 let r03 = 3
89 let r04 = 4
90 let r05 = 5
91 let r06 = 6
92 let r07 = 7
93 let r10 = 8
94 let r11 = 9
95 let r12 = 10
96 let r13 = 11
97 let r14 = 12
98 let r15 = 13
99 let r16 = 14
100 let r17 = 15
101 let r20 = 16
102 let r21 = 17
103 let r22 = 18
104 let r23 = 19
105 let r24 = 20
106 let r25 = 21
107 let r26 = 22
108 let r27 = 23
109 let r30 = 24
110 let r31 = 25
111 let r32 = 26
112 let r33 = 27
113 let r34 = 28
114 let r35 = 29
115 let r36 = 30
116 let r37 = 31
117 let a = 224
118 let b = 240
119 let dpl = 130
120 let dph = 131
121 let carry = -1 (* only used for the liveness analysis. *)
122
123 let print_register = function
124   | 0 -> "R00"
125   | 1 -> "R01"
126   | 2 -> "R02"
127   | 3 -> "R03"
128   | 4 -> "R04"
129   | 5 -> "R05"
130   | 6 -> "R06"
131   | 7 -> "R07"
132   | 8 -> "R10"
133   | 9 -> "R11"
134   | 10 -> "R12"
135   | 11 -> "R13"
136   | 12 -> "R14"
137   | 13 -> "R15"
138   | 14 -> "R16"
139   | 15 -> "R17"
140   | 16 -> "R20"
141   | 17 -> "R21"
142   | 18 -> "R22"
143   | 19 -> "R23"
144   | 20 -> "R24"
145   | 21 -> "R25"
146   | 22 -> "R26"
147   | 23 -> "R27"
148   | 24 -> "R30"
149   | 25 -> "R31"
150   | 26 -> "R32"
151   | 27 -> "R33"
152   | 28 -> "R34"
153   | 29 -> "R35"
154   | 30 -> "R36"
155   | 31 -> "R37"
156   | 224 -> "A"
157   | 240 -> "B"
158   | 130 -> "DPL"
159   | 131 -> "DPH"
160   | _ -> assert false (* impossible *)
161
162 let sst = r10
163 let st0 = r02
164 let st1 = r03
165 let st2 = r04
166 let st3 = r05
167 let sts = [st0 ; st1 ; st2 ; st3]
168 let spl = r06
169 let sph = r07
170 let rets = [dpl ; dph ; r00 ; r01]
171
172 let spl_addr = spl
173 let spl_init = 255
174 let sph_addr = sph
175 let sph_init = 255
176 let isp_addr = 129
177 let isp_init = 47
178
179 let set_of_list rl = List.fold_right RegisterSet.add rl RegisterSet.empty
180 let list_of_set rs = RegisterSet.fold (fun r l -> r :: l) rs []
181
182 let registers =
183   set_of_list [r00 ; r01 ; r02 ; r03 ; r04 ; r05 ; r06 ; r07 ;
184                r10 ; r11 ; r12 ; r13 ; r14 ; r15 ; r16 ; r17 ;
185                r20 ; r21 ; r22 ; r23 ; r24 ; r25 ; r26 ; r27 ;
186                r30 ; r31 ; r32 ; r33 ; r34 ; r35 ; r36 ; r37 ;
187                a ; b ; dpl ; dph ; spl ; sph ; st0 ; st1 ; sst]
188
189 let forbidden =
190   set_of_list
191     [a ; b ; dpl ; dph ; spl ; sph ; st0 ; st1 ; st2 ; st3 ; sst]
192
193 let parameters =
194   let params = set_of_list [r30 ; r31 ; r32 ; r33 ; r34 ; r35 ; r36 ; r37] in
195   list_of_set (RegisterSet.diff params forbidden)
196
197 let callee_saved =
198   RegisterSet.diff (set_of_list [r20 ; r21 ; r22 ; r23 ; r24 ; r25 ; r26 ; r27])
199     forbidden
200 let caller_saved =
201   RegisterSet.diff (RegisterSet.diff registers callee_saved) forbidden
202 let allocatable  = RegisterSet.diff registers forbidden
203
204 let reg_addr r = `DIRECT (BitVectors.vect_of_int r `Eight)
205
206 (* External RAM size *)
207 let ext_ram_size = MiscPottier.pow 2 16
208 (* Internal RAM size *)
209 let int_ram_size = MiscPottier.pow 2 8