"vld1", Dt, "\\{$dst\\}, $addr$offset",
"$addr.addr = $wb", []>;
class VLD1QWB<bits<4> op7_4, string Dt>
- : NLdSt<0,0b10,0b1010,op7_4, (outs QPR:$dst, GPR:$wb),
+ : NLdSt<0,0b10,0b1010,op7_4, (outs DPR:$dst1, DPR:$dst2, GPR:$wb),
(ins addrmode6:$addr, am6offset:$offset), IIC_VLD2,
- "vld1", Dt, "${dst:dregpair}, $addr$offset",
+ "vld1", Dt, "\\{$dst1, $dst2\\}, $addr$offset",
"$addr.addr = $wb", []>;
def VLD1d8_UPD : VLD1DWB<0b0000, "8">;
"vst1", Dt, "\\{$src\\}, $addr$offset", "$addr.addr = $wb", []>;
class VST1QWB<bits<4> op7_4, string Dt>
: NLdSt<0, 0b00, 0b1010, op7_4, (outs GPR:$wb),
- (ins addrmode6:$addr, am6offset:$offset, QPR:$src), IIC_VST,
- "vst1", Dt, "${src:dregpair}, $addr$offset", "$addr.addr = $wb", []>;
+ (ins addrmode6:$addr, am6offset:$offset, DPR:$src1, DPR:$src2),
+ IIC_VST, "vst1", Dt, "\\{$src1, $src2\\}, $addr$offset",
+ "$addr.addr = $wb", []>;
def VST1d8_UPD : VST1DWB<0b0000, "8">;
def VST1d16_UPD : VST1DWB<0b0100, "16">;
#undef MachineInstr
#undef ARMAsmPrinter
-static unsigned NextReg(unsigned Reg) {
- switch (Reg) {
+// Get the constituent sub-regs for a dregpair from a Q register.
+static std::pair<unsigned, unsigned> GetDRegPair(unsigned QReg) {
+ switch (QReg) {
default:
assert(0 && "Unexpected register enum");
-
- case ARM::D0:
- return ARM::D1;
- case ARM::D1:
- return ARM::D2;
- case ARM::D2:
- return ARM::D3;
- case ARM::D3:
- return ARM::D4;
- case ARM::D4:
- return ARM::D5;
- case ARM::D5:
- return ARM::D6;
- case ARM::D6:
- return ARM::D7;
- case ARM::D7:
- return ARM::D8;
- case ARM::D8:
- return ARM::D9;
- case ARM::D9:
- return ARM::D10;
- case ARM::D10:
- return ARM::D11;
- case ARM::D11:
- return ARM::D12;
- case ARM::D12:
- return ARM::D13;
- case ARM::D13:
- return ARM::D14;
- case ARM::D14:
- return ARM::D15;
- case ARM::D15:
- return ARM::D16;
- case ARM::D16:
- return ARM::D17;
- case ARM::D17:
- return ARM::D18;
- case ARM::D18:
- return ARM::D19;
- case ARM::D19:
- return ARM::D20;
- case ARM::D20:
- return ARM::D21;
- case ARM::D21:
- return ARM::D22;
- case ARM::D22:
- return ARM::D23;
- case ARM::D23:
- return ARM::D24;
- case ARM::D24:
- return ARM::D25;
- case ARM::D25:
- return ARM::D26;
- case ARM::D26:
- return ARM::D27;
- case ARM::D27:
- return ARM::D28;
- case ARM::D28:
- return ARM::D29;
- case ARM::D29:
- return ARM::D30;
- case ARM::D30:
- return ARM::D31;
+ case ARM::Q0: return std::pair<unsigned, unsigned>(ARM::D0, ARM::D1);
+ case ARM::Q1: return std::pair<unsigned, unsigned>(ARM::D2, ARM::D3);
+ case ARM::Q2: return std::pair<unsigned, unsigned>(ARM::D4, ARM::D5);
+ case ARM::Q3: return std::pair<unsigned, unsigned>(ARM::D6, ARM::D7);
+ case ARM::Q4: return std::pair<unsigned, unsigned>(ARM::D8, ARM::D9);
+ case ARM::Q5: return std::pair<unsigned, unsigned>(ARM::D10, ARM::D11);
+ case ARM::Q6: return std::pair<unsigned, unsigned>(ARM::D12, ARM::D13);
+ case ARM::Q7: return std::pair<unsigned, unsigned>(ARM::D14, ARM::D15);
+ case ARM::Q8: return std::pair<unsigned, unsigned>(ARM::D16, ARM::D17);
+ case ARM::Q9: return std::pair<unsigned, unsigned>(ARM::D18, ARM::D19);
+ case ARM::Q10: return std::pair<unsigned, unsigned>(ARM::D20, ARM::D21);
+ case ARM::Q11: return std::pair<unsigned, unsigned>(ARM::D22, ARM::D23);
+ case ARM::Q12: return std::pair<unsigned, unsigned>(ARM::D24, ARM::D25);
+ case ARM::Q13: return std::pair<unsigned, unsigned>(ARM::D26, ARM::D27);
+ case ARM::Q14: return std::pair<unsigned, unsigned>(ARM::D28, ARM::D29);
+ case ARM::Q15: return std::pair<unsigned, unsigned>(ARM::D30, ARM::D31);
}
}
if (Op.isReg()) {
unsigned Reg = Op.getReg();
if (Modifier && strcmp(Modifier, "dregpair") == 0) {
- O << '{' << getRegisterName(Reg) << ", "
- << getRegisterName(NextReg(Reg)) << '}';
-#if 0
- // FIXME: Breaks e.g. ARM/vmul.ll.
- assert(0);
- /*
- unsigned DRegLo = TRI->getSubReg(Reg, ARM::dsub_0);
- unsigned DRegHi = TRI->getSubReg(Reg, ARM::dsub_1);
- O << '{'
- << getRegisterName(DRegLo) << ',' << getRegisterName(DRegHi)
- << '}';*/
-#endif
+ std::pair<unsigned, unsigned> dregpair = GetDRegPair(Reg);
+ O << '{' << getRegisterName(dregpair.first) << ", "
+ << getRegisterName(dregpair.second) << '}';
} else if (Modifier && strcmp(Modifier, "lane") == 0) {
+ // FIXME
assert(0);
/*
unsigned RegNum = ARMRegisterInfo::getRegisterNumbering(Reg);
}
// Return the register enum Based on RegClass and the raw register number.
-// For DRegPair, see comments below.
// FIXME: Auto-gened?
-static unsigned getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister,
- bool DRegPair = false) {
-
- if (DRegPair && RegClassID == ARM::QPRRegClassID) {
- // LLVM expects { Dd, Dd+1 } to form a super register; this is not specified
- // in the ARM Architecture Manual as far as I understand it (A8.6.307).
- // Therefore, we morph the RegClassID to be the sub register class and don't
- // subsequently transform the RawRegister encoding when calculating RegNum.
- //
- // See also ARMinstPrinter::printOperand() wrt "dregpair" modifier part
- // where this workaround is meant for.
- RegClassID = ARM::DPRRegClassID;
- }
-
+static unsigned
+getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister) {
// For this purpose, we can treat rGPR as if it were GPR.
if (RegClassID == ARM::rGPRRegClassID) RegClassID = ARM::GPRRegClassID;
return (insn >> 8) & 0xF;
}
-static bool UseDRegPair(unsigned Opcode) {
- switch (Opcode) {
- default:
- return false;
- case ARM::VLD1q8_UPD:
- case ARM::VLD1q16_UPD:
- case ARM::VLD1q32_UPD:
- case ARM::VLD1q64_UPD:
- case ARM::VST1q8_UPD:
- case ARM::VST1q16_UPD:
- case ARM::VST1q32_UPD:
- case ARM::VST1q64_UPD:
- return true;
- }
-}
-
// VLD*
// D[d] D[d2] ... Rn [TIED_TO Rn] align [Rm]
// VLD*LN*
// We have homogeneous NEON registers for Load/Store.
unsigned RegClass = 0;
- bool DRegPair = UseDRegPair(Opcode);
// Double-spaced registers have increments of 2.
- unsigned Inc = (DblSpaced || DRegPair) ? 2 : 1;
+ unsigned Inc = DblSpaced ? 2 : 1;
unsigned Rn = decodeRn(insn);
unsigned Rm = decodeRm(insn);
RegClass = OpInfo[OpIdx].RegClass;
while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(B, RegClass, Rd, DRegPair)));
+ getRegisterEnum(B, RegClass, Rd)));
Rd += Inc;
++OpIdx;
}
while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(B, RegClass, Rd, DRegPair)));
+ getRegisterEnum(B, RegClass, Rd)));
Rd += Inc;
++OpIdx;
}
# CHECK: vdup.32 q3, d1[0]
0x41 0x6c 0xb4 0xf3
-# VLD1q8_UPD (with ${dst:dregpair} operand)
# CHECK: vld1.8 {d17, d18}, [r6], r5
0x05 0x1a 0x66 0xf4
+# CHECK: vld1.8 {d17, d18, d19}, [r6], r5
+0x05 0x16 0x66 0xf4
+
# CHECK: vld4.8 {d0, d1, d2, d3}, [r2], r7
0x07 0x00 0x22 0xf4