aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-11-30 01:09:44 +0000
committerJim Grosbach <grosbach@apple.com>2011-11-30 01:09:44 +0000
commit98b05a57b67d1968381563c8cccbbb6c6cb65e3d (patch)
tree1f6868b8a57f7b66aca8c50621f1479c52e2a18f /lib/Target
parent3d925d24e8c54cde05228258c25cc21687cad922 (diff)
downloadexternal_llvm-98b05a57b67d1968381563c8cccbbb6c6cb65e3d.tar.gz
external_llvm-98b05a57b67d1968381563c8cccbbb6c6cb65e3d.tar.bz2
external_llvm-98b05a57b67d1968381563c8cccbbb6c6cb65e3d.zip
ARM parsing aliases for VLD1 single register all lanes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@145464 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td3
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td18
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp117
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp7
-rw-r--r--lib/Target/ARM/InstPrinter/ARMInstPrinter.h2
5 files changed, 141 insertions, 6 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index be039246a0..f0077e5b10 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -812,6 +812,9 @@ def addrmode6dup : Operand<i32>,
let PrintMethod = "printAddrMode6Operand";
let MIOperandInfo = (ops GPR:$addr, i32imm);
let EncoderMethod = "getAddrMode6DupAddressOpValue";
+ // FIXME: This is close, but not quite right. The alignment specifier is
+ // different.
+ let ParserMatchClass = AddrMode6AsmOperand;
}
// addrmodepc := pc + reg
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index ce2ea30779..0a1afa454b 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -120,6 +120,16 @@ def VecListTwoQ : RegisterOperand<DPR, "printVectorListTwo"> {
let ParserMatchClass = VecListTwoQAsmOperand;
}
+// Register list of one D register, with "all lanes" subscripting.
+def VecListOneDAllLanesAsmOperand : AsmOperandClass {
+ let Name = "VecListOneDAllLanes";
+ let ParserMethod = "parseVectorList";
+ let RenderMethod = "addVecListOperands";
+}
+def VecListOneDAllLanes : RegisterOperand<DPR, "printVectorListOneAllLanes"> {
+ let ParserMatchClass = VecListOneDAllLanesAsmOperand;
+}
+
//===----------------------------------------------------------------------===//
// NEON-specific DAG Nodes.
//===----------------------------------------------------------------------===//
@@ -1003,9 +1013,11 @@ def VLD4LNq32Pseudo_UPD : VLDQQQQLNWBPseudo<IIC_VLD4lnu>;
// VLD1DUP : Vector Load (single element to all lanes)
class VLD1DUP<bits<4> op7_4, string Dt, ValueType Ty, PatFrag LoadOp>
- : NLdSt<1, 0b10, 0b1100, op7_4, (outs DPR:$Vd), (ins addrmode6dup:$Rn),
- IIC_VLD1dup, "vld1", Dt, "\\{$Vd[]\\}, $Rn", "",
- [(set DPR:$Vd, (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> {
+ : NLdSt<1, 0b10, 0b1100, op7_4, (outs VecListOneDAllLanes:$Vd),
+ (ins addrmode6dup:$Rn),
+ IIC_VLD1dup, "vld1", Dt, "$Vd, $Rn", "",
+ [(set VecListOneDAllLanes:$Vd,
+ (Ty (NEONvdup (i32 (LoadOp addrmode6dup:$Rn)))))]> {
let Rm = 0b1111;
let Inst{4} = Rn{4};
let DecoderMethod = "DecodeVLD1DupInstruction";
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index b2e2f7a5b5..a96b37d53a 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -39,6 +39,8 @@ namespace {
class ARMOperand;
+enum VectorLaneTy { NoLanes, AllLanes };
+
class ARMAsmParser : public MCTargetAsmParser {
MCSubtargetInfo &STI;
MCAsmParser &Parser;
@@ -161,6 +163,7 @@ class ARMAsmParser : public MCTargetAsmParser {
OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
+ OperandMatchResultTy parseVectorLane(VectorLaneTy &LaneKind);
// Asm Match Converter Methods
bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
@@ -271,6 +274,7 @@ class ARMOperand : public MCParsedAsmOperand {
k_DPRRegisterList,
k_SPRRegisterList,
k_VectorList,
+ k_VectorListAllLanes,
k_ShiftedRegister,
k_ShiftedImmediate,
k_ShifterImmediate,
@@ -409,6 +413,7 @@ public:
Registers = o.Registers;
break;
case k_VectorList:
+ case k_VectorListAllLanes:
VectorList = o.VectorList;
break;
case k_CoprocNum:
@@ -967,6 +972,11 @@ public:
return VectorList.Count == 2 && false;
}
+ bool isVecListOneDAllLanes() const {
+ if (Kind != k_VectorListAllLanes) return false;
+ return VectorList.Count == 1;
+ }
+
bool isVectorIndex8() const {
if (Kind != k_VectorIndex) return false;
return VectorIndex.Val < 8;
@@ -1761,6 +1771,16 @@ public:
return Op;
}
+ static ARMOperand *CreateVectorListAllLanes(unsigned RegNum, unsigned Count,
+ SMLoc S, SMLoc E) {
+ ARMOperand *Op = new ARMOperand(k_VectorListAllLanes);
+ Op->VectorList.RegNum = RegNum;
+ Op->VectorList.Count = Count;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+ }
+
static ARMOperand *CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E,
MCContext &Ctx) {
ARMOperand *Op = new ARMOperand(k_VectorIndex);
@@ -1954,6 +1974,10 @@ void ARMOperand::print(raw_ostream &OS) const {
OS << "<vector_list " << VectorList.Count << " * "
<< VectorList.RegNum << ">";
break;
+ case k_VectorListAllLanes:
+ OS << "<vector_list(all lanes) " << VectorList.Count << " * "
+ << VectorList.RegNum << ">";
+ break;
case k_Token:
OS << "'" << getToken() << "'";
break;
@@ -2453,9 +2477,29 @@ parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return false;
}
+// Helper function to parse the lane index for vector lists.
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+parseVectorLane(VectorLaneTy &LaneKind) {
+ if (Parser.getTok().is(AsmToken::LBrac)) {
+ Parser.Lex(); // Eat the '['.
+ if (Parser.getTok().is(AsmToken::RBrac)) {
+ // "Dn[]" is the 'all lanes' syntax.
+ LaneKind = AllLanes;
+ Parser.Lex(); // Eat the ']'.
+ return MatchOperand_Success;
+ }
+ // FIXME: Other lane kinds as we add them.
+ Error(Parser.getTok().getLoc(), "FIXME: Unexpected lane kind.");
+ return MatchOperand_ParseFail;
+ }
+ LaneKind = NoLanes;
+ return MatchOperand_Success;
+}
+
// parse a vector register list
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ VectorLaneTy LaneKind;
SMLoc S = Parser.getTok().getLoc();
// As an extension (to match gas), support a plain D register or Q register
// (without encosing curly braces) as a single or double entry list,
@@ -2466,12 +2510,40 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_NoMatch;
SMLoc E = Parser.getTok().getLoc();
if (ARMMCRegisterClasses[ARM::DPRRegClassID].contains(Reg)) {
- Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E));
+ OperandMatchResultTy Res = parseVectorLane(LaneKind);
+ if (Res != MatchOperand_Success)
+ return Res;
+ switch (LaneKind) {
+ default:
+ assert(0 && "unexpected lane kind!");
+ case NoLanes:
+ E = Parser.getTok().getLoc();
+ Operands.push_back(ARMOperand::CreateVectorList(Reg, 1, S, E));
+ break;
+ case AllLanes:
+ E = Parser.getTok().getLoc();
+ Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 1, S, E));
+ break;
+ }
return MatchOperand_Success;
}
if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains(Reg)) {
Reg = getDRegFromQReg(Reg);
- Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E));
+ OperandMatchResultTy Res = parseVectorLane(LaneKind);
+ if (Res != MatchOperand_Success)
+ return Res;
+ switch (LaneKind) {
+ default:
+ assert(0 && "unexpected lane kind!");
+ case NoLanes:
+ E = Parser.getTok().getLoc();
+ Operands.push_back(ARMOperand::CreateVectorList(Reg, 2, S, E));
+ break;
+ case AllLanes:
+ E = Parser.getTok().getLoc();
+ Operands.push_back(ARMOperand::CreateVectorListAllLanes(Reg, 2, S, E));
+ break;
+ }
return MatchOperand_Success;
}
Error(S, "vector register expected");
@@ -2498,6 +2570,8 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
++Reg;
++Count;
}
+ if (parseVectorLane(LaneKind) != MatchOperand_Success)
+ return MatchOperand_ParseFail;
while (Parser.getTok().is(AsmToken::Comma) ||
Parser.getTok().is(AsmToken::Minus)) {
@@ -2526,6 +2600,15 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
Error(EndLoc, "bad range in register list");
return MatchOperand_ParseFail;
}
+ // Parse the lane specifier if present.
+ VectorLaneTy NextLaneKind;
+ if (parseVectorLane(NextLaneKind) != MatchOperand_Success)
+ return MatchOperand_ParseFail;
+ if (NextLaneKind != LaneKind) {
+ Error(EndLoc, "mismatched lane index in register list");
+ return MatchOperand_ParseFail;
+ }
+ EndLoc = Parser.getTok().getLoc();
// Add all the registers in the range to the register list.
Count += EndReg - Reg;
@@ -2554,6 +2637,15 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
}
++Reg;
Count += 2;
+ // Parse the lane specifier if present.
+ VectorLaneTy NextLaneKind;
+ SMLoc EndLoc = Parser.getTok().getLoc();
+ if (parseVectorLane(NextLaneKind) != MatchOperand_Success)
+ return MatchOperand_ParseFail;
+ if (NextLaneKind != LaneKind) {
+ Error(EndLoc, "mismatched lane index in register list");
+ return MatchOperand_ParseFail;
+ }
continue;
}
// Normal D register. Just check that it's contiguous and keep going.
@@ -2562,6 +2654,15 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
return MatchOperand_ParseFail;
}
++Count;
+ // Parse the lane specifier if present.
+ VectorLaneTy NextLaneKind;
+ SMLoc EndLoc = Parser.getTok().getLoc();
+ if (parseVectorLane(NextLaneKind) != MatchOperand_Success)
+ return MatchOperand_ParseFail;
+ if (NextLaneKind != LaneKind) {
+ Error(EndLoc, "mismatched lane index in register list");
+ return MatchOperand_ParseFail;
+ }
}
SMLoc E = Parser.getTok().getLoc();
@@ -2571,7 +2672,17 @@ parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
}
Parser.Lex(); // Eat '}' token.
- Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
+ switch (LaneKind) {
+ default:
+ assert(0 && "unexpected lane kind in register list.");
+ case NoLanes:
+ Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
+ break;
+ case AllLanes:
+ Operands.push_back(ARMOperand::CreateVectorListAllLanes(FirstReg, Count,
+ S, E));
+ break;
+ }
return MatchOperand_Success;
}
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
index 6c6c02146f..ed2594e2ae 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
@@ -1029,3 +1029,10 @@ void ARMInstPrinter::printVectorListFour(const MCInst *MI, unsigned OpNum,
<< getRegisterName(MI->getOperand(OpNum).getReg() + 2) << ", "
<< getRegisterName(MI->getOperand(OpNum).getReg() + 3) << "}";
}
+
+void ARMInstPrinter::printVectorListOneAllLanes(const MCInst *MI,
+ unsigned OpNum,
+ raw_ostream &O) {
+ O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "[]}";
+}
+
diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
index 3f38f1a0ee..e25fc7c199 100644
--- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
+++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.h
@@ -133,6 +133,8 @@ public:
void printVectorListTwo(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printVectorListThree(const MCInst *MI, unsigned OpNum, raw_ostream &O);
void printVectorListFour(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+ void printVectorListOneAllLanes(const MCInst *MI, unsigned OpNum,
+ raw_ostream &O);
};
} // end namespace llvm