< prev index next >

src/hotspot/cpu/aarch64/aarch64-asmtest.py

Print this page
rev 61975 : [vector] Address review comments for AArch64 backend changes
1. Seperate newly added NEON instructions to a new ad file
   aarch64_neon.ad
2. Add assembler tests for NEON instructions. Trailing spaces
   in the python script are also removed.

   1 import random


   2 
   3 AARCH64_AS = "<PATH-TO-AS>"
   4 AARCH64_OBJDUMP = "<PATH-TO-OBJDUMP>"
   5 AARCH64_OBJCOPY = "<PATH-TO-OBJCOPY>"
   6 



   7 class Operand(object):
   8 
   9      def generate(self):
  10         return self
  11 
  12 class Register(Operand):
  13 
  14     def generate(self):
  15         self.number = random.randint(0, 30)
  16         return self
  17 
  18     def astr(self, prefix):
  19         return prefix + str(self.number)
  20 
  21 class FloatRegister(Register):
  22 
  23     def __str__(self):
  24         return self.astr("v")
  25 
  26     def nextReg(self):


  63             return prefix + str(self.number)
  64 
  65     def __str__(self):
  66         if (self.number == 31):
  67             return self.astr()
  68         else:
  69             return self.astr("r")
  70 
  71 class FloatZero(Operand):
  72 
  73     def __str__(self):
  74         return "0.0"
  75 
  76     def astr(self, ignored):
  77         return "#0.0"
  78 
  79 class OperandFactory:
  80 
  81     _modes = {'x' : GeneralRegister,
  82               'w' : GeneralRegister,


  83               's' : FloatRegister,
  84               'd' : FloatRegister,
  85               'z' : FloatZero}
  86 
  87     @classmethod
  88     def create(cls, mode):
  89         return OperandFactory._modes[mode]()
  90 
  91 class ShiftKind:
  92 
  93     def generate(self):
  94         self.kind = ["LSL", "LSR", "ASR"][random.randint(0,2)]
  95         return self
  96 
  97     def cstr(self):
  98         return self.kind
  99 
 100 class Instruction(object):
 101 
 102     def __init__(self, name):


 320             0x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000, 
 321             0xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000, 
 322             0x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000, 
 323             0x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000, 
 324             0x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000, 
 325             0x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8, 
 326             0x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000, 
 327             0x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff, 
 328             0xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003, 
 329             0xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff, 
 330             0xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000, 
 331             0xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f, 
 332             0xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff, 
 333             0xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff, 
 334             0xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f]
 335 
 336      def generate(self):
 337           AddSubImmOp.generate(self)
 338           self.immed = \
 339               self.immediates32[random.randint(0, len(self.immediates32)-1)] \
 340                 if self.isWord \
 341               else \
 342                 self.immediates[random.randint(0, len(self.immediates)-1)]
 343               
 344           return self
 345                   
 346      def astr(self):
 347           return (super(TwoRegImmedInstruction, self).astr()
 348                   + ', #0x%x' % self.immed)
 349 
 350      def cstr(self):
 351           return super(AddSubImmOp, self).cstr() + "l);"
 352     
 353 class MultiOp():
 354 
 355     def multipleForms(self):
 356          return 3
 357 
 358     def forms(self):
 359          return ["__ pc()", "back", "forth"]
 360 
 361     def aforms(self):


 811         name, self.modes = args
 812         Instruction.__init__(self, name)
 813 
 814     def generate(self):
 815         self.reg = [OperandFactory.create(self.modes[i]).generate() 
 816                     for i in range(self.numRegs)]
 817         return self
 818 
 819     def cstr(self):
 820         formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])
 821         return (formatStr
 822                 % tuple([Instruction.cstr(self)] +
 823                         [str(self.reg[i]) for i in range(self.numRegs)])) # Yowza
 824     
 825     def astr(self):
 826         formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])
 827         return (formatStr
 828                 % tuple([Instruction.astr(self)] +
 829                         [(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)]))
 830 
 831 class LdStSIMDOp(Instruction):
 832     def __init__(self, args):
 833         self._name, self.regnum, self.arrangement, self.addresskind = args
 834 
 835     def generate(self):
 836         self.address = Address().generate(self.addresskind, 0)
 837         self._firstSIMDreg = FloatRegister().generate()
 838         if (self.addresskind  == Address.post):
 839             if (self._name in ["ld1r", "ld2r", "ld3r", "ld4r"]):
 840                 elem_size = {"8B" : 1, "16B" : 1, "4H" : 2, "8H" : 2, "2S" : 4, "4S" : 4, "1D" : 8, "2D" : 8} [self.arrangement]
 841                 self.address.offset = self.regnum * elem_size
 842             else:
 843                 if (self.arrangement in ["8B", "4H", "2S", "1D"]):
 844                     self.address.offset = self.regnum * 8
 845                 else:
 846                     self.address.offset = self.regnum * 16
 847         return self
 848 
 849     def cstr(self):
 850         buf = super(LdStSIMDOp, self).cstr() + str(self._firstSIMDreg)
 851         current = self._firstSIMDreg
 852         for cnt in range(1, self.regnum):
 853             buf = '%s, %s' % (buf, current.nextReg())
 854             current = current.nextReg()
 855         return '%s, __ T%s, %s);' % (buf, self.arrangement, str(self.address))
 856 
 857     def astr(self):
 858         buf = '%s\t{%s.%s' % (self._name, self._firstSIMDreg, self.arrangement)
 859         current = self._firstSIMDreg
 860         for cnt in range(1, self.regnum):
 861             buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
 862             current = current.nextReg()
 863         return  '%s}, %s' % (buf, self.address.astr("x"))
 864 
 865     def aname(self):
 866          return self._name
 867 



















































 868 class LSEOp(Instruction):
 869     def __init__(self, args):
 870         self._name, self.asmname, self.size, self.suffix = args
 871 
 872     def generate(self):
 873         self._name = "%s%s" % (self._name, self.suffix)
 874         self.asmname = "%s%s" % (self.asmname, self.suffix)
 875         self.srcReg = GeneralRegisterOrZr().generate()
 876         self.tgtReg = GeneralRegisterOrZr().generate()
 877         self.adrReg = GeneralRegisterOrSp().generate()
 878 
 879         return self
 880 
 881     def cstr(self):
 882         sizeSpec = {"x" : "Assembler::xword", "w" : "Assembler::word"} [self.size]
 883         return super(LSEOp, self).cstr() + "%s, %s, %s, %s);" % (sizeSpec, self.srcReg, self.tgtReg, self.adrReg)
 884 
 885     def astr(self):
 886         return "%s\t%s, %s, [%s]" % (self.asmname, self.srcReg.astr(self.size), self.tgtReg.astr(self.size), self.adrReg.astr("x"))
 887 


 892     numRegs = 2
 893 
 894 class ThreeRegFloatOp(TwoRegFloatOp):
 895     numRegs = 3
 896 
 897 class FourRegFloatOp(TwoRegFloatOp):
 898     numRegs = 4
 899 
 900 class FloatConvertOp(TwoRegFloatOp):
 901 
 902     def __init__(self, args):
 903         self._cname, self._aname, modes = args
 904         TwoRegFloatOp.__init__(self, [self._cname, modes])
 905 
 906     def aname(self):
 907         return self._aname
 908 
 909     def cname(self):
 910         return self._cname
 911 






 912 class SpecialCases(Instruction):
 913     def __init__(self, data):
 914         self._name = data[0]
 915         self._cstr = data[1]
 916         self._astr = data[2]
 917 
 918     def cstr(self):
 919         return self._cstr
 920 
 921     def astr(self):
 922         return self._astr
 923 
 924 def generate(kind, names):
 925     outfile.write("# " + kind.__name__ + "\n");
 926     print "\n// " + kind.__name__
 927     for name in names:
 928         for i in range(1):
 929              op = kind(name).generate()
 930              if op.multipleForms():
 931                   forms = op.forms()
 932                   aforms = op.aforms()
 933                   for i in range(op.multipleForms()):
 934                        cstr = op.cstr() % forms[i]
 935                        astr = op.astr() % aforms[i]
 936                        print "    %-50s //\t%s" % (cstr, astr)
 937                        outfile.write("\t" + astr + "\n")
 938              else:
 939                   print "    %-50s //\t%s" % (op.cstr(), op.astr())
 940                   outfile.write("\t" + op.astr() + "\n")
 941 
 942 outfile = open("aarch64ops.s", "w")

 943 
 944 print "// BEGIN  Generated code -- do not edit"
 945 print "// Generated by aarch64-asmtest.py"
 946 
 947 print "    Label back, forth;"
 948 print "    __ bind(back);"
 949 
 950 outfile.write("back:\n")
 951 
 952 generate (ArithOp, 
 953           [ "add", "sub", "adds", "subs",
 954             "addw", "subw", "addsw", "subsw",
 955             "and", "orr", "eor", "ands",
 956             "andw", "orrw", "eorw", "andsw", 
 957             "bic", "orn", "eon", "bics", 
 958             "bicw", "ornw", "eonw", "bicsw" ])
 959 
 960 generate (AddSubImmOp, 
 961           [ "addw", "addsw", "subw", "subsw",
 962             "add", "adds", "sub", "subs"])


