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