diff options
| author | Simon Dardis <simon.dardis@imgtec.com> | 2017-09-14 17:27:53 +0000 |
|---|---|---|
| committer | Simon Dardis <simon.dardis@imgtec.com> | 2017-09-14 17:27:53 +0000 |
| commit | 55e446737feb6c0b0a15ae95c0b489796658d0db (patch) | |
| tree | 4b57da32d272a29fb15a2c2281e79597d4d8753f /llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | |
| parent | 82959cd5d8051eae241d09b014539db9c20bc240 (diff) | |
| download | bcm5719-llvm-55e446737feb6c0b0a15ae95c0b489796658d0db.tar.gz bcm5719-llvm-55e446737feb6c0b0a15ae95c0b489796658d0db.zip | |
[mips] Implement the 'dext' aliases and it's disassembly alias.
The other members of the dext family of instructions (dextm, dextu) are
traditionally handled by the assembler selecting the right variant of
'dext' depending on the values of the position and size operands.
When these instructions are disassembled, rather than reporting the
actual instruction, an equivalent aliased form of 'dext' is generated
and is reported. This is to mimic the behaviour of binutils.
Reviewers: slthakur, nitesh.jain, atanasyan
Differential Revision: https://reviews.llvm.org/D34887
llvm-svn: 313276
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 73 |
1 files changed, 51 insertions, 22 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 0714f8cb522..9bbb430962e 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -465,6 +465,7 @@ public: Match_NonZeroOperandForSync, Match_RequiresPosSizeRange0_32, Match_RequiresPosSizeRange33_64, + Match_RequiresPosSizeUImm6, #define GET_OPERAND_DIAGNOSTIC_TYPES #include "MipsGenAsmMatcher.inc" #undef GET_OPERAND_DIAGNOSTIC_TYPES @@ -4979,28 +4980,50 @@ unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) { if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()) return Match_RequiresDifferentOperands; return Match_Success; - case Mips::DINS: - case Mips::DINS_MM64R6: { - assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && - "Operands must be immediates for dins!"); - const signed Pos = Inst.getOperand(2).getImm(); - const signed Size = Inst.getOperand(3).getImm(); - if ((0 > (Pos + Size)) || ((Pos + Size) > 32)) - return Match_RequiresPosSizeRange0_32; - return Match_Success; - } - case Mips::DINSM: - case Mips::DINSM_MM64R6: - case Mips::DINSU: - case Mips::DINSU_MM64R6: { - assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && - "Operands must be immediates for dinsm/dinsu!"); - const signed Pos = Inst.getOperand(2).getImm(); - const signed Size = Inst.getOperand(3).getImm(); - if ((32 >= (Pos + Size)) || ((Pos + Size) > 64)) - return Match_RequiresPosSizeRange33_64; - return Match_Success; - } + case Mips::DINS: + case Mips::DINS_MM64R6: { + assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && + "Operands must be immediates for dins!"); + const signed Pos = Inst.getOperand(2).getImm(); + const signed Size = Inst.getOperand(3).getImm(); + if ((0 > (Pos + Size)) || ((Pos + Size) > 32)) + return Match_RequiresPosSizeRange0_32; + return Match_Success; + } + case Mips::DINSM: + case Mips::DINSM_MM64R6: + case Mips::DINSU: + case Mips::DINSU_MM64R6: { + assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && + "Operands must be immediates for dinsm/dinsu!"); + const signed Pos = Inst.getOperand(2).getImm(); + const signed Size = Inst.getOperand(3).getImm(); + if ((32 >= (Pos + Size)) || ((Pos + Size) > 64)) + return Match_RequiresPosSizeRange33_64; + return Match_Success; + } + case Mips::DEXT: + case Mips::DEXT_MM64R6: { + assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && + "Operands must be immediates for DEXTM!"); + const signed Pos = Inst.getOperand(2).getImm(); + const signed Size = Inst.getOperand(3).getImm(); + if ((1 > (Pos + Size)) || ((Pos + Size) > 63)) + return Match_RequiresPosSizeUImm6; + return Match_Success; + } + case Mips::DEXTM: + case Mips::DEXTU: + case Mips::DEXTM_MM64R6: + case Mips::DEXTU_MM64R6: { + assert(Inst.getOperand(2).isImm() && Inst.getOperand(3).isImm() && + "Operands must be immediates for dextm/dextu!"); + const signed Pos = Inst.getOperand(2).getImm(); + const signed Size = Inst.getOperand(3).getImm(); + if ((32 > (Pos + Size)) || ((Pos + Size) > 64)) + return Match_RequiresPosSizeRange33_64; + return Match_Success; + } } uint64_t TSFlags = getInstDesc(Inst.getOpcode()).TSFlags; @@ -5199,6 +5222,12 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, return Error(ErrorStart, "size plus position are not in the range 0 .. 32", SMRange(ErrorStart, ErrorEnd)); } + case Match_RequiresPosSizeUImm6: { + SMLoc ErrorStart = Operands[3]->getStartLoc(); + SMLoc ErrorEnd = Operands[4]->getEndLoc(); + return Error(ErrorStart, "size plus position are not in the range 1 .. 63", + SMRange(ErrorStart, ErrorEnd)); + } case Match_RequiresPosSizeRange33_64: { SMLoc ErrorStart = Operands[3]->getStartLoc(); SMLoc ErrorEnd = Operands[4]->getEndLoc(); |

