Deleted Added
sdiff udiff text old ( 4587:2c9a2534a489 ) new ( 4601:38c989d15fef )
full compact
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
63// Load templates
64
65output header {{
66 /**
67 * Base class for load and store ops
68 */
69 class LdStOp : public X86MicroopBase
70 {
71 protected:
72 const uint8_t scale;
73 const RegIndex index;
74 const RegIndex base;
75 const uint64_t disp;
76 const uint8_t segment;
77 const RegIndex data;
78 const uint8_t dataSize;
79 const uint8_t addressSize;
80
81 //Constructor
82 LdStOp(ExtMachInst _machInst,
83 const char * mnem, const char * _instMnem,
84 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
85 uint8_t _scale, RegIndex _index, RegIndex _base,
86 uint64_t _disp, uint8_t _segment,
87 RegIndex _data,
88 uint8_t _dataSize, uint8_t _addressSize,
89 OpClass __opClass) :
90 X86MicroopBase(machInst, mnem, _instMnem,
91 isMicro, isDelayed, isFirst, isLast, __opClass),
92 scale(_scale), index(_index), base(_base),
93 disp(_disp), segment(_segment),
94 data(_data),
95 dataSize(_dataSize), addressSize(_addressSize)
96 {}
97
98 std::string generateDisassembly(Addr pc,
99 const SymbolTable *symtab) const;
100 };
101}};
102
103output decoder {{
104 std::string LdStOp::generateDisassembly(Addr pc,
105 const SymbolTable *symtab) const
106 {
107 std::stringstream response;
108
109 printMnemonic(response, instMnem, mnemonic);
110 printReg(response, data);
111 response << ", ";
112 printSegment(response, segment);
113 ccprintf(response, ":[%d*", scale);
114 printReg(response, index);
115 response << " + ";
116 printReg(response, base);
117 ccprintf(response, " + %#x]", disp);
118 return response.str();
119 }
120}};
121
122def template MicroLoadExecute {{
123 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
124 Trace::InstRecord *traceData) const
125 {
126 Fault fault = NoFault;
127 Addr EA;
128
129 %(op_decl)s;
130 %(op_rd)s;
131 %(ea_code)s;
132 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
133
134 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
135 if(fault == NoFault)
136 {
137 %(code)s;
138 }
139 if(fault == NoFault)
140 {
141 %(op_wb)s;
142 }
143
144 return fault;
145 }
146}};
147
148def template MicroLoadInitiateAcc {{
149 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
150 Trace::InstRecord * traceData) const
151 {
152 Fault fault = NoFault;
153 Addr EA;
154
155 %(op_decl)s;
156 %(op_rd)s;
157 %(ea_code)s;
158 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
159
160 fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, 0);
161
162 return fault;
163 }
164}};
165
166def template MicroLoadCompleteAcc {{
167 Fault %(class_name)s::completeAcc(PacketPtr pkt,
168 %(CPU_exec_context)s * xc,
169 Trace::InstRecord * traceData) const
170 {
171 Fault fault = NoFault;
172
173 %(op_decl)s;
174 %(op_rd)s;
175
176 Mem = pkt->get<typeof(Mem)>();
177 %(code)s;
178
179 if(fault == NoFault)
180 {
181 %(op_wb)s;
182 }
183
184 return fault;
185 }
186}};
187
188// Store templates
189
190def template MicroStoreExecute {{
191 Fault %(class_name)s::execute(%(CPU_exec_context)s * xc,
192 Trace::InstRecord *traceData) const
193 {
194 Fault fault = NoFault;
195
196 Addr EA;
197 %(op_decl)s;
198 %(op_rd)s;
199 %(ea_code)s;
200 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
201
202 %(code)s;
203
204 if(fault == NoFault)
205 {
206 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
207 EA, 0, 0);
208 }
209 if(fault == NoFault)
210 {
211 %(op_wb)s;
212 }
213
214 return fault;
215 }
216}};
217
218def template MicroStoreInitiateAcc {{
219 Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
220 Trace::InstRecord * traceData) const
221 {
222 Fault fault = NoFault;
223
224 Addr EA;
225 %(op_decl)s;
226 %(op_rd)s;
227 %(ea_code)s;
228 DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
229
230 %(code)s;
231
232 if(fault == NoFault)
233 {
234 fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
235 EA, 0, 0);
236 }
237 if(fault == NoFault)
238 {
239 %(op_wb)s;
240 }
241 return fault;
242 }
243}};
244
245def template MicroStoreCompleteAcc {{
246 Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
247 Trace::InstRecord * traceData) const
248 {
249 return NoFault;
250 }
251}};
252
253// Common templates
254
255//This delcares the initiateAcc function in memory operations
256def template InitiateAccDeclare {{
257 Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
258}};
259
260//This declares the completeAcc function in memory operations
261def template CompleteAccDeclare {{
262 Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
263}};
264
265def template MicroLdStOpDeclare {{
266 class %(class_name)s : public %(base_class)s
267 {
268 protected:
269 void buildMe();
270
271 public:
272 %(class_name)s(ExtMachInst _machInst,
273 const char * instMnem,
274 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
275 uint8_t _scale, RegIndex _index, RegIndex _base,
276 uint64_t _disp, uint8_t _segment,
277 RegIndex _data,
278 uint8_t _dataSize, uint8_t _addressSize);
279
280 %(class_name)s(ExtMachInst _machInst,
281 const char * instMnem,
282 uint8_t _scale, RegIndex _index, RegIndex _base,
283 uint64_t _disp, uint8_t _segment,
284 RegIndex _data,
285 uint8_t _dataSize, uint8_t _addressSize);
286
287 %(BasicExecDeclare)s
288
289 %(InitiateAccDeclare)s
290
291 %(CompleteAccDeclare)s
292 };
293}};
294
295def template MicroLdStOpConstructor {{
296
297 inline void %(class_name)s::buildMe()
298 {
299 %(constructor)s;
300 }
301
302 inline %(class_name)s::%(class_name)s(
303 ExtMachInst machInst, const char * instMnem,
304 uint8_t _scale, RegIndex _index, RegIndex _base,
305 uint64_t _disp, uint8_t _segment,
306 RegIndex _data,
307 uint8_t _dataSize, uint8_t _addressSize) :
308 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
309 false, false, false, false,
310 _scale, _index, _base,
311 _disp, _segment, _data,
312 _dataSize, _addressSize, %(op_class)s)
313 {
314 buildMe();
315 }
316
317 inline %(class_name)s::%(class_name)s(
318 ExtMachInst machInst, const char * instMnem,
319 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
320 uint8_t _scale, RegIndex _index, RegIndex _base,
321 uint64_t _disp, uint8_t _segment,
322 RegIndex _data,
323 uint8_t _dataSize, uint8_t _addressSize) :
324 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
325 isMicro, isDelayed, isFirst, isLast,
326 _scale, _index, _base,
327 _disp, _segment, _data,
328 _dataSize, _addressSize, %(op_class)s)
329 {
330 buildMe();
331 }
332}};
333
334let {{
335 class LdStOp(X86Microop):
336 def __init__(self, data, segment, addr, disp):
337 self.data = data
338 [self.scale, self.index, self.base] = addr
339 self.disp = disp
340 self.segment = segment
341 self.dataSize = "env.dataSize"
342 self.addressSize = "env.addressSize"
343
344 def getAllocator(self, *microFlags):
345 allocator = '''new %(class_name)s(machInst, mnemonic
346 %(flags)s, %(scale)s, %(index)s, %(base)s,
347 %(disp)s, %(segment)s, %(data)s,
348 %(dataSize)s, %(addressSize)s)''' % {
349 "class_name" : self.className,
350 "flags" : self.microFlagsText(microFlags),
351 "scale" : self.scale, "index" : self.index,
352 "base" : self.base,
353 "disp" : self.disp,
354 "segment" : self.segment, "data" : self.data,
355 "dataSize" : self.dataSize, "addressSize" : self.addressSize}
356 return allocator
357}};
358
359let {{
360
361 # Make these empty strings so that concatenating onto
362 # them will always work.
363 header_output = ""
364 decoder_output = ""
365 exec_output = ""
366
367 calculateEA = "EA = scale * Index + Base + disp;"
368
369 def defineMicroLoadOp(mnemonic, code):
370 global header_output
371 global decoder_output
372 global exec_output
373 global microopClasses
374 Name = mnemonic
375 name = mnemonic.lower()
376
377 # Build up the all register version of this micro op
378 iop = InstObjParams(name, Name, 'LdStOp',
379 {"code": code, "ea_code": calculateEA})
380 header_output += MicroLdStOpDeclare.subst(iop)
381 decoder_output += MicroLdStOpConstructor.subst(iop)
382 exec_output += MicroLoadExecute.subst(iop)
383 exec_output += MicroLoadInitiateAcc.subst(iop)
384 exec_output += MicroLoadCompleteAcc.subst(iop)
385
386 class LoadOp(LdStOp):
387 def __init__(self, data, segment, addr, disp = 0):
388 super(LoadOp, self).__init__(data, segment, addr, disp)
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, '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, addr, segment):
415 super(LoadOp, self).__init__(data, addr, segment)
416 self.className = Name
417 self.mnemonic = name
418
419 microopClasses[name] = StoreOp
420
421 defineMicroLoadOp('St', 'Mem = Data;')
422}};
423