mirror of
https://github.com/RPCSX/llvm.git
synced 2025-02-10 22:43:46 +00:00
[ARM64] Parse fixed vector lanes properly so that diagnostics can be emitted
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208863 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dbe4f8b96e
commit
e7856db583
@ -690,6 +690,53 @@ def fpimm0 : PatLeaf<(fpimm), [{
|
|||||||
return N->isExactlyValue(+0.0);
|
return N->isExactlyValue(+0.0);
|
||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
|
// Vector lane operands
|
||||||
|
class AsmVectorIndex<string Suffix> : AsmOperandClass {
|
||||||
|
let Name = "VectorIndex" # Suffix;
|
||||||
|
let DiagnosticType = "InvalidIndex" # Suffix;
|
||||||
|
}
|
||||||
|
def VectorIndex1Operand : AsmVectorIndex<"1">;
|
||||||
|
def VectorIndexBOperand : AsmVectorIndex<"B">;
|
||||||
|
def VectorIndexHOperand : AsmVectorIndex<"H">;
|
||||||
|
def VectorIndexSOperand : AsmVectorIndex<"S">;
|
||||||
|
def VectorIndexDOperand : AsmVectorIndex<"D">;
|
||||||
|
|
||||||
|
def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
|
||||||
|
return ((uint64_t)Imm) == 1;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = VectorIndex1Operand;
|
||||||
|
let PrintMethod = "printVectorIndex";
|
||||||
|
let MIOperandInfo = (ops i64imm);
|
||||||
|
}
|
||||||
|
def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
|
||||||
|
return ((uint64_t)Imm) < 16;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = VectorIndexBOperand;
|
||||||
|
let PrintMethod = "printVectorIndex";
|
||||||
|
let MIOperandInfo = (ops i64imm);
|
||||||
|
}
|
||||||
|
def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
|
||||||
|
return ((uint64_t)Imm) < 8;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = VectorIndexHOperand;
|
||||||
|
let PrintMethod = "printVectorIndex";
|
||||||
|
let MIOperandInfo = (ops i64imm);
|
||||||
|
}
|
||||||
|
def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
|
||||||
|
return ((uint64_t)Imm) < 4;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = VectorIndexSOperand;
|
||||||
|
let PrintMethod = "printVectorIndex";
|
||||||
|
let MIOperandInfo = (ops i64imm);
|
||||||
|
}
|
||||||
|
def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
|
||||||
|
return ((uint64_t)Imm) < 2;
|
||||||
|
}]> {
|
||||||
|
let ParserMatchClass = VectorIndexDOperand;
|
||||||
|
let PrintMethod = "printVectorIndex";
|
||||||
|
let MIOperandInfo = (ops i64imm);
|
||||||
|
}
|
||||||
|
|
||||||
// 8-bit immediate for AdvSIMD where 64-bit values of the form:
|
// 8-bit immediate for AdvSIMD where 64-bit values of the form:
|
||||||
// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
|
// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
|
||||||
// are encoded as the eight bit value 'abcdefgh'.
|
// are encoded as the eight bit value 'abcdefgh'.
|
||||||
@ -3409,8 +3456,8 @@ let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
|
|||||||
class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
|
class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
|
||||||
RegisterClass srcType, RegisterOperand dstType, string asm,
|
RegisterClass srcType, RegisterOperand dstType, string asm,
|
||||||
string kind>
|
string kind>
|
||||||
: I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
|
: I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
|
||||||
"{\t$Rd"#kind#"[1], $Rn|"#kind#"\t$Rd[1], $Rn}", "", []>,
|
"{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
|
||||||
Sched<[WriteFCopy]> {
|
Sched<[WriteFCopy]> {
|
||||||
bits<5> Rd;
|
bits<5> Rd;
|
||||||
bits<5> Rn;
|
bits<5> Rn;
|
||||||
@ -3421,14 +3468,16 @@ class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
|
|||||||
let Inst{15-10} = 0b000000;
|
let Inst{15-10} = 0b000000;
|
||||||
let Inst{9-5} = Rn;
|
let Inst{9-5} = Rn;
|
||||||
let Inst{4-0} = Rd;
|
let Inst{4-0} = Rd;
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeFMOVLaneInstruction";
|
||||||
}
|
}
|
||||||
|
|
||||||
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
|
let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
|
||||||
class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
|
class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
|
||||||
RegisterOperand srcType, RegisterClass dstType, string asm,
|
RegisterOperand srcType, RegisterClass dstType, string asm,
|
||||||
string kind>
|
string kind>
|
||||||
: I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
|
: I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
|
||||||
"{\t$Rd, $Rn"#kind#"[1]|"#kind#"\t$Rd, $Rn[1]}", "", []>,
|
"{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
|
||||||
Sched<[WriteFCopy]> {
|
Sched<[WriteFCopy]> {
|
||||||
bits<5> Rd;
|
bits<5> Rd;
|
||||||
bits<5> Rn;
|
bits<5> Rn;
|
||||||
@ -3439,6 +3488,8 @@ class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
|
|||||||
let Inst{15-10} = 0b000000;
|
let Inst{15-10} = 0b000000;
|
||||||
let Inst{9-5} = Rn;
|
let Inst{9-5} = Rn;
|
||||||
let Inst{4-0} = Rd;
|
let Inst{4-0} = Rd;
|
||||||
|
|
||||||
|
let DecoderMethod = "DecodeFMOVLaneInstruction";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3810,44 +3861,6 @@ multiclass FPMoveImmediate<string asm> {
|
|||||||
// AdvSIMD
|
// AdvSIMD
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
class AsmVectorIndex<string Suffix> : AsmOperandClass {
|
|
||||||
let Name = "VectorIndex" # Suffix;
|
|
||||||
let DiagnosticType = "InvalidIndex" # Suffix;
|
|
||||||
}
|
|
||||||
def VectorIndexBOperand : AsmVectorIndex<"B">;
|
|
||||||
def VectorIndexHOperand : AsmVectorIndex<"H">;
|
|
||||||
def VectorIndexSOperand : AsmVectorIndex<"S">;
|
|
||||||
def VectorIndexDOperand : AsmVectorIndex<"D">;
|
|
||||||
|
|
||||||
def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
|
|
||||||
return ((uint64_t)Imm) < 16;
|
|
||||||
}]> {
|
|
||||||
let ParserMatchClass = VectorIndexBOperand;
|
|
||||||
let PrintMethod = "printVectorIndex";
|
|
||||||
let MIOperandInfo = (ops i64imm);
|
|
||||||
}
|
|
||||||
def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
|
|
||||||
return ((uint64_t)Imm) < 8;
|
|
||||||
}]> {
|
|
||||||
let ParserMatchClass = VectorIndexHOperand;
|
|
||||||
let PrintMethod = "printVectorIndex";
|
|
||||||
let MIOperandInfo = (ops i64imm);
|
|
||||||
}
|
|
||||||
def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
|
|
||||||
return ((uint64_t)Imm) < 4;
|
|
||||||
}]> {
|
|
||||||
let ParserMatchClass = VectorIndexSOperand;
|
|
||||||
let PrintMethod = "printVectorIndex";
|
|
||||||
let MIOperandInfo = (ops i64imm);
|
|
||||||
}
|
|
||||||
def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
|
|
||||||
return ((uint64_t)Imm) < 2;
|
|
||||||
}]> {
|
|
||||||
let ParserMatchClass = VectorIndexDOperand;
|
|
||||||
let PrintMethod = "printVectorIndex";
|
|
||||||
let MIOperandInfo = (ops i64imm);
|
|
||||||
}
|
|
||||||
|
|
||||||
def MemorySIMDNoIndexOperand : AsmOperandClass {
|
def MemorySIMDNoIndexOperand : AsmOperandClass {
|
||||||
let Name = "MemorySIMDNoIndex";
|
let Name = "MemorySIMDNoIndex";
|
||||||
let ParserMethod = "tryParseNoIndexMemory";
|
let ParserMethod = "tryParseNoIndexMemory";
|
||||||
|
@ -831,6 +831,9 @@ public:
|
|||||||
return VectorList.NumElements == NumElements;
|
return VectorList.NumElements == NumElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isVectorIndex1() const {
|
||||||
|
return Kind == k_VectorIndex && VectorIndex.Val == 1;
|
||||||
|
}
|
||||||
bool isVectorIndexB() const {
|
bool isVectorIndexB() const {
|
||||||
return Kind == k_VectorIndex && VectorIndex.Val < 16;
|
return Kind == k_VectorIndex && VectorIndex.Val < 16;
|
||||||
}
|
}
|
||||||
@ -1217,6 +1220,11 @@ public:
|
|||||||
MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
|
MCOperand::CreateReg(FirstReg + getVectorListStart() - ARM64::Q0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
|
||||||
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
|
void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
|
||||||
assert(N == 1 && "Invalid number of operands!");
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
|
Inst.addOperand(MCOperand::CreateImm(getVectorIndex()));
|
||||||
@ -3782,6 +3790,8 @@ bool ARM64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) {
|
|||||||
return Error(Loc, "immediate must be an integer in range [1, 32].");
|
return Error(Loc, "immediate must be an integer in range [1, 32].");
|
||||||
case Match_InvalidImm1_64:
|
case Match_InvalidImm1_64:
|
||||||
return Error(Loc, "immediate must be an integer in range [1, 64].");
|
return Error(Loc, "immediate must be an integer in range [1, 64].");
|
||||||
|
case Match_InvalidIndex1:
|
||||||
|
return Error(Loc, "expected lane specifier '[1]'");
|
||||||
case Match_InvalidIndexB:
|
case Match_InvalidIndexB:
|
||||||
return Error(Loc, "vector lane must be an integer in range [0, 15].");
|
return Error(Loc, "vector lane must be an integer in range [0, 15].");
|
||||||
case Match_InvalidIndexH:
|
case Match_InvalidIndexH:
|
||||||
@ -4062,45 +4072,6 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Horrible hack to handle the literal .d[1] vector index on
|
|
||||||
// FMOV instructions. The index isn't an actual instruction operand
|
|
||||||
// but rather syntactic sugar. It really should be part of the mnemonic,
|
|
||||||
// not the operand, but whatever.
|
|
||||||
if ((NumOperands == 5) && Tok == "fmov") {
|
|
||||||
// If the last operand is a vectorindex of '1', then replace it with
|
|
||||||
// a '[' '1' ']' token sequence, which is what the matcher
|
|
||||||
// (annoyingly) expects for a literal vector index operand.
|
|
||||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[NumOperands - 1]);
|
|
||||||
if (Op->isVectorIndexD() && Op->getVectorIndex() == 1) {
|
|
||||||
SMLoc Loc = Op->getStartLoc();
|
|
||||||
Operands.pop_back();
|
|
||||||
delete Op;
|
|
||||||
Operands.push_back(
|
|
||||||
ARM64Operand::CreateToken("[", false, Loc, getContext()));
|
|
||||||
Operands.push_back(
|
|
||||||
ARM64Operand::CreateToken("1", false, Loc, getContext()));
|
|
||||||
Operands.push_back(
|
|
||||||
ARM64Operand::CreateToken("]", false, Loc, getContext()));
|
|
||||||
} else if (Op->isReg()) {
|
|
||||||
// Similarly, check the destination operand for the GPR->High-lane
|
|
||||||
// variant.
|
|
||||||
unsigned OpNo = NumOperands - 2;
|
|
||||||
ARM64Operand *Op = static_cast<ARM64Operand *>(Operands[OpNo]);
|
|
||||||
if (Op->isVectorIndexD() && Op->getVectorIndex() == 1) {
|
|
||||||
SMLoc Loc = Op->getStartLoc();
|
|
||||||
Operands[OpNo] =
|
|
||||||
ARM64Operand::CreateToken("[", false, Loc, getContext());
|
|
||||||
Operands.insert(
|
|
||||||
Operands.begin() + OpNo + 1,
|
|
||||||
ARM64Operand::CreateToken("1", false, Loc, getContext()));
|
|
||||||
Operands.insert(
|
|
||||||
Operands.begin() + OpNo + 2,
|
|
||||||
ARM64Operand::CreateToken("]", false, Loc, getContext()));
|
|
||||||
delete Op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MCInst Inst;
|
MCInst Inst;
|
||||||
// First try to match against the secondary set of tables containing the
|
// First try to match against the secondary set of tables containing the
|
||||||
// short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
|
// short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
|
||||||
@ -4216,6 +4187,7 @@ bool ARM64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||||||
case Match_InvalidImm1_16:
|
case Match_InvalidImm1_16:
|
||||||
case Match_InvalidImm1_32:
|
case Match_InvalidImm1_32:
|
||||||
case Match_InvalidImm1_64:
|
case Match_InvalidImm1_64:
|
||||||
|
case Match_InvalidIndex1:
|
||||||
case Match_InvalidIndexB:
|
case Match_InvalidIndexB:
|
||||||
case Match_InvalidIndexH:
|
case Match_InvalidIndexH:
|
||||||
case Match_InvalidIndexS:
|
case Match_InvalidIndexS:
|
||||||
|
@ -144,6 +144,9 @@ static DecodeStatus DecodeSystemPStateInstruction(llvm::MCInst &Inst,
|
|||||||
static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
|
static DecodeStatus DecodeTestAndBranch(llvm::MCInst &Inst, uint32_t insn,
|
||||||
uint64_t Address, const void *Decoder);
|
uint64_t Address, const void *Decoder);
|
||||||
|
|
||||||
|
static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||||||
|
uint64_t Address,
|
||||||
|
const void *Decoder);
|
||||||
static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
|
static DecodeStatus DecodeVecShiftR64Imm(llvm::MCInst &Inst, unsigned Imm,
|
||||||
uint64_t Addr, const void *Decoder);
|
uint64_t Addr, const void *Decoder);
|
||||||
static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
|
static DecodeStatus DecodeVecShiftR64ImmNarrow(llvm::MCInst &Inst, unsigned Imm,
|
||||||
@ -634,6 +637,29 @@ static DecodeStatus DecodeMSRSystemRegister(llvm::MCInst &Inst, unsigned Imm,
|
|||||||
return ValidNamed ? Success : Fail;
|
return ValidNamed ? Success : Fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DecodeStatus DecodeFMOVLaneInstruction(llvm::MCInst &Inst, unsigned Insn,
|
||||||
|
uint64_t Address,
|
||||||
|
const void *Decoder) {
|
||||||
|
// This decoder exists to add the dummy Lane operand to the MCInst, which must
|
||||||
|
// be 1 in assembly but has no other real manifestation.
|
||||||
|
unsigned Rd = fieldFromInstruction(Insn, 0, 5);
|
||||||
|
unsigned Rn = fieldFromInstruction(Insn, 5, 5);
|
||||||
|
unsigned IsToVec = fieldFromInstruction(Insn, 16, 1);
|
||||||
|
|
||||||
|
if (IsToVec) {
|
||||||
|
DecodeFPR128RegisterClass(Inst, Rd, Address, Decoder);
|
||||||
|
DecodeGPR64RegisterClass(Inst, Rn, Address, Decoder);
|
||||||
|
} else {
|
||||||
|
DecodeGPR64RegisterClass(Inst, Rd, Address, Decoder);
|
||||||
|
DecodeFPR128RegisterClass(Inst, Rn, Address, Decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the lane
|
||||||
|
Inst.addOperand(MCOperand::CreateImm(1));
|
||||||
|
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
|
||||||
static DecodeStatus DecodeVecShiftRImm(llvm::MCInst &Inst, unsigned Imm,
|
static DecodeStatus DecodeVecShiftRImm(llvm::MCInst &Inst, unsigned Imm,
|
||||||
unsigned Add) {
|
unsigned Add) {
|
||||||
Inst.addOperand(MCOperand::CreateImm(Add - Imm));
|
Inst.addOperand(MCOperand::CreateImm(Add - Imm));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user