aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/Mips64InstrInfo.td10
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp11
-rw-r--r--lib/Target/Mips/MipsMCInstLower.cpp35
-rw-r--r--lib/Target/Mips/MipsMCInstLower.h1
-rw-r--r--test/MC/Mips/mips64extins.ll28
5 files changed, 82 insertions, 3 deletions
diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td
index 20fc178..3666725 100644
--- a/lib/Target/Mips/Mips64InstrInfo.td
+++ b/lib/Target/Mips/Mips64InstrInfo.td
@@ -110,9 +110,9 @@ def DSLLV : shift_rotate_reg<0x14, 0x00, "dsllv", shl, CPU64Regs>;
def DSRLV : shift_rotate_reg<0x16, 0x00, "dsrlv", srl, CPU64Regs>;
def DSRAV : shift_rotate_reg<0x17, 0x00, "dsrav", sra, CPU64Regs>;
let Pattern = []<dag> in {
-def DSLL32 : shift_rotate_imm64<0x3c, 0x00, "dsll32", shl>;
-def DSRL32 : shift_rotate_imm64<0x3e, 0x00, "dsrl32", srl>;
-def DSRA32 : shift_rotate_imm64<0x3f, 0x00, "dsra32", sra>;
+ def DSLL32 : shift_rotate_imm64<0x3c, 0x00, "dsll32", shl>;
+ def DSRL32 : shift_rotate_imm64<0x3e, 0x00, "dsrl32", srl>;
+ def DSRA32 : shift_rotate_imm64<0x3f, 0x00, "dsra32", sra>;
}
}
// Rotate Instructions
@@ -217,6 +217,10 @@ let DecoderNamespace = "Mips64" in {
def RDHWR64 : ReadHardware<CPU64Regs, HWRegs64>;
def DEXT : ExtBase<3, "dext", CPU64Regs>;
+let Pattern = []<dag> in {
+ def DEXTU : ExtBase<2, "dextu", CPU64Regs>;
+ def DEXTM : ExtBase<1, "dextm", CPU64Regs>;
+}
def DINS : InsBase<7, "dins", CPU64Regs>;
let isCodeGenOnly = 1, rs = 0, shamt = 0 in {
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index 3b1509d..13bd0cc 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -83,6 +83,17 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
return;
}
}
+ break;
+ // Double extract instruction is chosen by pos and size operands
+ case Mips::DEXT:
+ assert(Subtarget->hasMips64() &&
+ "DEXT is a MIPS64 instruction");
+ {
+ MCInst TmpInst0;
+ MCInstLowering.LowerDEXT(I, TmpInst0);
+ OutStreamer.EmitInstruction(TmpInst0);
+ return;
+ }
}
MCInstLowering.Lower(I++, TmpInst0);
diff --git a/lib/Target/Mips/MipsMCInstLower.cpp b/lib/Target/Mips/MipsMCInstLower.cpp
index d4c5e6d..d65e74d 100644
--- a/lib/Target/Mips/MipsMCInstLower.cpp
+++ b/lib/Target/Mips/MipsMCInstLower.cpp
@@ -189,3 +189,38 @@ void MipsMCInstLower::LowerLargeShift(const MachineInstr *MI,
break;
}
}
+
+// Pick a DEXT instruction variant based on the pos and size operands
+void MipsMCInstLower::LowerDEXT(const MachineInstr *MI, MCInst& Inst) {
+
+ assert(MI->getNumOperands() == 4 && "Invalid no. of machine operands for DEXT!");
+ assert(MI->getOperand(2).isImm());
+ int64_t pos = MI->getOperand(2).getImm();
+ assert(MI->getOperand(3).isImm());
+ int64_t size = MI->getOperand(3).getImm();
+
+ // rt
+ Inst.addOperand(LowerOperand(MI->getOperand(0)));
+ // rs
+ Inst.addOperand(LowerOperand(MI->getOperand(1)));
+
+ // DEXT
+ if ((pos < 32) && (size <= 32)) {
+ Inst.addOperand(MCOperand::CreateImm(pos));
+ Inst.addOperand(MCOperand::CreateImm(size));
+ Inst.setOpcode(Mips::DEXT);
+ }
+ // DEXTU
+ else if ((pos < 64) && (size <= 32)) {
+ Inst.addOperand(MCOperand::CreateImm(pos - 32));
+ Inst.addOperand(MCOperand::CreateImm(size));
+ Inst.setOpcode(Mips::DEXTU);
+ }
+ // DEXTM
+ else {
+ Inst.addOperand(MCOperand::CreateImm(pos));
+ Inst.addOperand(MCOperand::CreateImm(size - 32));
+ Inst.setOpcode(Mips::DEXTM);
+ }
+ return;
+}
diff --git a/lib/Target/Mips/MipsMCInstLower.h b/lib/Target/Mips/MipsMCInstLower.h
index 0abb996..b5d88de 100644
--- a/lib/Target/Mips/MipsMCInstLower.h
+++ b/lib/Target/Mips/MipsMCInstLower.h
@@ -34,6 +34,7 @@ public:
void Initialize(Mangler *mang, MCContext *C);
void Lower(const MachineInstr *MI, MCInst &OutMI) const;
void LowerLargeShift(const MachineInstr *MI, MCInst &Inst, int64_t Shift);
+ void LowerDEXT(const MachineInstr *MI, MCInst &Inst);
private:
MCOperand LowerSymbolOperand(const MachineOperand &MO,
diff --git a/test/MC/Mips/mips64extins.ll b/test/MC/Mips/mips64extins.ll
new file mode 100644
index 0000000..b15409e
--- /dev/null
+++ b/test/MC/Mips/mips64extins.ll
@@ -0,0 +1,28 @@
+; RUN: llc -march=mips64el -filetype=obj -mcpu=mips64r2 -mattr=n64 %s -o - \
+; RUN: | llvm-objdump -disassemble -triple mips64el -mattr +mips64r2 - \
+; RUN: | FileCheck %s
+
+define i64 @dext(i64 %i) nounwind readnone {
+entry:
+; CHECK: dext ${{[0-9]+}}, ${{[0-9]+}}, 5, 10
+ %shr = lshr i64 %i, 5
+ %and = and i64 %shr, 1023
+ ret i64 %and
+}
+
+define i64 @dextu(i64 %i) nounwind readnone {
+entry:
+; CHECK: dextu ${{[0-9]+}}, ${{[0-9]+}}, 2, 6
+ %shr = lshr i64 %i, 34
+ %and = and i64 %shr, 63
+ ret i64 %and
+}
+
+define i64 @dextm(i64 %i) nounwind readnone {
+entry:
+; CHECK: dextm ${{[0-9]+}}, ${{[0-9]+}}, 5, 2
+ %shr = lshr i64 %i, 5
+ %and = and i64 %shr, 17179869183
+ ret i64 %and
+}
+