ldstop.isa (10196:be0e1724eb39) ldstop.isa (10760:8f5993cfa916)
1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
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
101 fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, 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
130 fault = readMemTiming(xc, traceData, EA, Mem, dataSize, 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
146 Mem = getMem(pkt, dataSize, 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 {
177 fault = writeMemAtomic(xc, traceData, Mem, dataSize, 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 {
205 fault = writeMemTiming(xc, traceData, Mem, dataSize, 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
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
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
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
363 calculateEA = '''
364 EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
365 '''
366
367 def defineMicroLoadOp(mnemonic, code, bigCode='',
368 mem_flags="0", big=True):
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',
378 {"code": code, "ea_code": calculateEA})]
379 if big:
380 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
381 {"code": bigCode, "ea_code": calculateEA})]
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",
396 atCPL0=False, prefetch=False, nonSpec=False):
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);',
1// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
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
101 fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, 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
130 fault = readMemTiming(xc, traceData, EA, Mem, dataSize, 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
146 Mem = getMem(pkt, dataSize, 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 {
177 fault = writeMemAtomic(xc, traceData, Mem, dataSize, 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 {
205 fault = writeMemTiming(xc, traceData, Mem, dataSize, 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
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
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
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
363 calculateEA = '''
364 EA = SegBase + bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
365 '''
366
367 def defineMicroLoadOp(mnemonic, code, bigCode='',
368 mem_flags="0", big=True):
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',
378 {"code": code, "ea_code": calculateEA})]
379 if big:
380 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
381 {"code": bigCode, "ea_code": calculateEA})]
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",
396 atCPL0=False, prefetch=False, nonSpec=False):
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);',
412 '(StoreCheck << FlagShift) | Request::LOCKED')
412 '(StoreCheck << FlagShift) | Request::LOCKED_RMW')
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 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
431 global header_output
432 global decoder_output
433 global exec_output
434 global microopClasses
435 Name = mnemonic
436 name = mnemonic.lower()
437
438 # Build up the all register version of this micro op
439 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
440 {"code": code,
441 "complete_code": completeCode,
442 "ea_code": calculateEA})
443 header_output += MicroLdStOpDeclare.subst(iop)
444 decoder_output += MicroLdStOpConstructor.subst(iop)
445 exec_output += MicroStoreExecute.subst(iop)
446 exec_output += MicroStoreInitiateAcc.subst(iop)
447 exec_output += MicroStoreCompleteAcc.subst(iop)
448
449 class StoreOp(LdStOp):
450 def __init__(self, data, segment, addr, disp = 0,
451 dataSize="env.dataSize",
452 addressSize="env.addressSize",
453 atCPL0=False, nonSpec=False):
454 super(StoreOp, self).__init__(data, segment, addr, disp,
455 dataSize, addressSize, mem_flags, atCPL0, False,
456 nonSpec)
457 self.className = Name
458 self.mnemonic = name
459
460 microopClasses[name] = StoreOp
461
462 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
463 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
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 def defineMicroStoreOp(mnemonic, code, completeCode="", mem_flags="0"):
431 global header_output
432 global decoder_output
433 global exec_output
434 global microopClasses
435 Name = mnemonic
436 name = mnemonic.lower()
437
438 # Build up the all register version of this micro op
439 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
440 {"code": code,
441 "complete_code": completeCode,
442 "ea_code": calculateEA})
443 header_output += MicroLdStOpDeclare.subst(iop)
444 decoder_output += MicroLdStOpConstructor.subst(iop)
445 exec_output += MicroStoreExecute.subst(iop)
446 exec_output += MicroStoreInitiateAcc.subst(iop)
447 exec_output += MicroStoreCompleteAcc.subst(iop)
448
449 class StoreOp(LdStOp):
450 def __init__(self, data, segment, addr, disp = 0,
451 dataSize="env.dataSize",
452 addressSize="env.addressSize",
453 atCPL0=False, nonSpec=False):
454 super(StoreOp, self).__init__(data, segment, addr, disp,
455 dataSize, addressSize, mem_flags, atCPL0, False,
456 nonSpec)
457 self.className = Name
458 self.mnemonic = name
459
460 microopClasses[name] = StoreOp
461
462 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
463 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
464 mem_flags="Request::LOCKED")
464 mem_flags="Request::LOCKED_RMW")
465
466 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
467
468 defineMicroStoreOp('Stfp87', code='''
469 switch (dataSize)
470 {
471 case 4: {
472 float single(FpData_df);
473 Mem = *(uint32_t *)&single;
474 } break;
475 case 8:
476 Mem = *(uint64_t *)&FpData_df;
477 break;
478 default:
479 panic("Unhandled data size in StFp87.\\n");
480 }
481 ''')
482
483 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
484
485 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
486 {"code": "Data = merge(Data, EA, dataSize);",
487 "ea_code": '''
488 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
489 '''})
490 header_output += MicroLeaDeclare.subst(iop)
491 decoder_output += MicroLdStOpConstructor.subst(iop)
492 exec_output += MicroLeaExecute.subst(iop)
493
494 class LeaOp(LdStOp):
495 def __init__(self, data, segment, addr, disp = 0,
496 dataSize="env.dataSize", addressSize="env.addressSize"):
497 super(LeaOp, self).__init__(data, segment, addr, disp,
498 dataSize, addressSize, "0", False, False, False)
499 self.className = "Lea"
500 self.mnemonic = "lea"
501
502 microopClasses["lea"] = LeaOp
503
504
505 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
506 {"code": "xc->demapPage(EA, 0);",
507 "ea_code": calculateEA})
508 header_output += MicroLeaDeclare.subst(iop)
509 decoder_output += MicroLdStOpConstructor.subst(iop)
510 exec_output += MicroLeaExecute.subst(iop)
511
512 class TiaOp(LdStOp):
513 def __init__(self, segment, addr, disp = 0,
514 dataSize="env.dataSize",
515 addressSize="env.addressSize"):
516 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
517 addr, disp, dataSize, addressSize, "0", False, False,
518 False)
519 self.className = "Tia"
520 self.mnemonic = "tia"
521
522 microopClasses["tia"] = TiaOp
523
524 class CdaOp(LdStOp):
525 def __init__(self, segment, addr, disp = 0,
526 dataSize="env.dataSize",
527 addressSize="env.addressSize", atCPL0=False):
528 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
529 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
530 atCPL0, False, False)
531 self.className = "Cda"
532 self.mnemonic = "cda"
533
534 microopClasses["cda"] = CdaOp
535}};
536
465
466 defineMicroStoreOp('Stfp', code='Mem = FpData_uqw;')
467
468 defineMicroStoreOp('Stfp87', code='''
469 switch (dataSize)
470 {
471 case 4: {
472 float single(FpData_df);
473 Mem = *(uint32_t *)&single;
474 } break;
475 case 8:
476 Mem = *(uint64_t *)&FpData_df;
477 break;
478 default:
479 panic("Unhandled data size in StFp87.\\n");
480 }
481 ''')
482
483 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
484
485 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
486 {"code": "Data = merge(Data, EA, dataSize);",
487 "ea_code": '''
488 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
489 '''})
490 header_output += MicroLeaDeclare.subst(iop)
491 decoder_output += MicroLdStOpConstructor.subst(iop)
492 exec_output += MicroLeaExecute.subst(iop)
493
494 class LeaOp(LdStOp):
495 def __init__(self, data, segment, addr, disp = 0,
496 dataSize="env.dataSize", addressSize="env.addressSize"):
497 super(LeaOp, self).__init__(data, segment, addr, disp,
498 dataSize, addressSize, "0", False, False, False)
499 self.className = "Lea"
500 self.mnemonic = "lea"
501
502 microopClasses["lea"] = LeaOp
503
504
505 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
506 {"code": "xc->demapPage(EA, 0);",
507 "ea_code": calculateEA})
508 header_output += MicroLeaDeclare.subst(iop)
509 decoder_output += MicroLdStOpConstructor.subst(iop)
510 exec_output += MicroLeaExecute.subst(iop)
511
512 class TiaOp(LdStOp):
513 def __init__(self, segment, addr, disp = 0,
514 dataSize="env.dataSize",
515 addressSize="env.addressSize"):
516 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
517 addr, disp, dataSize, addressSize, "0", False, False,
518 False)
519 self.className = "Tia"
520 self.mnemonic = "tia"
521
522 microopClasses["tia"] = TiaOp
523
524 class CdaOp(LdStOp):
525 def __init__(self, segment, addr, disp = 0,
526 dataSize="env.dataSize",
527 addressSize="env.addressSize", atCPL0=False):
528 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
529 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
530 atCPL0, False, False)
531 self.className = "Cda"
532 self.mnemonic = "cda"
533
534 microopClasses["cda"] = CdaOp
535}};
536