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