19 |
* We'll try to promote to the next largest size. |
* We'll try to promote to the next largest size. |
20 |
*) |
*) |
21 |
val naturalWidths : T.ty list |
val naturalWidths : T.ty list |
22 |
|
|
23 |
|
(* |
24 |
|
* Are integers of widths less than the size of integer word. |
25 |
|
* automatically sign extended, zero extended, or neither. |
26 |
|
* When in doubt, choose neither since it is conservative. |
27 |
|
*) |
28 |
|
datatype rep = SE | ZE | NEITHER |
29 |
|
val rep : rep |
30 |
|
|
31 |
) : MLTREEGEN = |
) : MLTREEGEN = |
32 |
struct |
struct |
33 |
|
|
40 |
fun size(T.REG(ty,_)) = ty |
fun size(T.REG(ty,_)) = ty |
41 |
| size(T.LI _) = intTy |
| size(T.LI _) = intTy |
42 |
| size(T.LI32 _) = intTy |
| size(T.LI32 _) = intTy |
43 |
|
| size(T.LI64 _) = intTy |
44 |
| size(T.LABEL _) = intTy |
| size(T.LABEL _) = intTy |
45 |
| size(T.CONST _) = intTy |
| size(T.CONST _) = intTy |
46 |
| size(T.ADD(ty,_,_)) = ty |
| size(T.ADD(ty,_,_)) = ty |
47 |
| size(T.SUB(ty,_,_)) = ty |
| size(T.SUB(ty,_,_)) = ty |
48 |
| size(T.MULS(ty,_,_)) = ty |
| size(T.MULS(ty,_,_)) = ty |
49 |
| size(T.DIVS(ty,_,_)) = ty |
| size(T.DIVS(ty,_,_)) = ty |
50 |
|
| size(T.REMS(ty,_,_)) = ty |
51 |
| size(T.MULU(ty,_,_)) = ty |
| size(T.MULU(ty,_,_)) = ty |
52 |
| size(T.DIVU(ty,_,_)) = ty |
| size(T.DIVU(ty,_,_)) = ty |
53 |
|
| size(T.REMU(ty,_,_)) = ty |
54 |
| size(T.ADDT(ty,_,_)) = ty |
| size(T.ADDT(ty,_,_)) = ty |
55 |
| size(T.SUBT(ty,_,_)) = ty |
| size(T.SUBT(ty,_,_)) = ty |
56 |
| size(T.MULT(ty,_,_)) = ty |
| size(T.MULT(ty,_,_)) = ty |
57 |
| size(T.DIVT(ty,_,_)) = ty |
| size(T.DIVT(ty,_,_)) = ty |
58 |
|
| size(T.REMT(ty,_,_)) = ty |
59 |
|
| size(T.ANDB(ty,_,_)) = ty |
60 |
|
| size(T.ORB(ty,_,_)) = ty |
61 |
|
| size(T.XORB(ty,_,_)) = ty |
62 |
|
| size(T.NOTB(ty,_)) = ty |
63 |
|
| size(T.SRA(ty,_,_)) = ty |
64 |
|
| size(T.SRL(ty,_,_)) = ty |
65 |
|
| size(T.SLL(ty,_,_)) = ty |
66 |
|
| size(T.COND(ty,_,_,_)) = ty |
67 |
| size(T.LOAD(ty,_,_)) = ty |
| size(T.LOAD(ty,_,_)) = ty |
68 |
|
| size(T.LOAD_UNALIGNED(ty,_,_)) = ty |
69 |
| size(T.CVTI2I(ty,_,_)) = ty |
| size(T.CVTI2I(ty,_,_)) = ty |
70 |
| size(T.CVTF2I(ty,_,_)) = ty |
| size(T.CVTF2I(ty,_,_)) = ty |
71 |
| size(T.SEQ(s,e)) = size e |
| size(T.SEQ(s,e)) = size e |
72 |
| size(T.COND(ty,_,_,_)) = ty |
| size(T.EXTENSION(ty,_,_)) = ty |
73 |
| size(T.MARK(e,_)) = size e |
| size(T.MARK(e,_)) = size e |
74 |
| size _ = raise SizeUnknown |
| size _ = raise SizeUnknown |
75 |
|
|
76 |
fun fsize(T.FREG(ty,_)) = ty |
fun fsize(T.FREG(ty,_)) = ty |
77 |
|
| fsize(T.FLOAD(ty,_,_)) = ty |
78 |
|
| fsize(T.FLOAD_UNALIGNED(ty,_,_)) = ty |
79 |
| fsize(T.FADD(ty,_,_)) = ty |
| fsize(T.FADD(ty,_,_)) = ty |
80 |
| fsize(T.FSUB(ty,_,_)) = ty |
| fsize(T.FSUB(ty,_,_)) = ty |
81 |
| fsize(T.FMUL(ty,_,_)) = ty |
| fsize(T.FMUL(ty,_,_)) = ty |
82 |
| fsize(T.FDIV(ty,_,_)) = ty |
| fsize(T.FDIV(ty,_,_)) = ty |
|
| fsize(T.FNEG(ty,_)) = ty |
|
83 |
| fsize(T.FABS(ty,_)) = ty |
| fsize(T.FABS(ty,_)) = ty |
84 |
|
| fsize(T.FNEG(ty,_)) = ty |
85 |
| fsize(T.FSQRT(ty,_)) = ty |
| fsize(T.FSQRT(ty,_)) = ty |
|
| fsize(T.FLOAD(ty,_,_)) = ty |
|
86 |
| fsize(T.CVTI2F(ty,_,_)) = ty |
| fsize(T.CVTI2F(ty,_,_)) = ty |
87 |
| fsize(T.CVTF2F(ty,_,_)) = ty |
| fsize(T.CVTF2F(ty,_,_)) = ty |
88 |
| fsize(T.FSEQ(_,e)) = fsize e |
| fsize(T.FSEQ(_,e)) = fsize e |
89 |
|
| fsize(T.FEXTENSION(ty,_,_)) = ty |
90 |
| fsize(T.FMARK(e,_)) = fsize e |
| fsize(T.FMARK(e,_)) = fsize e |
91 |
| fsize _ = raise SizeUnknown |
| fsize _ = raise SizeUnknown |
92 |
|
|
166 |
*) |
*) |
167 |
| T.NOTB(ty,e) => T.XORB(ty,e,T.LI ~1) |
| T.NOTB(ty,e) => T.XORB(ty,e,T.LI ~1) |
168 |
|
|
169 |
|
(* |
170 |
|
* Default ways of converting integers to integers |
171 |
|
*) |
172 |
|
| T.CVTI2I(ty,T.SIGN_EXTEND,e) => |
173 |
|
let val fromTy = size e |
174 |
|
in if fromTy = ty then e |
175 |
|
else if rep = SE andalso fromTy < ty andalso |
176 |
|
fromTy >= hd naturalWidths then e |
177 |
|
else |
178 |
|
let val shift = T.LI(W - fromTy) |
179 |
|
in T.SRA(W,T.SLL(W,e,shift),shift) |
180 |
|
end |
181 |
|
end |
182 |
|
| T.CVTI2I(ty,T.ZERO_EXTEND,e) => |
183 |
|
let val fromTy = size e |
184 |
|
in if fromTy <= ty then e |
185 |
|
else case fromTy of |
186 |
|
8 => T.ANDB(ty,e,T.LI32 0wxff) |
187 |
|
| 16 => T.ANDB(ty,e,T.LI32 0wxffff) |
188 |
|
| 32 => T.ANDB(ty,e,T.LI32 0wxffffffff) |
189 |
|
| _ => raise T.Unsupported("unknown expression",exp) |
190 |
|
end |
191 |
|
|
192 |
|
(* |
193 |
|
* Converting floating point to integers. |
194 |
|
* The following rule handles the case when ty is not |
195 |
|
* one of the naturally supported widths on the machine. |
196 |
|
*) |
197 |
|
| T.CVTF2I(ty,round,e) => |
198 |
|
let val ty' = promoteTy(exp,ty) |
199 |
|
in T.CVTI2I(ty,T.SIGN_EXTEND,T.CVTF2I(ty',round,e)) |
200 |
|
end |
201 |
|
|
202 |
| exp => raise T.Unsupported("unknown expression",exp) |
| exp => raise T.Unsupported("unknown expression",exp) |
203 |
|
|
204 |
(* |
(* |