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: Ing. Cosimo Oliboni, oliboni@cs.unibo.it *)
19 (* Ultima modifica: 05/08/2009 *)
21 (* ********************************************************************** *)
23 include "num/word16.ma".
29 nrecord word32 : Type ≝
36 notation "〈x.y〉" non associative with precedence 80
37 for @{ 'mk_word32 $x $y }.
38 interpretation "mk_word32" 'mk_word32 x y = (mk_word32 x y).
41 ndefinition eq_w32 ≝ λdw1,dw2.(eq_w16 (w32h dw1) (w32h dw2)) ⊗ (eq_w16 (w32l dw1) (w32l dw2)).
45 λdw1,dw2:word32.match lt_w16 (w32h dw1) (w32h dw2) with
47 | false ⇒ match gt_w16 (w32h dw1) (w32h dw2) with
49 | false ⇒ lt_w16 (w32l dw1) (w32l dw2) ]].
52 ndefinition le_w32 ≝ λdw1,dw2:word32.(eq_w32 dw1 dw2) ⊕ (lt_w32 dw1 dw2).
55 ndefinition gt_w32 ≝ λdw1,dw2:word32.⊖ (le_w32 dw1 dw2).
58 ndefinition ge_w32 ≝ λdw1,dw2:word32.⊖ (lt_w32 dw1 dw2).
62 λdw1,dw2:word32.mk_word32 (and_w16 (w32h dw1) (w32h dw2)) (and_w16 (w32l dw1) (w32l dw2)).
66 λdw1,dw2:word32.mk_word32 (or_w16 (w32h dw1) (w32h dw2)) (or_w16 (w32l dw1) (w32l dw2)).
70 λdw1,dw2:word32.mk_word32 (xor_w16 (w32h dw1) (w32h dw2)) (xor_w16 (w32l dw1) (w32l dw2)).
72 (* operatore rotazione destra con carry *)
74 λdw:word32.λc:bool.match rcr_w16 (w32h dw) c with
75 [ pair wh' c' ⇒ match rcr_w16 (w32l dw) c' with
76 [ pair wl' c'' ⇒ pair … (mk_word32 wh' wl') c'' ]].
78 (* operatore shift destro *)
80 λdw:word32.match rcr_w16 (w32h dw) false with
81 [ pair wh' c' ⇒ match rcr_w16 (w32l dw) c' with
82 [ pair wl' c'' ⇒ pair … (mk_word32 wh' wl') c'' ]].
84 (* operatore rotazione destra *)
86 λdw:word32.match rcr_w16 (w32h dw) false with
87 [ pair wh' c' ⇒ match rcr_w16 (w32l dw) c' with
88 [ pair wl' c'' ⇒ match c'' with
89 [ true ⇒ mk_word32 (or_w16 (mk_word16 (mk_byte8 x8 x0) (mk_byte8 x0 x0)) wh') wl'
90 | false ⇒ mk_word32 wh' wl' ]]].
92 (* operatore rotazione destra n-volte *)
93 nlet rec ror_w32_n (dw:word32) (n:nat) on n ≝
96 | S n' ⇒ ror_w32_n (ror_w32 dw) n' ].
98 (* operatore rotazione sinistra con carry *)
100 λdw:word32.λc:bool.match rcl_w16 (w32l dw) c with
101 [ pair wl' c' ⇒ match rcl_w16 (w32h dw) c' with
102 [ pair wh' c'' ⇒ pair … (mk_word32 wh' wl') c'' ]].
104 (* operatore shift sinistro *)
105 ndefinition shl_w32 ≝
106 λdw:word32.match rcl_w16 (w32l dw) false with
107 [ pair wl' c' ⇒ match rcl_w16 (w32h dw) c' with
108 [ pair wh' c'' ⇒ pair … (mk_word32 wh' wl') c'' ]].
110 (* operatore rotazione sinistra *)
111 ndefinition rol_w32 ≝
112 λdw:word32.match rcl_w16 (w32l dw) false with
113 [ pair wl' c' ⇒ match rcl_w16 (w32h dw) c' with
114 [ pair wh' c'' ⇒ match c'' with
115 [ true ⇒ mk_word32 wh' (or_w16 (mk_word16 (mk_byte8 x0 x0) (mk_byte8 x0 x1)) wl')
116 | false ⇒ mk_word32 wh' wl' ]]].
118 (* operatore rotazione sinistra n-volte *)
119 nlet rec rol_w32_n (dw:word32) (n:nat) on n ≝
122 | S n' ⇒ rol_w32_n (rol_w32 dw) n' ].
124 (* operatore not/complemento a 1 *)
125 ndefinition not_w32 ≝
126 λdw:word32.mk_word32 (not_w16 (w32h dw)) (not_w16 (w32l dw)).
128 (* operatore somma con data+carry → data+carry *)
129 ndefinition plus_w32_dc_dc ≝
130 λdw1,dw2:word32.λc:bool.
131 match plus_w16_dc_dc (w32l dw1) (w32l dw2) c with
132 [ pair l c ⇒ match plus_w16_dc_dc (w32h dw1) (w32h dw2) c with
133 [ pair h c' ⇒ pair … 〈h.l〉 c' ]].
135 (* operatore somma con data+carry → data *)
136 ndefinition plus_w32_dc_d ≝
137 λdw1,dw2:word32.λc:bool.
138 match plus_w16_dc_dc (w32l dw1) (w32l dw2) c with
139 [ pair l c ⇒ 〈plus_w16_dc_d (w32h dw1) (w32h dw2) c.l〉 ].
141 (* operatore somma con data+carry → c *)
142 ndefinition plus_w32_dc_c ≝
143 λdw1,dw2:word32.λc:bool.
144 plus_w16_dc_c (w32h dw1) (w32h dw2) (plus_w16_dc_c (w32l dw1) (w32l dw2) c).
146 (* operatore somma con data → data+carry *)
147 ndefinition plus_w32_d_dc ≝
149 match plus_w16_d_dc (w32l dw1) (w32l dw2) with
150 [ pair l c ⇒ match plus_w16_dc_dc (w32h dw1) (w32h dw2) c with
151 [ pair h c' ⇒ pair … 〈h.l〉 c' ]].
153 (* operatore somma con data → data *)
154 ndefinition plus_w32_d_d ≝
156 match plus_w16_d_dc (w32l dw1) (w32l dw2) with
157 [ pair l c ⇒ 〈plus_w16_dc_d (w32h dw1) (w32h dw2) c.l〉 ].
159 (* operatore somma con data → c *)
160 ndefinition plus_w32_d_c ≝
162 plus_w16_dc_c (w32h dw1) (w32h dw2) (plus_w16_d_c (w32l dw1) (w32l dw2)).
164 (* operatore Most Significant Bit *)
165 ndefinition MSB_w32 ≝ λdw:word32.eq_ex x8 (and_ex x8 (b8h (w16h (w32h dw)))).
167 (* operatore predecessore *)
168 ndefinition pred_w32 ≝
169 λdw:word32.match eq_w16 (w32l dw) (mk_word16 (mk_byte8 x0 x0) (mk_byte8 x0 x0)) with
170 [ true ⇒ mk_word32 (pred_w16 (w32h dw)) (pred_w16 (w32l dw))
171 | false ⇒ mk_word32 (w32h dw) (pred_w16 (w32l dw)) ].
173 (* operatore successore *)
174 ndefinition succ_w32 ≝
175 λdw:word32.match eq_w16 (w32l dw) (mk_word16 (mk_byte8 xF xF) (mk_byte8 xF xF)) with
176 [ true ⇒ mk_word32 (succ_w16 (w32h dw)) (succ_w16 (w32l dw))
177 | false ⇒ mk_word32 (w32h dw) (succ_w16 (w32l dw)) ].
179 (* operatore neg/complemento a 2 *)
180 ndefinition compl_w32 ≝
181 λdw:word32.match MSB_w32 dw with
182 [ true ⇒ succ_w32 (not_w32 dw)
183 | false ⇒ not_w32 (pred_w32 dw) ].
186 operatore moltiplicazione senza segno: b*b=[0x00000000,0xFFFE0001]
187 ... in pratica (〈a:b〉*〈c:d〉) = (a*c)<<16+(a*d)<<8+(b*c)<<8+(b*d)
189 ndefinition mul_w16 ≝
190 λw1,w2:word16.match w1 with
191 [ mk_word16 b1h b1l ⇒ match w2 with
192 [ mk_word16 b2h b2l ⇒ match mul_b8 b1l b2l with
193 [ mk_word16 t1_h t1_l ⇒ match mul_b8 b1h b2l with
194 [ mk_word16 t2_h t2_l ⇒ match mul_b8 b2h b1l with
195 [ mk_word16 t3_h t3_l ⇒ match mul_b8 b1h b2h with
196 [ mk_word16 t4_h t4_l ⇒
199 (plus_w32_d_d 〈〈〈x0,x0〉:t3_h〉.〈t3_l:〈x0,x0〉〉〉 〈〈〈x0,x0〉:t2_h〉.〈t2_l:〈x0,x0〉〉〉) 〈〈t4_h:t4_l〉.〈〈x0,x0〉:〈x0,x0〉〉〉)〈〈〈x0,x0〉:〈x0,x0〉〉.〈t1_h:t1_l〉〉
202 (* divisione senza segno (secondo la logica delle ALU): (quoziente resto) overflow *)
203 nlet rec div_w16_aux (divd:word32) (divs:word32) (molt:word16) (q:word16) (c:nat) on c ≝
204 let w' ≝ plus_w32_d_d divd (compl_w32 divs) in
206 [ O ⇒ match le_w32 divs divd with
207 [ true ⇒ triple … (or_w16 molt q) (w32l w') (⊖ (eq_w16 (w32h w') 〈〈x0,x0〉:〈x0,x0〉〉))
208 | false ⇒ triple … q (w32l divd) (⊖ (eq_w16 (w32h divd) 〈〈x0,x0〉:〈x0,x0〉〉)) ]
209 | S c' ⇒ match le_w32 divs divd with
210 [ true ⇒ div_w16_aux w' (ror_w32 divs) (ror_w16 molt) (or_w16 molt q) c'
211 | false ⇒ div_w16_aux divd (ror_w32 divs) (ror_w16 molt) q c' ]].
213 ndefinition div_w16 ≝
214 λw:word32.λb:word16.match eq_w16 b 〈〈x0,x0〉:〈x0,x0〉〉 with
216 la combinazione n/0 e' illegale, segnala solo overflow senza dare risultato
218 [ true ⇒ triple … 〈〈xF,xF〉:〈xF,xF〉〉 (w32l w) true
219 | false ⇒ match eq_w32 w 〈〈〈x0,x0〉:〈x0,x0〉〉.〈〈x0,x0〉:〈x0,x0〉〉〉 with
220 (* 0 diviso qualsiasi cosa diverso da 0 da' q=0 r=0 o=false *)
221 [ true ⇒ triple … 〈〈x0,x0〉:〈x0,x0〉〉 〈〈x0,x0〉:〈x0,x0〉〉 false
222 (* 1) e' una divisione sensata che produrra' overflow/risultato *)
223 (* 2) parametri: dividendo, divisore, moltiplicatore, quoziente, contatore *)
224 (* 3) ad ogni ciclo il divisore e il moltiplicatore vengono scalati di 1 a dx *)
225 (* 4) il moltiplicatore e' la quantita' aggiunta al quoziente se il divisore *)
226 (* puo' essere sottratto al dividendo *)
227 | false ⇒ div_w16_aux w (rol_w32_n 〈〈〈x0,x0〉:〈x0,x0〉〉.b〉 nat15) 〈〈x8,x0〉:〈x0,x0〉〉 〈〈x0,x0〉:〈x0,x0〉〉 nat15 ]].
229 (* operatore x in [inf,sup] *)
230 ndefinition inrange_w32 ≝
231 λx,inf,sup:word32.(le_w32 inf sup) ⊗ (ge_w32 x inf) ⊗ (le_w32 x sup).
233 (* iteratore sulle word *)
234 ndefinition forall_w32 ≝
238 P (mk_word32 bh bl ))).