Path: blob/master/test/hotspot/gtest/aarch64/aarch64-asmtest.py
41145 views
import os1import random2import subprocess3import sys45AARCH64_AS = "as"6AARCH64_OBJDUMP = "objdump"7AARCH64_OBJCOPY = "objcopy"89class Operand(object):1011def generate(self):12return self1314class Register(Operand):1516def generate(self):17self.number = random.randint(0, 30)18if self.number == 18:19self.number = 1720return self2122def astr(self, prefix):23return prefix + str(self.number)2425class FloatRegister(Register):2627def __str__(self):28return self.astr("v")2930def nextReg(self):31next = FloatRegister()32next.number = (self.number + 1) % 3233return next3435class GeneralRegister(Register):3637def __str__(self):38return self.astr("r")3940class GeneralRegisterOrZr(Register):4142def generate(self):43self.number = random.randint(0, 31)44if self.number == 18:45self.number = 1646return self4748def astr(self, prefix = ""):49if (self.number == 31):50return prefix + "zr"51else:52return prefix + str(self.number)5354def __str__(self):55if (self.number == 31):56return self.astr()57else:58return self.astr("r")5960class GeneralRegisterOrSp(Register):61def generate(self):62self.number = random.randint(0, 31)63if self.number == 18:64self.number = 1565return self6667def astr(self, prefix = ""):68if (self.number == 31):69return "sp"70else:71return prefix + str(self.number)7273def __str__(self):74if (self.number == 31):75return self.astr()76else:77return self.astr("r")7879class SVEVectorRegister(FloatRegister):80def __str__(self):81return self.astr("z")8283class SVEPRegister(Register):84def __str__(self):85return self.astr("p")8687def generate(self):88self.number = random.randint(0, 15)89return self9091class SVEGoverningPRegister(Register):92def __str__(self):93return self.astr("p")94def generate(self):95self.number = random.randint(0, 7)96return self9798class RegVariant(object):99def __init__(self, low, high):100self.number = random.randint(low, high)101102def astr(self):103nameMap = {1040: ".b",1051: ".h",1062: ".s",1073: ".d",1084: ".q"109}110return nameMap.get(self.number)111112def cstr(self):113nameMap = {1140: "__ B",1151: "__ H",1162: "__ S",1173: "__ D",1184: "__ Q"119}120return nameMap.get(self.number)121122class FloatZero(Operand):123124def __str__(self):125return "0.0"126127def astr(self, ignored):128return "#0.0"129130class OperandFactory:131132_modes = {'x' : GeneralRegister,133'w' : GeneralRegister,134'b' : FloatRegister,135'h' : FloatRegister,136's' : FloatRegister,137'd' : FloatRegister,138'z' : FloatZero,139'p' : SVEPRegister,140'P' : SVEGoverningPRegister,141'Z' : SVEVectorRegister}142143@classmethod144def create(cls, mode):145return OperandFactory._modes[mode]()146147class ShiftKind:148149def generate(self):150self.kind = ["LSL", "LSR", "ASR"][random.randint(0,2)]151return self152153def cstr(self):154return self.kind155156class Instruction(object):157158def __init__(self, name):159self._name = name160self.isWord = name.endswith("w") | name.endswith("wi")161self.asmRegPrefix = ["x", "w"][self.isWord]162163def aname(self):164if (self._name.endswith("wi")):165return self._name[:len(self._name)-2]166else:167if (self._name.endswith("i") | self._name.endswith("w")):168return self._name[:len(self._name)-1]169else:170return self._name171172def emit(self) :173pass174175def compare(self) :176pass177178def generate(self) :179return self180181def cstr(self):182return '__ %s(' % self.name()183184def astr(self):185return '%s\t' % self.aname()186187def name(self):188name = self._name189if name == "and":190name = "andr" # Special case: the name "and" can't be used191# in HotSpot, even for a member.192return name193194def multipleForms(self):195return 0196197class InstructionWithModes(Instruction):198199def __init__(self, name, mode):200Instruction.__init__(self, name)201self.mode = mode202self.isFloat = (mode == 'd') | (mode == 's')203if self.isFloat:204self.isWord = mode != 'd'205self.asmRegPrefix = ["d", "s"][self.isWord]206else:207self.isWord = mode != 'x'208self.asmRegPrefix = ["x", "w"][self.isWord]209210def name(self):211return self._name + (self.mode if self.mode != 'x' else '')212213def aname(self):214return (self._name+mode if (mode == 'b' or mode == 'h')215else self._name)216217class ThreeRegInstruction(Instruction):218219def generate(self):220self.reg = [GeneralRegister().generate(), GeneralRegister().generate(),221GeneralRegister().generate()]222return self223224225def cstr(self):226return (super(ThreeRegInstruction, self).cstr()227+ ('%s, %s, %s'228% (self.reg[0],229self.reg[1], self.reg[2])))230231def astr(self):232prefix = self.asmRegPrefix233return (super(ThreeRegInstruction, self).astr()234+ ('%s, %s, %s'235% (self.reg[0].astr(prefix),236self.reg[1].astr(prefix), self.reg[2].astr(prefix))))237238class FourRegInstruction(ThreeRegInstruction):239240def generate(self):241self.reg = ThreeRegInstruction.generate(self).reg + [GeneralRegister().generate()]242return self243244245def cstr(self):246return (super(FourRegInstruction, self).cstr()247+ (', %s' % self.reg[3]))248249def astr(self):250prefix = self.asmRegPrefix251return (super(FourRegInstruction, self).astr()252+ (', %s' % self.reg[3].astr(prefix)))253254class TwoRegInstruction(Instruction):255256def generate(self):257self.reg = [GeneralRegister().generate(), GeneralRegister().generate()]258return self259260def cstr(self):261return (super(TwoRegInstruction, self).cstr()262+ '%s, %s' % (self.reg[0],263self.reg[1]))264265def astr(self):266prefix = self.asmRegPrefix267return (super(TwoRegInstruction, self).astr()268+ ('%s, %s'269% (self.reg[0].astr(prefix),270self.reg[1].astr(prefix))))271272class TwoRegImmedInstruction(TwoRegInstruction):273274def generate(self):275super(TwoRegImmedInstruction, self).generate()276self.immed = random.randint(0, 1<<11 -1)277return self278279def cstr(self):280return (super(TwoRegImmedInstruction, self).cstr()281+ ', %su' % self.immed)282283def astr(self):284return (super(TwoRegImmedInstruction, self).astr()285+ ', #%s' % self.immed)286287class OneRegOp(Instruction):288289def generate(self):290self.reg = GeneralRegister().generate()291return self292293def cstr(self):294return (super(OneRegOp, self).cstr()295+ '%s);' % self.reg)296297def astr(self):298return (super(OneRegOp, self).astr()299+ '%s' % self.reg.astr(self.asmRegPrefix))300301class ArithOp(ThreeRegInstruction):302303def generate(self):304super(ArithOp, self).generate()305self.kind = ShiftKind().generate()306self.distance = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)307return self308309def cstr(self):310return ('%s, Assembler::%s, %s);'311% (ThreeRegInstruction.cstr(self),312self.kind.cstr(), self.distance))313314def astr(self):315return ('%s, %s #%s'316% (ThreeRegInstruction.astr(self),317self.kind.cstr(),318self.distance))319320class AddSubCarryOp(ThreeRegInstruction):321322def cstr(self):323return ('%s);'324% (ThreeRegInstruction.cstr(self)))325326class AddSubExtendedOp(ThreeRegInstruction):327328uxtb, uxth, uxtw, uxtx, sxtb, sxth, sxtw, sxtx = range(8)329optNames = ["uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"]330331def generate(self):332super(AddSubExtendedOp, self).generate()333self.amount = random.randint(1, 4)334self.option = random.randint(0, 7)335return self336337def cstr(self):338return (super(AddSubExtendedOp, self).cstr()339+ (", ext::" + AddSubExtendedOp.optNames[self.option]340+ ", " + str(self.amount) + ");"))341342def astr(self):343return (super(AddSubExtendedOp, self).astr()344+ (", " + AddSubExtendedOp.optNames[self.option]345+ " #" + str(self.amount)))346347class AddSubImmOp(TwoRegImmedInstruction):348349def cstr(self):350return super(AddSubImmOp, self).cstr() + ");"351352class LogicalImmOp(AddSubImmOp):353354# These tables are legal immediate logical operands355immediates32 \356= [0x1, 0x3f, 0x1f0, 0x7e0,3570x1c00, 0x3ff0, 0x8000, 0x1e000,3580x3e000, 0x78000, 0xe0000, 0x100000,3590x1fffe0, 0x3fe000, 0x780000, 0x7ffff8,3600xff8000, 0x1800180, 0x1fffc00, 0x3c003c0,3610x3ffff00, 0x7c00000, 0x7fffe00, 0xf000f00,3620xfffe000, 0x18181818, 0x1ffc0000, 0x1ffffffe,3630x3f003f00, 0x3fffe000, 0x60006000, 0x7f807f80,3640x7ffffc00, 0x800001ff, 0x803fffff, 0x9f9f9f9f,3650xc0000fff, 0xc0c0c0c0, 0xe0000000, 0xe003e003,3660xe3ffffff, 0xf0000fff, 0xf0f0f0f0, 0xf80000ff,3670xf83ff83f, 0xfc00007f, 0xfc1fffff, 0xfe0001ff,3680xfe3fffff, 0xff003fff, 0xff800003, 0xff87ff87,3690xffc00fff, 0xffe0000f, 0xffefffef, 0xfff1fff1,3700xfff83fff, 0xfffc0fff, 0xfffe0fff, 0xffff3fff,3710xffffc007, 0xffffe1ff, 0xfffff80f, 0xfffffe07,3720xffffffbf, 0xfffffffd]373374immediates \375= [0x1, 0x1f80, 0x3fff0, 0x3ffffc,3760x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000,3770xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000,3780x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000,3790x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000,3800x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000,3810x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8,3820x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000,3830x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff,3840xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003,3850xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff,3860xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000,3870xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f,3880xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff,3890xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff,3900xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f]391392def generate(self):393AddSubImmOp.generate(self)394self.immed = \395self.immediates32[random.randint(0, len(self.immediates32)-1)] \396if self.isWord else \397self.immediates[random.randint(0, len(self.immediates)-1)]398399return self400401def astr(self):402return (super(TwoRegImmedInstruction, self).astr()403+ ', #0x%x' % self.immed)404405def cstr(self):406return super(AddSubImmOp, self).cstr() + "ll);"407408class MultiOp():409410def multipleForms(self):411return 3412413def forms(self):414return ["__ pc()", "back", "forth"]415416def aforms(self):417return [".", "back", "forth"]418419class AbsOp(MultiOp, Instruction):420421def cstr(self):422return super(AbsOp, self).cstr() + "%s);"423424def astr(self):425return Instruction.astr(self) + "%s"426427class RegAndAbsOp(MultiOp, Instruction):428429def multipleForms(self):430if self.name() == "adrp":431# We can only test one form of adrp because anything other432# than "adrp ." requires relocs in the assembler output433return 1434return 3435436def generate(self):437Instruction.generate(self)438self.reg = GeneralRegister().generate()439return self440441def cstr(self):442if self.name() == "adrp":443return "__ _adrp(" + "%s, %s);" % (self.reg, "%s")444return (super(RegAndAbsOp, self).cstr()445+ "%s, %s);" % (self.reg, "%s"))446447def astr(self):448return (super(RegAndAbsOp, self).astr()449+ self.reg.astr(self.asmRegPrefix) + ", %s")450451class RegImmAbsOp(RegAndAbsOp):452453def cstr(self):454return (Instruction.cstr(self)455+ "%s, %s, %s);" % (self.reg, self.immed, "%s"))456457def astr(self):458return (Instruction.astr(self)459+ ("%s, #%s, %s"460% (self.reg.astr(self.asmRegPrefix), self.immed, "%s")))461462def generate(self):463super(RegImmAbsOp, self).generate()464self.immed = random.randint(0, 1<<5 -1)465return self466467class MoveWideImmOp(RegImmAbsOp):468469def multipleForms(self):470return 0471472def cstr(self):473return (Instruction.cstr(self)474+ "%s, %s, %s);" % (self.reg, self.immed, self.shift))475476def astr(self):477return (Instruction.astr(self)478+ ("%s, #%s, lsl %s"479% (self.reg.astr(self.asmRegPrefix),480self.immed, self.shift)))481482def generate(self):483super(RegImmAbsOp, self).generate()484self.immed = random.randint(0, 1<<16 -1)485if self.isWord:486self.shift = random.randint(0, 1) * 16487else:488self.shift = random.randint(0, 3) * 16489return self490491class BitfieldOp(TwoRegInstruction):492493def cstr(self):494return (Instruction.cstr(self)495+ ("%s, %s, %s, %s);"496% (self.reg[0], self.reg[1], self.immr, self.imms)))497498def astr(self):499return (TwoRegInstruction.astr(self)500+ (", #%s, #%s"501% (self.immr, self.imms)))502503def generate(self):504TwoRegInstruction.generate(self)505self.immr = random.randint(0, 31)506self.imms = random.randint(0, 31)507return self508509class ExtractOp(ThreeRegInstruction):510511def generate(self):512super(ExtractOp, self).generate()513self.lsb = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)514return self515516def cstr(self):517return (ThreeRegInstruction.cstr(self)518+ (", %s);" % self.lsb))519520def astr(self):521return (ThreeRegInstruction.astr(self)522+ (", #%s" % self.lsb))523524class CondBranchOp(MultiOp, Instruction):525526def cstr(self):527return "__ br(Assembler::" + self.name() + ", %s);"528529def astr(self):530return "b." + self.name() + "\t%s"531532class ImmOp(Instruction):533534def cstr(self):535return "%s%s);" % (Instruction.cstr(self), self.immed)536537def astr(self):538return Instruction.astr(self) + "#" + str(self.immed)539540def generate(self):541self.immed = random.randint(0, 1<<16 -1)542return self543544class Op(Instruction):545546def cstr(self):547return Instruction.cstr(self) + ");"548def astr(self):549return self.aname();550551class SystemOp(Instruction):552553def __init__(self, op):554Instruction.__init__(self, op[0])555self.barriers = op[1]556557def generate(self):558Instruction.generate(self)559self.barrier \560= self.barriers[random.randint(0, len(self.barriers)-1)]561return self562563def cstr(self):564return Instruction.cstr(self) + "Assembler::" + self.barrier + ");"565566def astr(self):567return Instruction.astr(self) + self.barrier568569conditionCodes = ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", \570"VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV"]571572class ConditionalCompareOp(TwoRegImmedInstruction):573574def generate(self):575TwoRegImmedInstruction.generate(self)576self.cond = random.randint(0, 15)577self.immed = random.randint(0, 15)578return self579580def cstr(self):581return (super(ConditionalCompareOp, self).cstr() + ", "582+ "Assembler::" + conditionCodes[self.cond] + ");")583584def astr(self):585return (super(ConditionalCompareOp, self).astr() +586", " + conditionCodes[self.cond])587588class ConditionalCompareImmedOp(Instruction):589590def generate(self):591self.reg = GeneralRegister().generate()592self.cond = random.randint(0, 15)593self.immed2 = random.randint(0, 15)594self.immed = random.randint(0, 31)595return self596597def cstr(self):598return (Instruction.cstr(self) + str(self.reg) + ", "599+ str(self.immed) + ", "600+ str(self.immed2) + ", "601+ "Assembler::" + conditionCodes[self.cond] + ");")602603def astr(self):604return (Instruction.astr(self)605+ self.reg.astr(self.asmRegPrefix)606+ ", #" + str(self.immed)607+ ", #" + str(self.immed2)608+ ", " + conditionCodes[self.cond])609610class TwoRegOp(TwoRegInstruction):611612def cstr(self):613return TwoRegInstruction.cstr(self) + ");"614615class ThreeRegOp(ThreeRegInstruction):616617def cstr(self):618return ThreeRegInstruction.cstr(self) + ");"619620class FourRegMulOp(FourRegInstruction):621622def cstr(self):623return FourRegInstruction.cstr(self) + ");"624625def astr(self):626isMaddsub = self.name().startswith("madd") | self.name().startswith("msub")627midPrefix = self.asmRegPrefix if isMaddsub else "w"628return (Instruction.astr(self)629+ self.reg[0].astr(self.asmRegPrefix)630+ ", " + self.reg[1].astr(midPrefix)631+ ", " + self.reg[2].astr(midPrefix)632+ ", " + self.reg[3].astr(self.asmRegPrefix))633634class ConditionalSelectOp(ThreeRegInstruction):635636def generate(self):637ThreeRegInstruction.generate(self)638self.cond = random.randint(0, 15)639return self640641def cstr(self):642return (ThreeRegInstruction.cstr(self) + ", "643+ "Assembler::" + conditionCodes[self.cond] + ");")644645def astr(self):646return (ThreeRegInstruction.astr(self)647+ ", " + conditionCodes[self.cond])648649class LoadStoreExclusiveOp(InstructionWithModes):650651def __init__(self, op): # op is a tuple of ["name", "mode", registers]652InstructionWithModes.__init__(self, op[0], op[1])653self.num_registers = op[2]654655def astr(self):656result = self.aname() + '\t'657regs = list(self.regs)658index = regs.pop() # The last reg is the index register659prefix = ('x' if (self.mode == 'x')660& ((self.name().startswith("ld"))661| (self.name().startswith("stlr"))) # Ewww :-(662else 'w')663result = result + regs.pop(0).astr(prefix) + ", "664for s in regs:665result = result + s.astr(self.asmRegPrefix) + ", "666result = result + "[" + index.astr("x") + "]"667return result668669def cstr(self):670result = InstructionWithModes.cstr(self)671regs = list(self.regs)672index = regs.pop() # The last reg is the index register673for s in regs:674result = result + str(s) + ", "675result = result + str(index) + ");"676return result677678def appendUniqueReg(self):679result = 0680while result == 0:681newReg = GeneralRegister().generate()682result = 1683for i in self.regs:684result = result and (i.number != newReg.number)685self.regs.append(newReg)686687def generate(self):688self.regs = []689for i in range(self.num_registers):690self.appendUniqueReg()691return self692693def name(self):694if self.mode == 'x':695return self._name696else:697return self._name + self.mode698699def aname(self):700if (self.mode == 'b') | (self.mode == 'h'):701return self._name + self.mode702else:703return self._name704705class Address(object):706707base_plus_unscaled_offset, pre, post, base_plus_reg, \708base_plus_scaled_offset, pcrel, post_reg, base_only = range(8)709kinds = ["base_plus_unscaled_offset", "pre", "post", "base_plus_reg",710"base_plus_scaled_offset", "pcrel", "post_reg", "base_only"]711extend_kinds = ["uxtw", "lsl", "sxtw", "sxtx"]712713@classmethod714def kindToStr(cls, i):715return cls.kinds[i]716717def generate(self, kind, shift_distance):718self.kind = kind719self.base = GeneralRegister().generate()720self.index = GeneralRegister().generate()721self.offset = {722Address.base_plus_unscaled_offset: random.randint(-1<<8, 1<<8-1) | 1,723Address.pre: random.randint(-1<<8, 1<<8-1),724Address.post: random.randint(-1<<8, 1<<8-1),725Address.pcrel: random.randint(0, 2),726Address.base_plus_reg: 0,727Address.base_plus_scaled_offset: (random.randint(0, 1<<11-1) | (3 << 9))*8,728Address.post_reg: 0,729Address.base_only: 0} [kind]730self.offset >>= (3 - shift_distance)731self.extend_kind = Address.extend_kinds[random.randint(0, 3)]732self.shift_distance = random.randint(0, 1) * shift_distance733return self734735def __str__(self):736result = {737Address.base_plus_unscaled_offset: "Address(%s, %s)" \738% (str(self.base), self.offset),739Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset),740Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset),741Address.post_reg: "Address(__ post(%s, %s))" % (str(self.base), self.index),742Address.base_only: "Address(%s)" % (str(self.base)),743Address.pcrel: "",744Address.base_plus_reg: "Address(%s, %s, Address::%s(%s))" \745% (self.base, self.index, self.extend_kind, self.shift_distance),746Address.base_plus_scaled_offset:747"Address(%s, %s)" % (self.base, self.offset) } [self.kind]748if (self.kind == Address.pcrel):749result = ["__ pc()", "back", "forth"][self.offset]750return result751752def astr(self, prefix):753extend_prefix = prefix754if self.kind == Address.base_plus_reg:755if self.extend_kind.endswith("w"):756extend_prefix = "w"757result = {758Address.base_plus_unscaled_offset: "[%s, %s]" \759% (self.base.astr(prefix), self.offset),760Address.pre: "[%s, %s]!" % (self.base.astr(prefix), self.offset),761Address.post: "[%s], %s" % (self.base.astr(prefix), self.offset),762Address.post_reg: "[%s], %s" % (self.base.astr(prefix), self.index.astr(prefix)),763Address.base_only: "[%s]" % (self.base.astr(prefix)),764Address.pcrel: "",765Address.base_plus_reg: "[%s, %s, %s #%s]" \766% (self.base.astr(prefix), self.index.astr(extend_prefix),767self.extend_kind, self.shift_distance),768Address.base_plus_scaled_offset: \769"[%s, %s]" \770% (self.base.astr(prefix), self.offset)771} [self.kind]772if (self.kind == Address.pcrel):773result = [".", "back", "forth"][self.offset]774return result775776class LoadStoreOp(InstructionWithModes):777778def __init__(self, args):779name, self.asmname, self.kind, mode = args780InstructionWithModes.__init__(self, name, mode)781782def generate(self):783784# This is something of a kludge, but the offset needs to be785# scaled by the memory datamode somehow.786shift = 3787if (self.mode == 'b') | (self.asmname.endswith("b")):788shift = 0789elif (self.mode == 'h') | (self.asmname.endswith("h")):790shift = 1791elif (self.mode == 'w') | (self.asmname.endswith("w")) \792| (self.mode == 's') :793shift = 2794795self.adr = Address().generate(self.kind, shift)796797isFloat = (self.mode == 'd') | (self.mode == 's')798799regMode = FloatRegister if isFloat else GeneralRegister800self.reg = regMode().generate()801kindStr = Address.kindToStr(self.kind);802if (not isFloat) and (kindStr is "pre" or kindStr is "post"):803(self.reg.number, self.adr.base.number) = random.sample(list(set(range(31)) - set([18])), 2)804return self805806def cstr(self):807if not(self._name.startswith("prfm")):808return "%s%s, %s);" % (Instruction.cstr(self), str(self.reg), str(self.adr))809else: # No target register for a prefetch810return "%s%s);" % (Instruction.cstr(self), str(self.adr))811812def astr(self):813if not(self._name.startswith("prfm")):814return "%s\t%s, %s" % (self.aname(), self.reg.astr(self.asmRegPrefix),815self.adr.astr("x"))816else: # No target register for a prefetch817return "%s %s" % (self.aname(),818self.adr.astr("x"))819820def aname(self):821result = self.asmname822# if self.kind == Address.base_plus_unscaled_offset:823# result = result.replace("ld", "ldu", 1)824# result = result.replace("st", "stu", 1)825return result826827class LoadStorePairOp(InstructionWithModes):828829numRegs = 2830831def __init__(self, args):832name, self.asmname, self.kind, mode = args833InstructionWithModes.__init__(self, name, mode)834self.offset = random.randint(-1<<4, 1<<4-1) << 4835836def generate(self):837self.reg = [OperandFactory.create(self.mode).generate()838for i in range(self.numRegs)]839self.base = OperandFactory.create('x').generate()840kindStr = Address.kindToStr(self.kind);841if kindStr is "pre" or kindStr is "post":842if self._name.startswith("ld"):843(self.reg[0].number, self.reg[1].number, self.base.number) = random.sample(list(set(range(31)) - set([18])), 3)844if self._name.startswith("st"):845self.base.number = random.choice(list(set(range(31)) - set([self.reg[0].number, self.reg[1].number, 18])))846elif self._name.startswith("ld"):847(self.reg[0].number, self.reg[1].number) = random.sample(list(set(range(31)) - set([18])), 2)848return self849850def astr(self):851address = ["[%s, #%s]", "[%s, #%s]!", "[%s], #%s"][self.kind]852address = address % (self.base.astr('x'), self.offset)853result = "%s\t%s, %s, %s" \854% (self.asmname,855self.reg[0].astr(self.asmRegPrefix),856self.reg[1].astr(self.asmRegPrefix), address)857return result858859def cstr(self):860address = {861Address.base_plus_unscaled_offset: "Address(%s, %s)" \862% (str(self.base), self.offset),863Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset),864Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset),865} [self.kind]866result = "__ %s(%s, %s, %s);" \867% (self.name(), self.reg[0], self.reg[1], address)868return result869870class FloatInstruction(Instruction):871872def aname(self):873if (self._name.endswith("s") | self._name.endswith("d")):874return self._name[:len(self._name)-1]875else:876return self._name877878def __init__(self, args):879name, self.modes = args880Instruction.__init__(self, name)881882def generate(self):883self.reg = [OperandFactory.create(self.modes[i]).generate()884for i in range(self.numRegs)]885return self886887def cstr(self):888formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])889return (formatStr890% tuple([Instruction.cstr(self)] +891[str(self.reg[i]) for i in range(self.numRegs)])) # Yowza892893def astr(self):894formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])895return (formatStr896% tuple([Instruction.astr(self)] +897[(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)]))898899class SVEVectorOp(Instruction):900def __init__(self, args):901name = args[0]902regTypes = args[1]903regs = []904for c in regTypes:905regs.append(OperandFactory.create(c).generate())906self.reg = regs907self.numRegs = len(regs)908if regTypes[0] != "p" and regTypes[1] == 'P':909self._isPredicated = True910self._merge = "/m"911else:912self._isPredicated = False913self._merge =""914915self._bitwiseop = False916if name[0] == 'f':917self._width = RegVariant(2, 3)918elif not self._isPredicated and (name in ["and", "eor", "orr", "bic"]):919self._width = RegVariant(3, 3)920self._bitwiseop = True921else:922self._width = RegVariant(0, 3)923if len(args) > 2:924self._dnm = args[2]925else:926self._dnm = None927Instruction.__init__(self, name)928929def cstr(self):930formatStr = "%s%s" + ''.join([", %s" for i in range(0, self.numRegs)] + [");"])931if self._bitwiseop:932width = []933formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])934else:935width = [self._width.cstr()]936return (formatStr937% tuple(["__ sve_" + self._name + "("] +938[str(self.reg[0])] +939width +940[str(self.reg[i]) for i in range(1, self.numRegs)]))941def astr(self):942formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])943if self._dnm == 'dn':944formatStr += ", %s"945dnReg = [str(self.reg[0]) + self._width.astr()]946else:947dnReg = []948949if self._isPredicated:950restRegs = [str(self.reg[1]) + self._merge] + dnReg + [str(self.reg[i]) + self._width.astr() for i in range(2, self.numRegs)]951else:952restRegs = dnReg + [str(self.reg[i]) + self._width.astr() for i in range(1, self.numRegs)]953return (formatStr954% tuple([Instruction.astr(self)] +955[str(self.reg[0]) + self._width.astr()] +956restRegs))957def generate(self):958return self959960class SVEReductionOp(Instruction):961def __init__(self, args):962name = args[0]963lowRegType = args[1]964self.reg = []965Instruction.__init__(self, name)966self.reg.append(OperandFactory.create('s').generate())967self.reg.append(OperandFactory.create('P').generate())968self.reg.append(OperandFactory.create('Z').generate())969self._width = RegVariant(lowRegType, 3)970def cstr(self):971return "__ sve_%s(%s, %s, %s, %s);" % (self.name(),972str(self.reg[0]),973self._width.cstr(),974str(self.reg[1]),975str(self.reg[2]))976def astr(self):977if self.name() == "uaddv":978dstRegName = "d" + str(self.reg[0].number)979else:980dstRegName = self._width.astr()[1] + str(self.reg[0].number)981formatStr = "%s %s, %s, %s"982if self.name() == "fadda":983formatStr += ", %s"984moreReg = [dstRegName]985else:986moreReg = []987return formatStr % tuple([self.name()] +988[dstRegName] +989[str(self.reg[1])] +990moreReg +991[str(self.reg[2]) + self._width.astr()])992993class LdStNEONOp(Instruction):994def __init__(self, args):995self._name, self.regnum, self.arrangement, self.addresskind = args996997def generate(self):998self.address = Address().generate(self.addresskind, 0)999self._firstSIMDreg = FloatRegister().generate()1000if (self.addresskind == Address.post):1001if (self._name in ["ld1r", "ld2r", "ld3r", "ld4r"]):1002elem_size = {"8B" : 1, "16B" : 1, "4H" : 2, "8H" : 2, "2S" : 4, "4S" : 4, "1D" : 8, "2D" : 8} [self.arrangement]1003self.address.offset = self.regnum * elem_size1004else:1005if (self.arrangement in ["8B", "4H", "2S", "1D"]):1006self.address.offset = self.regnum * 81007else:1008self.address.offset = self.regnum * 161009return self10101011def cstr(self):1012buf = super(LdStNEONOp, self).cstr() + str(self._firstSIMDreg)1013current = self._firstSIMDreg1014for cnt in range(1, self.regnum):1015buf = '%s, %s' % (buf, current.nextReg())1016current = current.nextReg()1017return '%s, __ T%s, %s);' % (buf, self.arrangement, str(self.address))10181019def astr(self):1020buf = '%s\t{%s.%s' % (self._name, self._firstSIMDreg, self.arrangement)1021current = self._firstSIMDreg1022for cnt in range(1, self.regnum):1023buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)1024current = current.nextReg()1025return '%s}, %s' % (buf, self.address.astr("x"))10261027def aname(self):1028return self._name10291030class NEONReduceInstruction(Instruction):1031def __init__(self, args):1032self._name, self.insname, self.arrangement = args10331034def generate(self):1035current = FloatRegister().generate()1036self.dstSIMDreg = current1037self.srcSIMDreg = current.nextReg()1038return self10391040def cstr(self):1041buf = Instruction.cstr(self) + str(self.dstSIMDreg)1042if self._name == "fmaxp" or self._name == "fminp":1043buf = '%s, %s, __ %s);' % (buf, self.srcSIMDreg, self.arrangement[1:])1044else:1045buf = '%s, __ T%s, %s);' % (buf, self.arrangement, self.srcSIMDreg)1046return buf10471048def astr(self):1049buf = '%s\t%s' % (self.insname, self.dstSIMDreg.astr(self.arrangement[-1].lower()))1050buf = '%s, %s.%s' % (buf, self.srcSIMDreg, self.arrangement)1051return buf10521053def aname(self):1054return self._name10551056class CommonNEONInstruction(Instruction):1057def __init__(self, args):1058self._name, self.insname, self.arrangement = args10591060def generate(self):1061self._firstSIMDreg = FloatRegister().generate()1062return self10631064def cstr(self):1065buf = Instruction.cstr(self) + str(self._firstSIMDreg)1066buf = '%s, __ T%s' % (buf, self.arrangement)1067current = self._firstSIMDreg1068for cnt in range(1, self.numRegs):1069buf = '%s, %s' % (buf, current.nextReg())1070current = current.nextReg()1071return '%s);' % (buf)10721073def astr(self):1074buf = '%s\t%s.%s' % (self.insname, self._firstSIMDreg, self.arrangement)1075current = self._firstSIMDreg1076for cnt in range(1, self.numRegs):1077buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)1078current = current.nextReg()1079return buf10801081def aname(self):1082return self._name10831084class SHA512SIMDOp(Instruction):10851086def generate(self):1087if (self._name == 'sha512su0'):1088self.reg = [FloatRegister().generate(), FloatRegister().generate()]1089else:1090self.reg = [FloatRegister().generate(), FloatRegister().generate(),1091FloatRegister().generate()]1092return self10931094def cstr(self):1095if (self._name == 'sha512su0'):1096return (super(SHA512SIMDOp, self).cstr()1097+ ('%s, __ T2D, %s);' % (self.reg[0], self.reg[1])))1098else:1099return (super(SHA512SIMDOp, self).cstr()1100+ ('%s, __ T2D, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2])))11011102def astr(self):1103if (self._name == 'sha512su0'):1104return (super(SHA512SIMDOp, self).astr()1105+ ('\t%s.2D, %s.2D' % (self.reg[0].astr("v"), self.reg[1].astr("v"))))1106elif (self._name == 'sha512su1'):1107return (super(SHA512SIMDOp, self).astr()1108+ ('\t%s.2D, %s.2D, %s.2D' % (self.reg[0].astr("v"),1109self.reg[1].astr("v"), self.reg[2].astr("v"))))1110else:1111return (super(SHA512SIMDOp, self).astr()1112+ ('\t%s, %s, %s.2D' % (self.reg[0].astr("q"),1113self.reg[1].astr("q"), self.reg[2].astr("v"))))11141115class SHA3SIMDOp(Instruction):11161117def generate(self):1118if ((self._name == 'eor3') or (self._name == 'bcax')):1119self.reg = [FloatRegister().generate(), FloatRegister().generate(),1120FloatRegister().generate(), FloatRegister().generate()]1121else:1122self.reg = [FloatRegister().generate(), FloatRegister().generate(),1123FloatRegister().generate()]1124if (self._name == 'xar'):1125self.imm6 = random.randint(0, 63)1126return self11271128def cstr(self):1129if ((self._name == 'eor3') or (self._name == 'bcax')):1130return (super(SHA3SIMDOp, self).cstr()1131+ ('%s, __ T16B, %s, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2], self.reg[3])))1132elif (self._name == 'rax1'):1133return (super(SHA3SIMDOp, self).cstr()1134+ ('%s, __ T2D, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2])))1135else:1136return (super(SHA3SIMDOp, self).cstr()1137+ ('%s, __ T2D, %s, %s, %s);' % (self.reg[0], self.reg[1], self.reg[2], self.imm6)))11381139def astr(self):1140if ((self._name == 'eor3') or (self._name == 'bcax')):1141return (super(SHA3SIMDOp, self).astr()1142+ ('\t%s.16B, %s.16B, %s.16B, %s.16B' % (self.reg[0].astr("v"), self.reg[1].astr("v"),1143self.reg[2].astr("v"), self.reg[3].astr("v"))))1144elif (self._name == 'rax1'):1145return (super(SHA3SIMDOp, self).astr()1146+ ('\t%s.2D, %s.2D, %s.2D') % (self.reg[0].astr("v"), self.reg[1].astr("v"),1147self.reg[2].astr("v")))1148else:1149return (super(SHA3SIMDOp, self).astr()1150+ ('\t%s.2D, %s.2D, %s.2D, #%s') % (self.reg[0].astr("v"), self.reg[1].astr("v"),1151self.reg[2].astr("v"), self.imm6))11521153class LSEOp(Instruction):1154def __init__(self, args):1155self._name, self.asmname, self.size, self.suffix = args11561157def generate(self):1158self._name = "%s%s" % (self._name, self.suffix)1159self.asmname = "%s%s" % (self.asmname, self.suffix)1160self.srcReg = GeneralRegisterOrZr().generate()1161self.tgtReg = GeneralRegisterOrZr().generate()1162self.adrReg = GeneralRegisterOrSp().generate()11631164return self11651166def cstr(self):1167sizeSpec = {"x" : "Assembler::xword", "w" : "Assembler::word"} [self.size]1168return super(LSEOp, self).cstr() + "%s, %s, %s, %s);" % (sizeSpec, self.srcReg, self.tgtReg, self.adrReg)11691170def astr(self):1171return "%s\t%s, %s, [%s]" % (self.asmname, self.srcReg.astr(self.size), self.tgtReg.astr(self.size), self.adrReg.astr("x"))11721173def aname(self):1174return self.asmname11751176class TwoRegFloatOp(FloatInstruction):1177numRegs = 211781179class ThreeRegFloatOp(TwoRegFloatOp):1180numRegs = 311811182class FourRegFloatOp(TwoRegFloatOp):1183numRegs = 411841185class FloatConvertOp(TwoRegFloatOp):11861187def __init__(self, args):1188self._cname, self._aname, modes = args1189TwoRegFloatOp.__init__(self, [self._cname, modes])11901191def aname(self):1192return self._aname11931194def cname(self):1195return self._cname11961197class TwoRegNEONOp(CommonNEONInstruction):1198numRegs = 211991200class ThreeRegNEONOp(TwoRegNEONOp):1201numRegs = 312021203class SpecialCases(Instruction):1204def __init__(self, data):1205self._name = data[0]1206self._cstr = data[1]1207self._astr = data[2]12081209def cstr(self):1210return self._cstr12111212def astr(self):1213return self._astr12141215def generate(kind, names):1216outfile.write("# " + kind.__name__ + "\n");1217print "\n// " + kind.__name__1218for name in names:1219for i in range(1):1220op = kind(name).generate()1221if op.multipleForms():1222forms = op.forms()1223aforms = op.aforms()1224for i in range(op.multipleForms()):1225cstr = op.cstr() % forms[i]1226astr = op.astr() % aforms[i]1227print " %-50s //\t%s" % (cstr, astr)1228outfile.write("\t" + astr + "\n")1229else:1230print " %-50s //\t%s" % (op.cstr(), op.astr())1231outfile.write("\t" + op.astr() + "\n")12321233outfile = open("aarch64ops.s", "w")12341235# To minimize the changes of assembler test code1236random.seed(0)12371238print "// BEGIN Generated code -- do not edit"1239print "// Generated by aarch64-asmtest.py"12401241print " Label back, forth;"1242print " __ bind(back);"12431244outfile.write("back:\n")12451246generate (ArithOp,1247[ "add", "sub", "adds", "subs",1248"addw", "subw", "addsw", "subsw",1249"and", "orr", "eor", "ands",1250"andw", "orrw", "eorw", "andsw",1251"bic", "orn", "eon", "bics",1252"bicw", "ornw", "eonw", "bicsw" ])12531254generate (AddSubImmOp,1255[ "addw", "addsw", "subw", "subsw",1256"add", "adds", "sub", "subs"])1257generate (LogicalImmOp,1258[ "andw", "orrw", "eorw", "andsw",1259"and", "orr", "eor", "ands"])12601261generate (AbsOp, [ "b", "bl" ])12621263generate (RegAndAbsOp, ["cbzw", "cbnzw", "cbz", "cbnz", "adr", "adrp"])12641265generate (RegImmAbsOp, ["tbz", "tbnz"])12661267generate (MoveWideImmOp, ["movnw", "movzw", "movkw", "movn", "movz", "movk"])12681269generate (BitfieldOp, ["sbfm", "bfmw", "ubfmw", "sbfm", "bfm", "ubfm"])12701271generate (ExtractOp, ["extrw", "extr"])12721273generate (CondBranchOp, ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", "VC",1274"HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV" ])12751276generate (ImmOp, ["svc", "hvc", "smc", "brk", "hlt", # "dcps1", "dcps2", "dcps3"1277])12781279generate (Op, ["nop", "eret", "drps", "isb"])12801281barriers = ["OSHLD", "OSHST", "OSH", "NSHLD", "NSHST", "NSH",1282"ISHLD", "ISHST", "ISH", "LD", "ST", "SY"]12831284generate (SystemOp, [["dsb", barriers], ["dmb", barriers]])12851286generate (OneRegOp, ["br", "blr"])12871288for mode in 'xwhb':1289generate (LoadStoreExclusiveOp, [["stxr", mode, 3], ["stlxr", mode, 3],1290["ldxr", mode, 2], ["ldaxr", mode, 2],1291["stlr", mode, 2], ["ldar", mode, 2]])12921293for mode in 'xw':1294generate (LoadStoreExclusiveOp, [["ldxp", mode, 3], ["ldaxp", mode, 3],1295["stxp", mode, 4], ["stlxp", mode, 4]])12961297for kind in range(6):1298sys.stdout.write("\n// " + Address.kindToStr(kind))1299if kind != Address.pcrel:1300generate (LoadStoreOp,1301[["str", "str", kind, "x"], ["str", "str", kind, "w"],1302["str", "strb", kind, "b"], ["str", "strh", kind, "h"],1303["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"],1304["ldr", "ldrb", kind, "b"], ["ldr", "ldrh", kind, "h"],1305["ldrsb", "ldrsb", kind, "x"], ["ldrsh", "ldrsh", kind, "x"],1306["ldrsh", "ldrsh", kind, "w"], ["ldrsw", "ldrsw", kind, "x"],1307["ldr", "ldr", kind, "d"], ["ldr", "ldr", kind, "s"],1308["str", "str", kind, "d"], ["str", "str", kind, "s"],1309])1310else:1311generate (LoadStoreOp,1312[["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"]])131313141315for kind in (Address.base_plus_unscaled_offset, Address.pcrel, Address.base_plus_reg, \1316Address.base_plus_scaled_offset):1317generate (LoadStoreOp,1318[["prfm", "prfm\tPLDL1KEEP,", kind, "x"]])13191320generate(AddSubCarryOp, ["adcw", "adcsw", "sbcw", "sbcsw", "adc", "adcs", "sbc", "sbcs"])13211322generate(AddSubExtendedOp, ["addw", "addsw", "sub", "subsw", "add", "adds", "sub", "subs"])13231324generate(ConditionalCompareOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])1325generate(ConditionalCompareImmedOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])1326generate(ConditionalSelectOp,1327["cselw", "csincw", "csinvw", "csnegw", "csel", "csinc", "csinv", "csneg"])13281329generate(TwoRegOp,1330["rbitw", "rev16w", "revw", "clzw", "clsw", "rbit",1331"rev16", "rev32", "rev", "clz", "cls"])1332generate(ThreeRegOp,1333["udivw", "sdivw", "lslvw", "lsrvw", "asrvw", "rorvw", "udiv", "sdiv",1334"lslv", "lsrv", "asrv", "rorv", "umulh", "smulh"])1335generate(FourRegMulOp,1336["maddw", "msubw", "madd", "msub", "smaddl", "smsubl", "umaddl", "umsubl"])13371338generate(ThreeRegFloatOp,1339[["fabds", "sss"], ["fmuls", "sss"], ["fdivs", "sss"], ["fadds", "sss"], ["fsubs", "sss"],1340["fabdd", "ddd"], ["fmuld", "ddd"], ["fdivd", "ddd"], ["faddd", "ddd"], ["fsubd", "ddd"],1341])13421343generate(FourRegFloatOp,1344[["fmadds", "ssss"], ["fmsubs", "ssss"], ["fnmadds", "ssss"], ["fnmadds", "ssss"],1345["fmaddd", "dddd"], ["fmsubd", "dddd"], ["fnmaddd", "dddd"], ["fnmaddd", "dddd"],])13461347generate(TwoRegFloatOp,1348[["fmovs", "ss"], ["fabss", "ss"], ["fnegs", "ss"], ["fsqrts", "ss"],1349["fcvts", "ds"],1350["fmovd", "dd"], ["fabsd", "dd"], ["fnegd", "dd"], ["fsqrtd", "dd"],1351["fcvtd", "sd"],1352])13531354generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"],1355["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"],1356["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"],1357["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"],1358["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"],1359["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]])13601361generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"],1362["fcmps", "sz"], ["fcmpd", "dz"]])13631364for kind in range(3):1365generate(LoadStorePairOp, [["stp", "stp", kind, "w"], ["ldp", "ldp", kind, "w"],1366["ldpsw", "ldpsw", kind, "x"],1367["stp", "stp", kind, "x"], ["ldp", "ldp", kind, "x"]1368])1369generate(LoadStorePairOp, [["stnp", "stnp", 0, "w"], ["ldnp", "ldnp", 0, "w"],1370["stnp", "stnp", 0, "x"], ["ldnp", "ldnp", 0, "x"]])13711372generate(LdStNEONOp, [["ld1", 1, "8B", Address.base_only],1373["ld1", 2, "16B", Address.post],1374["ld1", 3, "1D", Address.post_reg],1375["ld1", 4, "8H", Address.post],1376["ld1r", 1, "8B", Address.base_only],1377["ld1r", 1, "4S", Address.post],1378["ld1r", 1, "1D", Address.post_reg],1379["ld2", 2, "2D", Address.base_only],1380["ld2", 2, "4H", Address.post],1381["ld2r", 2, "16B", Address.base_only],1382["ld2r", 2, "2S", Address.post],1383["ld2r", 2, "2D", Address.post_reg],1384["ld3", 3, "4S", Address.post_reg],1385["ld3", 3, "2S", Address.base_only],1386["ld3r", 3, "8H", Address.base_only],1387["ld3r", 3, "4S", Address.post],1388["ld3r", 3, "1D", Address.post_reg],1389["ld4", 4, "8H", Address.post],1390["ld4", 4, "8B", Address.post_reg],1391["ld4r", 4, "8B", Address.base_only],1392["ld4r", 4, "4H", Address.post],1393["ld4r", 4, "2S", Address.post_reg],1394])13951396generate(NEONReduceInstruction,1397[["addv", "addv", "8B"], ["addv", "addv", "16B"],1398["addv", "addv", "4H"], ["addv", "addv", "8H"],1399["addv", "addv", "4S"],1400["smaxv", "smaxv", "8B"], ["smaxv", "smaxv", "16B"],1401["smaxv", "smaxv", "4H"], ["smaxv", "smaxv", "8H"],1402["smaxv", "smaxv", "4S"], ["fmaxv", "fmaxv", "4S"],1403["sminv", "sminv", "8B"], ["uminv", "uminv", "8B"],1404["sminv", "sminv", "16B"],["uminv", "uminv", "16B"],1405["sminv", "sminv", "4H"], ["uminv", "uminv", "4H"],1406["sminv", "sminv", "8H"], ["uminv", "uminv", "8H"],1407["sminv", "sminv", "4S"], ["uminv", "uminv", "4S"],1408["fminv", "fminv", "4S"],1409["fmaxp", "fmaxp", "2S"], ["fmaxp", "fmaxp", "2D"],1410["fminp", "fminp", "2S"], ["fminp", "fminp", "2D"],1411])14121413generate(TwoRegNEONOp,1414[["absr", "abs", "8B"], ["absr", "abs", "16B"],1415["absr", "abs", "4H"], ["absr", "abs", "8H"],1416["absr", "abs", "2S"], ["absr", "abs", "4S"],1417["absr", "abs", "2D"],1418["fabs", "fabs", "2S"], ["fabs", "fabs", "4S"],1419["fabs", "fabs", "2D"],1420["fneg", "fneg", "2S"], ["fneg", "fneg", "4S"],1421["fneg", "fneg", "2D"],1422["fsqrt", "fsqrt", "2S"], ["fsqrt", "fsqrt", "4S"],1423["fsqrt", "fsqrt", "2D"],1424["notr", "not", "8B"], ["notr", "not", "16B"],1425])14261427generate(ThreeRegNEONOp,1428[["andr", "and", "8B"], ["andr", "and", "16B"],1429["orr", "orr", "8B"], ["orr", "orr", "16B"],1430["eor", "eor", "8B"], ["eor", "eor", "16B"],1431["addv", "add", "8B"], ["addv", "add", "16B"],1432["addv", "add", "4H"], ["addv", "add", "8H"],1433["addv", "add", "2S"], ["addv", "add", "4S"],1434["addv", "add", "2D"],1435["fadd", "fadd", "2S"], ["fadd", "fadd", "4S"],1436["fadd", "fadd", "2D"],1437["subv", "sub", "8B"], ["subv", "sub", "16B"],1438["subv", "sub", "4H"], ["subv", "sub", "8H"],1439["subv", "sub", "2S"], ["subv", "sub", "4S"],1440["subv", "sub", "2D"],1441["fsub", "fsub", "2S"], ["fsub", "fsub", "4S"],1442["fsub", "fsub", "2D"],1443["mulv", "mul", "8B"], ["mulv", "mul", "16B"],1444["mulv", "mul", "4H"], ["mulv", "mul", "8H"],1445["mulv", "mul", "2S"], ["mulv", "mul", "4S"],1446["fabd", "fabd", "2S"], ["fabd", "fabd", "4S"],1447["fabd", "fabd", "2D"],1448["fmul", "fmul", "2S"], ["fmul", "fmul", "4S"],1449["fmul", "fmul", "2D"],1450["mlav", "mla", "4H"], ["mlav", "mla", "8H"],1451["mlav", "mla", "2S"], ["mlav", "mla", "4S"],1452["fmla", "fmla", "2S"], ["fmla", "fmla", "4S"],1453["fmla", "fmla", "2D"],1454["mlsv", "mls", "4H"], ["mlsv", "mls", "8H"],1455["mlsv", "mls", "2S"], ["mlsv", "mls", "4S"],1456["fmls", "fmls", "2S"], ["fmls", "fmls", "4S"],1457["fmls", "fmls", "2D"],1458["fdiv", "fdiv", "2S"], ["fdiv", "fdiv", "4S"],1459["fdiv", "fdiv", "2D"],1460["maxv", "smax", "8B"], ["maxv", "smax", "16B"],1461["maxv", "smax", "4H"], ["maxv", "smax", "8H"],1462["maxv", "smax", "2S"], ["maxv", "smax", "4S"],1463["smaxp", "smaxp", "8B"], ["smaxp", "smaxp", "16B"],1464["smaxp", "smaxp", "4H"], ["smaxp", "smaxp", "8H"],1465["smaxp", "smaxp", "2S"], ["smaxp", "smaxp", "4S"],1466["fmax", "fmax", "2S"], ["fmax", "fmax", "4S"],1467["fmax", "fmax", "2D"],1468["minv", "smin", "8B"], ["minv", "smin", "16B"],1469["minv", "smin", "4H"], ["minv", "smin", "8H"],1470["minv", "smin", "2S"], ["minv", "smin", "4S"],1471["sminp", "sminp", "8B"], ["sminp", "sminp", "16B"],1472["sminp", "sminp", "4H"], ["sminp", "sminp", "8H"],1473["sminp", "sminp", "2S"], ["sminp", "sminp", "4S"],1474["fmin", "fmin", "2S"], ["fmin", "fmin", "4S"],1475["fmin", "fmin", "2D"],1476["cmeq", "cmeq", "8B"], ["cmeq", "cmeq", "16B"],1477["cmeq", "cmeq", "4H"], ["cmeq", "cmeq", "8H"],1478["cmeq", "cmeq", "2S"], ["cmeq", "cmeq", "4S"],1479["cmeq", "cmeq", "2D"],1480["fcmeq", "fcmeq", "2S"], ["fcmeq", "fcmeq", "4S"],1481["fcmeq", "fcmeq", "2D"],1482["cmgt", "cmgt", "8B"], ["cmgt", "cmgt", "16B"],1483["cmgt", "cmgt", "4H"], ["cmgt", "cmgt", "8H"],1484["cmgt", "cmgt", "2S"], ["cmgt", "cmgt", "4S"],1485["cmgt", "cmgt", "2D"],1486["fcmgt", "fcmgt", "2S"], ["fcmgt", "fcmgt", "4S"],1487["fcmgt", "fcmgt", "2D"],1488["cmge", "cmge", "8B"], ["cmge", "cmge", "16B"],1489["cmge", "cmge", "4H"], ["cmge", "cmge", "8H"],1490["cmge", "cmge", "2S"], ["cmge", "cmge", "4S"],1491["cmge", "cmge", "2D"],1492["fcmge", "fcmge", "2S"], ["fcmge", "fcmge", "4S"],1493["fcmge", "fcmge", "2D"],1494])14951496generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", "ccmn\txzr, xzr, #3, LE"],1497["ccmnw", "__ ccmnw(zr, zr, 5u, Assembler::EQ);", "ccmn\twzr, wzr, #5, EQ"],1498["ccmp", "__ ccmp(zr, 1, 4u, Assembler::NE);", "ccmp\txzr, 1, #4, NE"],1499["ccmpw", "__ ccmpw(zr, 2, 2, Assembler::GT);", "ccmp\twzr, 2, #2, GT"],1500["extr", "__ extr(zr, zr, zr, 0);", "extr\txzr, xzr, xzr, 0"],1501["stlxp", "__ stlxp(r0, zr, zr, sp);", "stlxp\tw0, xzr, xzr, [sp]"],1502["stlxpw", "__ stlxpw(r2, zr, zr, r3);", "stlxp\tw2, wzr, wzr, [x3]"],1503["stxp", "__ stxp(r4, zr, zr, r5);", "stxp\tw4, xzr, xzr, [x5]"],1504["stxpw", "__ stxpw(r6, zr, zr, sp);", "stxp\tw6, wzr, wzr, [sp]"],1505["dup", "__ dup(v0, __ T16B, zr);", "dup\tv0.16b, wzr"],1506["mov", "__ mov(v1, __ T1D, 0, zr);", "mov\tv1.d[0], xzr"],1507["mov", "__ mov(v1, __ T2S, 1, zr);", "mov\tv1.s[1], wzr"],1508["mov", "__ mov(v1, __ T4H, 2, zr);", "mov\tv1.h[2], wzr"],1509["mov", "__ mov(v1, __ T8B, 3, zr);", "mov\tv1.b[3], wzr"],1510["smov", "__ smov(r0, v1, __ S, 0);", "smov\tx0, v1.s[0]"],1511["smov", "__ smov(r0, v1, __ H, 1);", "smov\tx0, v1.h[1]"],1512["smov", "__ smov(r0, v1, __ B, 2);", "smov\tx0, v1.b[2]"],1513["umov", "__ umov(r0, v1, __ D, 0);", "umov\tx0, v1.d[0]"],1514["umov", "__ umov(r0, v1, __ S, 1);", "umov\tw0, v1.s[1]"],1515["umov", "__ umov(r0, v1, __ H, 2);", "umov\tw0, v1.h[2]"],1516["umov", "__ umov(r0, v1, __ B, 3);", "umov\tw0, v1.b[3]"],1517["ld1", "__ ld1(v31, v0, __ T2D, Address(__ post(r1, r0)));", "ld1\t{v31.2d, v0.2d}, [x1], x0"],1518# SVE instructions1519["cpy", "__ sve_cpy(z0, __ S, p0, v1);", "mov\tz0.s, p0/m, s1"],1520["inc", "__ sve_inc(r0, __ S);", "incw\tx0"],1521["dec", "__ sve_dec(r1, __ H);", "dech\tx1"],1522["lsl", "__ sve_lsl(z0, __ B, z1, 7);", "lsl\tz0.b, z1.b, #7"],1523["lsl", "__ sve_lsl(z21, __ H, z1, 15);", "lsl\tz21.h, z1.h, #15"],1524["lsl", "__ sve_lsl(z0, __ S, z1, 31);", "lsl\tz0.s, z1.s, #31"],1525["lsl", "__ sve_lsl(z0, __ D, z1, 63);", "lsl\tz0.d, z1.d, #63"],1526["lsr", "__ sve_lsr(z0, __ B, z1, 7);", "lsr\tz0.b, z1.b, #7"],1527["asr", "__ sve_asr(z0, __ H, z11, 15);", "asr\tz0.h, z11.h, #15"],1528["lsr", "__ sve_lsr(z30, __ S, z1, 31);", "lsr\tz30.s, z1.s, #31"],1529["asr", "__ sve_asr(z0, __ D, z1, 63);", "asr\tz0.d, z1.d, #63"],1530["addvl", "__ sve_addvl(sp, r0, 31);", "addvl\tsp, x0, #31"],1531["addpl", "__ sve_addpl(r1, sp, -32);", "addpl\tx1, sp, -32"],1532["cntp", "__ sve_cntp(r8, __ B, p0, p1);", "cntp\tx8, p0, p1.b"],1533["dup", "__ sve_dup(z0, __ B, 127);", "dup\tz0.b, 127"],1534["dup", "__ sve_dup(z1, __ H, -128);", "dup\tz1.h, -128"],1535["dup", "__ sve_dup(z2, __ S, 32512);", "dup\tz2.s, 32512"],1536["dup", "__ sve_dup(z7, __ D, -32768);", "dup\tz7.d, -32768"],1537["ld1b", "__ sve_ld1b(z0, __ B, p0, Address(sp));", "ld1b\t{z0.b}, p0/z, [sp]"],1538["ld1h", "__ sve_ld1h(z10, __ H, p1, Address(sp, -8));", "ld1h\t{z10.h}, p1/z, [sp, #-8, MUL VL]"],1539["ld1w", "__ sve_ld1w(z20, __ S, p2, Address(r0, 7));", "ld1w\t{z20.s}, p2/z, [x0, #7, MUL VL]"],1540["ld1b", "__ sve_ld1b(z30, __ B, p3, Address(sp, r8));", "ld1b\t{z30.b}, p3/z, [sp, x8]"],1541["ld1w", "__ sve_ld1w(z0, __ S, p4, Address(sp, r28));", "ld1w\t{z0.s}, p4/z, [sp, x28, LSL #2]"],1542["ld1d", "__ sve_ld1d(z11, __ D, p5, Address(r0, r1));", "ld1d\t{z11.d}, p5/z, [x0, x1, LSL #3]"],1543["st1b", "__ sve_st1b(z22, __ B, p6, Address(sp));", "st1b\t{z22.b}, p6, [sp]"],1544["st1b", "__ sve_st1b(z31, __ B, p7, Address(sp, -8));", "st1b\t{z31.b}, p7, [sp, #-8, MUL VL]"],1545["st1w", "__ sve_st1w(z0, __ S, p1, Address(r0, 7));", "st1w\t{z0.s}, p1, [x0, #7, MUL VL]"],1546["st1b", "__ sve_st1b(z0, __ B, p2, Address(sp, r1));", "st1b\t{z0.b}, p2, [sp, x1]"],1547["st1h", "__ sve_st1h(z0, __ H, p3, Address(sp, r8));", "st1h\t{z0.h}, p3, [sp, x8, LSL #1]"],1548["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r17));", "st1d\t{z0.d}, p4, [x0, x17, LSL #3]"],1549["ldr", "__ sve_ldr(z0, Address(sp));", "ldr\tz0, [sp]"],1550["ldr", "__ sve_ldr(z31, Address(sp, -256));", "ldr\tz31, [sp, #-256, MUL VL]"],1551["str", "__ sve_str(z8, Address(r8, 255));", "str\tz8, [x8, #255, MUL VL]"],1552])15531554print "\n// FloatImmediateOp"1555for float in ("2.0", "2.125", "4.0", "4.25", "8.0", "8.5", "16.0", "17.0", "0.125",1556"0.1328125", "0.25", "0.265625", "0.5", "0.53125", "1.0", "1.0625",1557"-2.0", "-2.125", "-4.0", "-4.25", "-8.0", "-8.5", "-16.0", "-17.0",1558"-0.125", "-0.1328125", "-0.25", "-0.265625", "-0.5", "-0.53125", "-1.0", "-1.0625"):1559astr = "fmov d0, #" + float1560cstr = "__ fmovd(v0, " + float + ");"1561print " %-50s //\t%s" % (cstr, astr)1562outfile.write("\t" + astr + "\n")15631564# ARMv8.1A1565for size in ("x", "w"):1566for suffix in ("", "a", "al", "l"):1567generate(LSEOp, [["swp", "swp", size, suffix],1568["ldadd", "ldadd", size, suffix],1569["ldbic", "ldclr", size, suffix],1570["ldeor", "ldeor", size, suffix],1571["ldorr", "ldset", size, suffix],1572["ldsmin", "ldsmin", size, suffix],1573["ldsmax", "ldsmax", size, suffix],1574["ldumin", "ldumin", size, suffix],1575["ldumax", "ldumax", size, suffix]]);15761577# ARMv8.2A1578generate(SHA3SIMDOp, ["bcax", "eor3", "rax1", "xar"])15791580generate(SHA512SIMDOp, ["sha512h", "sha512h2", "sha512su0", "sha512su1"])15811582generate(SVEVectorOp, [["add", "ZZZ"],1583["sub", "ZZZ"],1584["fadd", "ZZZ"],1585["fmul", "ZZZ"],1586["fsub", "ZZZ"],1587["abs", "ZPZ"],1588["add", "ZPZ", "dn"],1589["asr", "ZPZ", "dn"],1590["cnt", "ZPZ"],1591["lsl", "ZPZ", "dn"],1592["lsr", "ZPZ", "dn"],1593["mul", "ZPZ", "dn"],1594["neg", "ZPZ"],1595["not", "ZPZ"],1596["smax", "ZPZ", "dn"],1597["smin", "ZPZ", "dn"],1598["sub", "ZPZ", "dn"],1599["fabs", "ZPZ"],1600["fadd", "ZPZ", "dn"],1601["fdiv", "ZPZ", "dn"],1602["fmax", "ZPZ", "dn"],1603["fmin", "ZPZ", "dn"],1604["fmul", "ZPZ", "dn"],1605["fneg", "ZPZ"],1606["frintm", "ZPZ"],1607["frintn", "ZPZ"],1608["frintp", "ZPZ"],1609["fsqrt", "ZPZ"],1610["fsub", "ZPZ", "dn"],1611["fmla", "ZPZZ"],1612["fmls", "ZPZZ"],1613["fnmla", "ZPZZ"],1614["fnmls", "ZPZZ"],1615["mla", "ZPZZ"],1616["mls", "ZPZZ"],1617["and", "ZZZ"],1618["eor", "ZZZ"],1619["orr", "ZZZ"],1620["bic", "ZZZ"],1621])16221623generate(SVEReductionOp, [["andv", 0], ["orv", 0], ["eorv", 0], ["smaxv", 0], ["sminv", 0],1624["fminv", 2], ["fmaxv", 2], ["fadda", 2], ["uaddv", 0]])16251626print "\n __ bind(forth);"1627outfile.write("forth:\n")16281629outfile.close()16301631# compile for sve with 8.2 and sha3 because of SHA3 crypto extension.1632subprocess.check_call([AARCH64_AS, "-march=armv8.2-a+sha3+sve", "aarch64ops.s", "-o", "aarch64ops.o"])163316341635print "/*"1636print "*/"16371638subprocess.check_call([AARCH64_OBJCOPY, "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"])16391640infile = open("aarch64ops.bin", "r")1641bytes = bytearray(infile.read())164216431644print " static const unsigned int insns[] ="1645print " {"16461647i = 01648while i < len(bytes):1649print " 0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]),1650i += 41651if i%16 == 0:16521653print "\n };"1654print "// END Generated code -- do not edit"16551656infile.close()16571658for f in ["aarch64ops.s", "aarch64ops.o", "aarch64ops.bin"]:1659os.remove(f)166016611662