1import os
2import sys
3
4class RegAliases(object):
5  def __init__(self, AliasesStr):
6    self.Aliases = list(Alias.strip() for Alias in AliasesStr.split(','))
7
8  def __str__(self):
9    return 'REGLIST{AliasCount}(RegARM32, {Aliases})'.format(
10      AliasCount=len(self.Aliases), Aliases=', '.join(self.Aliases))
11
12def _ArgumentNames(Method):
13  import inspect
14  return (ArgName for ArgName in inspect.getargspec(Method).args
15      if ArgName != 'self')
16
17class RegFeatures(object):
18  def __init__(self, AsmStr=None, CCArg=0, IsScratch=0, IsPreserved=0,
19               IsStackPtr=0, IsFramePtr=0, IsGPR=0, IsInt=0, IsI64Pair=0,
20               IsFP32=0, IsFP64=0, IsVec128=0, Aliases=None):
21    assert (not IsInt) or IsGPR
22    assert (not IsI64Pair) or (not IsGPR)
23    assert not (IsInt and IsI64Pair)
24    assert not (IsFP32 and IsFP64)
25    assert not (IsFP32 and IsVec128)
26    assert not (IsFP64 and IsVec128)
27    assert not ((IsGPR) and (IsFP32 or IsFP64 or IsVec128))
28    assert (not IsFramePtr) or IsGPR
29    assert (not IsStackPtr) or IsGPR
30    assert not (IsScratch and IsPreserved)
31    self.Features = [x for x in _ArgumentNames(self.__init__)]
32    self.FeaturesDict = {}
33    # The argument Aliases is a string with the register aliasing information.
34    # The next line convert it to a RegAlias object, for pretty printing.
35    Aliases = RegAliases(Aliases)
36    AsmStr = '"%s"' % AsmStr
37    for Feature in self.Features:
38      self.FeaturesDict[Feature] = locals()[Feature]
39
40  def __str__(self):
41    return '%s' % (', '.join(str(self.FeaturesDict[Feature]) for
42                                 Feature in self.Features))
43
44  def Aliases(self):
45    return self.FeaturesDict['Aliases']
46
47  def LivesInGPR(self):
48    return (any(self.FeaturesDict[IntFeature] for IntFeature in (
49                   'IsInt', 'IsI64Pair', 'IsStackPtr', 'IsFramePtr')) or
50            not self.LivesInVFP())
51
52  def LivesInVFP(self):
53    return any(self.FeaturesDict[FpFeature] for FpFeature in (
54                   'IsFP32', 'IsFP64', 'IsVec128'))
55
56  def DefiningXMacro(self, OtherFeatures):
57    return 'define X({parameters})'.format(
58        parameters=', '.join(OtherFeatures + self.Features))
59
60class Reg(object):
61  def __init__(self, Name, Encode, AsmStr=None, **Features):
62    self.Name = Name
63    self.Encode = Encode
64    if not AsmStr:
65      AsmStr = '%s' % Name
66    self.Features = RegFeatures(AsmStr=AsmStr, **Features)
67
68  def __str__(self):
69    return 'Reg_{Name}, {Encode}, {Features}'.format(Name=self.Name,
70      Encode=self.Encode, Features=self.Features)
71
72  def IsAnAliasOf(self, Other):
73    return Other.Name in self.Features.Aliases().Aliases
74
75  def DefiningXMacro(self):
76    return self.Features.DefiningXMacro(['Tag', 'Encoding'])
77
78# Note: The following tables break the usual 80-col on purpose -- it is easier
79# to read the register tables if each register entry is contained on a single
80# line.
81GPRs = [
82  Reg( 'r0',  0,   IsScratch=1, CCArg=1, IsGPR = 1, IsInt=1,               Aliases= 'r0,  r0r1'),
83  Reg( 'r1',  1,   IsScratch=1, CCArg=2, IsGPR = 1, IsInt=1,               Aliases= 'r1,  r0r1'),
84  Reg( 'r2',  2,   IsScratch=1, CCArg=3, IsGPR = 1, IsInt=1,               Aliases= 'r2,  r2r3'),
85  Reg( 'r3',  3,   IsScratch=1, CCArg=4, IsGPR = 1, IsInt=1,               Aliases= 'r3,  r2r3'),
86  Reg( 'r4',  4, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases= 'r4,  r4r5'),
87  Reg( 'r5',  5, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases= 'r5,  r4r5'),
88  Reg( 'r6',  6, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases= 'r6,  r6r7'),
89  Reg( 'r7',  7, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases= 'r7,  r6r7'),
90  Reg( 'r8',  8, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases= 'r8,  r8r9'),
91  Reg( 'r9',  9, IsPreserved=1,          IsGPR = 1, IsInt=0,               Aliases= 'r9,  r8r9'),
92  Reg('r10', 10, IsPreserved=1,          IsGPR = 1, IsInt=1,               Aliases='r10, r10fp'),
93  Reg( 'fp', 11, IsPreserved=1,          IsGPR = 1, IsInt=1, IsFramePtr=1, Aliases= 'fp, r10fp'),
94  Reg( 'ip', 12,   IsScratch=1,          IsGPR = 1, IsInt=0,               Aliases= 'ip'),
95  Reg( 'sp', 13,   IsScratch=0,          IsGPR = 1, IsInt=0, IsStackPtr=1, Aliases= 'sp'),
96  Reg( 'lr', 14,   IsScratch=0,          IsGPR = 1, IsInt=0,               Aliases= 'lr'),
97  Reg( 'pc', 15,   IsScratch=0,          IsGPR = 1, IsInt=0,               Aliases= 'pc'),
98]
99
100I64Pairs = [
101  Reg( 'r0r1',  0, AsmStr= 'r0, r1',   IsScratch=1, CCArg=1, IsI64Pair=1, Aliases= 'r0r1,  r0, r1'),
102  Reg( 'r2r3',  2, AsmStr= 'r2, r3',   IsScratch=1, CCArg=2, IsI64Pair=1, Aliases= 'r2r3,  r2, r3'),
103  Reg( 'r4r5',  4, AsmStr= 'r4, r5', IsPreserved=1,          IsI64Pair=1, Aliases= 'r4r5,  r4, r5'),
104  Reg( 'r6r7',  6, AsmStr= 'r6, r7', IsPreserved=1,          IsI64Pair=1, Aliases= 'r6r7,  r6, r7'),
105  Reg( 'r8r9',  8, AsmStr= 'r8, r9', IsPreserved=1,          IsI64Pair=0, Aliases= 'r8r9,  r8, r9'),
106  Reg('r10fp', 10, AsmStr='r10, fp', IsPreserved=1,          IsI64Pair=0, Aliases='r10fp, r10, fp'),
107]
108
109FP32 = [
110  Reg( 's0',  0,   IsScratch=1, CCArg=1,  IsFP32=1, Aliases= 's0, d0 , q0'),
111  Reg( 's1',  1,   IsScratch=1, CCArg=2,  IsFP32=1, Aliases= 's1, d0 , q0'),
112  Reg( 's2',  2,   IsScratch=1, CCArg=3,  IsFP32=1, Aliases= 's2, d1 , q0'),
113  Reg( 's3',  3,   IsScratch=1, CCArg=4,  IsFP32=1, Aliases= 's3, d1 , q0'),
114  Reg( 's4',  4,   IsScratch=1, CCArg=5,  IsFP32=1, Aliases= 's4, d2 , q1'),
115  Reg( 's5',  5,   IsScratch=1, CCArg=6,  IsFP32=1, Aliases= 's5, d2 , q1'),
116  Reg( 's6',  6,   IsScratch=1, CCArg=7,  IsFP32=1, Aliases= 's6, d3 , q1'),
117  Reg( 's7',  7,   IsScratch=1, CCArg=8,  IsFP32=1, Aliases= 's7, d3 , q1'),
118  Reg( 's8',  8,   IsScratch=1, CCArg=9,  IsFP32=1, Aliases= 's8, d4 , q2'),
119  Reg( 's9',  9,   IsScratch=1, CCArg=10, IsFP32=1, Aliases= 's9, d4 , q2'),
120  Reg('s10', 10,   IsScratch=1, CCArg=11, IsFP32=1, Aliases='s10, d5 , q2'),
121  Reg('s11', 11,   IsScratch=1, CCArg=12, IsFP32=1, Aliases='s11, d5 , q2'),
122  Reg('s12', 12,   IsScratch=1, CCArg=13, IsFP32=1, Aliases='s12, d6 , q3'),
123  Reg('s13', 13,   IsScratch=1, CCArg=14, IsFP32=1, Aliases='s13, d6 , q3'),
124  Reg('s14', 14,   IsScratch=1, CCArg=15, IsFP32=1, Aliases='s14, d7 , q3'),
125  Reg('s15', 15,   IsScratch=1, CCArg=16, IsFP32=1, Aliases='s15, d7 , q3'),
126  Reg('s16', 16, IsPreserved=1,           IsFP32=1, Aliases='s16, d8 , q4'),
127  Reg('s17', 17, IsPreserved=1,           IsFP32=1, Aliases='s17, d8 , q4'),
128  Reg('s18', 18, IsPreserved=1,           IsFP32=1, Aliases='s18, d9 , q4'),
129  Reg('s19', 19, IsPreserved=1,           IsFP32=1, Aliases='s19, d9 , q4'),
130  Reg('s20', 20, IsPreserved=1,           IsFP32=1, Aliases='s20, d10, q5'),
131  Reg('s21', 21, IsPreserved=1,           IsFP32=1, Aliases='s21, d10, q5'),
132  Reg('s22', 22, IsPreserved=1,           IsFP32=1, Aliases='s22, d11, q5'),
133  Reg('s23', 23, IsPreserved=1,           IsFP32=1, Aliases='s23, d11, q5'),
134  Reg('s24', 24, IsPreserved=1,           IsFP32=1, Aliases='s24, d12, q6'),
135  Reg('s25', 25, IsPreserved=1,           IsFP32=1, Aliases='s25, d12, q6'),
136  Reg('s26', 26, IsPreserved=1,           IsFP32=1, Aliases='s26, d13, q6'),
137  Reg('s27', 27, IsPreserved=1,           IsFP32=1, Aliases='s27, d13, q6'),
138  Reg('s28', 28, IsPreserved=1,           IsFP32=1, Aliases='s28, d14, q7'),
139  Reg('s29', 29, IsPreserved=1,           IsFP32=1, Aliases='s29, d14, q7'),
140  Reg('s30', 30, IsPreserved=1,           IsFP32=1, Aliases='s30, d15, q7'),
141  Reg('s31', 31, IsPreserved=1,           IsFP32=1, Aliases='s31, d15, q7'),
142]
143
144FP64 = [
145  Reg( 'd0',  0,   IsScratch=1, CCArg=1, IsFP64=1, Aliases= 'd0,  q0,  s0,  s1'),
146  Reg( 'd1',  1,   IsScratch=1, CCArg=2, IsFP64=1, Aliases= 'd1,  q0,  s2,  s3'),
147  Reg( 'd2',  2,   IsScratch=1, CCArg=3, IsFP64=1, Aliases= 'd2,  q1,  s4,  s5'),
148  Reg( 'd3',  3,   IsScratch=1, CCArg=4, IsFP64=1, Aliases= 'd3,  q1,  s6,  s7'),
149  Reg( 'd4',  4,   IsScratch=1, CCArg=5, IsFP64=1, Aliases= 'd4,  q2,  s8,  s9'),
150  Reg( 'd5',  5,   IsScratch=1, CCArg=6, IsFP64=1, Aliases= 'd5,  q2, s10, s11'),
151  Reg( 'd6',  6,   IsScratch=1, CCArg=7, IsFP64=1, Aliases= 'd6,  q3, s12, s13'),
152  Reg( 'd7',  7,   IsScratch=1, CCArg=8, IsFP64=1, Aliases= 'd7,  q3, s14, s15'),
153  Reg( 'd8',  8, IsPreserved=1,          IsFP64=1, Aliases= 'd8,  q4, s16, s17'),
154  Reg( 'd9',  9, IsPreserved=1,          IsFP64=1, Aliases= 'd9,  q4, s18, s19'),
155  Reg('d10', 10, IsPreserved=1,          IsFP64=1, Aliases='d10,  q5, s20, s21'),
156  Reg('d11', 11, IsPreserved=1,          IsFP64=1, Aliases='d11,  q5, s22, s23'),
157  Reg('d12', 12, IsPreserved=1,          IsFP64=1, Aliases='d12,  q6, s24, s25'),
158  Reg('d13', 13, IsPreserved=1,          IsFP64=1, Aliases='d13,  q6, s26, s27'),
159  Reg('d14', 14, IsPreserved=1,          IsFP64=1, Aliases='d14,  q7, s28, s29'),
160  Reg('d15', 15, IsPreserved=1,          IsFP64=1, Aliases='d15,  q7, s30, s31'),
161  Reg('d16', 16,   IsScratch=1,          IsFP64=1, Aliases='d16,  q8'),
162  Reg('d17', 17,   IsScratch=1,          IsFP64=1, Aliases='d17,  q8'),
163  Reg('d18', 18,   IsScratch=1,          IsFP64=1, Aliases='d18,  q9'),
164  Reg('d19', 19,   IsScratch=1,          IsFP64=1, Aliases='d19,  q9'),
165  Reg('d20', 20,   IsScratch=1,          IsFP64=1, Aliases='d20, q10'),
166  Reg('d21', 21,   IsScratch=1,          IsFP64=1, Aliases='d21, q10'),
167  Reg('d22', 22,   IsScratch=1,          IsFP64=1, Aliases='d22, q11'),
168  Reg('d23', 23,   IsScratch=1,          IsFP64=1, Aliases='d23, q11'),
169  Reg('d24', 24,   IsScratch=1,          IsFP64=1, Aliases='d24, q12'),
170  Reg('d25', 25,   IsScratch=1,          IsFP64=1, Aliases='d25, q12'),
171  Reg('d26', 26,   IsScratch=1,          IsFP64=1, Aliases='d26, q13'),
172  Reg('d27', 27,   IsScratch=1,          IsFP64=1, Aliases='d27, q13'),
173  Reg('d28', 28,   IsScratch=1,          IsFP64=1, Aliases='d28, q14'),
174  Reg('d29', 29,   IsScratch=1,          IsFP64=1, Aliases='d29, q14'),
175  Reg('d30', 30,   IsScratch=1,          IsFP64=1, Aliases='d30, q15'),
176  Reg('d31', 31,   IsScratch=1,          IsFP64=1, Aliases='d31, q15'),
177]
178
179Vec128 = [
180  Reg( 'q0',  0,   IsScratch=1, CCArg=1, IsVec128=1, Aliases= 'q0,  d0,  d1,  s0,  s1,  s2,  s3'),
181  Reg( 'q1',  1,   IsScratch=1, CCArg=2, IsVec128=1, Aliases= 'q1,  d2,  d3,  s4,  s5,  s6,  s7'),
182  Reg( 'q2',  2,   IsScratch=1, CCArg=3, IsVec128=1, Aliases= 'q2,  d4,  d5,  s8,  s9, s10, s11'),
183  Reg( 'q3',  3,   IsScratch=1, CCArg=4, IsVec128=1, Aliases= 'q3,  d6,  d7, s12, s13, s14, s15'),
184  Reg( 'q4',  4, IsPreserved=1,          IsVec128=1, Aliases= 'q4,  d8,  d9, s16, s17, s18, s19'),
185  Reg( 'q5',  5, IsPreserved=1,          IsVec128=1, Aliases= 'q5, d10, d11, s20, s21, s22, s23'),
186  Reg( 'q6',  6, IsPreserved=1,          IsVec128=1, Aliases= 'q6, d12, d13, s24, s25, s26, s27'),
187  Reg( 'q7',  7, IsPreserved=1,          IsVec128=1, Aliases= 'q7, d14, d15, s28, s29, s30, s31'),
188  Reg( 'q8',  8,   IsScratch=1,          IsVec128=1, Aliases= 'q8, d16, d17'),
189  Reg( 'q9',  9,   IsScratch=1,          IsVec128=1, Aliases= 'q9, d18, d19'),
190  Reg('q10', 10,   IsScratch=1,          IsVec128=1, Aliases='q10, d20, d21'),
191  Reg('q11', 11,   IsScratch=1,          IsVec128=1, Aliases='q11, d22, d23'),
192  Reg('q12', 12,   IsScratch=1,          IsVec128=1, Aliases='q12, d24, d25'),
193  Reg('q13', 13,   IsScratch=1,          IsVec128=1, Aliases='q13, d26, d27'),
194  Reg('q14', 14,   IsScratch=1,          IsVec128=1, Aliases='q14, d28, d29'),
195  Reg('q15', 15,   IsScratch=1,          IsVec128=1, Aliases='q15, d30, d31'),
196]
197
198# TODO(jpp): Fix the pop emission, then emit FP64/Vec128 reverted.
199RegClasses = [('GPR', GPRs),  ('I64PAIR', I64Pairs), ('FP32', FP32),
200              ('FP64', FP64), ('VEC128', Vec128)]
201
202AllRegs = {}
203for _, RegClass in RegClasses:
204  for Reg in RegClass:
205    assert Reg.Name not in AllRegs
206    AllRegs[Reg.Name] = Reg
207
208for _, RegClass in RegClasses:
209  for Reg in RegClass:
210    for Alias in AllRegs[Reg.Name].Features.Aliases().Aliases:
211      assert AllRegs[Alias].IsAnAliasOf(Reg), '%s VS %s' % (Reg, AllRegs[Alias])
212      assert (AllRegs[Alias].Features.LivesInGPR() ==
213                 Reg.Features.LivesInGPR()), '%s VS %s' % (Reg, AllRegs[Alias])
214      assert (AllRegs[Alias].Features.LivesInVFP() ==
215                 Reg.Features.LivesInVFP()), '%s VS %s' % (Reg, AllRegs[Alias])
216
217print ("// This file was auto generated by the {script} script.\n"
218       "// Do not modify it: modify the script instead.\n"
219       "\n"
220       "#ifndef SUBZERO_SRC_ICEREGISTERSARM32_DEF\n"
221       "#define SUBZERO_SRC_ICEREGISTERSARM32_DEF\n".format(script=os.path.basename(sys.argv[0])))
222
223for Name, RegClass in RegClasses:
224  print '//{xmacro}'.format(xmacro=Reg.DefiningXMacro())
225  print "#define REGARM32_%s_TABLE" % Name,
226  for Reg in RegClass:
227    sys.stdout.write(' \\\n  X({Reg})'.format(Reg=Reg))
228  print '\n'
229print "#endif // SUBZERO_SRC_ICEREGISTERSARM32_DEF",
230