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

# SCM Repository

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

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

Revision 773 - (view) (download) (as text)
Original Path: sml/trunk/src/compiler/FLINT/kernel/primop.sig

 1 : monnier 16 (* Copyright 1996 by AT&T Bell Laboratories *) 2 : (* primop.sig *) 3 : 4 : (********************************************************************* 5 : Integer/Word Conversions Explained 6 : 7 : All integer/word conversion operations are expressed using five 8 : primitive conversion operators. Algebraic equations over these 9 : operators are easy to define and can be used to simplify composition 10 : of conversion operations. 11 : 12 : The five basic conversion operators are (in all cases, we assume 13 : that (n >= m): 14 : 15 : TEST(n,m) -- map an n-bit, 2's complement signed value to an 16 : m-bit, 2's complement signed value; 17 : raise Overflow if the value is too large. 18 : 19 : TESTU(n,m) -- map an unsigned n-bit value to an m-bit 2's 20 : complement value; raise Overflow if the value 21 : is too large. 22 : 23 : EXTEND(m,n) -- sign extend an m-bit value to a n-bit value 24 : 25 : TRUNC(n,m) -- truncate an n-bit value to an m-bit value. 26 : 27 : COPY(m,n) -- copy an m-bit value to an n-bit value. 28 : 29 : TEST, TESTU, and TRUNC are used to go from large values to small 30 : ones, and EXTEND and COPY are used to go from small values to 31 : large. The operators EXTEND, TRUNC, and COPY are "pure," while TEST 32 : and TESTU may raise Overflow. 33 : 34 : Conversions where the sizes are the same can be simplified to copies: 35 : 36 : TEST(n,n) == COPY(n,n) 37 : EXTEND(n,n) == COPY(n,n) Note: this does not apply to TESTU 38 : TRUNC(n,n) == COPY(n,n) 39 : 40 : The translation of conversion operations in the Word32 and Word8 41 : structures (for example) is given by: 42 : 43 : Module function => Implemented by 44 : ---------------------------------------------------------- 45 : Word32 toLargeInt => TESTU(32,32) 46 : toLargeIntX => EXTEND(32,32) = COPY(32,32) 47 : fromLargeInt => COPY(32,32) 48 : toInt => TESTU(32,31) 49 : toIntX => TEST(32,31) 50 : fromInt => EXTEND(31,32) 51 : toLargeWord => COPY(32,32) 52 : toLargeWordX => EXTEND(32,32) = COPY(32,32) 53 : fromLargeWord => TRUNC(32,32) = COPY(32,32) 54 : 55 : Word8 toLargeInt => COPY(8,32) 56 : toLargeIntX => EXTEND(8,32) 57 : fromLargeInt => TRUNC(32,8) 58 : toInt => COPY(8,31) 59 : toIntX => EXTEND(8,31) 60 : fromInt => TRUNC(31,8) 61 : toLargeWord => COPY(8,32) 62 : toLargeWordX => EXTEND(8,32) 63 : fromLargeWord => TRUNC(32,8) 64 : 65 : 66 : Each operator composed with itself is itself, but with different parameters: 67 : 68 : TEST(n,m) o TEST(p,n) == TEST(p,m) 69 : TESTU(n,m) o TESTU(p,n) == TESTU(p,m) 70 : EXTEND(n,m) o EXTEND(p,n) == EXTEND(p,m) 71 : TRUNC(n,m) o TRUNC(p,n) == TRUNC(p,m) 72 : COPY(n,m) o COPY(p,n) == COPY(p,m) 73 : 74 : The composition of these operators can be described by a simple algebra. 75 : 76 : EXTEND(n,m) o COPY(p,n) == COPY(p,m) if (n > p) 77 : == EXTEND(p,m) if (n = p) 78 : COPY(n,m) o EXTEND(p,n) == EXTEND(p,m) if (n = m) 79 : 80 : TRUNC(n,m) o COPY(p,n) == COPY(p,m) if (m >= p) 81 : == TRUNC(p,m) if (m < p) 82 : 83 : COPY(n,m) o TRUNC(p,n) == TRUNC(p,m) if (n = m) 84 : 85 : TEST(n,m) o COPY(p,n) == COPY(p,m) if (m >= p) 86 : == TEST(p,m) if (m < p) 87 : 88 : TESTU(n,m) o COPY(p,n) == COPY(p,m) if (m >= p) 89 : == TESTU(p,m) if (m < p) 90 : 91 : COPY(n,m) o TEST(p,n) == TEST(p,m) if (n = m) 92 : 93 : COPY(n,m) o TESTU(p,n) == TESTU(p,m) if (n = m) 94 : 95 : TRUNC(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p) 96 : == TRUNC(p,m) if (m < p) 97 : 98 : TEST(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p) 99 : == TEST(p,m) if (m < p) 100 : 101 : TESTU(n,m) o EXTEND(p,n) == EXTEND(p,m) if (m >= p) 102 : == TESTU(p,m) if (m < p) 103 : 104 : For example, consider: 105 : Word.toInt o Word.fromLargeWord o Word8.toLargeWord 106 : 107 : This translates to: 108 : TESTU(31,31) o TRUNC(32,31) o COPY(8,32) 109 : 110 : and simplifies to: 111 : TESTU(31,31) o COPY(8,31) 112 : 113 : This further simplifies to: 114 : COPY(8, 31) 115 : 116 : Since both 8-bit and 31-bit quantities are tagged the same way, this 117 : gets translated to a MOVE. With a smart register allocator that MOVE 118 : can be eliminated. 119 : *********************************************************************) 120 : 121 : signature PRIM_OP = 122 : sig 123 : 124 : (* numkind includes kind and number of bits *) 125 : datatype numkind 126 : = INT of int 127 : | UINT of int 128 : | FLOAT of int 129 : 130 : datatype arithop 131 : george 717 = + | - | * | / | ~ (* int or float *) 132 : | ABS | FSQRT | FSIN | FCOS | FTAN (* floating point only *) 133 : | LSHIFT | RSHIFT | RSHIFTL (* int only *) 134 : | ANDB | ORB | XORB | NOTB (* int only *) 135 : 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 : ml_flt_args: bool list, 228 : ml_flt_res: bool } option 229 : monnier 16 230 : monnier 45 231 : monnier 16 val IADD : primop (* default integer addition *) 232 : val ISUB : primop (* default integer subtraction *) 233 : val IMUL : primop 234 : val IDIV : primop 235 : val INEG : primop 236 : 237 : val FEQLd : primop 238 : val IEQL : primop 239 : val INEQ : primop 240 : val IGT : primop 241 : val ILT : primop 242 : val ILE : primop 243 : val IGE : primop 244 : 245 : val prNumkind : numkind -> string 246 : val prPrimop: primop -> string 247 : val mayRaise : primop -> bool 248 : monnier 204 (* This should return more than just a boolean. 249 : * True means "can not be dead-code eliminated" *) 250 : val effect : primop -> bool 251 : monnier 16 252 : end (* signature PRIM_OP *) 253 :

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