ldstop.isa (7967:b243dc8cec8b) ldstop.isa (8102:77ee9ad2e113)
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)s *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)s *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 = read(xc, EA, Mem, 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)s * 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 = read(xc, EA, Mem, memFlags);
131
132 return fault;
133 }
134}};
135
136def template MicroLoadCompleteAcc {{
137 Fault %(class_name)s::completeAcc(PacketPtr pkt,
138 %(CPU_exec_context)s * xc,
139 Trace::InstRecord * traceData) const
140 {
141 Fault fault = NoFault;
142
143 %(op_decl)s;
144 %(op_rd)s;
145
146 Mem = get(pkt);
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)s * 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 = write(xc, Mem, EA, memFlags);
178 if(fault == NoFault)
179 {
180 %(post_code)s;
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)s * 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 write(xc, Mem, EA, memFlags);
206 }
207 return fault;
208 }
209}};
210
211def template MicroStoreCompleteAcc {{
212 Fault %(class_name)s::completeAcc(PacketPtr pkt,
213 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
214 {
215 %(op_decl)s;
216 %(op_rd)s;
217 %(complete_code)s;
218 %(op_wb)s;
219 return NoFault;
220 }
221}};
222
223// Common templates
224
225//This delcares the initiateAcc function in memory operations
226def template InitiateAccDeclare {{
227 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
228}};
229
230//This declares the completeAcc function in memory operations
231def template CompleteAccDeclare {{
232 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
233}};
234
235def template MicroLdStOpDeclare {{
236 class %(class_name)s : public %(base_class)s
237 {
238 public:
239 %(class_name)s(ExtMachInst _machInst,
240 const char * instMnem, uint64_t setFlags,
241 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
242 uint64_t _disp, InstRegIndex _segment,
243 InstRegIndex _data,
244 uint8_t _dataSize, uint8_t _addressSize,
245 Request::FlagsType _memFlags);
246
247 %(BasicExecDeclare)s
248
249 %(InitiateAccDeclare)s
250
251 %(CompleteAccDeclare)s
252 };
253}};
254
255def template MicroLdStOpConstructor {{
256 inline %(class_name)s::%(class_name)s(
257 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
258 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
259 uint64_t _disp, InstRegIndex _segment,
260 InstRegIndex _data,
261 uint8_t _dataSize, uint8_t _addressSize,
262 Request::FlagsType _memFlags) :
263 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
264 _scale, _index, _base,
265 _disp, _segment, _data,
266 _dataSize, _addressSize, _memFlags, %(op_class)s)
267 {
268 %(constructor)s;
269 }
270}};
271
272let {{
273 class LdStOp(X86Microop):
274 def __init__(self, data, segment, addr, disp,
275 dataSize, addressSize, baseFlags, atCPL0, prefetch):
276 self.data = data
277 [self.scale, self.index, self.base] = addr
278 self.disp = disp
279 self.segment = segment
280 self.dataSize = dataSize
281 self.addressSize = addressSize
282 self.memFlags = baseFlags
283 if atCPL0:
284 self.memFlags += " | (CPL0FlagBit << FlagShift)"
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)s *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)s *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 = read(xc, EA, Mem, 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)s * 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 = read(xc, EA, Mem, memFlags);
131
132 return fault;
133 }
134}};
135
136def template MicroLoadCompleteAcc {{
137 Fault %(class_name)s::completeAcc(PacketPtr pkt,
138 %(CPU_exec_context)s * xc,
139 Trace::InstRecord * traceData) const
140 {
141 Fault fault = NoFault;
142
143 %(op_decl)s;
144 %(op_rd)s;
145
146 Mem = get(pkt);
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)s * 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 = write(xc, Mem, EA, memFlags);
178 if(fault == NoFault)
179 {
180 %(post_code)s;
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)s * 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 write(xc, Mem, EA, memFlags);
206 }
207 return fault;
208 }
209}};
210
211def template MicroStoreCompleteAcc {{
212 Fault %(class_name)s::completeAcc(PacketPtr pkt,
213 %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const
214 {
215 %(op_decl)s;
216 %(op_rd)s;
217 %(complete_code)s;
218 %(op_wb)s;
219 return NoFault;
220 }
221}};
222
223// Common templates
224
225//This delcares the initiateAcc function in memory operations
226def template InitiateAccDeclare {{
227 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
228}};
229
230//This declares the completeAcc function in memory operations
231def template CompleteAccDeclare {{
232 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
233}};
234
235def template MicroLdStOpDeclare {{
236 class %(class_name)s : public %(base_class)s
237 {
238 public:
239 %(class_name)s(ExtMachInst _machInst,
240 const char * instMnem, uint64_t setFlags,
241 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
242 uint64_t _disp, InstRegIndex _segment,
243 InstRegIndex _data,
244 uint8_t _dataSize, uint8_t _addressSize,
245 Request::FlagsType _memFlags);
246
247 %(BasicExecDeclare)s
248
249 %(InitiateAccDeclare)s
250
251 %(CompleteAccDeclare)s
252 };
253}};
254
255def template MicroLdStOpConstructor {{
256 inline %(class_name)s::%(class_name)s(
257 ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
258 uint8_t _scale, InstRegIndex _index, InstRegIndex _base,
259 uint64_t _disp, InstRegIndex _segment,
260 InstRegIndex _data,
261 uint8_t _dataSize, uint8_t _addressSize,
262 Request::FlagsType _memFlags) :
263 %(base_class)s(machInst, "%(mnemonic)s", instMnem, setFlags,
264 _scale, _index, _base,
265 _disp, _segment, _data,
266 _dataSize, _addressSize, _memFlags, %(op_class)s)
267 {
268 %(constructor)s;
269 }
270}};
271
272let {{
273 class LdStOp(X86Microop):
274 def __init__(self, data, segment, addr, disp,
275 dataSize, addressSize, baseFlags, atCPL0, prefetch):
276 self.data = data
277 [self.scale, self.index, self.base] = addr
278 self.disp = disp
279 self.segment = segment
280 self.dataSize = dataSize
281 self.addressSize = addressSize
282 self.memFlags = baseFlags
283 if atCPL0:
284 self.memFlags += " | (CPL0FlagBit << FlagShift)"
285 self.instFlags = ""
285 if prefetch:
286 self.memFlags += " | Request::PREFETCH"
286 if prefetch:
287 self.memFlags += " | Request::PREFETCH"
288 self.instFlags += " | StaticInst::IsDataPrefetch"
287 self.memFlags += " | (machInst.legacy.addr ? " + \
288 "(AddrSizeFlagBit << FlagShift) : 0)"
289
290 def getAllocator(self, microFlags):
291 allocator = '''new %(class_name)s(machInst, macrocodeBlock,
292 %(flags)s, %(scale)s, %(index)s, %(base)s,
293 %(disp)s, %(segment)s, %(data)s,
294 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
295 "class_name" : self.className,
289 self.memFlags += " | (machInst.legacy.addr ? " + \
290 "(AddrSizeFlagBit << FlagShift) : 0)"
291
292 def getAllocator(self, microFlags):
293 allocator = '''new %(class_name)s(machInst, macrocodeBlock,
294 %(flags)s, %(scale)s, %(index)s, %(base)s,
295 %(disp)s, %(segment)s, %(data)s,
296 %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % {
297 "class_name" : self.className,
296 "flags" : self.microFlagsText(microFlags),
298 "flags" : self.microFlagsText(microFlags) + self.instFlags,
297 "scale" : self.scale, "index" : self.index,
298 "base" : self.base,
299 "disp" : self.disp,
300 "segment" : self.segment, "data" : self.data,
301 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
302 "memFlags" : self.memFlags}
303 return allocator
304
305 class BigLdStOp(X86Microop):
306 def __init__(self, data, segment, addr, disp,
307 dataSize, addressSize, baseFlags, atCPL0, prefetch):
308 self.data = data
309 [self.scale, self.index, self.base] = addr
310 self.disp = disp
311 self.segment = segment
312 self.dataSize = dataSize
313 self.addressSize = addressSize
314 self.memFlags = baseFlags
315 if atCPL0:
316 self.memFlags += " | (CPL0FlagBit << FlagShift)"
317 if prefetch:
318 self.memFlags += " | Request::PREFETCH"
319 self.memFlags += " | (machInst.legacy.addr ? " + \
320 "(AddrSizeFlagBit << FlagShift) : 0)"
321
322 def getAllocator(self, microFlags):
323 allocString = '''
324 (%(dataSize)s >= 4) ?
325 (StaticInstPtr)(new %(class_name)sBig(machInst,
326 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
327 %(base)s, %(disp)s, %(segment)s, %(data)s,
328 %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
329 (StaticInstPtr)(new %(class_name)s(machInst,
330 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
331 %(base)s, %(disp)s, %(segment)s, %(data)s,
332 %(dataSize)s, %(addressSize)s, %(memFlags)s))
333 '''
334 allocator = allocString % {
335 "class_name" : self.className,
336 "flags" : self.microFlagsText(microFlags),
337 "scale" : self.scale, "index" : self.index,
338 "base" : self.base,
339 "disp" : self.disp,
340 "segment" : self.segment, "data" : self.data,
341 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
342 "memFlags" : self.memFlags}
343 return allocator
344}};
345
346let {{
347
348 # Make these empty strings so that concatenating onto
349 # them will always work.
350 header_output = ""
351 decoder_output = ""
352 exec_output = ""
353
354 calculateEA = '''
355 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
356 '''
357
358 def defineMicroLoadOp(mnemonic, code, bigCode='',
359 mem_flags="0", big=True):
360 global header_output
361 global decoder_output
362 global exec_output
363 global microopClasses
364 Name = mnemonic
365 name = mnemonic.lower()
366
367 # Build up the all register version of this micro op
368 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
369 {"code": code, "ea_code": calculateEA})]
370 if big:
371 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
372 {"code": bigCode, "ea_code": calculateEA})]
373 for iop in iops:
374 header_output += MicroLdStOpDeclare.subst(iop)
375 decoder_output += MicroLdStOpConstructor.subst(iop)
376 exec_output += MicroLoadExecute.subst(iop)
377 exec_output += MicroLoadInitiateAcc.subst(iop)
378 exec_output += MicroLoadCompleteAcc.subst(iop)
379
380 base = LdStOp
381 if big:
382 base = BigLdStOp
383 class LoadOp(base):
384 def __init__(self, data, segment, addr, disp = 0,
385 dataSize="env.dataSize",
386 addressSize="env.addressSize",
387 atCPL0=False, prefetch=False):
388 super(LoadOp, self).__init__(data, segment, addr,
389 disp, dataSize, addressSize, mem_flags,
390 atCPL0, prefetch)
391 self.className = Name
392 self.mnemonic = name
393
394 microopClasses[name] = LoadOp
395
396 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
397 'Data = Mem & mask(dataSize * 8);')
398 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
399 'Data = Mem & mask(dataSize * 8);',
400 '(StoreCheck << FlagShift)')
401 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
402 'Data = Mem & mask(dataSize * 8);',
403 '(StoreCheck << FlagShift) | Request::LOCKED')
404 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;', big = False)
405
406 def defineMicroStoreOp(mnemonic, code, \
407 postCode="", completeCode="", mem_flags="0"):
408 global header_output
409 global decoder_output
410 global exec_output
411 global microopClasses
412 Name = mnemonic
413 name = mnemonic.lower()
414
415 # Build up the all register version of this micro op
416 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
417 {"code": code,
418 "post_code": postCode,
419 "complete_code": completeCode,
420 "ea_code": calculateEA})
421 header_output += MicroLdStOpDeclare.subst(iop)
422 decoder_output += MicroLdStOpConstructor.subst(iop)
423 exec_output += MicroStoreExecute.subst(iop)
424 exec_output += MicroStoreInitiateAcc.subst(iop)
425 exec_output += MicroStoreCompleteAcc.subst(iop)
426
427 class StoreOp(LdStOp):
428 def __init__(self, data, segment, addr, disp = 0,
429 dataSize="env.dataSize",
430 addressSize="env.addressSize",
431 atCPL0=False):
432 super(StoreOp, self).__init__(data, segment, addr,
433 disp, dataSize, addressSize, mem_flags, atCPL0, False)
434 self.className = Name
435 self.mnemonic = name
436
437 microopClasses[name] = StoreOp
438
439 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
440 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
441 mem_flags="Request::LOCKED")
442 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;')
443 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
444
445 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
446 {"code": "Data = merge(Data, EA, dataSize);",
447 "ea_code": '''
448 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
449 '''})
450 header_output += MicroLeaDeclare.subst(iop)
451 decoder_output += MicroLdStOpConstructor.subst(iop)
452 exec_output += MicroLeaExecute.subst(iop)
453
454 class LeaOp(LdStOp):
455 def __init__(self, data, segment, addr, disp = 0,
456 dataSize="env.dataSize", addressSize="env.addressSize"):
457 super(LeaOp, self).__init__(data, segment,
458 addr, disp, dataSize, addressSize, "0", False, False)
459 self.className = "Lea"
460 self.mnemonic = "lea"
461
462 microopClasses["lea"] = LeaOp
463
464
465 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
466 {"code": "xc->demapPage(EA, 0);",
467 "ea_code": calculateEA})
468 header_output += MicroLeaDeclare.subst(iop)
469 decoder_output += MicroLdStOpConstructor.subst(iop)
470 exec_output += MicroLeaExecute.subst(iop)
471
472 class TiaOp(LdStOp):
473 def __init__(self, segment, addr, disp = 0,
474 dataSize="env.dataSize",
475 addressSize="env.addressSize"):
476 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
477 addr, disp, dataSize, addressSize, "0", False, False)
478 self.className = "Tia"
479 self.mnemonic = "tia"
480
481 microopClasses["tia"] = TiaOp
482
483 class CdaOp(LdStOp):
484 def __init__(self, segment, addr, disp = 0,
485 dataSize="env.dataSize",
486 addressSize="env.addressSize", atCPL0=False):
487 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
488 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
489 atCPL0, False)
490 self.className = "Cda"
491 self.mnemonic = "cda"
492
493 microopClasses["cda"] = CdaOp
494}};
495
299 "scale" : self.scale, "index" : self.index,
300 "base" : self.base,
301 "disp" : self.disp,
302 "segment" : self.segment, "data" : self.data,
303 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
304 "memFlags" : self.memFlags}
305 return allocator
306
307 class BigLdStOp(X86Microop):
308 def __init__(self, data, segment, addr, disp,
309 dataSize, addressSize, baseFlags, atCPL0, prefetch):
310 self.data = data
311 [self.scale, self.index, self.base] = addr
312 self.disp = disp
313 self.segment = segment
314 self.dataSize = dataSize
315 self.addressSize = addressSize
316 self.memFlags = baseFlags
317 if atCPL0:
318 self.memFlags += " | (CPL0FlagBit << FlagShift)"
319 if prefetch:
320 self.memFlags += " | Request::PREFETCH"
321 self.memFlags += " | (machInst.legacy.addr ? " + \
322 "(AddrSizeFlagBit << FlagShift) : 0)"
323
324 def getAllocator(self, microFlags):
325 allocString = '''
326 (%(dataSize)s >= 4) ?
327 (StaticInstPtr)(new %(class_name)sBig(machInst,
328 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
329 %(base)s, %(disp)s, %(segment)s, %(data)s,
330 %(dataSize)s, %(addressSize)s, %(memFlags)s)) :
331 (StaticInstPtr)(new %(class_name)s(machInst,
332 macrocodeBlock, %(flags)s, %(scale)s, %(index)s,
333 %(base)s, %(disp)s, %(segment)s, %(data)s,
334 %(dataSize)s, %(addressSize)s, %(memFlags)s))
335 '''
336 allocator = allocString % {
337 "class_name" : self.className,
338 "flags" : self.microFlagsText(microFlags),
339 "scale" : self.scale, "index" : self.index,
340 "base" : self.base,
341 "disp" : self.disp,
342 "segment" : self.segment, "data" : self.data,
343 "dataSize" : self.dataSize, "addressSize" : self.addressSize,
344 "memFlags" : self.memFlags}
345 return allocator
346}};
347
348let {{
349
350 # Make these empty strings so that concatenating onto
351 # them will always work.
352 header_output = ""
353 decoder_output = ""
354 exec_output = ""
355
356 calculateEA = '''
357 EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0);
358 '''
359
360 def defineMicroLoadOp(mnemonic, code, bigCode='',
361 mem_flags="0", big=True):
362 global header_output
363 global decoder_output
364 global exec_output
365 global microopClasses
366 Name = mnemonic
367 name = mnemonic.lower()
368
369 # Build up the all register version of this micro op
370 iops = [InstObjParams(name, Name, 'X86ISA::LdStOp',
371 {"code": code, "ea_code": calculateEA})]
372 if big:
373 iops += [InstObjParams(name, Name + "Big", 'X86ISA::LdStOp',
374 {"code": bigCode, "ea_code": calculateEA})]
375 for iop in iops:
376 header_output += MicroLdStOpDeclare.subst(iop)
377 decoder_output += MicroLdStOpConstructor.subst(iop)
378 exec_output += MicroLoadExecute.subst(iop)
379 exec_output += MicroLoadInitiateAcc.subst(iop)
380 exec_output += MicroLoadCompleteAcc.subst(iop)
381
382 base = LdStOp
383 if big:
384 base = BigLdStOp
385 class LoadOp(base):
386 def __init__(self, data, segment, addr, disp = 0,
387 dataSize="env.dataSize",
388 addressSize="env.addressSize",
389 atCPL0=False, prefetch=False):
390 super(LoadOp, self).__init__(data, segment, addr,
391 disp, dataSize, addressSize, mem_flags,
392 atCPL0, prefetch)
393 self.className = Name
394 self.mnemonic = name
395
396 microopClasses[name] = LoadOp
397
398 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);',
399 'Data = Mem & mask(dataSize * 8);')
400 defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);',
401 'Data = Mem & mask(dataSize * 8);',
402 '(StoreCheck << FlagShift)')
403 defineMicroLoadOp('Ldstl', 'Data = merge(Data, Mem, dataSize);',
404 'Data = Mem & mask(dataSize * 8);',
405 '(StoreCheck << FlagShift) | Request::LOCKED')
406 defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;', big = False)
407
408 def defineMicroStoreOp(mnemonic, code, \
409 postCode="", completeCode="", mem_flags="0"):
410 global header_output
411 global decoder_output
412 global exec_output
413 global microopClasses
414 Name = mnemonic
415 name = mnemonic.lower()
416
417 # Build up the all register version of this micro op
418 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
419 {"code": code,
420 "post_code": postCode,
421 "complete_code": completeCode,
422 "ea_code": calculateEA})
423 header_output += MicroLdStOpDeclare.subst(iop)
424 decoder_output += MicroLdStOpConstructor.subst(iop)
425 exec_output += MicroStoreExecute.subst(iop)
426 exec_output += MicroStoreInitiateAcc.subst(iop)
427 exec_output += MicroStoreCompleteAcc.subst(iop)
428
429 class StoreOp(LdStOp):
430 def __init__(self, data, segment, addr, disp = 0,
431 dataSize="env.dataSize",
432 addressSize="env.addressSize",
433 atCPL0=False):
434 super(StoreOp, self).__init__(data, segment, addr,
435 disp, dataSize, addressSize, mem_flags, atCPL0, False)
436 self.className = Name
437 self.mnemonic = name
438
439 microopClasses[name] = StoreOp
440
441 defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);')
442 defineMicroStoreOp('Stul', 'Mem = pick(Data, 2, dataSize);',
443 mem_flags="Request::LOCKED")
444 defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;')
445 defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS")
446
447 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
448 {"code": "Data = merge(Data, EA, dataSize);",
449 "ea_code": '''
450 EA = bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);
451 '''})
452 header_output += MicroLeaDeclare.subst(iop)
453 decoder_output += MicroLdStOpConstructor.subst(iop)
454 exec_output += MicroLeaExecute.subst(iop)
455
456 class LeaOp(LdStOp):
457 def __init__(self, data, segment, addr, disp = 0,
458 dataSize="env.dataSize", addressSize="env.addressSize"):
459 super(LeaOp, self).__init__(data, segment,
460 addr, disp, dataSize, addressSize, "0", False, False)
461 self.className = "Lea"
462 self.mnemonic = "lea"
463
464 microopClasses["lea"] = LeaOp
465
466
467 iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp',
468 {"code": "xc->demapPage(EA, 0);",
469 "ea_code": calculateEA})
470 header_output += MicroLeaDeclare.subst(iop)
471 decoder_output += MicroLdStOpConstructor.subst(iop)
472 exec_output += MicroLeaExecute.subst(iop)
473
474 class TiaOp(LdStOp):
475 def __init__(self, segment, addr, disp = 0,
476 dataSize="env.dataSize",
477 addressSize="env.addressSize"):
478 super(TiaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
479 addr, disp, dataSize, addressSize, "0", False, False)
480 self.className = "Tia"
481 self.mnemonic = "tia"
482
483 microopClasses["tia"] = TiaOp
484
485 class CdaOp(LdStOp):
486 def __init__(self, segment, addr, disp = 0,
487 dataSize="env.dataSize",
488 addressSize="env.addressSize", atCPL0=False):
489 super(CdaOp, self).__init__("InstRegIndex(NUM_INTREGS)", segment,
490 addr, disp, dataSize, addressSize, "Request::NO_ACCESS",
491 atCPL0, False)
492 self.className = "Cda"
493 self.mnemonic = "cda"
494
495 microopClasses["cda"] = CdaOp
496}};
497