Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/compiler/ElabData/prim/primop.sig
ViewVC logotype

Annotation of /sml/trunk/compiler/ElabData/prim/primop.sig

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4428 - (view) (download) (as text)
Original Path: sml/trunk/compiler/Semant/prim/primop.sig

1 : monnier 16 (* Copyright 1996 by AT&T Bell Laboratories *)
2 :     (* primop.sig *)
3 :    
4 :     (*********************************************************************
5 :     Integer/Word Conversions Explained
6 :    
7 :     All integer/word conversion operations are expressed using five
8 :     primitive conversion operators. Algebraic equations over these
9 :     operators are easy to define and can be used to simplify composition
10 :     of conversion operations.
11 :    
12 :     The five basic conversion operators are (in all cases, we assume
13 :     that (n >= m):
14 :    
15 :     TEST(n,m) -- map an n-bit, 2's complement signed value to an
16 :     m-bit, 2's complement signed value;
17 :     raise Overflow if the value is too large.
18 :    
19 :     TESTU(n,m) -- map an unsigned n-bit value to an m-bit 2's
20 :     complement value; raise Overflow if the value
21 :     is too large.
22 :    
23 :     EXTEND(m,n) -- sign extend an m-bit value to a n-bit value
24 :    
25 :     TRUNC(n,m) -- truncate an n-bit value to an m-bit value.
26 :    
27 :     COPY(m,n) -- copy an m-bit value to an n-bit value.
28 :    
29 :     TEST, TESTU, and TRUNC are used to go from large values to small
30 :     ones, and EXTEND and COPY are used to go from small values to
31 :     large. The operators EXTEND, TRUNC, and COPY are "pure," while TEST
32 :     and TESTU may raise Overflow.
33 :    
34 :     Conversions where the sizes are the same can be simplified to copies:
35 :    
36 :     TEST(n,n) == COPY(n,n)
37 :     EXTEND(n,n) == COPY(n,n) Note: this does not apply to TESTU
38 :     TRUNC(n,n) == COPY(n,n)
39 :    
40 :     The translation of conversion operations in the Word32 and Word8
41 :     structures (for example) is given by:
42 :    
43 :     Module function => Implemented by
44 :     ----------------------------------------------------------
45 :     Word32 toLargeInt => TESTU(32,32)
46 :     toLargeIntX => EXTEND(32,32) = COPY(32,32)
47 :     fromLargeInt => COPY(32,32)
48 :     toInt => TESTU(32,31)
49 :     toIntX => TEST(32,31)
50 :     fromInt => EXTEND(31,32)
51 :     toLargeWord => COPY(32,32)
52 :     toLargeWordX => EXTEND(32,32) = COPY(32,32)
53 :     fromLargeWord => TRUNC(32,32) = COPY(32,32)
54 :    
55 :     Word8 toLargeInt => COPY(8,32)
56 :     toLargeIntX => EXTEND(8,32)
57 :     fromLargeInt => TRUNC(32,8)
58 :     toInt => COPY(8,31)
59 :     toIntX => EXTEND(8,31)
60 :     fromInt => TRUNC(31,8)
61 :     toLargeWord => COPY(8,32)
62 :     toLargeWordX => EXTEND(8,32)
63 :     fromLargeWord => TRUNC(32,8)
64 :    
65 :    
66 :     Each operator composed with itself is itself, but with different parameters:
67 :    
68 :     TEST(n,m) o TEST(p,n) == TEST(p,m)
69 :     TESTU(n,m) o TESTU(p,n) == TESTU(p,m)
70 :     EXTEND(n,m) o EXTEND(p,n) == EXTEND(p,m)
71 :     TRUNC(n,m) o TRUNC(p,n) == TRUNC(p,m)
72 :     COPY(n,m) o COPY(p,n) == COPY(p,m)
73 :    
74 :     The composition of these operators can be described by a simple algebra.
75 :    
76 :     EXTEND(n,m) o COPY(p,n) == COPY(p,m) if (n > p)
77 :     == EXTEND(p,m) if (n = p)
78 :     COPY(n,m) o EXTEND(p,n) == EXTEND(p,m) if (n = m)
79 :    
80 :     TRUNC(n,m) o COPY(p,n) == COPY(p,m) if (m >= p)
81 :     == TRUNC(p,m) if (m < p)
82 :    
83 :     COPY(n,m) o TRUNC(p,n) == TRUNC(p,m) if (n = m)
84 :    
85 :     TEST(n,m) o COPY(p,n) == COPY(p,m) if (m >= p)
86 :     == TEST(p,m) if (m < p)
87 :    
88 :     TESTU(n,m) o COPY(p,n) == COPY(p,m) if (m >= p)
89 :     == TESTU(p,m) if (m < p)
90 :    
91 :     COPY(n,m) o TEST(p,n) == TEST(p,m) if (n = m)
92 :    
93 :     COPY(n,m) o TESTU(p,n) == TESTU(p,m) if (n = m)
94 :    
95 :     TRUNC(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p)
96 :     == TRUNC(p,m) if (m < p)
97 :    
98 :     TEST(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p)
99 :     == TEST(p,m) if (m < p)
100 :    
101 :     TESTU(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p)
102 :     == TESTU(p,m) if (m < p)
103 :    
104 :     For example, consider:
105 :     Word.toInt o Word.fromLargeWord o Word8.toLargeWord
106 :    
107 :     This translates to:
108 :     TESTU(31,31) o TRUNC(32,31) o COPY(8,32)
109 :    
110 :     and simplifies to:
111 :     TESTU(31,31) o COPY(8,31)
112 :    
113 :     This further simplifies to:
114 :     COPY(8, 31)
115 :    
116 :     Since both 8-bit and 31-bit quantities are tagged the same way, this
117 :     gets translated to a MOVE. With a smart register allocator that MOVE
118 :     can be eliminated.
119 :     *********************************************************************)
120 :    
121 :     signature PRIM_OP =
122 :     sig
123 :    
124 :     (* numkind includes kind and number of bits *)
125 :     datatype numkind
126 :     = INT of int
127 :     | UINT of int
128 :     | FLOAT of int
129 :    
130 :     datatype arithop
131 : george 717 = + | - | * | / | ~ (* int or float *)
132 :     | ABS | FSQRT | FSIN | FCOS | FTAN (* floating point only *)
133 :     | LSHIFT | RSHIFT | RSHIFTL (* int only *)
134 :     | ANDB | ORB | XORB | NOTB (* int only *)
135 : blume 1183 | REM | DIV | MOD (* int only *)
136 : monnier 16
137 : gkuan 2732 datatype cmpop = > | >= | < | <= | LEU | LTU | GEU | GTU | EQL | NEQ
138 :     | FSGN (* floating point only *)
139 : monnier 16
140 : dbm 4428 (* datatype primop:
141 :     * Various primitive operations. Those that are designated "inline" (L:) in
142 :     * the comments are expanded into lambda code in terms of other operators,
143 :     * as are the "checked=true" versions of NUMSUBSCRIPT and NUMUPDATE (L?:).
144 :     * "Environmental" primops (occurring in the InLine structure) are indicated
145 :     * by "E:" in the comment.
146 : monnier 16 *)
147 :     datatype primop
148 : dbm 4428 = ARITH of {oper: arithop, overflow: bool, kind: numkind} (* E: arithmetic ops *)
149 :     | INLLSHIFT of numkind (* E: left shift *)
150 :     | INLRSHIFT of numkind (* E: right shift *)
151 :     | INLRSHIFTL of numkind (* E: right shift logical *)
152 :     | CMP of {oper: cmpop, kind: numkind} (* generic compare *)
153 : monnier 16
154 : dbm 4428 | TESTU of int * int (* E: conversions to int, e.g. testu_31_31 *)
155 :     | TEST of int * int (* E: conversions to int, e.g. test_32_31_w *)
156 :     | TRUNC of int * int (* E: truncations to smaller int/word, e.g. trunc_32_31_i *)
157 :     | EXTEND of int * int (* E: extensions to int32, word32 *)
158 :     | COPY of int * int (* E: conversions, e.g. copy_32_32_ii *)
159 : monnier 16
160 : dbm 4428 | TEST_INF of int (* E: intinf conversions, e.g. test_inf_31 *)
161 :     | TRUNC_INF of int (* E: intinf truncations, e.g. trunc_inf_31 *)
162 :     | EXTEND_INF of int (* E: intinf extensions, e.g. extend_8_inf *)
163 :     | COPY_INF of int (* E: conversions to intinf, e.g. copy_8_inf *)
164 : mblume 1347
165 : dbm 4428 | ROUND of {floor: bool, fromkind: numkind, tokind: numkind} (* E: floor, round *)
166 :     | REAL of {fromkind: numkind, tokind: numkind} (* E: real, real32 *)
167 : monnier 16
168 : dbm 4428 | NUMSUBSCRIPT of {kind: numkind, checked: bool, immutable: bool} (* E: L?: ordof, etc. *)
169 :     | NUMUPDATE of {kind: numkind, checked: bool} (* E: L?: store, etc. *)
170 : monnier 16
171 : dbm 4428 | SUBSCRIPT (* E: polymorphic array subscript *)
172 :     | SUBSCRIPTV (* E: poly vector subscript *)
173 :     | INLSUBSCRIPT (* E: L: poly array subscript *)
174 :     | INLSUBSCRIPTV (* E: L: poly vector subscript *)
175 :     | INLMKARRAY (* E: L: poly array creation *)
176 : monnier 16
177 : dbm 4428 | PTREQL | PTRNEQ (* E: pointer equality *)
178 :     | POLYEQL | POLYNEQ (* E: polymorphic equality *)
179 :     | BOXED | UNBOXED (* E: boxity tests *)
180 :     | LENGTH (* E: vector, string, array, ... length *)
181 :     | OBJLENGTH (* E: length of arbitrary heap object *)
182 :     | CAST (* E: cast *)
183 :     | GETHDLR | SETHDLR (* E: get/set exn handler pointer *)
184 :     | GETVAR | SETVAR (* E: get/set var register *)
185 :     | GETPSEUDO | SETPSEUDO (* E: get/set pseudo registers *)
186 :     | SETMARK | DISPOSE (* E: capture/dispose frames *)
187 :     | MAKEREF (* E: allocate a ref cell *)
188 :     | CALLCC | CAPTURE | THROW (* E: continuation operations *)
189 :     | ISOLATE (* E: isolating a function *)
190 :     | DEREF (* E: dereferencing *)
191 :     | ASSIGN (* E: assignment *)
192 :     | UPDATE (* E: array or reference update (maybe boxed) *)
193 :     | INLUPDATE (* E: L: array update (maybe boxed) *)
194 :     | UNBOXEDUPDATE (* E: update array of integers WITH tags
195 :     * removed by Zhong, put back by Matthias (see FLINT/trans/primopmap.sml) *)
196 :     | GETTAG (* E: extract the tag portion of an
197 :     * object's descriptor as an ML int *)
198 :     | MKSPECIAL (* E: make a special object *)
199 :     | SETSPECIAL (* E: set the state of a special object *)
200 :     | GETSPECIAL (* E: get the state of a special object *)
201 :     | INLMIN of numkind (* E: L: min *)
202 :     | INLMAX of numkind (* E: L: max *)
203 :     | INLABS of numkind (* E: L: abs *)
204 :     | INLNOT (* E: L: bool not operator *)
205 :     | INLCOMPOSE (* E: L: compose "op o" operator *)
206 :     | INLBEFORE (* E: L: "before" operator *)
207 :     | INLIGNORE (* E: L: "ignore" function *)
208 :    
209 :     (* primops to support new array representations *)
210 :     | NEW_ARRAY0 (* E: allocate zero-length array header *)
211 :     | GET_SEQ_DATA (* E: get data pointer from arr/vec header *)
212 :     | SUBSCRIPT_REC (* E: record subscript operation *)
213 :     | SUBSCRIPT_RAW64 (* E: raw64 subscript operation *)
214 : monnier 16
215 : dbm 4428 | INLIDENTITY (* E: polymorphic identity *)
216 : monnier 16
217 : dbm 4428 | CVT64 (* E: convert between external and
218 :     * internal representation of compiler
219 :     * simulated 64-bit scalars, e.g. w64p *)
220 :    
221 : blume 772 (* Primops to support new experimental C FFI. *)
222 : dbm 4428 | RAW_LOAD of numkind (* E: load from arbitrary memory location *)
223 :     | RAW_STORE of numkind (* E: store to arbitrary memory location *)
224 : blume 773 (* make a call to a C-function;
225 :     * The primop carries C function prototype information and specifies
226 :     * which of its (ML-) arguments are floating point. C prototype
227 :     * information is for use by the backend, ML information is for
228 :     * use by the CPS converter. *)
229 :     | RAW_CCALL of { c_proto: CTypes.c_proto,
230 : leunga 1174 ml_args: ccall_type list,
231 :     ml_res_opt: ccall_type option,
232 : dbm 4428 reentrant: bool
233 :     } option (* E: *)
234 : leunga 1174 (* Allocate uninitialized storage on the heap.
235 :     * The record is meant to hold short-lived C objects, i.e., they
236 : blume 1178 * are not ML pointers. The representation is
237 : dbm 4428 * the same as RECORD with tag tag_raw32 or tag_fblock.
238 : leunga 1174 *)
239 : dbm 4428 | RAW_RECORD of { fblock: bool } (* E: *)
240 : monnier 16
241 : dbm 4428 (* non-environmental primops (not found in InLine) *)
242 : mblume 1347
243 : dbm 4428 | UNBOXEDASSIGN (* assignment to integer reference *)
244 : mblume 1683
245 : dbm 4428 | WCAST (* ? *)
246 :     | MARKEXN (* mark an exception value with a string *)
247 :    
248 :     | INL_ARRAY (* L: polymorphic array allocation *)
249 :     | INL_VECTOR (* L: polymorphic vector allocation *)
250 :     | INL_MONOARRAY of numkind (* L: monomorphic array allocation *)
251 :     | INL_MONOVECTOR of numkind (* L: monomorphic vector allocation *)
252 :    
253 :     | MKETAG (* make a new exception tag *)
254 :     | WRAP (* box a value by wrapping it *)
255 :     | UNWRAP (* unbox a value by unwrapping it *)
256 :    
257 : blume 1178 and ccall_type =
258 :     CCI32 | (* passed as int32 *)
259 :     CCI64 | (* int64, currently unused *)
260 :     CCR64 | (* passed as real64 *)
261 :     CCML (* passed as Unsafe.Object.object *)
262 : monnier 45
263 : monnier 16 val IADD : primop (* default integer addition *)
264 :     val ISUB : primop (* default integer subtraction *)
265 :     val IMUL : primop
266 :     val IDIV : primop
267 :     val INEG : primop
268 :    
269 :     val FEQLd : primop
270 :     val IEQL : primop
271 :     val INEQ : primop
272 :     val IGT : primop
273 :     val ILT : primop
274 :     val ILE : primop
275 :     val IGE : primop
276 :    
277 :     val prNumkind : numkind -> string
278 :     val prPrimop: primop -> string
279 :     val mayRaise : primop -> bool
280 : monnier 204 (* This should return more than just a boolean.
281 :     * True means "can not be dead-code eliminated" *)
282 :     val effect : primop -> bool
283 : monnier 16
284 :     end (* signature PRIM_OP *)
285 :    

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0