summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2010-12-09 17:32:30 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2010-12-09 17:32:30 +0000
commit908b6ddad6dac40c4c0453d690f0db9422b48b10 (patch)
tree7908da8429c8e1c18f1dd588d1f6667bba51df5a
parent90c595425bdc47563714d6ed13f6e9151552ceae (diff)
Add ROTR and ROTRV mips32 instructions. Patch by Akira Hatanaka
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121377 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/Mips/MipsISelLowering.cpp5
-rw-r--r--lib/Target/Mips/MipsInstrInfo.td36
-rw-r--r--test/CodeGen/Mips/rotate.ll40
3 files changed, 68 insertions, 13 deletions
diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp
index 1f199efaafe..8ba7b632bbe 100644
--- a/lib/Target/Mips/MipsISelLowering.cpp
+++ b/lib/Target/Mips/MipsISelLowering.cpp
@@ -115,7 +115,10 @@ MipsTargetLowering(MipsTargetMachine &TM)
setOperationAction(ISD::CTPOP, MVT::i32, Expand);
setOperationAction(ISD::CTTZ, MVT::i32, Expand);
setOperationAction(ISD::ROTL, MVT::i32, Expand);
- setOperationAction(ISD::ROTR, MVT::i32, Expand);
+
+ if (!Subtarget->isMips32r2())
+ setOperationAction(ISD::ROTR, MVT::i32, Expand);
+
setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td
index 20feff903cb..cc8e4560929 100644
--- a/lib/Target/Mips/MipsInstrInfo.td
+++ b/lib/Target/Mips/MipsInstrInfo.td
@@ -60,6 +60,7 @@ def HasBitCount : Predicate<"Subtarget.hasBitCount()">;
def HasSwap : Predicate<"Subtarget.hasSwap()">;
def HasCondMov : Predicate<"Subtarget.hasCondMov()">;
def IsMips32 : Predicate<"Subtarget.isMips32()">;
+def IsMips32r2 : Predicate<"Subtarget.isMips32r2()">;
//===----------------------------------------------------------------------===//
// Mips Operand, Complex Patterns and Transformations Definitions.
@@ -168,16 +169,21 @@ class LogicNOR<bits<6> op, bits<6> func, string instr_asm>:
[(set CPURegs:$dst, (not (or CPURegs:$b, CPURegs:$c)))], IIAlu>;
// Shifts
-let rt = 0 in
-class LogicR_shift_imm<bits<6> func, string instr_asm, SDNode OpNode>:
+class LogicR_shift_rotate_imm<bits<6> func, bits<5> _rs, string instr_asm,
+ SDNode OpNode>:
FR<0x00, func, (outs CPURegs:$dst), (ins CPURegs:$b, shamt:$c),
!strconcat(instr_asm, "\t$dst, $b, $c"),
- [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu>;
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, immZExt5:$c))], IIAlu> {
+ let rs = _rs;
+}
-class LogicR_shift_reg<bits<6> func, string instr_asm, SDNode OpNode>:
- FR<0x00, func, (outs CPURegs:$dst), (ins CPURegs:$b, CPURegs:$c),
+class LogicR_shift_rotate_reg<bits<6> func, bits<5> _shamt, string instr_asm,
+ SDNode OpNode>:
+ FR<0x00, func, (outs CPURegs:$dst), (ins CPURegs:$c, CPURegs:$b),
!strconcat(instr_asm, "\t$dst, $b, $c"),
- [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>;
+ [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu> {
+ let shamt = _shamt;
+}
// Load Upper Imediate
class LoadUpper<bits<6> op, string instr_asm>:
@@ -376,12 +382,18 @@ def XOR : LogicR<0x26, "xor", xor>;
def NOR : LogicNOR<0x00, 0x27, "nor">;
/// Shift Instructions
-def SLL : LogicR_shift_imm<0x00, "sll", shl>;
-def SRL : LogicR_shift_imm<0x02, "srl", srl>;
-def SRA : LogicR_shift_imm<0x03, "sra", sra>;
-def SLLV : LogicR_shift_reg<0x04, "sllv", shl>;
-def SRLV : LogicR_shift_reg<0x06, "srlv", srl>;
-def SRAV : LogicR_shift_reg<0x07, "srav", sra>;
+def SLL : LogicR_shift_rotate_imm<0x00, 0x00, "sll", shl>;
+def SRL : LogicR_shift_rotate_imm<0x02, 0x00, "srl", srl>;
+def SRA : LogicR_shift_rotate_imm<0x03, 0x00, "sra", sra>;
+def SLLV : LogicR_shift_rotate_reg<0x04, 0x00, "sllv", shl>;
+def SRLV : LogicR_shift_rotate_reg<0x06, 0x00, "srlv", srl>;
+def SRAV : LogicR_shift_rotate_reg<0x07, 0x00, "srav", sra>;
+
+// Rotate Instructions
+let Predicates = [IsMips32r2] in {
+ def ROTR : LogicR_shift_rotate_imm<0x02, 0x01, "rotr", rotr>;
+ def ROTRV : LogicR_shift_rotate_reg<0x06, 0x01, "rotrv", rotr>;
+}
/// Load and Store Instructions
def LB : LoadM<0x20, "lb", sextloadi8>;
diff --git a/test/CodeGen/Mips/rotate.ll b/test/CodeGen/Mips/rotate.ll
new file mode 100644
index 00000000000..e7dc3093214
--- /dev/null
+++ b/test/CodeGen/Mips/rotate.ll
@@ -0,0 +1,40 @@
+; RUN: llc -march=mips -mcpu=4ke < %s | FileCheck %s
+
+; CHECK: rotrv $2, $4, $2
+define i32 @rot0(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %shl = shl i32 %a, %b
+ %sub = sub i32 32, %b
+ %shr = lshr i32 %a, %sub
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+
+; CHECK: rotr $2, $4, 22
+define i32 @rot1(i32 %a) nounwind readnone {
+entry:
+ %shl = shl i32 %a, 10
+ %shr = lshr i32 %a, 22
+ %or = or i32 %shl, %shr
+ ret i32 %or
+}
+
+; CHECK: rotrv $2, $4, $5
+define i32 @rot2(i32 %a, i32 %b) nounwind readnone {
+entry:
+ %shr = lshr i32 %a, %b
+ %sub = sub i32 32, %b
+ %shl = shl i32 %a, %sub
+ %or = or i32 %shl, %shr
+ ret i32 %or
+}
+
+; CHECK: rotr $2, $4, 10
+define i32 @rot3(i32 %a) nounwind readnone {
+entry:
+ %shr = lshr i32 %a, 10
+ %shl = shl i32 %a, 22
+ %or = or i32 %shr, %shl
+ ret i32 %or
+}
+