summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/MipsAsmPrinter.cpp18
-rw-r--r--llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp16
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp4
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.h7
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp68
-rw-r--r--llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h10
6 files changed, 111 insertions, 12 deletions
diff --git a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
index c6572402e95..1eb3b2c6568 100644
--- a/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/llvm/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -437,7 +437,7 @@ bool MipsAsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock*
// Print out an operand for an inline asm expression.
bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
- unsigned AsmVariant,const char *ExtraCode,
+ unsigned AsmVariant, const char *ExtraCode,
raw_ostream &O) {
// Does this asm operand have a single letter operand modifier?
if (ExtraCode && ExtraCode[0]) {
@@ -539,18 +539,24 @@ bool MipsAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
unsigned OpNum, unsigned AsmVariant,
const char *ExtraCode,
raw_ostream &O) {
- int Offset = 0;
+ assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
+ const MachineOperand &BaseMO = MI->getOperand(OpNum);
+ const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
+ assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
+ assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
+ int Offset = OffsetMO.getImm();
+
// Currently we are expecting either no ExtraCode or 'D'
if (ExtraCode) {
if (ExtraCode[0] == 'D')
- Offset = 4;
+ Offset += 4;
else
return true; // Unknown modifier.
+ // FIXME: M = high order bits
+ // FIXME: L = low order bits
}
- const MachineOperand &MO = MI->getOperand(OpNum);
- assert(MO.isReg() && "unexpected inline asm memory operand");
- O << Offset << "($" << MipsInstPrinter::getRegisterName(MO.getReg()) << ")";
+ O << Offset << "($" << MipsInstPrinter::getRegisterName(BaseMO.getReg()) << ")";
return false;
}
diff --git a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
index 50776f9015b..c78c3296762 100644
--- a/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsISelDAGToDAG.cpp
@@ -232,8 +232,16 @@ SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
bool MipsDAGToDAGISel::
SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
std::vector<SDValue> &OutOps) {
- assert(ConstraintID == InlineAsm::Constraint_m &&
- "unexpected asm memory constraint");
- OutOps.push_back(Op);
- return false;
+ // All memory constraints can at least accept raw pointers.
+ switch(ConstraintID) {
+ default:
+ llvm_unreachable("Unexpected asm memory constraint");
+ case InlineAsm::Constraint_i:
+ case InlineAsm::Constraint_m:
+ case InlineAsm::Constraint_R:
+ case InlineAsm::Constraint_ZC:
+ OutOps.push_back(Op);
+ return false;
+ }
+ return true;
}
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 2eebd76ce24..e4bae03ebd4 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3173,6 +3173,10 @@ getConstraintType(const std::string &Constraint) const
return C_Memory;
}
}
+
+ if (Constraint == "ZC")
+ return C_Memory;
+
return TargetLowering::getConstraintType(Constraint);
}
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 02efba84fcf..40b6661b537 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -507,8 +507,11 @@ namespace llvm {
unsigned getInlineAsmMemConstraint(
const std::string &ConstraintCode) const override {
- // FIXME: Map different constraints differently.
- return InlineAsm::Constraint_m;
+ if (ConstraintCode == "R")
+ return InlineAsm::Constraint_R;
+ else if (ConstraintCode == "ZC")
+ return InlineAsm::Constraint_ZC;
+ return TargetLowering::getInlineAsmMemConstraint(ConstraintCode);
}
bool isLegalAddressingMode(const AddrMode &AM, Type *Ty) const override;
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
index 4da30bece9e..252f9b68c1d 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.cpp
@@ -382,6 +382,17 @@ bool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
selectAddrDefault(Addr, Base, Offset);
}
+bool MipsSEDAGToDAGISel::selectAddrRegImm9(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const {
+ if (selectAddrFrameIndex(Addr, Base, Offset))
+ return true;
+
+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 9))
+ return true;
+
+ return false;
+}
+
bool MipsSEDAGToDAGISel::selectAddrRegImm10(SDValue Addr, SDValue &Base,
SDValue &Offset) const {
if (selectAddrFrameIndex(Addr, Base, Offset))
@@ -405,6 +416,17 @@ bool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base,
return false;
}
+bool MipsSEDAGToDAGISel::selectAddrRegImm16(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const {
+ if (selectAddrFrameIndex(Addr, Base, Offset))
+ return true;
+
+ if (selectAddrFrameIndexOffset(Addr, Base, Offset, 16))
+ return true;
+
+ return false;
+}
+
bool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
SDValue &Offset) const {
return selectAddrRegImm12(Addr, Base, Offset) ||
@@ -916,6 +938,52 @@ std::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) {
return std::make_pair(false, nullptr);
}
+bool MipsSEDAGToDAGISel::
+SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
+ std::vector<SDValue> &OutOps) {
+ SDValue Base, Offset;
+
+ switch(ConstraintID) {
+ default:
+ llvm_unreachable("Unexpected asm memory constraint");
+ // All memory constraints can at least accept raw pointers.
+ case InlineAsm::Constraint_i:
+ case InlineAsm::Constraint_m:
+ case InlineAsm::Constraint_R:
+ OutOps.push_back(Op);
+ OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ return false;
+ case InlineAsm::Constraint_ZC:
+ // ZC matches whatever the pref, ll, and sc instructions can handle for the
+ // given subtarget.
+ if (Subtarget->inMicroMipsMode()) {
+ // On microMIPS, they can handle 12-bit offsets.
+ if (selectAddrRegImm12(Op, Base, Offset)) {
+ OutOps.push_back(Base);
+ OutOps.push_back(Offset);
+ return false;
+ }
+ } else if (Subtarget->hasMips32r6()) {
+ // On MIPS32r6/MIPS64r6, they can only handle 9-bit offsets.
+ if (selectAddrRegImm9(Op, Base, Offset)) {
+ OutOps.push_back(Base);
+ OutOps.push_back(Offset);
+ return false;
+ }
+ } else if (selectAddrRegImm16(Op, Base, Offset)) {
+ // Prior to MIPS32r6/MIPS64r6, they can handle 16-bit offsets.
+ OutOps.push_back(Base);
+ OutOps.push_back(Offset);
+ return false;
+ }
+ // In all cases, 0-bit offsets are acceptable.
+ OutOps.push_back(Op);
+ OutOps.push_back(CurDAG->getTargetConstant(0, MVT::i32));
+ return false;
+ }
+ return true;
+}
+
FunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) {
return new MipsSEDAGToDAGISel(TM);
}
diff --git a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
index 2d24eb43e30..a11fcf4e2e0 100644
--- a/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
+++ b/llvm/lib/Target/Mips/MipsSEISelDAGToDAG.h
@@ -56,12 +56,18 @@ private:
bool selectIntAddr(SDValue Addr, SDValue &Base,
SDValue &Offset) const override;
+ bool selectAddrRegImm9(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const;
+
bool selectAddrRegImm10(SDValue Addr, SDValue &Base,
SDValue &Offset) const;
bool selectAddrRegImm12(SDValue Addr, SDValue &Base,
SDValue &Offset) const;
+ bool selectAddrRegImm16(SDValue Addr, SDValue &Base,
+ SDValue &Offset) const;
+
bool selectIntAddrMM(SDValue Addr, SDValue &Base,
SDValue &Offset) const override;
@@ -111,6 +117,10 @@ private:
// Insert instructions to initialize the global base register in the
// first MBB of the function.
void initGlobalBaseReg(MachineFunction &MF);
+
+ bool SelectInlineAsmMemoryOperand(const SDValue &Op,
+ unsigned ConstraintID,
+ std::vector<SDValue> &OutOps) override;
};
FunctionPass *createMipsSEISelDag(MipsTargetMachine &TM);
OpenPOWER on IntegriCloud