mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
ARM VTBL (one register) assembly parsing and encoding.
llvm-svn: 142441
This commit is contained in:
parent
da2d6a83c8
commit
6a932d6ad1
@ -70,6 +70,14 @@ def VectorIndex32 : Operand<i32>, ImmLeaf<i32, [{
|
||||
let MIOperandInfo = (ops i32imm);
|
||||
}
|
||||
|
||||
def VecListOneDAsmOperand : AsmOperandClass {
|
||||
let Name = "VecListOneD";
|
||||
let ParserMethod = "parseVectorList";
|
||||
}
|
||||
def VecListOneD : RegisterOperand<DPR, "printVectorListOne"> {
|
||||
let ParserMatchClass = VecListOneDAsmOperand;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// NEON-specific DAG Nodes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -4869,9 +4877,9 @@ def VZIPq32 : N2VQShuffle<0b10, 0b00011, IIC_VPERMQ3, "vzip", "32">;
|
||||
let DecoderMethod = "DecodeTBLInstruction" in {
|
||||
def VTBL1
|
||||
: N3V<1,1,0b11,0b1000,0,0, (outs DPR:$Vd),
|
||||
(ins DPR:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,
|
||||
"vtbl", "8", "$Vd, \\{$Vn\\}, $Vm", "",
|
||||
[(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 DPR:$Vn, DPR:$Vm)))]>;
|
||||
(ins VecListOneD:$Vn, DPR:$Vm), NVTBLFrm, IIC_VTB1,
|
||||
"vtbl", "8", "$Vd, $Vn, $Vm", "",
|
||||
[(set DPR:$Vd, (v8i8 (int_arm_neon_vtbl1 VecListOneD:$Vn, DPR:$Vm)))]>;
|
||||
let hasExtraSrcRegAllocReq = 1 in {
|
||||
def VTBL2
|
||||
: N3V<1,1,0b11,0b1001,0,0, (outs DPR:$Vd),
|
||||
|
@ -161,6 +161,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
OperandMatchResultTy parsePostIdxReg(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseAM3Offset(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseFPImm(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
OperandMatchResultTy parseVectorList(SmallVectorImpl<MCParsedAsmOperand*>&);
|
||||
|
||||
// Asm Match Converter Methods
|
||||
bool cvtT2LdrdPre(MCInst &Inst, unsigned Opcode,
|
||||
@ -262,6 +263,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||
k_RegisterList,
|
||||
k_DPRRegisterList,
|
||||
k_SPRRegisterList,
|
||||
k_VectorList,
|
||||
k_ShiftedRegister,
|
||||
k_ShiftedImmediate,
|
||||
k_ShifterImmediate,
|
||||
@ -311,6 +313,12 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||
unsigned RegNum;
|
||||
} Reg;
|
||||
|
||||
// A vector register list is a sequential list of 1 to 4 registers.
|
||||
struct {
|
||||
unsigned RegNum;
|
||||
unsigned Count;
|
||||
} VectorList;
|
||||
|
||||
struct {
|
||||
unsigned Val;
|
||||
} VectorIndex;
|
||||
@ -393,6 +401,9 @@ public:
|
||||
case k_SPRRegisterList:
|
||||
Registers = o.Registers;
|
||||
break;
|
||||
case k_VectorList:
|
||||
VectorList = o.VectorList;
|
||||
break;
|
||||
case k_CoprocNum:
|
||||
case k_CoprocReg:
|
||||
Cop = o.Cop;
|
||||
@ -899,6 +910,11 @@ public:
|
||||
bool isProcIFlags() const { return Kind == k_ProcIFlags; }
|
||||
|
||||
// NEON operands.
|
||||
bool isVecListOneD() const {
|
||||
if (Kind != k_VectorList) return false;
|
||||
return VectorList.Count == 1;
|
||||
}
|
||||
|
||||
bool isVectorIndex8() const {
|
||||
if (Kind != k_VectorIndex) return false;
|
||||
return VectorIndex.Val < 8;
|
||||
@ -1486,6 +1502,11 @@ public:
|
||||
Inst.addOperand(MCOperand::CreateImm(unsigned(getProcIFlags())));
|
||||
}
|
||||
|
||||
void addVecListOneDOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateReg(VectorList.RegNum));
|
||||
}
|
||||
|
||||
void addVectorIndex8Operands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
|
||||
@ -1705,6 +1726,16 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static ARMOperand *CreateVectorList(unsigned RegNum, unsigned Count,
|
||||
SMLoc S, SMLoc E) {
|
||||
ARMOperand *Op = new ARMOperand(k_VectorList);
|
||||
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);
|
||||
@ -1896,6 +1927,10 @@ void ARMOperand::print(raw_ostream &OS) const {
|
||||
OS << ">";
|
||||
break;
|
||||
}
|
||||
case k_VectorList:
|
||||
OS << "<vector_list " << VectorList.Count << " * "
|
||||
<< VectorList.RegNum << ">";
|
||||
break;
|
||||
case k_Token:
|
||||
OS << "'" << getToken() << "'";
|
||||
break;
|
||||
@ -2387,6 +2422,55 @@ parseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse a vector register list
|
||||
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
||||
parseVectorList(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
if(Parser.getTok().isNot(AsmToken::LCurly))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
Parser.Lex(); // Eat '{' token.
|
||||
SMLoc RegLoc = Parser.getTok().getLoc();
|
||||
|
||||
int Reg = tryParseRegister();
|
||||
if (Reg == -1) {
|
||||
Error(RegLoc, "register expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
unsigned FirstReg = Reg;
|
||||
unsigned Count = 1;
|
||||
while (Parser.getTok().is(AsmToken::Comma)) {
|
||||
Parser.Lex(); // Eat the comma.
|
||||
RegLoc = Parser.getTok().getLoc();
|
||||
int OldReg = Reg;
|
||||
Reg = tryParseRegister();
|
||||
if (Reg == -1) {
|
||||
Error(RegLoc, "register expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
// vector register lists must also be contiguous.
|
||||
// It's OK to use the enumeration values directly here rather, as the
|
||||
// VFP register classes have the enum sorted properly.
|
||||
if (Reg != OldReg + 1) {
|
||||
Error(RegLoc, "non-contiguous register range");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
++Count;
|
||||
}
|
||||
|
||||
SMLoc E = Parser.getTok().getLoc();
|
||||
if (Parser.getTok().isNot(AsmToken::RCurly)) {
|
||||
Error(E, "'}' expected");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex(); // Eat '}' token.
|
||||
|
||||
Operands.push_back(ARMOperand::CreateVectorList(FirstReg, Count, S, E));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
/// parseMemBarrierOptOperand - Try to parse DSB/DMB data barrier options.
|
||||
ARMAsmParser::OperandMatchResultTy ARMAsmParser::
|
||||
parseMemBarrierOptOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||
|
@ -990,3 +990,8 @@ void ARMInstPrinter::printVectorIndex(const MCInst *MI, unsigned OpNum,
|
||||
raw_ostream &O) {
|
||||
O << "[" << MI->getOperand(OpNum).getImm() << "]";
|
||||
}
|
||||
|
||||
void ARMInstPrinter::printVectorListOne(const MCInst *MI, unsigned OpNum,
|
||||
raw_ostream &O) {
|
||||
O << "{" << getRegisterName(MI->getOperand(OpNum).getReg()) << "}";
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ public:
|
||||
void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printT2LdrLabelOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printVectorIndex(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printVectorListOne(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -571,6 +571,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
||||
REG("QPR");
|
||||
REG("QQPR");
|
||||
REG("QQQQPR");
|
||||
REG("VecListOneD");
|
||||
|
||||
IMM("i32imm");
|
||||
IMM("i32imm_hilo16");
|
||||
|
Loading…
Reference in New Issue
Block a user