1
0
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:
Jim Grosbach 2011-10-18 23:02:30 +00:00
parent da2d6a83c8
commit 6a932d6ad1
5 changed files with 102 additions and 3 deletions

View File

@ -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),

View File

@ -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) {

View File

@ -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()) << "}";
}

View File

@ -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

View File

@ -571,6 +571,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
REG("QPR");
REG("QQPR");
REG("QQQQPR");
REG("VecListOneD");
IMM("i32imm");
IMM("i32imm_hilo16");