ldstop.isa (4720:15cb65a86e5a) ldstop.isa (4767:5e55d650692e)
1// Copyright (c) 2007 The Hewlett-Packard Development Company
2// All rights reserved.
3//
4// Redistribution and use of this software in source and binary forms,
5// with or without modification, are permitted provided that the
6// following conditions are met:
7//
8// The software must be used only for Non-Commercial Use which means any
9// use which is NOT directed to receiving any direct monetary
10// compensation for, or commercial advantage from such use. Illustrative
11// examples of non-commercial use are academic research, personal study,
12// teaching, education and corporate research & development.
13// Illustrative examples of commercial use are distributing products for
14// commercial advantage and providing services using the software for
15// commercial advantage.
16//
17// If you wish to use this software or functionality therein that may be
18// covered by patents for commercial use, please contact:
19// Director of Intellectual Property Licensing
20// Office of Strategy and Technology
21// Hewlett-Packard Company
22// 1501 Page Mill Road
23// Palo Alto, California 94304
24//
25// Redistributions of source code must retain the above copyright notice,
26// this list of conditions and the following disclaimer. Redistributions
27// in binary form must reproduce the above copyright notice, this list of
28// conditions and the following disclaimer in the documentation and/or
29// other materials provided with the distribution. Neither the name of
30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
31// contributors may be used to endorse or promote products derived from
32// this software without specific prior written permission. No right of
33// sublicense is granted herewith. Derivatives of the software and
34// output created using the software may be prepared, but only for
35// Non-Commercial Uses. Derivatives of the software may be shared with
36// others provided: (i) the others agree to abide by the list of
37// conditions herein which includes the Non-Commercial Use restrictions;
38// and (ii) such Derivatives of the software include the above copyright
39// notice to acknowledge the contribution from this software where
40// applicable, this list of conditions and the disclaimer below.
41//
42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53//
54// Authors: Gabe Black
55
56//////////////////////////////////////////////////////////////////////////
57//
58// LdStOp Microop templates
59//
60//////////////////////////////////////////////////////////////////////////
61
62// LEA template
63
64def template MicroLeaExecute {{
65 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
66 Trace::InstRecord *traceData) const
67 {
68 Fault fault = NoFault;
69 Addr EA;
70
71 %(op_decl)s;
72 %(op_rd)s;
73 %(ea_code)s;
74 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
75
76 %(code)s;
77 if(fault == NoFault)
78 {
79 %(op_wb)s;
80 }
81
82 return fault;
83 }
84}};
85
86def template MicroLeaDeclare {{
87 class %(class_name)s : public %(base_class)s
88 {
89 protected:
90 void buildMe();
91
92 public:
93 %(class_name)s(ExtMachInst _machInst,
94 const char * instMnem,
95 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
96 uint8_t _scale, RegIndex _index, RegIndex _base,
97 uint64_t _disp, uint8_t _segment,
98 RegIndex _data,
99 uint8_t _dataSize, uint8_t _addressSize);
100
101 %(class_name)s(ExtMachInst _machInst,
102 const char * instMnem,
103 uint8_t _scale, RegIndex _index, RegIndex _base,
104 uint64_t _disp, uint8_t _segment,
105 RegIndex _data,
106 uint8_t _dataSize, uint8_t _addressSize);
107
108 %(BasicExecDeclare)s
109 };
110}};
111
112// Load templates
113
114def template MicroLoadExecute {{
115 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
116 Trace::InstRecord *traceData) const
117 {
118 Fault fault = NoFault;
119 Addr EA;
120
121 %(op_decl)s;
122 %(op_rd)s;
123 %(ea_code)s;
124 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
125
1// Copyright (c) 2007 The Hewlett-Packard Development Company
2// All rights reserved.
3//
4// Redistribution and use of this software in source and binary forms,
5// with or without modification, are permitted provided that the
6// following conditions are met:
7//
8// The software must be used only for Non-Commercial Use which means any
9// use which is NOT directed to receiving any direct monetary
10// compensation for, or commercial advantage from such use. Illustrative
11// examples of non-commercial use are academic research, personal study,
12// teaching, education and corporate research & development.
13// Illustrative examples of commercial use are distributing products for
14// commercial advantage and providing services using the software for
15// commercial advantage.
16//
17// If you wish to use this software or functionality therein that may be
18// covered by patents for commercial use, please contact:
19// Director of Intellectual Property Licensing
20// Office of Strategy and Technology
21// Hewlett-Packard Company
22// 1501 Page Mill Road
23// Palo Alto, California 94304
24//
25// Redistributions of source code must retain the above copyright notice,
26// this list of conditions and the following disclaimer. Redistributions
27// in binary form must reproduce the above copyright notice, this list of
28// conditions and the following disclaimer in the documentation and/or
29// other materials provided with the distribution. Neither the name of
30// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
31// contributors may be used to endorse or promote products derived from
32// this software without specific prior written permission. No right of
33// sublicense is granted herewith. Derivatives of the software and
34// output created using the software may be prepared, but only for
35// Non-Commercial Uses. Derivatives of the software may be shared with
36// others provided: (i) the others agree to abide by the list of
37// conditions herein which includes the Non-Commercial Use restrictions;
38// and (ii) such Derivatives of the software include the above copyright
39// notice to acknowledge the contribution from this software where
40// applicable, this list of conditions and the disclaimer below.
41//
42// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53//
54// Authors: Gabe Black
55
56//////////////////////////////////////////////////////////////////////////
57//
58// LdStOp Microop templates
59//
60//////////////////////////////////////////////////////////////////////////
61
62// LEA template
63
64def template MicroLeaExecute {{
65 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
66 Trace::InstRecord *traceData) const
67 {
68 Fault fault = NoFault;
69 Addr EA;
70
71 %(op_decl)s;
72 %(op_rd)s;
73 %(ea_code)s;
74 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
75
76 %(code)s;
77 if(fault == NoFault)
78 {
79 %(op_wb)s;
80 }
81
82 return fault;
83 }
84}};
85
86def template MicroLeaDeclare {{
87 class %(class_name)s : public %(base_class)s
88 {
89 protected:
90 void buildMe();
91
92 public:
93 %(class_name)s(ExtMachInst _machInst,
94 const char * instMnem,
95 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
96 uint8_t _scale, RegIndex _index, RegIndex _base,
97 uint64_t _disp, uint8_t _segment,
98 RegIndex _data,
99 uint8_t _dataSize, uint8_t _addressSize);
100
101 %(class_name)s(ExtMachInst _machInst,
102 const char * instMnem,
103 uint8_t _scale, RegIndex _index, RegIndex _base,
104 uint64_t _disp, uint8_t _segment,
105 RegIndex _data,
106 uint8_t _dataSize, uint8_t _addressSize);
107
108 %(BasicExecDeclare)s
109 };
110}};
111
112// Load templates
113
114def template MicroLoadExecute {{
115 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
116 Trace::InstRecord *traceData) const
117 {
118 Fault fault = NoFault;
119 Addr EA;
120
121 %(op_decl)s;
122 %(op_rd)s;
123 %(ea_code)s;
124 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
125
126 unsigned flags = 0;
127 switch(dataSize)
128 {
129 case 1:
130 fault = xc->read(EA, (uint8_t&)Mem, flags);
131 break;
132 case 2:
133 fault = xc->read(EA, (uint16_t&)Mem, flags);
134 break;
135 case 4:
136 fault = xc->read(EA, (uint32_t&)Mem, flags);
137 break;
138 case 8:
139 fault = xc->read(EA, (uint64_t&)Mem, flags);
140 break;
141 default:
142 panic("Bad operand size!\n");
143 }
126 fault = read(xc, EA, Mem, 0);
127 int offset = EA & (dataSize - 1);
128 Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
144
145 if(fault == NoFault)
146 {
147 %(code)s;
148 }
149 if(fault == NoFault)
150 {
151 %(op_wb)s;
152 }
153
154 return fault;
155 }
156}};
157
158def template MicroLoadInitiateAcc {{
159 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
160 Trace::InstRecord * traceData) const
161 {
162 Fault fault = NoFault;
163 Addr EA;
164
165 %(op_decl)s;
166 %(op_rd)s;
167 %(ea_code)s;
168 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
169
129
130 if(fault == NoFault)
131 {
132 %(code)s;
133 }
134 if(fault == NoFault)
135 {
136 %(op_wb)s;
137 }
138
139 return fault;
140 }
141}};
142
143def template MicroLoadInitiateAcc {{
144 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
145 Trace::InstRecord * traceData) const
146 {
147 Fault fault = NoFault;
148 Addr EA;
149
150 %(op_decl)s;
151 %(op_rd)s;
152 %(ea_code)s;
153 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
154
170 unsigned flags = 0;
171 switch(dataSize)
172 {
173 case 1:
174 fault = xc->read(EA, (uint8_t&)Mem, flags);
175 break;
176 case 2:
177 fault = xc->read(EA, (uint16_t&)Mem, flags);
178 break;
179 case 4:
180 fault = xc->read(EA, (uint32_t&)Mem, flags);
181 break;
182 case 8:
183 fault = xc->read(EA, (uint64_t&)Mem, flags);
184 break;
185 default:
186 panic("Bad operand size!\n");
187 }
155 int offset = EA & (dataSize - 1);
156 fault = read(xc, EA, Mem, offset);
188
189 return fault;
190 }
191}};
192
193def template MicroLoadCompleteAcc {{
194 Fault %(class_name)s::completeAcc(PacketPtr pkt,
195 %(CPU_exec_context)s * xc,
196 Trace::InstRecord * traceData) const
197 {
198 Fault fault = NoFault;
199
200 %(op_decl)s;
201 %(op_rd)s;
202
203 Mem = pkt->get<typeof(Mem)>();
157
158 return fault;
159 }
160}};
161
162def template MicroLoadCompleteAcc {{
163 Fault %(class_name)s::completeAcc(PacketPtr pkt,
164 %(CPU_exec_context)s * xc,
165 Trace::InstRecord * traceData) const
166 {
167 Fault fault = NoFault;
168
169 %(op_decl)s;
170 %(op_rd)s;
171
172 Mem = pkt->get<typeof(Mem)>();
173 int offset = pkt->flags;
174 Mem = bits(Mem, (offset + dataSize) * 8 - 1, offset * 8);
204 %(code)s;
205
206 if(fault == NoFault)
207 {
208 %(op_wb)s;
209 }
210
211 return fault;
212 }
213}};
214
215// Store templates
216
217def template MicroStoreExecute {{
218 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
219 Trace::InstRecord *traceData) const
220 {
221 Fault fault = NoFault;
222
223 Addr EA;
224 %(op_decl)s;
225 %(op_rd)s;
226 %(ea_code)s;
227 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
228
229 %(code)s;
230
231 if(fault == NoFault)
232 {
175 %(code)s;
176
177 if(fault == NoFault)
178 {
179 %(op_wb)s;
180 }
181
182 return fault;
183 }
184}};
185
186// Store templates
187
188def template MicroStoreExecute {{
189 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
190 Trace::InstRecord *traceData) const
191 {
192 Fault fault = NoFault;
193
194 Addr EA;
195 %(op_decl)s;
196 %(op_rd)s;
197 %(ea_code)s;
198 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
199
200 %(code)s;
201
202 if(fault == NoFault)
203 {
233 unsigned flags = 0;
234 uint64_t *res = 0;
235 switch(dataSize)
204 Mem = Mem << ((EA & (dataSize - 1)) * 8);
205 fault = write(xc, Mem, EA, 0);
206 if(fault == NoFault)
236 {
207 {
237 case 1:
238 fault = xc->write((uint8_t&)Mem, EA, flags, res);
239 break;
240 case 2:
241 fault = xc->write((uint16_t&)Mem, EA, flags, res);
242 break;
243 case 4:
244 fault = xc->write((uint32_t&)Mem, EA, flags, res);
245 break;
246 case 8:
247 fault = xc->write((uint64_t&)Mem, EA, flags, res);
248 break;
249 default:
250 panic("Bad operand size!\n");
208 %(op_wb)s;
251 }
252 }
209 }
210 }
253 if(fault == NoFault)
254 {
255 %(op_wb)s;
256 }
257
258 return fault;
259 }
260}};
261
262def template MicroStoreInitiateAcc {{
263 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
264 Trace::InstRecord * traceData) const
265 {
266 Fault fault = NoFault;
267
268 Addr EA;
269 %(op_decl)s;
270 %(op_rd)s;
271 %(ea_code)s;
272 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
273
274 %(code)s;
275
276 if(fault == NoFault)
277 {
211
212 return fault;
213 }
214}};
215
216def template MicroStoreInitiateAcc {{
217 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
218 Trace::InstRecord * traceData) const
219 {
220 Fault fault = NoFault;
221
222 Addr EA;
223 %(op_decl)s;
224 %(op_rd)s;
225 %(ea_code)s;
226 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
227
228 %(code)s;
229
230 if(fault == NoFault)
231 {
278 unsigned flags = 0;
279 uint64_t *res = 0;
280 switch(dataSize)
232 Mem = Mem << ((EA & (dataSize - 1)) * 8);
233 fault = write(xc, Mem, EA, 0);
234 if(fault == NoFault)
281 {
235 {
282 case 1:
283 fault = xc->write((uint8_t&)Mem, EA, flags, res);
284 break;
285 case 2:
286 fault = xc->write((uint16_t&)Mem, EA, flags, res);
287 break;
288 case 4:
289 fault = xc->write((uint32_t&)Mem, EA, flags, res);
290 break;
291 case 8:
292 fault = xc->write((uint64_t&)Mem, EA, flags, res);
293 break;
294 default:
295 panic("Bad operand size!\n");
236 %(op_wb)s;
296 }
297 }
237 }
238 }
298 if(fault == NoFault)
299 {
300 %(op_wb)s;
301 }
302 return fault;
303 }
304}};
305
306def template MicroStoreCompleteAcc {{
307 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
308 Trace::InstRecord * traceData) const
309 {
310 return NoFault;
311 }
312}};
313
314// Common templates
315
316//This delcares the initiateAcc function in memory operations
317def template InitiateAccDeclare {{
318 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
319}};
320
321//This declares the completeAcc function in memory operations
322def template CompleteAccDeclare {{
323 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
324}};
325
326def template MicroLdStOpDeclare {{
327 class %(class_name)s : public %(base_class)s
328 {
329 protected:
330 void buildMe();
331
332 public:
333 %(class_name)s(ExtMachInst _machInst,
334 const char * instMnem,
335 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
336 uint8_t _scale, RegIndex _index, RegIndex _base,
337 uint64_t _disp, uint8_t _segment,
338 RegIndex _data,
339 uint8_t _dataSize, uint8_t _addressSize);
340
341 %(class_name)s(ExtMachInst _machInst,
342 const char * instMnem,
343 uint8_t _scale, RegIndex _index, RegIndex _base,
344 uint64_t _disp, uint8_t _segment,
345 RegIndex _data,
346 uint8_t _dataSize, uint8_t _addressSize);
347
348 %(BasicExecDeclare)s
349
350 %(InitiateAccDeclare)s
351
352 %(CompleteAccDeclare)s
353 };
354}};
355
356def template MicroLdStOpConstructor {{
357
358 inline void %(class_name)s::buildMe()
359 {
360 %(constructor)s;
361 }
362
363 inline %(class_name)s::%(class_name)s(
364 ExtMachInst machInst, const char * instMnem,
365 uint8_t _scale, RegIndex _index, RegIndex _base,
366 uint64_t _disp, uint8_t _segment,
367 RegIndex _data,
368 uint8_t _dataSize, uint8_t _addressSize) :
369 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
370 false, false, false, false,
371 _scale, _index, _base,
372 _disp, _segment, _data,
373 _dataSize, _addressSize, %(op_class)s)
374 {
375 buildMe();
376 }
377
378 inline %(class_name)s::%(class_name)s(
379 ExtMachInst machInst, const char * instMnem,
380 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
381 uint8_t _scale, RegIndex _index, RegIndex _base,
382 uint64_t _disp, uint8_t _segment,
383 RegIndex _data,
384 uint8_t _dataSize, uint8_t _addressSize) :
385 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
386 isMicro, isDelayed, isFirst, isLast,
387 _scale, _index, _base,
388 _disp, _segment, _data,
389 _dataSize, _addressSize, %(op_class)s)
390 {
391 buildMe();
392 }
393}};
394
395let {{
396 class LdStOp(X86Microop):
397 def __init__(self, data, segment, addr, disp, dataSize):
398 self.data = data
399 [self.scale, self.index, self.base] = addr
400 self.disp = disp
401 self.segment = segment
402 self.dataSize = dataSize
403 self.addressSize = "env.addressSize"
404
405 def getAllocator(self, *microFlags):
406 allocator = '''new %(class_name)s(machInst, mnemonic
407 %(flags)s, %(scale)s, %(index)s, %(base)s,
408 %(disp)s, %(segment)s, %(data)s,
409 %(dataSize)s, %(addressSize)s)''' % {
410 "class_name" : self.className,
411 "flags" : self.microFlagsText(microFlags),
412 "scale" : self.scale, "index" : self.index,
413 "base" : self.base,
414 "disp" : self.disp,
415 "segment" : self.segment, "data" : self.data,
416 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
417 return allocator
418}};
419
420let {{
421
422 # Make these empty strings so that concatenating onto
423 # them will always work.
424 header_output = ""
425 decoder_output = ""
426 exec_output = ""
427
428 calculateEA = "EA = scale * Index + Base + disp;"
429
430 def defineMicroLoadOp(mnemonic, code):
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, "ea_code": calculateEA})
441 header_output += MicroLdStOpDeclare.subst(iop)
442 decoder_output += MicroLdStOpConstructor.subst(iop)
443 exec_output += MicroLoadExecute.subst(iop)
444 exec_output += MicroLoadInitiateAcc.subst(iop)
445 exec_output += MicroLoadCompleteAcc.subst(iop)
446
447 class LoadOp(LdStOp):
448 def __init__(self, data, segment, addr,
449 disp = 0, dataSize="env.dataSize"):
450 super(LoadOp, self).__init__(data, segment,
451 addr, disp, dataSize)
452 self.className = Name
453 self.mnemonic = name
454
455 microopClasses[name] = LoadOp
456
457 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
458
459 def defineMicroStoreOp(mnemonic, code):
460 global header_output
461 global decoder_output
462 global exec_output
463 global microopClasses
464 Name = mnemonic
465 name = mnemonic.lower()
466
467 # Build up the all register version of this micro op
468 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
469 {"code": code, "ea_code": calculateEA})
470 header_output += MicroLdStOpDeclare.subst(iop)
471 decoder_output += MicroLdStOpConstructor.subst(iop)
472 exec_output += MicroStoreExecute.subst(iop)
473 exec_output += MicroStoreInitiateAcc.subst(iop)
474 exec_output += MicroStoreCompleteAcc.subst(iop)
475
476 class StoreOp(LdStOp):
477 def __init__(self, data, segment, addr,
478 disp = 0, dataSize="env.dataSize"):
479 super(StoreOp, self).__init__(data, segment,
480 addr, disp, dataSize)
481 self.className = Name
482 self.mnemonic = name
483
484 microopClasses[name] = StoreOp
485
486 defineMicroStoreOp('St', 'Mem = Data;')
487
488 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
489 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
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,
496 disp = 0, dataSize="env.dataSize"):
497 super(LeaOp, self).__init__(data, segment,
498 addr, disp, dataSize)
499 self.className = "Lea"
500 self.mnemonic = "lea"
501
502 microopClasses["lea"] = LeaOp
503}};
504
239 return fault;
240 }
241}};
242
243def template MicroStoreCompleteAcc {{
244 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
245 Trace::InstRecord * traceData) const
246 {
247 return NoFault;
248 }
249}};
250
251// Common templates
252
253//This delcares the initiateAcc function in memory operations
254def template InitiateAccDeclare {{
255 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
256}};
257
258//This declares the completeAcc function in memory operations
259def template CompleteAccDeclare {{
260 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
261}};
262
263def template MicroLdStOpDeclare {{
264 class %(class_name)s : public %(base_class)s
265 {
266 protected:
267 void buildMe();
268
269 public:
270 %(class_name)s(ExtMachInst _machInst,
271 const char * instMnem,
272 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
273 uint8_t _scale, RegIndex _index, RegIndex _base,
274 uint64_t _disp, uint8_t _segment,
275 RegIndex _data,
276 uint8_t _dataSize, uint8_t _addressSize);
277
278 %(class_name)s(ExtMachInst _machInst,
279 const char * instMnem,
280 uint8_t _scale, RegIndex _index, RegIndex _base,
281 uint64_t _disp, uint8_t _segment,
282 RegIndex _data,
283 uint8_t _dataSize, uint8_t _addressSize);
284
285 %(BasicExecDeclare)s
286
287 %(InitiateAccDeclare)s
288
289 %(CompleteAccDeclare)s
290 };
291}};
292
293def template MicroLdStOpConstructor {{
294
295 inline void %(class_name)s::buildMe()
296 {
297 %(constructor)s;
298 }
299
300 inline %(class_name)s::%(class_name)s(
301 ExtMachInst machInst, const char * instMnem,
302 uint8_t _scale, RegIndex _index, RegIndex _base,
303 uint64_t _disp, uint8_t _segment,
304 RegIndex _data,
305 uint8_t _dataSize, uint8_t _addressSize) :
306 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
307 false, false, false, false,
308 _scale, _index, _base,
309 _disp, _segment, _data,
310 _dataSize, _addressSize, %(op_class)s)
311 {
312 buildMe();
313 }
314
315 inline %(class_name)s::%(class_name)s(
316 ExtMachInst machInst, const char * instMnem,
317 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
318 uint8_t _scale, RegIndex _index, RegIndex _base,
319 uint64_t _disp, uint8_t _segment,
320 RegIndex _data,
321 uint8_t _dataSize, uint8_t _addressSize) :
322 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
323 isMicro, isDelayed, isFirst, isLast,
324 _scale, _index, _base,
325 _disp, _segment, _data,
326 _dataSize, _addressSize, %(op_class)s)
327 {
328 buildMe();
329 }
330}};
331
332let {{
333 class LdStOp(X86Microop):
334 def __init__(self, data, segment, addr, disp, dataSize):
335 self.data = data
336 [self.scale, self.index, self.base] = addr
337 self.disp = disp
338 self.segment = segment
339 self.dataSize = dataSize
340 self.addressSize = "env.addressSize"
341
342 def getAllocator(self, *microFlags):
343 allocator = '''new %(class_name)s(machInst, mnemonic
344 %(flags)s, %(scale)s, %(index)s, %(base)s,
345 %(disp)s, %(segment)s, %(data)s,
346 %(dataSize)s, %(addressSize)s)''' % {
347 "class_name" : self.className,
348 "flags" : self.microFlagsText(microFlags),
349 "scale" : self.scale, "index" : self.index,
350 "base" : self.base,
351 "disp" : self.disp,
352 "segment" : self.segment, "data" : self.data,
353 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
354 return allocator
355}};
356
357let {{
358
359 # Make these empty strings so that concatenating onto
360 # them will always work.
361 header_output = ""
362 decoder_output = ""
363 exec_output = ""
364
365 calculateEA = "EA = scale * Index + Base + disp;"
366
367 def defineMicroLoadOp(mnemonic, code):
368 global header_output
369 global decoder_output
370 global exec_output
371 global microopClasses
372 Name = mnemonic
373 name = mnemonic.lower()
374
375 # Build up the all register version of this micro op
376 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
377 {"code": code, "ea_code": calculateEA})
378 header_output += MicroLdStOpDeclare.subst(iop)
379 decoder_output += MicroLdStOpConstructor.subst(iop)
380 exec_output += MicroLoadExecute.subst(iop)
381 exec_output += MicroLoadInitiateAcc.subst(iop)
382 exec_output += MicroLoadCompleteAcc.subst(iop)
383
384 class LoadOp(LdStOp):
385 def __init__(self, data, segment, addr,
386 disp = 0, dataSize="env.dataSize"):
387 super(LoadOp, self).__init__(data, segment,
388 addr, disp, dataSize)
389 self.className = Name
390 self.mnemonic = name
391
392 microopClasses[name] = LoadOp
393
394 defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);')
395
396 def defineMicroStoreOp(mnemonic, code):
397 global header_output
398 global decoder_output
399 global exec_output
400 global microopClasses
401 Name = mnemonic
402 name = mnemonic.lower()
403
404 # Build up the all register version of this micro op
405 iop = InstObjParams(name, Name, 'X86ISA::LdStOp',
406 {"code": code, "ea_code": calculateEA})
407 header_output += MicroLdStOpDeclare.subst(iop)
408 decoder_output += MicroLdStOpConstructor.subst(iop)
409 exec_output += MicroStoreExecute.subst(iop)
410 exec_output += MicroStoreInitiateAcc.subst(iop)
411 exec_output += MicroStoreCompleteAcc.subst(iop)
412
413 class StoreOp(LdStOp):
414 def __init__(self, data, segment, addr,
415 disp = 0, dataSize="env.dataSize"):
416 super(StoreOp, self).__init__(data, segment,
417 addr, disp, dataSize)
418 self.className = Name
419 self.mnemonic = name
420
421 microopClasses[name] = StoreOp
422
423 defineMicroStoreOp('St', 'Mem = Data;')
424
425 iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
426 {"code": "Data = merge(Data, EA, dataSize);", "ea_code": calculateEA})
427 header_output += MicroLeaDeclare.subst(iop)
428 decoder_output += MicroLdStOpConstructor.subst(iop)
429 exec_output += MicroLeaExecute.subst(iop)
430
431 class LeaOp(LdStOp):
432 def __init__(self, data, segment, addr,
433 disp = 0, dataSize="env.dataSize"):
434 super(LeaOp, self).__init__(data, segment,
435 addr, disp, dataSize)
436 self.className = "Lea"
437 self.mnemonic = "lea"
438
439 microopClasses["lea"] = LeaOp
440}};
441