Deleted Added
sdiff udiff text old ( 4679:0b39fa8f5eb8 ) new ( 4688:82d7cbf0e66d )
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

--- 53 unchanged lines hidden (view full) ---

62def template MicroRegOpExecute {{
63 Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
64 Trace::InstRecord *traceData) const
65 {
66 Fault fault = NoFault;
67
68 %(op_decl)s;
69 %(op_rd)s;
70
71 if(%(cond_check)s)
72 {
73 %(code)s;
74 %(flag_code)s;
75 }
76
77 //Write the resulting state to the execution context
78 if(fault == NoFault)
79 {
80 %(op_wb)s;
81 }
82 return fault;
83 }
84}};
85
86def template MicroRegOpImmExecute {{
87 Fault %(class_name)sImm::execute(%(CPU_exec_context)s *xc,
88 Trace::InstRecord *traceData) const
89 {
90 Fault fault = NoFault;
91
92 %(op_decl)s;
93 %(op_rd)s;
94
95 if(%(cond_check)s)
96 {
97 %(code)s;
98 %(flag_code)s;
99 }
100
101 //Write the resulting state to the execution context
102 if(fault == NoFault)
103 {
104 %(op_wb)s;
105 }
106 return fault;
107 }
108}};

--- 4 unchanged lines hidden (view full) ---

