1(* 2 Copyright (c) 2012, 2016-17 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 | FloatingPtType 27 28 structure BuiltIns: BUILTINS 29 30 datatype backendIC = 31 BICNewenv of bicCodeBinding list * backendIC (* Set of bindings with an expression. *) 32 33 | BICConstnt of machineWord * Universal.universal list (* Load a constant *) 34 35 | BICExtract of bicLoadForm (* Get a local variable, an argument or a closure value *) 36 37 | BICField of {base: backendIC, offset: int } 38 (* Load a field from a tuple or record *) 39 40 | BICEval of (* Evaluate a function with an argument list. *) 41 { 42 function: backendIC, 43 argList: (backendIC * argumentType) list, 44 resultType: argumentType 45 } 46 47 (* Built-in functions. *) 48 | BICUnary of {oper: BuiltIns.unaryOps, arg1: backendIC} 49 | BICBinary of {oper: BuiltIns.binaryOps, arg1: backendIC, arg2: backendIC} 50 51 | BICArbitrary of {oper: BuiltIns.arithmeticOperations, shortCond: backendIC, arg1: backendIC, arg2: backendIC, longCall: backendIC} 52 53 | BICLambda of bicLambdaForm (* Lambda expressions. *) 54 55 | BICCond of backendIC * backendIC * backendIC (* If-then-else expression *) 56 57 | BICCase of (* Case expressions *) 58 { 59 cases : backendIC option list, (* NONE means "jump to the default". *) 60 test : backendIC, 61 default : backendIC, 62 isExhaustive: bool, 63 firstIndex: word 64 } 65 66 | BICBeginLoop of (* Start of tail-recursive inline function. *) 67 { loop: backendIC, arguments: (bicSimpleBinding * argumentType) list } 68 69 | BICLoop of (backendIC * argumentType) list (* Jump back to start of tail-recursive function. *) 70 71 | BICRaise of backendIC (* Raise an exception *) 72 73 | BICHandle of (* Exception handler. *) { exp: backendIC, handler: backendIC, exPacketAddr: int } 74 75 | BICTuple of backendIC list (* Tuple *) 76 77 | BICSetContainer of (* Copy a tuple to a container. *) 78 { 79 container: backendIC, 80 tuple: backendIC, 81 filter: BoolVector.vector 82 } 83 84 | BICTagTest of { test: backendIC, tag: word, maxTag: word } 85 86 | BICLoadOperation of { kind: loadStoreKind, address: bicAddress } 87 88 | BICStoreOperation of { kind: loadStoreKind, address: bicAddress, value: backendIC } 89 90 | BICBlockOperation of 91 { kind: blockOpKind, sourceLeft: bicAddress, destRight: bicAddress, length: backendIC } 92 93 | BICGetThreadId 94 95 | BICAllocateWordMemory of {numWords: backendIC, flags: backendIC, initial: backendIC} 96 97 98 and bicCodeBinding = 99 BICDeclar of bicSimpleBinding (* Make a local declaration or push an argument *) 100 | BICRecDecs of { addr: int, lambda: bicLambdaForm } list (* Set of mutually recursive declarations. *) 101 | BICNullBinding of backendIC (* Just evaluate the expression and discard the result. *) 102 | BICDecContainer of { addr: int, size: int } (* Create a container for a tuple on the stack. *) 103 104 and caseType = 105 CaseWord (* Word or fixed-precision integer. *) 106 | CaseTag of word 107 108 and bicLoadForm = 109 BICLoadLocal of int (* Local binding *) 110 | BICLoadArgument of int (* Argument - 0 is first arg etc.*) 111 | BICLoadClosure of int (* Closure - 0 is first closure item etc *) 112 | BICLoadRecursive (* Recursive call *) 113 114 and loadStoreKind = 115 LoadStoreMLWord of {isImmutable: bool} (* Load/Store an ML word in an ML word cell. *) 116 | LoadStoreMLByte of {isImmutable: bool} (* Load/Store a byte, tagging and untagging as appropriate, in an ML byte cell. *) 117 | LoadStoreC8 (* Load/Store C values - The base address is a boxed SysWord.word value. *) 118 | LoadStoreC16 119 | LoadStoreC32 120 | LoadStoreC64 121 | LoadStoreCFloat 122 | LoadStoreCDouble 123 | LoadStoreUntaggedUnsigned 124 125 and blockOpKind = 126 BlockOpMove of {isByteMove: bool} 127 | BlockOpEqualByte 128 | BlockOpCompareByte 129 130 withtype bicSimpleBinding = 131 { (* Declare a value or push an argument. *) 132 value: backendIC, 133 addr: int 134 } 135 136 and bicLambdaForm = 137 { (* Lambda expressions. *) 138 body : backendIC, 139 name : string, 140 closure : bicLoadForm list, 141 argTypes : argumentType list, 142 resultType : argumentType, 143 localCount : int, 144 heapClosure : bool 145 } 146 147 and bicAddress = 148 (* Address form used in loads, store and block operations. The base is an ML 149 address if this is to/from ML memory or a (boxed) SysWord.word if it is 150 to/from C memory. The index is a value in units of the size of the item 151 being loaded/stored and the offset is always in bytes. *) 152 {base: backendIC, index: backendIC option, offset: word} 153 154 type pretty 155 val pretty : backendIC -> pretty 156 157 val loadStoreKindRepr: loadStoreKind -> string 158 and blockOpKindRepr: blockOpKind -> string 159 160 structure CodeTags: 161 sig 162 val tupleTag: Universal.universal list list Universal.tag 163 val mergeTupleProps: 164 Universal.universal list * Universal.universal list -> Universal.universal list 165 end 166 167 structure Sharing: 168 sig 169 type backendIC = backendIC 170 and bicLoadForm = bicLoadForm 171 and caseType = caseType 172 and pretty = pretty 173 and argumentType = argumentType 174 and bicCodeBinding = bicCodeBinding 175 and bicSimpleBinding = bicSimpleBinding 176 and loadStoreKind = loadStoreKind 177 and blockOpKind = blockOpKind 178 and unaryOps = BuiltIns.unaryOps 179 and binaryOps = BuiltIns.binaryOps 180 and testConditions = BuiltIns.testConditions 181 and arithmeticOperations = BuiltIns.arithmeticOperations 182 end 183 184end; 185