ldstop.isa (11328:9512d2e25f14) ldstop.isa (11329:82bb3ee706b3)
1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
2// Copyright (c) 2015 Advanced Micro Devices, Inc.
2// All rights reserved.
3//
4// The license below extends only to copyright in the software and shall
5// not be construed as granting a license to any other intellectual
6// property including but not limited to intellectual property relating
7// to a hardware implementation of the functionality of the software
8// licensed hereunder. You may use the software subject to the license
9// terms below provided that you ensure that this notice is replicated
10// unmodified and in its entirety in all distributions of the software,
11// modified or unmodified, in source code or in binary form.
12//
13// Copyright (c) 2008 The Regents of The University of Michigan
14// All rights reserved.
15//
16// Redistribution and use in source and binary forms, with or without
17// modification, are permitted provided that the following conditions are
18// met: redistributions of source code must retain the above copyright
19// notice, this list of conditions and the following disclaimer;
20// redistributions in binary form must reproduce the above copyright
21// notice, this list of conditions and the following disclaimer in the
22// documentation and/or other materials provided with the distribution;
23// neither the name of the copyright holders nor the names of its
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38//
39// Authors: Gabe Black
40
41//////////////////////////////////////////////////////////////////////////
42//
43// LdStOp Microop templates
44//
45//////////////////////////////////////////////////////////////////////////
46
47// LEA template
48
49def template MicroLeaExecute {{
50 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
51 Trace::InstRecord *traceData) const
52 {
53 Fault fault = NoFault;
54 Addr EA;
55
56 %(op_decl)s;
57 %(op_rd)s;
58 %(ea_code)s;
59 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
60
61 %(code)s;
62 if(fault == NoFault)
63 {
64 %(op_wb)s;
65 }
66
67 return fault;
68 }
69}};
70
71def template MicroLeaDeclare {{
72 class %(class_name)s : public %(base_class)s
73 {
74 public:
75 %(class_name)s(ExtMachInst _machInst,
76 const char * instMnem, uint64_t setFlags,
77 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
78 uint64_t _disp, InstRegIndex _segment,
79 InstRegIndex _data,
80 uint8_t _dataSize, uint8_t _addressSize,
81 Request::FlagsType _memFlags);
82
83 %(BasicExecDeclare)s
84 };
85}};
86
87// Load templates
88
89def template MicroLoadExecute {{
90 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
91 Trace::InstRecord *traceData) const
92 {
93 Fault fault = NoFault;
94 Addr EA;
95
96 %(op_decl)s;
97 %(op_rd)s;
98 %(ea_code)s;
99 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
100
3// All rights reserved.
4//
5// The license below extends only to copyright in the software and shall
6// not be construed as granting a license to any other intellectual
7// property including but not limited to intellectual property relating
8// to a hardware implementation of the functionality of the software
9// licensed hereunder. You may use the software subject to the license
10// terms below provided that you ensure that this notice is replicated
11// unmodified and in its entirety in all distributions of the software,
12// modified or unmodified, in source code or in binary form.
13//
14// Copyright (c) 2008 The Regents of The University of Michigan
15// All rights reserved.
16//
17// Redistribution and use in source and binary forms, with or without
18// modification, are permitted provided that the following conditions are
19// met: redistributions of source code must retain the above copyright
20// notice, this list of conditions and the following disclaimer;
21// redistributions in binary form must reproduce the above copyright
22// notice, this list of conditions and the following disclaimer in the
23// documentation and/or other materials provided with the distribution;
24// neither the name of the copyright holders nor the names of its
25// contributors may be used to endorse or promote products derived from
26// this software without specific prior written permission.
27//
28// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39//
40// Authors: Gabe Black
41
42//////////////////////////////////////////////////////////////////////////
43//
44// LdStOp Microop templates
45//
46//////////////////////////////////////////////////////////////////////////
47
48// LEA template
49
50def template MicroLeaExecute {{
51 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
52 Trace::InstRecord *traceData) const
53 {
54 Fault fault = NoFault;
55 Addr EA;
56
57 %(op_decl)s;
58 %(op_rd)s;
59 %(ea_code)s;
60 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
61
62 %(code)s;
63 if(fault == NoFault)
64 {
65 %(op_wb)s;
66 }
67
68 return fault;
69 }
70}};
71
72def template MicroLeaDeclare {{
73 class %(class_name)s : public %(base_class)s
74 {
75 public:
76 %(class_name)s(ExtMachInst _machInst,
77 const char * instMnem, uint64_t setFlags,
78 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
79 uint64_t _disp, InstRegIndex _segment,
80 InstRegIndex _data,
81 uint8_t _dataSize, uint8_t _addressSize,
82 Request::FlagsType _memFlags);
83
84 %(BasicExecDeclare)s
85 };
86}};
87
88// Load templates
89
90def template MicroLoadExecute {{
91 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
92 Trace::InstRecord *traceData) const
93 {
94 Fault fault = NoFault;
95 Addr EA;
96
97 %(op_decl)s;
98 %(op_rd)s;
99 %(ea_code)s;
100 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
101
101 fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
102 fault = readMemAtomic(xc, traceData, EA, Mem,
103 %(memDataSize)s, memFlags);
102
103 if (fault == NoFault) {
104 %(code)s;
105 } else if (memFlags & Request::PREFETCH) {
106 // For prefetches, ignore any faults/exceptions.
107 return NoFault;
108 }
109 if(fault == NoFault)
110 {
111 %(op_wb)s;
112 }
113
114 return fault;
115 }
116}};
117
118def template MicroLoadInitiateAcc {{
119 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
120 Trace::InstRecord * traceData) const
121 {
122 Fault fault = NoFault;
123 Addr EA;
124
125 %(op_decl)s;
126 %(op_rd)s;
127 %(ea_code)s;
128 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
129
104
105 if (fault == NoFault) {
106 %(code)s;
107 } else if (memFlags & Request::PREFETCH) {
108 // For prefetches, ignore any faults/exceptions.
109 return NoFault;
110 }
111 if(fault == NoFault)
112 {
113 %(op_wb)s;
114 }
115
116 return fault;
117 }
118}};
119
120def template MicroLoadInitiateAcc {{
121 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
122 Trace::InstRecord * traceData) const
123 {
124 Fault fault = NoFault;
125 Addr EA;
126
127 %(op_decl)s;
128 %(op_rd)s;
129 %(ea_code)s;
130 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
131
130 fault = initiateMemRead(xc, traceData, EA, dataSize, memFlags);
132 fault = initiateMemRead(xc, traceData, EA,
133 %(memDataSize)s, memFlags);
131
132 return fault;
133 }
134}};
135
136def template MicroLoadCompleteAcc {{
137 Fault %(class_name)s::completeAcc(PacketPtr pkt,
138 CPU_EXEC_CONTEXT * xc,
139 Trace::InstRecord * traceData) const
140 {
141 Fault fault = NoFault;
142
143 %(op_decl)s;
144 %(op_rd)s;
145
134
135 return fault;
136 }
137}};
138
139def template MicroLoadCompleteAcc {{
140 Fault %(class_name)s::completeAcc(PacketPtr pkt,
141 CPU_EXEC_CONTEXT * xc,
142 Trace::InstRecord * traceData) const
143 {
144 Fault fault = NoFault;
145
146 %(op_decl)s;
147 %(op_rd)s;
148
146 getMem(pkt, Mem, dataSize, traceData);
149 getMem(pkt, Mem, %(memDataSize)s, traceData);
147
148 %(code)s;
149
150 if(fault == NoFault)
151 {
152 %(op_wb)s;
153 }
154
155 return fault;
156 }
157}};
158
159// Store templates
160
161def template MicroStoreExecute {{
162 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT * xc,
163 Trace::InstRecord *traceData) const
164 {
165 Fault fault = NoFault;
166
167 Addr EA;
168 %(op_decl)s;
169 %(op_rd)s;
170 %(ea_code)s;
171 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
172
173 %(code)s;
174
175 if(fault == NoFault)
176 {
150
151 %(code)s;
152
153 if(fault == NoFault)
154 {
155 %(op_wb)s;
156 }
157
158 return fault;
159 }
160}};
161
162// Store templates
163
164def template MicroStoreExecute {{
165 Fault %(class_name)s::execute(CPU_EXEC_CONTEXT * xc,
166 Trace::InstRecord *traceData) const
167 {
168 Fault fault = NoFault;
169
170 Addr EA;
171 %(op_decl)s;
172 %(op_rd)s;
173 %(ea_code)s;
174 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
175
176 %(code)s;
177
178 if(fault == NoFault)
179 {
177 fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
180 fault = writeMemAtomic(xc, traceData, Mem, %(memDataSize)s, EA,
178 memFlags, NULL);
179 if(fault == NoFault)
180 {
181 %(op_wb)s;
182 }
183 }
184
185 return fault;
186 }
187}};
188
189def template MicroStoreInitiateAcc {{
190 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
191 Trace::InstRecord * traceData) const
192 {
193 Fault fault = NoFault;
194
195 Addr EA;
196 %(op_decl)s;
197 %(op_rd)s;
198 %(ea_code)s;
199 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
200
201 %(code)s;
202
203 if(fault == NoFault)
204 {
181 memFlags, NULL);
182 if(fault == NoFault)
183 {
184 %(op_wb)s;
185 }
186 }
187
188 return fault;
189 }
190}};
191
192def template MicroStoreInitiateAcc {{
193 Fault %(class_name)s::initiateAcc(CPU_EXEC_CONTEXT * xc,
194 Trace::InstRecord * traceData) const
195 {
196 Fault fault = NoFault;
197
198 Addr EA;
199 %(op_decl)s;
200 %(op_rd)s;
201 %(ea_code)s;
202 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
203
204 %(code)s;
205
206 if(fault == NoFault)
207 {
205 fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
208 fault = writeMemTiming(xc, traceData, Mem, %(memDataSize)s, EA,
206 memFlags, NULL);
207 }
208 return fault;
209 }
210}};
211
212def template MicroStoreCompleteAcc {{
213 Fault %(class_name)s::completeAcc(PacketPtr pkt,
214 CPU_EXEC_CONTEXT * xc, Trace::InstRecord * traceData) const
215 {
216 %(op_decl)s;
217 %(op_rd)s;
218 %(complete_code)s;
219 %(op_wb)s;
220 return NoFault;
221 }
222}};
223
224// Common templates
225
226//This delcares the initiateAcc function in memory operations
227def template InitiateAccDeclare {{
228 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
229}};
230
231//This declares the completeAcc function in memory operations
232def template CompleteAccDeclare {{
233 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
234}};
235
236def template MicroLdStOpDeclare {{
237 class %(class_name)s : public %(base_class)s
238 {
239 public:
240 %(class_name)s(ExtMachInst _machInst,
241 const char * instMnem, uint64_t setFlags,
242 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
243 uint64_t _disp, InstRegIndex _segment,
244 InstRegIndex _data,
245 uint8_t _dataSize, uint8_t _addressSize,
246 Request::FlagsType _memFlags);
247
248 %(BasicExecDeclare)s
249
250 %(InitiateAccDeclare)s
251
252 %(CompleteAccDeclare)s
253 };
254}};
255
209 memFlags, NULL);
210 }
211 return fault;
212 }
213}};
214
215def template MicroStoreCompleteAcc {{
216 Fault %(class_name)s::completeAcc(PacketPtr pkt,
217 CPU_EXEC_CONTEXT * xc, Trace::InstRecord * traceData) const
218 {
219 %(op_decl)s;
220 %(op_rd)s;
221 %(complete_code)s;
222 %(op_wb)s;
223 return NoFault;
224 }
225}};
226
227// Common templates
228
229//This delcares the initiateAcc function in memory operations
230def template InitiateAccDeclare {{
231 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
232}};
233
234//This declares the completeAcc function in memory operations
235def template CompleteAccDeclare {{
236 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
237}};
238
239def template MicroLdStOpDeclare {{
240 class %(class_name)s : public %(base_class)s
241 {
242 public:
243 %(class_name)s(ExtMachInst _machInst,
244 const char * instMnem, uint64_t setFlags,
245 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
246 uint64_t _disp, InstRegIndex _segment,
247 InstRegIndex _data,
248 uint8_t _dataSize, uint8_t _addressSize,
249 Request::FlagsType _memFlags);
250
251 %(BasicExecDeclare)s
252
253 %(InitiateAccDeclare)s
254
255 %(CompleteAccDeclare)s
256 };
257}};
258
259// LdStSplitOp is a load or store that uses a pair of regs as the
260// source or destination. Used for cmpxchg{8,16}b.
261def template MicroLdStSplitOpDeclare {{
262 class %(class_name)s : public %(base_class)s
263 {
264 public:
265 %(class_name)s(ExtMachInst _machInst,
266 const char * instMnem, uint64_t setFlags,
267 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
268 uint64_t _disp, InstRegIndex _segment,
269 InstRegIndex _dataLow, InstRegIndex _dataHi,
270 uint8_t _dataSize, uint8_t _addressSize,
271 Request::FlagsType _memFlags);
272
273 %(BasicExecDeclare)s
274
275 %(InitiateAccDeclare)s
276
277 %(CompleteAccDeclare)s
278 };
279}};
280
256def template MicroLdStOpConstructor {{
257 %(class_name)s::%(class_name)s(
258 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
259 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
260 uint64_t _disp, InstRegIndex _segment,
261 InstRegIndex _data,
262 uint8_t _dataSize, uint8_t _addressSize,
263 Request::FlagsType _memFlags) :
264 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
265 _scale, _index, _base,
266 _disp, _segment, _data,
267 _dataSize, _addressSize, _memFlags, %(op_class)s)
268 {
269 %(constructor)s;
270 }
271}};
272
281def template MicroLdStOpConstructor {{
282 %(class_name)s::%(class_name)s(
283 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
284 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
285 uint64_t _disp, InstRegIndex _segment,
286 InstRegIndex _data,
287 uint8_t _dataSize, uint8_t _addressSize,
288 Request::FlagsType _memFlags) :
289 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
290 _scale, _index, _base,
291 _disp, _segment, _data,
292 _dataSize, _addressSize, _memFlags, %(op_class)s)
293 {
294 %(constructor)s;
295 }
296}};
297
298def template MicroLdStSplitOpConstructor {{
299 %(class_name)s::%(class_name)s(
300 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
301 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
302 uint64_t _disp, InstRegIndex _segment,
303 InstRegIndex _dataLow, InstRegIndex _dataHi,
304 uint8_t _dataSize, uint8_t _addressSize,
305 Request::FlagsType _memFlags) :
306 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
307 _scale, _index, _base,
308 _disp, _segment, _dataLow, _dataHi,
309 _dataSize, _addressSize, _memFlags, %(op_class)s)
310 {
311 %(constructor)s;
312 }
313}};
314
273let {{
274 class LdStOp(X86Microop):
275 def __init__(self, data, segment, addr, disp,
276 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
277 self.data = data
278 [self.scale, self.index, self.base] = addr
279 self.disp = disp
280 self.segment = segment
281 self.dataSize = dataSize
282 self.addressSize = addressSize
283 self.memFlags = baseFlags
284 if atCPL0:
285 self.memFlags += " | (CPL0FlagBit << FlagShift)"
286 self.instFlags = ""
287 if prefetch:
288 self.memFlags += " | Request::PREFETCH"
289 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
290 if nonSpec:
291 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
292 self.memFlags += " | (machInst.legacy.addr ? " + \
293 "(AddrSizeFlagBit << FlagShift) : 0)"
294
295 def getAllocator(self, microFlags):
296 allocator = '''new %(class_name)s(machInst, macrocodeBlock,
297 %(flags)s, %(scale)s, %(index)s, %(base)s,
298 %(disp)s, %(segment)s, %(data)s,
299 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
300 "class_name" : self.className,
301 "flags" : self.microFlagsText(microFlags) + self.instFlags,
302 "scale" : self.scale, "index" : self.index,
303 "base" : self.base,
304 "disp" : self.disp,
305 "segment" : self.segment, "data" : self.data,
306 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
307 "memFlags" : self.memFlags}
308 return allocator
309
310 class BigLdStOp(X86Microop):
311 def __init__(self, data, segment, addr, disp,
312 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
313 self.data = data
314 [self.scale, self.index, self.base] = addr
315 self.disp = disp
316 self.segment = segment
317 self.dataSize = dataSize
318 self.addressSize = addressSize
319 self.memFlags = baseFlags
320 if atCPL0:
321 self.memFlags += " | (CPL0FlagBit << FlagShift)"
322 self.instFlags = ""
323 if prefetch:
324 self.memFlags += " | Request::PREFETCH"
325 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
326 if nonSpec:
327 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
328 self.memFlags += " | (machInst.legacy.addr ? " + \
329 "(AddrSizeFlagBit << FlagShift) : 0)"
330
331 def getAllocator(self, microFlags):
332 allocString = '''
333 (%(dataSize)s >= 4) ?
334 (StaticInstPtr)(new %(class_name)sBig(machInst,
335 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
336 %(base)s, %(disp)s, %(segment)s, %(data)s,
337 %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
338 (StaticInstPtr)(new %(class_name)s(machInst,
339 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
340 %(base)s, %(disp)s, %(segment)s, %(data)s,
341 %(dataSize)s, %(addressSize)s, %(memFlags)s))
342 '''
343 allocator = allocString % {
344 "class_name" : self.className,
345 "flags" : self.microFlagsText(microFlags) + self.instFlags,
346 "scale" : self.scale, "index" : self.index,
347 "base" : self.base,
348 "disp" : self.disp,
349 "segment" : self.segment, "data" : self.data,
350 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
351 "memFlags" : self.memFlags}
352 return allocator
315let {{
316 class LdStOp(X86Microop):
317 def __init__(self, data, segment, addr, disp,
318 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
319 self.data = data
320 [self.scale, self.index, self.base] = addr
321 self.disp = disp
322 self.segment = segment
323 self.dataSize = dataSize
324 self.addressSize = addressSize
325 self.memFlags = baseFlags
326 if atCPL0:
327 self.memFlags += " | (CPL0FlagBit << FlagShift)"
328 self.instFlags = ""
329 if prefetch:
330 self.memFlags += " | Request::PREFETCH"
331 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
332 if nonSpec:
333 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
334 self.memFlags += " | (machInst.legacy.addr ? " + \
335 "(AddrSizeFlagBit << FlagShift) : 0)"
336
337 def getAllocator(self, microFlags):
338 allocator = '''new %(class_name)s(machInst, macrocodeBlock,
339 %(flags)s, %(scale)s, %(index)s, %(base)s,
340 %(disp)s, %(segment)s, %(data)s,
341 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
342 "class_name" : self.className,
343 "flags" : self.microFlagsText(microFlags) + self.instFlags,
344 "scale" : self.scale, "index" : self.index,
345 "base" : self.base,
346 "disp" : self.disp,
347 "segment" : self.segment, "data" : self.data,
348 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
349 "memFlags" : self.memFlags}
350 return allocator
351
352 class BigLdStOp(X86Microop):
353 def __init__(self, data, segment, addr, disp,
354 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
355 self.data = data
356 [self.scale, self.index, self.base] = addr
357 self.disp = disp
358 self.segment = segment
359 self.dataSize = dataSize
360 self.addressSize = addressSize
361 self.memFlags = baseFlags
362 if atCPL0:
363 self.memFlags += " | (CPL0FlagBit << FlagShift)"
364 self.instFlags = ""
365 if prefetch:
366 self.memFlags += " | Request::PREFETCH"
367 self.instFlags += " | (1ULL << StaticInst::IsDataPrefetch)"
368 if nonSpec:
369 self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
370 self.memFlags += " | (machInst.legacy.addr ? " + \
371 "(AddrSizeFlagBit << FlagShift) : 0)"
372
373 def getAllocator(self, microFlags):
374 allocString = '''
375 (%(dataSize)s >= 4) ?
376 (StaticInstPtr)(new %(class_name)sBig(machInst,
377 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
378 %(base)s, %(disp)s, %(segment)s, %(data)s,
379 %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
380 (StaticInstPtr)(new %(class_name)s(machInst,
381 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
382 %(base)s, %(disp)s, %(segment)s, %(data)s,
383 %(dataSize)s, %(addressSize)s, %(memFlags)s))
384 '''
385 allocator = allocString % {
386 "class_name" : self.className,
387 "flags" : self.microFlagsText(microFlags) + self.instFlags,
388 "scale" : self.scale, "index" : self.index,
389 "base" : self.base,
390 "disp" : self.disp,
391 "segment" : self.segment, "data" : self.data,
392 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
393 "memFlags" : self.memFlags}
394 return allocator
395
396 class LdStSplitOp(LdStOp):
397 def __init__(self, data, segment, addr, disp,
398 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec):
399 super(LdStSplitOp, self).__init__(0, segment, addr, disp,
400 dataSize, addressSize, baseFlags, atCPL0, prefetch, nonSpec)
401 (self.dataLow, self.dataHi) = data
402
403 def getAllocator(self, microFlags):
404 allocString = '''(StaticInstPtr)(new %(class_name)s(machInst,
405 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
406 %(base)s, %(disp)s, %(segment)s,
407 %(dataLow)s, %(dataHi)s,
408 %(dataSize)s, %(addressSize)s, %(memFlags)s))
409 '''
410 allocator = allocString % {
411 "class_name" : self.className,
412 "flags" : self.microFlagsText(microFlags) + self.instFlags,
413 "scale" : self.scale, "index" : self.index,
414 "base" : self.base,
415 "disp" : self.disp,
416 "segment" : self.segment,
417 "dataLow" : self.dataLow, "dataHi" : self.dataHi,
418 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
419 "memFlags" : self.memFlags}
420 return allocator
421
353}};
354
355let {{
356
357 # Make these empty strings so that concatenating onto
358 # them will always work.
359 header_output = ""
360 decoder_output = ""
361 exec_output = ""
362
422}};
423
424let {{
425
426 # Make these empty strings so that concatenating onto
427 # them will always work.
428 header_output = ""
429 decoder_output = ""
430 exec_output = ""
431
363 calculateEA = '''
364 EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
365 '''
432 segmentEAExpr = \
433 'bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);'
366
434
435 calculateEA = 'EA = SegBase + ' + segmentEAExpr
436
367 def defineMicroLoadOp(mnemonic, code, bigCode='',
437 def defineMicroLoadOp(mnemonic, code, bigCode='',
368 mem_flags="0", big=True):
438 mem_flags="0", big=True, nonSpec=False):
369 global header_output
370 global decoder_output
371 global exec_output
372 global microopClasses
373 Name = mnemonic
374 name = mnemonic.lower()
375
376 # Build up the all register version of this micro op
377 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
439 global header_output
440 global decoder_output
441 global exec_output
442 global microopClasses
443 Name = mnemonic
444 name = mnemonic.lower()
445
446 # Build up the all register version of this micro op
447 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
378 {"code": code, "ea_code": calculateEA})]
448 { "code": code,
449 "ea_code": calculateEA,
450 "memDataSize": "dataSize" })]
379 if big:
380 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
451 if big:
452 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
381 {"code": bigCode, "ea_code": calculateEA})]
453 { "code": bigCode,
454 "ea_code": calculateEA,
455 "memDataSize": "dataSize" })]
382 for iop in iops:
383 header_output += MicroLdStOpDeclare.subst(iop)
384 decoder_output += MicroLdStOpConstructor.subst(iop)
385 exec_output += MicroLoadExecute.subst(iop)
386 exec_output += MicroLoadInitiateAcc.subst(iop)
387 exec_output += MicroLoadCompleteAcc.subst(iop)
388
389 base = LdStOp
390 if big:
391 base = BigLdStOp
392 class LoadOp(base):
393 def __init__(self, data, segment, addr, disp = 0,
394 dataSize="env.dataSize",
395 addressSize="env.addressSize",
456 for iop in iops:
457 header_output += MicroLdStOpDeclare.subst(iop)
458 decoder_output += MicroLdStOpConstructor.subst(iop)
459 exec_output += MicroLoadExecute.subst(iop)
460 exec_output += MicroLoadInitiateAcc.subst(iop)
461 exec_output += MicroLoadCompleteAcc.subst(iop)
462
463 base = LdStOp
464 if big:
465 base = BigLdStOp
466 class LoadOp(base):
467 def __init__(self, data, segment, addr, disp = 0,
468 dataSize="env.dataSize",
469 addressSize="env.addressSize",
396 atCPL0=False, prefetch=False, nonSpec=False):
470 atCPL0=False, prefetch=False, nonSpec=nonSpec):
397 super(LoadOp, self).__init__(data, segment, addr,
398 disp, dataSize, addressSize, mem_flags,
399 atCPL0, prefetch, nonSpec)
400 self.className = Name
401 self.mnemonic = name
402
403 microopClasses[name] = LoadOp
404
405 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
406 'Data = Mem & mask(dataSize * 8);')
407 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
408 'Data = Mem & mask(dataSize * 8);',
409 '(StoreCheck << FlagShift)')
410 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
411 'Data = Mem & mask(dataSize * 8);',
471 super(LoadOp, self).__init__(data, segment, addr,
472 disp, dataSize, addressSize, mem_flags,
473 atCPL0, prefetch, nonSpec)
474 self.className = Name
475 self.mnemonic = name
476
477 microopClasses[name] = LoadOp
478
479 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
480 'Data = Mem & mask(dataSize * 8);')
481 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
482 'Data = Mem & mask(dataSize * 8);',
483 '(StoreCheck << FlagShift)')
484 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
485 'Data = Mem & mask(dataSize * 8);',
412 '(StoreCheck << FlagShift) | Request::LOCKED_RMW')
486 '(StoreCheck << FlagShift) | Request::LOCKED_RMW',
487 nonSpec=True)
413
414 defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
415
416 defineMicroLoadOp('Ldfp87', code='''
417 switch (dataSize)
418 {
419 case 4:
420 FpData_df = *(float *)&Mem;
421 break;
422 case 8:
423 FpData_df = *(double *)&Mem;
424 break;
425 default:
426 panic("Unhandled data size in LdFp87.\\n");
427 }
428 ''', big = False)
429
430 # Load integer from memory into x87 top-of-stack register.
431 # Used to implement fild instruction.
432 defineMicroLoadOp('Ldifp87', code='''
433 switch (dataSize)
434 {
435 case 2:
436 FpData_df = (int64_t)sext<16>(Mem);
437 break;
438 case 4:
439 FpData_df = (int64_t)sext<32>(Mem);
440 break;
441 case 8:
442 FpData_df = (int64_t)Mem;
443 break;
444 default:
445 panic("Unhandled data size in LdIFp87.\\n");
446 }
447 ''', big = False)
448
488
489 defineMicroLoadOp('Ldfp', code='FpData_uqw = Mem', big = False)
490
491 defineMicroLoadOp('Ldfp87', code='''
492 switch (dataSize)
493 {
494 case 4:
495 FpData_df = *(float *)&Mem;
496 break;
497 case 8:
498 FpData_df = *(double *)&Mem;
499 break;
500 default:
501 panic("Unhandled data size in LdFp87.\\n");
502 }
503 ''', big = False)
504
505 # Load integer from memory into x87 top-of-stack register.
506 # Used to implement fild instruction.
507 defineMicroLoadOp('Ldifp87', code='''
508 switch (dataSize)
509 {
510 case 2:
511 FpData_df = (int64_t)sext<16>(Mem);
512 break;
513 case 4:
514 FpData_df = (int64_t)sext<32>(Mem);
515 break;
516 case 8:
517 FpData_df = (int64_t)Mem;
518 break;
519 default:
520 panic("Unhandled data size in LdIFp87.\\n");
521 }
522 ''', big = False)
523
524 def defineMicroLoadSplitOp(mnemonic, code, mem_flags="0", nonSpec=False):
525 global header_output
526 global decoder_output
527 global exec_output
528 global microopClasses
529 Name = mnemonic
530 name = mnemonic.lower()
531
532 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
533 { "code": code,
534 "ea_code": calculateEA,
535 "memDataSize": "2 * dataSize" })
536
537 header_output += MicroLdStSplitOpDeclare.subst(iop)
538 decoder_output += MicroLdStSplitOpConstructor.subst(iop)
539 exec_output += MicroLoadExecute.subst(iop)
540 exec_output += MicroLoadInitiateAcc.subst(iop)
541 exec_output += MicroLoadCompleteAcc.subst(iop)
542
543 class LoadOp(LdStSplitOp):
544 def __init__(self, data, segment, addr, disp = 0,
545 dataSize="env.dataSize",
546 addressSize="env.addressSize",
547 atCPL0=False, prefetch=False, nonSpec=nonSpec):
548 super(LoadOp, self).__init__(data, segment, addr,
549 disp, dataSize, addressSize, mem_flags,
550 atCPL0, prefetch, nonSpec)
551 self.className = Name
552 self.mnemonic = name
553
554 microopClasses[name] = LoadOp
555
556 code = '''
557 switch (dataSize) {
558 case 4:
559 DataLow = bits(Mem_u2qw[0], 31, 0);
560 DataHi = bits(Mem_u2qw[0], 63, 32);
561 break;
562 case 8:
563 DataLow = Mem_u2qw[0];
564 DataHi = Mem_u2qw[1];
565 break;
566 default:
567 panic("Unhandled data size %d in LdSplit.\\n", dataSize);
568 }'''
569
570 defineMicroLoadSplitOp('LdSplit', code,
571 '(StoreCheck << FlagShift)')
572
573 defineMicroLoadSplitOp('LdSplitl', code,
574 '(StoreCheck << FlagShift) | Request::LOCKED_RMW',
575 nonSpec=True)
576
449 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
450 global header_output
451 global decoder_output
452 global exec_output
453 global microopClasses
454 Name = mnemonic
455 name = mnemonic.lower()
456
457 # Build up the all register version of this micro op
458 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
577 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
578 global header_output
579 global decoder_output
580 global exec_output
581 global microopClasses
582 Name = mnemonic
583 name = mnemonic.lower()
584
585 # Build up the all register version of this micro op
586 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
459 {"code": code,
460 "complete_code": completeCode,
461 "ea_code": calculateEA})
587 { "code": code,
588 "complete_code": completeCode,
589 "ea_code": calculateEA,
590 "memDataSize": "dataSize" })
462 header_output += MicroLdStOpDeclare.subst(iop)
463 decoder_output += MicroLdStOpConstructor.subst(iop)
464 exec_output += MicroStoreExecute.subst(iop)
465 exec_output += MicroStoreInitiateAcc.subst(iop)
466 exec_output += MicroStoreCompleteAcc.subst(iop)
467
468 class StoreOp(LdStOp):
469 def __init__(self, data, segment, addr, disp = 0,
470 dataSize="env.dataSize",
471 addressSize="env.addressSize",
472 atCPL0=False, nonSpec=False):
473 super(StoreOp, self).__init__(data, segment, addr, disp,
474 dataSize, addressSize, mem_flags, atCPL0, False,
475 nonSpec)
476 self.className = Name
477 self.mnemonic = name
478
479 microopClasses[name] = StoreOp
480
481 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
482 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
483 mem_flags="Request::LOCKED_RMW")
484
485 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
486
487 defineMicroStoreOp('Stfp87', code='''
488 switch (dataSize)
489 {
490 case 4: {
491 float single(FpData_df);
492 Mem = *(uint32_t *)&single;
493 } break;
494 case 8:
495 Mem = *(uint64_t *)&FpData_df;
496 break;
497 default:
498 panic("Unhandled data size in StFp87.\\n");
499 }
500 ''')
501
502 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
503
591 header_output += MicroLdStOpDeclare.subst(iop)
592 decoder_output += MicroLdStOpConstructor.subst(iop)
593 exec_output += MicroStoreExecute.subst(iop)
594 exec_output += MicroStoreInitiateAcc.subst(iop)
595 exec_output += MicroStoreCompleteAcc.subst(iop)
596
597 class StoreOp(LdStOp):
598 def __init__(self, data, segment, addr, disp = 0,
599 dataSize="env.dataSize",
600 addressSize="env.addressSize",
601 atCPL0=False, nonSpec=False):
602 super(StoreOp, self).__init__(data, segment, addr, disp,
603 dataSize, addressSize, mem_flags, atCPL0, False,
604 nonSpec)
605 self.className = Name
606 self.mnemonic = name
607
608 microopClasses[name] = StoreOp
609
610 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
611 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
612 mem_flags="Request::LOCKED_RMW")
613
614 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
615
616 defineMicroStoreOp('Stfp87', code='''
617 switch (dataSize)
618 {
619 case 4: {
620 float single(FpData_df);
621 Mem = *(uint32_t *)&single;
622 } break;
623 case 8:
624 Mem = *(uint64_t *)&FpData_df;
625 break;
626 default:
627 panic("Unhandled data size in StFp87.\\n");
628 }
629 ''')
630
631 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
632
633 def defineMicroStoreSplitOp(mnemonic, code,
634 completeCode="", mem_flags="0"):
635 global header_output
636 global decoder_output
637 global exec_output
638 global microopClasses
639 Name = mnemonic
640 name = mnemonic.lower()
641
642 iop = InstObjParams(name, Name, 'X86ISA::LdStSplitOp',
643 { "code": code,
644 "complete_code": completeCode,
645 "ea_code": calculateEA,
646 "memDataSize": "2 * dataSize" })
647
648 header_output += MicroLdStSplitOpDeclare.subst(iop)
649 decoder_output += MicroLdStSplitOpConstructor.subst(iop)
650 exec_output += MicroStoreExecute.subst(iop)
651 exec_output += MicroStoreInitiateAcc.subst(iop)
652 exec_output += MicroStoreCompleteAcc.subst(iop)
653
654 class StoreOp(LdStSplitOp):
655 def __init__(self, data, segment, addr, disp = 0,
656 dataSize="env.dataSize",
657 addressSize="env.addressSize",
658 atCPL0=False, nonSpec=False):
659 super(StoreOp, self).__init__(data, segment, addr, disp,
660 dataSize, addressSize, mem_flags, atCPL0, False,
661 nonSpec)
662 self.className = Name
663 self.mnemonic = name
664
665 microopClasses[name] = StoreOp
666
667 code = '''
668 switch (dataSize) {
669 case 4:
670 Mem_u2qw[0] = (DataHi << 32) | DataLow;
671 break;
672 case 8:
673 Mem_u2qw[0] = DataLow;
674 Mem_u2qw[1] = DataHi;
675 break;
676 default:
677 panic("Unhandled data size %d in StSplit.\\n", dataSize);
678 }'''
679
680 defineMicroStoreSplitOp('StSplit', code);
681
682 defineMicroStoreSplitOp('StSplitul', code,
683 mem_flags='Request::LOCKED_RMW')
684
504 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
685 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
505 {"code": "Data = merge(Data, EA, dataSize);",
506 "ea_code": '''
507 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
508 '''})
686 { "code": "Data = merge(Data, EA, dataSize);",
687 "ea_code": "EA = " + segmentEAExpr,
688 "memDataSize": "dataSize" })
509 header_output += MicroLeaDeclare.subst(iop)
510 decoder_output += MicroLdStOpConstructor.subst(iop)
511 exec_output += MicroLeaExecute.subst(iop)
512
513 class LeaOp(LdStOp):
514 def __init__(self, data, segment, addr, disp = 0,
515 dataSize="env.dataSize", addressSize="env.addressSize"):
516 super(LeaOp, self).__init__(data, segment, addr, disp,
517 dataSize, addressSize, "0", False, False, False)
518 self.className = "Lea"
519 self.mnemonic = "lea"
520
521 microopClasses["lea"] = LeaOp
522
523
524 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
689 header_output += MicroLeaDeclare.subst(iop)
690 decoder_output += MicroLdStOpConstructor.subst(iop)
691 exec_output += MicroLeaExecute.subst(iop)
692
693 class LeaOp(LdStOp):
694 def __init__(self, data, segment, addr, disp = 0,
695 dataSize="env.dataSize", addressSize="env.addressSize"):
696 super(LeaOp, self).__init__(data, segment, addr, disp,
697 dataSize, addressSize, "0", False, False, False)
698 self.className = "Lea"
699 self.mnemonic = "lea"
700
701 microopClasses["lea"] = LeaOp
702
703
704 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
525 {"code": "xc->demapPage(EA, 0);",
526 "ea_code": calculateEA})
705 { "code": "xc->demapPage(EA, 0);",
706 "ea_code": calculateEA,
707 "memDataSize": "dataSize" })
527 header_output += MicroLeaDeclare.subst(iop)
528 decoder_output += MicroLdStOpConstructor.subst(iop)
529 exec_output += MicroLeaExecute.subst(iop)
530
531 class TiaOp(LdStOp):
532 def __init__(self, segment, addr, disp = 0,
533 dataSize="env.dataSize",
534 addressSize="env.addressSize"):
535 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
536 addr, disp, dataSize, addressSize, "0", False, False,
537 False)
538 self.className = "Tia"
539 self.mnemonic = "tia"
540
541 microopClasses["tia"] = TiaOp
542
543 class CdaOp(LdStOp):
544 def __init__(self, segment, addr, disp = 0,
545 dataSize="env.dataSize",
546 addressSize="env.addressSize", atCPL0=False):
547 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
548 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
549 atCPL0, False, False)
550 self.className = "Cda"
551 self.mnemonic = "cda"
552
553 microopClasses["cda"] = CdaOp
554}};
555
708 header_output += MicroLeaDeclare.subst(iop)
709 decoder_output += MicroLdStOpConstructor.subst(iop)
710 exec_output += MicroLeaExecute.subst(iop)
711
712 class TiaOp(LdStOp):
713 def __init__(self, segment, addr, disp = 0,
714 dataSize="env.dataSize",
715 addressSize="env.addressSize"):
716 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
717 addr, disp, dataSize, addressSize, "0", False, False,
718 False)
719 self.className = "Tia"
720 self.mnemonic = "tia"
721
722 microopClasses["tia"] = TiaOp
723
724 class CdaOp(LdStOp):
725 def __init__(self, segment, addr, disp = 0,
726 dataSize="env.dataSize",
727 addressSize="env.addressSize", atCPL0=False):
728 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
729 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
730 atCPL0, False, False)
731 self.className = "Cda"
732 self.mnemonic = "cda"
733
734 microopClasses["cda"] = CdaOp
735}};
736