diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-09-14 23:54:06 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-09-14 23:54:06 +0000 |
commit | 05ae0c6026c15cc934ef2117a7a75ae57c55067d (patch) | |
tree | 11316a778d297f2a31eff479eed921642b82e5d6 /lib | |
parent | ef63c9a9b6f79fef91dc144db9d5f217d2b83a95 (diff) |
Reapply r113875 with additional cleanups.
"The register specified for a dregpair is the corresponding Q register, so to
get the pair, we need to look up the sub-regs based on the qreg. Create a
lookup function since we don't have access to TargetRegisterInfo here to
be able to use getSubReg(ARM::dsub_[01])."
Additionaly, fix the NEON VLD1* and VST1* instruction patterns not to use
the dregpair modifier for the 2xdreg versions. Explicitly specifying the two
registers as operands is more correct and more consistent with the other
instruction patterns. This enables further cleanup of special case code in the
disassembler as a nice side-effect.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@113903 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 9 | ||||
-rw-r--r-- | lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp | 100 | ||||
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp | 40 |
3 files changed, 33 insertions, 116 deletions
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 9e79047b46..6937392bde 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -218,9 +218,9 @@ class VLD1DWB<bits<4> op7_4, string Dt> "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">; @@ -675,8 +675,9 @@ class VST1DWB<bits<4> op7_4, string Dt> "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">; diff --git a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp index ef4897e7db..000108a7cc 100644 --- a/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/AsmPrinter/ARMInstPrinter.cpp @@ -29,73 +29,27 @@ using namespace llvm; #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); } } @@ -189,19 +143,11 @@ void ARMInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, 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); diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp index 9f493b9aee..edfb20766c 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp @@ -79,22 +79,9 @@ const char *ARMUtils::OpcodeName(unsigned Opcode) { } // 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; @@ -2201,22 +2188,6 @@ static unsigned decodeN3VImm(uint32_t insn) { 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* @@ -2243,10 +2214,9 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn, // 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); @@ -2292,7 +2262,7 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t 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; } @@ -2311,7 +2281,7 @@ static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn, while (OpIdx < NumOps && (unsigned)OpInfo[OpIdx].RegClass == RegClass) { MI.addOperand(MCOperand::CreateReg( - getRegisterEnum(B, RegClass, Rd, DRegPair))); + getRegisterEnum(B, RegClass, Rd))); Rd += Inc; ++OpIdx; } |