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