1 import random 2 3 AARCH64_AS = "as" 4 AARCH64_OBJDUMP = "objdump" 5 AARCH64_OBJCOPY = "objcopy" 6 7 class Operand(object): 8 9 def generate(self): 10 return self 11 12 class Register(Operand): 13 14 def generate(self): 15 self.number = random.randint(0, 30) 16 return self 17 18 def astr(self, prefix): 19 return prefix + str(self.number) 20 21 class FloatRegister(Register): 22 23 def __str__(self): 24 return self.astr("v") 25 26 def nextReg(self): 27 next = FloatRegister() 28 next.number = (self.number + 1) % 32 29 return next 30 31 class GeneralRegister(Register): 32 33 def __str__(self): 34 return self.astr("r") 35 36 class GeneralRegisterOrZr(Register): 37 38 def generate(self): 39 self.number = random.randint(0, 31) 40 return self 41 42 def astr(self, prefix = ""): 43 if (self.number == 31): 44 return prefix + "zr" 45 else: 46 return prefix + str(self.number) 47 48 def __str__(self): 49 if (self.number == 31): 50 return self.astr() 51 else: 52 return self.astr("r") 53 54 class GeneralRegisterOrSp(Register): 55 def generate(self): 56 self.number = random.randint(0, 31) 57 return self 58 59 def astr(self, prefix = ""): 60 if (self.number == 31): 61 return "sp" 62 else: 63 return prefix + str(self.number) 64 65 def __str__(self): 66 if (self.number == 31): 67 return self.astr() 68 else: 69 return self.astr("r") 70 71 class FloatZero(Operand): 72 73 def __str__(self): 74 return "0.0" 75 76 def astr(self, ignored): 77 return "#0.0" 78 79 class OperandFactory: 80 81 _modes = {'x' : GeneralRegister, 82 'w' : GeneralRegister, 83 's' : FloatRegister, 84 'd' : FloatRegister, 85 'z' : FloatZero} 86 87 @classmethod 88 def create(cls, mode): 89 return OperandFactory._modes[mode]() 90 91 class ShiftKind: 92 93 def generate(self): 94 self.kind = ["LSL", "LSR", "ASR"][random.randint(0,2)] 95 return self 96 97 def cstr(self): 98 return self.kind 99 100 class Instruction(object): 101 102 def __init__(self, name): 103 self._name = name 104 self.isWord = name.endswith("w") | name.endswith("wi") 105 self.asmRegPrefix = ["x", "w"][self.isWord] 106 107 def aname(self): 108 if (self._name.endswith("wi")): 109 return self._name[:len(self._name)-2] 110 else: 111 if (self._name.endswith("i") | self._name.endswith("w")): 112 return self._name[:len(self._name)-1] 113 else: 114 return self._name 115 116 def emit(self) : 117 pass 118 119 def compare(self) : 120 pass 121 122 def generate(self) : 123 return self 124 125 def cstr(self): 126 return '__ %s(' % self.name() 127 128 def astr(self): 129 return '%s\t' % self.aname() 130 131 def name(self): 132 name = self._name 133 if name == "and": 134 name = "andr" # Special case: the name "and" can't be used 135 # in HotSpot, even for a member. 136 return name 137 138 def multipleForms(self): 139 return 0 140 141 class InstructionWithModes(Instruction): 142 143 def __init__(self, name, mode): 144 Instruction.__init__(self, name) 145 self.mode = mode 146 self.isFloat = (mode == 'd') | (mode == 's') 147 if self.isFloat: 148 self.isWord = mode != 'd' 149 self.asmRegPrefix = ["d", "s"][self.isWord] 150 else: 151 self.isWord = mode != 'x' 152 self.asmRegPrefix = ["x", "w"][self.isWord] 153 154 def name(self): 155 return self._name + (self.mode if self.mode != 'x' else '') 156 157 def aname(self): 158 return (self._name+mode if (mode == 'b' or mode == 'h') 159 else self._name) 160 161 class ThreeRegInstruction(Instruction): 162 163 def generate(self): 164 self.reg = [GeneralRegister().generate(), GeneralRegister().generate(), 165 GeneralRegister().generate()] 166 return self 167 168 169 def cstr(self): 170 return (super(ThreeRegInstruction, self).cstr() 171 + ('%s, %s, %s' 172 % (self.reg[0], 173 self.reg[1], self.reg[2]))) 174 175 def astr(self): 176 prefix = self.asmRegPrefix 177 return (super(ThreeRegInstruction, self).astr() 178 + ('%s, %s, %s' 179 % (self.reg[0].astr(prefix), 180 self.reg[1].astr(prefix), self.reg[2].astr(prefix)))) 181 182 class FourRegInstruction(ThreeRegInstruction): 183 184 def generate(self): 185 self.reg = ThreeRegInstruction.generate(self).reg + [GeneralRegister().generate()] 186 return self 187 188 189 def cstr(self): 190 return (super(FourRegInstruction, self).cstr() 191 + (', %s' % self.reg[3])) 192 193 def astr(self): 194 prefix = self.asmRegPrefix 195 return (super(FourRegInstruction, self).astr() 196 + (', %s' % self.reg[3].astr(prefix))) 197 198 class TwoRegInstruction(Instruction): 199 200 def generate(self): 201 self.reg = [GeneralRegister().generate(), GeneralRegister().generate()] 202 return self 203 204 def cstr(self): 205 return (super(TwoRegInstruction, self).cstr() 206 + '%s, %s' % (self.reg[0], 207 self.reg[1])) 208 209 def astr(self): 210 prefix = self.asmRegPrefix 211 return (super(TwoRegInstruction, self).astr() 212 + ('%s, %s' 213 % (self.reg[0].astr(prefix), 214 self.reg[1].astr(prefix)))) 215 216 class TwoRegImmedInstruction(TwoRegInstruction): 217 218 def generate(self): 219 super(TwoRegImmedInstruction, self).generate() 220 self.immed = random.randint(0, 1<<11 -1) 221 return self 222 223 def cstr(self): 224 return (super(TwoRegImmedInstruction, self).cstr() 225 + ', %su' % self.immed) 226 227 def astr(self): 228 return (super(TwoRegImmedInstruction, self).astr() 229 + ', #%s' % self.immed) 230 231 class OneRegOp(Instruction): 232 233 def generate(self): 234 self.reg = GeneralRegister().generate() 235 return self 236 237 def cstr(self): 238 return (super(OneRegOp, self).cstr() 239 + '%s);' % self.reg) 240 241 def astr(self): 242 return (super(OneRegOp, self).astr() 243 + '%s' % self.reg.astr(self.asmRegPrefix)) 244 245 class ArithOp(ThreeRegInstruction): 246 247 def generate(self): 248 super(ArithOp, self).generate() 249 self.kind = ShiftKind().generate() 250 self.distance = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1) 251 return self 252 253 def cstr(self): 254 return ('%s, Assembler::%s, %s);' 255 % (ThreeRegInstruction.cstr(self), 256 self.kind.cstr(), self.distance)) 257 258 def astr(self): 259 return ('%s, %s #%s' 260 % (ThreeRegInstruction.astr(self), 261 self.kind.cstr(), 262 self.distance)) 263 264 class AddSubCarryOp(ThreeRegInstruction): 265 266 def cstr(self): 267 return ('%s);' 268 % (ThreeRegInstruction.cstr(self))) 269 270 class AddSubExtendedOp(ThreeRegInstruction): 271 272 uxtb, uxth, uxtw, uxtx, sxtb, sxth, sxtw, sxtx = range(8) 273 optNames = ["uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"] 274 275 def generate(self): 276 super(AddSubExtendedOp, self).generate() 277 self.amount = random.randint(1, 4) 278 self.option = random.randint(0, 7) 279 return self 280 281 def cstr(self): 282 return (super(AddSubExtendedOp, self).cstr() 283 + (", ext::" + AddSubExtendedOp.optNames[self.option] 284 + ", " + str(self.amount) + ");")) 285 286 def astr(self): 287 return (super(AddSubExtendedOp, self).astr() 288 + (", " + AddSubExtendedOp.optNames[self.option] 289 + " #" + str(self.amount))) 290 291 class AddSubImmOp(TwoRegImmedInstruction): 292 293 def cstr(self): 294 return super(AddSubImmOp, self).cstr() + ");" 295 296 class LogicalImmOp(AddSubImmOp): 297 298 # These tables are legal immediate logical operands 299 immediates32 \ 300 = [0x1, 0x3f, 0x1f0, 0x7e0, 301 0x1c00, 0x3ff0, 0x8000, 0x1e000, 302 0x3e000, 0x78000, 0xe0000, 0x100000, 303 0x1fffe0, 0x3fe000, 0x780000, 0x7ffff8, 304 0xff8000, 0x1800180, 0x1fffc00, 0x3c003c0, 305 0x3ffff00, 0x7c00000, 0x7fffe00, 0xf000f00, 306 0xfffe000, 0x18181818, 0x1ffc0000, 0x1ffffffe, 307 0x3f003f00, 0x3fffe000, 0x60006000, 0x7f807f80, 308 0x7ffffc00, 0x800001ff, 0x803fffff, 0x9f9f9f9f, 309 0xc0000fff, 0xc0c0c0c0, 0xe0000000, 0xe003e003, 310 0xe3ffffff, 0xf0000fff, 0xf0f0f0f0, 0xf80000ff, 311 0xf83ff83f, 0xfc00007f, 0xfc1fffff, 0xfe0001ff, 312 0xfe3fffff, 0xff003fff, 0xff800003, 0xff87ff87, 313 0xffc00fff, 0xffe0000f, 0xffefffef, 0xfff1fff1, 314 0xfff83fff, 0xfffc0fff, 0xfffe0fff, 0xffff3fff, 315 0xffffc007, 0xffffe1ff, 0xfffff80f, 0xfffffe07, 316 0xffffffbf, 0xfffffffd] 317 318 immediates \ 319 = [0x1, 0x1f80, 0x3fff0, 0x3ffffc, 320 0x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000, 321 0xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000, 322 0x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000, 323 0x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000, 324 0x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000, 325 0x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8, 326 0x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000, 327 0x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff, 328 0xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003, 329 0xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff, 330 0xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000, 331 0xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f, 332 0xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff, 333 0xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff, 334 0xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f] 335 336 def generate(self): 337 AddSubImmOp.generate(self) 338 self.immed = \ 339 self.immediates32[random.randint(0, len(self.immediates32)-1)] \ 340 if self.isWord \ 341 else \ 342 self.immediates[random.randint(0, len(self.immediates)-1)] 343 344 return self 345 346 def astr(self): 347 return (super(TwoRegImmedInstruction, self).astr() 348 + ', #0x%x' % self.immed) 349 350 def cstr(self): 351 return super(AddSubImmOp, self).cstr() + "ll);" 352 353 class MultiOp(): 354 355 def multipleForms(self): 356 return 3 357 358 def forms(self): 359 return ["__ pc()", "back", "forth"] 360 361 def aforms(self): 362 return [".", "back", "forth"] 363 364 class AbsOp(MultiOp, Instruction): 365 366 def cstr(self): 367 return super(AbsOp, self).cstr() + "%s);" 368 369 def astr(self): 370 return Instruction.astr(self) + "%s" 371 372 class RegAndAbsOp(MultiOp, Instruction): 373 374 def multipleForms(self): 375 if self.name() == "adrp": 376 # We can only test one form of adrp because anything other 377 # than "adrp ." requires relocs in the assembler output 378 return 1 379 return 3 380 381 def generate(self): 382 Instruction.generate(self) 383 self.reg = GeneralRegister().generate() 384 return self 385 386 def cstr(self): 387 if self.name() == "adrp": 388 return "__ _adrp(" + "%s, %s);" % (self.reg, "%s") 389 return (super(RegAndAbsOp, self).cstr() 390 + "%s, %s);" % (self.reg, "%s")) 391 392 def astr(self): 393 return (super(RegAndAbsOp, self).astr() 394 + self.reg.astr(self.asmRegPrefix) + ", %s") 395 396 class RegImmAbsOp(RegAndAbsOp): 397 398 def cstr(self): 399 return (Instruction.cstr(self) 400 + "%s, %s, %s);" % (self.reg, self.immed, "%s")) 401 402 def astr(self): 403 return (Instruction.astr(self) 404 + ("%s, #%s, %s" 405 % (self.reg.astr(self.asmRegPrefix), self.immed, "%s"))) 406 407 def generate(self): 408 super(RegImmAbsOp, self).generate() 409 self.immed = random.randint(0, 1<<5 -1) 410 return self 411 412 class MoveWideImmOp(RegImmAbsOp): 413 414 def multipleForms(self): 415 return 0 416 417 def cstr(self): 418 return (Instruction.cstr(self) 419 + "%s, %s, %s);" % (self.reg, self.immed, self.shift)) 420 421 def astr(self): 422 return (Instruction.astr(self) 423 + ("%s, #%s, lsl %s" 424 % (self.reg.astr(self.asmRegPrefix), 425 self.immed, self.shift))) 426 427 def generate(self): 428 super(RegImmAbsOp, self).generate() 429 self.immed = random.randint(0, 1<<16 -1) 430 if self.isWord: 431 self.shift = random.randint(0, 1) * 16 432 else: 433 self.shift = random.randint(0, 3) * 16 434 return self 435 436 class BitfieldOp(TwoRegInstruction): 437 438 def cstr(self): 439 return (Instruction.cstr(self) 440 + ("%s, %s, %s, %s);" 441 % (self.reg[0], self.reg[1], self.immr, self.imms))) 442 443 def astr(self): 444 return (TwoRegInstruction.astr(self) 445 + (", #%s, #%s" 446 % (self.immr, self.imms))) 447 448 def generate(self): 449 TwoRegInstruction.generate(self) 450 self.immr = random.randint(0, 31) 451 self.imms = random.randint(0, 31) 452 return self 453 454 class ExtractOp(ThreeRegInstruction): 455 456 def generate(self): 457 super(ExtractOp, self).generate() 458 self.lsb = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1) 459 return self 460 461 def cstr(self): 462 return (ThreeRegInstruction.cstr(self) 463 + (", %s);" % self.lsb)) 464 465 def astr(self): 466 return (ThreeRegInstruction.astr(self) 467 + (", #%s" % self.lsb)) 468 469 class CondBranchOp(MultiOp, Instruction): 470 471 def cstr(self): 472 return "__ br(Assembler::" + self.name() + ", %s);" 473 474 def astr(self): 475 return "b." + self.name() + "\t%s" 476 477 class ImmOp(Instruction): 478 479 def cstr(self): 480 return "%s%s);" % (Instruction.cstr(self), self.immed) 481 482 def astr(self): 483 return Instruction.astr(self) + "#" + str(self.immed) 484 485 def generate(self): 486 self.immed = random.randint(0, 1<<16 -1) 487 return self 488 489 class Op(Instruction): 490 491 def cstr(self): 492 return Instruction.cstr(self) + ");" 493 494 class SystemOp(Instruction): 495 496 def __init__(self, op): 497 Instruction.__init__(self, op[0]) 498 self.barriers = op[1] 499 500 def generate(self): 501 Instruction.generate(self) 502 self.barrier \ 503 = self.barriers[random.randint(0, len(self.barriers)-1)] 504 return self 505 506 def cstr(self): 507 return Instruction.cstr(self) + "Assembler::" + self.barrier + ");" 508 509 def astr(self): 510 return Instruction.astr(self) + self.barrier 511 512 conditionCodes = ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", \ 513 "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV"] 514 515 class ConditionalCompareOp(TwoRegImmedInstruction): 516 517 def generate(self): 518 TwoRegImmedInstruction.generate(self) 519 self.cond = random.randint(0, 15) 520 self.immed = random.randint(0, 15) 521 return self 522 523 def cstr(self): 524 return (super(ConditionalCompareOp, self).cstr() + ", " 525 + "Assembler::" + conditionCodes[self.cond] + ");") 526 527 def astr(self): 528 return (super(ConditionalCompareOp, self).astr() + 529 ", " + conditionCodes[self.cond]) 530 531 class ConditionalCompareImmedOp(Instruction): 532 533 def generate(self): 534 self.reg = GeneralRegister().generate() 535 self.cond = random.randint(0, 15) 536 self.immed2 = random.randint(0, 15) 537 self.immed = random.randint(0, 31) 538 return self 539 540 def cstr(self): 541 return (Instruction.cstr(self) + str(self.reg) + ", " 542 + str(self.immed) + ", " 543 + str(self.immed2) + ", " 544 + "Assembler::" + conditionCodes[self.cond] + ");") 545 546 def astr(self): 547 return (Instruction.astr(self) 548 + self.reg.astr(self.asmRegPrefix) 549 + ", #" + str(self.immed) 550 + ", #" + str(self.immed2) 551 + ", " + conditionCodes[self.cond]) 552 553 class TwoRegOp(TwoRegInstruction): 554 555 def cstr(self): 556 return TwoRegInstruction.cstr(self) + ");" 557 558 class ThreeRegOp(ThreeRegInstruction): 559 560 def cstr(self): 561 return ThreeRegInstruction.cstr(self) + ");" 562 563 class FourRegMulOp(FourRegInstruction): 564 565 def cstr(self): 566 return FourRegInstruction.cstr(self) + ");" 567 568 def astr(self): 569 isMaddsub = self.name().startswith("madd") | self.name().startswith("msub") 570 midPrefix = self.asmRegPrefix if isMaddsub else "w" 571 return (Instruction.astr(self) 572 + self.reg[0].astr(self.asmRegPrefix) 573 + ", " + self.reg[1].astr(midPrefix) 574 + ", " + self.reg[2].astr(midPrefix) 575 + ", " + self.reg[3].astr(self.asmRegPrefix)) 576 577 class ConditionalSelectOp(ThreeRegInstruction): 578 579 def generate(self): 580 ThreeRegInstruction.generate(self) 581 self.cond = random.randint(0, 15) 582 return self 583 584 def cstr(self): 585 return (ThreeRegInstruction.cstr(self) + ", " 586 + "Assembler::" + conditionCodes[self.cond] + ");") 587 588 def astr(self): 589 return (ThreeRegInstruction.astr(self) 590 + ", " + conditionCodes[self.cond]) 591 592 class LoadStoreExclusiveOp(InstructionWithModes): 593 594 def __init__(self, op): # op is a tuple of ["name", "mode", registers] 595 InstructionWithModes.__init__(self, op[0], op[1]) 596 self.num_registers = op[2] 597 598 def astr(self): 599 result = self.aname() + '\t' 600 regs = list(self.regs) 601 index = regs.pop() # The last reg is the index register 602 prefix = ('x' if (self.mode == 'x') 603 & ((self.name().startswith("ld")) 604 | (self.name().startswith("stlr"))) # Ewww :-( 605 else 'w') 606 result = result + regs.pop(0).astr(prefix) + ", " 607 for s in regs: 608 result = result + s.astr(self.asmRegPrefix) + ", " 609 result = result + "[" + index.astr("x") + "]" 610 return result 611 612 def cstr(self): 613 result = InstructionWithModes.cstr(self) 614 regs = list(self.regs) 615 index = regs.pop() # The last reg is the index register 616 for s in regs: 617 result = result + str(s) + ", " 618 result = result + str(index) + ");" 619 return result 620 621 def appendUniqueReg(self): 622 result = 0 623 while result == 0: 624 newReg = GeneralRegister().generate() 625 result = 1 626 for i in self.regs: 627 result = result and (i.number != newReg.number) 628 self.regs.append(newReg) 629 630 def generate(self): 631 self.regs = [] 632 for i in range(self.num_registers): 633 self.appendUniqueReg() 634 return self 635 636 def name(self): 637 if self.mode == 'x': 638 return self._name 639 else: 640 return self._name + self.mode 641 642 def aname(self): 643 if (self.mode == 'b') | (self.mode == 'h'): 644 return self._name + self.mode 645 else: 646 return self._name 647 648 class Address(object): 649 650 base_plus_unscaled_offset, pre, post, base_plus_reg, \ 651 base_plus_scaled_offset, pcrel, post_reg, base_only = range(8) 652 kinds = ["base_plus_unscaled_offset", "pre", "post", "base_plus_reg", 653 "base_plus_scaled_offset", "pcrel", "post_reg", "base_only"] 654 extend_kinds = ["uxtw", "lsl", "sxtw", "sxtx"] 655 656 @classmethod 657 def kindToStr(cls, i): 658 return cls.kinds[i] 659 660 def generate(self, kind, shift_distance): 661 self.kind = kind 662 self.base = GeneralRegister().generate() 663 self.index = GeneralRegister().generate() 664 self.offset = { 665 Address.base_plus_unscaled_offset: random.randint(-1<<8, 1<<8-1) | 1, 666 Address.pre: random.randint(-1<<8, 1<<8-1), 667 Address.post: random.randint(-1<<8, 1<<8-1), 668 Address.pcrel: random.randint(0, 2), 669 Address.base_plus_reg: 0, 670 Address.base_plus_scaled_offset: (random.randint(0, 1<<11-1) | (3 << 9))*8, 671 Address.post_reg: 0, 672 Address.base_only: 0} [kind] 673 self.offset >>= (3 - shift_distance) 674 self.extend_kind = Address.extend_kinds[random.randint(0, 3)] 675 self.shift_distance = random.randint(0, 1) * shift_distance 676 return self 677 678 def __str__(self): 679 result = { 680 Address.base_plus_unscaled_offset: "Address(%s, %s)" \ 681 % (str(self.base), self.offset), 682 Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset), 683 Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset), 684 Address.post_reg: "Address(__ post(%s, %s))" % (str(self.base), self.index), 685 Address.base_only: "Address(%s)" % (str(self.base)), 686 Address.pcrel: "", 687 Address.base_plus_reg: "Address(%s, %s, Address::%s(%s))" \ 688 % (self.base, self.index, self.extend_kind, self.shift_distance), 689 Address.base_plus_scaled_offset: 690 "Address(%s, %s)" % (self.base, self.offset) } [self.kind] 691 if (self.kind == Address.pcrel): 692 result = ["__ pc()", "back", "forth"][self.offset] 693 return result 694 695 def astr(self, prefix): 696 extend_prefix = prefix 697 if self.kind == Address.base_plus_reg: 698 if self.extend_kind.endswith("w"): 699 extend_prefix = "w" 700 result = { 701 Address.base_plus_unscaled_offset: "[%s, %s]" \ 702 % (self.base.astr(prefix), self.offset), 703 Address.pre: "[%s, %s]!" % (self.base.astr(prefix), self.offset), 704 Address.post: "[%s], %s" % (self.base.astr(prefix), self.offset), 705 Address.post_reg: "[%s], %s" % (self.base.astr(prefix), self.index.astr(prefix)), 706 Address.base_only: "[%s]" % (self.base.astr(prefix)), 707 Address.pcrel: "", 708 Address.base_plus_reg: "[%s, %s, %s #%s]" \ 709 % (self.base.astr(prefix), self.index.astr(extend_prefix), 710 self.extend_kind, self.shift_distance), 711 Address.base_plus_scaled_offset: \ 712 "[%s, %s]" \ 713 % (self.base.astr(prefix), self.offset) 714 } [self.kind] 715 if (self.kind == Address.pcrel): 716 result = [".", "back", "forth"][self.offset] 717 return result 718 719 class LoadStoreOp(InstructionWithModes): 720 721 def __init__(self, args): 722 name, self.asmname, self.kind, mode = args 723 InstructionWithModes.__init__(self, name, mode) 724 725 def generate(self): 726 727 # This is something of a kludge, but the offset needs to be 728 # scaled by the memory datamode somehow. 729 shift = 3 730 if (self.mode == 'b') | (self.asmname.endswith("b")): 731 shift = 0 732 elif (self.mode == 'h') | (self.asmname.endswith("h")): 733 shift = 1 734 elif (self.mode == 'w') | (self.asmname.endswith("w")) \ 735 | (self.mode == 's') : 736 shift = 2 737 738 self.adr = Address().generate(self.kind, shift) 739 740 isFloat = (self.mode == 'd') | (self.mode == 's') 741 742 regMode = FloatRegister if isFloat else GeneralRegister 743 self.reg = regMode().generate() 744 kindStr = Address.kindToStr(self.kind); 745 if (not isFloat) and (kindStr is "pre" or kindStr is "post"): 746 (self.reg.number, self.adr.base.number) = random.sample(range(31), 2) 747 return self 748 749 def cstr(self): 750 if not(self._name.startswith("prfm")): 751 return "%s%s, %s);" % (Instruction.cstr(self), str(self.reg), str(self.adr)) 752 else: # No target register for a prefetch 753 return "%s%s);" % (Instruction.cstr(self), str(self.adr)) 754 755 def astr(self): 756 if not(self._name.startswith("prfm")): 757 return "%s\t%s, %s" % (self.aname(), self.reg.astr(self.asmRegPrefix), 758 self.adr.astr("x")) 759 else: # No target register for a prefetch 760 return "%s %s" % (self.aname(), 761 self.adr.astr("x")) 762 763 def aname(self): 764 result = self.asmname 765 # if self.kind == Address.base_plus_unscaled_offset: 766 # result = result.replace("ld", "ldu", 1) 767 # result = result.replace("st", "stu", 1) 768 return result 769 770 class LoadStorePairOp(InstructionWithModes): 771 772 numRegs = 2 773 774 def __init__(self, args): 775 name, self.asmname, self.kind, mode = args 776 InstructionWithModes.__init__(self, name, mode) 777 self.offset = random.randint(-1<<4, 1<<4-1) << 4 778 779 def generate(self): 780 self.reg = [OperandFactory.create(self.mode).generate() 781 for i in range(self.numRegs)] 782 self.base = OperandFactory.create('x').generate() 783 kindStr = Address.kindToStr(self.kind); 784 if kindStr is "pre" or kindStr is "post": 785 if self._name.startswith("ld"): 786 (self.reg[0].number, self.reg[1].number, self.base.number) = random.sample(range(31), 3) 787 if self._name.startswith("st"): 788 self.base.number = random.choice(list(set(range(31)) - set([self.reg[0].number, self.reg[1].number]))) 789 elif self._name.startswith("ld"): 790 (self.reg[0].number, self.reg[1].number) = random.sample(range(31), 2) 791 return self 792 793 def astr(self): 794 address = ["[%s, #%s]", "[%s, #%s]!", "[%s], #%s"][self.kind] 795 address = address % (self.base.astr('x'), self.offset) 796 result = "%s\t%s, %s, %s" \ 797 % (self.asmname, 798 self.reg[0].astr(self.asmRegPrefix), 799 self.reg[1].astr(self.asmRegPrefix), address) 800 return result 801 802 def cstr(self): 803 address = { 804 Address.base_plus_unscaled_offset: "Address(%s, %s)" \ 805 % (str(self.base), self.offset), 806 Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset), 807 Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset), 808 } [self.kind] 809 result = "__ %s(%s, %s, %s);" \ 810 % (self.name(), self.reg[0], self.reg[1], address) 811 return result 812 813 class FloatInstruction(Instruction): 814 815 def aname(self): 816 if (self._name.endswith("s") | self._name.endswith("d")): 817 return self._name[:len(self._name)-1] 818 else: 819 return self._name 820 821 def __init__(self, args): 822 name, self.modes = args 823 Instruction.__init__(self, name) 824 825 def generate(self): 826 self.reg = [OperandFactory.create(self.modes[i]).generate() 827 for i in range(self.numRegs)] 828 return self 829 830 def cstr(self): 831 formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"]) 832 return (formatStr 833 % tuple([Instruction.cstr(self)] + 834 [str(self.reg[i]) for i in range(self.numRegs)])) # Yowza 835 836 def astr(self): 837 formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)]) 838 return (formatStr 839 % tuple([Instruction.astr(self)] + 840 [(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)])) 841 842 class LdStSIMDOp(Instruction): 843 def __init__(self, args): 844 self._name, self.regnum, self.arrangement, self.addresskind = args 845 846 def generate(self): 847 self.address = Address().generate(self.addresskind, 0) 848 self._firstSIMDreg = FloatRegister().generate() 849 if (self.addresskind == Address.post): 850 if (self._name in ["ld1r", "ld2r", "ld3r", "ld4r"]): 851 elem_size = {"8B" : 1, "16B" : 1, "4H" : 2, "8H" : 2, "2S" : 4, "4S" : 4, "1D" : 8, "2D" : 8} [self.arrangement] 852 self.address.offset = self.regnum * elem_size 853 else: 854 if (self.arrangement in ["8B", "4H", "2S", "1D"]): 855 self.address.offset = self.regnum * 8 856 else: 857 self.address.offset = self.regnum * 16 858 return self 859 860 def cstr(self): 861 buf = super(LdStSIMDOp, self).cstr() + str(self._firstSIMDreg) 862 current = self._firstSIMDreg 863 for cnt in range(1, self.regnum): 864 buf = '%s, %s' % (buf, current.nextReg()) 865 current = current.nextReg() 866 return '%s, __ T%s, %s);' % (buf, self.arrangement, str(self.address)) 867 868 def astr(self): 869 buf = '%s\t{%s.%s' % (self._name, self._firstSIMDreg, self.arrangement) 870 current = self._firstSIMDreg 871 for cnt in range(1, self.regnum): 872 buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement) 873 current = current.nextReg() 874 return '%s}, %s' % (buf, self.address.astr("x")) 875 876 def aname(self): 877 return self._name 878 879 class SHA512SIMDOp(Instruction): 880 881 def generate(self): 882 if (self._name == 'sha512su0'): 883 self.reg = [FloatRegister().generate(), FloatRegister().generate()] 884 else: 885 self.reg = [FloatRegister().generate(), FloatRegister().generate(), 886 FloatRegister().generate()] 887 return self 888 889 def cstr(self): 890 if (self._name == 'sha512su0'): 891 return (super(SHA512SIMDOp, self).cstr() 892 + ('%s, __ T2D, %s);' % (self.reg[0], self.reg[1]))) 893 else: 894 return (super(SHA512SIMDOp, self).cstr() 895 + ('%s, __ T2D, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2]))) 896 897 def astr(self): 898 if (self._name == 'sha512su0'): 899 return (super(SHA512SIMDOp, self).astr() 900 + ('\t%s.2D, %s.2D' % (self.reg[0].astr("v"), self.reg[1].astr("v")))) 901 elif (self._name == 'sha512su1'): 902 return (super(SHA512SIMDOp, self).astr() 903 + ('\t%s.2D, %s.2D, %s.2D' % (self.reg[0].astr("v"), 904 self.reg[1].astr("v"), self.reg[2].astr("v")))) 905 else: 906 return (super(SHA512SIMDOp, self).astr() 907 + ('\t%s, %s, %s.2D' % (self.reg[0].astr("q"), 908 self.reg[1].astr("q"), self.reg[2].astr("v")))) 909 910 class LSEOp(Instruction): 911 def __init__(self, args): 912 self._name, self.asmname, self.size, self.suffix = args 913 914 def generate(self): 915 self._name = "%s%s" % (self._name, self.suffix) 916 self.asmname = "%s%s" % (self.asmname, self.suffix) 917 self.srcReg = GeneralRegisterOrZr().generate() 918 self.tgtReg = GeneralRegisterOrZr().generate() 919 self.adrReg = GeneralRegisterOrSp().generate() 920 921 return self 922 923 def cstr(self): 924 sizeSpec = {"x" : "Assembler::xword", "w" : "Assembler::word"} [self.size] 925 return super(LSEOp, self).cstr() + "%s, %s, %s, %s);" % (sizeSpec, self.srcReg, self.tgtReg, self.adrReg) 926 927 def astr(self): 928 return "%s\t%s, %s, [%s]" % (self.asmname, self.srcReg.astr(self.size), self.tgtReg.astr(self.size), self.adrReg.astr("x")) 929 930 def aname(self): 931 return self.asmname 932 933 class TwoRegFloatOp(FloatInstruction): 934 numRegs = 2 935 936 class ThreeRegFloatOp(TwoRegFloatOp): 937 numRegs = 3 938 939 class FourRegFloatOp(TwoRegFloatOp): 940 numRegs = 4 941 942 class FloatConvertOp(TwoRegFloatOp): 943 944 def __init__(self, args): 945 self._cname, self._aname, modes = args 946 TwoRegFloatOp.__init__(self, [self._cname, modes]) 947 948 def aname(self): 949 return self._aname 950 951 def cname(self): 952 return self._cname 953 954 class SpecialCases(Instruction): 955 def __init__(self, data): 956 self._name = data[0] 957 self._cstr = data[1] 958 self._astr = data[2] 959 960 def cstr(self): 961 return self._cstr 962 963 def astr(self): 964 return self._astr 965 966 def generate(kind, names): 967 outfile.write("# " + kind.__name__ + "\n"); 968 print "\n// " + kind.__name__ 969 for name in names: 970 for i in range(1): 971 op = kind(name).generate() 972 if op.multipleForms(): 973 forms = op.forms() 974 aforms = op.aforms() 975 for i in range(op.multipleForms()): 976 cstr = op.cstr() % forms[i] 977 astr = op.astr() % aforms[i] 978 print " %-50s //\t%s" % (cstr, astr) 979 outfile.write("\t" + astr + "\n") 980 else: 981 print " %-50s //\t%s" % (op.cstr(), op.astr()) 982 outfile.write("\t" + op.astr() + "\n") 983 984 outfile = open("aarch64ops.s", "w") 985 986 random.seed(0) 987 988 print "// BEGIN Generated code -- do not edit" 989 print "// Generated by aarch64-asmtest.py" 990 991 print " Label back, forth;" 992 print " __ bind(back);" 993 994 outfile.write("back:\n") 995 996 generate (ArithOp, 997 [ "add", "sub", "adds", "subs", 998 "addw", "subw", "addsw", "subsw", 999 "and", "orr", "eor", "ands", 1000 "andw", "orrw", "eorw", "andsw", 1001 "bic", "orn", "eon", "bics", 1002 "bicw", "ornw", "eonw", "bicsw" ]) 1003 1004 generate (AddSubImmOp, 1005 [ "addw", "addsw", "subw", "subsw", 1006 "add", "adds", "sub", "subs"]) 1007 generate (LogicalImmOp, 1008 [ "andw", "orrw", "eorw", "andsw", 1009 "and", "orr", "eor", "ands"]) 1010 1011 generate (AbsOp, [ "b", "bl" ]) 1012 1013 generate (RegAndAbsOp, ["cbzw", "cbnzw", "cbz", "cbnz", "adr", "adrp"]) 1014 1015 generate (RegImmAbsOp, ["tbz", "tbnz"]) 1016 1017 generate (MoveWideImmOp, ["movnw", "movzw", "movkw", "movn", "movz", "movk"]) 1018 1019 generate (BitfieldOp, ["sbfm", "bfmw", "ubfmw", "sbfm", "bfm", "ubfm"]) 1020 1021 generate (ExtractOp, ["extrw", "extr"]) 1022 1023 generate (CondBranchOp, ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", "VC", 1024 "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV" ]) 1025 1026 generate (ImmOp, ["svc", "hvc", "smc", "brk", "hlt", # "dcps1", "dcps2", "dcps3" 1027 ]) 1028 1029 generate (Op, ["nop", "eret", "drps", "isb"]) 1030 1031 barriers = ["OSHLD", "OSHST", "OSH", "NSHLD", "NSHST", "NSH", 1032 "ISHLD", "ISHST", "ISH", "LD", "ST", "SY"] 1033 1034 generate (SystemOp, [["dsb", barriers], ["dmb", barriers]]) 1035 1036 generate (OneRegOp, ["br", "blr"]) 1037 1038 for mode in 'xwhb': 1039 generate (LoadStoreExclusiveOp, [["stxr", mode, 3], ["stlxr", mode, 3], 1040 ["ldxr", mode, 2], ["ldaxr", mode, 2], 1041 ["stlr", mode, 2], ["ldar", mode, 2]]) 1042 1043 for mode in 'xw': 1044 generate (LoadStoreExclusiveOp, [["ldxp", mode, 3], ["ldaxp", mode, 3], 1045 ["stxp", mode, 4], ["stlxp", mode, 4]]) 1046 1047 for kind in range(6): 1048 print "\n// " + Address.kindToStr(kind), 1049 if kind != Address.pcrel: 1050 generate (LoadStoreOp, 1051 [["str", "str", kind, "x"], ["str", "str", kind, "w"], 1052 ["str", "strb", kind, "b"], ["str", "strh", kind, "h"], 1053 ["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"], 1054 ["ldr", "ldrb", kind, "b"], ["ldr", "ldrh", kind, "h"], 1055 ["ldrsb", "ldrsb", kind, "x"], ["ldrsh", "ldrsh", kind, "x"], 1056 ["ldrsh", "ldrsh", kind, "w"], ["ldrsw", "ldrsw", kind, "x"], 1057 ["ldr", "ldr", kind, "d"], ["ldr", "ldr", kind, "s"], 1058 ["str", "str", kind, "d"], ["str", "str", kind, "s"], 1059 ]) 1060 else: 1061 generate (LoadStoreOp, 1062 [["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"]]) 1063 1064 1065 for kind in (Address.base_plus_unscaled_offset, Address.pcrel, Address.base_plus_reg, \ 1066 Address.base_plus_scaled_offset): 1067 generate (LoadStoreOp, 1068 [["prfm", "prfm\tPLDL1KEEP,", kind, "x"]]) 1069 1070 generate(AddSubCarryOp, ["adcw", "adcsw", "sbcw", "sbcsw", "adc", "adcs", "sbc", "sbcs"]) 1071 1072 generate(AddSubExtendedOp, ["addw", "addsw", "sub", "subsw", "add", "adds", "sub", "subs"]) 1073 1074 generate(ConditionalCompareOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"]) 1075 generate(ConditionalCompareImmedOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"]) 1076 generate(ConditionalSelectOp, 1077 ["cselw", "csincw", "csinvw", "csnegw", "csel", "csinc", "csinv", "csneg"]) 1078 1079 generate(TwoRegOp, 1080 ["rbitw", "rev16w", "revw", "clzw", "clsw", "rbit", 1081 "rev16", "rev32", "rev", "clz", "cls"]) 1082 generate(ThreeRegOp, 1083 ["udivw", "sdivw", "lslvw", "lsrvw", "asrvw", "rorvw", "udiv", "sdiv", 1084 "lslv", "lsrv", "asrv", "rorv", "umulh", "smulh"]) 1085 generate(FourRegMulOp, 1086 ["maddw", "msubw", "madd", "msub", "smaddl", "smsubl", "umaddl", "umsubl"]) 1087 1088 generate(ThreeRegFloatOp, 1089 [["fmuls", "sss"], ["fdivs", "sss"], ["fadds", "sss"], ["fsubs", "sss"], 1090 ["fmuls", "sss"], 1091 ["fmuld", "ddd"], ["fdivd", "ddd"], ["faddd", "ddd"], ["fsubd", "ddd"], 1092 ["fmuld", "ddd"]]) 1093 1094 generate(FourRegFloatOp, 1095 [["fmadds", "ssss"], ["fmsubs", "ssss"], ["fnmadds", "ssss"], ["fnmadds", "ssss"], 1096 ["fmaddd", "dddd"], ["fmsubd", "dddd"], ["fnmaddd", "dddd"], ["fnmaddd", "dddd"],]) 1097 1098 generate(TwoRegFloatOp, 1099 [["fmovs", "ss"], ["fabss", "ss"], ["fnegs", "ss"], ["fsqrts", "ss"], 1100 ["fcvts", "ds"], 1101 ["fmovd", "dd"], ["fabsd", "dd"], ["fnegd", "dd"], ["fsqrtd", "dd"], 1102 ["fcvtd", "sd"], 1103 ]) 1104 1105 generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"], 1106 ["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"], 1107 ["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"], 1108 ["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"], 1109 ["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"], 1110 ["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]]) 1111 1112 generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"], 1113 ["fcmps", "sz"], ["fcmpd", "dz"]]) 1114 1115 for kind in range(3): 1116 generate(LoadStorePairOp, [["stp", "stp", kind, "w"], ["ldp", "ldp", kind, "w"], 1117 ["ldpsw", "ldpsw", kind, "x"], 1118 ["stp", "stp", kind, "x"], ["ldp", "ldp", kind, "x"] 1119 ]) 1120 generate(LoadStorePairOp, [["stnp", "stnp", 0, "w"], ["ldnp", "ldnp", 0, "w"], 1121 ["stnp", "stnp", 0, "x"], ["ldnp", "ldnp", 0, "x"]]) 1122 1123 generate(LdStSIMDOp, [["ld1", 1, "8B", Address.base_only], 1124 ["ld1", 2, "16B", Address.post], 1125 ["ld1", 3, "1D", Address.post_reg], 1126 ["ld1", 4, "8H", Address.post], 1127 ["ld1r", 1, "8B", Address.base_only], 1128 ["ld1r", 1, "4S", Address.post], 1129 ["ld1r", 1, "1D", Address.post_reg], 1130 ["ld2", 2, "2D", Address.base_only], 1131 ["ld2", 2, "4H", Address.post], 1132 ["ld2r", 2, "16B", Address.base_only], 1133 ["ld2r", 2, "2S", Address.post], 1134 ["ld2r", 2, "2D", Address.post_reg], 1135 ["ld3", 3, "4S", Address.post_reg], 1136 ["ld3", 3, "2S", Address.base_only], 1137 ["ld3r", 3, "8H", Address.base_only], 1138 ["ld3r", 3, "4S", Address.post], 1139 ["ld3r", 3, "1D", Address.post_reg], 1140 ["ld4", 4, "8H", Address.post], 1141 ["ld4", 4, "8B", Address.post_reg], 1142 ["ld4r", 4, "8B", Address.base_only], 1143 ["ld4r", 4, "4H", Address.post], 1144 ["ld4r", 4, "2S", Address.post_reg], 1145 ]) 1146 1147 generate(SHA512SIMDOp, ["sha512h", "sha512h2", "sha512su0", "sha512su1"]) 1148 1149 generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", "ccmn\txzr, xzr, #3, LE"], 1150 ["ccmnw", "__ ccmnw(zr, zr, 5u, Assembler::EQ);", "ccmn\twzr, wzr, #5, EQ"], 1151 ["ccmp", "__ ccmp(zr, 1, 4u, Assembler::NE);", "ccmp\txzr, 1, #4, NE"], 1152 ["ccmpw", "__ ccmpw(zr, 2, 2, Assembler::GT);", "ccmp\twzr, 2, #2, GT"], 1153 ["extr", "__ extr(zr, zr, zr, 0);", "extr\txzr, xzr, xzr, 0"], 1154 ["stlxp", "__ stlxp(r0, zr, zr, sp);", "stlxp\tw0, xzr, xzr, [sp]"], 1155 ["stlxpw", "__ stlxpw(r2, zr, zr, r3);", "stlxp\tw2, wzr, wzr, [x3]"], 1156 ["stxp", "__ stxp(r4, zr, zr, r5);", "stxp\tw4, xzr, xzr, [x5]"], 1157 ["stxpw", "__ stxpw(r6, zr, zr, sp);", "stxp\tw6, wzr, wzr, [sp]"], 1158 ["dup", "__ dup(v0, __ T16B, zr);", "dup\tv0.16b, wzr"], 1159 ["mov", "__ mov(v1, __ T1D, 0, zr);", "mov\tv1.d[0], xzr"], 1160 ["mov", "__ mov(v1, __ T2S, 1, zr);", "mov\tv1.s[1], wzr"], 1161 ["mov", "__ mov(v1, __ T4H, 2, zr);", "mov\tv1.h[2], wzr"], 1162 ["mov", "__ mov(v1, __ T8B, 3, zr);", "mov\tv1.b[3], wzr"], 1163 ["ld1", "__ ld1(v31, v0, __ T2D, Address(__ post(r1, r0)));", "ld1\t{v31.2d, v0.2d}, [x1], x0"]]) 1164 1165 print "\n// FloatImmediateOp" 1166 for float in ("2.0", "2.125", "4.0", "4.25", "8.0", "8.5", "16.0", "17.0", "0.125", 1167 "0.1328125", "0.25", "0.265625", "0.5", "0.53125", "1.0", "1.0625", 1168 "-2.0", "-2.125", "-4.0", "-4.25", "-8.0", "-8.5", "-16.0", "-17.0", 1169 "-0.125", "-0.1328125", "-0.25", "-0.265625", "-0.5", "-0.53125", "-1.0", "-1.0625"): 1170 astr = "fmov d0, #" + float 1171 cstr = "__ fmovd(v0, " + float + ");" 1172 print " %-50s //\t%s" % (cstr, astr) 1173 outfile.write("\t" + astr + "\n") 1174 1175 # ARMv8.1A 1176 for size in ("x", "w"): 1177 for suffix in ("", "a", "al", "l"): 1178 generate(LSEOp, [["swp", "swp", size, suffix], 1179 ["ldadd", "ldadd", size, suffix], 1180 ["ldbic", "ldclr", size, suffix], 1181 ["ldeor", "ldeor", size, suffix], 1182 ["ldorr", "ldset", size, suffix], 1183 ["ldsmin", "ldsmin", size, suffix], 1184 ["ldsmax", "ldsmax", size, suffix], 1185 ["ldumin", "ldumin", size, suffix], 1186 ["ldumax", "ldumax", size, suffix]]); 1187 1188 print "\n __ bind(forth);" 1189 outfile.write("forth:\n") 1190 1191 outfile.close() 1192 1193 import subprocess 1194 import sys 1195 1196 # compile for 8.1 and sha2 because of lse atomics and sha512 crypto extension. 1197 subprocess.check_call([AARCH64_AS, "-march=armv8.1-a+sha2", "aarch64ops.s", "-o", "aarch64ops.o"]) 1198 1199 print 1200 print "/*", 1201 sys.stdout.flush() 1202 subprocess.check_call([AARCH64_OBJDUMP, "-d", "aarch64ops.o"]) 1203 print "*/" 1204 1205 subprocess.check_call([AARCH64_OBJCOPY, "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"]) 1206 1207 infile = open("aarch64ops.bin", "r") 1208 bytes = bytearray(infile.read()) 1209 1210 print 1211 print " static const unsigned int insns[] =" 1212 print " {" 1213 1214 i = 0 1215 while i < len(bytes): 1216 print " 0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]), 1217 i += 4 1218 if i%16 == 0: 1219 print 1220 print "\n };" 1221 print "// END Generated code -- do not edit" 1222 1223