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 4876, Sat Oct 6 15:33:34 2018 UTC revision 4961, Thu Apr 18 10:18:12 2019 UTC
# Line 7  Line 7 
7  internal representation becomes target-specific in many cases.  internal representation becomes target-specific in many cases.
8    
9    
   
10  ## Relavant source files  ## Relavant source files
11    
12    * `compiler/ElabData/prim/primop.sml`<br/>    * `compiler/ElabData/prim/primop.sml`<br/>
# Line 29  Line 28 
28    
29  ## Naming conventions  ## Naming conventions
30    
31    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      * "`seq`" -- sequence types (arrays and vectors)
49    
50    We use the attribute "`raw`" to denote direct machine operations that are not
51    directly accesible in the Basis Library (*e.g.*, shift operations, where the basis
52    versions clamp the shift amount to the word size, but the raw versions do not).
53    
54    We use the attribute "`unsafe`" for operations that could potentially result in
55    a crash (*e.g.*, array subscript operations that do not check the index against
56    the array bounds).
57    
58  ## Primitive operators  ## Primitive operators
59    
60  ### Size-independent primops  ### Size-independent primops
# Line 54  Line 80 
80    * `! : 'a ref -> 'a`<br/>    * `! : 'a ref -> 'a`<br/>
81      `P.DEREF`      `P.DEREF`
82    
83    * `:= : xx`<br/>    * `:= : 'a ref * 'a -> unit`<br/>
84      `P.ASSIGN`      `P.ASSIGN`
85    
86    * `makeref : 'a ref * 'a -> unit`<br/>    * `makeref : 'a ref * 'a -> unit`<br/>
# Line 81  Line 107 
107    * `<> : ''a * ''a -> bool`<br/>    * `<> : ''a * ''a -> bool`<br/>
108      `P.POLYNEQ`      `P.POLYNEQ`
109    
110    * `ptreql : 'a * 'a -> bool`<br/>    * `ptr_eql : 'a * 'a -> bool`<br/>
111      `P.PTREQL`      `P.PTREQL`
112    
113    * `ptrneq : 'a * 'a -> bool`<br/>    * `ptr_neq : 'a * 'a -> bool`<br/>
114      `P.PTRNEQ`      `P.PTRNEQ`
115    
116    
# Line 95  Line 121 
121    * `setvar : 'a -> unit`<br/>    * `setvar : 'a -> unit`<br/>
122      `P.SETVAR`      `P.SETVAR`
123    
   * `setpseudo : 'a * int -> unit`<br/>  
     `P.SETPSEUDO`  
   
   * `getpseudo : int -> 'a`<br/>  
     `P.GETPSEUDO`  
   
124    * `mkspecial : int * 'a -> 'b`<br/>    * `mkspecial : int * 'a -> 'b`<br/>
125      `P.MKSPECIAL`      `P.MKSPECIAL`
126    
# Line 119  Line 139 
139    * `gettag : 'a -> int`<br/>    * `gettag : 'a -> int`<br/>
140      `P.GETTAG`      `P.GETTAG`
141    
142    * `setmark : 'a -> unit`<br/>    * `objlength : 'a -> int`<br/>
143      `P.SETMARK`      extracts the length field from an object's header word.
144        `P.OBJLENGTH`
   * `dispose : 'a -> unit`<br/>  
     `P.DISPOSE`  
145    
146    
147  #### Inline operations  #### Inline operations
148    These primops are Basis Library functions that should be inlined for efficiency.
149    * `compose : ('b -> 'c) * ('a -> 'b) -> 'a -> 'c`<br/>    * `compose : ('b -> 'c) * ('a -> 'b) -> 'a -> 'c`<br/>
150      `P.INLCOMPOSE`      `P.INLCOMPOSE`
151    
# Line 139  Line 158 
158    * `identity : 'a -> 'a`<br/>    * `identity : 'a -> 'a`<br/>
159      `P.INLIDENTITY`      `P.INLIDENTITY`
160    
161    * `length : 'a -> int`<br/>    * `bool_not : bool -> bool`<br/>
     `P.LENGTH`  
   
   * `objlength : 'a -> int`<br/>  
     `P.OBJLENGTH`  
   
   * `unboxedupdate : 'a array * int * 'a -> unit`<br/>  
     `P.UNBOXEDUPDATE`  
   
   
 #### Boolean operations  
   * `inlnot : bool -> bool`<br/>  
