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", "sb",]) 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)