ARM more NEON VLD/VST composite physical register refactoring.

Register pair, all lanes subscripting.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152157 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2012-03-06 23:10:38 +00:00
parent c511c2827d
commit 4d0983a4d7
6 changed files with 59 additions and 40 deletions

View File

@ -163,14 +163,14 @@ def VecListDPairAllLanes : RegisterOperand<DPair,
let ParserMatchClass = VecListDPairAllLanesAsmOperand;
}
// Register list of two D registers spaced by 2 (two sequential Q registers).
def VecListTwoQAllLanesAsmOperand : AsmOperandClass {
let Name = "VecListTwoQAllLanes";
def VecListDPairSpacedAllLanesAsmOperand : AsmOperandClass {
let Name = "VecListDPairSpacedAllLanes";
let ParserMethod = "parseVectorList";
let RenderMethod = "addVecListOperands";
}
def VecListTwoQAllLanes : RegisterOperand<DPR,
def VecListDPairSpacedAllLanes : RegisterOperand<DPair,
"printVectorListTwoSpacedAllLanes"> {
let ParserMatchClass = VecListTwoQAllLanesAsmOperand;
let ParserMatchClass = VecListDPairSpacedAllLanesAsmOperand;
}
// Register list of three D registers, with "all lanes" subscripting.
def VecListThreeDAllLanesAsmOperand : AsmOperandClass {
@ -1369,10 +1369,10 @@ def VLD2DUPd8 : VLD2DUP<{0,0,0,?}, "8", VecListDPairAllLanes>;
def VLD2DUPd16 : VLD2DUP<{0,1,0,?}, "16", VecListDPairAllLanes>;
def VLD2DUPd32 : VLD2DUP<{1,0,0,?}, "32", VecListDPairAllLanes>;
// ...with double-spaced registers (not used for codegen):
def VLD2DUPd8x2 : VLD2DUP<{0,0,1,?}, "8", VecListTwoQAllLanes>;
def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListTwoQAllLanes>;
def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListTwoQAllLanes>;
// ...with double-spaced registers
def VLD2DUPd8x2 : VLD2DUP<{0,0,1,?}, "8", VecListDPairSpacedAllLanes>;
def VLD2DUPd16x2 : VLD2DUP<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
def VLD2DUPd32x2 : VLD2DUP<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
// ...with address register writeback:
multiclass VLD2DUPWB<bits<4> op7_4, string Dt, RegisterOperand VdTy> {
@ -1401,9 +1401,9 @@ defm VLD2DUPd8wb : VLD2DUPWB<{0,0,0,0}, "8", VecListDPairAllLanes>;
defm VLD2DUPd16wb : VLD2DUPWB<{0,1,0,?}, "16", VecListDPairAllLanes>;
defm VLD2DUPd32wb : VLD2DUPWB<{1,0,0,?}, "32", VecListDPairAllLanes>;
defm VLD2DUPd8x2wb : VLD2DUPWB<{0,0,1,0}, "8", VecListTwoQAllLanes>;
defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListTwoQAllLanes>;
defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListTwoQAllLanes>;
defm VLD2DUPd8x2wb : VLD2DUPWB<{0,0,1,0}, "8", VecListDPairSpacedAllLanes>;
defm VLD2DUPd16x2wb : VLD2DUPWB<{0,1,1,?}, "16", VecListDPairSpacedAllLanes>;
defm VLD2DUPd32x2wb : VLD2DUPWB<{1,0,1,?}, "32", VecListDPairSpacedAllLanes>;
// VLD3DUP : Vector Load (single 3-element structure to all lanes)
class VLD3DUP<bits<4> op7_4, string Dt>

View File

@ -1101,11 +1101,6 @@ public:
return VectorList.Count == 4;
}
bool isVecListTwoQ() const {
if (!isDoubleSpacedVectorList()) return false;
return VectorList.Count == 2;
}
bool isVecListDPairSpaced() const {
if (!isSingleSpacedVectorList()) return false;
return (ARMMCRegisterClasses[ARM::DPairSpcRegClassID]
@ -1139,7 +1134,7 @@ public:
.contains(VectorList.RegNum));
}
bool isVecListTwoQAllLanes() const {
bool isVecListDPairSpacedAllLanes() const {
if (!isDoubleSpacedVectorAllLanes()) return false;
return VectorList.Count == 2;
}
@ -3169,8 +3164,10 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
case AllLanes:
// Two-register operands have been converted to the
// composite register classes.
if (Count == 2 && Spacing == 1) {
const MCRegisterClass *RC = &ARMMCRegisterClasses[ARM::DPairRegClassID];
if (Count == 2) {
const MCRegisterClass *RC = (Spacing == 1) ?
&ARMMCRegisterClasses[ARM::DPairRegClassID] :
&ARMMCRegisterClasses[ARM::DPairSpcRegClassID];
FirstReg = MRI->getMatchingSuperReg(FirstReg, ARM::dsub_0, RC);
}
Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,

View File

@ -2572,6 +2572,13 @@ static DecodeStatus DecodeVLD2DupInstruction(llvm::MCInst &Inst, unsigned Insn,
if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
return MCDisassembler::Fail;
break;
case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
return MCDisassembler::Fail;
break;
default:
if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
return MCDisassembler::Fail;

View File

@ -1104,11 +1104,10 @@ void ARMInstPrinter::printVectorListFourAllLanes(const MCInst *MI,
void ARMInstPrinter::printVectorListTwoSpacedAllLanes(const MCInst *MI,
unsigned OpNum,
raw_ostream &O) {
// Normally, it's not safe to use register enum values directly with
// addition to get the next register, but for VFP registers, the
// sort order is guaranteed because they're all of the form D<n>.
O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[], "
<< getRegisterName(MI->getOperand(OpNum).getReg() + 2) << "[]}";
unsigned Reg = MI->getOperand(OpNum).getReg();
unsigned Reg0 = MRI.getSubReg(Reg, ARM::dsub_0);
unsigned Reg1 = MRI.getSubReg(Reg, ARM::dsub_2);
O << "{" << getRegisterName(Reg0) << "[], " << getRegisterName(Reg1) << "[]}";
}
void ARMInstPrinter::printVectorListThreeSpacedAllLanes(const MCInst *MI,

View File

@ -187,21 +187,37 @@ inline static unsigned getARMRegisterNumbering(unsigned Reg) {
case S31: case D31: return 31;
// Composite registers use the regnum of the first register in the list.
case D1_D2: return 1;
case D3_D5: return 3;
case D5_D7: return 5;
case D7_D9: return 7;
case D9_D10: return 9;
case D11_D12: return 11;
case D13_D14: return 13;
case D15_D16: return 15;
case D17_D18: return 17;
case D19_D20: return 19;
case D21_D22: return 21;
case D23_D24: return 23;
case D25_D26: return 25;
case D27_D28: return 27;
case D29_D30: return 29;
/* Q0 */ case D0_D2: return 0;
case D1_D2: case D1_D3: return 1;
/* Q1 */ case D2_D4: return 2;
case D3_D4: case D3_D5: return 3;
/* Q2 */ case D4_D6: return 4;
case D5_D6: case D5_D7: return 5;
/* Q3 */ case D6_D8: return 6;
case D7_D8: case D7_D9: return 7;
/* Q4 */ case D8_D10: return 8;
case D9_D10: case D9_D11: return 9;
/* Q5 */ case D10_D12: return 10;
case D11_D12: case D11_D13: return 11;
/* Q6 */ case D12_D14: return 12;
case D13_D14: case D13_D15: return 13;
/* Q7 */ case D14_D16: return 14;
case D15_D16: case D15_D17: return 15;
/* Q8 */ case D16_D18: return 16;
case D17_D18: case D17_D19: return 17;
/* Q9 */ case D18_D20: return 18;
case D19_D20: case D19_D21: return 19;
/* Q10 */ case D20_D22: return 20;
case D21_D22: case D21_D23: return 21;
/* Q11 */ case D22_D24: return 22;
case D23_D24: case D23_D25: return 23;
/* Q12 */ case D24_D26: return 24;
case D25_D26: case D25_D27: return 25;
/* Q13 */ case D26_D28: return 26;
case D27_D28: case D27_D29: return 27;
/* Q14 */ case D28_D30: return 28;
case D29_D30: case D29_D31: return 29;
/* Q15 */
}
}

View File

@ -580,7 +580,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
REG("VecListFourD");
REG("VecListOneDAllLanes");
REG("VecListDPairAllLanes");
REG("VecListTwoQAllLanes");
REG("VecListDPairSpacedAllLanes");
IMM("i32imm");
IMM("fbits16");