113 protected:
114 void buildMe();
115
116 public:
117 %(class_name)s(ExtMachInst _machInst,
118 const char * instMnem,
119 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
120 RegIndex _src1, RegIndex _src2, RegIndex _dest,
121 uint8_t _dataSize, uint8_t _ext);
122
123 %(class_name)s(ExtMachInst _machInst,
124 const char * instMnem,
125 RegIndex _src1, RegIndex _src2, RegIndex _dest,
126 uint8_t _dataSize, uint8_t _ext);
127
128 %(BasicExecDeclare)s
129 };
130}};
131
132def template MicroRegOpImmDeclare {{
133
134 class %(class_name)sImm : public %(base_class)s
135 {
136 protected:
137 void buildMe();
138
139 public:
140 %(class_name)sImm(ExtMachInst _machInst,
141 const char * instMnem,
142 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
143 RegIndex _src1, uint8_t _imm8, RegIndex _dest,
144 uint8_t _dataSize, uint8_t _ext);
145
146 %(class_name)sImm(ExtMachInst _machInst,
147 const char * instMnem,
148 RegIndex _src1, uint8_t _imm8, RegIndex _dest,
149 uint8_t _dataSize, uint8_t _ext);
150
151 %(BasicExecDeclare)s
152 };
153}};
154
155def template MicroRegOpConstructor {{
156
157 inline void %(class_name)s::buildMe()
158 {
159 %(constructor)s;
160 }
161
162 inline %(class_name)s::%(class_name)s(
163 ExtMachInst machInst, const char * instMnem,
164 RegIndex _src1, RegIndex _src2, RegIndex _dest,
165 uint8_t _dataSize, uint8_t _ext) :
166 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
167 false, false, false, false,
168 _src1, _src2, _dest, _dataSize, _ext,
169 %(op_class)s)
170 {
171 buildMe();
172 }
173
174 inline %(class_name)s::%(class_name)s(
175 ExtMachInst machInst, const char * instMnem,
176 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
177 RegIndex _src1, RegIndex _src2, RegIndex _dest,
178 uint8_t _dataSize, uint8_t _ext) :
179 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
180 isMicro, isDelayed, isFirst, isLast,
181 _src1, _src2, _dest, _dataSize, _ext,
182 %(op_class)s)
183 {
184 buildMe();
185 }
186}};
187
188def template MicroRegOpImmConstructor {{
189
190 inline void %(class_name)sImm::buildMe()
191 {
192 %(constructor)s;
193 }
194
195 inline %(class_name)sImm::%(class_name)sImm(
196 ExtMachInst machInst, const char * instMnem,
197 RegIndex _src1, uint8_t _imm8, RegIndex _dest,
198 uint8_t _dataSize, uint8_t _ext) :
199 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
200 false, false, false, false,
201 _src1, _imm8, _dest, _dataSize, _ext,
202 %(op_class)s)
203 {
204 buildMe();
205 }
206
207 inline %(class_name)sImm::%(class_name)sImm(
208 ExtMachInst machInst, const char * instMnem,
209 bool isMicro, bool isDelayed, bool isFirst, bool isLast,
210 RegIndex _src1, uint8_t _imm8, RegIndex _dest,
211 uint8_t _dataSize, uint8_t _ext) :
212 %(base_class)s(machInst, "%(mnemonic)s", instMnem,
213 isMicro, isDelayed, isFirst, isLast,
214 _src1, _imm8, _dest, _dataSize, _ext,
215 %(op_class)s)
216 {
217 buildMe();
218 }
219}};
220
221let {{
222 class X86MicroMeta(type):
223 def __new__(mcls, name, bases, dict):
224 abstract = False
225 if "abstract" in dict:
226 abstract = dict['abstract']
227 del dict['abstract']
228
229 cls = type.__new__(mcls, name, bases, dict)
230 if not abstract:
231 allClasses[name] = cls
232 return cls
233
234 class XXX86Microop(object):
235 __metaclass__ = X86MicroMeta
236 abstract = True
237
238 class RegOp(X86Microop):
239 abstract = True
240 def __init__(self, dest, src1, src2, flags):
241 self.dest = dest
242 self.src1 = src1
243 self.src2 = src2
244 self.flags = flags
245 self.dataSize = "env.dataSize"
246 if flags is None:
247 self.ext = 0
248 else:
249 if not isinstance(flags, (list, tuple)):
250 raise Exception, "flags must be a list or tuple of flags"
251 self.ext = " | ".join(flags)
252 self.className += "Flags"
253
254 def getAllocator(self, *microFlags):
255 allocator = '''new %(class_name)s(machInst, mnemonic
256 %(flags)s, %(src1)s, %(src2)s, %(dest)s,
257 %(dataSize)s, %(ext)s)''' % {
258 "class_name" : self.className,
259 "flags" : self.microFlagsText(microFlags),
260 "src1" : self.src1, "src2" : self.src2,
261 "dest" : self.dest,
262 "dataSize" : self.dataSize,
263 "ext" : self.ext}
264 return allocator
265
266 class RegOpImm(X86Microop):
267 abstract = True
268 def __init__(self, dest, src1, imm8, flags):
269 self.dest = dest
270 self.src1 = src1
271 self.imm8 = imm8
272 self.flags = flags
273 self.dataSize = "env.dataSize"
274 if flags is None:
275 self.ext = 0
276 else:
277 if not isinstance(flags, (list, tuple)):
278 raise Exception, "flags must be a list or tuple of flags"
279 self.ext = " | ".join(flags)
280 self.className += "Flags"
281
282 def getAllocator(self, *microFlags):
283 allocator = '''new %(class_name)s(machInst, mnemonic
284 %(flags)s, %(src1)s, %(imm8)s, %(dest)s,
285 %(dataSize)s, %(ext)s)''' % {
286 "class_name" : self.className,
287 "flags" : self.microFlagsText(microFlags),
288 "src1" : self.src1, "imm8" : self.imm8,
289 "dest" : self.dest,
290 "dataSize" : self.dataSize,
291 "ext" : self.ext}
292 return allocator
293}};
294
295let {{
296
297 # Make these empty strings so that concatenating onto
298 # them will always work.
299 header_output = ""
300 decoder_output = ""
301 exec_output = ""
302
303 # A function which builds the C++ classes that implement the microops
304 def setUpMicroRegOp(name, Name, base, code, flagCode, condCheck):
305 global header_output
306 global decoder_output
307 global exec_output
308 global microopClasses
309
310 iop = InstObjParams(name, Name, base,
311 {"code" : code,
312 "flag_code" : flagCode,
313 "cond_check" : condCheck})
314 header_output += MicroRegOpDeclare.subst(iop)
315 decoder_output += MicroRegOpConstructor.subst(iop)
316 exec_output += MicroRegOpExecute.subst(iop)
317
318
319 checkCCFlagBits = "checkCondition(ccFlagBits)"
320 genCCFlagBits = "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, SrcReg1, %s);"
321
322
323 # This creates a python representations of a microop which are a cross
324 # product of reg/immediate and flag/no flag versions.
325 def defineMicroRegOp(mnemonic, code, secondSrc = "op2", cc=False):
326 Name = mnemonic
327 name = mnemonic.lower()
328
329 # Find op2 in each of the instruction definitions. Create two versions
330 # of the code, one with an integer operand, and one with an immediate
331 # operand.
332 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
333 regCode = matcher.sub("SrcReg2", code)
334 immCode = matcher.sub("imm8", code)
335
336 if not cc:
337 flagCode = genCCFlagBits % secondSrc
338 condCode = "true"
339 else:
340 flagCode = ""
341 condCode = checkCCFlagBits
342
343 regFlagCode = matcher.sub("SrcReg2", flagCode)
344 immFlagCode = matcher.sub("imm8", flagCode)
345
346 class RegOpChild(RegOp):
347 mnemonic = name
348 className = Name
349 def __init__(self, dest, src1, src2, flags=None):
350 super(RegOpChild, self).__init__(dest, src1, src2, flags)
351
352 microopClasses[name] = RegOpChild
353
354 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true");
355 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, regFlagCode, condCode);
356
357 class RegOpChildImm(RegOpImm):
358 mnemonic = name + 'i'
359 className = Name + 'Imm'
360 def __init__(self, dest, src1, src2, flags=None):
361 super(RegOpChildImm, self).__init__(dest, src1, src2, flags)
362
363 microopClasses[name + 'i'] = RegOpChildImm
364
365 setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true");
366 setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm", immCode, immFlagCode, condCode);
367
368 defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
369 defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
370 defineMicroRegOp('Adc', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)')
371 defineMicroRegOp('Sbb', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2')
372 defineMicroRegOp('And', 'DestReg = merge(DestReg, SrcReg1 & op2, dataSize)')
373 defineMicroRegOp('Sub', 'DestReg = merge(DestReg, SrcReg1 - op2, dataSize)', '-op2')
374 defineMicroRegOp('Xor', 'DestReg = merge(DestReg, SrcReg1 ^ op2, dataSize)')
375 defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)', '-op2')
376 defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)', cc=True)
377
378 # This has it's own function because Wr ops have implicit destinations
379 def defineMicroRegOpWr(mnemonic, code):
380 Name = mnemonic
381 name = mnemonic.lower()
382
383 # Find op2 in each of the instruction definitions. Create two versions
384 # of the code, one with an integer operand, and one with an immediate
385 # operand.
386 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
387 regCode = matcher.sub("SrcReg2", code)
388 immCode = matcher.sub("imm8", code)
389
390 class RegOpChild(RegOp):
391 mnemonic = name
392 className = Name
393 def __init__(self, src1, src2, flags=None):
394 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags)
395
396 microopClasses[name] = RegOpChild
397
398 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode, "", "true");
399 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode, "", checkCCFlagBits);
400
401 class RegOpChildImm(RegOpImm):
402 mnemonic = name
403 className = Name
404 def __init__(self, src1, src2):
405 super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, None)
406
407 microopClasses[name + 'i'] = RegOpChildImm
408
409 setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", immCode, "", "true");
410 setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", immCode, "", checkCCFlagBits);
411
412 defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
413
414 # This has it's own function because Rd ops don't always have two parameters
415 def defineMicroRegOpRd(mnemonic, code):
416 Name = mnemonic
417 name = mnemonic.lower()
418
419 class RegOpChild(RegOp):
420 def __init__(self, dest, src1 = "NUM_INTREGS"):
421 super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None)
422 self.className = Name
423 self.mnemonic = name
424
425 microopClasses[name] = RegOpChild
426
427 setUpMicroRegOp(name, Name, "X86ISA::RegOp", code, "", "true");
428
429 defineMicroRegOpRd('Rdip', 'DestReg = RIP')
430
431 def defineMicroRegOpImm(mnemonic, code):
432 Name = mnemonic
433 name = mnemonic.lower()
434
435 class RegOpChild(RegOpImm):
436 def __init__(self, dest, src1, src2):
437 super(RegOpChild, self).__init__(dest, src1, src2, None)
438 self.className = Name
439 self.mnemonic = name
440
441 microopClasses[name] = RegOpChild
442
443 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, "", "true");
444
445 defineMicroRegOpImm('Sext', '''
446 IntReg val = SrcReg1;
447 int sign_bit = bits(val, imm8-1, imm8-1);
448 val = sign_bit ? (val | ~mask(imm8)) : val;
449 DestReg = merge(DestReg, val, dataSize);''')
450}};