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 /dev-notes/primop-list.md
ViewVC logotype

Annotation of /dev-notes/primop-list.md

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4993 - (view) (download)

1 : jhr 4876 # SML/NJ Primitive Operations
2 :    
3 :     This document describes the primitive operators (primops) that the
4 :     compiler exposes. These are used to define the `InlineT` structure,
5 :     which, in turn is used in the implementation of the Basis Library.
6 :     With the addition of 64-bit targets, the mapping from primop to
7 :     internal representation becomes target-specific in many cases.
8 :    
9 :    
10 :     ## Relavant source files
11 :    
12 :     * `compiler/ElabData/prim/primop.sml`<br/>
13 :     this file defines the `Primop` structure, which includes the various
14 :     datatypes used to represent primitive operations internally in the
15 :     front-end of the compiler. The main type is `Primop.primop`.
16 :    
17 : jhr 4985 * `compiler/ElabData/prim/primop.sig`<br/>
18 : jhr 4876 this file defines the `PRIMOP` signature use for the `Primop` structure.
19 :    
20 :     * `compiler/Semant/prim/primop-bindings.sml`<br/>
21 :     this file defines the bindings between the SML variables
22 :     exposed by the compiler and the internal `Primop.primop`
23 :     type.
24 :    
25 :     * `system/smlnj/init/built-in32.sml`<br/>
26 :     this file defines the `InlineT` structure for 32-bit targets
27 :    
28 :    
29 :     ## Naming conventions
30 :    
31 : jhr 4879 Operations that "belong" to a specific type (*e.g.*, addition) have an initial
32 :     prefix that specifies the type as follows:
33 :    
34 :     * "`int`" -- default tagged integer type (*i.e.*, either `Int31.int` or `Int63.int`)
35 :     * "`word`" -- default tagged word type (*i.e.*, either `Word31.word` or `Word63.word`)
36 :     * "`int32`" -- 32-bit integers
37 :     * "`word32`" -- 32-bit words
38 :     * "`int64`" -- 64-bit integers
39 :     * "`word64`" -- 64-bit words
40 :     * "`intinf`" -- arbitrary precision integers
41 :     * "`real32`" -- 32-bit real numbers (not yet supported)
42 :     * "`real64`" -- 64-bit real numbers
43 :     * "`ptr`" -- machine address
44 :     * "`barr`" -- bytearray (used for arrays of `Word8.word` and `char`)
45 :     * "`bvec`" -- bytevector (used for strings and vectors of `Word8.word`)
46 :     * "`arr`" -- polymorphic arrays
47 :     * "`vec`" -- polymorphic vectors
48 : jhr 4880 * "`seq`" -- sequence types (arrays and vectors)
49 : jhr 4879
50 : jhr 4978 Following the type prefix may one or more attributes, which highlight properties
51 :     of the operation.
52 :    
53 : jhr 4879 We use the attribute "`raw`" to denote direct machine operations that are not
54 :     directly accesible in the Basis Library (*e.g.*, shift operations, where the basis
55 :     versions clamp the shift amount to the word size, but the raw versions do not).
56 :    
57 :     We use the attribute "`unsafe`" for operations that could potentially result in
58 :     a crash (*e.g.*, array subscript operations that do not check the index against
59 :     the array bounds).
60 :    
61 : jhr 4876 ## Primitive operators
62 :    
63 :     ### Size-independent primops
64 :    
65 :     #### Continuation operators
66 :     * `callcc : ('a cont -> 'a) -> 'a`<br/>
67 :     `P.CALLCC`
68 :    
69 :     * `throw : 'a cont -> 'a -> 'b`<br/>
70 :     `P.THROW`
71 :    
72 :     * `capture : ('a control_cont -> 'a) -> 'a`<br/>
73 :     `P.CAPTURE`
74 :    
75 :     * `isolate : ('a -> unit) -> 'a cont`<br/>
76 :     `P.ISOLATE`
77 :    
78 :     * `cthrow : 'a control_cont -> 'a -> 'b`<br/>
79 :     `P.THROW`
80 :    
81 :    
82 :     #### Reference operations
83 :     * `! : 'a ref -> 'a`<br/>
84 :     `P.DEREF`
85 :    
86 : jhr 4879 * `:= : 'a ref * 'a -> unit`<br/>
87 : jhr 4876 `P.ASSIGN`
88 :    
89 :     * `makeref : 'a ref * 'a -> unit`<br/>
90 :     `P.MAKEREF`
91 :    
92 :    
93 :     #### Boxity tests
94 :     * `boxed : 'a -> bool`<br/>
95 :     `P.BOXED`
96 :    
97 :     * `unboxed : 'a -> bool`<br/>
98 :     `P.UNBOXED`
99 :    
100 :    
101 :     #### Type cast
102 :     * `cast : 'a -> 'b`<br/>
103 :     `P.CAST`
104 :    
105 :    
106 :     #### Equality tests
107 :     * `= : ''a * ''a -> bool`<br/>
108 :     `P.POLYEQL`
109 :    
110 :     * `<> : ''a * ''a -> bool`<br/>
111 :     `P.POLYNEQ`
112 :    
113 : jhr 4885 * `ptr_eql : 'a * 'a -> bool`<br/>
114 : jhr 4876 `P.PTREQL`
115 :    
116 : jhr 4885 * `ptr_neq : 'a * 'a -> bool`<br/>
117 : jhr 4876 `P.PTRNEQ`
118 :    
119 :    
120 :     #### Runtime hooks
121 :     * `getvar : unit -> 'a`<br/>
122 :     `P.GETVAR`
123 :    
124 :     * `setvar : 'a -> unit`<br/>
125 :     `P.SETVAR`
126 :    
127 :     * `mkspecial : int * 'a -> 'b`<br/>
128 :     `P.MKSPECIAL`
129 :    
130 :     * `getspecial : 'a -> int`<br/>
131 :     `P.GETSPECIAL`
132 :    
133 :     * `setspecial : 'a * int -> unit`<br/>
134 :     `P.SETSPECIAL`
135 :    
136 :     * `gethdlr : unit -> 'a cont`<br/>
137 :     `P.GETHDLR`
138 :    
139 :     * `sethdlr : 'a cont -> unit`<br/>
140 :     `P.SETHDLR`
141 :    
142 :     * `gettag : 'a -> int`<br/>
143 :     `P.GETTAG`
144 :    
145 : jhr 4888 * `objlength : 'a -> int`<br/>
146 :     extracts the length field from an object's header word.
147 : jhr 4988 (`P.OBJLENGTH`)
148 : jhr 4876
149 :    
150 :     #### Inline operations
151 : jhr 4888 These primops are Basis Library functions that should be inlined for efficiency.
152 : jhr 4876 * `compose : ('b -> 'c) * ('a -> 'b) -> 'a -> 'c`<br/>
153 :     `P.INLCOMPOSE`
154 :    
155 :     * `before : 'a * 'b -> 'a`<br/>
156 :     `P.INLBEFORE`
157 :    
158 :     * `ignore : 'a -> unit`<br/>
159 :     `P.INLIGNORE`
160 :    
161 :     * `identity : 'a -> 'a`<br/>
162 :     `P.INLIDENTITY`
163 :    
164 : jhr 4879 * `bool_not : bool -> bool`<br/>
165 : jhr 4876 `P.INLNOT`
166 :    
167 : jhr 4978 Some additional candidates for inlined operations include `hd`, `tl`, `null`, `chr`,
168 :     and `ord`.
169 :    
170 : jhr 4888 If the compiler had the `option` and `order` datatypes builtin (like `bool` and `list`),
171 : jhr 4978 then `valOf`, `isSome`, `isNone` and some of the `compare` functions could also
172 :     be inlined.
173 : jhr 4876
174 : jhr 4978 In the long run, however, a better way to support inlining library functions would
175 :     be through a reliable cross-module inliner.
176 : jhr 4888
177 : jhr 4876 #### Bytearray and bytevector operations
178 : jhr 4879 Operations on byte/char array/vectors. We renamed these to make it clear
179 :     which operations do bounds checking and which do not.
180 : jhr 4876
181 : jhr 4879 * `bvec_unsafe_sub : 'a * int -> 'b`<br/>
182 :     subscript from byte vector without bounds checking
183 :     (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=true}`)
184 : jhr 4876
185 : jhr 4879 * `barr_unsafe_sub : 'a * int -> 'b`<br/>
186 :     subscript from byte array without bounds checking
187 :     (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=false}`)
188 : jhr 4876
189 : jhr 4879 * `barr_unsafe_update : 'a * int * 'b -> unit`<br/>
190 :     update byte array without bounds checking
191 :     (`P.NUMUPDATE{kind=P.INT 8, checked=false}`)
192 : jhr 4876
193 : jhr 4879 * `bvec_sub : 'a * int -> 'b`<br/>
194 :     subscript from byte vector
195 :     (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=true}`)
196 : jhr 4876
197 : jhr 4879 * `barr_sub : 'a * int -> 'b`<br/>
198 :     subscript from byte array
199 :     (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=false}`)
200 : jhr 4876
201 : jhr 4879 * `barr_update : 'a * int * 'b -> unit`<br/>
202 :     update byte array
203 :     (`P.NUMUPDATE{kind=P.INT 8, checked=true}`)
204 :    
205 : jhr 4876 #### Polymorphic array and vector
206 :     * `mkarray : int * 'a -> 'a array`<br/>
207 : jhr 4879 create a polymorphic array
208 :     (`P.INLMKARRAY`)
209 : jhr 4876
210 : jhr 4879 * `arr_unsafe_sub : 'a array * int -> 'a`<br/>
211 :     subscript from polymorphic array without bounds checking
212 :     (`P.SUBSCRIPT`)
213 : jhr 4876
214 : jhr 4879 * `arr_sub : 'a array * int -> 'a`<br/>
215 :     subscript from polymorphic array
216 :     (`P.INLSUBSCRIPT`)
217 : jhr 4876
218 : jhr 4879 * `vec_unsafe_sub : 'a vector * int -> 'a`<br/>
219 :     subscript from polymorphic vector without bounds checking
220 :     (`P.SUBSCRIPTV`)
221 : jhr 4876
222 : jhr 4879 * `vec_sub : 'a vector * int -> 'a`<br/>
223 :     subscript from polymorphic vector
224 :     (`P.INLSUBSCRIPTV`)
225 : jhr 4876
226 : jhr 4879 * `arr_unsafe_update : 'a array * int * 'a -> unit`<br/>
227 :     update a polymorphic array without bounds checking
228 :     (`P.UPDATE`)
229 : jhr 4876
230 : jhr 4879 * `arr_update : 'a array * int * 'a -> unit`<br/>
231 :     update a polymorphic array
232 :     (`P.INLUPDATE`)
233 : jhr 4876
234 : jhr 4879 * `arr_unboxed_update : 'a array * int * 'a -> unit`<br/>
235 :     update a polymorphic array with an unboxed value, which means that there is
236 :     no store-list entry created for the update.
237 : jhr 4988 (`P.UNBOXEDUPDATE`)
238 : jhr 4876
239 :     #### Sequence operations
240 : jhr 4880 Sequence values (*e.g.*, `string`, `'a array`, `RealVector.vector`, *etc*.)
241 :     are represented by a header consisting of a length (in elements) and a data
242 :     pointer to the raw sequence data.
243 :    
244 : jhr 4876 * `newArray0 : unit -> 'a`<br/>
245 :     `P.NEW_ARRAY0`
246 :    
247 : jhr 4880 * `seq_length : 'a -> int`<br/>
248 :     get the length field from a sequence header
249 : jhr 4988 (`P.LENGTH`)
250 : jhr 4880
251 :     * `seq_data : 'a -> 'b`<br/>
252 :     get the length field from a sequence header
253 : jhr 4988 (`P.GET_SEQ_DATA`)
254 : jhr 4876
255 : jhr 4879 * `unsafe_record_sub : 'a * int -> 'b`<br/>
256 : jhr 4876 `P.SUBSCRIPT_REC`
257 :    
258 :     * `raw64Sub : 'a * int -> real64`<br/>
259 : jhr 4978 gets an element from a packed tuple of 64-bit reals. The only use of
260 :     this function is in the implementation of the `Unsafe.Object.nth`
261 :     function. <br/>
262 : jhr 4988 (`P.SUBSCRIPT_RAW64`)
263 : jhr 4876
264 :    
265 :     ### Numeric primops
266 :    
267 :     #### Default tagged integer operations
268 : jhr 4879 These are the primitive operations on the default tagged integer
269 :     type (`Int.int`).
270 :    
271 : jhr 4876 * `int_add : int * int -> int`<br/>
272 : jhr 4884 Signed integer addition with overflow checking.
273 : jhr 4988 (`P.ARITH{oper=P.ADD, overflow=true, kind=P.INT <int-size>}`)
274 : jhr 4876
275 : jhr 4884 * `int_unsafe_add : int * int -> int`<br/>
276 :     Signed integer addition *without* overflow checking.
277 : jhr 4988 (`P.ARITH{oper=P.ADD, overflow=false, kind=P.INT <int-size>}`)
278 : jhr 4884
279 : jhr 4876 * `int_sub : int * int -> int`<br/>
280 : jhr 4884 Signed integer subtraction with overflow checking.
281 : jhr 4988 (`P.ARITH{oper=P.SUB, overflow=true, kind=P.INT <int-size>}`)
282 : jhr 4876
283 : jhr 4884 * `int_unsafe_sub : int * int -> int`<br/>
284 :     Signed integer subtraction *without* overflow checking.
285 : jhr 4988 (`P.ARITH{oper=P.SUB, overflow=false, kind=P.INT <int-size>}`)
286 : jhr 4884
287 : jhr 4876 * `int_mul : int * int -> int`<br/>
288 :     `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT <int-size>}`
289 :    
290 :     * `int_div : int * int -> int`<br/>
291 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT <int-size>}`
292 :    
293 :     * `int_mod : int * int -> int`<br/>
294 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT <int-size>}`
295 :    
296 :     * `int_quot : int * int -> int`<br/>
297 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT <int-size>}`
298 :    
299 :     * `int_rem : int * int -> int`<br/>
300 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT <int-size>}`
301 :    
302 :     * `int_orb : int * int -> int`<br/>
303 :     `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT <int-size>}`
304 :    
305 :     * `int_xorb : int * int -> int`<br/>
306 :     `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT <int-size>}`
307 :    
308 :     * `int_andb : int * int -> int`<br/>
309 :     `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT <int-size>}`
310 :    
311 :     * `int_neg : word32 -> word32`<br/>
312 :     `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT <int-size>}`
313 :    
314 :     * `int_raw_rshift : int * word -> int`<br/>
315 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT <int-size>}`
316 :    
317 :     * `int_raw_lshift : int * word -> int`<br/>
318 :     `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT <int-size>}`
319 :    
320 :     * `int_gt : int * int -> bool`<br/>
321 :     `P.CMP{oper=P.GT, kind=P.INT <int-size>}`
322 :    
323 :     * `int_ge : int * int -> bool`<br/>
324 :     `P.CMP{oper=P.GTE, kind=P.INT <int-size>}`
325 :    
326 :     * `int_lt : int * int -> bool`<br/>
327 :     `P.CMP{oper=P.LT, kind=P.INT <int-size>}`
328 :    
329 :     * `int_le : int * int -> bool`<br/>
330 :     `P.CMP{oper=P.LTE, kind=P.INT <int-size>}`
331 :    
332 : jhr 4885 * `int_eql : int * int -> bool`<br/>
333 : jhr 4876 `P.CMP{oper=P.EQL, kind=P.INT <int-size>}`
334 :    
335 : jhr 4885 * `int_neq : int * int -> bool`<br/>
336 : jhr 4876 `P.CMP{oper=P.NEQ, kind=P.INT <int-size>}`
337 :    
338 :     * `int_min : int * int -> int`<br/>
339 :     `P.INLMIN (P.INT <int-size>)`
340 :    
341 :     * `int_max : int * int -> int`<br/>
342 :     `P.INLMAX (P.INT <int-size>)`
343 :    
344 : jhr 4985 * `int_abs : int -> int`<br/>
345 : jhr 4876 `P.INLABS (P.INT <int-size>)`
346 :    
347 :     #### Default tagged word operations
348 : jhr 4879 These are the primitive operations on the default tagged word
349 :     type (`Word.word`).
350 :    
351 : jhr 4876 * `word_mul : word * word -> word`<br/>
352 : jhr 4985 `P.ARITH{oper=P.MUL, overflow=false, kind=P.UINT <int-size>}`
353 : jhr 4876
354 :     * `word_div : word * word -> word`<br/>
355 : jhr 4985 `P.ARITH{oper=P.QUOT, overflow=false, kind=P.UINT <int-size>}`
356 : jhr 4876
357 :     * `word_mod : word * word -> word`<br/>
358 : jhr 4985 `P.ARITH{oper=P.REM, overflow=false, kind=P.UINT <int-size>}`
359 : jhr 4876
360 :     * `word_add : word * word -> word`<br/>
361 : jhr 4985 `P.ARITH{oper=P.ADD, overflow=false, kind=P.UINT <int-size>}`
362 : jhr 4876
363 :     * `word_sub : word * word -> word`<br/>
364 : jhr 4985 `P.ARITH{oper=P.SUB, overflow=false, kind=P.UINT <int-size>}`
365 : jhr 4876
366 :     * `word_orb : word * word -> word`<br/>
367 : jhr 4985 `P.ARITH{oper=P.ORB, overflow=false, kind=P.UINT <int-size>}`
368 : jhr 4876
369 :     * `word_xorb : word * word -> word`<br/>
370 : jhr 4985 `P.ARITH{oper=P.XORB, overflow=false, kind=P.UINT <int-size>}`
371 : jhr 4876
372 :     * `word_andb : word * word -> word`<br/>
373 : jhr 4985 `P.ARITH{oper=P.ANDB, overflow=false, kind=P.UINT <int-size>}`
374 : jhr 4876
375 :     * `word_notb : word -> word`<br/>
376 : jhr 4985 `P.ARITH{oper=P.NOTB, overflow=false, kind=P.UINT <int-size>}`
377 : jhr 4876
378 :     * `word_neg : word -> word`<br/>
379 : jhr 4985 `P.ARITH{oper=P.NEG, overflow=false, kind=P.UINT <int-size>}`
380 : jhr 4876
381 :     * `word_rshift : word * word -> word`<br/>
382 : jhr 4985 `P.INLRSHIFT(P.UINT <int-size>)`
383 : jhr 4876
384 :     * `word_rshiftl : word * word -> word`<br/>
385 : jhr 4985 `P.INLRSHIFTL(P.UINT <int-size>)`
386 : jhr 4876
387 :     * `word_lshift : word * word -> word`<br/>
388 : jhr 4985 `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.UINT <int-size>}`
389 : jhr 4876
390 : jhr 4985 * `word_raw_rshift : word * word -> word`<br/>
391 :     `P.INLLSHIFT(P.UINT <int-size>)`
392 :    
393 :     * `word_raw_rshiftl : word * word -> word`<br/>
394 :     `P.ARITH{oper=P.RSHIFTL, overflow=false, kind=P.UINT <int-size>}`
395 :    
396 :     * `word_raw_lshift : word * word -> word`<br/>
397 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.UINT <int-size>}`
398 :    
399 : jhr 4876 * `word_gt : word * word -> bool`<br/>
400 :     `P.CMP{oper=P.GT, kind=P.UINT <int-size>}`
401 :    
402 :     * `word_ge : word * word -> bool`<br/>
403 :     `P.CMP{oper=P.GTE, kind=P.UINT <int-size>}`
404 :    
405 :     * `word_lt : word * word -> bool`<br/>
406 :     `P.CMP{oper=P.LT, kind=P.UINT <int-size>}`
407 :    
408 :     * `word_le : word * word -> bool`<br/>
409 :     `P.CMP{oper=P.LTE, kind=P.UINT <int-size>}`
410 :    
411 : jhr 4885 * `word_eql : word * word -> bool`<br/>
412 : jhr 4876 `P.CMP{oper=P.EQL, kind=P.UINT <int-size>}`
413 :    
414 : jhr 4885 * `word_neq : word * word -> bool`<br/>
415 : jhr 4876 `P.CMP{oper=P.NEQ, kind=P.UINT <int-size>}`
416 :    
417 :     * `word_min : word * word -> word`<br/>
418 :     `P.INLMIN (P.UINT <int-size>)`
419 :    
420 :     * `word_max : word * word -> word`<br/>
421 :     `P.INLMAX (P.UINT <int-size>)`
422 :    
423 :     #### 8-bit word operations
424 :    
425 :     #### 32-bit integer operations
426 :     * `int32_add : int32 * int32 -> int32`<br/>
427 :     `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT 32}`
428 :    
429 :     * `int32_sub : int32 * int32 -> int32`<br/>
430 :     `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT 32}`
431 :    
432 :     * `int32_mul : int32 * int32 -> int32`<br/>
433 :     `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT 32}`
434 :    
435 :     * `int32_div : int32 * int32 -> int32`<br/>
436 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 32}`
437 :    
438 :     * `int32_mod : int32 * int32 -> int32`<br/>
439 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 32}`
440 :    
441 :     * `int32_quot : int32 * int32 -> int32`<br/>
442 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 32}`
443 :    
444 :     * `int32_rem : int32 * int32 -> int32`<br/>
445 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 32}`
446 :    
447 :     * `int32_orb : int32 * int32 -> int32`<br/>
448 :     `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT 32}`
449 :    
450 :     * `int32_xorb : int32 * int32 -> int32`<br/>
451 :     `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT 32}`
452 :    
453 :     * `int32_andb : int32 * int32 -> int32`<br/>
454 :     `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT 32}`
455 :    
456 :     * `int32_neg : word32 -> word32`<br/>
457 :     `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT 32}`
458 :    
459 :     * `int32_raw_rshift : int32 * word -> int32`<br/>
460 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT 32}`
461 :    
462 :     * `int32_raw_lshift : int32 * word -> int32`<br/>
463 :     `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT 32}`
464 :    
465 :     * `int32_gt : int32 * int32 -> bool`<br/>
466 :     `P.CMP{oper=P.GT, kind=P.INT 32}`
467 :    
468 :     * `int32_ge : int32 * int32 -> bool`<br/>
469 :     `P.CMP{oper=P.GTE, kind=P.INT 32}`
470 :    
471 :     * `int32_lt : int32 * int32 -> bool`<br/>
472 :     `P.CMP{oper=P.LT, kind=P.INT 32}`
473 :    
474 :     * `int32_le : int32 * int32 -> bool`<br/>
475 :     `P.CMP{oper=P.LTE, kind=P.INT 32}`
476 :    
477 : jhr 4885 * `int32_eql : int32 * int32 -> bool`<br/>
478 : jhr 4876 `P.CMP{oper=P.EQL, kind=P.INT 32}`
479 :    
480 : jhr 4885 * `int32_neq : int32 * int32 -> bool`<br/>
481 : jhr 4876 `P.CMP{oper=P.NEQ, kind=P.INT 32}`
482 :    
483 :     * `int32_min : int32 * int32 -> int32`<br/>
484 :     `P.INLMIN (P.INT 32)`
485 :    
486 :     * `int32_max : int32 * int32 -> int32`<br/>
487 :     `P.INLMAX (P.INT 32)`
488 :    
489 : jhr 4985 * `int32_abs : int32 -> int32`<br/>
490 : jhr 4876 `P.INLABS (P.INT 32)`
491 :    
492 :     #### 32-bit word operations
493 : jhr 4985 These operations work on the boxed 32-bit word type on 32-bit
494 :     machines and are just wrappers for 63-bit tagged word operations
495 :     on 64-bit machines.
496 : jhr 4876
497 : jhr 4985 * `word32_mul : word32 * word32 -> word32`<br/>
498 :     `P.ARITH{oper=P.MUL, overflow=false, kind=P.UINT 32}`
499 :    
500 :     * `word32_div : word32 * word32 -> word32`<br/>
501 :     `P.ARITH{oper=P.QUOT, overflow=false, kind=P.UINT 32}`
502 :    
503 :     * `word32_mod : word32 * word32 -> word32`<br/>
504 :     `P.ARITH{oper=P.REM, overflow=false, kind=P.UINT 32}`
505 :    
506 :     * `word32_add : word32 * word32 -> word32`<br/>
507 :     `P.ARITH{oper=P.ADD, overflow=false, kind=P.UINT 32}`
508 :    
509 :     * `word32_sub : word32 * word32 -> word32`<br/>
510 :     `P.ARITH{oper=P.SUB, overflow=false, kind=P.UINT 32}`
511 :    
512 :     * `word32_orb : word32 * word32 -> word32`<br/>
513 :     `P.ARITH{oper=P.ORB, overflow=false, kind=P.UINT 32}`
514 :    
515 :     * `word32_xorb : word32 * word32 -> word32`<br/>
516 :     `P.ARITH{oper=P.XORB, overflow=false, kind=P.UINT 32}`
517 :    
518 :     * `word32_andb : word32 * word32 -> word32`<br/>
519 :     `P.ARITH{oper=P.ANDB, overflow=false, kind=P.UINT 32}`
520 :    
521 :     * `word32_notb : word32 -> word32`<br/>
522 :     `P.ARITH{oper=P.NOTB, overflow=false, kind=P.UINT 32}`
523 :    
524 :     * `word32_neg : word32 -> word32`<br/>
525 :     `P.ARITH{oper=P.NEG, overflow=false, kind=P.UINT 32}`
526 :    
527 :     * `word32_rshift : word32 * word -> word`<br/>
528 :     `P.INLRSHIFT(P.UINT 32)`
529 :    
530 :     * `word32_rshiftl : word32 * word -> word`<br/>
531 :     `P.INLRSHIFTL(P.UINT 32)`
532 :    
533 :     * `word32_lshift : word32 * word -> word`<br/>
534 :     `P.INLLSHIFT(P.UINT 32)`
535 :    
536 :     * `word32_raw_rshift : word32 * word -> word`<br/>
537 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.UINT 32}`
538 :    
539 :     * `word32_raw_rshiftl : word32 * word -> word`<br/>
540 :     `P.ARITH{oper=P.RSHIFTL, overflow=false, kind=P.UINT 32}`
541 :    
542 :     * `word32_raw_lshift : word32 * word -> word`<br/>
543 :     `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.UINT 32}`
544 :    
545 :     * `word32_gt : word32 * word32 -> bool`<br/>
546 :     `P.CMP{oper=P.GT, kind=P.UINT 32}`
547 :    
548 :     * `word32_ge : word32 * word32 -> bool`<br/>
549 :     `P.CMP{oper=P.GTE, kind=P.UINT 32}`
550 :    
551 :     * `word32_lt : word32 * word32 -> bool`<br/>
552 :     `P.CMP{oper=P.LT, kind=P.UINT 32}`
553 :    
554 :     * `word32_le : word32 * word32 -> bool`<br/>
555 :     `P.CMP{oper=P.LTE, kind=P.UINT 32}`
556 :    
557 :     * `word32_eql : word32 * word32 -> bool`<br/>
558 :     `P.CMP{oper=P.EQL, kind=P.UINT 32}`
559 :    
560 :     * `word32_neq : word32 * word32 -> bool`<br/>
561 :     `P.CMP{oper=P.NEQ, kind=P.UINT 32}`
562 :    
563 :     * `word32_min : word32 * word32 -> word32`<br/>
564 :     `P.INLMIN (P.UINT 32)`
565 :    
566 :     * `word32_max : word32 * word32 -> word32`<br/>
567 :     `P.INLMAX (P.UINT 32)`
568 :    
569 : jhr 4876 #### 64-bit integer operations
570 :     * `int64_add : int64 * int64 -> int64`<br/>
571 :     `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT 64}`
572 :    
573 :     * `int64_sub : int64 * int64 -> int64`<br/>
574 :     `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT 64}`
575 :    
576 :     * `int64_mul : int64 * int64 -> int64`<br/>
577 :     `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT 64}`
578 :    
579 :     * `int64_div : int64 * int64 -> int64`<br/>
580 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 64}`
581 :    
582 :     * `int64_mod : int64 * int64 -> int64`<br/>
583 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 64}`
584 :    
585 :     * `int64_quot : int64 * int64 -> int64`<br/>
586 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 64}`
587 :    
588 :     * `int64_rem : int64 * int64 -> int64`<br/>
589 :     `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 64}`
590 :    
591 :     * `int64_orb : int64 * int64 -> int64`<br/>
592 :     `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT 64}`
593 :    
594 :     * `int64_xorb : int64 * int64 -> int64`<br/>
595 :     `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT 64}`
596 :    
597 :     * `int64_andb : int64 * int64 -> int64`<br/>
598 :     `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT 64}`
599 :    
600 :     * `int64_neg : word32 -> word32`<br/>
601 :     `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT 64}`
602 :    
603 :     * `int64_raw_rshift : int64 * word -> int64`<br/>
604 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT 64}`
605 :    
606 :     * `int64_raw_lshift : int64 * word -> int64`<br/>
607 :     `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT 64}`
608 :    
609 :     * `int64_gt : int64 * int64 -> bool`<br/>
610 :     `P.CMP{oper=P.GT, kind=P.INT 64}`
611 :    
612 :     * `int64_ge : int64 * int64 -> bool`<br/>
613 :     `P.CMP{oper=P.GTE, kind=P.INT 64}`
614 :    
615 :     * `int64_lt : int64 * int64 -> bool`<br/>
616 :     `P.CMP{oper=P.LT, kind=P.INT 64}`
617 :    
618 :     * `int64_le : int64 * int64 -> bool`<br/>
619 :     `P.CMP{oper=P.LTE, kind=P.INT 64}`
620 :    
621 : jhr 4885 * `int64_eql : int64 * int64 -> bool`<br/>
622 : jhr 4876 `P.CMP{oper=P.EQL, kind=P.INT 64}`
623 :    
624 : jhr 4885 * `int64_neq : int64 * int64 -> bool`<br/>
625 : jhr 4876 `P.CMP{oper=P.NEQ, kind=P.INT 64}`
626 :    
627 :     * `int64_min : int64 * int64 -> int64`<br/>
628 :     `P.INLMIN (P.INT 64)`
629 :    
630 :     * `int64_max : int64 * int64 -> int64`<br/>
631 :     `P.INLMAX (P.INT 64)`
632 :    
633 : jhr 4985 * `int64_abs : int64 -> int64`<br/>
634 : jhr 4876 `P.INLABS (P.INT 64)`
635 :    
636 :     #### 64-bit word operations
637 :    
638 : jhr 4985 * `word64_mul : word64 * word64 -> word64`<br/>
639 :     `P.ARITH{oper=P.MUL, overflow=false, kind=P.UINT 64}`
640 :    
641 :     * `word64_div : word64 * word64 -> word64`<br/>
642 :     `P.ARITH{oper=P.QUOT, overflow=false, kind=P.UINT 64}`
643 :    
644 :     * `word64_mod : word64 * word64 -> word64`<br/>
645 :     `P.ARITH{oper=P.REM, overflow=false, kind=P.UINT 64}`
646 :    
647 :     * `word64_add : word64 * word64 -> word64`<br/>
648 :     `P.ARITH{oper=P.ADD, overflow=false, kind=P.UINT 64}`
649 :    
650 :     * `word64_sub : word64 * word64 -> word64`<br/>
651 :     `P.ARITH{oper=P.SUB, overflow=false, kind=P.UINT 64}`
652 :    
653 :     * `word64_orb : word64 * word64 -> word64`<br/>
654 :     `P.ARITH{oper=P.ORB, overflow=false, kind=P.UINT 64}`
655 :    
656 :     * `word64_xorb : word64 * word64 -> word64`<br/>
657 :     `P.ARITH{oper=P.XORB, overflow=false, kind=P.UINT 64}`
658 :    
659 :     * `word64_andb : word64 * word64 -> word64`<br/>
660 :     `P.ARITH{oper=P.ANDB, overflow=false, kind=P.UINT 64}`
661 :    
662 :     * `word64_notb : word64 -> word64`<br/>
663 :     `P.ARITH{oper=P.NOTB, overflow=false, kind=P.UINT 64}`
664 :    
665 :     * `word64_neg : word64 -> word64`<br/>
666 :     `P.ARITH{oper=P.NEG, overflow=false, kind=P.UINT 64}`
667 :    
668 :     * `word64_rshift : word64 * word -> word`<br/>
669 :     `P.INLRSHIFT(P.UINT 64)`
670 :    
671 :     * `word64_rshiftl : word64 * word -> word`<br/>
672 :     `P.INLRSHIFTL(P.UINT 64)`
673 :    
674 :     * `word64_lshift : word64 * word -> word`<br/>
675 :     `P.INLLSHIFT(P.UINT 64)`
676 :    
677 :     * `word64_raw_rshift : word64 * word -> word`<br/>
678 :     `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.UINT 64}`
679 :    
680 :     * `word64_raw_rshiftl : word64 * word -> word`<br/>
681 :     `P.ARITH{oper=P.RSHIFTL, overflow=false, kind=P.UINT 64}`
682 :    
683 :     * `word64_raw_lshift : word64 * word -> word`<br/>
684 :     `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.UINT 64}`
685 :    
686 :     * `word64_gt : word64 * word64 -> bool`<br/>
687 :     `P.CMP{oper=P.GT, kind=P.UINT 64}`
688 :    
689 :     * `word64_ge : word64 * word64 -> bool`<br/>
690 :     `P.CMP{oper=P.GTE, kind=P.UINT 64}`
691 :    
692 :     * `word64_lt : word64 * word64 -> bool`<br/>
693 :     `P.CMP{oper=P.LT, kind=P.UINT 64}`
694 :    
695 :     * `word64_le : word64 * word64 -> bool`<br/>
696 :     `P.CMP{oper=P.LTE, kind=P.UINT 64}`
697 :    
698 :     * `word64_eql : word64 * word64 -> bool`<br/>
699 :     `P.CMP{oper=P.EQL, kind=P.UINT 64}`
700 :    
701 :     * `word64_neq : word64 * word64 -> bool`<br/>
702 :     `P.CMP{oper=P.NEQ, kind=P.UINT 64}`
703 :    
704 :     * `word64_min : word64 * word64 -> word64`<br/>
705 :     `P.INLMIN (P.UINT 64)`
706 :    
707 :     * `word64_max : word64 * word64 -> word64`<br/>
708 :     `P.INLMAX (P.UINT 64)`
709 :    
710 : jhr 4876 #### 64-bit real operations
711 : jhr 4985 * `real64_add : real64 * real64 -> real64`<br/>
712 :     `P.ARITH{oper=P.ADD, overflow=true, kind=P.FLOAT 64}`
713 : jhr 4876
714 : jhr 4985 * `real64_sub : real64 * real64 -> real64`<br/>
715 :     `P.ARITH{oper=P.SUB, overflow=true, kind=P.FLOAT 64}`
716 :    
717 :     * `real64_mul : real64 * real64 -> real64`<br/>
718 :     `P.ARITH{oper=P.MUL, overflow=true, kind=P.FLOAT 64}`
719 :    
720 :     * `real64_div : real64 * real64 -> real64`<br/>
721 :     `P.ARITH{oper=P.QUOT, overflow=true, kind=P.FLOAT 64}`
722 :    
723 :     * `real64_neg : word32 -> word32`<br/>
724 :     `P.ARITH{oper=P.NEG, overflow=true, kind=P.FLOAT 64}`
725 :    
726 :     * `real64_gt : real64 * real64 -> bool`<br/>
727 :     `P.CMP{oper=P.GT, kind=P.FLOAT 64}`
728 :    
729 :     * `real64_ge : real64 * real64 -> bool`<br/>
730 :     `P.CMP{oper=P.GTE, kind=P.FLOAT 64}`
731 :    
732 :     * `real64_lt : real64 * real64 -> bool`<br/>
733 :     `P.CMP{oper=P.LT, kind=P.FLOAT 64}`
734 :    
735 :     * `real64_le : real64 * real64 -> bool`<br/>
736 :     `P.CMP{oper=P.LTE, kind=P.FLOAT 64}`
737 :    
738 :     * `real64_eql : real64 * real64 -> bool`<br/>
739 :     `P.CMP{oper=P.EQL, kind=P.FLOAT 64}`
740 :    
741 :     * `real64_neq : real64 * real64 -> bool`<br/>
742 :     `P.CMP{oper=P.NEQ, kind=P.FLOAT 64}`
743 :    
744 :     * `real64_sgn : real64 -> bool`<br/>
745 :     `P.CMP{oper=P.FSGN, kind=P.FLOAT 64}`
746 :    
747 :     * `real64_min : real64 * real64 -> real64`<br/>
748 :     `P.INLMIN (P.FLOAT 64)`
749 :    
750 :     * `real64_max : real64 * real64 -> real64`<br/>
751 :     `P.INLMAX (P.FLOAT 64)`
752 :    
753 :     * `abs : real64 -> real64`<br/>
754 :     `P.ARITH{oper=P.ABS, kind=P.FLOAT 64}`
755 :    
756 :     * `real64_sin : real64 -> real64`<br/>
757 :     `P.ARITH{oper=P.FSIN, kind=P.FLOAT 64}`
758 :    
759 :     * `real64_cos : real64 -> real64`<br/>
760 :     `P.ARITH{oper=P.FCOS, kind=P.FLOAT 64}`
761 :    
762 :     * `real64_tan : real64 -> real64`<br/>
763 :     `P.ARITH{oper=P.FTAN, kind=P.FLOAT 64}`
764 :    
765 :     * `real64_sqrt : real64 -> real64`<br/>
766 :     `P.ARITH{oper=P.FSQRT, kind=P.FLOAT 64}`
767 :    
768 :    
769 :     ### Conversions
770 :    
771 :     We use the following operation-prefixes for conversions between integer and
772 :     word types:
773 :    
774 :     * `cvt_unsigned` -- for word to integer conversions where the resulting
775 :     integer will be non-negative (*i.e.*, represent the same number as the
776 :     argument). These operations raise `Overflow` if the argument it not
777 :     representable as an integer of the specified size.
778 :    
779 :     * `cvt_signed` -- for word to integer conversions where the resulting
780 :     integer will have the same bit representation as the argument. These
781 :     operations raise `Overflow` if the argument (interpreted as a signed
782 :     2's complement number) is not representable as an integer of the specified
783 :     size.
784 :    
785 :     * `cvt` -- for integer-to-integer, integer-to-word, and word-to-word,
786 :     conversions. In the case of integer-to-integer conversions, the
787 :     operation will raise `Overflow` if the argument is too large to
788 :     represent in the result type.
789 :    
790 :     For conversions between integer and word types, there are five basic
791 :     primitive operations (**TEST**, **TESTU**, **EXTEND**, **TRUNC**, and **COPY**),
792 :     which are described in the `conversions.md` file.
793 :    
794 :     * `cvt_int_to_word : int -> word`<br />
795 :     `P.COPY(<int-size>, <int-size>)`
796 :    
797 :     * `cvt_signed_word_to_int : word -> int`<br />
798 :     `P.COPY(<int-size>, <int-size>)`
799 :    
800 :     * `cvt_unsigned_word_to_int : word -> int`<br />
801 :     `P.TESTU(<int-size>, <int-size>)`
802 :    
803 :     * `cvt_int_to_int8 : int -> int8`<br />
804 :     `P.TEST(<int-size>, 8)`
805 :    
806 :     * `cvt_int_to_word8 : int -> word8`<br />
807 :     `P.TRUNC(<int-size>, 8)`
808 :    
809 :     * `cvt_signed_word_to_int8 : word -> int8`<br />
810 :     `P.TEST(<int-size>, 8)`
811 :    
812 :     * `cvt_unsigned_word_to_int8 : word -> int8`<br />
813 :     `P.TESTU(<int-size>, 8)`
814 :    
815 :     * `cvt_word_to_word8 : word -> word8`<br />
816 :     `P.TRUNC(<int-size>, 8)`
817 :    
818 :     * `cvt_int_to_int32 : int -> int32`<br />
819 :     `P.EXTEND(31, 32)` on 32-bit targets or `P.TEST(63, 32)` on 64-bit targets.
820 :    
821 :     * `cvt_int_to_word32 : int -> word32`<br />
822 :     `P.COPY(31, 32)` on 32-bit targets or `P.TRUNC(63, 32)` on 64-bit targets.
823 :    
824 :     * `cvt_signed_word_to_int32 : word -> int32`<br />
825 :     `P.EXTEND(31, 32)` on 32-bit targets or `P.TEST(63, 32)` on 64-bit targets.
826 :    
827 :     * `cvt_unsigned_word_to_int32 : word -> int32`<br />
828 :     `P.COPY(31, 32)` on 32-bit targets or `P.TESTU(63, 32)` on 64-bit targets.
829 :    
830 :     * `cvt_word_to_word32 : word -> word32`<br />
831 :     `P.COPY(31, 32)` on 32-bit targets or `P.TRUNC(63, 32)` on 64-bit targets.
832 :    
833 :     * `cvt_int_to_int64 : int -> int64`<br />
834 :     `P.EXTEND(<int-size>, 64)`
835 :    
836 :     * `cvt_int_to_word64 : int -> word64`<br />
837 :    
838 :     * `cvt_signed_word_to_int64 : word -> int64`<br />
839 :    
840 :     * `cvt_unsigned_word_to_int64 : word -> int64`<br />
841 :    
842 :     * `cvt_word_to_word64 : word -> word64`<br />
843 :    
844 :     * `cvt_int8_to_int : int8 -> int`<br />
845 :    
846 :     * `cvt_int8_to_word : int8 -> word`<br />
847 :    
848 :     * `cvt_signed_word8_to_int : word8 -> int`<br />
849 :    
850 :     * `cvt_unsigned_word8_to_int : word8 -> int`<br />
851 :    
852 :     * `cvt_word8_to_word : word8 -> word`<br />
853 :    
854 :     * `cvt_int32_to_int : int32 -> int`<br />
855 :    
856 :     * `cvt_int32_to_word : int32 -> word`<br />
857 :    
858 :     * `cvt_signed_word32_to_int : word32 -> int`<br />
859 :    
860 :     * `cvt_unsigned_word32_to_int : word32 -> int`<br />
861 :    
862 :     * `cvt_word32_to_word : word32 -> word`<br />
863 :    
864 :     * `cvt_int64_to_int : int64 -> int`<br />
865 :    
866 :     * `cvt_int64_to_word : int64 -> word`<br />
867 :    
868 :     * `cvt_signed_word64_to_int : word64 -> int`<br />
869 :    
870 :     * `cvt_unsigned_word64_to_int : word64 -> int`<br />
871 :    
872 :     * `cvt_word64_to_word : word64 -> word`<br />
873 :    
874 :     #### Conversions that are specific to 32-bit targets
875 :    
876 :     These conversions assume that the `LargeWord` structure is
877 :     bound to `Word32` (even though there is a `Word64` structure).
878 :    
879 :     * `cvt_int8_to_word32 : int8 -> word32`<br />
880 :     `P.EXTEND(8, 32)`
881 :    
882 :     * `cvt_word8_to_word32 : word8 -> word32`<br />
883 :     `P.COPY(8, 32)`
884 :    
885 :     * `cvt_int32_to_word32 : int32 -> word32`<br />
886 :     `P.COPY(32, 32)`
887 :    
888 :     * `cvt_int64_to_word32 : int64 -> word32`<br />
889 :     `P.TRUNC(64, 32)`
890 :    
891 :     * `cvt_word64_to_word32 : word64 -> word32`<br />
892 :     `P.TRUNC(64, 32)`
893 :    
894 :     #### Conversions that are specific to 64-bit targets
895 :    
896 :     * `cvt_int8_to_word64 : int8 -> word64`<br />
897 :     `P.EXTEND(8, 64)`
898 :    
899 :     * `cvt_word8_to_word64 : word8 -> word64`<br />
900 :     `P.COPY(8, 64)`
901 :    
902 :     * `cvt_int32_to_word64 : int32 -> word64`<br />
903 :     `P.EXTEND(32, 64)`
904 :    
905 :     * `cvt_word32_to_word64 : word32 -> word64`<br />
906 :     `P.COPY(32, 64)`
907 :    
908 :     * `cvt_int64_to_word64 : int64 -> word64`<br />
909 :     `P.COPY(64, 64)`
910 :    
911 :     #### Conversions between integers and reals
912 :    
913 : jhr 4989 * `cvt_int_to_real64 : int -> real64`<br />
914 : jhr 4993 `P.INT_TO_REAL{from=<int-size>, to=64}`
915 : jhr 4989
916 :     * `cvt_int32_to_real64 : int32 -> real64`<br />
917 : jhr 4993 `P.INT_TO_REAL{from=32, to=64}`
918 : jhr 4989
919 :     * `floor_real64_to_int : real64 -> int`<br />
920 : jhr 4985 `P.ROUND{floor=true, from=64, to=<int-size>}`
921 :    
922 : jhr 4989 * `round_real64_to_int : real64 -> int`<br />
923 : jhr 4985 `P.ROUND{floor=false, from=64, to=<int-size>}`

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