1(* 2 Copyright (c) 2012, 2016-20 David C.J. Matthews 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License version 2.1 as published by the Free Software Foundation. 7 8 This library is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 Lesser General Public License for more details. 12 13 You should have received a copy of the GNU Lesser General Public 14 License along with this library; if not, write to the Free Software 15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16*) 17 18(* Intermediate code tree for the back end of the compiler. *) 19 20signature BackendIntermediateCodeSig = 21sig 22 type machineWord = Address.machineWord 23 24 datatype argumentType = 25 GeneralType 26 | DoubleFloatType 27 | SingleFloatType 28 29 structure BuiltIns: BUILTINS 30 31 datatype backendIC = 32 BICNewenv of bicCodeBinding list * backendIC (* Set of bindings with an expression. *) 33 34 | BICConstnt of machineWord * Universal.universal list (* Load a constant *) 35 36 | BICExtract of bicLoadForm (* Get a local variable, an argument or a closure value *) 37 38 | BICField of {base: backendIC, offset: int } 39 (* Load a field from a tuple or record *) 40 41 | BICEval of (* Evaluate a function with an argument list. *) 42 { 43 function: backendIC, 44 argList: (backendIC * argumentType) list, 45 resultType: argumentType 46 } 47 48 (* Built-in functions. *) 49 | BICNullary of {oper: BuiltIns.nullaryOps} 50 | BICUnary of {oper: BuiltIns.unaryOps, arg1: backendIC} 51 | BICBinary of {oper: BuiltIns.binaryOps, arg1: backendIC, arg2: backendIC} 52 53 | BICArbitrary of {oper: BuiltIns.arithmeticOperations, shortCond: backendIC, arg1: backendIC, arg2: backendIC, longCall: backendIC} 54 55 | BICLambda of bicLambdaForm (* Lambda expressions. *) 56 57 | BICCond of backendIC * backendIC * backendIC (* If-then-else expression *) 58 59 | BICCase of (* Case expressions *) 60 { 61 cases : backendIC option list, (* NONE means "jump to the default". *) 62 test : backendIC, 63 default : backendIC, 64 isExhaustive: bool, 65 firstIndex: word 66 } 67 68 | BICBeginLoop of (* Start of tail-recursive inline function. *) 69 { loop: backendIC, arguments: (bicSimpleBinding * argumentType) list } 70 71 | BICLoop of (backendIC * argumentType) list (* Jump back to start of tail-recursive function. *) 72 73 | BICRaise of backendIC (* Raise an exception *) 74 75 | BICHandle of (* Exception handler. *) { exp: backendIC, handler: backendIC, exPacketAddr: int } 76 77 | BICTuple of backendIC list (* Tuple *) 78 79 | BICSetContainer of (* Copy a tuple to a container. *) 80 { 81 container: backendIC, 82 tuple: backendIC, 83 filter: BoolVector.vector 84 } 85 86 | BICLoadContainer of {base: backendIC, offset: int } 87 88 | BICTagTest of { test: backendIC, tag: word, maxTag: word } 89 90 | BICLoadOperation of { kind: loadStoreKind, address: bicAddress } 91 92 | BICStoreOperation of { kind: loadStoreKind, address: bicAddress, value: backendIC } 93 94 | BICBlockOperation of 95 { kind: blockOpKind, sourceLeft: bicAddress, destRight: bicAddress, length: backendIC } 96 97 | BICAllocateWordMemory of {numWords: backendIC, flags: backendIC, initial: backendIC} 98 99 100 and bicCodeBinding = 101 BICDeclar of bicSimpleBinding (* Make a local declaration or push an argument *) 102 | BICRecDecs of { addr: int, lambda: bicLambdaForm } list (* Set of mutually recursive declarations. *) 103 | BICNullBinding of backendIC (* Just evaluate the expression and discard the result. *) 104 | BICDecContainer of { addr: int, size: int } (* Create a container for a tuple on the stack. *) 105 106 and caseType = 107 CaseWord (* Word or fixed-precision integer. *) 108 | CaseTag of word 109 110 and bicLoadForm = 111 BICLoadLocal of int (* Local binding *) 112 | BICLoadArgument of int (* Argument - 0 is first arg etc.*) 113 | BICLoadClosure of int (* Closure - 0 is first closure item etc *) 114 | BICLoadRecursive (* Recursive call *) 115 116 and loadStoreKind = 117 LoadStoreMLWord of {isImmutable: bool} (* Load/Store an ML word in an ML word cell. *) 118 | LoadStoreMLByte of {isImmutable: bool} (* Load/Store a byte, tagging and untagging as appropriate, in an ML byte cell. *) 119 | LoadStoreC8 (* Load/Store C values - The base address is a boxed SysWord.word value. *) 120 | LoadStoreC16 121 | LoadStoreC32 122 | LoadStoreC64 123 | LoadStoreCFloat 124 | LoadStoreCDouble 125 | LoadStoreUntaggedUnsigned 126 127 and blockOpKind = 128 BlockOpMove of {isByteMove: bool} 129 | BlockOpEqualByte 130 | BlockOpCompareByte 131 132 withtype bicSimpleBinding = 133 { (* Declare a value or push an argument. *) 134 value: backendIC, 135 addr: int 136 } 137 138 and bicLambdaForm = 139 { (* Lambda expressions. *) 140 body : backendIC, 141 name : string, 142 closure : bicLoadForm list, 143 argTypes : argumentType list, 144 resultType : argumentType, 145 localCount : int, 146 heapClosure : bool 147 } 148 149 and bicAddress = 150 (* Address form used in loads, store and block operations. The base is an ML 151 address if this is to/from ML memory or a (boxed) SysWord.word if it is 152 to/from C memory. The index is a value in units of the size of the item 153 being loaded/stored and the offset is always in bytes. 154 For ML memory accesses the index and offset are unsigned; for C values 155 they are signed. *) 156 {base: backendIC, index: backendIC option, offset: int} 157 158 type pretty 159 val pretty : backendIC -> pretty 160 161 val loadStoreKindRepr: loadStoreKind -> string 162 and blockOpKindRepr: blockOpKind -> string 163 164 structure CodeTags: 165 sig 166 val tupleTag: Universal.universal list list Universal.tag 167 val mergeTupleProps: 168 Universal.universal list * Universal.universal list -> Universal.universal list 169 end 170 171 structure Sharing: 172 sig 173 type backendIC = backendIC 174 and bicLoadForm = bicLoadForm 175 and caseType = caseType 176 and pretty = pretty 177 and argumentType = argumentType 178 and bicCodeBinding = bicCodeBinding 179 and bicSimpleBinding = bicSimpleBinding 180 and loadStoreKind = loadStoreKind 181 and blockOpKind = blockOpKind 182 and unaryOps = BuiltIns.unaryOps 183 and binaryOps = BuiltIns.binaryOps 184 and nullaryOps = BuiltIns.nullaryOps 185 and testConditions = BuiltIns.testConditions 186 and arithmeticOperations = BuiltIns.arithmeticOperations 187 end 188 189end; 190