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

SCM Repository

[smlnj] Diff of /dev-notes/primop-list.md
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4961, Thu Apr 18 10:18:12 2019 UTC revision 5019, Mon Apr 29 17:33:30 2019 UTC
# Line 14  Line 14 
14      datatypes used to represent primitive operations internally in the      datatypes used to represent primitive operations internally in the
15      front-end of the compiler.  The main type is `Primop.primop`.      front-end of the compiler.  The main type is `Primop.primop`.
16    
17    * `compiler/ElabData/prim/primop.sml`<br/>    * `compiler/ElabData/prim/primop.sig`<br/>
18      this file defines the `PRIMOP` signature use for the `Primop` structure.      this file defines the `PRIMOP` signature use for the `Primop` structure.
19    
20    * `compiler/Semant/prim/primop-bindings.sml`<br/>    * `compiler/Semant/prim/primop-bindings.sml`<br/>
# Line 41  Line 41 
41    * "`real32`" -- 32-bit real numbers (not yet supported)    * "`real32`" -- 32-bit real numbers (not yet supported)
42    * "`real64`" -- 64-bit real numbers    * "`real64`" -- 64-bit real numbers
43    * "`ptr`" -- machine address    * "`ptr`" -- machine address
44    * "`barr`" -- bytearray (used for arrays of `Word8.word` and `char`)    * "`w8arr`" -- bytearray (used for arrays of `Word8.word` and `char`)
45    * "`bvec`" -- bytevector (used for strings and vectors of `Word8.word`)    * "`w8vec`" -- bytevector (used for strings and vectors of `Word8.word`)
46    * "`arr`" -- polymorphic arrays    * "`arr`" -- polymorphic arrays
47    * "`vec`" -- polymorphic vectors    * "`vec`" -- polymorphic vectors
48    * "`seq`" -- sequence types (arrays and vectors)    * "`seq`" -- sequence types (arrays and vectors)
49    
50    Following the type prefix may one or more attributes, which highlight properties
51    of the operation.
52    
53  We use the attribute "`raw`" to denote direct machine operations that are not  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  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).  versions clamp the shift amount to the word size, but the raw versions do not).
# Line 141  Line 144 
144    
145    * `objlength : 'a -> int`<br/>    * `objlength : 'a -> int`<br/>
146      extracts the length field from an object's header word.      extracts the length field from an object's header word.
147      `P.OBJLENGTH`      (`P.OBJLENGTH`)
148    
149    
150  #### Inline operations  #### Inline operations
# Line 161  Line 164 
164    * `bool_not : bool -> bool`<br/>    * `bool_not : bool -> bool`<br/>
165      `P.INLNOT`      `P.INLNOT`
166    
167  Some additional candidates for inlined operations include `hd`, `tl`, `null`, `chr`, and `ord`.    * `char_chr : int -> char`<br/>
168         `P.INLCHR`
169    
170    Some additional candidates for inlined operations include `hd`, `tl`, and `null`.
171    
172  If the compiler had the `option` and `order` datatypes builtin (like `bool` and `list`),  If the compiler had the `option` and `order` datatypes builtin (like `bool` and `list`),
173  then `valOf`, `isSome`, `isNone` and some of the `compare` functions could be inlined.  then `valOf`, `isSome`, `isNone` and some of the `compare` functions could also
174    be inlined.
175    
176    In the long run, however, a better way to support inlining library functions would
177    be through a reliable cross-module inliner.
178    
179  #### Bytearray and bytevector operations  #### Bytearray and bytevector operations
180  Operations on byte/char array/vectors.  We renamed these to make it clear  Operations on byte/char array/vectors.  We renamed these to make it clear
181  which operations do bounds checking and which do not.  which operations do bounds checking and which do not.
182    
183    * `bvec_unsafe_sub : 'a * int -> 'b`<br/>    * `w8vec_unsafe_sub : 'a * int -> 'b`<br/>
184      subscript from byte vector without bounds checking      subscript from byte vector without bounds checking
185      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=true}`)      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=true}`)
186    
187    * `barr_unsafe_sub : 'a * int -> 'b`<br/>    * `w8arr_unsafe_sub : 'a * int -> 'b`<br/>
188      subscript from byte array without bounds checking      subscript from byte array without bounds checking
189      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=false}`)      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=false}`)
190    
191    * `barr_unsafe_update : 'a * int * 'b -> unit`<br/>    * `w8arr_unsafe_update : 'a * int * 'b -> unit`<br/>
192      update byte array without bounds checking      update byte array without bounds checking
193      (`P.NUMUPDATE{kind=P.INT 8, checked=false}`)      (`P.NUMUPDATE{kind=P.INT 8, checked=false}`)
194    
195    * `bvec_sub : 'a * int -> 'b`<br/>    * `w8vec_sub : 'a * int -> 'b`<br/>
196      subscript from byte vector      subscript from byte vector
197      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=true}`)      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=true}`)
198    
199    * `barr_sub : 'a * int -> 'b`<br/>    * `w8arr_sub : 'a * int -> 'b`<br/>
200      subscript from byte array      subscript from byte array
201      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=false}`)      (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=false}`)
202    
203    * `barr_update : 'a * int * 'b -> unit`<br/>    * `w8arr_update : 'a * int * 'b -> unit`<br/>
204      update byte array      update byte array
205      (`P.NUMUPDATE{kind=P.INT 8, checked=true}`)      (`P.NUMUPDATE{kind=P.INT 8, checked=true}`)
206    
   