1059           ])
1060 
1061 generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"],
1062                           ["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"],
1063                           ["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"],
1064                           ["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"],
1065                           ["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"],
1066                           ["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]])
1067 
1068 generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"], 
1069                          ["fcmps", "sz"], ["fcmpd", "dz"]])
1070 
1071 for kind in range(3):
1072      generate(LoadStorePairOp, [["stp", "stp", kind, "w"], ["ldp", "ldp", kind, "w"],
1073                                 ["ldpsw", "ldpsw", kind, "x"], 
1074                                 ["stp", "stp", kind, "x"], ["ldp", "ldp", kind, "x"]
1075                                 ])
1076 generate(LoadStorePairOp, [["stnp", "stnp", 0, "w"], ["ldnp", "ldnp", 0, "w"],
1077                            ["stnp", "stnp", 0, "x"], ["ldnp", "ldnp", 0, "x"]])
1078 
1079 generate(LdStSIMDOp, [["ld1",  1, "8B",  Address.base_only],
1080                       ["ld1",  2, "16B", Address.post],
1081                       ["ld1",  3, "1D",  Address.post_reg],
1082                       ["ld1",  4, "8H",  Address.post],
1083                       ["ld1r", 1, "8B",  Address.base_only],
1084                       ["ld1r", 1, "4S",  Address.post],
1085                       ["ld1r", 1, "1D",  Address.post_reg],
1086                       ["ld2",  2, "2D",  Address.base_only],
1087                       ["ld2",  2, "4H",  Address.post],
1088                       ["ld2r", 2, "16B", Address.base_only],
1089                       ["ld2r", 2, "2S",  Address.post],
1090                       ["ld2r", 2, "2D",  Address.post_reg],
1091                       ["ld3",  3, "4S",  Address.post_reg],
1092                       ["ld3",  3, "2S",  Address.base_only],
1093                       ["ld3r", 3, "8H",  Address.base_only],
1094                       ["ld3r", 3, "4S",  Address.post],
1095                       ["ld3r", 3, "1D",  Address.post_reg],
1096                       ["ld4",  4, "8H",  Address.post],
1097                       ["ld4",  4, "8B",  Address.post_reg],
1098                       ["ld4r", 4, "8B",  Address.base_only],
1099                       ["ld4r", 4, "4H",  Address.post],
1100                       ["ld4r", 4, "2S",  Address.post_reg],
1101 ])
1102 























































































