Commit 2187c84a by John Porto

Subzero. ARM32. Introduces explicit register parameter attribute.

The ARM32 backend used to rely on a specific register declaration order for calling convention register assignment. This CL introduces a new field in the ARM32 register tables for explicitly setting which register holds which parameter. BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1508423003 .
parent 6106df80
...@@ -323,6 +323,9 @@ $(SB_OBJDIR)/pnacl-sz.x86-32.nexe: $(SB_OBJS) ...@@ -323,6 +323,9 @@ $(SB_OBJDIR)/pnacl-sz.x86-32.nexe: $(SB_OBJS)
$(SB_TRANSLATE) -arch x86-32 $(PNACL_SZ_BASE).nonfinal.pexe -o $@ \ $(SB_TRANSLATE) -arch x86-32 $(PNACL_SZ_BASE).nonfinal.pexe -o $@ \
--allow-llvm-bitcode-input --allow-llvm-bitcode-input
src/IceRegistersARM32.def: pydir/gen_arm32_reg_tables.py
python $< > $@
# TODO(stichnot): Be more precise than "*.h" here and elsewhere. # TODO(stichnot): Be more precise than "*.h" here and elsewhere.
$(OBJS): $(OBJDIR)/%.o: src/%.cpp src/*.h src/*.def $(OBJS): $(OBJDIR)/%.o: src/%.cpp src/*.h src/*.def
$(CXX) -c $(CXXFLAGS) $< -o $@ $(CXX) -c $(CXXFLAGS) $< -o $@
......
import os
import sys
class RegAliases(object): class RegAliases(object):
def __init__(self, *Aliases): def __init__(self, AliasesStr):
self.Aliases = list(Aliases) self.Aliases = list(Alias.strip() for Alias in AliasesStr.split(','))
def __str__(self): def __str__(self):
return 'REGLIST{AliasCount}(RegARM32, {Aliases})'.format( return 'REGLIST{AliasCount}(RegARM32, {Aliases})'.format(
...@@ -12,9 +15,9 @@ def _ArgumentNames(Method): ...@@ -12,9 +15,9 @@ def _ArgumentNames(Method):
if ArgName != 'self') if ArgName != 'self')
class RegFeatures(object): class RegFeatures(object):
def __init__(self, IsScratch=0, IsPreserved=0, IsStackPtr=0, IsFramePtr=0, def __init__(self, AsmStr=None, CCArg=0, IsScratch=0, IsPreserved=0,
IsInt=0, IsI64Pair=0, IsFP32=0, IsFP64=0, IsVec128=0, IsStackPtr=0, IsFramePtr=0, IsInt=0, IsI64Pair=0, IsFP32=0,
Aliases=None): IsFP64=0, IsVec128=0, Aliases=None):
assert not (IsInt and IsI64Pair) assert not (IsInt and IsI64Pair)
assert not (IsFP32 and IsFP64) assert not (IsFP32 and IsFP64)
assert not (IsFP32 and IsVec128) assert not (IsFP32 and IsVec128)
...@@ -26,6 +29,10 @@ class RegFeatures(object): ...@@ -26,6 +29,10 @@ class RegFeatures(object):
assert not (IsScratch and IsPreserved) assert not (IsScratch and IsPreserved)
self.Features = [x for x in _ArgumentNames(self.__init__)] self.Features = [x for x in _ArgumentNames(self.__init__)]
self.FeaturesDict = {} self.FeaturesDict = {}
# The argument Aliases is a string with the register aliasing information.
# The next line convert it to a RegAlias object, for pretty printing.
Aliases = RegAliases(Aliases)
AsmStr = '"%s"' % AsmStr
for Feature in self.Features: for Feature in self.Features:
self.FeaturesDict[Feature] = locals()[Feature] self.FeaturesDict[Feature] = locals()[Feature]
...@@ -46,10 +53,12 @@ class RegFeatures(object): ...@@ -46,10 +53,12 @@ class RegFeatures(object):
'IsFP32', 'IsFP64', 'IsVec128')) 'IsFP32', 'IsFP64', 'IsVec128'))
class Reg(object): class Reg(object):
def __init__(self, Name, Encode, **Features): def __init__(self, Name, Encode, AsmStr=None, **Features):
self.Name = Name self.Name = Name
self.Encode = Encode self.Encode = Encode
self.Features = RegFeatures(**Features) if not AsmStr:
AsmStr = '%s' % Name
self.Features = RegFeatures(AsmStr=AsmStr, **Features)
def __str__(self): def __str__(self):
return 'Reg_{Name}, {Encode}, {Features}'.format(Name=self.Name, return 'Reg_{Name}, {Encode}, {Features}'.format(Name=self.Name,
...@@ -62,133 +71,135 @@ class Reg(object): ...@@ -62,133 +71,135 @@ class Reg(object):
# to read the register tables if each register entry is contained on a single # to read the register tables if each register entry is contained on a single
# line. # line.
GPRs = [ GPRs = [
Reg( 'r0', 0, IsScratch=1, IsInt=1, Aliases=RegAliases( 'r0', 'r0r1')), Reg( 'r0', 0, IsScratch=1, CCArg=1, IsInt=1, Aliases= 'r0, r0r1'),
Reg( 'r1', 1, IsScratch=1, IsInt=1, Aliases=RegAliases( 'r1', 'r0r1')), Reg( 'r1', 1, IsScratch=1, CCArg=2, IsInt=1, Aliases= 'r1, r0r1'),
Reg( 'r2', 2, IsScratch=1, IsInt=1, Aliases=RegAliases( 'r2', 'r2r3')), Reg( 'r2', 2, IsScratch=1, CCArg=3, IsInt=1, Aliases= 'r2, r2r3'),
Reg( 'r3', 3, IsScratch=1, IsInt=1, Aliases=RegAliases( 'r3', 'r2r3')), Reg( 'r3', 3, IsScratch=1, CCArg=4, IsInt=1, Aliases= 'r3, r2r3'),
Reg( 'r4', 4, IsPreserved=1, IsInt=1, Aliases=RegAliases( 'r4', 'r4r5')), Reg( 'r4', 4, IsPreserved=1, IsInt=1, Aliases= 'r4, r4r5'),
Reg( 'r5', 5, IsPreserved=1, IsInt=1, Aliases=RegAliases( 'r5', 'r4r5')), Reg( 'r5', 5, IsPreserved=1, IsInt=1, Aliases= 'r5, r4r5'),
Reg( 'r6', 6, IsPreserved=1, IsInt=1, Aliases=RegAliases( 'r6', 'r6r7')), Reg( 'r6', 6, IsPreserved=1, IsInt=1, Aliases= 'r6, r6r7'),
Reg( 'r7', 7, IsPreserved=1, IsInt=1, Aliases=RegAliases( 'r7', 'r6r7')), Reg( 'r7', 7, IsPreserved=1, IsInt=1, Aliases= 'r7, r6r7'),
Reg( 'r8', 8, IsPreserved=1, IsInt=1, Aliases=RegAliases( 'r8', 'r8r9')), Reg( 'r8', 8, IsPreserved=1, IsInt=1, Aliases= 'r8, r8r9'),
Reg( 'r9', 9, IsPreserved=1, IsInt=0, Aliases=RegAliases( 'r9', 'r8r9')), Reg( 'r9', 9, IsPreserved=1, IsInt=0, Aliases= 'r9, r8r9'),
Reg('r10', 10, IsPreserved=1, IsInt=1, Aliases=RegAliases('r10', 'r10fp')), Reg('r10', 10, IsPreserved=1, IsInt=1, Aliases='r10, r10fp'),
Reg( 'fp', 11, IsPreserved=1, IsInt=1, IsFramePtr=1, Aliases=RegAliases( 'fp', 'r10fp')), Reg( 'fp', 11, IsPreserved=1, IsInt=1, IsFramePtr=1, Aliases= 'fp, r10fp'),
Reg( 'ip', 12, IsScratch=1, IsInt=1, Aliases=RegAliases( 'ip')), Reg( 'ip', 12, IsScratch=1, IsInt=0, Aliases= 'ip'),
Reg( 'sp', 13, IsScratch=0, IsInt=0, IsStackPtr=1, Aliases=RegAliases( 'sp')), Reg( 'sp', 13, IsScratch=0, IsInt=0, IsStackPtr=1, Aliases= 'sp'),
Reg( 'lr', 14, IsScratch=0, IsInt=0, Aliases=RegAliases( 'lr')), Reg( 'lr', 14, IsScratch=0, IsInt=0, Aliases= 'lr'),
Reg( 'pc', 15, IsScratch=0, IsInt=0, Aliases=RegAliases( 'pc')), Reg( 'pc', 15, IsScratch=0, IsInt=0, Aliases= 'pc'),
] ]
I64Pairs = [ I64Pairs = [
Reg( 'r0r1', 0, IsScratch=1, IsI64Pair=1, Aliases=RegAliases( 'r0r1', 'r0', 'r1')), Reg( 'r0r1', 0, AsmStr= 'r0, r1', IsScratch=1, CCArg=1, IsI64Pair=1, Aliases= 'r0r1, r0, r1'),
Reg( 'r2r3', 2, IsScratch=1, IsI64Pair=1, Aliases=RegAliases( 'r2r3', 'r2', 'r3')), Reg( 'r2r3', 2, AsmStr= 'r2, r3', IsScratch=1, CCArg=2, IsI64Pair=1, Aliases= 'r2r3, r2, r3'),
Reg( 'r4r5', 4, IsPreserved=1, IsI64Pair=1, Aliases=RegAliases( 'r4r5', 'r4', 'r5')), Reg( 'r4r5', 4, AsmStr= 'r4, r5', IsPreserved=1, IsI64Pair=1, Aliases= 'r4r5, r4, r5'),
Reg( 'r6r7', 6, IsPreserved=1, IsI64Pair=1, Aliases=RegAliases( 'r6r7', 'r6', 'r7')), Reg( 'r6r7', 6, AsmStr= 'r6, r7', IsPreserved=1, IsI64Pair=1, Aliases= 'r6r7, r6, r7'),
Reg( 'r8r9', 8, IsPreserved=1, IsI64Pair=0, Aliases=RegAliases( 'r8r9', 'r8', 'r9')), Reg( 'r8r9', 8, AsmStr= 'r8, r9', IsPreserved=1, IsI64Pair=0, Aliases= 'r8r9, r8, r9'),
Reg('r10fp', 10, IsPreserved=1, IsI64Pair=1, Aliases=RegAliases('r10fp', 'r10', 'fp')), Reg('r10fp', 10, AsmStr='r10, fp', IsPreserved=1, IsI64Pair=0, Aliases='r10fp, r10, fp'),
] ]
FP32 = [ FP32 = [
Reg( 's0', 0, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's0', 'd0' , 'q0')), Reg( 's0', 0, IsScratch=1, CCArg=1, IsFP32=1, Aliases= 's0, d0 , q0'),
Reg( 's1', 1, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's1', 'd0' , 'q0')), Reg( 's1', 1, IsScratch=1, CCArg=2, IsFP32=1, Aliases= 's1, d0 , q0'),
Reg( 's2', 2, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's2', 'd1' , 'q0')), Reg( 's2', 2, IsScratch=1, CCArg=3, IsFP32=1, Aliases= 's2, d1 , q0'),
Reg( 's3', 3, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's3', 'd1' , 'q0')), Reg( 's3', 3, IsScratch=1, CCArg=4, IsFP32=1, Aliases= 's3, d1 , q0'),
Reg( 's4', 4, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's4', 'd2' , 'q1')), Reg( 's4', 4, IsScratch=1, CCArg=5, IsFP32=1, Aliases= 's4, d2 , q1'),
Reg( 's5', 5, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's5', 'd2' , 'q1')), Reg( 's5', 5, IsScratch=1, CCArg=6, IsFP32=1, Aliases= 's5, d2 , q1'),
Reg( 's6', 6, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's6', 'd3' , 'q1')), Reg( 's6', 6, IsScratch=1, CCArg=7, IsFP32=1, Aliases= 's6, d3 , q1'),
Reg( 's7', 7, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's7', 'd3' , 'q1')), Reg( 's7', 7, IsScratch=1, CCArg=8, IsFP32=1, Aliases= 's7, d3 , q1'),
Reg( 's8', 8, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's8', 'd4' , 'q2')), Reg( 's8', 8, IsScratch=1, CCArg=9, IsFP32=1, Aliases= 's8, d4 , q2'),
Reg( 's9', 9, IsScratch=1, IsFP32=1, Aliases=RegAliases( 's9', 'd4' , 'q2')), Reg( 's9', 9, IsScratch=1, CCArg=10, IsFP32=1, Aliases= 's9, d4 , q2'),
Reg('s10', 10, IsScratch=1, IsFP32=1, Aliases=RegAliases('s10', 'd5' , 'q2')), Reg('s10', 10, IsScratch=1, CCArg=11, IsFP32=1, Aliases='s10, d5 , q2'),
Reg('s11', 11, IsScratch=1, IsFP32=1, Aliases=RegAliases('s11', 'd5' , 'q2')), Reg('s11', 11, IsScratch=1, CCArg=12, IsFP32=1, Aliases='s11, d5 , q2'),
Reg('s12', 12, IsScratch=1, IsFP32=1, Aliases=RegAliases('s12', 'd6' , 'q3')), Reg('s12', 12, IsScratch=1, CCArg=13, IsFP32=1, Aliases='s12, d6 , q3'),
Reg('s13', 13, IsScratch=1, IsFP32=1, Aliases=RegAliases('s13', 'd6' , 'q3')), Reg('s13', 13, IsScratch=1, CCArg=14, IsFP32=1, Aliases='s13, d6 , q3'),
Reg('s14', 14, IsScratch=1, IsFP32=1, Aliases=RegAliases('s14', 'd7' , 'q3')), Reg('s14', 14, IsScratch=1, CCArg=15, IsFP32=1, Aliases='s14, d7 , q3'),
Reg('s15', 15, IsScratch=1, IsFP32=1, Aliases=RegAliases('s15', 'd7' , 'q3')), Reg('s15', 15, IsScratch=1, CCArg=16, IsFP32=1, Aliases='s15, d7 , q3'),
Reg('s16', 16, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s16', 'd8' , 'q4')), Reg('s16', 16, IsPreserved=1, IsFP32=1, Aliases='s16, d8 , q4'),
Reg('s17', 17, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s17', 'd8' , 'q4')), Reg('s17', 17, IsPreserved=1, IsFP32=1, Aliases='s17, d8 , q4'),
Reg('s18', 18, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s18', 'd9' , 'q4')), Reg('s18', 18, IsPreserved=1, IsFP32=1, Aliases='s18, d9 , q4'),
Reg('s19', 19, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s19', 'd9' , 'q4')), Reg('s19', 19, IsPreserved=1, IsFP32=1, Aliases='s19, d9 , q4'),
Reg('s20', 20, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s20', 'd10', 'q5')), Reg('s20', 20, IsPreserved=1, IsFP32=1, Aliases='s20, d10, q5'),
Reg('s21', 21, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s21', 'd10', 'q5')), Reg('s21', 21, IsPreserved=1, IsFP32=1, Aliases='s21, d10, q5'),
Reg('s22', 22, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s22', 'd11', 'q5')), Reg('s22', 22, IsPreserved=1, IsFP32=1, Aliases='s22, d11, q5'),
Reg('s23', 23, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s23', 'd11', 'q5')), Reg('s23', 23, IsPreserved=1, IsFP32=1, Aliases='s23, d11, q5'),
Reg('s24', 24, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s24', 'd12', 'q6')), Reg('s24', 24, IsPreserved=1, IsFP32=1, Aliases='s24, d12, q6'),
Reg('s25', 25, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s25', 'd12', 'q6')), Reg('s25', 25, IsPreserved=1, IsFP32=1, Aliases='s25, d12, q6'),
Reg('s26', 26, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s26', 'd13', 'q6')), Reg('s26', 26, IsPreserved=1, IsFP32=1, Aliases='s26, d13, q6'),
Reg('s27', 27, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s27', 'd13', 'q6')), Reg('s27', 27, IsPreserved=1, IsFP32=1, Aliases='s27, d13, q6'),
Reg('s28', 28, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s28', 'd14', 'q7')), Reg('s28', 28, IsPreserved=1, IsFP32=1, Aliases='s28, d14, q7'),
Reg('s29', 29, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s29', 'd14', 'q7')), Reg('s29', 29, IsPreserved=1, IsFP32=1, Aliases='s29, d14, q7'),
Reg('s30', 30, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s30', 'd15', 'q7')), Reg('s30', 30, IsPreserved=1, IsFP32=1, Aliases='s30, d15, q7'),
Reg('s31', 31, IsPreserved=1, IsFP32=1, Aliases=RegAliases('s31', 'd14', 'q7')), Reg('s31', 31, IsPreserved=1, IsFP32=1, Aliases='s31, d14, q7'),
] ]
FP64 = [ FP64 = [
Reg( 'd0', 0, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd0', 'q0', 's0', 's1')), Reg( 'd0', 0, IsScratch=1, CCArg=1, IsFP64=1, Aliases= 'd0, q0, s0, s1'),
Reg( 'd1', 1, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd1', 'q0', 's2', 's3')), Reg( 'd1', 1, IsScratch=1, CCArg=2, IsFP64=1, Aliases= 'd1, q0, s2, s3'),
Reg( 'd2', 2, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd2', 'q1', 's4', 's5')), Reg( 'd2', 2, IsScratch=1, CCArg=3, IsFP64=1, Aliases= 'd2, q1, s4, s5'),
Reg( 'd3', 3, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd3', 'q1', 's6', 's7')), Reg( 'd3', 3, IsScratch=1, CCArg=4, IsFP64=1, Aliases= 'd3, q1, s6, s7'),
Reg( 'd4', 4, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd4', 'q2', 's8', 's9')), Reg( 'd4', 4, IsScratch=1, CCArg=5, IsFP64=1, Aliases= 'd4, q2, s8, s9'),
Reg( 'd5', 5, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd5', 'q2', 's10', 's11')), Reg( 'd5', 5, IsScratch=1, CCArg=6, IsFP64=1, Aliases= 'd5, q2, s10, s11'),
Reg( 'd6', 6, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd6', 'q3', 's12', 's13')), Reg( 'd6', 6, IsScratch=1, CCArg=7, IsFP64=1, Aliases= 'd6, q3, s12, s13'),
Reg( 'd7', 7, IsScratch=1, IsFP64=1, Aliases=RegAliases( 'd7', 'q3', 's14', 's15')), Reg( 'd7', 7, IsScratch=1, CCArg=8, IsFP64=1, Aliases= 'd7, q3, s14, s15'),
Reg( 'd8', 8, IsPreserved=1, IsFP64=1, Aliases=RegAliases( 'd8', 'q4', 's16', 's17')), Reg( 'd8', 8, IsPreserved=1, IsFP64=1, Aliases= 'd8, q4, s16, s17'),
Reg( 'd9', 9, IsPreserved=1, IsFP64=1, Aliases=RegAliases( 'd9', 'q4', 's18', 's19')), Reg( 'd9', 9, IsPreserved=1, IsFP64=1, Aliases= 'd9, q4, s18, s19'),
Reg('d10', 10, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d10', 'q5', 's20', 's21')), Reg('d10', 10, IsPreserved=1, IsFP64=1, Aliases='d10, q5, s20, s21'),
Reg('d11', 11, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d11', 'q5', 's22', 's24')), Reg('d11', 11, IsPreserved=1, IsFP64=1, Aliases='d11, q5, s22, s24'),
Reg('d12', 12, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d12', 'q6', 's24', 's25')), Reg('d12', 12, IsPreserved=1, IsFP64=1, Aliases='d12, q6, s24, s25'),
Reg('d13', 13, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d13', 'q6', 's26', 's27')), Reg('d13', 13, IsPreserved=1, IsFP64=1, Aliases='d13, q6, s26, s27'),
Reg('d14', 14, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d14', 'q7', 's28', 's28')), Reg('d14', 14, IsPreserved=1, IsFP64=1, Aliases='d14, q7, s28, s28'),
Reg('d15', 15, IsPreserved=1, IsFP64=1, Aliases=RegAliases('d15', 'q7', 's30', 's31')), Reg('d15', 15, IsPreserved=1, IsFP64=1, Aliases='d15, q7, s30, s31'),
Reg('d16', 16, IsScratch=1, IsFP64=1, Aliases=RegAliases('d16', 'q8')), Reg('d16', 16, IsScratch=1, IsFP64=1, Aliases='d16, q8'),
Reg('d17', 17, IsScratch=1, IsFP64=1, Aliases=RegAliases('d17', 'q8')), Reg('d17', 17, IsScratch=1, IsFP64=1, Aliases='d17, q8'),
Reg('d18', 18, IsScratch=1, IsFP64=1, Aliases=RegAliases('d18', 'q9')), Reg('d18', 18, IsScratch=1, IsFP64=1, Aliases='d18, q9'),
Reg('d19', 19, IsScratch=1, IsFP64=1, Aliases=RegAliases('d19', 'q9')), Reg('d19', 19, IsScratch=1, IsFP64=1, Aliases='d19, q9'),
Reg('d20', 20, IsScratch=1, IsFP64=1, Aliases=RegAliases('d20', 'q10')), Reg('d20', 20, IsScratch=1, IsFP64=1, Aliases='d20, q10'),
Reg('d21', 21, IsScratch=1, IsFP64=1, Aliases=RegAliases('d21', 'q10')), Reg('d21', 21, IsScratch=1, IsFP64=1, Aliases='d21, q10'),
Reg('d22', 22, IsScratch=1, IsFP64=1, Aliases=RegAliases('d22', 'q11')), Reg('d22', 22, IsScratch=1, IsFP64=1, Aliases='d22, q11'),
Reg('d23', 23, IsScratch=1, IsFP64=1, Aliases=RegAliases('d23', 'q11')), Reg('d23', 23, IsScratch=1, IsFP64=1, Aliases='d23, q11'),
Reg('d24', 24, IsScratch=1, IsFP64=1, Aliases=RegAliases('d24', 'q12')), Reg('d24', 24, IsScratch=1, IsFP64=1, Aliases='d24, q12'),
Reg('d25', 25, IsScratch=1, IsFP64=1, Aliases=RegAliases('d25', 'q12')), Reg('d25', 25, IsScratch=1, IsFP64=1, Aliases='d25, q12'),
Reg('d26', 26, IsScratch=1, IsFP64=1, Aliases=RegAliases('d26', 'q13')), Reg('d26', 26, IsScratch=1, IsFP64=1, Aliases='d26, q13'),
Reg('d27', 27, IsScratch=1, IsFP64=1, Aliases=RegAliases('d27', 'q13')), Reg('d27', 27, IsScratch=1, IsFP64=1, Aliases='d27, q13'),
Reg('d28', 28, IsScratch=1, IsFP64=1, Aliases=RegAliases('d28', 'q14')), Reg('d28', 28, IsScratch=1, IsFP64=1, Aliases='d28, q14'),
Reg('d29', 29, IsScratch=1, IsFP64=1, Aliases=RegAliases('d29', 'q14')), Reg('d29', 29, IsScratch=1, IsFP64=1, Aliases='d29, q14'),
Reg('d30', 30, IsScratch=1, IsFP64=1, Aliases=RegAliases('d30', 'q15')), Reg('d30', 30, IsScratch=1, IsFP64=1, Aliases='d30, q15'),
Reg('d31', 31, IsScratch=1, IsFP64=1, Aliases=RegAliases('d31', 'q15')), Reg('d31', 31, IsScratch=1, IsFP64=1, Aliases='d31, q15'),
] ]
Vec128 = [ Vec128 = [
Reg( 'q0', 0, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q0', 'd0', 'd1', 's0', 's1', 's2', 's3')), Reg( 'q0', 0, IsScratch=1, CCArg=1, IsVec128=1, Aliases= 'q0, d0, d1, s0, s1, s2, s3'),
Reg( 'q1', 1, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q1', 'd2', 'd3', 's4', 's5', 's6', 's7')), Reg( 'q1', 1, IsScratch=1, CCArg=2, IsVec128=1, Aliases= 'q1, d2, d3, s4, s5, s6, s7'),
Reg( 'q2', 2, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q2', 'd4', 'd5', 's8', 's9', 's10', 's11')), Reg( 'q2', 2, IsScratch=1, CCArg=3, IsVec128=1, Aliases= 'q2, d4, d5, s8, s9, s10, s11'),
Reg( 'q3', 3, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q3', 'd6', 'd7', 's12', 's13', 's14', 's15')), Reg( 'q3', 3, IsScratch=1, CCArg=4, IsVec128=1, Aliases= 'q3, d6, d7, s12, s13, s14, s15'),
Reg( 'q4', 4, IsPreserved=1, IsVec128=1, Aliases=RegAliases( 'q4', 'd8', 'd9', 's16', 's17', 's18', 's19')), Reg( 'q4', 4, IsPreserved=1, IsVec128=1, Aliases= 'q4, d8, d9, s16, s17, s18, s19'),
Reg( 'q5', 5, IsPreserved=1, IsVec128=1, Aliases=RegAliases( 'q5', 'd10', 'd11', 's20', 's21', 's22', 's23')), Reg( 'q5', 5, IsPreserved=1, IsVec128=1, Aliases= 'q5, d10, d11, s20, s21, s22, s23'),
Reg( 'q6', 6, IsPreserved=1, IsVec128=1, Aliases=RegAliases( 'q6', 'd12', 'd13', 's24', 's25', 's26', 's27')), Reg( 'q6', 6, IsPreserved=1, IsVec128=1, Aliases= 'q6, d12, d13, s24, s25, s26, s27'),
Reg( 'q7', 7, IsPreserved=1, IsVec128=1, Aliases=RegAliases( 'q7', 'd14', 'd15', 's28', 's29', 's30', 's31')), Reg( 'q7', 7, IsPreserved=1, IsVec128=1, Aliases= 'q7, d14, d15, s28, s29, s30, s31'),
Reg( 'q8', 8, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q8', 'd16', 'd17')), Reg( 'q8', 8, IsScratch=1, IsVec128=1, Aliases= 'q8, d16, d17'),
Reg( 'q9', 9, IsScratch=1, IsVec128=1, Aliases=RegAliases( 'q9', 'd18', 'd19')), Reg( 'q9', 9, IsScratch=1, IsVec128=1, Aliases= 'q9, d18, d19'),
Reg('q10', 10, IsScratch=1, IsVec128=1, Aliases=RegAliases('q10', 'd20', 'd21')), Reg('q10', 10, IsScratch=1, IsVec128=1, Aliases='q10, d20, d21'),
Reg('q11', 11, IsScratch=1, IsVec128=1, Aliases=RegAliases('q11', 'd22', 'd23')), Reg('q11', 11, IsScratch=1, IsVec128=1, Aliases='q11, d22, d23'),
Reg('q12', 12, IsScratch=1, IsVec128=1, Aliases=RegAliases('q12', 'd24', 'd25')), Reg('q12', 12, IsScratch=1, IsVec128=1, Aliases='q12, d24, d25'),
Reg('q13', 13, IsScratch=1, IsVec128=1, Aliases=RegAliases('q13', 'd26', 'd27')), Reg('q13', 13, IsScratch=1, IsVec128=1, Aliases='q13, d26, d27'),
Reg('q14', 14, IsScratch=1, IsVec128=1, Aliases=RegAliases('q14', 'd28', 'd29')), Reg('q14', 14, IsScratch=1, IsVec128=1, Aliases='q14, d28, d29'),
Reg('q15', 15, IsScratch=1, IsVec128=1, Aliases=RegAliases('q15', 'd30', 'd31')), Reg('q15', 15, IsScratch=1, IsVec128=1, Aliases='q15, d30, d31'),
] ]
def _reverse(x): def _reverse(x):
return sorted(x, key=lambda x: x.Encode, reverse=True) return sorted(x, key=lambda x: x.Encode, reverse=True)
RegClasses = [GPRs, I64Pairs, FP32, _reverse(FP64), _reverse(Vec128)]
RegClasses = [('GPR', GPRs), ('I64PAIR', I64Pairs), ('FP32', FP32),
('FP64', _reverse(FP64)), ('VEC128', _reverse(Vec128))]
AllRegs = {} AllRegs = {}
for RegClass in RegClasses: for _, RegClass in RegClasses:
for Reg in RegClass: for Reg in RegClass:
assert Reg.Name not in AllRegs assert Reg.Name not in AllRegs
AllRegs[Reg.Name] = Reg AllRegs[Reg.Name] = Reg
for RegClass in RegClasses: for _, RegClass in RegClasses:
for Reg in RegClass: for Reg in RegClass:
for Alias in AllRegs[Reg.Name].Features.Aliases().Aliases: for Alias in AllRegs[Reg.Name].Features.Aliases().Aliases:
assert AllRegs[Alias].IsAnAliasOf(Reg), '%s VS %s' % (Reg, AllRegs[Alias]) assert AllRegs[Alias].IsAnAliasOf(Reg), '%s VS %s' % (Reg, AllRegs[Alias])
...@@ -198,7 +209,15 @@ for RegClass in RegClasses: ...@@ -198,7 +209,15 @@ for RegClass in RegClasses:
assert (AllRegs[Alias].Features.LivesInVFP() == assert (AllRegs[Alias].Features.LivesInVFP() ==
Reg.Features.LivesInVFP()), '%s VS %s' % (Reg, AllRegs[Alias]) Reg.Features.LivesInVFP()), '%s VS %s' % (Reg, AllRegs[Alias])
for RegClass in RegClasses: print ("// This file was auto generated by the {script} script.\n"
"// Do not modify it: modify the script instead.\n"
"\n"
"#ifndef SUBZERO_SRC_ICEREGISTERSARM32_DEF\n"
"#define SUBZERO_SRC_ICEREGISTERSARM32_DEF\n".format(script=os.path.basename(sys.argv[0])))
for Name, RegClass in RegClasses:
print "#define REGARM32_%s_TABLE" % Name,
for Reg in RegClass: for Reg in RegClass:
print 'X({Reg})'.format(Reg=Reg) print '\\\n X({Reg})'.format(Reg=Reg),
print print '\n'
print "#endif // SUBZERO_SRC_ICEREGISTERSARM32_DEF",
...@@ -32,167 +32,9 @@ ...@@ -32,167 +32,9 @@
// The register tables can be generated using the gen_arm32_reg_tables.py // The register tables can be generated using the gen_arm32_reg_tables.py
// script. // script.
#define REGARM32_GPR_TABLE \ #include "IceRegistersARM32.def"
/* val, encode, name, scratch,preserved,stackptr,frameptr, \ // The register tables defined in IceRegistersARM32 use the following x-macro:
isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \ //#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,
X(Reg_r0, 0, "r0", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r0r1)) \
X(Reg_r1, 1, "r1", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r0r1)) \
X(Reg_r2, 2, "r2", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r2r3)) \
X(Reg_r3, 3, "r3", 1,0,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r2r3)) \
X(Reg_r4, 4, "r4", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r4r5)) \
X(Reg_r5, 5, "r5", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r4r5)) \
X(Reg_r6, 6, "r6", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r6r7)) \
X(Reg_r7, 7, "r7", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r6r7)) \
X(Reg_r8, 8, "r8", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r8r9)) \
X(Reg_r9, 9, "r9", 0,1,0,0, 0,0,0,0,0, REGLIST1(RegARM32, r8r9)) \
X(Reg_r10, 10, "r10", 0,1,0,0, 1,0,0,0,0, REGLIST1(RegARM32, r10fp)) \
X(Reg_fp, 11, "fp", 0,1,0,1, 1,0,0,0,0, REGLIST1(RegARM32, r10fp)) \
X(Reg_ip, 12, "ip", 1,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, ip)) \
X(Reg_sp, 13, "sp", 0,0,1,0, 0,0,0,0,0, REGLIST1(RegARM32, sp)) \
X(Reg_lr, 14, "lr", 0,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, lr)) \
X(Reg_pc, 15, "pc", 0,0,0,0, 0,0,0,0,0, REGLIST1(RegARM32, pc))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
// The following defines a table with the available pairs of consecutive i32
// GPRs starting at an even GPR that is not r14. Those are used to hold i64
// variables for atomic memory operations. If one of the registers in the pair
// is preserved, then we mark the whole pair as preserved to help the register
// allocator.
#define REGARM32_I64PAIR_TABLE \
/* val, encode, name, scratch,preserved,stackptr,frameptr, \
isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
X(Reg_r0r1, 0, "r0, r1", 1,0,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r0, r1)) \
X(Reg_r2r3, 2, "r2, r3", 1,0,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r2, r3)) \
X(Reg_r4r5, 4, "r4, r5", 0,1,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r4, r5)) \
X(Reg_r6r7, 6, "r6, r7", 0,1,0,0, 0,1,0,0,0, REGLIST2(RegARM32, r6, r7)) \
X(Reg_r8r9, 8, "r8, r9", 0,1,0,0, 0,0,0,0,0, REGLIST2(RegARM32, r8, r9)) \
X(Reg_r10fp, 10, "r10, fp", 0,1,0,0, 0,0,0,0,0, REGLIST2(RegARM32, r10, fp))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
// S registers 0-15 are scratch, but 16-31 are preserved.
#define REGARM32_FP32_TABLE \
/* val, encode, name, scratch,preserved,stackptr,frameptr, \
isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
X(Reg_s0, 0, "s0", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d0, q0)) \
X(Reg_s1, 1, "s1", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d0, q0)) \
X(Reg_s2, 2, "s2", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d1, q0)) \
X(Reg_s3, 3, "s3", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d1, q0)) \
X(Reg_s4, 4, "s4", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d2, q1)) \
X(Reg_s5, 5, "s5", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d2, q1)) \
X(Reg_s6, 6, "s6", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d3, q1)) \
X(Reg_s7, 7, "s7", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d3, q1)) \
X(Reg_s8, 8, "s8", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d4, q2)) \
X(Reg_s9, 9, "s9", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d4, q2)) \
X(Reg_s10, 10, "s10", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d5, q2)) \
X(Reg_s11, 11, "s11", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d5, q2)) \
X(Reg_s12, 12, "s12", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d6, q3)) \
X(Reg_s13, 13, "s13", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d6, q3)) \
X(Reg_s14, 14, "s14", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d7, q3)) \
X(Reg_s15, 15, "s15", 1,0,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d7, q3)) \
X(Reg_s16, 16, "s16", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d8, q4)) \
X(Reg_s17, 17, "s17", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d8, q4)) \
X(Reg_s18, 18, "s18", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d9, q4)) \
X(Reg_s19, 19, "s19", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d9, q4)) \
X(Reg_s20, 20, "s20", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d10, q5)) \
X(Reg_s21, 21, "s21", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d10, q5)) \
X(Reg_s22, 22, "s22", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d11, q5)) \
X(Reg_s23, 23, "s23", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d11, q5)) \
X(Reg_s24, 24, "s24", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d12, q6)) \
X(Reg_s25, 25, "s25", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d12, q6)) \
X(Reg_s26, 26, "s26", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d13, q6)) \
X(Reg_s27, 27, "s27", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d13, q6)) \
X(Reg_s28, 28, "s28", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d14, q7)) \
X(Reg_s29, 29, "s29", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d14, q7)) \
X(Reg_s30, 30, "s30", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d15, q7)) \
X(Reg_s31, 31, "s31", 0,1,0,0, 0,0,1,0,0, REGLIST2(RegARM32, d15, q7))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32,isFP64, isVec128, alias_init)
// D registers 0-7 are scratch, 8-15 are preserved, and 16-31 are also scratch
// (if supported by the D32 feature vs D16). D registers are defined in reverse
// order so that, during register allocation, Subzero will prefer higher D
// registers. In processors supporting the D32 feature this will effectively
// cause double allocation to bias towards allocating "high" D registers, which
// do not alias any S registers.
#define REGARM32_FP64_TABLE \
/* val, encode, name, scratch,preserved,stackptr,frameptr, \
isInt,isI64Pair,isFP32,isFP64,isVec128, alias_init */ \
X(Reg_d31, 31, "d31", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q15)) \
X(Reg_d30, 30, "d30", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q15)) \
X(Reg_d29, 29, "d29", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q14)) \
X(Reg_d28, 28, "d28", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q14)) \
X(Reg_d27, 27, "d27", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q13)) \
X(Reg_d26, 26, "d26", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q13)) \
X(Reg_d25, 25, "d25", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q12)) \
X(Reg_d24, 24, "d24", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q12)) \
X(Reg_d23, 23, "d23", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q11)) \
X(Reg_d22, 22, "d22", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q11)) \
X(Reg_d21, 21, "d21", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q10)) \
X(Reg_d20, 20, "d20", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q10)) \
X(Reg_d19, 19, "d19", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q9)) \
X(Reg_d18, 18, "d18", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q9)) \
X(Reg_d17, 17, "d17", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q8)) \
X(Reg_d16, 16, "d16", 1,0,0,0, 0,0,0,1,0, REGLIST1(RegARM32, q8)) \
X(Reg_d15, 15, "d15", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s30, s31, q7)) \
X(Reg_d14, 14, "d14", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s28, s29, q7)) \
X(Reg_d13, 13, "d13", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s26, s27, q6)) \
X(Reg_d12, 12, "d12", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s24, s25, q6)) \
X(Reg_d11, 11, "d11", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s22, s23, q5)) \
X(Reg_d10, 10, "d10", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s20, s21, q5)) \
X(Reg_d9, 9, "d9", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s18, s19, q4)) \
X(Reg_d8, 8, "d8", 0,1,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s16, s17, q4)) \
X(Reg_d7, 7, "d7", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s14, s15, q3)) \
X(Reg_d6, 6, "d6", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s12, s13, q3)) \
X(Reg_d5, 5, "d5", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s10, s11, q2)) \
X(Reg_d4, 4, "d4", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s8, s9, q2)) \
X(Reg_d3, 3, "d3", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s6, s7, q1)) \
X(Reg_d2, 2, "d2", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s4, s5, q1)) \
X(Reg_d1, 1, "d1", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s2, s3, q0)) \
X(Reg_d0, 0, "d0", 1,0,0,0, 0,0,0,1,0, REGLIST3(RegARM32, s0, s1, q0))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
// Q registers 0-3 are scratch, 4-7 are preserved, and 8-15 are also scratch
// (if supported by the D32 feature). Q registers are defined in reverse order
// for the same reason as D registers.
#define REGARM32_VEC128_TABLE \
/* val, encode, name, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
X(Reg_q15, 15, "q15", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d30, d31)) \
X(Reg_q14, 14, "q14", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d28, d29)) \
X(Reg_q13, 13, "q13", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d26, d27)) \
X(Reg_q12, 12, "q12", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d24, d25)) \
X(Reg_q11, 11, "q11", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d22, d23)) \
X(Reg_q10, 10, "q10", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d20, d21)) \
X(Reg_q9, 9, "q9", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d18, d19)) \
X(Reg_q8, 8, "q8", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST2(RegARM32, d16, d17)) \
X(Reg_q7, 7, "q7", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s28, s29, s30, s31, d14, d15)) \
X(Reg_q6, 6, "q6", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s24, s25, s26, s27, d12, d13)) \
X(Reg_q5, 5, "q5", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s20, s21, s22, s23, d10, d11)) \
X(Reg_q4, 4, "q4", 0, 1, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s16, s17, s18, s19, d8, d9)) \
X(Reg_q3, 3, "q3", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s12, s13, s14, s15, d6, d7)) \
X(Reg_q2, 2, "q2", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s8, s9, s10, s11, d4, d5)) \
X(Reg_q1, 1, "q1", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s4, s5, s6, s7, d2, d3)) \
X(Reg_q0, 0, "q0", 1, 0, 0, 0, 0, 0, 0, 0, 1, \
REGLIST6(RegARM32, s0, s1, s2, s3, d0, d1))
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr,
// isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) // isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init)
// We also provide a combined table, so that there is a namespace where all of // We also provide a combined table, so that there is a namespace where all of
...@@ -200,14 +42,14 @@ ...@@ -200,14 +42,14 @@
// contrast to the above, where the "encode" is based on how the register // contrast to the above, where the "encode" is based on how the register
// numbers will be encoded in binaries and values can overlap. // numbers will be encoded in binaries and values can overlap.
#define REGARM32_TABLE \ #define REGARM32_TABLE \
/* val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ /* val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isFP32, isFP64, isVec128, alias_init */ \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init */ \
REGARM32_GPR_TABLE \ REGARM32_GPR_TABLE \
REGARM32_I64PAIR_TABLE \ REGARM32_I64PAIR_TABLE \
REGARM32_FP32_TABLE \ REGARM32_FP32_TABLE \
REGARM32_FP64_TABLE \ REGARM32_FP64_TABLE \
REGARM32_VEC128_TABLE REGARM32_VEC128_TABLE
//#define X(val, encode, name, scratch, preserved, stackptr, frameptr, //#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr,
// isInt, isFP32, isFP64, isVec128, alias_init) // isInt, isFP32, isFP64, isVec128, alias_init)
#define REGARM32_TABLE_BOUNDS \ #define REGARM32_TABLE_BOUNDS \
......
...@@ -27,10 +27,10 @@ ...@@ -27,10 +27,10 @@
{ ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2 } { ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2 }
#define REGLIST4(ns, r0, r1, r2, r3) \ #define REGLIST4(ns, r0, r1, r2, r3) \
{ ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3 } { ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3 }
#define REGLIST6(ns, r0, r1, r2, r3, r4, r5) \ #define REGLIST7(ns, r0, r1, r2, r3, r4, r5, r6) \
{ \ { \
ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3, ns::Reg_##r4, \ ns::Reg_##r0, ns::Reg_##r1, ns::Reg_##r2, ns::Reg_##r3, ns::Reg_##r4, \
ns::Reg_##r5 \ ns::Reg_##r5, ns::Reg_##r6 \
} }
#endif // SUBZERO_SRC_ICEINSTREGLIST_H #endif // SUBZERO_SRC_ICEINSTREGLIST_H
// This file was auto generated by the gen_arm32_reg_tables.py script.
// Do not modify it: modify the script instead.
#ifndef SUBZERO_SRC_ICEREGISTERSARM32_DEF
#define SUBZERO_SRC_ICEREGISTERSARM32_DEF
#define REGARM32_GPR_TABLE \
X(Reg_r0, 0, "r0", 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r0, r0r1)) \
X(Reg_r1, 1, "r1", 2, 1, 0, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r1, r0r1)) \
X(Reg_r2, 2, "r2", 3, 1, 0, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r2, r2r3)) \
X(Reg_r3, 3, "r3", 4, 1, 0, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r3, r2r3)) \
X(Reg_r4, 4, "r4", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r4, r4r5)) \
X(Reg_r5, 5, "r5", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r5, r4r5)) \
X(Reg_r6, 6, "r6", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r6, r6r7)) \
X(Reg_r7, 7, "r7", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r7, r6r7)) \
X(Reg_r8, 8, "r8", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r8, r8r9)) \
X(Reg_r9, 9, "r9", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, REGLIST2(RegARM32, r9, r8r9)) \
X(Reg_r10, 10, "r10", 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, REGLIST2(RegARM32, r10, r10fp)) \
X(Reg_fp, 11, "fp", 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, REGLIST2(RegARM32, fp, r10fp)) \
X(Reg_ip, 12, "ip", 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, REGLIST1(RegARM32, ip)) \
X(Reg_sp, 13, "sp", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, REGLIST1(RegARM32, sp)) \
X(Reg_lr, 14, "lr", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, REGLIST1(RegARM32, lr)) \
X(Reg_pc, 15, "pc", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, REGLIST1(RegARM32, pc))
#define REGARM32_I64PAIR_TABLE \
X(Reg_r0r1, 0, "r0, r1", 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, REGLIST3(RegARM32, r0r1, r0, r1)) \
X(Reg_r2r3, 2, "r2, r3", 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, REGLIST3(RegARM32, r2r3, r2, r3)) \
X(Reg_r4r5, 4, "r4, r5", 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, REGLIST3(RegARM32, r4r5, r4, r5)) \
X(Reg_r6r7, 6, "r6, r7", 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, REGLIST3(RegARM32, r6r7, r6, r7)) \
X(Reg_r8r9, 8, "r8, r9", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, REGLIST3(RegARM32, r8r9, r8, r9)) \
X(Reg_r10fp, 10, "r10, fp", 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, REGLIST3(RegARM32, r10fp, r10, fp))
#define REGARM32_FP32_TABLE \
X(Reg_s0, 0, "s0", 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s0, d0, q0)) \
X(Reg_s1, 1, "s1", 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s1, d0, q0)) \
X(Reg_s2, 2, "s2", 3, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s2, d1, q0)) \
X(Reg_s3, 3, "s3", 4, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s3, d1, q0)) \
X(Reg_s4, 4, "s4", 5, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s4, d2, q1)) \
X(Reg_s5, 5, "s5", 6, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s5, d2, q1)) \
X(Reg_s6, 6, "s6", 7, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s6, d3, q1)) \
X(Reg_s7, 7, "s7", 8, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s7, d3, q1)) \
X(Reg_s8, 8, "s8", 9, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s8, d4, q2)) \
X(Reg_s9, 9, "s9", 10, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s9, d4, q2)) \
X(Reg_s10, 10, "s10", 11, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s10, d5, q2)) \
X(Reg_s11, 11, "s11", 12, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s11, d5, q2)) \
X(Reg_s12, 12, "s12", 13, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s12, d6, q3)) \
X(Reg_s13, 13, "s13", 14, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s13, d6, q3)) \
X(Reg_s14, 14, "s14", 15, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s14, d7, q3)) \
X(Reg_s15, 15, "s15", 16, 1, 0, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s15, d7, q3)) \
X(Reg_s16, 16, "s16", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s16, d8, q4)) \
X(Reg_s17, 17, "s17", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s17, d8, q4)) \
X(Reg_s18, 18, "s18", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s18, d9, q4)) \
X(Reg_s19, 19, "s19", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s19, d9, q4)) \
X(Reg_s20, 20, "s20", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s20, d10, q5)) \
X(Reg_s21, 21, "s21", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s21, d10, q5)) \
X(Reg_s22, 22, "s22", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s22, d11, q5)) \
X(Reg_s23, 23, "s23", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s23, d11, q5)) \
X(Reg_s24, 24, "s24", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s24, d12, q6)) \
X(Reg_s25, 25, "s25", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s25, d12, q6)) \
X(Reg_s26, 26, "s26", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s26, d13, q6)) \
X(Reg_s27, 27, "s27", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s27, d13, q6)) \
X(Reg_s28, 28, "s28", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s28, d14, q7)) \
X(Reg_s29, 29, "s29", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s29, d14, q7)) \
X(Reg_s30, 30, "s30", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s30, d15, q7)) \
X(Reg_s31, 31, "s31", 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, REGLIST3(RegARM32, s31, d14, q7))
#define REGARM32_FP64_TABLE \
X(Reg_d31, 31, "d31", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d31, q15)) \
X(Reg_d30, 30, "d30", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d30, q15)) \
X(Reg_d29, 29, "d29", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d29, q14)) \
X(Reg_d28, 28, "d28", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d28, q14)) \
X(Reg_d27, 27, "d27", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d27, q13)) \
X(Reg_d26, 26, "d26", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d26, q13)) \
X(Reg_d25, 25, "d25", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d25, q12)) \
X(Reg_d24, 24, "d24", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d24, q12)) \
X(Reg_d23, 23, "d23", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d23, q11)) \
X(Reg_d22, 22, "d22", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d22, q11)) \
X(Reg_d21, 21, "d21", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d21, q10)) \
X(Reg_d20, 20, "d20", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d20, q10)) \
X(Reg_d19, 19, "d19", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d19, q9)) \
X(Reg_d18, 18, "d18", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d18, q9)) \
X(Reg_d17, 17, "d17", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d17, q8)) \
X(Reg_d16, 16, "d16", 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST2(RegARM32, d16, q8)) \
X(Reg_d15, 15, "d15", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d15, q7, s30, s31)) \
X(Reg_d14, 14, "d14", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d14, q7, s28, s28)) \
X(Reg_d13, 13, "d13", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d13, q6, s26, s27)) \
X(Reg_d12, 12, "d12", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d12, q6, s24, s25)) \
X(Reg_d11, 11, "d11", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d11, q5, s22, s24)) \
X(Reg_d10, 10, "d10", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d10, q5, s20, s21)) \
X(Reg_d9, 9, "d9", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d9, q4, s18, s19)) \
X(Reg_d8, 8, "d8", 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d8, q4, s16, s17)) \
X(Reg_d7, 7, "d7", 8, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d7, q3, s14, s15)) \
X(Reg_d6, 6, "d6", 7, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d6, q3, s12, s13)) \
X(Reg_d5, 5, "d5", 6, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d5, q2, s10, s11)) \
X(Reg_d4, 4, "d4", 5, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d4, q2, s8, s9)) \
X(Reg_d3, 3, "d3", 4, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d3, q1, s6, s7)) \
X(Reg_d2, 2, "d2", 3, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d2, q1, s4, s5)) \
X(Reg_d1, 1, "d1", 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d1, q0, s2, s3)) \
X(Reg_d0, 0, "d0", 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, REGLIST4(RegARM32, d0, q0, s0, s1))
#define REGARM32_VEC128_TABLE \
X(Reg_q15, 15, "q15", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q15, d30, d31)) \
X(Reg_q14, 14, "q14", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q14, d28, d29)) \
X(Reg_q13, 13, "q13", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q13, d26, d27)) \
X(Reg_q12, 12, "q12", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q12, d24, d25)) \
X(Reg_q11, 11, "q11", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q11, d22, d23)) \
X(Reg_q10, 10, "q10", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q10, d20, d21)) \
X(Reg_q9, 9, "q9", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q9, d18, d19)) \
X(Reg_q8, 8, "q8", 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST3(RegARM32, q8, d16, d17)) \
X(Reg_q7, 7, "q7", 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q7, d14, d15, s28, s29, s30, s31)) \
X(Reg_q6, 6, "q6", 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q6, d12, d13, s24, s25, s26, s27)) \
X(Reg_q5, 5, "q5", 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q5, d10, d11, s20, s21, s22, s23)) \
X(Reg_q4, 4, "q4", 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q4, d8, d9, s16, s17, s18, s19)) \
X(Reg_q3, 3, "q3", 4, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q3, d6, d7, s12, s13, s14, s15)) \
X(Reg_q2, 2, "q2", 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q2, d4, d5, s8, s9, s10, s11)) \
X(Reg_q1, 1, "q1", 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q1, d2, d3, s4, s5, s6, s7)) \
X(Reg_q0, 0, "q0", 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, REGLIST7(RegARM32, q0, d0, d1, s0, s1, s2, s3))
#endif // SUBZERO_SRC_ICEREGISTERSARM32_DEF
...@@ -27,8 +27,8 @@ public: ...@@ -27,8 +27,8 @@ public:
/// An enum of every register. The enum value may not match the encoding used /// An enum of every register. The enum value may not match the encoding used
/// to binary encode register operands in instructions. /// to binary encode register operands in instructions.
enum AllRegisters { enum AllRegisters {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
val, val,
REGARM32_TABLE REGARM32_TABLE
#undef X #undef X
...@@ -41,8 +41,8 @@ public: ...@@ -41,8 +41,8 @@ public:
/// An enum of GPR Registers. The enum value does match the encoding used to /// An enum of GPR Registers. The enum value does match the encoding used to
/// binary encode register operands in instructions. /// binary encode register operands in instructions.
enum GPRRegister { enum GPRRegister {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
Encoded_##val = encode, Encoded_##val = encode,
REGARM32_GPR_TABLE REGARM32_GPR_TABLE
#undef X #undef X
...@@ -52,8 +52,8 @@ public: ...@@ -52,8 +52,8 @@ public:
/// An enum of FP32 S-Registers. The enum value does match the encoding used /// An enum of FP32 S-Registers. The enum value does match the encoding used
/// to binary encode register operands in instructions. /// to binary encode register operands in instructions.
enum SRegister { enum SRegister {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
Encoded_##val = encode, Encoded_##val = encode,
REGARM32_FP32_TABLE REGARM32_FP32_TABLE
#undef X #undef X
...@@ -63,8 +63,8 @@ public: ...@@ -63,8 +63,8 @@ public:
/// An enum of FP64 D-Registers. The enum value does match the encoding used /// An enum of FP64 D-Registers. The enum value does match the encoding used
/// to binary encode register operands in instructions. /// to binary encode register operands in instructions.
enum DRegister { enum DRegister {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
Encoded_##val = encode, Encoded_##val = encode,
REGARM32_FP64_TABLE REGARM32_FP64_TABLE
#undef X #undef X
...@@ -74,8 +74,8 @@ public: ...@@ -74,8 +74,8 @@ public:
/// An enum of 128-bit Q-Registers. The enum value does match the encoding /// An enum of 128-bit Q-Registers. The enum value does match the encoding
/// used to binary encode register operands in instructions. /// used to binary encode register operands in instructions.
enum QRegister { enum QRegister {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
Encoded_##val = encode, Encoded_##val = encode,
REGARM32_VEC128_TABLE REGARM32_VEC128_TABLE
#undef X #undef X
...@@ -94,6 +94,12 @@ public: ...@@ -94,6 +94,12 @@ public:
return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First)); return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First));
} }
static inline GPRRegister getI64PairSecondGPRNum(int32_t RegNum) {
assert(Reg_I64PAIR_First <= RegNum);
assert(RegNum <= Reg_I64PAIR_Last);
return GPRRegister(2 * (RegNum - Reg_I64PAIR_First + Reg_GPR_First) + 1);
}
static inline bool isI64RegisterPair(int32_t RegNum) { static inline bool isI64RegisterPair(int32_t RegNum) {
return Reg_I64PAIR_First <= RegNum && RegNum <= Reg_I64PAIR_Last; return Reg_I64PAIR_First <= RegNum && RegNum <= Reg_I64PAIR_Last;
} }
......
...@@ -160,6 +160,53 @@ TargetARM32Features::TargetARM32Features(const ClFlags &Flags) { ...@@ -160,6 +160,53 @@ TargetARM32Features::TargetARM32Features(const ClFlags &Flags) {
} }
} }
namespace {
constexpr SizeT NumGPRArgs =
#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
+(((cc_arg) > 0) ? 1 : 0)
REGARM32_GPR_TABLE
#undef X
;
std::array<uint32_t, NumGPRArgs> GPRArgInitializer;
constexpr SizeT NumI64Args =
#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
+(((cc_arg) > 0) ? 1 : 0)
REGARM32_I64PAIR_TABLE
#undef X
;
std::array<uint32_t, NumI64Args> I64ArgInitializer;
constexpr SizeT NumFP32Args =
#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
+(((cc_arg) > 0) ? 1 : 0)
REGARM32_FP32_TABLE
#undef X
;
std::array<uint32_t, NumFP32Args> FP32ArgInitializer;
constexpr SizeT NumFP64Args =
#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
+(((cc_arg) > 0) ? 1 : 0)
REGARM32_FP64_TABLE
#undef X
;
std::array<uint32_t, NumFP64Args> FP64ArgInitializer;
constexpr SizeT NumVec128Args =
#define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
+(((cc_arg > 0)) ? 1 : 0)
REGARM32_VEC128_TABLE
#undef X
;
std::array<uint32_t, NumVec128Args> Vec128ArgInitializer;
} // end of anonymous namespace
TargetARM32::TargetARM32(Cfg *Func) TargetARM32::TargetARM32(Cfg *Func)
: TargetLowering(Func), NeedSandboxing(Ctx->getFlags().getUseSandboxing()), : TargetLowering(Func), NeedSandboxing(Ctx->getFlags().getUseSandboxing()),
CPUFeatures(Func->getContext()->getFlags()) {} CPUFeatures(Func->getContext()->getFlags()) {}
...@@ -173,8 +220,8 @@ void TargetARM32::staticInit() { ...@@ -173,8 +220,8 @@ void TargetARM32::staticInit() {
llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM); llvm::SmallBitVector VectorRegisters(RegARM32::Reg_NUM);
llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM); llvm::SmallBitVector InvalidRegisters(RegARM32::Reg_NUM);
ScratchRegs.resize(RegARM32::Reg_NUM); ScratchRegs.resize(RegARM32::Reg_NUM);
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
IntegerRegisters[RegARM32::val] = isInt; \ IntegerRegisters[RegARM32::val] = isInt; \
I64PairRegisters[RegARM32::val] = isI64Pair; \ I64PairRegisters[RegARM32::val] = isI64Pair; \
Float32Registers[RegARM32::val] = isFP32; \ Float32Registers[RegARM32::val] = isFP32; \
...@@ -182,12 +229,24 @@ void TargetARM32::staticInit() { ...@@ -182,12 +229,24 @@ void TargetARM32::staticInit() {
VectorRegisters[RegARM32::val] = isVec128; \ VectorRegisters[RegARM32::val] = isVec128; \
RegisterAliases[RegARM32::val].resize(RegARM32::Reg_NUM); \ RegisterAliases[RegARM32::val].resize(RegARM32::Reg_NUM); \
for (SizeT RegAlias : alias_init) { \ for (SizeT RegAlias : alias_init) { \
assert(!RegisterAliases[RegARM32::val][RegAlias] && \ assert((!RegisterAliases[RegARM32::val][RegAlias] || \
RegAlias != RegARM32::val) && \
"Duplicate alias for " #val); \ "Duplicate alias for " #val); \
RegisterAliases[RegARM32::val].set(RegAlias); \ RegisterAliases[RegARM32::val].set(RegAlias); \
} \ } \
RegisterAliases[RegARM32::val].set(RegARM32::val); \ RegisterAliases[RegARM32::val].set(RegARM32::val); \
ScratchRegs[RegARM32::val] = scratch; ScratchRegs[RegARM32::val] = scratch; \
if ((isInt) && (cc_arg) > 0) { \
GPRArgInitializer[(cc_arg)-1] = RegARM32::val; \
} else if ((isI64Pair) && (cc_arg) > 0) { \
I64ArgInitializer[(cc_arg)-1] = RegARM32::val; \
} else if ((isFP32) && (cc_arg) > 0) { \
FP32ArgInitializer[(cc_arg)-1] = RegARM32::val; \
} else if ((isFP64) && (cc_arg) > 0) { \
FP64ArgInitializer[(cc_arg)-1] = RegARM32::val; \
} else if ((isVec128) && (cc_arg) > 0) { \
Vec128ArgInitializer[(cc_arg)-1] = RegARM32::val; \
}
REGARM32_TABLE; REGARM32_TABLE;
#undef X #undef X
TypeToRegisterSet[IceType_void] = InvalidRegisters; TypeToRegisterSet[IceType_void] = InvalidRegisters;
...@@ -237,24 +296,17 @@ void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) { ...@@ -237,24 +296,17 @@ void copyRegAllocFromInfWeightVariable64On32(const VarList &Vars) {
uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) { uint32_t TargetARM32::getCallStackArgumentsSizeBytes(const InstCall *Call) {
TargetARM32::CallingConv CC; TargetARM32::CallingConv CC;
int32_t DummyReg;
size_t OutArgsSizeBytes = 0; size_t OutArgsSizeBytes = 0;
for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) { for (SizeT i = 0, NumArgs = Call->getNumArgs(); i < NumArgs; ++i) {
Operand *Arg = legalizeUndef(Call->getArg(i)); Operand *Arg = legalizeUndef(Call->getArg(i));
Type Ty = Arg->getType(); const Type Ty = Arg->getType();
if (Ty == IceType_i64) { if (isScalarIntegerType(Ty)) {
std::pair<int32_t, int32_t> Regs; if (CC.argInGPR(Ty, &DummyReg)) {
if (CC.I64InRegs(&Regs)) {
continue;
}
} else if (isVectorType(Ty) || isFloatingType(Ty)) {
int32_t Reg;
if (CC.FPInReg(Ty, &Reg)) {
continue; continue;
} }
} else { } else {
assert(Ty == IceType_i32); if (CC.argInVFP(Ty, &DummyReg)) {
int32_t Reg;
if (CC.I32InReg(&Reg)) {
continue; continue;
} }
} }
...@@ -769,8 +821,8 @@ bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) { ...@@ -769,8 +821,8 @@ bool TargetARM32::doBranchOpt(Inst *I, const CfgNode *NextNode) {
} }
const char *RegARM32::RegNames[] = { const char *RegARM32::RegNames[] = {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
name, name,
REGARM32_TABLE REGARM32_TABLE
#undef X #undef X
...@@ -784,8 +836,8 @@ IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const { ...@@ -784,8 +836,8 @@ IceString TargetARM32::getRegName(SizeT RegNum, Type Ty) const {
Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) { Variable *TargetARM32::getPhysicalRegister(SizeT RegNum, Type Ty) {
static const Type DefaultType[] = { static const Type DefaultType[] = {
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
(isFP32) \ (isFP32) \
? IceType_f32 \ ? IceType_f32 \
: ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))), : ((isFP64) ? IceType_f64 : ((isVec128 ? IceType_v4i32 : IceType_i32))),
...@@ -848,118 +900,92 @@ void TargetARM32::emitVariable(const Variable *Var) const { ...@@ -848,118 +900,92 @@ void TargetARM32::emitVariable(const Variable *Var) const {
Str << "]"; Str << "]";
} }
bool TargetARM32::CallingConv::I64InRegs(std::pair<int32_t, int32_t> *Regs) { TargetARM32::CallingConv::CallingConv()
if (NumGPRRegsUsed >= ARM32_MAX_GPR_ARG) : GPRegsUsed(RegARM32::Reg_NUM),
return false; GPRArgs(GPRArgInitializer.rbegin(), GPRArgInitializer.rend()),
int32_t RegLo, RegHi; I64Args(I64ArgInitializer.rbegin(), I64ArgInitializer.rend()),
// Always start i64 registers at an even register, so this may end up padding VFPRegsUsed(RegARM32::Reg_NUM),
// away a register. FP32Args(FP32ArgInitializer.rbegin(), FP32ArgInitializer.rend()),
NumGPRRegsUsed = Utils::applyAlignment(NumGPRRegsUsed, 2); FP64Args(FP64ArgInitializer.rbegin(), FP64ArgInitializer.rend()),
RegLo = RegARM32::Reg_r0 + NumGPRRegsUsed; Vec128Args(Vec128ArgInitializer.rbegin(), Vec128ArgInitializer.rend()) {}
++NumGPRRegsUsed;
RegHi = RegARM32::Reg_r0 + NumGPRRegsUsed; bool TargetARM32::CallingConv::argInGPR(Type Ty, int32_t *Reg) {
++NumGPRRegsUsed; CfgVector<SizeT> *Source;
// If this bumps us past the boundary, don't allocate to a register and leave
// any previously speculatively consumed registers as consumed. switch (Ty) {
if (NumGPRRegsUsed > ARM32_MAX_GPR_ARG) default: {
assert(isScalarIntegerType(Ty));
Source = &GPRArgs;
} break;
case IceType_i64: {
Source = &I64Args;
} break;
}
discardUnavailableGPRsAndTheirAliases(Source);
if (Source->empty()) {
GPRegsUsed.set();
return false; return false;
Regs->first = RegLo; }
Regs->second = RegHi;
*Reg = Source->back();
// Note that we don't Source->pop_back() here. This is intentional. Notice how
// we mark all of Reg's aliases as Used. So, for the next argument,
// Source->back() is marked as unavailable, and it is thus implicitly popped
// from the stack.
GPRegsUsed |= RegisterAliases[*Reg];
return true; return true;
} }
bool TargetARM32::CallingConv::I32InReg(int32_t *Reg) { // GPR are not packed when passing parameters. Thus, a function foo(i32, i64,
if (NumGPRRegsUsed >= ARM32_MAX_GPR_ARG) // i32) will have the first argument in r0, the second in r1-r2, and the third
return false; // on the stack. To model this behavior, whenever we pop a register from Regs,
*Reg = RegARM32::Reg_r0 + NumGPRRegsUsed; // we remove all of its aliases from the pool of available GPRs. This has the
++NumGPRRegsUsed; // effect of computing the "closure" on the GPR registers.
return true; void TargetARM32::CallingConv::discardUnavailableGPRsAndTheirAliases(
CfgVector<SizeT> *Regs) {
while (!Regs->empty() && GPRegsUsed[Regs->back()]) {
GPRegsUsed |= RegisterAliases[Regs->back()];
Regs->pop_back();
}
} }
// The calling convention helper class (TargetARM32::CallingConv) expects the bool TargetARM32::CallingConv::argInVFP(Type Ty, int32_t *Reg) {
// following registers to be declared in a certain order, so we have these CfgVector<SizeT> *Source;
// sanity checks to ensure nothing breaks unknowingly.
// TODO(jpp): modify the CallingConv class so it does not rely on any register switch (Ty) {
// declaration order. default: {
#define SANITY_CHECK_QS(_0, _1) \ assert(isVectorType(Ty));
static_assert((RegARM32::Reg_##_1 + 1) == RegARM32::Reg_##_0, \ Source = &Vec128Args;
"ARM32 " #_0 " and " #_1 " registers are declared " \ } break;
"incorrectly.") case IceType_f32: {
SANITY_CHECK_QS(q0, q1); Source = &FP32Args;
SANITY_CHECK_QS(q1, q2); } break;
SANITY_CHECK_QS(q2, q3); case IceType_f64: {
SANITY_CHECK_QS(q3, q4); Source = &FP64Args;
#undef SANITY_CHECK_QS } break;
#define SANITY_CHECK_DS(_0, _1) \
static_assert((RegARM32::Reg_##_1 + 1) == RegARM32::Reg_##_0, \
"ARM32 " #_0 " and " #_1 " registers are declared " \
"incorrectly.")
SANITY_CHECK_DS(d0, d1);
SANITY_CHECK_DS(d1, d2);
SANITY_CHECK_DS(d2, d3);
SANITY_CHECK_DS(d3, d4);
SANITY_CHECK_DS(d4, d5);
SANITY_CHECK_DS(d5, d6);
SANITY_CHECK_DS(d6, d7);
SANITY_CHECK_DS(d7, d8);
#undef SANITY_CHECK_DS
#define SANITY_CHECK_SS(_0, _1) \
static_assert((RegARM32::Reg_##_0 + 1) == RegARM32::Reg_##_1, \
"ARM32 " #_0 " and " #_1 " registers are declared " \
"incorrectly.")
SANITY_CHECK_SS(s0, s1);
SANITY_CHECK_SS(s1, s2);
SANITY_CHECK_SS(s2, s3);
SANITY_CHECK_SS(s3, s4);
SANITY_CHECK_SS(s4, s5);
SANITY_CHECK_SS(s5, s6);
SANITY_CHECK_SS(s6, s7);
SANITY_CHECK_SS(s7, s8);
SANITY_CHECK_SS(s8, s9);
SANITY_CHECK_SS(s9, s10);
SANITY_CHECK_SS(s10, s11);
SANITY_CHECK_SS(s11, s12);
SANITY_CHECK_SS(s12, s13);
SANITY_CHECK_SS(s13, s14);
SANITY_CHECK_SS(s14, s15);
#undef SANITY_CHECK_SS
bool TargetARM32::CallingConv::FPInReg(Type Ty, int32_t *Reg) {
if (!VFPRegsFree.any()) {
return false;
} }
if (isVectorType(Ty)) { discardUnavailableVFPRegs(Source);
// Q registers are declared in reverse order, so RegARM32::Reg_q0 >
// RegARM32::Reg_q1. Therefore, we need to subtract QRegStart from Reg_q0. if (Source->empty()) {
// Same thing goes for D registers. VFPRegsUsed.set();
int32_t QRegStart = (VFPRegsFree & ValidV128Regs).find_first(); return false;
if (QRegStart >= 0) {
VFPRegsFree.reset(QRegStart, QRegStart + 4);
*Reg = RegARM32::Reg_q0 - (QRegStart / 4);
return true;
}
} else if (Ty == IceType_f64) {
int32_t DRegStart = (VFPRegsFree & ValidF64Regs).find_first();
if (DRegStart >= 0) {
VFPRegsFree.reset(DRegStart, DRegStart + 2);
*Reg = RegARM32::Reg_d0 - (DRegStart / 2);
return true;
}
} else {
assert(Ty == IceType_f32);
int32_t SReg = VFPRegsFree.find_first();
assert(SReg >= 0);
VFPRegsFree.reset(SReg);
*Reg = RegARM32::Reg_s0 + SReg;
return true;
} }
// Parameter allocation failed. From now on, every fp register must be placed *Reg = Source->back();
// on the stack. We clear VFRegsFree in case there are any "holes" from S and VFPRegsUsed |= RegisterAliases[*Reg];
// D registers. return true;
VFPRegsFree.clear(); }
return false;
// Arguments in VFP registers are not packed, so we don't mark the popped
// registers' aliases as unavailable.
void TargetARM32::CallingConv::discardUnavailableVFPRegs(
CfgVector<SizeT> *Regs) {
while (!Regs->empty() && VFPRegsUsed[Regs->back()]) {
Regs->pop_back();
}
} }
void TargetARM32::lowerArguments() { void TargetARM32::lowerArguments() {
...@@ -975,45 +1001,36 @@ void TargetARM32::lowerArguments() { ...@@ -975,45 +1001,36 @@ void TargetARM32::lowerArguments() {
for (SizeT I = 0, E = Args.size(); I < E; ++I) { for (SizeT I = 0, E = Args.size(); I < E; ++I) {
Variable *Arg = Args[I]; Variable *Arg = Args[I];
Type Ty = Arg->getType(); Type Ty = Arg->getType();
if (Ty == IceType_i64) { int RegNum;
std::pair<int32_t, int32_t> RegPair; if (isScalarIntegerType(Ty)) {
if (!CC.I64InRegs(&RegPair)) if (!CC.argInGPR(Ty, &RegNum)) {
continue; continue;
Variable *RegisterArg = Func->makeVariable(Ty);
auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg);
if (BuildDefs::dump())
RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName(Func));
RegisterArg64On32->initHiLo(Func);
RegisterArg64On32->setIsArg();
RegisterArg64On32->getLo()->setRegNum(RegPair.first);
RegisterArg64On32->getHi()->setRegNum(RegPair.second);
Arg->setIsArg(false);
Args[I] = RegisterArg64On32;
Context.insert(InstAssign::create(Func, Arg, RegisterArg));
continue;
} else {
int32_t RegNum;
if (isVectorType(Ty) || isFloatingType(Ty)) {
if (!CC.FPInReg(Ty, &RegNum))
continue;
} else {
assert(Ty == IceType_i32);
if (!CC.I32InReg(&RegNum))
continue;
} }
Variable *RegisterArg = Func->makeVariable(Ty); } else {
if (BuildDefs::dump()) { if (!CC.argInVFP(Ty, &RegNum)) {
RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func)); continue;
} }
RegisterArg->setRegNum(RegNum); }
RegisterArg->setIsArg();
Arg->setIsArg(false);
Args[I] = RegisterArg; Variable *RegisterArg = Func->makeVariable(Ty);
Context.insert(InstAssign::create(Func, Arg, RegisterArg)); if (BuildDefs::dump()) {
continue; RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
} }
RegisterArg->setIsArg();
Arg->setIsArg(false);
Args[I] = RegisterArg;
switch (Ty) {
default: { RegisterArg->setRegNum(RegNum); } break;
case IceType_i64: {
auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg);
RegisterArg64->initHiLo(Func);
RegisterArg64->getLo()->setRegNum(
RegARM32::getI64PairFirstGPRNum(RegNum));
RegisterArg64->getHi()->setRegNum(
RegARM32::getI64PairSecondGPRNum(RegNum));
} break;
}
Context.insert(InstAssign::create(Func, Arg, RegisterArg));
} }
} }
...@@ -1270,22 +1287,20 @@ void TargetARM32::addProlog(CfgNode *Node) { ...@@ -1270,22 +1287,20 @@ void TargetARM32::addProlog(CfgNode *Node) {
size_t InArgsSizeBytes = 0; size_t InArgsSizeBytes = 0;
TargetARM32::CallingConv CC; TargetARM32::CallingConv CC;
for (Variable *Arg : Args) { for (Variable *Arg : Args) {
Type Ty = Arg->getType(); int32_t DummyReg;
bool InRegs = false; const Type Ty = Arg->getType();
// Skip arguments passed in registers. // Skip arguments passed in registers.
if (isVectorType(Ty) || isFloatingType(Ty)) { if (isScalarIntegerType(Ty)) {
int32_t DummyReg; if (CC.argInGPR(Ty, &DummyReg)) {
InRegs = CC.FPInReg(Ty, &DummyReg); continue;
} else if (Ty == IceType_i64) { }
std::pair<int32_t, int32_t> DummyRegs;
InRegs = CC.I64InRegs(&DummyRegs);
} else { } else {
assert(Ty == IceType_i32); if (CC.argInVFP(Ty, &DummyReg)) {
int32_t DummyReg; continue;
InRegs = CC.I32InReg(&DummyReg); }
} }
if (!InRegs) finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, &InArgsSizeBytes);
finishArgumentLowering(Arg, FramePtr, BasicFrameOffset, &InArgsSizeBytes);
} }
// Fill in stack offsets for locals. // Fill in stack offsets for locals.
...@@ -1812,8 +1827,8 @@ llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include, ...@@ -1812,8 +1827,8 @@ llvm::SmallBitVector TargetARM32::getRegisterSet(RegSetMask Include,
RegSetMask Exclude) const { RegSetMask Exclude) const {
llvm::SmallBitVector Registers(RegARM32::Reg_NUM); llvm::SmallBitVector Registers(RegARM32::Reg_NUM);
#define X(val, encode, name, scratch, preserved, stackptr, frameptr, isInt, \ #define X(val, encode, name, cc_arg, scratch, preserved, stackptr, frameptr, \
isI64Pair, isFP32, isFP64, isVec128, alias_init) \ isInt, isI64Pair, isFP32, isFP64, isVec128, alias_init) \
if (scratch && (Include & RegSet_CallerSave)) \ if (scratch && (Include & RegSet_CallerSave)) \
Registers[RegARM32::val] = true; \ Registers[RegARM32::val] = true; \
if (preserved && (Include & RegSet_CalleeSave)) \ if (preserved && (Include & RegSet_CalleeSave)) \
...@@ -3230,10 +3245,8 @@ void TargetARM32::lowerCall(const InstCall *Instr) { ...@@ -3230,10 +3245,8 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
// Assign arguments to registers and stack. Also reserve stack. // Assign arguments to registers and stack. Also reserve stack.
TargetARM32::CallingConv CC; TargetARM32::CallingConv CC;
// Pair of Arg Operand -> GPR number assignments. // Pair of Arg Operand -> GPR number assignments.
llvm::SmallVector<std::pair<Operand *, int32_t>, llvm::SmallVector<std::pair<Operand *, int32_t>, NumGPRArgs> GPRArgs;
TargetARM32::CallingConv::ARM32_MAX_GPR_ARG> GPRArgs; llvm::SmallVector<std::pair<Operand *, int32_t>, NumFP32Args> FPArgs;
llvm::SmallVector<std::pair<Operand *, int32_t>,
TargetARM32::CallingConv::ARM32_MAX_FP_REG_UNITS> FPArgs;
// Pair of Arg Operand -> stack offset. // Pair of Arg Operand -> stack offset.
llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs; llvm::SmallVector<std::pair<Operand *, int32_t>, 8> StackArgs;
size_t ParameterAreaSizeBytes = 0; size_t ParameterAreaSizeBytes = 0;
...@@ -3242,37 +3255,34 @@ void TargetARM32::lowerCall(const InstCall *Instr) { ...@@ -3242,37 +3255,34 @@ void TargetARM32::lowerCall(const InstCall *Instr) {
// argument is passed. // argument is passed.
for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) { for (SizeT i = 0, NumArgs = Instr->getNumArgs(); i < NumArgs; ++i) {
Operand *Arg = legalizeUndef(Instr->getArg(i)); Operand *Arg = legalizeUndef(Instr->getArg(i));
Type Ty = Arg->getType(); const Type Ty = Arg->getType();
bool InRegs = false; bool InReg = false;
if (Ty == IceType_i64) { int32_t Reg;
std::pair<int32_t, int32_t> Regs; if (isScalarIntegerType(Ty)) {
if (CC.I64InRegs(&Regs)) { InReg = CC.argInGPR(Ty, &Reg);
InRegs = true;
Operand *Lo = loOperand(Arg);
Operand *Hi = hiOperand(Arg);
GPRArgs.push_back(std::make_pair(Lo, Regs.first));
GPRArgs.push_back(std::make_pair(Hi, Regs.second));
}
} else if (isVectorType(Ty) || isFloatingType(Ty)) {
int32_t Reg;
if (CC.FPInReg(Ty, &Reg)) {
InRegs = true;
FPArgs.push_back(std::make_pair(Arg, Reg));
}
} else { } else {
assert(Ty == IceType_i32); InReg = CC.argInVFP(Ty, &Reg);
int32_t Reg;
if (CC.I32InReg(&Reg)) {
InRegs = true;
GPRArgs.push_back(std::make_pair(Arg, Reg));
}
} }
if (!InRegs) { if (!InReg) {
ParameterAreaSizeBytes = ParameterAreaSizeBytes =
applyStackAlignmentTy(ParameterAreaSizeBytes, Ty); applyStackAlignmentTy(ParameterAreaSizeBytes, Ty);
StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes)); StackArgs.push_back(std::make_pair(Arg, ParameterAreaSizeBytes));
ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty); ParameterAreaSizeBytes += typeWidthInBytesOnStack(Ty);
continue;
}
if (Ty == IceType_i64) {
Operand *Lo = loOperand(Arg);
Operand *Hi = hiOperand(Arg);
GPRArgs.push_back(
std::make_pair(Lo, RegARM32::getI64PairFirstGPRNum(Reg)));
GPRArgs.push_back(
std::make_pair(Hi, RegARM32::getI64PairSecondGPRNum(Reg)));
} else if (isScalarIntegerType(Ty)) {
GPRArgs.push_back(std::make_pair(Arg, Reg));
} else {
FPArgs.push_back(std::make_pair(Arg, Reg));
} }
} }
......
...@@ -1046,34 +1046,30 @@ protected: ...@@ -1046,34 +1046,30 @@ protected:
CallingConv &operator=(const CallingConv &) = delete; CallingConv &operator=(const CallingConv &) = delete;
public: public:
CallingConv() CallingConv();
: VFPRegsFree(ARM32_MAX_FP_REG_UNITS, true),
ValidF64Regs(ARM32_MAX_FP_REG_UNITS),
ValidV128Regs(ARM32_MAX_FP_REG_UNITS) {
for (uint32_t i = 0; i < ARM32_MAX_FP_REG_UNITS; ++i) {
if ((i % 2) == 0) {
ValidF64Regs[i] = true;
}
if ((i % 4) == 0) {
ValidV128Regs[i] = true;
}
}
}
~CallingConv() = default; ~CallingConv() = default;
bool I64InRegs(std::pair<int32_t, int32_t> *Regs); /// argInGPR returns true if there is a GPR available for the requested
bool I32InReg(int32_t *Reg); /// type, and false otherwise. If it returns true, Reg is set to the
bool FPInReg(Type Ty, int32_t *Reg); /// appropriate register number. Note that, when Ty == IceType_i64, Reg will
/// be an I64 register pair.
bool argInGPR(Type Ty, int32_t *Reg);
static constexpr uint32_t ARM32_MAX_GPR_ARG = 4; /// argInVFP is to floating-point/vector types what argInGPR is for integer
// TODO(jpp): comment. /// types.
static constexpr uint32_t ARM32_MAX_FP_REG_UNITS = 16; bool argInVFP(Type Ty, int32_t *Reg);
private: private:
uint32_t NumGPRRegsUsed = 0; void discardUnavailableGPRsAndTheirAliases(CfgVector<SizeT> *Regs);
llvm::SmallBitVector VFPRegsFree; llvm::SmallBitVector GPRegsUsed;
llvm::SmallBitVector ValidF64Regs; CfgVector<SizeT> GPRArgs;
llvm::SmallBitVector ValidV128Regs; CfgVector<SizeT> I64Args;
void discardUnavailableVFPRegs(CfgVector<SizeT> *Regs);
llvm::SmallBitVector VFPRegsUsed;
CfgVector<SizeT> FP32Args;
CfgVector<SizeT> FP64Args;
CfgVector<SizeT> Vec128Args;
}; };
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment