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