1103 generate(SpecialCases, [["ccmn",   "__ ccmn(zr, zr, 3u, Assembler::LE);",                "ccmn\txzr, xzr, #3, LE"],
1104                         ["ccmnw",  "__ ccmnw(zr, zr, 5u, Assembler::EQ);",               "ccmn\twzr, wzr, #5, EQ"],
1105                         ["ccmp",   "__ ccmp(zr, 1, 4u, Assembler::NE);",                 "ccmp\txzr, 1, #4, NE"],
1106                         ["ccmpw",  "__ ccmpw(zr, 2, 2, Assembler::GT);",                 "ccmp\twzr, 2, #2, GT"],
1107                         ["extr",   "__ extr(zr, zr, zr, 0);",                            "extr\txzr, xzr, xzr, 0"],
1108                         ["stlxp",  "__ stlxp(r0, zr, zr, sp);",                          "stlxp\tw0, xzr, xzr, [sp]"],
1109                         ["stlxpw", "__ stlxpw(r2, zr, zr, r3);",                         "stlxp\tw2, wzr, wzr, [x3]"],
1110                         ["stxp",   "__ stxp(r4, zr, zr, r5);",                           "stxp\tw4, xzr, xzr, [x5]"],
1111                         ["stxpw",  "__ stxpw(r6, zr, zr, sp);",                          "stxp\tw6, wzr, wzr, [sp]"],
1112                         ["dup",    "__ dup(v0, __ T16B, zr);",                           "dup\tv0.16b, wzr"],
1113                         ["mov",    "__ mov(v1, __ T1D, 0, zr);",                         "mov\tv1.d[0], xzr"],
1114                         ["mov",    "__ mov(v1, __ T2S, 1, zr);",                         "mov\tv1.s[1], wzr"],
1115                         ["mov",    "__ mov(v1, __ T4H, 2, zr);",                         "mov\tv1.h[2], wzr"],
1116                         ["mov",    "__ mov(v1, __ T8B, 3, zr);",                         "mov\tv1.b[3], wzr"],
1117                         ["ld1",    "__ ld1(v31, v0, __ T2D, Address(__ post(r1, r0)));", "ld1\t{v31.2d, v0.2d}, [x1], x0"]])
1118 
1119 print "\n// FloatImmediateOp"
1120 for float in ("2.0", "2.125", "4.0", "4.25", "8.0", "8.5", "16.0", "17.0", "0.125", 
1121               "0.1328125", "0.25", "0.265625", "0.5", "0.53125", "1.0", "1.0625", 
1122               "-2.0", "-2.125", "-4.0", "-4.25", "-8.0", "-8.5", "-16.0", "-17.0", 


1127     outfile.write("\t" + astr + "\n")
1128 
1129 # ARMv8.1A
1130 for size in ("x", "w"):
1131     for suffix in ("", "a", "al", "l"):
1132         generate(LSEOp, [["swp", "swp", size, suffix],
1133                          ["ldadd", "ldadd", size, suffix],
1134                          ["ldbic", "ldclr", size, suffix],
1135                          ["ldeor", "ldeor", size, suffix],
1136                          ["ldorr", "ldset", size, suffix],
1137                          ["ldsmin", "ldsmin", size, suffix],
1138                          ["ldsmax", "ldsmax", size, suffix],
1139                          ["ldumin", "ldumin", size, suffix],
1140                          ["ldumax", "ldumax", size, suffix]]);
1141 
1142 print "\n    __ bind(forth);"
1143 outfile.write("forth:\n")
1144 
1145 outfile.close()
1146 
1147 import subprocess
1148 import sys
1149 
1150 # compile for 8.1 because of lse atomics
1151 subprocess.check_call([AARCH64_AS, "-march=armv8.1-a", "aarch64ops.s", "-o", "aarch64ops.o"])

1152 
1153 print
1154 print "/*",
1155 sys.stdout.flush()
1156 subprocess.check_call([AARCH64_OBJDUMP, "-d", "aarch64ops.o"])
1157 print "*/"
1158 
1159 subprocess.check_call([AARCH64_OBJCOPY, "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"])
1160 
1161 infile = open("aarch64ops.bin", "r")
1162 bytes = bytearray(infile.read())
1163 
1164 print
1165 print "  static const unsigned int insns[] ="
1166 print "  {"
1167 
1168 i = 0
1169 while i < len(bytes):
1170      print "    0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]),
1171      i += 4
1172      if i%16 == 0:
1173           print
1174 print "\n  };"
1175 print "// END  Generated code -- do not edit"
1176 










1177 


   1 import os
   2 import random
   3 import subprocess
   4 import sys
   5 
   6 AARCH64_AS = "<PATH-TO-AS>"
   7 AARCH64_OBJDUMP = "<PATH-TO-OBJDUMP>"
   8 AARCH64_OBJCOPY = "<PATH-TO-OBJCOPY>"
   9 
  10 # To minimize the changes of assembler test code
  11 random.seed(0)
  12 
  13 class Operand(object):
  14 
  15      def generate(self):
  16         return self
  17 
  18 class Register(Operand):
  19 
  20     def generate(self):
  21         self.number = random.randint(0, 30)
  22         return self
  23 
  24     def astr(self, prefix):
  25         return prefix + str(self.number)
  26 
  27 class FloatRegister(Register):
  28 
  29     def __str__(self):
  30         return self.astr("v")
  31 
  32     def nextReg(self):


  69             return prefix + str(self.number)
  70 
  71     def __str__(self):
  72         if (self.number == 31):
  73             return self.astr()
  74         else:
  75             return self.astr("r")
  76 
  77 class FloatZero(Operand):
  78 
  79     def __str__(self):
  80         return "0.0"
  81 
  82     def astr(self, ignored):
  83         return "#0.0"
  84 
  85 class OperandFactory:
  86 
  87     _modes = {'x' : GeneralRegister,
  88               'w' : GeneralRegister,
  89               'b' : FloatRegister,
  90               'h' : FloatRegister,
  91               's' : FloatRegister,
  92               'd' : FloatRegister,
  93               'z' : FloatZero}
  94 
  95     @classmethod
  96     def create(cls, mode):
  97         return OperandFactory._modes[mode]()
  98 
  99 class ShiftKind:
 100 
 101     def generate(self):
 102         self.kind = ["LSL", "LSR", "ASR"][random.randint(0,2)]
 103         return self
 104 
 105     def cstr(self):
 106         return self.kind
 107 
 108 class Instruction(object):
 109 
 110     def __init__(self, name):


 328             0x3fe0000, 0x1ffc0000, 0xf8000000, 0x3ffffc000,
 329             0xffffffe00, 0x3ffffff800, 0xffffc00000, 0x3f000000000,
 330             0x7fffffff800, 0x1fe000001fe0, 0x3ffffff80000, 0xc00000000000,
 331             0x1ffc000000000, 0x3ffff0003ffff, 0x7ffffffe00000, 0xfffffffffc000,
 332             0x1ffffffffffc00, 0x3fffffffffff00, 0x7ffffffffffc00, 0xffffffffff8000,
 333             0x1ffffffff800000, 0x3fffffc03fffffc, 0x7fffc0000000000, 0xff80ff80ff80ff8,
 334             0x1c00000000000000, 0x1fffffffffff0000, 0x3fffff803fffff80, 0x7fc000007fc00000,
 335             0x8000000000000000, 0x803fffff803fffff, 0xc000007fc000007f, 0xe00000000000ffff,
 336             0xe3ffffffffffffff, 0xf007f007f007f007, 0xf80003ffffffffff, 0xfc000003fc000003,
 337             0xfe000000007fffff, 0xff00000000007fff, 0xff800000000003ff, 0xffc00000000000ff,
 338             0xffe00000000003ff, 0xfff0000000003fff, 0xfff80000001fffff, 0xfffc0000fffc0000,
 339             0xfffe003fffffffff, 0xffff3fffffffffff, 0xffffc0000007ffff, 0xffffe01fffffe01f,
 340             0xfffff800000007ff, 0xfffffc0fffffffff, 0xffffff00003fffff, 0xffffffc0000007ff,
 341             0xfffffff0000001ff, 0xfffffffc00003fff, 0xffffffff07ffffff, 0xffffffffe003ffff,
 342             0xfffffffffc01ffff, 0xffffffffffc00003, 0xfffffffffffc000f, 0xffffffffffffe07f]
 343 
 344      def generate(self):
 345           AddSubImmOp.generate(self)
 346           self.immed = \
 347               self.immediates32[random.randint(0, len(self.immediates32)-1)] \
 348               if self.isWord else \

 349               self.immediates[random.randint(0, len(self.immediates)-1)]
 350 
 351           return self
 352 
 353      def astr(self):
 354           return (super(TwoRegImmedInstruction, self).astr()
 355                   + ', #0x%x' % self.immed)
 356 
 357      def cstr(self):
 358           return super(AddSubImmOp, self).cstr() + "l);"
 359 
 360 class MultiOp():
 361 
 362     def multipleForms(self):
 363          return 3
 364 
 365     def forms(self):
 366          return ["__ pc()", "back", "forth"]
 367 
 368     def aforms(self):


 818         name, self.modes = args
 819         Instruction.__init__(self, name)
 820 
 821     def generate(self):
 822         self.reg = [OperandFactory.create(self.modes[i]).generate()
 823                     for i in range(self.numRegs)]
 824         return self
 825 
 826     def cstr(self):
 827         formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)] + [");"])
 828         return (formatStr
 829                 % tuple([Instruction.cstr(self)] +
 830                         [str(self.reg[i]) for i in range(self.numRegs)])) # Yowza
 831 
 832     def astr(self):
 833         formatStr = "%s%s" + ''.join([", %s" for i in range(1, self.numRegs)])
 834         return (formatStr
 835                 % tuple([Instruction.astr(self)] +
 836                         [(self.reg[i].astr(self.modes[i])) for i in range(self.numRegs)]))
 837 
 838 class LdStNEONOp(Instruction):
 839     def __init__(self, args):
 840         self._name, self.regnum, self.arrangement, self.addresskind = args
 841 
 842     def generate(self):
 843         self.address = Address().generate(self.addresskind, 0)
 844         self._firstSIMDreg = FloatRegister().generate()
 845         if (self.addresskind  == Address.post):
 846             if (self._name in ["ld1r", "ld2r", "ld3r", "ld4r"]):
 847                 elem_size = {"8B" : 1, "16B" : 1, "4H" : 2, "8H" : 2, "2S" : 4, "4S" : 4, "1D" : 8, "2D" : 8} [self.arrangement]
 848                 self.address.offset = self.regnum * elem_size
 849             else:
 850                 if (self.arrangement in ["8B", "4H", "2S", "1D"]):
 851                     self.address.offset = self.regnum * 8
 852                 else:
 853                     self.address.offset = self.regnum * 16
 854         return self
 855 
 856     def cstr(self):
 857         buf = super(LdStNEONOp, self).cstr() + str(self._firstSIMDreg)
 858         current = self._firstSIMDreg
 859         for cnt in range(1, self.regnum):
 860             buf = '%s, %s' % (buf, current.nextReg())
 861             current = current.nextReg()
 862         return '%s, __ T%s, %s);' % (buf, self.arrangement, str(self.address))
 863 
 864     def astr(self):
 865         buf = '%s\t{%s.%s' % (self._name, self._firstSIMDreg, self.arrangement)
 866         current = self._firstSIMDreg
 867         for cnt in range(1, self.regnum):
 868             buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
 869             current = current.nextReg()
 870         return  '%s}, %s' % (buf, self.address.astr("x"))
 871 
 872     def aname(self):
 873          return self._name
 874 
 875 class NEONReduceInstruction(Instruction):
 876     def __init__(self, args):
 877         self._name, self.insname, self.arrangement = args
 878 
 879     def generate(self):
 880         current = FloatRegister().generate()
 881         self.dstSIMDreg = current
 882         self.srcSIMDreg = current.nextReg()
 883         return self
 884 
 885     def cstr(self):
 886         buf = Instruction.cstr(self) + str(self.dstSIMDreg)
 887         buf = '%s, __ T%s, %s);' % (buf, self.arrangement, self.srcSIMDreg)
 888         return buf
 889 
 890     def astr(self):
 891         buf = '%s\t%s' % (self.insname, self.dstSIMDreg.astr(self.arrangement[-1].lower()))
 892         buf = '%s, %s.%s' % (buf, self.srcSIMDreg, self.arrangement)
 893         return buf
 894 
 895     def aname(self):
 896         return self._name
 897 
 898 class CommonNEONInstruction(Instruction):
 899     def __init__(self, args):
 900         self._name, self.insname, self.arrangement = args
 901 
 902     def generate(self):
 903         self._firstSIMDreg = FloatRegister().generate()
 904         return self
 905 
 906     def cstr(self):
 907         buf = Instruction.cstr(self) + str(self._firstSIMDreg)
 908         buf = '%s, __ T%s' % (buf, self.arrangement)
 909         current = self._firstSIMDreg
 910         for cnt in range(1, self.numRegs):
 911             buf = '%s, %s' % (buf, current.nextReg())
 912             current = current.nextReg()
 913         return '%s);' % (buf)
 914 
 915     def astr(self):
 916         buf = '%s\t%s.%s' % (self.insname, self._firstSIMDreg, self.arrangement)
 917         current = self._firstSIMDreg
 918         for cnt in range(1, self.numRegs):
 919             buf = '%s, %s.%s' % (buf, current.nextReg(), self.arrangement)
 920             current = current.nextReg()
 921         return buf
 922 
 923     def aname(self):
 924         return self._name
 925 
 926 class LSEOp(Instruction):
 927     def __init__(self, args):
 928         self._name, self.asmname, self.size, self.suffix = args
 929 
 930     def generate(self):
 931         self._name = "%s%s" % (self._name, self.suffix)
 932         self.asmname = "%s%s" % (self.asmname, self.suffix)
 933         self.srcReg = GeneralRegisterOrZr().generate()
 934         self.tgtReg = GeneralRegisterOrZr().generate()
 935         self.adrReg = GeneralRegisterOrSp().generate()
 936 
 937         return self
 938 
 939     def cstr(self):
 940         sizeSpec = {"x" : "Assembler::xword", "w" : "Assembler::word"} [self.size]
 941         return super(LSEOp, self).cstr() + "%s, %s, %s, %s);" % (sizeSpec, self.srcReg, self.tgtReg, self.adrReg)
 942 
 943     def astr(self):
 944         return "%s\t%s, %s, [%s]" % (self.asmname, self.srcReg.astr(self.size), self.tgtReg.astr(self.size), self.adrReg.astr("x"))
 945 


 950     numRegs = 2
 951 
 952 class ThreeRegFloatOp(TwoRegFloatOp):
 953     numRegs = 3
 954 
 955 class FourRegFloatOp(TwoRegFloatOp):
 956     numRegs = 4
 957 
 958 class FloatConvertOp(TwoRegFloatOp):
 959 
 960     def __init__(self, args):
 961         self._cname, self._aname, modes = args
 962         TwoRegFloatOp.__init__(self, [self._cname, modes])
 963 
 964     def aname(self):
 965         return self._aname
 966 
 967     def cname(self):
 968         return self._cname
 969 
 970 class TwoRegNEONOp(CommonNEONInstruction):
 971     numRegs = 2
 972 
 973 class ThreeRegNEONOp(TwoRegNEONOp):
 974     numRegs = 3
 975 
 976 class SpecialCases(Instruction):
 977     def __init__(self, data):
 978         self._name = data[0]
 979         self._cstr = data[1]
 980         self._astr = data[2]
 981 
 982     def cstr(self):
 983         return self._cstr
 984 
 985     def astr(self):
 986         return self._astr
 987 
 988 def generate(kind, names):
 989     outfile.write("# " + kind.__name__ + "\n");
 990     print "\n// " + kind.__name__
 991     for name in names:
 992         for i in range(1):
 993              op = kind(name).generate()
 994              if op.multipleForms():
 995                   forms = op.forms()
 996                   aforms = op.aforms()
 997                   for i in range(op.multipleForms()):
 998                        cstr = op.cstr() % forms[i]
 999                        astr = op.astr() % aforms[i]
