Mips64 shift instructions.
authorAkira Hatanaka <ahatanaka@mips.com>
Fri, 30 Sep 2011 03:18:46 +0000 (03:18 +0000)
committerAkira Hatanaka <ahatanaka@mips.com>
Fri, 30 Sep 2011 03:18:46 +0000 (03:18 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140841 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/Mips64InstrInfo.td
test/CodeGen/Mips/mips64shift.ll [new file with mode: 0644]

index a42b404d13252ff32f2a6f1159129ed376c8a8e9..d28aff08139dbc8adc10f7bf757cb058e3598ff1 100644 (file)
@@ -23,12 +23,23 @@ def HasMips64r2  : Predicate<"Subtarget.hasMips64r2()">;
 
 // Instruction operand types
 def simm16_64      : Operand<i64>;
+def shamt_64       : Operand<i64>;
 
 // Unsigned Operand
 def uimm16_64      : Operand<i64> {
   let PrintMethod = "printUnsignedImm";
 }
 
+// Transformation Function - get Imm - 32.
+def Subtract32 : SDNodeXForm<imm, [{
+  return getI32Imm((unsigned)N->getZExtValue() - 32);
+}]>;
+
+// imm32_63 predicate - True if imm is in range [32, 63].
+def imm32_63 : ImmLeaf<i64,
+                       [{return (int32_t)Imm >= 32 && (int32_t)Imm < 64;}],
+                       Subtract32>;
+
 //===----------------------------------------------------------------------===//
 // Instructions specific format
 //===----------------------------------------------------------------------===//
@@ -61,6 +72,24 @@ class LogicI64<bits<6> op, string instr_asm, SDNode OpNode>:
      !strconcat(instr_asm, "\t$dst, $b, $c"),
      [(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, immZExt16:$c))], IIAlu>;
 
+// Shifts
+class LogicR_shift_rotate_imm64<bits<6> func, bits<5> _rs, string instr_asm,
+                                SDNode OpNode, PatFrag PF>:
+  FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$b, shamt_64:$c),
+     !strconcat(instr_asm, "\t$dst, $b, $c"),
+     [(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, (i64 PF:$c)))],
+     IIAlu> {
+  let rs = _rs;
+}
+
+class LogicR_shift_rotate_reg64<bits<6> func, bits<5> _shamt, string instr_asm,
+                                SDNode OpNode>:
+  FR<0x00, func, (outs CPU64Regs:$dst), (ins CPU64Regs:$c, CPU64Regs:$b),
+     !strconcat(instr_asm, "\t$dst, $b, $c"),
+     [(set CPU64Regs:$dst, (OpNode CPU64Regs:$b, CPU64Regs:$c))], IIAlu> {
+  let shamt = _shamt;
+}
+
 //===----------------------------------------------------------------------===//
 // Instruction definition
 //===----------------------------------------------------------------------===//
@@ -77,3 +106,14 @@ def DSUBu    : ArithR64<0x00, 0x2f, "dsubu", sub, IIAlu, 1>;
 def DAND     : LogicR64<0x24, "and", and>;
 def DOR      : LogicR64<0x25, "or", or>;
 def DXOR     : LogicR64<0x26, "xor", xor>;
+
+/// Shift Instructions
+def DSLL     : LogicR_shift_rotate_imm64<0x38, 0x00, "dsll", shl, immZExt5>;
+def DSRL     : LogicR_shift_rotate_imm64<0x3a, 0x00, "dsrl", srl, immZExt5>;
+def DSRA     : LogicR_shift_rotate_imm64<0x3b, 0x00, "dsra", sra, immZExt5>;
+def DSLL32   : LogicR_shift_rotate_imm64<0x3c, 0x00, "dsll32", shl, imm32_63>;
+def DSRL32   : LogicR_shift_rotate_imm64<0x3e, 0x00, "dsrl32", srl, imm32_63>;
+def DSRA32   : LogicR_shift_rotate_imm64<0x3f, 0x00, "dsra32", sra, imm32_63>;
+def DSLLV    : LogicR_shift_rotate_reg64<0x24, 0x00, "dsllv", shl>;
+def DSRLV    : LogicR_shift_rotate_reg64<0x26, 0x00, "dsrlv", srl>;
+def DSRAV    : LogicR_shift_rotate_reg64<0x27, 0x00, "dsrav", sra>;
\ No newline at end of file
diff --git a/test/CodeGen/Mips/mips64shift.ll b/test/CodeGen/Mips/mips64shift.ll
new file mode 100644 (file)
index 0000000..31e56c8
--- /dev/null
@@ -0,0 +1,64 @@
+; RUN: llc -march=mips64el -mcpu=mips64r1 < %s | FileCheck %s
+
+define i64 @f0(i64 %a0, i64 %a1) nounwind readnone {
+entry:
+; CHECK: dsllv
+  %shl = shl i64 %a0, %a1
+  ret i64 %shl
+}
+
+define i64 @f1(i64 %a0, i64 %a1) nounwind readnone {
+entry:
+; CHECK: dsrav
+  %shr = ashr i64 %a0, %a1
+  ret i64 %shr
+}
+
+define i64 @f2(i64 %a0, i64 %a1) nounwind readnone {
+entry:
+; CHECK: dsrlv
+  %shr = lshr i64 %a0, %a1
+  ret i64 %shr
+}
+
+define i64 @f3(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsll
+  %shl = shl i64 %a0, 10
+  ret i64 %shl
+}
+
+define i64 @f4(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsra
+  %shr = ashr i64 %a0, 10
+  ret i64 %shr
+}
+
+define i64 @f5(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsrl
+  %shr = lshr i64 %a0, 10
+  ret i64 %shr
+}
+
+define i64 @f6(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsll32
+  %shl = shl i64 %a0, 40
+  ret i64 %shl
+}
+
+define i64 @f7(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsra32
+  %shr = ashr i64 %a0, 40
+  ret i64 %shr
+}
+
+define i64 @f8(i64 %a0) nounwind readnone {
+entry:
+; CHECK: dsrl32
+  %shr = lshr i64 %a0, 40
+  ret i64 %shr
+}