1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 (* ********************************************************************** *)
16 (* Progetto FreeScale *)
18 (* Sviluppato da: Cosimo Oliboni, oliboni@cs.unibo.it *)
19 (* Cosimo Oliboni, oliboni@cs.unibo.it *)
21 (* ********************************************************************** *)
23 include "freescale/byte8.ma".
29 nrecord word16 : Type ≝
36 notation "〈x:y〉" non associative with precedence 80
37 for @{ 'mk_word16 $x $y }.
38 interpretation "mk_word16" 'mk_word16 x y = (mk_word16 x y).
41 ndefinition eq_w16 ≝ λw1,w2.(eq_b8 (w16h w1) (w16h w2)) ⊗ (eq_b8 (w16l w1) (w16l w2)).
45 λw1,w2:word16.match lt_b8 (w16h w1) (w16h w2) with
47 | false ⇒ match gt_b8 (w16h w1) (w16h w2) with
49 | false ⇒ lt_b8 (w16l w1) (w16l w2) ]].
52 ndefinition le_w16 ≝ λw1,w2:word16.(eq_w16 w1 w2) ⊕ (lt_w16 w1 w2).
55 ndefinition gt_w16 ≝ λw1,w2:word16.⊖ (le_w16 w1 w2).
58 ndefinition ge_w16 ≝ λw1,w2:word16.⊖ (lt_w16 w1 w2).
62 λw1,w2:word16.mk_word16 (and_b8 (w16h w1) (w16h w2)) (and_b8 (w16l w1) (w16l w2)).
66 λw1,w2:word16.mk_word16 (or_b8 (w16h w1) (w16h w2)) (or_b8 (w16l w1) (w16l w2)).
70 λw1,w2:word16.mk_word16 (xor_b8 (w16h w1) (w16h w2)) (xor_b8 (w16l w1) (w16l w2)).
72 (* operatore rotazione destra con carry *)
74 λw:word16.λc:bool.match rcr_b8 (w16h w) c with
75 [ pair wh' c' ⇒ match rcr_b8 (w16l w) c' with
76 [ pair wl' c'' ⇒ pair … (mk_word16 wh' wl') c'' ]].
78 (* operatore shift destro *)
80 λw:word16.match rcr_b8 (w16h w) false with
81 [ pair wh' c' ⇒ match rcr_b8 (w16l w) c' with
82 [ pair wl' c'' ⇒ pair … (mk_word16 wh' wl') c'' ]].
84 (* operatore rotazione destra *)
86 λw:word16.match rcr_b8 (w16h w) false with
87 [ pair wh' c' ⇒ match rcr_b8 (w16l w) c' with
88 [ pair wl' c'' ⇒ match c'' with
89 [ true ⇒ mk_word16 (or_b8 (mk_byte8 x8 x0) wh') wl'
90 | false ⇒ mk_word16 wh' wl' ]]].
92 (* operatore rotazione destra n-volte *)
93 nlet rec ror_w16_n (w:word16) (n:nat) on n ≝
96 | S n' ⇒ ror_w16_n (ror_w16 w) n' ].
98 (* operatore rotazione sinistra con carry *)
100 λw:word16.λc:bool.match rcl_b8 (w16l w) c with
101 [ pair wl' c' ⇒ match rcl_b8 (w16h w) c' with
102 [ pair wh' c'' ⇒ pair … (mk_word16 wh' wl') c'' ]].
104 (* operatore shift sinistro *)
105 ndefinition shl_w16 ≝
106 λw:word16.match rcl_b8 (w16l w) false with
107 [ pair wl' c' ⇒ match rcl_b8 (w16h w) c' with
108 [ pair wh' c'' ⇒ pair … (mk_word16 wh' wl') c'' ]].
110 (* operatore rotazione sinistra *)
111 ndefinition rol_w16 ≝
112 λw:word16.match rcl_b8 (w16l w) false with
113 [ pair wl' c' ⇒ match rcl_b8 (w16h w) c' with
114 [ pair wh' c'' ⇒ match c'' with
115 [ true ⇒ mk_word16 wh' (or_b8 (mk_byte8 x0 x1) wl')
116 | false ⇒ mk_word16 wh' wl' ]]].
118 (* operatore rotazione sinistra n-volte *)
119 nlet rec rol_w16_n (w:word16) (n:nat) on n ≝
122 | S n' ⇒ rol_w16_n (rol_w16 w) n' ].
124 (* operatore not/complemento a 1 *)
125 ndefinition not_w16 ≝
126 λw:word16.mk_word16 (not_b8 (w16h w)) (not_b8 (w16l w)).
128 (* operatore somma con data+carry → data+carry *)
129 ndefinition plus_w16_dc_dc ≝
130 λw1,w2:word16.λc:bool.
131 match plus_b8_dc_dc (w16l w1) (w16l w2) c with
132 [ pair l c ⇒ match plus_b8_dc_dc (w16h w1) (w16h w2) c with
133 [ pair h c' ⇒ pair … 〈h:l〉 c' ]].
135 (* operatore somma con data+carry → data *)
136 ndefinition plus_w16_dc_d ≝
137 λw1,w2:word16.λc:bool.
138 match plus_b8_dc_dc (w16l w1) (w16l w2) c with
139 [ pair l c ⇒ 〈plus_b8_dc_d (w16h w1) (w16h w2) c:l〉 ].
141 (* operatore somma con data+carry → c *)
142 ndefinition plus_w16_dc_c ≝
143 λw1,w2:word16.λc:bool.
144 plus_b8_dc_c (w16h w1) (w16h w2) (plus_b8_dc_c (w16l w1) (w16l w2) c).
146 (* operatore somma con data → data+carry *)
147 ndefinition plus_w16_d_dc ≝
149 match plus_b8_d_dc (w16l w1) (w16l w2) with
150 [ pair l c ⇒ match plus_b8_dc_dc (w16h w1) (w16h w2) c with
151 [ pair h c' ⇒ pair … 〈h:l〉 c' ]].
153 (* operatore somma con data → data *)
154 ndefinition plus_w16_d_d ≝
156 match plus_b8_d_dc (w16l w1) (w16l w2) with
157 [ pair l c ⇒ 〈plus_b8_dc_d (w16h w1) (w16h w2) c:l〉 ].
159 (* operatore somma con data → c *)
160 ndefinition plus_w16_d_c ≝
162 plus_b8_dc_c (w16h w1) (w16h w2) (plus_b8_d_c (w16l w1) (w16l w2)).
164 (* operatore Most Significant Bit *)
165 ndefinition MSB_w16 ≝ λw:word16.eq_ex x8 (and_ex x8 (b8h (w16h w))).
167 (* word → naturali *)
168 ndefinition nat_of_word16 ≝ λw:word16. 256 * (nat_of_byte8 (w16h w)) + (nat_of_byte8 (w16l w)).
170 (* operatore predecessore *)
171 ndefinition pred_w16 ≝
172 λw:word16.match eq_b8 (w16l w) (mk_byte8 x0 x0) with
173 [ true ⇒ mk_word16 (pred_b8 (w16h w)) (pred_b8 (w16l w))
174 | false ⇒ mk_word16 (w16h w) (pred_b8 (w16l w)) ].
176 (* operatore successore *)
177 ndefinition succ_w16 ≝
178 λw:word16.match eq_b8 (w16l w) (mk_byte8 xF xF) with
179 [ true ⇒ mk_word16 (succ_b8 (w16h w)) (succ_b8 (w16l w))
180 | false ⇒ mk_word16 (w16h w) (succ_b8 (w16l w)) ].
182 (* operatore neg/complemento a 2 *)
183 ndefinition compl_w16 ≝
184 λw:word16.match MSB_w16 w with
185 [ true ⇒ succ_w16 (not_w16 w)
186 | false ⇒ not_w16 (pred_w16 w) ].
189 operatore moltiplicazione senza segno: b*b=[0x0000,0xFE01]
190 ... in pratica (〈a,b〉*〈c,d〉) = (a*c)<<8+(a*d)<<4+(b*c)<<4+(b*d)
193 λb1,b2:byte8.match b1 with
194 [ mk_byte8 b1h b1l ⇒ match b2 with
195 [ mk_byte8 b2h b2l ⇒ match mul_ex b1l b2l with
196 [ mk_byte8 t1_h t1_l ⇒ match mul_ex b1h b2l with
197 [ mk_byte8 t2_h t2_l ⇒ match mul_ex b2h b1l with
198 [ mk_byte8 t3_h t3_l ⇒ match mul_ex b1h b2h with
199 [ mk_byte8 t4_h t4_l ⇒
202 (plus_w16_d_d 〈〈x0,t3_h〉:〈t3_l,x0〉〉 〈〈x0,t2_h〉:〈t2_l,x0〉〉) 〈〈t4_h,t4_l〉:〈x0,x0〉〉)〈〈x0,x0〉:〈t1_h,t1_l〉〉
205 (* divisione senza segno (secondo la logica delle ALU): (quoziente resto) overflow *)
206 nlet rec div_b8_aux (divd:word16) (divs:word16) (molt:byte8) (q:byte8) (c:nat) on c ≝
207 let w' ≝ plus_w16_d_d divd (compl_w16 divs) in
209 [ O ⇒ match le_w16 divs divd with
210 [ true ⇒ triple … (or_b8 molt q) (w16l w') (⊖ (eq_b8 (w16h w') 〈x0,x0〉))
211 | false ⇒ triple … q (w16l divd) (⊖ (eq_b8 (w16h divd) 〈x0,x0〉)) ]
212 | S c' ⇒ match le_w16 divs divd with
213 [ true ⇒ div_b8_aux w' (ror_w16 divs) (ror_b8 molt) (or_b8 molt q) c'
214 | false ⇒ div_b8_aux divd (ror_w16 divs) (ror_b8 molt) q c' ]].
217 λw:word16.λb:byte8.match eq_b8 b 〈x0,x0〉 with
219 la combinazione n/0 e' illegale, segnala solo overflow senza dare risultato
221 [ true ⇒ triple … 〈xF,xF〉 (w16l w) true
222 | false ⇒ match eq_w16 w 〈〈x0,x0〉:〈x0,x0〉〉 with
223 (* 0 diviso qualsiasi cosa diverso da 0 da' q=0 r=0 o=false *)
224 [ true ⇒ triple … 〈x0,x0〉 〈x0,x0〉 false
225 (* 1) e' una divisione sensata che produrra' overflow/risultato *)
226 (* 2) parametri: dividendo, divisore, moltiplicatore, quoziente, contatore *)
227 (* 3) ad ogni ciclo il divisore e il moltiplicatore vengono scalati di 1 a dx *)
228 (* 4) il moltiplicatore e' la quantita' aggiunta al quoziente se il divisore *)
229 (* puo' essere sottratto al dividendo *)
230 | false ⇒ div_b8_aux w (rol_w16_n 〈〈x0,x0〉:b〉 7) 〈x8,x0〉 〈x0,x0〉 7 ]].
232 (* operatore x in [inf,sup] *)
233 ndefinition in_range ≝
234 λx,inf,sup:word16.(le_w16 inf sup) ⊗ (ge_w16 x inf) ⊗ (le_w16 x sup).
236 (* iteratore sulle word *)
237 ndefinition forall_word16 ≝
241 P (mk_word16 bh bl ))).