File: X86CODESIG.sml

package info (click to toggle)
polyml 5.6-8
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 31,892 kB
  • ctags: 34,453
  • sloc: cpp: 44,983; ansic: 24,520; asm: 14,850; sh: 11,730; makefile: 551; exp: 484; python: 253; awk: 91; sed: 9
file content (209 lines) | stat: -rw-r--r-- 8,153 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
(*
    Copyright David C. J. Matthews 2010, 2012

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
    
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
    
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*)

signature X86CODESIG =
sig
    type machineWord = Address.machineWord
    type short = Address.short
    type address = Address.address

    type code

    val sameCode: code * code -> bool

    datatype reg =
        GenReg of Word8.word * bool
    |   FPReg of Word8.word

    val isX64: bool

    val eax: reg and ebx: reg and ecx: reg and edx: reg
    and edi: reg and esi: reg and esp: reg and ebp: reg
    and fp0: reg and fp1: reg and fp2: reg and fp3: reg
    and fp4: reg and fp5: reg and fp6: reg and fp7: reg
    and r8:  reg and r9:  reg and r10: reg and r11: reg
    and r12: reg and r13: reg and r14: reg and r15: reg
    (* For vector indexing we provide a numbering for the registers. *)
    val regs:   int
    val regN:   int -> reg
    val nReg:   reg -> int

    val regRepr: reg -> string
    
    type addrs and labList
    val addrZero: addrs

    structure RegSet:
    sig
        eqtype regSet
        val singleton: reg -> regSet
        val allRegisters: regSet (* All registers: data, address, floating pt. *)
        val generalRegisters: regSet (* Registers checked by the GC. *)
        val floatingPtRegisters: regSet
        val noRegisters: regSet
        val isAllRegs: regSet->bool
        val regSetUnion: regSet * regSet -> regSet
        val regSetIntersect: regSet * regSet -> regSet
        val listToSet: reg list -> regSet
        val setToList: regSet -> reg list
        val regSetMinus: regSet * regSet -> regSet
        val inSet: reg * regSet -> bool
        val cardinality: regSet -> int
        val regSetRepr: regSet -> string
        val oneOf: regSet -> reg
    end
    val getRegisterSet: Word.word -> RegSet.regSet

    datatype arithOp = ADD | OR (*|ADC | SBB*) | AND | SUB | XOR | CMP
    and      shiftType = SLL | SRL | SRA
    and      repOps = CMPSB | MOVSB | MOVSL | STOSB | STOSL
    and      fpOps = FADD | FMUL | FCOM | FCOMP | FSUB | FSUBR | FDIV | FDIVR
    and      fpUnaryOps = FABS | FCHS | FSQRT | FSIN | FCOS | FPATAN | FLD1 | FLDZ
    and      group3Ops = NOT | NEG | MUL | IMUL | DIV | IDIV

    datatype branchOps = JO | JNO | JE | JNE | JL | JGE | JLE | JG | JB | JNB | JNA | JA

    datatype callKinds =
        Recursive
    |   ConstantClosure of machineWord
    |   ConstantCode of machineWord
    |   CodeFun of code
    |   FullCall

    datatype label =
        Labels of
        {
            forward: labList ref,
            reverse: addrs ref,
            labId: int ref,
            uses: int ref,
            chain: label option ref
        }

    val mkLabel: unit -> label

    datatype indexType =
        NoIndex | Index1 of reg | Index2 of reg | Index4 of reg | Index8 of reg

    datatype memoryAddress =
        BaseOffset of { base: reg, offset: int, index: indexType }
    |   ConstantAddress of machineWord

    datatype branchPrediction = PredictNeutral | PredictTaken | PredictNotTaken

    datatype operation =
        MoveRR of { source: reg, output: reg }
    |   MoveConstR of { source: int, output: reg }
    |   MoveLongConstR of { source: machineWord, output: reg }
    |   LoadMemR of { source: memoryAddress, output: reg }
    |   LoadByteR of { source: memoryAddress, output: reg }
    |   PushR of reg
    |   PushConst of int
    |   PushLongConst of machineWord
    |   PushMem of { base: reg, offset: int }
    |   PopR of reg
    |   ArithRR of { opc: arithOp, output: reg, source: reg }
    |   ArithRConst of { opc: arithOp, output: reg, source: int }
    |   ArithRLongConst of { opc: arithOp, output: reg, source: machineWord }
    |   ArithRMem of { opc: arithOp, output: reg, offset: int, base: reg }
    |   ArithMemConst of { opc: arithOp, offset: int, base: reg, source: int }
    |   ArithMemLongConst of { opc: arithOp, offset: int, base: reg, source: machineWord }
    |   ShiftConstant of { shiftType: shiftType, output: reg, shift: Word8.word }
    |   ShiftVariable of { shiftType: shiftType, output: reg } (* Shift amount is in ecx *)
    |   ConditionalBranch of { test: branchOps, label: label, predict: branchPrediction }
    |   LockMutableSegment of reg
    |   LoadAddress of { output: reg, offset: int, base: reg option, index: indexType }
    |   LoadCodeRef of { output: reg, code: code }
    |   TestTagR of reg
    |   TestByteMem of { base: reg, offset: int, bits: word }
    |   CallRTS of int
    |   StoreRegToMemory of { toStore: reg, address: memoryAddress }
    |   StoreConstToMemory of { toStore: int, address: memoryAddress }
    |   StoreLongConstToMemory of { toStore: machineWord, address: memoryAddress }
    |   StoreByteRegToMemory of { toStore: reg, address: memoryAddress }
    |   StoreByteConstToMemory of { toStore: Word8.word, address: memoryAddress }
    |   AllocStore of { size: int, output: reg }
    |   AllocStoreVariable of reg
    |   StoreInitialised
    |   CallFunction of callKinds
    |   JumpToFunction of callKinds
    |   ReturnFromFunction of int
    |   RaiseException
    |   UncondBranch of label
    |   ResetStack of int
    |   InterruptCheck
    |   JumpLabel of label
    |   TagValue of { source: reg, output: reg }
        (* Some of these operations are higher-level and should be reduced. *)
    |   LoadHandlerAddress of { handlerLab: addrs ref, output: reg }
    |   StartHandler of { handlerLab: addrs ref }
    |   IndexedCase of { testReg: reg, workReg: reg, min: word, cases: label list }
    |   FreeRegisters of RegSet.regSet
    |   MakeSafe of reg
    |   RepeatOperation of repOps
    |   Group3Ops of reg * group3Ops
    |   AtomicXAdd of {base: reg, output: reg}
    |   FPLoadFromGenReg of reg
    |   FPLoadFromFPReg of { source: reg, lastRef: bool }
    |   FPLoadFromConst of real
    |   FPStoreToFPReg of { output: reg, andPop: bool }
    |   FPStoreToMemory of { base: reg, offset: int, andPop: bool }
    |   FPArithR of { opc: fpOps, source: reg }
    |   FPArithConst of { opc: fpOps, source: machineWord }
    |   FPArithMemory of { opc: fpOps, base: reg, offset: int }
    |   FPUnary of fpUnaryOps
    |   FPStatusToEAX
    |   FPLoadIntAndPop
    |   FPFree of reg
    |   PreAddDetag of reg

    type operations = operation list
    val printOperation: operation * (string -> unit) -> unit

    val codeCreate: bool * string * machineWord * Universal.universal list -> code  (* makes the initial segment. *)
    (* Code generate operations and construct the final code. *)
    val createCodeSegment: operations * RegSet.regSet * code -> address

    val addCompletionHook: code * (code * machineWord -> unit) -> unit

    val codeAddress: code -> address option
    val procName:   code -> string      (* Name of the procedure. *)

    val memRegHandlerRegister: int
    and memRegRaiseDiv: int
    and memRegArbEmulation: int
    and memRegThreadSelf: int
    and memRegStackLimit: int
    and memRegStackOverflowCall: int
    and memRegStackOverflowCallEx: int

    (* Debugging controls and streams for optimiser. *)
    val lowLevelOptimise: code -> bool
    val printLowLevelCode: operation list * code -> unit

    structure Sharing:
    sig
        type code           = code
        and  reg            = reg
        and  addrs          = addrs
        and  operation      = operation
        and  regSet         = RegSet.regSet
        and  label          = label
        and  labList        = labList
    end
end;