aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authoraph <none@none>2012-07-20 17:58:24 +0100
committeraph <none@none>2012-07-20 17:58:24 +0100
commit20df58d5b20a91194bd2b265cb4afdf676e44af0 (patch)
treec04f4438e5a3dac4b6672d2eff63801677dc644f /test
parentb2efc51638e73046feb5f3ec1c4d29da4e6f337c (diff)
Initial commit.
Diffstat (limited to 'test')
-rw-r--r--test/aarch64-asmtest.py860
1 files changed, 860 insertions, 0 deletions
diff --git a/test/aarch64-asmtest.py b/test/aarch64-asmtest.py
new file mode 100644
index 0000000..72f9fb8
--- /dev/null
+++ b/test/aarch64-asmtest.py
@@ -0,0 +1,860 @@
+import random
+
+class Operand(object):
+
+ def generate(self):
+ return self
+
+class Register(Operand):
+
+ def generate(self):
+ self.number = random.randint(0, 30)
+ return self
+
+ def astr(self, prefix):
+ return prefix + str(self.number)
+
+class FloatRegister(Register):
+
+ def __str__(self):
+ return self.astr("F")
+
+class GeneralRegister(Register):
+
+ def __str__(self):
+ return self.astr("r")
+
+class FloatZero(Operand):
+
+ def __str__(self):
+ return "0.0"
+
+ def astr(self, ignored):
+ return "#0.0"
+
+class OperandFactory:
+
+ _modes = {'x' : GeneralRegister,
+ 'w' : GeneralRegister,
+ 's' : FloatRegister,
+ 'd' : FloatRegister,
+ 'z' : FloatZero}
+
+ @classmethod
+ def create(cls, mode):
+ return OperandFactory._modes[mode]()
+
+class ShiftKind:
+
+ def generate(self):
+ self.kind = ["lsl", "lsr", "asr"][random.randint(0,2)]
+ return self
+
+ def cstr(self):
+ return self.kind
+
+class Instruction(object):
+
+ def __init__(self, name):
+ self._name = name
+ self.isWord = name.endswith("w") | name.endswith("wi")
+ self.asmRegPrefix = ["x", "w"][self.isWord]
+
+ def aname(self):
+ if (self._name.endswith("wi")):
+ return self._name[:len(self._name)-2]
+ else:
+ if (self._name.endswith("i") | self._name.endswith("w")):
+ return self._name[:len(self._name)-1]
+ else:
+ return self._name
+
+ def emit(self) :
+ pass
+
+ def compare(self) :
+ pass
+
+ def generate(self) :
+ return self
+
+ def cstr(self):
+ return '__ %s(' % self.name()
+
+ def astr(self):
+ return '%s\t' % self.aname()
+
+ def name(self):
+ name = self._name
+ if name == "and":
+ name = "andr" # Special case: the name "and" can't be used
+ # in HotSpot, even for a member.
+ return name
+
+class InstructionWithModes(Instruction):
+
+ def __init__(self, name, mode):
+ Instruction.__init__(self, name)
+ self.mode = mode
+ self.isFloat = (mode == 'd') | (mode == 's')
+ if self.isFloat:
+ self.isWord = mode != 'd'
+ self.asmRegPrefix = ["d", "s"][self.isWord]
+ else:
+ self.isWord = mode != 'x'
+ self.asmRegPrefix = ["x", "w"][self.isWord]
+
+ def name(self):
+ return self._name + (self.mode if self.mode != 'x' else '')
+
+ def aname(self):
+ return (self._name+mode if (mode == 'b' or mode == 'h')
+ else self._name)
+
+class ThreeRegInstruction(Instruction):
+
+ def generate(self):
+ self.reg = [GeneralRegister().generate(), GeneralRegister().generate(),
+ GeneralRegister().generate()]
+ return self
+
+
+ def cstr(self):
+ return (super(ThreeRegInstruction, self).cstr()
+ + ('%s, %s, %s'
+ % (self.reg[0],
+ self.reg[1], self.reg[2])))
+
+ def astr(self):
+ prefix = self.asmRegPrefix
+ return (super(ThreeRegInstruction, self).astr()
+ + ('%s, %s, %s'
+ % (self.reg[0].astr(prefix),
+ self.reg[1].astr(prefix), self.reg[2].astr(prefix))))
+
+class FourRegInstruction(ThreeRegInstruction):
+
+ def generate(self):
+ self.reg = ThreeRegInstruction.generate(self).reg + [GeneralRegister().generate()]
+ return self
+
+
+ def cstr(self):
+ return (super(FourRegInstruction, self).cstr()
+ + (', %s' % self.reg[3]))
+
+ def astr(self):
+ prefix = self.asmRegPrefix
+ return (super(FourRegInstruction, self).astr()
+ + (', %s' % self.reg[3].astr(prefix)))
+
+class TwoRegInstruction(Instruction):
+
+ def generate(self):
+ self.reg = [GeneralRegister().generate(), GeneralRegister().generate()]
+ return self
+
+ def cstr(self):
+ return (super(TwoRegInstruction, self).cstr()
+ + '%s, %s' % (self.reg[0],
+ self.reg[1]))
+
+ def astr(self):
+ prefix = self.asmRegPrefix
+ return (super(TwoRegInstruction, self).astr()
+ + ('%s, %s'
+ % (self.reg[0].astr(prefix),
+ self.reg[1].astr(prefix))))
+
+class TwoRegImmedInstruction(TwoRegInstruction):
+
+ def generate(self):
+ super(TwoRegImmedInstruction, self).generate()
+ self.immed = random.randint(0, 1<<11 -1)
+ return self
+
+ def cstr(self):
+ return (super(TwoRegImmedInstruction, self).cstr()
+ + ', %su' % self.immed)
+
+ def astr(self):
+ return (super(TwoRegImmedInstruction, self).astr()
+ + ', #%s' % self.immed)
+
+class OneRegOp(Instruction):
+
+ def generate(self):
+ self.reg = GeneralRegister().generate()
+ return self
+
+ def cstr(self):
+ return (super(OneRegOp, self).cstr()
+ + '%s);' % self.reg)
+
+ def astr(self):
+ return (super(OneRegOp, self).astr()
+ + '%s' % self.reg.astr(self.asmRegPrefix))
+
+class ArithOp(ThreeRegInstruction):
+
+ def generate(self):
+ super(ArithOp, self).generate()
+ self.kind = ShiftKind().generate()
+ self.distance = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)
+ return self
+
+ def cstr(self):
+ return ('%s, Assembler::%s, %s);'
+ % (ThreeRegInstruction.cstr(self),
+ self.kind.cstr(), self.distance))
+
+ def astr(self):
+ return ('%s, %s #%s'
+ % (ThreeRegInstruction.astr(self),
+ self.kind.cstr(),
+ self.distance))
+
+class AddSubCarryOp(ThreeRegInstruction):
+
+ def cstr(self):
+ return ('%s);'
+ % (ThreeRegInstruction.cstr(self)))
+
+class AddSubExtendedOp(ThreeRegInstruction):
+
+ uxtb, uxth, uxtw, uxtx, sxtb, sxth, sxtw, sxtx = range(8)
+ optNames = ["uxtb", "uxth", "uxtw", "uxtx", "sxtb", "sxth", "sxtw", "sxtx"]
+
+ def generate(self):
+ super(AddSubExtendedOp, self).generate()
+ self.amount = random.randint(1, 4)
+ self.option = random.randint(0, 7)
+ return self
+
+ def cstr(self):
+ return (super(AddSubExtendedOp, self).cstr()
+ + (", ext::" + AddSubExtendedOp.optNames[self.option]
+ + ", " + str(self.amount) + ");"))
+
+ def astr(self):
+ return (super(AddSubExtendedOp, self).astr()
+ + (", " + AddSubExtendedOp.optNames[self.option]
+ + " #" + str(self.amount)))
+
+class AddSubImmOp(TwoRegImmedInstruction):
+
+ def cstr(self):
+ return super(AddSubImmOp, self).cstr() + ");"
+
+class LogicalImmOp(AddSubImmOp):
+
+ # These tables are legal immediate logical operands
+ immediates32 \
+ = [0x1, 0x3f, 0x1f0, 0x7e0,
+ 0x1c00, 0x3ff0, 0x8000, 0x1e000,
+ 0x3e000, 0x78000, 0xe0000, 0x100000,
+ 0x1fffe0, 0x3fe000, 0x780000, 0x7ffff8,
+ 0xff8000, 0x1800180, 0x1fffc00, 0x3c003c0,
+ 0x3ffff00, 0x7c00000, 0x7fffe00, 0xf000f00,
+ 0xfffe000, 0x18181818, 0x1ffc0000, 0x1ffffffe,
+ 0x3f003f00, 0x3fffe000, 0x60006000, 0x7f807f80,
+ 0x7ffffc00, 0x800001ff, 0x803fffff, 0x9f9f9f9f,
+ 0xc0000fff, 0xc0c0c0c0, 0xe0000000, 0xe003e003,
+ 0xe3ffffff, 0xf0000fff, 0xf0f0f0f0, 0xf80000ff,
+ 0xf83ff83f, 0xfc00007f, 0xfc1fffff, 0xfe0001ff,
+ 0xfe3fffff, 0xff003fff, 0xff800003, 0xff87ff87,
+ 0xffc00fff, 0xffe0000f, 0xffefffef, 0xfff1fff1,
+ 0xfff83fff, 0xfffc0fff, 0xfffe0fff, 0xffff3fff,
+ 0xffffc007, 0xffffe1ff, 0xfffff80f, 0xfffffe07,
+ 0xffffffbf, 0xfffffffd]
+
+ immediates \
+ = [0x1, 0x1f80, 0x3fff0, 0x3ffffc,
+ 0x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000,
+ 0xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000,
+ 0x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000,
+ 0x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000,
+ 0x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000,
+ 0x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8,
+ 0x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000,
+ 0x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff,
+ 0xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003,
+ 0xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff,
+ 0xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000,
+ 0xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f,
+ 0xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff,
+ 0xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff,
+ 0xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f]
+
+ def generate(self):
+ AddSubImmOp.generate(self)
+ self.immed = \
+ self.immediates32[random.randint(0, len(self.immediates32)-1)] \
+ if self.isWord \
+ else \
+ self.immediates[random.randint(0, len(self.immediates)-1)]
+
+ return self
+
+ def astr(self):
+ return (super(TwoRegImmedInstruction, self).astr()
+ + ', #0x%x' % self.immed)
+
+ def cstr(self):
+ return super(AddSubImmOp, self).cstr() + "l);"
+
+class AbsOp(Instruction):
+
+ def cstr(self):
+ return super(AbsOp, self).cstr() + "__ pc());"
+
+ def astr(self):
+ return Instruction.astr(self) + "."
+
+class RegAndAbsOp(Instruction):
+
+ def generate(self):
+ super(RegAndAbsOp, self).generate()
+ self.reg = GeneralRegister().generate()
+ return self
+
+ def cstr(self):
+ return (super(RegAndAbsOp, self).cstr()
+ + "%s, __ pc());" % self.reg)
+
+ def astr(self):
+ return (super(RegAndAbsOp, self).astr()
+ + self.reg.astr(self.asmRegPrefix) + ", .")
+
+class RegImmAbsOp(RegAndAbsOp):
+
+ def cstr(self):
+ return (Instruction.cstr(self)
+ + "%s, %s, __ pc());" % (self.reg, self.immed))
+
+ def astr(self):
+ return (Instruction.astr(self)
+ + ("%s, #%s, ."
+ % (self.reg.astr(self.asmRegPrefix), self.immed)))
+
+ def generate(self):
+ super(RegImmAbsOp, self).generate()
+ self.immed = random.randint(0, 1<<5 -1)
+ return self
+
+class MoveWideImmOp(RegImmAbsOp):
+
+ def cstr(self):
+ return (Instruction.cstr(self)
+ + "%s, %s, %s);" % (self.reg, self.immed, self.shift))
+
+ def astr(self):
+ return (Instruction.astr(self)
+ + ("%s, #%s, lsl %s"
+ % (self.reg.astr(self.asmRegPrefix),
+ self.immed, self.shift)))
+
+ def generate(self):
+ super(RegImmAbsOp, self).generate()
+ self.immed = random.randint(0, 1<<16 -1)
+ if self.isWord:
+ self.shift = random.randint(0, 1) * 16
+ else:
+ self.shift = random.randint(0, 3) * 16
+ return self
+
+class BitfieldOp(TwoRegInstruction):
+
+ def cstr(self):
+ return (Instruction.cstr(self)
+ + ("%s, %s, %s, %s);"
+ % (self.reg[0], self.reg[1], self.immr, self.imms)))
+
+ def astr(self):
+ return (TwoRegInstruction.astr(self)
+ + (", #%s, #%s"
+ % (self.immr, self.imms)))
+
+ def generate(self):
+ TwoRegInstruction.generate(self)
+ self.immr = random.randint(0, 31)
+ self.imms = random.randint(0, 31)
+ return self
+
+class ExtractOp(ThreeRegInstruction):
+
+ def generate(self):
+ super(ExtractOp, self).generate()
+ self.lsb = random.randint(0, (1<<5)-1 if self.isWord else (1<<6)-1)
+ return self
+
+ def cstr(self):
+ return (ThreeRegInstruction.cstr(self)
+ + (", %s);" % self.lsb))
+
+ def astr(self):
+ return (ThreeRegInstruction.astr(self)
+ + (", #%s" % self.lsb))
+
+class CondBranchOp(Instruction):
+
+ def cstr(self):
+ return "__ b" + self.name() + "(__ pc());"
+
+ def astr(self):
+ return "b." + self.name() + "\t."
+
+class ImmOp(Instruction):
+
+ def cstr(self):
+ return "%s%s);" % (Instruction.cstr(self), self.immed)
+
+ def astr(self):
+ return Instruction.astr(self) + "#" + str(self.immed)
+
+ def generate(self):
+ self.immed = random.randint(0, 1<<16 -1)
+ return self
+
+class Op(Instruction):
+
+ def cstr(self):
+ return Instruction.cstr(self) + ");"
+
+conditionCodes = ["EQ", "NE", "HS", "CS", "LO", "CC", "MI", "PL", "VS", \
+ "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL", "NV"]
+
+class ConditionalCompareOp(TwoRegImmedInstruction):
+
+ def generate(self):
+ TwoRegImmedInstruction.generate(self)
+ self.cond = random.randint(0, 15)
+ self.immed = random.randint(0, 15)
+ return self
+
+ def cstr(self):
+ return (super(ConditionalCompareOp, self).cstr() + ", "
+ + "Assembler::" + conditionCodes[self.cond] + ");")
+
+ def astr(self):
+ return (super(ConditionalCompareOp, self).astr() +
+ ", " + conditionCodes[self.cond])
+
+class ConditionalCompareImmedOp(Instruction):
+
+ def generate(self):
+ self.reg = GeneralRegister().generate()
+ self.cond = random.randint(0, 15)
+ self.immed2 = random.randint(0, 15)
+ self.immed = random.randint(0, 31)
+ return self
+
+ def cstr(self):
+ return (Instruction.cstr(self) + str(self.reg) + ", "
+ + str(self.immed) + ", "
+ + str(self.immed2) + ", "
+ + "Assembler::" + conditionCodes[self.cond] + ");")
+
+ def astr(self):
+ return (Instruction.astr(self)
+ + self.reg.astr(self.asmRegPrefix)
+ + ", #" + str(self.immed)
+ + ", #" + str(self.immed2)
+ + ", " + conditionCodes[self.cond])
+
+class TwoRegOp(TwoRegInstruction):
+
+ def cstr(self):
+ return TwoRegInstruction.cstr(self) + ");"
+
+class ThreeRegOp(ThreeRegInstruction):
+
+ def cstr(self):
+ return ThreeRegInstruction.cstr(self) + ");"
+
+class FourRegMulOp(FourRegInstruction):
+
+ def cstr(self):
+ return FourRegInstruction.cstr(self) + ");"
+
+ def astr(self):
+ isMaddsub = self.name().startswith("madd") | self.name().startswith("msub")
+ midPrefix = self.asmRegPrefix if isMaddsub else "w"
+ return (Instruction.astr(self)
+ + self.reg[0].astr(self.asmRegPrefix)
+ + ", " + self.reg[1].astr(midPrefix)
+ + ", " + self.reg[2].astr(midPrefix)
+ + ", " + self.reg[3].astr(self.asmRegPrefix))
+
+class ConditionalSelectOp(ThreeRegInstruction):
+
+ def generate(self):
+ ThreeRegInstruction.generate(self)
+ self.cond = random.randint(0, 15)
+ return self
+
+ def cstr(self):
+ return (ThreeRegInstruction.cstr(self) + ", "
+ + "Assembler::" + conditionCodes[self.cond] + ");")
+
+ def astr(self):
+ return (ThreeRegInstruction.astr(self)
+ + ", " + conditionCodes[self.cond])
+
+class LoadStoreExclusiveOp(InstructionWithModes):
+
+ def __init__(self, op): # op is a tuple of ["name", "mode", registers]
+ InstructionWithModes.__init__(self, op[0], op[1])
+ self.num_registers = op[2]
+
+ def astr(self):
+ result = self.aname() + '\t'
+ regs = list(self.regs)
+ index = regs.pop() # The last reg is the index register
+ prefix = ('x' if (self.mode == 'x')
+ & ((self.name().startswith("ld"))
+ | (self.name().startswith("stlr"))) # Ewww :-(
+ else 'w')
+ result = result + regs.pop(0).astr(prefix) + ", "
+ for s in regs:
+ result = result + s.astr(self.asmRegPrefix) + ", "
+ result = result + "[" + index.astr("x") + "]"
+ return result
+
+ def cstr(self):
+ result = InstructionWithModes.cstr(self)
+ regs = list(self.regs)
+ index = regs.pop() # The last reg is the index register
+ for s in regs:
+ result = result + str(s) + ", "
+ result = result + str(index) + ");"
+ return result
+
+ def generate(self):
+ self.regs = []
+ for i in range(self.num_registers):
+ self.regs.append(GeneralRegister().generate())
+ return self
+
+ def name(self):
+ if self.mode == 'x':
+ return self._name
+ else:
+ return self._name + self.mode
+
+ def aname(self):
+ if (self.mode == 'b') | (self.mode == 'h'):
+ return self._name + self.mode
+ else:
+ return self._name
+
+class Address(object):
+
+ base_plus_unscaled_offset, pre, post, base_plus_reg, \
+ base_plus_scaled_offset, pcrel = range(6)
+ kinds = ["base_plus_unscaled_offset", "pre", "post", "base_plus_reg",
+ "base_plus_scaled_offset", "pcrel"]
+
+ @classmethod
+ def kindToStr(cls, i):
+ return cls.kinds[i]
+
+ def generate(self, kind):
+ self.kind = kind
+ self.base = GeneralRegister().generate()
+ self.index = GeneralRegister().generate()
+ self.offset = {
+ Address.base_plus_unscaled_offset: random.randint(-1<<8, 1<<8-1) | 1,
+ Address.pre: random.randint(-1<<8, 1<<8-1),
+ Address.post: random.randint(-1<<8, 1<<8-1),
+ Address.pcrel: random.randint(-1<<18, 1<<18-1),
+ Address.base_plus_reg: 0,
+ Address.base_plus_scaled_offset: (random.randint(0, 1<<11-1) | (3 << 9))*8 } \
+ [kind]
+ return self
+
+ def __str__(self):
+ return {
+ Address.base_plus_unscaled_offset: "Address(%s, %s)" \
+ % (str(self.base), self.offset),
+ Address.pre: "Address(__ pre(%s, %s))" % (str(self.base), self.offset),
+ Address.post: "Address(__ post(%s, %s))" % (str(self.base), self.offset),
+ Address.pcrel: "__ pc()",
+ Address.base_plus_reg: "Address(%s, %s)" % (self.base, self.index),
+ Address.base_plus_scaled_offset:
+ "Address(%s, %s)" % (self.base, self.offset) } [self.kind]
+
+ def astr(self, prefix):
+ return {
+ Address.base_plus_unscaled_offset: "[%s, %s]" \
+ % (self.base.astr(prefix), self.offset),
+ Address.pre: "[%s, %s]!" % (self.base.astr(prefix), self.offset),
+ Address.post: "[%s], %s" % (self.base.astr(prefix), self.offset),
+ Address.pcrel: ".",
+ Address.base_plus_reg: "[%s, %s]" \
+ % (self.base.astr(prefix), self.index.astr(prefix)),
+ Address.base_plus_scaled_offset: \
+ "[%s, %s]" % (self.base.astr(prefix), self.offset)
+ } [self.kind]
+
+class LoadStoreOp(InstructionWithModes):
+
+ def __init__(self, args):
+ name, self.asmname, self.kind, mode = args
+ InstructionWithModes.__init__(self, name, mode)
+
+ def generate(self):
+ adr = Address().generate(self.kind)
+ self.adr = adr
+
+ # This is something of a kludge, but the offset needs to be
+ # scaled by the memory datamode somehow.
+ if (self.mode == 'b') | (self.asmname.endswith("b")):
+ adr.offset /= 8
+ elif (self.mode == 'h') | (self.asmname.endswith("h")):
+ adr.offset /= 4
+ elif (self.mode == 'w') | (self.asmname.endswith("w")) \
+ | (self.mode == 's') :
+ adr.offset /= 2
+
+ isFloat = (self.mode == 'd') | (self.mode == 's')
+
+ regMode = FloatRegister if isFloat else GeneralRegister
+ self.reg = regMode().generate()
+ return self
+
+ def cstr(self):
+ if not(self._name.startswith("prfm")):
+ return "%s%s, %s);" % (Instruction.cstr(self), str(self.reg), str(self.adr))
+ else: # No target register for a prefetch
+ return "%s%s);" % (Instruction.cstr(self), str(self.adr))
+
+ def astr(self):
+ if not(self._name.startswith("prfm")):
+ return "%s\t%s, %s" % (self.aname(), self.reg.astr(self.asmRegPrefix),
+ self.adr.astr("x"))
+ else: # No target register for a prefetch
+ return "%s %s" % (self.aname(),
+ self.adr.astr("x"))
+
+ def aname(self):
+ result = self.asmname
+ # if self.kind == Address.base_plus_unscaled_offset:
+ # result = result.replace("ld", "ldu", 1)
+ # result = result.replace("st", "stu", 1)
+ return result
+
+class FloatInstruction(Instruction):
+
+ def aname(self):
+ if (self._name.endswith("s") | self._name.endswith("d")):
+ return self._name[:len(self._name)-1]
+ else:
+ return self._name
+
+ def __init__(self, args):
+ name, self.modes = args
+ Instruction.__init__(self, name)
+
+ def generate(self):
+ self.reg = [OperandFactory.create(self.modes[i]).generate()
+ for i in range(self.numRegs)]
+ return self
+
+ def cstr(self):
+ formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])
+ return (formatStr
+ % tuple([Instruction.cstr(self)] +
+ [str(self.reg[i]) for i in range(self.numRegs)])) # Yowza
+
+ def astr(self):
+ formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])
+ return (formatStr
+ % tuple([Instruction.astr(self)] +
+ [(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)]))
+
+class TwoRegFloatOp(FloatInstruction):
+ numRegs = 2
+
+class ThreeRegFloatOp(TwoRegFloatOp):
+ numRegs = 3
+
+class FourRegFloatOp(TwoRegFloatOp):
+ numRegs = 4
+
+class FloatConvertOp(TwoRegFloatOp):
+
+ def __init__(self, args):
+ self._cname, self._aname, modes = args
+ TwoRegFloatOp.__init__(self, [self._cname, modes])
+
+ def aname(self):
+ return self._aname
+
+ def cname(self):
+ return self._cname
+
+
+def generate(kind, names):
+ outfile.write("# " + kind.__name__ + "\n");
+ print "\n// " + kind.__name__
+ for name in names:
+ for i in range(1):
+ op = kind(name).generate()
+ print " %-45s //\t%s" % (op.cstr(), op.astr())
+ outfile.write("\t" + op.astr() + "\n")
+
+outfile = open("aarch64ops.s", "w")
+
+print "// BEGIN Generated code -- do not edit"
+print "// Generated by aarch64-asmtest.py"
+
+generate (ArithOp,
+ [ "add", "sub", "adds", "subs",
+ "addw", "subw", "addsw", "subsw",
+ "and", "orr", "eor", "ands",
+ "andw", "orrw", "eorw", "andsw",
+ "bic", "orn", "eon", "bics",
+ "bicw", "ornw", "eonw", "bicsw" ])
+
+generate (AddSubImmOp,
+ [ "addw", "addsw", "subw", "subsw",
+ "add", "adds", "sub", "subs"])
+generate (LogicalImmOp,
+ [ "andw", "orrw", "eorw", "andsw",
+ "and", "orr", "eor", "ands"])
+
+generate (AbsOp, [ "b", "bl" ])
+
+generate (RegAndAbsOp, ["cbzw", "cbnzw", "cbz", "cbnz", "adr", "adrp"])
+
+generate (RegImmAbsOp, ["tbz", "tbnz"])
+
+generate (MoveWideImmOp, ["movnw", "movzw", "movkw", "movn", "movz", "movk"])
+
+generate (BitfieldOp, ["sbfm", "bfmw", "ubfmw", "sbfm", "bfm", "ubfm"])
+
+generate (ExtractOp, ["extrw", "extr"])
+
+generate (CondBranchOp, ["eq", "ne", "hs", "cs", "lo", "cc", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" ])
+
+generate (ImmOp, ["svc", "hvc", "smc", "brk", "hlt", # "dpcs1", "dpcs2", "dpcs3"
+ ])
+
+generate (Op, ["nop", "eret", "drps"])
+
+generate (OneRegOp, ["br", "blr"])
+
+for mode in 'xwhb':
+ generate (LoadStoreExclusiveOp, [["stxr", mode, 3], ["stlxr", mode, 3],
+ ["ldxr", mode, 2], ["ldaxr", mode, 2],
+ ["stlr", mode, 2], ["ldar", mode, 2]])
+
+for mode in 'xw':
+ generate (LoadStoreExclusiveOp, [["ldxp", mode, 3], ["ldaxp", mode, 3],
+ ["stxp", mode, 4], ["stlxp", mode, 4]])
+
+for kind in range(6):
+ print "\n// " + Address.kindToStr(kind),
+ if kind != Address.pcrel:
+ generate (LoadStoreOp,
+ [["str", "str", kind, "x"], ["str", "str", kind, "w"],
+ ["str", "strb", kind, "b"], ["str", "strh", kind, "h"],
+ ["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"],
+ ["ldr", "ldrb", kind, "b"], ["ldr", "ldrh", kind, "h"],
+ ["ldrsb", "ldrsb", kind, "x"], ["ldrsh", "ldrsh", kind, "x"],
+ ["ldrsh", "ldrsh", kind, "w"], ["ldrsw", "ldrsw", kind, "x"],
+ ["ldr", "ldr", kind, "d"], ["ldr", "ldr", kind, "s"],
+ ["str", "str", kind, "d"], ["str", "str", kind, "s"],
+ ])
+ else:
+ generate (LoadStoreOp,
+ [["ldr", "ldr", kind, "x"], ["ldr", "ldr", kind, "w"]])
+
+
+for kind in (Address.base_plus_unscaled_offset, Address.pcrel, Address.base_plus_reg, \
+ Address.base_plus_scaled_offset):
+ generate (LoadStoreOp,
+ [["prfm", "prfm\tPLDL1KEEP,", kind, "x"]])
+
+generate(AddSubCarryOp, ["adcw", "adcsw", "sbcw", "sbcsw", "adc", "adcs", "sbc", "sbcs"])
+
+generate(AddSubExtendedOp, ["addw", "addsw", "sub", "subsw", "add", "adds", "sub", "subs"])
+
+generate(ConditionalCompareOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])
+generate(ConditionalCompareImmedOp, ["ccmnw", "ccmpw", "ccmn", "ccmp"])
+generate(ConditionalSelectOp,
+ ["cselw", "csincw", "csinvw", "csnegw", "csel", "csinc", "csinv", "csneg"])
+
+generate(TwoRegOp,
+ ["rbitw", "rev16w", "revw", "clzw", "clsw", "rbit",
+ "rev16", "rev32", "rev", "clz", "cls"])
+generate(ThreeRegOp,
+ ["udivw", "sdivw", "lslvw", "lsrvw", "asrvw", "rorvw", "udiv", "sdiv",
+ "lslv", "lsrv", "asrv", "rorv"])
+generate(FourRegMulOp,
+ ["maddw", "msubw", "madd", "msub", "smaddl", "smsubl", "umaddl", "umsubl"])
+
+generate(ThreeRegFloatOp,
+ [["fmuls", "sss"], ["fdivs", "sss"], ["fadds", "sss"], ["fsubs", "sss"],
+ ["fmuls", "sss"],
+ ["fmuld", "ddd"], ["fdivd", "ddd"], ["faddd", "ddd"], ["fsubd", "ddd"],
+ ["fmuld", "ddd"]])
+
+generate(FourRegFloatOp,
+ [["fmadds", "ssss"], ["fmsubs", "ssss"], ["fnmadds", "ssss"], ["fnmadds", "ssss"],
+ ["fmaddd", "dddd"], ["fmsubd", "dddd"], ["fnmaddd", "dddd"], ["fnmaddd", "dddd"],])
+
+generate(TwoRegFloatOp,
+ [["fmovs", "ss"], ["fabss", "ss"], ["fnegs", "ss"], ["fsqrts", "ss"],
+ ["fcvts", "ds"],
+ ["fmovd", "dd"], ["fabsd", "dd"], ["fnegd", "dd"], ["fsqrtd", "dd"],
+ ["fcvtd", "sd"],
+ ])
+
+generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"],
+ ["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"],
+ ["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"],
+ ["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"],
+ ["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"],
+ ["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]])
+
+generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"],
+ ["fcmps", "sz"], ["fcmpd", "dz"]])
+
+outfile.close()
+
+import subprocess
+import sys
+
+subprocess.check_call(["../../binutils/install/bin/aarch64-none-linux-gnu-as",
+ "aarch64ops.s", "-o", "aarch64ops.o"])
+
+print
+print "/*",
+sys.stdout.flush()
+subprocess.check_call(["../../binutils/install/bin/aarch64-none-linux-gnu-objdump",
+ "-d", "aarch64ops.o"])
+print "*/"
+
+subprocess.check_call(["../../binutils/install/bin/aarch64-none-linux-gnu-objcopy",
+ "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"])
+
+infile = open("aarch64ops.bin", "r")
+bytes = bytearray(infile.read())
+
+print
+print " static const unsigned int insns[] ="
+print " {"
+
+i = 0
+while i < len(bytes):
+ print " 0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]),
+ i += 4
+ if i%16 == 0:
+ print
+print "\n };"
+print "// END Generated code -- do not edit"
+
+