207  #### Polymorphic array and vector  #### Polymorphic array and vector
208    * `mkarray : int * 'a -> 'a array`<br/>    * `mkarray : int * 'a -> 'a array`<br/>
209      create a polymorphic array      create a polymorphic array
# Line 227  Line 236 
236    * `arr_unboxed_update : 'a array * int * 'a -> unit`<br/>    * `arr_unboxed_update : 'a array * int * 'a -> unit`<br/>
237      update a polymorphic array with an unboxed value, which means that there is      update a polymorphic array with an unboxed value, which means that there is
238      no store-list entry created for the update.      no store-list entry created for the update.
239      `P.UNBOXEDUPDATE`      (`P.UNBOXEDUPDATE`)
   
240    
241  #### Sequence operations  #### Sequence operations
242  Sequence values (*e.g.*, `string`, `'a array`, `RealVector.vector`, *etc*.)  Sequence values (*e.g.*, `string`, `'a array`, `RealVector.vector`, *etc*.)
# Line 240  Line 248 
248    
249    * `seq_length : 'a -> int`<br/>    * `seq_length : 'a -> int`<br/>
250      get the length field from a sequence header      get the length field from a sequence header
251      `P.LENGTH`      (`P.LENGTH`)
252    
253    * `seq_data : 'a -> 'b`<br/>    * `seq_data : 'a -> 'b`<br/>
254      get the length field from a sequence header      get the length field from a sequence header
255      `P.GET_SEQ_DATA`      (`P.GET_SEQ_DATA`)
256    
257    * `unsafe_record_sub : 'a * int -> 'b`<br/>    * `unsafe_record_sub : 'a * int -> 'b`<br/>
258      `P.SUBSCRIPT_REC`      `P.SUBSCRIPT_REC`
259    
260    * `raw64Sub : 'a * int -> real64`<br/>    * `raw64Sub : 'a * int -> real64`<br/>
261      Unclear what purpose this primop serves      gets an element from a packed tuple of 64-bit reals.  The only use of
262      `P.SUBSCRIPT_RAW64`      this function is in the implementation of the `Unsafe.Object.nth`
263        function. <br/>
264        (`P.SUBSCRIPT_RAW64`)
265    
266    
267  ### Numeric primops  ### Numeric primops
# Line 262  Line 272 
272    
273    * `int_add : int * int -> int`<br/>    * `int_add : int * int -> int`<br/>
274      Signed integer addition with overflow checking.      Signed integer addition with overflow checking.
275      `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT <int-size>}`      (`P.IARITH{oper=P.IADD, sz=<int-size>}`)
276    
277    * `int_unsafe_add : int * int -> int`<br/>    * `int_unsafe_add : int * int -> int`<br/>
278      Signed integer addition *without* overflow checking.      Signed integer addition *without* overflow checking.
279      `P.ARITH{oper=P.ADD, overflow=false, kind=P.INT <int-size>}`      (`P.PURE_ARITH{oper=P.ADD, kind=P.UINT <int-size>}`)
280    
281    * `int_sub : int * int -> int`<br/>    * `int_sub : int * int -> int`<br/>
282      Signed integer subtraction with overflow checking.      Signed integer subtraction with overflow checking.
283      `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT <int-size>}`      (`P.IARITH{oper=P.ISUB, sz=<int-size>}`)
284    
285    * `int_unsafe_sub : int * int -> int`<br/>    * `int_unsafe_sub : int * int -> int`<br/>
286      Signed integer subtraction *without* overflow checking.      Signed integer subtraction *without* overflow checking.
287      `P.ARITH{oper=P.SUB, overflow=false, kind=P.INT <int-size>}`      (`P.PURE_ARITH{oper=P.SUB, kind=P.UINT <int-size>}`)
288    
289    * `int_mul : int * int -> int`<br/>    * `int_mul : int * int -> int`<br/>
290      `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.IMUL, sz=<int-size>}`
291    
292    * `int_div : int * int -> int`<br/>    * `int_div : int * int -> int`<br/>
293      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.IQUOT, sz=<int-size>}`
294    
295    * `int_mod : int * int -> int`<br/>    * `int_mod : int * int -> int`<br/>
296      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.IREM, sz=<int-size>}`
297    
298    * `int_quot : int * int -> int`<br/>    * `int_quot : int * int -> int`<br/>
299      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.IQUOT, sz=<int-size>}`
300    
301    * `int_rem : int * int -> int`<br/>    * `int_rem : int * int -> int`<br/>
302      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.IREM, sz=<int-size>}`
303    
304    * `int_orb : int * int -> int`<br/>    * `int_orb : int * int -> int`<br/>
305      `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.ORB, kind=P.INT <int-size>}`
306    
307    * `int_xorb : int * int -> int`<br/>    * `int_xorb : int * int -> int`<br/>
308      `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.XORB, kind=P.INT <int-size>}`
309    
310    * `int_andb : int * int -> int`<br/>    * `int_andb : int * int -> int`<br/>
311      `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.ANDB, kind=P.INT <int-size>}`
312    
313    * `int_neg : word32 -> word32`<br/>    * `int_neg : word32 -> word32`<br/>
314      `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT <int-size>}`      `P.IARITH{oper=P.INEG, sz=<int-size>}`
315    
316    * `int_raw_rshift : int * word -> int`<br/>    * `int_raw_rshift : int * word -> int`<br/>
317      `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.RSHIFT, kind=P.INT <int-size>}`
318    
319    * `int_raw_lshift : int * word -> int`<br/>    * `int_raw_lshift : int * word -> int`<br/>
320      `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.LSHIFT, kind=P.INT <int-size>}`
321    
322    * `int_gt : int * int -> bool`<br/>    * `int_gt : int * int -> bool`<br/>
323      `P.CMP{oper=P.GT, kind=P.INT <int-size>}`      `P.CMP{oper=P.GT, kind=P.INT <int-size>}`
# Line 333  Line 343 
343    * `int_max : int * int -> int`<br/>    * `int_max : int * int -> int`<br/>
344      `P.INLMAX (P.INT <int-size>)`      `P.INLMAX (P.INT <int-size>)`
345    
346    * `int_abs : word32 -> word32`<br/>    * `int_abs : int -> int`<br/>
347      `P.INLABS (P.INT <int-size>)`      `P.INLABS (P.INT <int-size>)`
348    
349  #### Default tagged word operations  #### Default tagged word operations
# Line 341  Line 351 
351  type (`Word.word`).  type (`Word.word`).
352    
353    * `word_mul : word * word -> word`<br/>    * `word_mul : word * word -> word`<br/>
354      `P.ARITH{oper=P.MUL, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.MUL, kind=P.UINT <int-size>}`
355    
356    * `word_div : word * word -> word`<br/>    * `word_div : word * word -> word`<br/>
357      `P.ARITH{oper=P.QUOT, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.QUOT, kind=P.UINT <int-size>}`
358    
359    * `word_mod : word * word -> word`<br/>    * `word_mod : word * word -> word`<br/>
360      `P.ARITH{oper=P.REM, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.REM, kind=P.UINT <int-size>}`
361    
362    * `word_add : word * word -> word`<br/>    * `word_add : word * word -> word`<br/>
363      `P.ARITH{oper=P.ADD, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.ADD, kind=P.UINT <int-size>}`
364    
365    * `word_sub : word * word -> word`<br/>    * `word_sub : word * word -> word`<br/>
366      `P.ARITH{oper=P.SUB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.SUB, kind=P.UINT <int-size>}`
367    
368    * `word_orb : word * word -> word`<br/>    * `word_orb : word * word -> word`<br/>
369      `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.ORB, kind=P.UINT <int-size>}`
370    
371    * `word_xorb : word * word -> word`<br/>    * `word_xorb : word * word -> word`<br/>
372      `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.XORB, kind=P.UINT <int-size>}`
373    
374    * `word_andb : word * word -> word`<br/>    * `word_andb : word * word -> word`<br/>
375      `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.ANDB, kind=P.UINT <int-size>}`
376    
377    * `word_notb : word -> word`<br/>    * `word_notb : word -> word`<br/>
378      `P.ARITH{oper=P.NOTB, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.NOTB, kind=P.UINT <int-size>}`
379    
380    * `word_neg : word -> word`<br/>    * `word_neg : word -> word`<br/>
381      `P.ARITH{oper=P.NEG, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.NEG, kind=P.UINT <int-size>}`
382    
383    * `word_rshift : word * word -> word`<br/>    * `word_rshift : word * word -> word`<br/>
384      `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT <int-size>}`      `P.INLRSHIFT(P.UINT <int-size>)`
385    
386    * `word_rshiftl : word * word -> word`<br/>    * `word_rshiftl : word * word -> word`<br/>
387      `P.ARITH{oper=P.RSHIFTL, overflow=false, kind=P.INT <int-size>}`      `P.INLRSHIFTL(P.UINT <int-size>)`
388    
389    * `word_lshift : word * word -> word`<br/>    * `word_lshift : word * word -> word`<br/>
390      `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT <int-size>}`      `P.PURE_ARITH{oper=P.LSHIFT, kind=P.UINT <int-size>}`
391    
392      * `word_raw_rshift : word * word -> word`<br/>
393        `P.INLLSHIFT(P.UINT <int-size>)`
394    
395      * `word_raw_rshiftl : word * word -> word`<br/>
396        `P.PURE_ARITH{oper=P.RSHIFTL, kind=P.UINT <int-size>}`
397    
398      * `word_raw_lshift : word * word -> word`<br/>
399        `P.PURE_ARITH{oper=P.RSHIFT, kind=P.UINT <int-size>}`
400    
401    * `word_gt : word * word -> bool`<br/>    * `word_gt : word * word -> bool`<br/>
402      `P.CMP{oper=P.GT, kind=P.UINT <int-size>}`      `P.CMP{oper=P.GT, kind=P.UINT <int-size>}`
# Line 397  Line 416 
416    * `word_neq : word * word -> bool`<br/>    * `word_neq : word * word -> bool`<br/>
417      `P.CMP{oper=P.NEQ, kind=P.UINT <int-size>}`      `P.CMP{oper=P.NEQ, kind=P.UINT <int-size>}`
418    
   * `word_raw_rshift : word * word -> word`<br/>  
     `P.INLRSHIFT(P.UINT <int-size>)`  
   
   * `word_raw_rshiftl : word * word -> word`<br/>  
     `P.INLRSHIFTL(P.UINT <int-size>)`  
   
   * `word_raw_lshift : word * word -> word`<br/>  
     `P.INLLSHIFT(P.UINT <int-size>)`  
   
