summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp51
1 files changed, 48 insertions, 3 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 10222ec445f..d6400e24316 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -126,7 +126,8 @@ const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
- Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
+ Mips::FeatureCnMipsP, Mips::FeatureFP64Bit, Mips::FeatureGP64Bit,
+ Mips::FeatureNaN2008
};
namespace {
@@ -330,6 +331,9 @@ class MipsAsmParser : public MCTargetAsmParser {
bool expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
const MCSubtargetInfo *STI);
+ bool expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI);
+
bool reportParseError(Twine ErrorMsg);
bool reportParseError(SMLoc Loc, Twine ErrorMsg);
@@ -654,6 +658,10 @@ public:
return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
}
+ bool hasCnMipsP() const {
+ return (getSTI().getFeatureBits()[Mips::FeatureCnMipsP]);
+ }
+
bool inPicMode() {
return IsPicEnabled;
}
@@ -2545,6 +2553,9 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
case Mips::MFTHC1: case Mips::MTTHC1:
case Mips::CFTC1: case Mips::CTTC1:
return expandMXTRAlias(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
+ case Mips::SaaAddr:
+ case Mips::SaadAddr:
+ return expandSaaAddr(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
}
}
@@ -3041,7 +3052,7 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
return false;
- } else if (canUseATReg() && !RdRegIsRsReg) {
+ } else if (canUseATReg() && !RdRegIsRsReg && DstReg != getATReg(IDLoc)) {
unsigned ATReg = getATReg(IDLoc);
// If the $rs is different from $rd or if $rs isn't specified and we
@@ -3068,7 +3079,8 @@ bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
return false;
- } else if (!canUseATReg() && !RdRegIsRsReg) {
+ } else if ((!canUseATReg() && !RdRegIsRsReg) ||
+ (canUseATReg() && DstReg == getATReg(IDLoc))) {
// Otherwise, synthesize the address in the destination register
// serially:
// (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
@@ -5412,6 +5424,39 @@ bool MipsAsmParser::expandMXTRAlias(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
return false;
}
+bool MipsAsmParser::expandSaaAddr(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
+ const MCSubtargetInfo *STI) {
+ assert(Inst.getNumOperands() == 3 && "expected three operands");
+ assert(Inst.getOperand(0).isReg() && "expected register operand kind");
+ assert(Inst.getOperand(1).isReg() && "expected register operand kind");
+
+ warnIfNoMacro(IDLoc);
+
+ MipsTargetStreamer &TOut = getTargetStreamer();
+ unsigned Opcode = Inst.getOpcode() == Mips::SaaAddr ? Mips::SAA : Mips::SAAD;
+ unsigned RtReg = Inst.getOperand(0).getReg();
+ unsigned BaseReg = Inst.getOperand(1).getReg();
+ const MCOperand &BaseOp = Inst.getOperand(2);
+
+ if (BaseOp.isImm()) {
+ int64_t ImmValue = BaseOp.getImm();
+ if (ImmValue == 0) {
+ TOut.emitRR(Opcode, RtReg, BaseReg, IDLoc, STI);
+ return false;
+ }
+ }
+
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return true;
+
+ if (expandLoadAddress(ATReg, BaseReg, BaseOp, !isGP64bit(), IDLoc, Out, STI))
+ return true;
+
+ TOut.emitRR(Opcode, RtReg, ATReg, IDLoc, STI);
+ return false;
+}
+
unsigned
MipsAsmParser::checkEarlyTargetMatchPredicate(MCInst &Inst,
const OperandVector &Operands) {
OpenPOWER on IntegriCloud