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