419    * `word_min : word * word -> word`<br/>    * `word_min : word * word -> word`<br/>
420      `P.INLMIN (P.UINT <int-size>)`      `P.INLMIN (P.UINT <int-size>)`
421    
# Line 416  Line 426 
426    
427  #### 32-bit integer operations  #### 32-bit integer operations
428    * `int32_add : int32 * int32 -> int32`<br/>    * `int32_add : int32 * int32 -> int32`<br/>
429      `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IADD, sz=32}`
430    
431    * `int32_sub : int32 * int32 -> int32`<br/>    * `int32_sub : int32 * int32 -> int32`<br/>
432      `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.ISUB, sz=32}`
433    
434    * `int32_mul : int32 * int32 -> int32`<br/>    * `int32_mul : int32 * int32 -> int32`<br/>
435      `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IMUL, sz=32}`
436    
437    * `int32_div : int32 * int32 -> int32`<br/>    * `int32_div : int32 * int32 -> int32`<br/>
438      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IQUOT, sz=32}`
439    
440    * `int32_mod : int32 * int32 -> int32`<br/>    * `int32_mod : int32 * int32 -> int32`<br/>
441      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IREM, sz=32}`
442    
443    * `int32_quot : int32 * int32 -> int32`<br/>    * `int32_quot : int32 * int32 -> int32`<br/>
444      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IQUOT, sz=32}`
445    
446    * `int32_rem : int32 * int32 -> int32`<br/>    * `int32_rem : int32 * int32 -> int32`<br/>
447      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.IREM, sz=32}`
448    
449    * `int32_orb : int32 * int32 -> int32`<br/>    * `int32_orb : int32 * int32 -> int32`<br/>
450      `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT 32}`      `P.PURE_ARITH{oper=P.ORB, kind=P.INT 32}`
451    
452    * `int32_xorb : int32 * int32 -> int32`<br/>    * `int32_xorb : int32 * int32 -> int32`<br/>
453      `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT 32}`      `P.PURE_ARITH{oper=P.XORB, kind=P.INT 32}`
454    
455    * `int32_andb : int32 * int32 -> int32`<br/>    * `int32_andb : int32 * int32 -> int32`<br/>
456      `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT 32}`      `P.PURE_ARITH{oper=P.ANDB, kind=P.INT 32}`
457    
458    * `int32_neg : word32 -> word32`<br/>    * `int32_neg : word32 -> word32`<br/>
459      `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT 32}`      `P.IARITH{oper=P.INEG, sz=32}`
460    
461    * `int32_raw_rshift : int32 * word -> int32`<br/>    * `int32_raw_rshift : int32 * word -> int32`<br/>
462      `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT 32}`      `P.PURE_ARITH{oper=P.RSHIFT, kind=P.INT 32}`
463    
464    * `int32_raw_lshift : int32 * word -> int32`<br/>    * `int32_raw_lshift : int32 * word -> int32`<br/>
465      `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT 32}`      `P.PURE_ARITH{oper=P.LSHIFT, kind=P.INT 32}`
466    
467    * `int32_gt : int32 * int32 -> bool`<br/>    * `int32_gt : int32 * int32 -> bool`<br/>
468      `P.CMP{oper=P.GT, kind=P.INT 32}`      `P.CMP{oper=P.GT, kind=P.INT 32}`
# Line 478  Line 488 
488    * `int32_max : int32 * int32 -> int32`<br/>    * `int32_max : int32 * int32 -> int32`<br/>
489      `P.INLMAX (P.INT 32)`      `P.INLMAX (P.INT 32)`
490    
491    * `int32_abs : word32 -> word32`<br/>    * `int32_abs : int32 -> int32`<br/>
492      `P.INLABS (P.INT 32)`      `P.INLABS (P.INT 32)`
493    
494  #### 32-bit word operations  #### 32-bit word operations
495    These operations work on the boxed 32-bit word type on 32-bit
496    machines and are just wrappers for 63-bit tagged word operations
497    on 64-bit machines.
498    
499      * `word32_mul : word32 * word32 -> word32`<br/>
500        `P.PURE_ARITH{oper=P.MUL, kind=P.UINT 32}`
501    
502      * `word32_div : word32 * word32 -> word32`<br/>
503        `P.PURE_ARITH{oper=P.QUOT, kind=P.UINT 32}`
504    
505      * `word32_mod : word32 * word32 -> word32`<br/>
506        `P.PURE_ARITH{oper=P.REM, kind=P.UINT 32}`
507    
508      * `word32_add : word32 * word32 -> word32`<br/>
509        `P.PURE_ARITH{oper=P.ADD, kind=P.UINT 32}`
510    
511      * `word32_sub : word32 * word32 -> word32`<br/>
512        `P.PURE_ARITH{oper=P.SUB, kind=P.UINT 32}`
513    
514      * `word32_orb : word32 * word32 -> word32`<br/>
515        `P.PURE_ARITH{oper=P.ORB, kind=P.UINT 32}`
516    
517      * `word32_xorb : word32 * word32 -> word32`<br/>
518        `P.PURE_ARITH{oper=P.XORB, kind=P.UINT 32}`
519    
520      * `word32_andb : word32 * word32 -> word32`<br/>
521        `P.PURE_ARITH{oper=P.ANDB, kind=P.UINT 32}`
522    
523      * `word32_notb : word32 -> word32`<br/>
524        `P.PURE_ARITH{oper=P.NOTB, kind=P.UINT 32}`
525    
526      * `word32_neg : word32 -> word32`<br/>
527        `P.PURE_ARITH{oper=P.NEG, kind=P.UINT 32}`
528    
529      * `word32_rshift : word32 * word -> word`<br/>
530        `P.INLRSHIFT(P.UINT 32)`
531    
532      * `word32_rshiftl : word32 * word -> word`<br/>
533        `P.INLRSHIFTL(P.UINT 32)`
534    
535      * `word32_lshift : word32 * word -> word`<br/>
536        `P.INLLSHIFT(P.UINT 32)`
537    
538      * `word32_raw_rshift : word32 * word -> word`<br/>
539        `P.PURE_ARITH{oper=P.RSHIFT, kind=P.UINT 32}`
540    
541      * `word32_raw_rshiftl : word32 * word -> word`<br/>
542        `P.PURE_ARITH{oper=P.RSHIFTL, kind=P.UINT 32}`
543    
544      * `word32_raw_lshift : word32 * word -> word`<br/>
545        `P.PURE_ARITH{oper=P.LSHIFT, kind=P.UINT 32}`
546    
547      * `word32_gt : word32 * word32 -> bool`<br/>
548        `P.CMP{oper=P.GT, kind=P.UINT 32}`
549    
550      * `word32_ge : word32 * word32 -> bool`<br/>
551        `P.CMP{oper=P.GTE, kind=P.UINT 32}`
552    
553      * `word32_lt : word32 * word32 -> bool`<br/>
554        `P.CMP{oper=P.LT, kind=P.UINT 32}`
555    
556      * `word32_le : word32 * word32 -> bool`<br/>
557        `P.CMP{oper=P.LTE, kind=P.UINT 32}`
558    
559      * `word32_eql : word32 * word32 -> bool`<br/>
560        `P.CMP{oper=P.EQL, kind=P.UINT 32}`
561    
562      * `word32_neq : word32 * word32 -> bool`<br/>
563        `P.CMP{oper=P.NEQ, kind=P.UINT 32}`
564    
565      * `word32_min : word32 * word32 -> word32`<br/>
566        `P.INLMIN (P.UINT 32)`
567    
568      * `word32_max : word32 * word32 -> word32`<br/>
569        `P.INLMAX (P.UINT 32)`
570    
571  #### 64-bit integer operations  #### 64-bit integer operations
572    * `int64_add : int64 * int64 -> int64`<br/>    * `int64_add : int64 * int64 -> int64`<br/>
573      `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IADD, sz=64}`
574    
575    * `int64_sub : int64 * int64 -> int64`<br/>    * `int64_sub : int64 * int64 -> int64`<br/>
576      `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.ISUB, sz=64}`
577    
578    * `int64_mul : int64 * int64 -> int64`<br/>    * `int64_mul : int64 * int64 -> int64`<br/>
579      `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IMUL, sz=64}`
580    
581    * `int64_div : int64 * int64 -> int64`<br/>    * `int64_div : int64 * int64 -> int64`<br/>
582      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IQUOT, sz=64}`
583    
584    * `int64_mod : int64 * int64 -> int64`<br/>    * `int64_mod : int64 * int64 -> int64`<br/>
585      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IREM, sz=64}`
586    
587    * `int64_quot : int64 * int64 -> int64`<br/>    * `int64_quot : int64 * int64 -> int64`<br/>
588      `P.ARITH{oper=P.QUOT, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IQUOT, sz=64}`
589    
590    * `int64_rem : int64 * int64 -> int64`<br/>    * `int64_rem : int64 * int64 -> int64`<br/>
591      `P.ARITH{oper=P.REM, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.IREM, sz=64}`
592    
593    * `int64_orb : int64 * int64 -> int64`<br/>    * `int64_orb : int64 * int64 -> int64`<br/>
594      `P.ARITH{oper=P.ORB, overflow=false, kind=P.INT 64}`      `P.PURE_ARITH{oper=P.ORB, kind=P.INT 64}`
595    
596    * `int64_xorb : int64 * int64 -> int64`<br/>    * `int64_xorb : int64 * int64 -> int64`<br/>
597      `P.ARITH{oper=P.XORB, overflow=false, kind=P.INT 64}`      `P.PURE_ARITH{oper=P.XORB, kind=P.INT 64}`
598    
599    * `int64_andb : int64 * int64 -> int64`<br/>    * `int64_andb : int64 * int64 -> int64`<br/>
600      `P.ARITH{oper=P.ANDB, overflow=false, kind=P.INT 64}`      `P.PURE_ARITH{oper=P.ANDB, kind=P.INT 64}`
601    
602    * `int64_neg : word32 -> word32`<br/>    * `int64_neg : word32 -> word32`<br/>
603      `P.ARITH{oper=P.NEG, overflow=true, kind=P.INT 64}`      `P.IARITH{oper=P.INEG, sz=64}`
604    
605    * `int64_raw_rshift : int64 * word -> int64`<br/>    * `int64_raw_rshift : int64 * word -> int64`<br/>
606      `P.ARITH{oper=P.RSHIFT, overflow=false, kind=P.INT 64}`      `P.PURE_ARITH{oper=P.RSHIFT, kind=P.INT 64}`
607    
608    * `int64_raw_lshift : int64 * word -> int64`<br/>    * `int64_raw_lshift : int64 * word -> int64`<br/>
609      `P.ARITH{oper=P.LSHIFT, overflow=false, kind=P.INT 64}`      `P.PURE_ARITH{oper=P.LSHIFT, kind=P.INT 64}`
610    
611    * `int64_gt : int64 * int64 -> bool`<br/>    * `int64_gt : int64 * int64 -> bool`<br/>
612      `P.CMP{oper=P.GT, kind=P.INT 64}`      `P.CMP{oper=P.GT, kind=P.INT 64}`
# Line 547  Line 632 
632    * `int64_max : int64 * int64 -> int64`<br/>    * `int64_max : int64 * int64 -> int64`<br/>
633      `P.INLMAX (P.INT 64)`      `P.INLMAX (P.INT 64)`
634    
635    * `int64_abs : word32 -> word32`<br/>    * `int64_abs : int64 -> int64`<br/>
636      `P.INLABS (P.INT 64)`      `P.INLABS (P.INT 64)`
637    
638  #### 64-bit word operations  #### 64-bit word operations
639    
640      * `word64_mul : word64 * word64 -> word64`<br/>
641        `P.PURE_ARITH{oper=P.MUL, kind=P.UINT 64}`
642    
643      * `word64_div : word64 * word64 -> word64`<br/>
644        `P.PURE_ARITH{oper=P.QUOT, kind=P.UINT 64}`
645    
646      * `word64_mod : word64 * word64 -> word64`<br/>
647        `P.PURE_ARITH{oper=P.REM, kind=P.UINT 64}`
648    
649      * `word64_add : word64 * word64 -> word64`<br/>
650        `P.PURE_ARITH{oper=P.ADD, kind=P.UINT 64}`
651    
652      * `word64_sub : word64 * word64 -> word64`<br/>
653        `P.PURE_ARITH{oper=P.SUB, kind=P.UINT 64}`
654    
655      * `word64_orb : word64 * word64 -> word64`<br/>
656        `P.PURE_ARITH{oper=P.ORB, kind=P.UINT 64}`
657    
658      * `word64_xorb : word64 * word64 -> word64`<br/>
659        `P.PURE_ARITH{oper=P.XORB, kind=P.UINT 64}`
660    
661      * `word64_andb : word64 * word64 -> word64`<br/>
662        `P.PURE_ARITH{oper=P.ANDB, kind=P.UINT 64}`
663    
664      * `word64_notb : word64 -> word64`<br/>
665        `P.PURE_ARITH{oper=P.NOTB, kind=P.UINT 64}`
666    
667      * `word64_neg : word64 -> word64`<br/>
668        `P.PURE_ARITH{oper=P.NEG, kind=P.UINT 64}`
669    
670      * `word64_rshift : word64 * word -> word`<br/>
671        `P.INLRSHIFT(P.UINT 64)`
672    
673      * `word64_rshiftl : word64 * word -> word`<br/>
674        `P.INLRSHIFTL(P.UINT 64)`
675    
676      * `word64_lshift : word64 * word -> word`<br/>
677        `P.INLLSHIFT(P.UINT 64)`
678    
679      * `word64_raw_rshift : word64 * word -> word`<br/>
680        `P.PURE_ARITH{oper=P.RSHIFT, kind=P.UINT 64}`
681    
682      * `word64_raw_rshiftl : word64 * word -> word`<br/>
683        `P.PURE_ARITH{oper=P.RSHIFTL, kind=P.UINT 64}`
684    
685      * `word64_raw_lshift : word64 * word -> word`<br/>
686        `P.PURE_ARITH{oper=P.LSHIFT, kind=P.UINT 64}`
687    
688      * `word64_gt : word64 * word64 -> bool`<br/>
689        `P.CMP{oper=P.GT, kind=P.UINT 64}`
690    
691      * `word64_ge : word64 * word64 -> bool`<br/>
692        `P.CMP{oper=P.GTE, kind=P.UINT 64}`
693    
694      * `word64_lt : word64 * word64 -> bool`<br/>
695        `P.CMP{oper=P.LT, kind=P.UINT 64}`
696    
697      * `word64_le : word64 * word64 -> bool`<br/>
698        `P.CMP{oper=P.LTE, kind=P.UINT 64}`
699    
700      * `word64_eql : word64 * word64 -> bool`<br/>
701        `P.CMP{oper=P.EQL, kind=P.UINT 64}`
702    
703      * `word64_neq : word64 * word64 -> bool`<br/>
704        `P.CMP{oper=P.NEQ, kind=P.UINT 64}`
705    
706      * `word64_min : word64 * word64 -> word64`<br/>
707        `P.INLMIN (P.UINT 64)`
708    
709      * `word64_max : word64 * word64 -> word64`<br/>
710        `P.INLMAX (P.UINT 64)`
711    
712  #### 64-bit real operations  #### 64-bit real operations
713      * `real64_add : real64 * real64 -> real64`<br/>
714        `P.ARITH{oper=P.ADD, overflow=true, kind=P.FLOAT 64}`
715    
716      * `real64_sub : real64 * real64 -> real64`<br/>
717        `P.ARITH{oper=P.SUB, overflow=true, kind=P.FLOAT 64}`
718    
719      * `real64_mul : real64 * real64 -> real64`<br/>
720        `P.ARITH{oper=P.MUL, overflow=true, kind=P.FLOAT 64}`
721    
722      * `real64_div : real64 * real64 -> real64`<br/>
723        `P.ARITH{oper=P.QUOT, overflow=true, kind=P.FLOAT 64}`
724    
725      * `real64_neg : word32 -> word32`<br/>
726        `P.ARITH{oper=P.NEG, overflow=true, kind=P.FLOAT 64}`
727    
728      * `real64_gt : real64 * real64 -> bool`<br/>
729        `P.CMP{oper=P.GT, kind=P.FLOAT 64}`
730    
731      * `real64_ge : real64 * real64 -> bool`<br/>
732        `P.CMP{oper=P.GTE, kind=P.FLOAT 64}`
733    
734      * `real64_lt : real64 * real64 -> bool`<br/>
735        `P.CMP{oper=P.LT, kind=P.FLOAT 64}`
736    
737      * `real64_le : real64 * real64 -> bool`<br/>
738        `P.CMP{oper=P.LTE, kind=P.FLOAT 64}`
739    
740      * `real64_eql : real64 * real64 -> bool`<br/>
741        `P.CMP{oper=P.EQL, kind=P.FLOAT 64}`
742    
743      * `real64_neq : real64 * real64 -> bool`<br/>
744        `P.CMP{oper=P.NEQ, kind=P.FLOAT 64}`
745    
746      * `real64_sgn : real64 -> bool`<br/>
747        `P.CMP{oper=P.FSGN, kind=P.FLOAT 64}`
748    
749      * `real64_min : real64 * real64 -> real64`<br/>
750        `P.INLMIN (P.FLOAT 64)`
751    
752      * `real64_max : real64 * real64 -> real64`<br/>
753        `P.INLMAX (P.FLOAT 64)`
754    
755      * `abs : real64 -> real64`<br/>
756        `P.ARITH{oper=P.ABS, kind=P.FLOAT 64}`
757    
758      * `real64_sin : real64 -> real64`<br/>
759        `P.ARITH{oper=P.FSIN, kind=P.FLOAT 64}`
760    
761      * `real64_cos : real64 -> real64`<br/>
762        `P.ARITH{oper=P.FCOS, kind=P.FLOAT 64}`
763    
764      * `real64_tan : real64 -> real64`<br/>
765        `P.ARITH{oper=P.FTAN, kind=P.FLOAT 64}`
766    
767      * `real64_sqrt : real64 -> real64`<br/>
768        `P.ARITH{oper=P.FSQRT, kind=P.FLOAT 64}`
769    
770    
771  ### Conversions  ### Conversions
772    
773    We use the following operation-prefixes for conversions between integer and
774    word types:
775    
776      * `cvt_unsigned` -- for word to integer conversions where the resulting
777        integer will be non-negative (*i.e.*, represent the same number as the
778        argument).  These operations raise `Overflow` if the argument it not
779        representable as an integer of the specified size.
780    
781      * `cvt_signed` -- for word to integer conversions where the resulting
782        integer will have the same bit representation as the argument.  These
783        operations raise `Overflow` if the argument (interpreted as a signed
784        2's complement number) is not representable as an integer of the specified
785        size.
786    
787      * `cvt` -- for integer-to-integer, integer-to-word, and word-to-word,
788        conversions.  In the case of integer-to-integer conversions, the
789        operation will raise `Overflow` if the argument is too large to
790        represent in the result type.
791    
792    For conversions between integer and word types, there are five basic
793    primitive operations (**TEST**, **TESTU**, **EXTEND**, **TRUNC**, and **COPY**),
794    which are described in the `conversions.md` file.
795    
796      * `cvt_int_to_word : int -> word`<br />
797        `P.COPY(<int-size>, <int-size>)`
798    
799      * `cvt_signed_word_to_int : word -> int`<br />
800        `P.COPY(<int-size>, <int-size>)`
801    
802      * `cvt_unsigned_word_to_int : word -> int`<br />
803        `P.TESTU(<int-size>, <int-size>)`
804    
805      * `cvt_int_to_int8 : int -> int8`<br />
806        `P.TEST(<int-size>, 8)`
807    
808      * `cvt_int_to_word8 : int -> word8`<br />
809        `P.TRUNC(<int-size>, 8)`
810    
811      * `cvt_signed_word_to_int8 : word -> int8`<br />
812        `P.TEST(<int-size>, 8)`
813    
814      * `cvt_unsigned_word_to_int8 : word -> int8`<br />
815        `P.TESTU(<int-size>, 8)`
816    
817      * `cvt_word_to_word8 : word -> word8`<br />
818        `P.TRUNC(<int-size>, 8)`
819    
820      * `cvt_int_to_int32 : int -> int32`<br />
821        `P.EXTEND(31, 32)` on 32-bit targets or `P.TEST(63, 32)` on 64-bit targets.
822    
823      * `cvt_int_to_word32 : int -> word32`<br />
824        `P.COPY(31, 32)` on 32-bit targets or `P.TRUNC(63, 32)` on 64-bit targets.
825    
826      * `cvt_signed_word_to_int32 : word -> int32`<br />
827        `P.EXTEND(31, 32)` on 32-bit targets or `P.TEST(63, 32)` on 64-bit targets.
828    
829      * `cvt_unsigned_word_to_int32 : word -> int32`<br />
830        `P.COPY(31, 32)` on 32-bit targets or `P.TESTU(63, 32)` on 64-bit targets.
831    
832      * `cvt_word_to_word32 : word -> word32`<br />
833        `P.COPY(31, 32)` on 32-bit targets or `P.TRUNC(63, 32)` on 64-bit targets.
834    
835      * `cvt_int_to_int64 : int -> int64`<br />
836        `P.EXTEND(<int-size>, 64)`
837    
838      * `cvt_int_to_word64 : int -> word64`<br />
839    
840      * `cvt_signed_word_to_int64 : word -> int64`<br />
841    
842      * `cvt_unsigned_word_to_int64 : word -> int64`<br />
843    
844      * `cvt_word_to_word64 : word -> word64`<br />
845    
846      * `cvt_int8_to_int : int8 -> int`<br />
847    
848      * `cvt_int8_to_word : int8 -> word`<br />
849    
850      * `cvt_signed_word8_to_int : word8 -> int`<br />
851    
852      * `cvt_unsigned_word8_to_int : word8 -> int`<br />
853    
854      * `cvt_word8_to_word : word8 -> word`<br />
855    
856      * `cvt_int32_to_int : int32 -> int`<br />
857    
858      * `cvt_int32_to_word : int32 -> word`<br />
859    
860      * `cvt_signed_word32_to_int : word32 -> int`<br />
861    
862      * `cvt_unsigned_word32_to_int : word32 -> int`<br />
863    
864      * `cvt_word32_to_word : word32 -> word`<br />
865    
866      * `cvt_int64_to_int : int64 -> int`<br />
867    
868      * `cvt_int64_to_word : int64 -> word`<br />
869    
870      * `cvt_signed_word64_to_int : word64 -> int`<br />
871    
872      * `cvt_unsigned_word64_to_int : word64 -> int`<br />
873    
874      * `cvt_word64_to_word : word64 -> word`<br />
875    
876    #### Conversions that are specific to 32-bit targets
877    
878    These conversions assume that the `LargeWord` structure is
879    bound to `Word32` (even though there is a `Word64` structure).
880    
881      * `cvt_int8_to_word32 : int8 -> word32`<br />
882        `P.EXTEND(8, 32)`
883    
884      * `cvt_word8_to_word32 : word8 -> word32`<br />
885        `P.COPY(8, 32)`
886    
887      * `cvt_int32_to_word32 : int32 -> word32`<br />
888        `P.COPY(32, 32)`
889    
890      * `cvt_int64_to_word32 : int64 -> word32`<br />
891        `P.TRUNC(64, 32)`
892    
893      * `cvt_word64_to_word32 : word64 -> word32`<br />
894        `P.TRUNC(64, 32)`
895    
896    #### Conversions that are specific to 64-bit targets
897    
898      * `cvt_int8_to_word64 : int8 -> word64`<br />
899        `P.EXTEND(8, 64)`
900    
901      * `cvt_word8_to_word64 : word8 -> word64`<br />
902        `P.COPY(8, 64)`
903    
904      * `cvt_int32_to_word64 : int32 -> word64`<br />
905        `P.EXTEND(32, 64)`
906    
907      * `cvt_word32_to_word64 : word32 -> word64`<br />
908        `P.COPY(32, 64)`
909    
910      * `cvt_int64_to_word64 : int64 -> word64`<br />
911        `P.COPY(64, 64)`
912    
913    #### Conversions between integers and reals
914    
915      * `cvt_int_to_real64 : int -> real64`<br />
916        `P.INT_TO_REAL{from=<int-size>, to=64}`
917    
918      * `cvt_int32_to_real64 : int32 -> real64`<br />
919        `P.INT_TO_REAL{from=32, to=64}`
920    
921      * `floor_real64_to_int : real64 -> int`<br />
922        `P.ROUND{floor=true, from=64, to=<int-size>}`
923    
924      * `round_real64_to_int : real64 -> int`<br />
925        `P.ROUND{floor=false, from=64, to=<int-size>}`
926    
927    ### Character comparisons
928    
929      * `char_lt : char * char -> bool`<br />
930        `P.CMP{oper=P.LT, kind=P.UINT <int-size>}`
931    
932      * `char_lte : char * char -> bool`<br />
933        `P.CMP{oper=P.LTE, kind=P.UINT <int-size>}`
934    
935      * `char_gt : char * char -> bool`<br />
936        `P.CMP{oper=P.GT, kind=P.UINT <int-size>}`
937    
938      * `char_gte : char * char -> bool`<br />
939        `P.CMP{oper=P.GTE, kind=P.UINT <int-size>}`

Legend:
Removed from v.4961  
changed lines
  Added in v.5019

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