regop.isa (5032:17f771e6b2f2) regop.isa (5040:126e4510b5bb)
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

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

223 _src1, _imm8, _dest, _dataSize, _ext,
224 %(op_class)s)
225 {
226 buildMe();
227 }
228}};
229
230let {{
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

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

223 _src1, _imm8, _dest, _dataSize, _ext,
224 %(op_class)s)
225 {
226 buildMe();
227 }
228}};
229
230let {{
231 class X86MicroMeta(type):
232 def __new__(mcls, name, bases, dict):
231 # Make these empty strings so that concatenating onto
232 # them will always work.
233 header_output = ""
234 decoder_output = ""
235 exec_output = ""
236
237 immTemplates = (
238 MicroRegOpImmDeclare,
239 MicroRegOpImmConstructor,
240 MicroRegOpImmExecute)
241
242 regTemplates = (
243 MicroRegOpDeclare,
244 MicroRegOpConstructor,
245 MicroRegOpExecute)
246
247 class RegOpMeta(type):
248 def buildCppClasses(self, name, Name, suffix, \
249 code, flag_code, cond_check, else_code):
250
251 # Globals to stick the output in
252 global header_output
253 global decoder_output
254 global exec_output
255
256 # Stick all the code together so it can be searched at once
257 allCode = "|".join((code, flag_code, cond_check, else_code))
258
259 # If op2 is used anywhere, make register and immediate versions
260 # of this code.
261 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
262 if matcher.search(allCode):
263 self.buildCppClasses(name, Name, suffix,
264 matcher.sub("psrc2", code),
265 matcher.sub("psrc2", flag_code),
266 matcher.sub("psrc2", cond_check),
267 matcher.sub("psrc2", else_code))
268 self.buildCppClasses(name + "i", Name, suffix + "Imm",
269 matcher.sub("imm8", code),
270 matcher.sub("imm8", flag_code),
271 matcher.sub("imm8", cond_check),
272 matcher.sub("imm8", else_code))
273 return
274
275 # If there's something optional to do with flags, generate
276 # a version without it and fix up this version to use it.
277 if flag_code is not "" or cond_check is not "true":
278 self.buildCppClasses(name, Name, suffix,
279 code, "", "true", else_code)
280 suffix = "Flags" + suffix
281
282 # If psrc1 or psrc2 is used, we need to actually insert code to
283 # compute it.
284 matcher = re.compile("(?<!\w)psrc1(?!\w)")
285 if matcher.search(allCode):
286 code = "IntReg psrc1 = pick(SrcReg1, 0, dataSize);" + code
287 matcher = re.compile("(?<!\w)psrc2(?!\w)")
288 if matcher.search(allCode):
289 code = "IntReg psrc2 = pick(SrcReg2, 1, dataSize);" + code
290
291 base = "X86ISA::RegOp"
292
293 # If imm8 shows up in the code, use the immediate templates, if
294 # not, hopefully the register ones will be correct.
295 templates = regTemplates
296 matcher = re.compile("(?<!\w)imm8(?!\w)")
297 if matcher.search(allCode):
298 base += "Imm"
299 templates = immTemplates
300
301 # Get everything ready for the substitution
302 iop = InstObjParams(name, Name + suffix, base,
303 {"code" : code,
304 "flag_code" : flag_code,
305 "cond_check" : cond_check,
306 "else_code" : else_code})
307
308 # Generate the actual code (finally!)
309 header_output += templates[0].subst(iop)
310 decoder_output += templates[1].subst(iop)
311 exec_output += templates[2].subst(iop)
312
313
314 def __new__(mcls, Name, bases, dict):
233 abstract = False
315 abstract = False
316 name = Name.lower()
234 if "abstract" in dict:
235 abstract = dict['abstract']
236 del dict['abstract']
237
317 if "abstract" in dict:
318 abstract = dict['abstract']
319 del dict['abstract']
320
238 cls = type.__new__(mcls, name, bases, dict)
321 cls = super(RegOpMeta, mcls).__new__(mcls, Name, bases, dict)
239 if not abstract:
322 if not abstract:
240 allClasses[name] = cls
323 cls.className = Name
324 cls.base_mnemonic = name
325 code = cls.code
326 flag_code = cls.flag_code
327 cond_check = cls.cond_check
328 else_code = cls.else_code
329
330 # Set up the C++ classes
331 mcls.buildCppClasses(cls, name, Name, "",
332 code, flag_code, cond_check, else_code)
333
334 # Hook into the microassembler dict
335 global microopClasses
336 microopClasses[name] = cls
337
338 allCode = "|".join((code, flag_code, cond_check, else_code))
339
340 # If op2 is used anywhere, make register and immediate versions
341 # of this code.
342 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
343 if matcher.search(allCode):
344 microopClasses[name + 'i'] = cls
241 return cls
242
345 return cls
346
243 class XXX86Microop(object):
244 __metaclass__ = X86MicroMeta
245 abstract = True
246
247 class RegOp(X86Microop):
347
348 class RegOp(X86Microop):
349 __metaclass__ = RegOpMeta
350 # This class itself doesn't act as a microop
248 abstract = True
351 abstract = True
249 def __init__(self, dest, src1, src2, flags, dataSize):
250 self.dest = dest
251 self.src1 = src1
252 self.src2 = src2
253 self.flags = flags
254 self.dataSize = dataSize
255 if flags is None:
256 self.ext = 0
257 else:
258 if not isinstance(flags, (list, tuple)):
259 raise Exception, "flags must be a list or tuple of flags"
260 self.ext = " | ".join(flags)
261 self.className += "Flags"
262
352
263 def getAllocator(self, *microFlags):
264 allocator = '''new %(class_name)s(machInst, mnemonic
265 %(flags)s, %(src1)s, %(src2)s, %(dest)s,
266 %(dataSize)s, %(ext)s)''' % {
267 "class_name" : self.className,
268 "flags" : self.microFlagsText(microFlags),
269 "src1" : self.src1, "src2" : self.src2,
270 "dest" : self.dest,
271 "dataSize" : self.dataSize,
272 "ext" : self.ext}
273 return allocator
353 # Default template parameter values
354 flag_code = ""
355 cond_check = "true"
356 else_code = ";"
274
357
275 class RegOpImm(X86Microop):
276 abstract = True
277 def __init__(self, dest, src1, imm8, flags, dataSize):
358 def __init__(self, dest, src1, op2, flags = None, dataSize = "env.dataSize"):
278 self.dest = dest
279 self.src1 = src1
359 self.dest = dest
360 self.src1 = src1
280 self.imm8 = imm8
361 self.op2 = op2
281 self.flags = flags
282 self.dataSize = dataSize
283 if flags is None:
284 self.ext = 0
285 else:
286 if not isinstance(flags, (list, tuple)):
287 raise Exception, "flags must be a list or tuple of flags"
288 self.ext = " | ".join(flags)
289 self.className += "Flags"
290
291 def getAllocator(self, *microFlags):
362 self.flags = flags
363 self.dataSize = dataSize
364 if flags is None:
365 self.ext = 0
366 else:
367 if not isinstance(flags, (list, tuple)):
368 raise Exception, "flags must be a list or tuple of flags"
369 self.ext = " | ".join(flags)
370 self.className += "Flags"
371
372 def getAllocator(self, *microFlags):
373 className = self.className
374 if self.mnemonic == self.base_mnemonic + 'i':
375 className += "Imm"
292 allocator = '''new %(class_name)s(machInst, mnemonic
376 allocator = '''new %(class_name)s(machInst, mnemonic
293 %(flags)s, %(src1)s, %(imm8)s, %(dest)s,
377 %(flags)s, %(src1)s, %(op2)s, %(dest)s,
294 %(dataSize)s, %(ext)s)''' % {
378 %(dataSize)s, %(ext)s)''' % {
295 "class_name" : self.className,
379 "class_name" : className,
296 "flags" : self.microFlagsText(microFlags),
380 "flags" : self.microFlagsText(microFlags),
297 "src1" : self.src1, "imm8" : self.imm8,
381 "src1" : self.src1, "op2" : self.op2,
298 "dest" : self.dest,
299 "dataSize" : self.dataSize,
300 "ext" : self.ext}
301 return allocator
382 "dest" : self.dest,
383 "dataSize" : self.dataSize,
384 "ext" : self.ext}
385 return allocator
302}};
303
386
304let {{
387 class LogicRegOp(RegOp):
388 abstract = True
389 flag_code = '''
390 //Don't have genFlags handle the OF or CF bits
391 uint64_t mask = CFBit | OFBit;
392 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2);
393 //If a logic microop wants to set these, it wants to set them to 0.
394 ccFlagBits &= ~(CFBit & ext);
395 ccFlagBits &= ~(OFBit & ext);
396 '''
305
397
306 # Make these empty strings so that concatenating onto
307 # them will always work.
308 header_output = ""
309 decoder_output = ""
310 exec_output = ""
398 class FlagRegOp(RegOp):
399 abstract = True
400 flag_code = \
401 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);"
311
402
312 # A function which builds the C++ classes that implement the microops
313 def setUpMicroRegOp(name, Name, base, code, flagCode = "", condCheck = "true", elseCode = ";", imm=False):
314 global header_output
315 global decoder_output
316 global exec_output
317 global microopClasses
403 class SubRegOp(RegOp):
404 abstract = True
405 flag_code = \
406 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);"
318
407
319 iop = InstObjParams(name, Name, base,
320 {"code" : code,
321 "flag_code" : flagCode,
322 "cond_check" : condCheck,
323 "else_code" : elseCode})
324 if imm:
325 header_output += MicroRegOpImmDeclare.subst(iop)
326 decoder_output += MicroRegOpImmConstructor.subst(iop)
327 exec_output += MicroRegOpImmExecute.subst(iop)
328 else:
329 header_output += MicroRegOpDeclare.subst(iop)
330 decoder_output += MicroRegOpConstructor.subst(iop)
331 exec_output += MicroRegOpExecute.subst(iop)
408 class CondRegOp(RegOp):
409 abstract = True
410 cond_check = "checkCondition(ccFlagBits)"
332
411
412 class Add(FlagRegOp):
413 code = 'DestReg = merge(DestReg, psrc1 + op2, dataSize);'
333
414
334 checkCCFlagBits = "checkCondition(ccFlagBits)"
335 genCCFlagBits = \
336 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, op2);"
337 genCCFlagBitsSub = \
338 "ccFlagBits = genFlags(ccFlagBits, ext, DestReg, psrc1, ~op2, true);"
339 genCCFlagBitsLogic = '''
340 //Don't have genFlags handle the OF or CF bits
341 uint64_t mask = CFBit | OFBit;
342 ccFlagBits = genFlags(ccFlagBits, ext & ~mask, DestReg, psrc1, op2);
343 //If a logic microop wants to set these, it wants to set them to 0.
344 ccFlagBits &= ~(CFBit & ext);
345 ccFlagBits &= ~(OFBit & ext);
346 '''
415 class Or(LogicRegOp):
416 code = 'DestReg = merge(DestReg, psrc1 | op2, dataSize);'
347
417
348 regPick = '''
349 IntReg psrc1 = pick(SrcReg1, 0, dataSize);
350 IntReg psrc2 = pick(SrcReg2, 1, dataSize);
351 '''
352 immPick = '''
353 IntReg psrc1 = pick(SrcReg1, 0, dataSize);
354 '''
418 class Adc(FlagRegOp):
419 code = '''
420 CCFlagBits flags = ccFlagBits;
421 DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize);
422 '''
355
423
424 class Sbb(SubRegOp):
425 code = '''
426 CCFlagBits flags = ccFlagBits;
427 DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize);
428 '''
356
429
357 # This creates a python representations of a microop which are a cross
358 # product of reg/immediate and flag/no flag versions.
359 def defineMicroRegOp(mnemonic, code, flagCode=genCCFlagBits, \
360 cc=False, doImm=True, elseCode=";"):
361 Name = mnemonic
362 name = mnemonic.lower()
430 class And(LogicRegOp):
431 code = 'DestReg = merge(DestReg, psrc1 & op2, dataSize)'
363
432
364 # Find op2 in each of the instruction definitions. Create two versions
365 # of the code, one with an integer operand, and one with an immediate
366 # operand.
367 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
368 regCode = regPick + matcher.sub("psrc2", code)
369 immCode = immPick + matcher.sub("imm8", code)
433 class Sub(SubRegOp):
434 code = 'DestReg = merge(DestReg, psrc1 - op2, dataSize)'
370
435
371 if not cc:
372 condCode = "true"
373 else:
374 flagCode = ""
375 condCode = checkCCFlagBits
436 class Xor(LogicRegOp):
437 code = 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)'
376
438
377 regFlagCode = matcher.sub("psrc2", flagCode)
378 immFlagCode = matcher.sub("imm8", flagCode)
379
380 class RegOpChild(RegOp):
381 mnemonic = name
382 className = Name
383 def __init__(self, dest, src1, src2, \
384 flags=None, dataSize="env.dataSize"):
385 super(RegOpChild, self).__init__(dest, src1, src2, \
386 flags, dataSize)
387
388 microopClasses[name] = RegOpChild
389
390 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
391 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp",
392 regCode, flagCode=regFlagCode,
393 condCheck=condCode, elseCode=elseCode);
394
395 if doImm:
396 class RegOpChildImm(RegOpImm):
397 mnemonic = name + 'i'
398 className = Name + 'Imm'
399 def __init__(self, dest, src1, src2, \
400 flags=None, dataSize="env.dataSize"):
401 super(RegOpChildImm, self).__init__(dest, src1, src2, \
402 flags, dataSize)
403
404 microopClasses[name + 'i'] = RegOpChildImm
405
406 setUpMicroRegOp(name + "i", Name + "Imm", "X86ISA::RegOpImm", \
407 immCode, imm=True);
408 setUpMicroRegOp(name + "i", Name + "ImmFlags", "X86ISA::RegOpImm",
409 immCode, flagCode=immFlagCode,
410 condCheck=condCode, elseCode=elseCode, imm=True);
411
412 # This has it's own function because Wr ops have implicit destinations
413 def defineMicroRegOpWr(mnemonic, code, elseCode=";"):
414 Name = mnemonic
415 name = mnemonic.lower()
416
417 # Find op2 in each of the instruction definitions. Create two versions
418 # of the code, one with an integer operand, and one with an immediate
419 # operand.
420 matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
421 regCode = regPick + matcher.sub("psrc2", code)
422 immCode = immPick + matcher.sub("imm8", code)
423
424 class RegOpChild(RegOp):
425 mnemonic = name
426 className = Name
427 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
428 super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
429
430 microopClasses[name] = RegOpChild
431
432 setUpMicroRegOp(name, Name, "X86ISA::RegOp", regCode);
433 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOp", regCode,
434 condCheck = checkCCFlagBits, elseCode = elseCode);
435
436 class RegOpChildImm(RegOpImm):
437 mnemonic = name + 'i'
438 className = Name + 'Imm'
439 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
440 super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
441
442 microopClasses[name + 'i'] = RegOpChildImm
443
444 setUpMicroRegOp(name + 'i', Name + "Imm", "X86ISA::RegOpImm", \
445 immCode, imm=True);
446 setUpMicroRegOp(name + 'i', Name + "ImmFlags", "X86ISA::RegOpImm", \
447 immCode, condCheck = checkCCFlagBits, elseCode = elseCode, \
448 imm=True);
449
450 # This has it's own function because Rd ops don't always have two parameters
451 def defineMicroRegOpRd(mnemonic, code):
452 Name = mnemonic
453 name = mnemonic.lower()
454
455 class RegOpChild(RegOp):
456 className = Name
457 mnemonic = name
458 def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
459 super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
460
461 microopClasses[name] = RegOpChild
462
463 setUpMicroRegOp(name, Name, "X86ISA::RegOp", code);
464
465 def defineMicroRegOpImm(mnemonic, code, flagCode=""):
466 Name = mnemonic
467 name = mnemonic.lower()
468 code = immPick + code
469
470 class RegOpChild(RegOpImm):
471 className = Name
472 mnemonic = name
473 def __init__(self, dest, src1, src2, \
474 flags=None, dataSize="env.dataSize"):
475 super(RegOpChild, self).__init__(dest, \
476 src1, src2, flags, dataSize)
477
478 microopClasses[name] = RegOpChild
479
480 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True);
481 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \
482 code, flagCode=flagCode, imm=True);
483
484 def defineMicroRegOpRdImm(mnemonic, code, flagCode=""):
485 Name = mnemonic
486 name = mnemonic.lower()
487 code = immPick + code
488
489 class RegOpChildRdImm(RegOpImm):
490 className = Name
491 mnemonic = name
492 def __init__(self, dest, imm, flags=None, \
493 dataSize="env.dataSize"):
494 super(RegOpChildRdImm, self).__init__(dest, \
495 "NUM_INTREGS", imm, flags, dataSize)
496
497 microopClasses[name] = RegOpChildRdImm
498
499 setUpMicroRegOp(name, Name, "X86ISA::RegOpImm", code, imm=True);
500 setUpMicroRegOp(name, Name + "Flags", "X86ISA::RegOpImm", \
501 code, flagCode=flagCode, imm=True);
502
503 defineMicroRegOp('Add', 'DestReg = merge(DestReg, psrc1 + op2, dataSize)')
504 defineMicroRegOp('Or', 'DestReg = merge(DestReg, psrc1 | op2, dataSize);',
505 flagCode = genCCFlagBitsLogic)
506 defineMicroRegOp('Adc', '''
507 CCFlagBits flags = ccFlagBits;
508 DestReg = merge(DestReg, psrc1 + op2 + flags.CF, dataSize);
509 ''')
510 defineMicroRegOp('Sbb', '''
511 CCFlagBits flags = ccFlagBits;
512 DestReg = merge(DestReg, psrc1 - op2 - flags.CF, dataSize);
513 ''', flagCode = genCCFlagBitsSub)
514 defineMicroRegOp('And', \
515 'DestReg = merge(DestReg, psrc1 & op2, dataSize)', \
516 flagCode = genCCFlagBitsLogic)
517 defineMicroRegOp('Sub', \
518 'DestReg = merge(DestReg, psrc1 - op2, dataSize)', \
519 flagCode = genCCFlagBitsSub)
520 defineMicroRegOp('Xor', \
521 'DestReg = merge(DestReg, psrc1 ^ op2, dataSize)', \
522 flagCode = genCCFlagBitsLogic)
523 defineMicroRegOp('Mul1s', '''
439 class Mul1s(FlagRegOp):
440 code = '''
524 int signPos = (dataSize * 8) / 2 - 1;
525 IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos);
526 IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos);
527 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
441 int signPos = (dataSize * 8) / 2 - 1;
442 IntReg srcVal1 = psrc1 | (-bits(psrc1, signPos) << signPos);
443 IntReg srcVal2 = op2 | (-bits(psrc1, signPos) << signPos);
444 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
528 ''')
529 defineMicroRegOp('Mul1u', '''
445 '''
446
447 class Mul1u(FlagRegOp):
448 code = '''
530 int halfSize = (dataSize * 8) / 2;
531 IntReg srcVal1 = psrc1 & mask(halfSize);
532 IntReg srcVal2 = op2 & mask(halfSize);
533 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
449 int halfSize = (dataSize * 8) / 2;
450 IntReg srcVal1 = psrc1 & mask(halfSize);
451 IntReg srcVal2 = op2 & mask(halfSize);
452 DestReg = merge(DestReg, srcVal1 * srcVal2, dataSize)
534 ''')
535 defineMicroRegOp('Mulel', \
536 'DestReg = merge(DestReg, psrc1 * op2, dataSize)')
537 defineMicroRegOp('Muleh', '''
453 '''
454
455 class Mulel(FlagRegOp):
456 code = 'DestReg = merge(DestReg, psrc1 * op2, dataSize)'
457
458 class Muleh(FlagRegOp):
459 code = '''
538 int halfSize = (dataSize * 8) / 2;
539 uint64_t psrc1_h = psrc1 >> halfSize;
540 uint64_t psrc1_l = psrc1 & mask(halfSize);
541 uint64_t psrc2_h = op2 >> halfSize;
542 uint64_t psrc2_l = op2 & mask(halfSize);
543 uint64_t result =
544 ((psrc1_l * psrc2_h) >> halfSize) +
545 ((psrc1_h * psrc2_l) >> halfSize) +
546 psrc1_h * psrc2_h;
547 DestReg = merge(DestReg, result, dataSize);
460 int halfSize = (dataSize * 8) / 2;
461 uint64_t psrc1_h = psrc1 >> halfSize;
462 uint64_t psrc1_l = psrc1 & mask(halfSize);
463 uint64_t psrc2_h = op2 >> halfSize;
464 uint64_t psrc2_l = op2 & mask(halfSize);
465 uint64_t result =
466 ((psrc1_l * psrc2_h) >> halfSize) +
467 ((psrc1_h * psrc2_l) >> halfSize) +
468 psrc1_h * psrc2_h;
469 DestReg = merge(DestReg, result, dataSize);
548 ''')
549 defineMicroRegOp('Div1', '''
470 '''
471
472 class Div1(FlagRegOp):
473 code = '''
550 int halfSize = (dataSize * 8) / 2;
551 IntReg quotient = (psrc1 / op2) & mask(halfSize);
552 IntReg remainder = (psrc1 % op2) & mask(halfSize);
553 IntReg result = quotient | (remainder << halfSize);
554 DestReg = merge(DestReg, result, dataSize);
474 int halfSize = (dataSize * 8) / 2;
475 IntReg quotient = (psrc1 / op2) & mask(halfSize);
476 IntReg remainder = (psrc1 % op2) & mask(halfSize);
477 IntReg result = quotient | (remainder << halfSize);
478 DestReg = merge(DestReg, result, dataSize);
555 ''')
556 defineMicroRegOp('Divq', '''
557 DestReg = merge(DestReg, psrc1 / op2, dataSize);
558 ''')
559 defineMicroRegOp('Divr', '''
560 DestReg = merge(DestReg, psrc1 % op2, dataSize);
561 ''')
479 '''
562
480
563 #
564 # HACK HACK HACK HACK - Put psrc1 in here but make it inert to shut up gcc.
565 #
566 defineMicroRegOp('Mov',
567 'DestReg = merge(SrcReg1, psrc1 * 0 + op2, dataSize)',
568 elseCode='DestReg=DestReg;', cc=True)
481 class Divq(FlagRegOp):
482 code = 'DestReg = merge(DestReg, psrc1 / op2, dataSize);'
569
483
570 defineMicroRegOp('Movfp',
571 'FpDestReg = FpSrcReg2 + psrc1 * 0 + psrc2 * 0',
572 elseCode='FpDestReg=FpDestReg;', cc=True, doImm=False)
484 class Divr(FlagRegOp):
485 code = 'DestReg = merge(DestReg, psrc1 % op2, dataSize);'
573
486
487 class Mov(CondRegOp):
488 code = 'DestReg = merge(SrcReg1, op2, dataSize)'
489 else_code = 'DestReg=DestReg;'
490
491 class Movfp(CondRegOp):
492 code = 'FpDestReg = FpSrcReg2'
493 else_code = 'FpDestReg = FpDestReg;'
494
574 # Shift instructions
495 # Shift instructions
575 defineMicroRegOp('Sll', '''
496
497 class Sll(FlagRegOp):
498 code = '''
576 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
577 DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize);
499 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
500 DestReg = merge(DestReg, psrc1 << shiftAmt, dataSize);
578 ''')
579 defineMicroRegOp('Srl', '''
501 '''
502
503 class Srl(FlagRegOp):
504 code = '''
580 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
581 // Because what happens to the bits shift -in- on a right shift
582 // is not defined in the C/C++ standard, we have to mask them out
583 // to be sure they're zero.
584 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
585 DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize);
505 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
506 // Because what happens to the bits shift -in- on a right shift
507 // is not defined in the C/C++ standard, we have to mask them out
508 // to be sure they're zero.
509 uint64_t logicalMask = mask(dataSize * 8 - shiftAmt);
510 DestReg = merge(DestReg, (psrc1 >> shiftAmt) & logicalMask, dataSize);
586 ''')
587 defineMicroRegOp('Sra', '''
511 '''
512
513 class Sra(FlagRegOp):
514 code = '''
588 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
589 // Because what happens to the bits shift -in- on a right shift
590 // is not defined in the C/C++ standard, we have to sign extend
591 // them manually to be sure.
592 uint64_t arithMask =
593 -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
594 DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize);
515 uint8_t shiftAmt = (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
516 // Because what happens to the bits shift -in- on a right shift
517 // is not defined in the C/C++ standard, we have to sign extend
518 // them manually to be sure.
519 uint64_t arithMask =
520 -bits(psrc1, dataSize * 8 - 1) << (dataSize * 8 - shiftAmt);
521 DestReg = merge(DestReg, (psrc1 >> shiftAmt) | arithMask, dataSize);
595 ''')
596 defineMicroRegOp('Ror', '''
522 '''
523
524 class Ror(FlagRegOp):
525 code = '''
597 uint8_t shiftAmt =
598 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
599 if(shiftAmt)
600 {
601 uint64_t top = psrc1 << (dataSize * 8 - shiftAmt);
602 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
603 DestReg = merge(DestReg, top | bottom, dataSize);
604 }
605 else
606 DestReg = DestReg;
526 uint8_t shiftAmt =
527 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
528 if(shiftAmt)
529 {
530 uint64_t top = psrc1 << (dataSize * 8 - shiftAmt);
531 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
532 DestReg = merge(DestReg, top | bottom, dataSize);
533 }
534 else
535 DestReg = DestReg;
607 ''')
608 defineMicroRegOp('Rcr', '''
536 '''
537
538 class Rcr(FlagRegOp):
539 code = '''
609 uint8_t shiftAmt =
610 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
611 if(shiftAmt)
612 {
613 CCFlagBits flags = ccFlagBits;
614 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
615 if(shiftAmt > 1)
616 top |= psrc1 << (dataSize * 8 - shiftAmt - 1);
617 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
618 DestReg = merge(DestReg, top | bottom, dataSize);
619 }
620 else
621 DestReg = DestReg;
540 uint8_t shiftAmt =
541 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
542 if(shiftAmt)
543 {
544 CCFlagBits flags = ccFlagBits;
545 uint64_t top = flags.CF << (dataSize * 8 - shiftAmt);
546 if(shiftAmt > 1)
547 top |= psrc1 << (dataSize * 8 - shiftAmt - 1);
548 uint64_t bottom = bits(psrc1, dataSize * 8, shiftAmt);
549 DestReg = merge(DestReg, top | bottom, dataSize);
550 }
551 else
552 DestReg = DestReg;
622 ''')
623 defineMicroRegOp('Rol', '''
553 '''
554
555 class Rol(FlagRegOp):
556 code = '''
624 uint8_t shiftAmt =
625 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
626 if(shiftAmt)
627 {
628 uint64_t top = psrc1 << shiftAmt;
629 uint64_t bottom =
630 bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
631 DestReg = merge(DestReg, top | bottom, dataSize);
632 }
633 else
634 DestReg = DestReg;
557 uint8_t shiftAmt =
558 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
559 if(shiftAmt)
560 {
561 uint64_t top = psrc1 << shiftAmt;
562 uint64_t bottom =
563 bits(psrc1, dataSize * 8 - 1, dataSize * 8 - shiftAmt);
564 DestReg = merge(DestReg, top | bottom, dataSize);
565 }
566 else
567 DestReg = DestReg;
635 ''')
636 defineMicroRegOp('Rcl', '''
568 '''
569
570 class Rcl(FlagRegOp):
571 code = '''
637 uint8_t shiftAmt =
638 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
639 if(shiftAmt)
640 {
641 CCFlagBits flags = ccFlagBits;
642 uint64_t top = psrc1 << shiftAmt;
643 uint64_t bottom = flags.CF << (shiftAmt - 1);
644 if(shiftAmt > 1)
645 bottom |=
646 bits(psrc1, dataSize * 8 - 1,
647 dataSize * 8 - shiftAmt + 1);
648 DestReg = merge(DestReg, top | bottom, dataSize);
649 }
650 else
651 DestReg = DestReg;
572 uint8_t shiftAmt =
573 (op2 & ((dataSize == 8) ? mask(6) : mask(5)));
574 if(shiftAmt)
575 {
576 CCFlagBits flags = ccFlagBits;
577 uint64_t top = psrc1 << shiftAmt;
578 uint64_t bottom = flags.CF << (shiftAmt - 1);
579 if(shiftAmt > 1)
580 bottom |=
581 bits(psrc1, dataSize * 8 - 1,
582 dataSize * 8 - shiftAmt + 1);
583 DestReg = merge(DestReg, top | bottom, dataSize);
584 }
585 else
586 DestReg = DestReg;
652 ''')
587 '''
653
588
654 defineMicroRegOpWr('Wrip', 'RIP = psrc1 + op2', elseCode="RIP = RIP;")
655 defineMicroRegOpWr('Br', 'nuIP = psrc1 + op2;', elseCode='nuIP = nuIP;')
656 defineMicroRegOpWr('Wruflags', 'ccFlagBits = psrc1 ^ op2')
589 class WrRegOp(RegOp):
590 abstract = True
591 def __init__(self, src1, src2, flags=None, dataSize="env.dataSize"):
592 super(WrRegOp, self).__init__("NUM_INTREGS", src1, src2, flags, dataSize)
657
593
658 defineMicroRegOpRd('Rdip', 'DestReg = RIP')
659 defineMicroRegOpRd('Ruflags', 'DestReg = ccFlagBits')
660 defineMicroRegOpRdImm('Ruflag', '''
594 class Wrip(WrRegOp, CondRegOp):
595 code = 'RIP = psrc1 + op2'
596 else_code="RIP = RIP;"
597
598 class Br(WrRegOp, CondRegOp):
599 code = 'nuIP = psrc1 + op2;'
600 else_code='nuIP = nuIP;'
601
602 class Wruflags(WrRegOp):
603 code = 'ccFlagBits = psrc1 ^ op2'
604
605 class RdRegOp(RegOp):
606 abstract = True
607 def __init__(self, dest, src1 = "NUM_INTREGS", dataSize="env.dataSize"):
608 super(RdRegOp, self).__init__(dest, src1, "NUM_INTREGS", None, dataSize)
609
610 class Rdip(RdRegOp):
611 code = 'DestReg = RIP'
612
613 class Ruflags(RdRegOp):
614 code = 'DestReg = ccFlagBits'
615
616 class Ruflag(RegOp):
617 code = '''
661 int flag = bits(ccFlagBits, imm8 + 0*psrc1);
662 DestReg = merge(DestReg, flag, dataSize);
663 ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
664 (ccFlagBits & ~EZFBit);
618 int flag = bits(ccFlagBits, imm8 + 0*psrc1);
619 DestReg = merge(DestReg, flag, dataSize);
620 ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) :
621 (ccFlagBits & ~EZFBit);
665 ''')
622 '''
623 def __init__(self, dest, imm, flags=None, \
624 dataSize="env.dataSize"):
625 super(Ruflag, self).__init__(dest, \
626 "NUM_INTREGS", imm, flags, dataSize)
666
627
667 defineMicroRegOpImm('Sext', '''
628 class Sext(RegOp):
629 code = '''
668 IntReg val = psrc1;
669 int sign_bit = bits(val, imm8-1, imm8-1);
670 uint64_t maskVal = mask(imm8);
671 val = sign_bit ? (val | ~maskVal) : (val & maskVal);
672 DestReg = merge(DestReg, val, dataSize);
630 IntReg val = psrc1;
631 int sign_bit = bits(val, imm8-1, imm8-1);
632 uint64_t maskVal = mask(imm8);
633 val = sign_bit ? (val | ~maskVal) : (val & maskVal);
634 DestReg = merge(DestReg, val, dataSize);
673 ''')
635 '''
674
636
675 defineMicroRegOpImm('Zext', 'DestReg = bits(psrc1, imm8-1, 0);')
637 class Zext(RegOp):
638 code = 'DestReg = bits(psrc1, imm8-1, 0);'
676}};
639}};