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