1000                        print "    %-50s //\t%s" % (cstr, astr)
1001                        outfile.write("\t" + astr + "\n")
1002              else:
1003                   print "    %-50s //\t%s" % (op.cstr(), op.astr())
1004                   outfile.write("\t" + op.astr() + "\n")
1005 
1006 outfile = open("aarch64ops.s", "w")
1007 sys.stdout = open("aarch64ops.asm", "w")
1008 
1009 print "// BEGIN  Generated code -- do not edit"
1010 print "// Generated by aarch64-asmtest.py"
1011 
1012 print "    Label back, forth;"
1013 print "    __ bind(back);"
1014 
1015 outfile.write("back:\n")
1016 
1017 generate (ArithOp,
1018           [ "add", "sub", "adds", "subs",
1019             "addw", "subw", "addsw", "subsw",
1020             "and", "orr", "eor", "ands",
1021             "andw", "orrw", "eorw", "andsw",
1022             "bic", "orn", "eon", "bics",
1023             "bicw", "ornw", "eonw", "bicsw" ])
1024 
1025 generate (AddSubImmOp,
1026           [ "addw", "addsw", "subw", "subsw",
1027             "add", "adds", "sub", "subs"])


1124           ])
1125 
1126 generate(FloatConvertOp, [["fcvtzsw", "fcvtzs", "ws"], ["fcvtzs", "fcvtzs", "xs"],
1127                           ["fcvtzdw", "fcvtzs", "wd"], ["fcvtzd", "fcvtzs", "xd"],
1128                           ["scvtfws", "scvtf", "sw"], ["scvtfs", "scvtf", "sx"],
1129                           ["scvtfwd", "scvtf", "dw"], ["scvtfd", "scvtf", "dx"],
1130                           ["fmovs", "fmov", "ws"], ["fmovd", "fmov", "xd"],
1131                           ["fmovs", "fmov", "sw"], ["fmovd", "fmov", "dx"]])
1132 
1133 generate(TwoRegFloatOp, [["fcmps", "ss"], ["fcmpd", "dd"],
1134                          ["fcmps", "sz"], ["fcmpd", "dz"]])
1135 
1136 for kind in range(3):
1137      generate(LoadStorePairOp, [["stp", "stp", kind, "w"], ["ldp", "ldp", kind, "w"],
1138                                 ["ldpsw", "ldpsw", kind, "x"],
1139                                 ["stp", "stp", kind, "x"], ["ldp", "ldp", kind, "x"]
1140                                 ])
1141 generate(LoadStorePairOp, [["stnp", "stnp", 0, "w"], ["ldnp", "ldnp", 0, "w"],
1142                            ["stnp", "stnp", 0, "x"], ["ldnp", "ldnp", 0, "x"]])
1143 
1144 generate(LdStNEONOp, [["ld1",  1, "8B",  Address.base_only],
1145                       ["ld1",  2, "16B", Address.post],
1146                       ["ld1",  3, "1D",  Address.post_reg],
1147                       ["ld1",  4, "8H",  Address.post],
1148                       ["ld1r", 1, "8B",  Address.base_only],
1149                       ["ld1r", 1, "4S",  Address.post],
1150                       ["ld1r", 1, "1D",  Address.post_reg],
1151                       ["ld2",  2, "2D",  Address.base_only],
1152                       ["ld2",  2, "4H",  Address.post],
1153                       ["ld2r", 2, "16B", Address.base_only],
1154                       ["ld2r", 2, "2S",  Address.post],
1155                       ["ld2r", 2, "2D",  Address.post_reg],
1156                       ["ld3",  3, "4S",  Address.post_reg],
1157                       ["ld3",  3, "2S",  Address.base_only],
1158                       ["ld3r", 3, "8H",  Address.base_only],
1159                       ["ld3r", 3, "4S",  Address.post],
1160                       ["ld3r", 3, "1D",  Address.post_reg],
1161                       ["ld4",  4, "8H",  Address.post],
1162                       ["ld4",  4, "8B",  Address.post_reg],
1163                       ["ld4r", 4, "8B",  Address.base_only],
1164                       ["ld4r", 4, "4H",  Address.post],
1165                       ["ld4r", 4, "2S",  Address.post_reg],
1166 ])
1167 
1168 generate(NEONReduceInstruction,
1169          [["addv", "addv", "8B"], ["addv", "addv", "16B"],
1170           ["addv", "addv", "4H"], ["addv", "addv", "8H"],
1171           ["addv", "addv", "4S"],
1172           ["smaxv", "smaxv", "8B"], ["smaxv", "smaxv", "16B"],
1173           ["smaxv", "smaxv", "4H"], ["smaxv", "smaxv", "8H"],
1174           ["smaxv", "smaxv", "4S"], ["fmaxv", "fmaxv", "4S"],
1175           ["sminv", "sminv", "8B"], ["sminv", "sminv", "16B"],
1176           ["sminv", "sminv", "4H"], ["sminv", "sminv", "8H"],
1177           ["sminv", "sminv", "4S"], ["fminv", "fminv", "4S"],
1178           ])
1179 
1180 generate(TwoRegNEONOp,
1181          [["absr", "abs", "8B"], ["absr", "abs", "16B"],
1182           ["absr", "abs", "4H"], ["absr", "abs", "8H"],
1183           ["absr", "abs", "2S"], ["absr", "abs", "4S"],
1184           ["absr", "abs", "2D"],
1185           ["fabs", "fabs", "2S"], ["fabs", "fabs", "4S"],
1186           ["fabs", "fabs", "2D"],
1187           ["fneg", "fneg", "2S"], ["fneg", "fneg", "4S"],
1188           ["fneg", "fneg", "2D"],
1189           ["fsqrt", "fsqrt", "2S"], ["fsqrt", "fsqrt", "4S"],
1190           ["fsqrt", "fsqrt", "2D"],
1191           ["notr", "not", "8B"], ["notr", "not", "16B"],
1192           ])
1193 
1194 generate(ThreeRegNEONOp,
1195          [["andr", "and", "8B"], ["andr", "and", "16B"],
1196           ["orr", "orr", "8B"], ["orr", "orr", "16B"],
1197           ["eor", "eor", "8B"], ["eor", "eor", "16B"],
1198           ["addv", "add", "8B"], ["addv", "add", "16B"],
1199           ["addv", "add", "4H"], ["addv", "add", "8H"],
1200           ["addv", "add", "2S"], ["addv", "add", "4S"],
1201           ["addv", "add", "2D"],
1202           ["fadd", "fadd", "2S"], ["fadd", "fadd", "4S"],
1203           ["fadd", "fadd", "2D"],
1204           ["subv", "sub", "8B"], ["subv", "sub", "16B"],
1205           ["subv", "sub", "4H"], ["subv", "sub", "8H"],
1206           ["subv", "sub", "2S"], ["subv", "sub", "4S"],
1207           ["subv", "sub", "2D"],
1208           ["fsub", "fsub", "2S"], ["fsub", "fsub", "4S"],
1209           ["fsub", "fsub", "2D"],
1210           ["mulv", "mul", "8B"], ["mulv", "mul", "16B"],
1211           ["mulv", "mul", "4H"], ["mulv", "mul", "8H"],
1212           ["mulv", "mul", "2S"], ["mulv", "mul", "4S"],
1213           ["fmul", "fmul", "2S"], ["fmul", "fmul", "4S"],
1214           ["fmul", "fmul", "2D"],
1215           ["mlav", "mla", "4H"], ["mlav", "mla", "8H"],
1216           ["mlav", "mla", "2S"], ["mlav", "mla", "4S"],
1217           ["fmla", "fmla", "2S"], ["fmla", "fmla", "4S"],
1218           ["fmla", "fmla", "2D"],
1219           ["mlsv", "mls", "4H"], ["mlsv", "mls", "8H"],
1220           ["mlsv", "mls", "2S"], ["mlsv", "mls", "4S"],
1221           ["fmls", "fmls", "2S"], ["fmls", "fmls", "4S"],
1222           ["fmls", "fmls", "2D"],
1223           ["fdiv", "fdiv", "2S"], ["fdiv", "fdiv", "4S"],
1224           ["fdiv", "fdiv", "2D"],
1225           ["maxv", "smax", "8B"], ["maxv", "smax", "16B"],
1226           ["maxv", "smax", "4H"], ["maxv", "smax", "8H"],
1227           ["maxv", "smax", "2S"], ["maxv", "smax", "4S"],
1228           ["fmax", "fmax", "2S"], ["fmax", "fmax", "4S"],
1229           ["fmax", "fmax", "2D"],
1230           ["minv", "smin", "8B"], ["minv", "smin", "16B"],
1231           ["minv", "smin", "4H"], ["minv", "smin", "8H"],
1232           ["minv", "smin", "2S"], ["minv", "smin", "4S"],
1233           ["fmin", "fmin", "2S"], ["fmin", "fmin", "4S"],
1234           ["fmin", "fmin", "2D"],
1235           ["cmeq", "cmeq", "8B"], ["cmeq", "cmeq", "16B"],
1236           ["cmeq", "cmeq", "4H"], ["cmeq", "cmeq", "8H"],
1237           ["cmeq", "cmeq", "2S"], ["cmeq", "cmeq", "4S"],
1238           ["cmeq", "cmeq", "2D"],
1239           ["fcmeq", "fcmeq", "2S"], ["fcmeq", "fcmeq", "4S"],
1240           ["fcmeq", "fcmeq", "2D"],
1241           ["cmgt", "cmgt", "8B"], ["cmgt", "cmgt", "16B"],
1242           ["cmgt", "cmgt", "4H"], ["cmgt", "cmgt", "8H"],
1243           ["cmgt", "cmgt", "2S"], ["cmgt", "cmgt", "4S"],
1244           ["cmgt", "cmgt", "2D"],
1245           ["fcmgt", "fcmgt", "2S"], ["fcmgt", "fcmgt", "4S"],
1246           ["fcmgt", "fcmgt", "2D"],
1247           ["cmge", "cmge", "8B"], ["cmge", "cmge", "16B"],
1248           ["cmge", "cmge", "4H"], ["cmge", "cmge", "8H"],
1249           ["cmge", "cmge", "2S"], ["cmge", "cmge", "4S"],
1250           ["cmge", "cmge", "2D"],
1251           ["fcmge", "fcmge", "2S"], ["fcmge", "fcmge", "4S"],
1252           ["fcmge", "fcmge", "2D"],
1253           ])
1254 
1255 generate(SpecialCases, [["ccmn",   "__ ccmn(zr, zr, 3u, Assembler::LE);",                "ccmn\txzr, xzr, #3, LE"],
1256                         ["ccmnw",  "__ ccmnw(zr, zr, 5u, Assembler::EQ);",               "ccmn\twzr, wzr, #5, EQ"],
1257                         ["ccmp",   "__ ccmp(zr, 1, 4u, Assembler::NE);",                 "ccmp\txzr, 1, #4, NE"],
1258                         ["ccmpw",  "__ ccmpw(zr, 2, 2, Assembler::GT);",                 "ccmp\twzr, 2, #2, GT"],
1259                         ["extr",   "__ extr(zr, zr, zr, 0);",                            "extr\txzr, xzr, xzr, 0"],
1260                         ["stlxp",  "__ stlxp(r0, zr, zr, sp);",                          "stlxp\tw0, xzr, xzr, [sp]"],
1261                         ["stlxpw", "__ stlxpw(r2, zr, zr, r3);",                         "stlxp\tw2, wzr, wzr, [x3]"],
1262                         ["stxp",   "__ stxp(r4, zr, zr, r5);",                           "stxp\tw4, xzr, xzr, [x5]"],
1263                         ["stxpw",  "__ stxpw(r6, zr, zr, sp);",                          "stxp\tw6, wzr, wzr, [sp]"],
1264                         ["dup",    "__ dup(v0, __ T16B, zr);",                           "dup\tv0.16b, wzr"],
1265                         ["mov",    "__ mov(v1, __ T1D, 0, zr);",                         "mov\tv1.d[0], xzr"],
1266                         ["mov",    "__ mov(v1, __ T2S, 1, zr);",                         "mov\tv1.s[1], wzr"],
1267                         ["mov",    "__ mov(v1, __ T4H, 2, zr);",                         "mov\tv1.h[2], wzr"],
1268                         ["mov",    "__ mov(v1, __ T8B, 3, zr);",                         "mov\tv1.b[3], wzr"],
1269                         ["ld1",    "__ ld1(v31, v0, __ T2D, Address(__ post(r1, r0)));", "ld1\t{v31.2d, v0.2d}, [x1], x0"]])
1270 
1271 print "\n// FloatImmediateOp"
1272 for float in ("2.0", "2.125", "4.0", "4.25", "8.0", "8.5", "16.0", "17.0", "0.125",
1273               "0.1328125", "0.25", "0.265625", "0.5", "0.53125", "1.0", "1.0625",
1274               "-2.0", "-2.125", "-4.0", "-4.25", "-8.0", "-8.5", "-16.0", "-17.0",


1279     outfile.write("\t" + astr + "\n")
1280 
1281 # ARMv8.1A
1282 for size in ("x", "w"):
1283     for suffix in ("", "a", "al", "l"):
1284         generate(LSEOp, [["swp", "swp", size, suffix],
1285                          ["ldadd", "ldadd", size, suffix],
1286                          ["ldbic", "ldclr", size, suffix],
1287                          ["ldeor", "ldeor", size, suffix],
1288                          ["ldorr", "ldset", size, suffix],
1289                          ["ldsmin", "ldsmin", size, suffix],
1290                          ["ldsmax", "ldsmax", size, suffix],
1291                          ["ldumin", "ldumin", size, suffix],
1292                          ["ldumax", "ldumax", size, suffix]]);
1293 
1294 print "\n    __ bind(forth);"
1295 outfile.write("forth:\n")
1296 
1297 outfile.close()
1298 



1299 # compile for 8.1 because of lse atomics
1300 subprocess.check_call([AARCH64_AS, "-march=armv8.1-a", "aarch64ops.s", "-o", "aarch64ops.o"])
1301 output = subprocess.check_output([AARCH64_OBJDUMP, "-d", "aarch64ops.o"])
1302 
1303 print
1304 print "/*"
1305 print output

1306 print "*/"
1307 
1308 subprocess.check_call([AARCH64_OBJCOPY, "-O", "binary", "-j", ".text", "aarch64ops.o", "aarch64ops.bin"])
1309 
1310 infile = open("aarch64ops.bin", "r")
1311 bytes = bytearray(infile.read())
1312 
1313 print
1314 print "  static const unsigned int insns[] ="
1315 print "  {"
1316 
1317 i = 0
1318 while i < len(bytes):
1319      print "    0x%02x%02x%02x%02x," % (bytes[i+3], bytes[i+2], bytes[i+1], bytes[i]),
1320      i += 4
1321      if i%16 == 0:
1322           print
1323 print "\n  };"
1324 print "// END  Generated code -- do not edit"
1325 
1326 infile.close()
1327 sys.stdout.close()
1328 
1329 # Remove trailing spaces and replace tab with 4 spaces
1330 sys.stdout = sys.__stdout__
1331 with open("aarch64ops.asm", "r") as infile:
1332     for line in infile:
1333         line = line.rstrip()
1334         line = line.replace("\t", "    ")
1335         print line
1336 
1337 for f in ["aarch64ops.s", "aarch64ops.o", "aarch64ops.bin", "aarch64ops.asm"]:
1338     os.remove(f)
< prev index next >