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/src/compiler/FLINT/kernel/primop.sig
ViewVC logotype

Annotation of /sml/trunk/src/compiler/FLINT/kernel/primop.sig

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1174 - (view) (download) (as text)

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 : monnier 16
136 :     datatype cmpop = > | >= | < | <= | LEU | LTU | GEU | GTU | EQL | NEQ
137 :    
138 :     (*
139 :     * Various primitive operations. Those that are designated "inline" are
140 :     * expanded into lambda code in terms of other operators,
141 :     * as is the "checked=true" version of NUMSUBSCRIPT or NUMUPDATE.
142 :     * NUMSUBSCRIPT and NUMUPDATE are for arrays of floats or integers
143 :     * stored WITHOUT boxing or tags.
144 :     *)
145 :     datatype primop
146 :     = ARITH of {oper: arithop, overflow: bool, kind: numkind}
147 :     | INLLSHIFT of numkind
148 :     | INLRSHIFT of numkind
149 :     | INLRSHIFTL of numkind
150 :     | CMP of {oper: cmpop, kind: numkind}
151 :    
152 :     | TESTU of int * int
153 :     | TEST of int * int
154 :     | TRUNC of int * int
155 :     | EXTEND of int * int
156 :     | COPY of int * int
157 :    
158 :     | ROUND of {floor: bool, fromkind: numkind, tokind: numkind}
159 :     | REAL of {fromkind: numkind, tokind: numkind}
160 :    
161 :     | NUMSUBSCRIPT of {kind: numkind, checked: bool, immutable: bool}
162 :     | NUMUPDATE of {kind: numkind, checked: bool}
163 :    
164 :     | SUBSCRIPT (* polymorphic array subscript *)
165 :     | SUBSCRIPTV (* poly vector subscript *)
166 :     | INLSUBSCRIPT (* inline poly array subscript *)
167 :     | INLSUBSCRIPTV (* inline poly vector subscript *)
168 :     | INLMKARRAY (* inline poly array creation *)
169 :    
170 :     | PTREQL | PTRNEQ (* pointer equality *)
171 :     | POLYEQL | POLYNEQ (* polymorphic equality *)
172 :     | BOXED | UNBOXED (* boxity tests *)
173 :     | LENGTH (* vector, string, array, ... length *)
174 :     | OBJLENGTH (* length of arbitrary heap object *)
175 :     | CAST
176 : monnier 69 | WCAST
177 : monnier 16 | GETRUNVEC (* get the pointer to the run-vector *)
178 :     | MARKEXN (* mark an exception value with a string *)
179 :     | GETHDLR | SETHDLR (* get/set exn handler pointer *)
180 :     | GETVAR | SETVAR (* get/set var register *)
181 :     | GETPSEUDO | SETPSEUDO (* get/set pseudo registers *)
182 :     | SETMARK | DISPOSE (* capture/dispose frames *)
183 :     | MAKEREF (* allocate a ref cell *)
184 :     | CALLCC | CAPTURE | THROW (* continuation operations *)
185 :     | ISOLATE (* isolating a function *)
186 :     | DEREF (* dereferencing *)
187 : monnier 251 | ASSIGN (* assignment *)
188 :     | UNBOXEDASSIGN (* assignment to integer reference *)
189 : monnier 16 | UPDATE (* array update (maybe boxed) *)
190 :     | INLUPDATE (* inline array update (maybe boxed) *)
191 :     | BOXEDUPDATE (* boxed array update *)
192 :     | UNBOXEDUPDATE (* update array of integers WITH tags *)
193 :    
194 :     | GETTAG (* extract the tag portion of an *)
195 :     (* object's descriptor as an ML int *)
196 :     | MKSPECIAL (* make a special object *)
197 :     | SETSPECIAL (* set the state of a special object *)
198 :     | GETSPECIAL (* get the state of a special object *)
199 :     | USELVAR | DEFLVAR
200 :     | INLDIV | INLMOD | INLREM (* inline interger arithmetic *)
201 :     | INLMIN |INLMAX | INLABS (* inline interger arithmetic *)
202 :     | INLNOT (* inline bool not operator *)
203 :     | INLCOMPOSE (* inline compose "op o" operator *)
204 :     | INLBEFORE (* inline "before" operator *)
205 :     | INL_ARRAY (* inline polymorphic array allocation *)
206 :     | INL_VECTOR (* inline polymorphic vector allocation *)
207 :     | INL_MONOARRAY of numkind (* inline monomorphic array allocation *)
208 :     | INL_MONOVECTOR of numkind (* inline monomorphic vector allocation *)
209 :    
210 : monnier 45 | MKETAG (* make a new exception tag *)
211 :     | WRAP (* box a value by wrapping it *)
212 :     | UNWRAP (* unbox a value by unwrapping it *)
213 : monnier 251 (* Primops to support new array representations *)
214 :     | NEW_ARRAY0 (* allocate zero-length array header *)
215 :     | GET_SEQ_DATA (* get data pointer from arr/vec header *)
216 :     | SUBSCRIPT_REC (* record subscript operation *)
217 :     | SUBSCRIPT_RAW64 (* raw64 subscript operation *)
218 : blume 772 (* Primops to support new experimental C FFI. *)
219 :     | RAW_LOAD of numkind (* load from arbitrary memory location *)
220 :     | RAW_STORE of numkind (* store to arbitrary memory location *)
221 : blume 773 (* make a call to a C-function;
222 :     * The primop carries C function prototype information and specifies
223 :     * which of its (ML-) arguments are floating point. C prototype
224 :     * information is for use by the backend, ML information is for
225 :     * use by the CPS converter. *)
226 :     | RAW_CCALL of { c_proto: CTypes.c_proto,
227 : leunga 1174 ml_args: ccall_type list,
228 :     ml_res_opt: ccall_type option,
229 :     reentrant : bool
230 :     } option
231 :     (* Allocate uninitialized storage on the heap.
232 :     * The record is meant to hold short-lived C objects, i.e., they
233 :     * are not ML pointers. With the tag, the representation is
234 :     * the same as RECORD with tag tag_raw32 (sz=4), or tag_fblock (sz=8)
235 :     *)
236 :     | RAW_RECORD of {tag:bool,sz:int}
237 :     and ccall_type = CCALL_INT32 | CCALL_REAL64 | CCALL_ML_PTR
238 : monnier 16
239 : monnier 45
240 : monnier 16 val IADD : primop (* default integer addition *)
241 :     val ISUB : primop (* default integer subtraction *)
242 :     val IMUL : primop
243 :     val IDIV : primop
244 :     val INEG : primop
245 :    
246 :     val FEQLd : primop
247 :     val IEQL : primop
248 :     val INEQ : primop
249 :     val IGT : primop
250 :     val ILT : primop
251 :     val ILE : primop
252 :     val IGE : primop
253 :    
254 :     val prNumkind : numkind -> string
255 :     val prPrimop: primop -> string
256 :     val mayRaise : primop -> bool
257 : monnier 204 (* This should return more than just a boolean.
258 :     * True means "can not be dead-code eliminated" *)
259 :     val effect : primop -> bool
260 : monnier 16
261 :     end (* signature PRIM_OP *)
262 :    

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