From 25a7d94e81317a5f562631906692c4761dcd2395 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Fri, 30 Sep 2011 03:18:46 +0000 Subject: [PATCH] Mips64 shift instructions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140841 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/Mips64InstrInfo.td | 40 +++++++++++++++++++ test/CodeGen/Mips/mips64shift.ll | 64 ++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 test/CodeGen/Mips/mips64shift.ll diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index a42b404d132..d28aff08139 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -23,12 +23,23 @@ def HasMips64r2 : Predicate<"Subtarget.hasMips64r2()">; // Instruction operand types def simm16_64 : Operand; +def shamt_64 : Operand; // Unsigned Operand def uimm16_64 : Operand { let PrintMethod = "printUnsignedImm"; } +// Transformation Function - get Imm - 32. +def Subtract32 : SDNodeXFormgetZExtValue() - 32); +}]>; + +// imm32_63 predicate - True if imm is in range [32, 63]. +def imm32_63 : ImmLeaf= 32 && (int32_t)Imm < 64;}], + Subtract32>; + //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// @@ -61,6 +72,24 @@ class LogicI64 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 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 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 index 00000000000..31e56c82a7c --- /dev/null +++ b/test/CodeGen/Mips/mips64shift.ll @@ -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 +}