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