162      `P.INLNOT`      `P.INLNOT`
163    
164    Some additional candidates for inlined operations include `hd`, `tl`, `null`, `chr`, and `ord`.
165    If the compiler had the `option` and `order` datatypes builtin (like `bool` and `list`),
166    then `valOf`, `isSome`, `isNone` and some of the `compare` functions could be inlined.
167    
 #### Bytearray and bytevector operations  
   * `ordof : 'a * int -> 'b`<br/>  
     `P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=true}`  
   
   * `store : 'a * int * 'b -> unit`<br/>  
     `P.NUMUPDATE{kind=P.INT 8, checked=false}`  
168    
169    * `inlbyteof : 'a * int -> 'b`<br/>  #### Bytearray and bytevector operations
170      `P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=false}`  Operations on byte/char array/vectors.  We renamed these to make it clear
171    which operations do bounds checking and which do not.
   * `inlstore : 'a * int * 'b -> unit`<br/>  
     `P.NUMUPDATE{kind=P.INT 8, checked=true}`  
172    
173    * `inlordof : 'a * int -> 'b`<br/>    * `bvec_unsafe_sub : 'a * int -> 'b`<br/>
174      `P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=true}`      subscript from byte vector without bounds checking
175        (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=true}`)
176    
177      * `barr_unsafe_sub : 'a * int -> 'b`<br/>
178        subscript from byte array without bounds checking
179        (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=false, immutable=false}`)
180    
181      * `barr_unsafe_update : 'a * int * 'b -> unit`<br/>
182        update byte array without bounds checking
183        (`P.NUMUPDATE{kind=P.INT 8, checked=false}`)
184    
185      * `bvec_sub : 'a * int -> 'b`<br/>
186        subscript from byte vector
187        (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=true}`)
188    
189      * `barr_sub : 'a * int -> 'b`<br/>
190        subscript from byte array
191        (`P.NUMSUBSCRIPT{kind=P.INT 8, checked=true, immutable=false}`)
192    
193      * `barr_update : 'a * int * 'b -> unit`<br/>
194        update byte array
195        (`P.NUMUPDATE{kind=P.INT 8, checked=true}`)
196    
197    
198  #### Polymorphic array and vector  #### Polymorphic array and vector
199    * `mkarray : int * 'a -> 'a array`<br/>    * `mkarray : int * 'a -> 'a array`<br/>
200      `P.INLMKARRAY`      create a polymorphic array
201        (`P.INLMKARRAY`)
   * `arrSub : 'a array * int -> 'a`<br/>  
     `P.SUBSCRIPT`  
   
   * `arrChkSub : 'a array * int -> 'a`<br/>  
     `P.INLSUBSCRIPT`  
   
   * `vecSub : 'a vector * int -> 'a`<br/>  
     `P.SUBSCRIPTV`  
202    
203    * `vecChkSub : 'a vector * int -> 'a`<br/>    * `arr_unsafe_sub : 'a array * int -> 'a`<br/>
204      `P.INLSUBSCRIPTV`      subscript from polymorphic array without bounds checking
205        (`P.SUBSCRIPT`)
206    * `arrUpdate : 'a array * int * 'a -> unit`<br/>  
207      `P.UPDATE`    * `arr_sub : 'a array * int -> 'a`<br/>
208        subscript from polymorphic array
209    * `arrChkUpdate : 'a array * int * 'a -> unit`<br/>      (`P.INLSUBSCRIPT`)
210      `P.INLUPDATE`  
211      * `vec_unsafe_sub : 'a vector * int -> 'a`<br/>
212        subscript from polymorphic vector without bounds checking
213        (`P.SUBSCRIPTV`)
214    
215      * `vec_sub : 'a vector * int -> 'a`<br/>
216        subscript from polymorphic vector
217        (`P.INLSUBSCRIPTV`)
218    
219      * `arr_unsafe_update : 'a array * int * 'a -> unit`<br/>
220        update a polymorphic array without bounds checking
221        (`P.UPDATE`)
222    
223      * `arr_update : 'a array * int * 'a -> unit`<br/>
224        update a polymorphic array
225        (`P.INLUPDATE`)
226    
227      * `arr_unboxed_update : 'a array * int * 'a -> unit`<br/>
228        update a polymorphic array with an unboxed value, which means that there is
229        no store-list entry created for the update.
230        `P.UNBOXEDUPDATE`
231    
232    
233  #### Sequence operations  #### Sequence operations
234    Sequence values (*e.g.*, `string`, `'a array`, `RealVector.vector`, *etc*.)
235    are represented by a header consisting of a length (in elements) and a data
236    pointer to the raw sequence data.
237    
238    * `newArray0 : unit -> 'a`<br/>    * `newArray0 : unit -> 'a`<br/>
239      `P.NEW_ARRAY0`      `P.NEW_ARRAY0`
240    
241    * `getSeqData : 'a -> 'b`<br/>    * `seq_length : 'a -> int`<br/>
242        get the length field from a sequence header
243        `P.LENGTH`
244    
245      * `seq_data : 'a -> 'b`<br/>
246        get the length field from a sequence header
247      `P.GET_SEQ_DATA`      `P.GET_SEQ_DATA`
248    
249    * `recordSub : 'a * int -> 'b`<br/>    * `unsafe_record_sub : 'a * int -> 'b`<br/>
250      `P.SUBSCRIPT_REC`      `P.SUBSCRIPT_REC`
251    
252    * `raw64Sub : 'a * int -> real64`<br/>    * `raw64Sub : 'a * int -> real64`<br/>
253        Unclear what purpose this primop serves
254      `P.SUBSCRIPT_RAW64`      `P.SUBSCRIPT_RAW64`
255    
256    
257  ### Numeric primops  ### Numeric primops
258    
259  #### Default tagged integer operations  #### Default tagged integer operations
260    These are the primitive operations on the default tagged integer
261    type (`Int.int`).
262    
263    * `int_add : int * int -> int`<br/>    * `int_add : int * int -> int`<br/>
264        Signed integer addition with overflow checking.
265      `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT <int-size>}`      `P.ARITH{oper=P.ADD, overflow=true, kind=P.INT <int-size>}`
266    
267      * `int_unsafe_add : int * int -> int`<br/>
268        Signed integer addition *without* overflow checking.
269        `P.ARITH{oper=P.ADD, overflow=false, kind=P.INT <int-size>}`
270    
271    * `int_sub : int * int -> int`<br/>    * `int_sub : int * int -> int`<br/>
272        Signed integer subtraction with overflow checking.
273      `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT <int-size>}`      `P.ARITH{oper=P.SUB, overflow=true, kind=P.INT <int-size>}`
274    
275      * `int_unsafe_sub : int * int -> int`<br/>
276        Signed integer subtraction *without* overflow checking.
277        `P.ARITH{oper=P.SUB, overflow=false, kind=P.INT <int-size>}`
278    
279    * `int_mul : int * int -> int`<br/>    * `int_mul : int * int -> int`<br/>
280      `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT <int-size>}`      `P.ARITH{oper=P.MUL, overflow=true, kind=P.INT <int-size>}`
281    
# Line 262  Line 321 
321    * `int_le : int * int -> bool`<br/>    * `int_le : int * int -> bool`<br/>
322      `P.CMP{oper=P.LTE, kind=P.INT <int-size>}`      `P.CMP{oper=P.LTE, kind=P.INT <int-size>}`
323    
324    * `int_eq : int * int -> bool`<br/>    * `int_eql : int * int -> bool`<br/>
325      `P.CMP{oper=P.EQL, kind=P.INT <int-size>}`      `P.CMP{oper=P.EQL, kind=P.INT <int-size>}`
326    
327    * `int_ne : int * int -> bool`<br/>    * `int_neq : int * int -> bool`<br/>
328      `P.CMP{oper=P.NEQ, kind=P.INT <int-size>}`      `P.CMP{oper=P.NEQ, kind=P.INT <int-size>}`
329    
330    * `int_min : int * int -> int`<br/>    * `int_min : int * int -> int`<br/>
# Line 278  Line 337 
337      `P.INLABS (P.INT <int-size>)`      `P.INLABS (P.INT <int-size>)`
338    
339  #### Default tagged word operations  #### Default tagged word operations
340    These are the primitive operations on the default tagged word
341    type (`Word.word`).
342    
343    * `word_mul : word * word -> word`<br/>    * `word_mul : word * word -> word`<br/>
344      `P.ARITH{oper=P.MUL, overflow=false, kind=P.INT <int-size>}`      `P.ARITH{oper=P.MUL, overflow=false, kind=P.INT <int-size>}`
345    
# Line 329  Line 391 
391    * `word_le : word * word -> bool`<br/>    * `word_le : word * word -> bool`<br/>
392      `P.CMP{oper=P.LTE, kind=P.UINT <int-size>}`      `P.CMP{oper=P.LTE, kind=P.UINT <int-size>}`
393    
394    * `word_eq : word * word -> bool`<br/>    * `word_eql : word * word -> bool`<br/>
395      `P.CMP{oper=P.EQL, kind=P.UINT <int-size>}`      `P.CMP{oper=P.EQL, kind=P.UINT <int-size>}`
396    
397    * `word_ne : word * word -> bool`<br/>    * `word_neq : word * word -> bool`<br/>
398      `P.CMP{oper=P.NEQ, kind=P.UINT <int-size>}`      `P.CMP{oper=P.NEQ, kind=P.UINT <int-size>}`
399    
400    * `word_raw_rshift : word * word -> word`<br/>    * `word_raw_rshift : word * word -> word`<br/>
# Line 404  Line 466 
466    * `int32_le : int32 * int32 -> bool`<br/>    * `int32_le : int32 * int32 -> bool`<br/>
467      `P.CMP{oper=P.LTE, kind=P.INT 32}`      `P.CMP{oper=P.LTE, kind=P.INT 32}`
468    
469    * `int32_eq : int32 * int32 -> bool`<br/>    * `int32_eql : int32 * int32 -> bool`<br/>
470      `P.CMP{oper=P.EQL, kind=P.INT 32}`      `P.CMP{oper=P.EQL, kind=P.INT 32}`
471    
472    * `int32_ne : int32 * int32 -> bool`<br/>    * `int32_neq : int32 * int32 -> bool`<br/>
473      `P.CMP{oper=P.NEQ, kind=P.INT 32}`      `P.CMP{oper=P.NEQ, kind=P.INT 32}`
474    
475    * `int32_min : int32 * int32 -> int32`<br/>    * `int32_min : int32 * int32 -> int32`<br/>
# Line 473  Line 535 
535    * `int64_le : int64 * int64 -> bool`<br/>    * `int64_le : int64 * int64 -> bool`<br/>
536      `P.CMP{oper=P.LTE, kind=P.INT 64}`      `P.CMP{oper=P.LTE, kind=P.INT 64}`
537    
538    * `int64_eq : int64 * int64 -> bool`<br/>    * `int64_eql : int64 * int64 -> bool`<br/>
539      `P.CMP{oper=P.EQL, kind=P.INT 64}`      `P.CMP{oper=P.EQL, kind=P.INT 64}`
540    
541    * `int64_ne : int64 * int64 -> bool`<br/>    * `int64_neq : int64 * int64 -> bool`<br/>
542      `P.CMP{oper=P.NEQ, kind=P.INT 64}`      `P.CMP{oper=P.NEQ, kind=P.INT 64}`
543    
544    * `int64_min : int64 * int64 -> int64`<br/>    * `int64_min : int64 * int64 -> int64`<br/>

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

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