[llvm] r178525 - Add 64-bit shift instructions.

Jakob Stoklund Olesen stoklund at 2pi.dk
Mon Apr 1 21:09:13 PDT 2013


Author: stoklund
Date: Mon Apr  1 23:09:12 2013
New Revision: 178525

URL: http://llvm.org/viewvc/llvm-project?rev=178525&view=rev
Log:
Add 64-bit shift instructions.

SPARC v9 defines new 64-bit shift instructions. The 32-bit shift right
instructions are still usable as zero and sign extensions.

This adds new F3_Sr and F3_Si instruction formats that probably should
be used for the 32-bit shifts as well. They don't really encode an
simm13 field.

Added:
    llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
Modified:
    llvm/trunk/lib/Target/Sparc/SparcInstrFormats.td
    llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
    llvm/trunk/test/CodeGen/SPARC/64bit.ll

Added: llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td?rev=178525&view=auto
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td (added)
+++ llvm/trunk/lib/Target/Sparc/SparcInstr64Bit.td Mon Apr  1 23:09:12 2013
@@ -0,0 +1,47 @@
+//===-- SparcInstr64Bit.td - 64-bit instructions for Sparc Target ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains instruction definitions and patterns needed for 64-bit
+// code generation on SPARC v9.
+//
+// Some SPARC v9 instructions are defined in SparcInstrInfo.td because they can
+// also be used in 32-bit code running on a SPARC v9 CPU.
+//
+//===----------------------------------------------------------------------===//
+
+let Predicates = [Is64Bit] in {
+// The same integer registers are used for i32 and i64 values.
+// When registers hold i32 values, the high bits are don't care.
+// This give us free trunc and anyext.
+def : Pat<(i64 (anyext i32:$val)), (COPY $val)>;
+def : Pat<(i32 (trunc i64:$val)), (COPY $val)>;
+
+} // Predicates = [Is64Bit]
+
+
+//===----------------------------------------------------------------------===//
+// 64-bit Shift Instructions.
+//===----------------------------------------------------------------------===//
+//
+// The 32-bit shift instructions are still available. The left shift srl
+// instructions shift all 64 bits, but it only accepts a 5-bit shift amount.
+//
+// The srl instructions only shift the low 32 bits and clear the high 32 bits.
+// Finally, sra shifts the low 32 bits and sign-extends to 64 bits.
+
+let Predicates = [Is64Bit] in {
+
+def : Pat<(i64 (zext i32:$val)), (SRLri $val, 0)>;
+def : Pat<(i64 (sext i32:$val)), (SRAri $val, 0)>;
+
+defm SLLX : F3_S<"sllx", 0b100101, 1, shl, i64, I64Regs>;
+defm SRLX : F3_S<"srlx", 0b100110, 1, srl, i64, I64Regs>;
+defm SRAX : F3_S<"srax", 0b100111, 1, sra, i64, I64Regs>;
+
+} // Predicates = [Is64Bit]

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrFormats.td?rev=178525&r1=178524&r2=178525&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrFormats.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrFormats.td Mon Apr  1 23:09:12 2013
@@ -111,4 +111,41 @@ class F3_3<bits<2> opVal, bits<6> op3val
   let Inst{4-0}  = rs2;
 }
 
+// Shift by register rs2.
+class F3_Sr<bits<2> opVal, bits<6> op3val, bit xVal, dag outs, dag ins,
+            string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
+  bit x = xVal;           // 1 for 64-bit shifts.
+  bits<5> rs2;
 
+  let op         = opVal;
+  let op3        = op3val;
+
+  let Inst{13}   = 0;     // i field = 0
+  let Inst{12}   = x;     // extended registers.
+  let Inst{4-0}  = rs2;
+}
+
+// Shift by immediate.
+class F3_Si<bits<2> opVal, bits<6> op3val, bit xVal, dag outs, dag ins,
+            string asmstr, list<dag> pattern> : F3<outs, ins, asmstr, pattern> {
+  bit x = xVal;           // 1 for 64-bit shifts.
+  bits<6> shcnt;          // shcnt32 / shcnt64.
+
+  let op         = opVal;
+  let op3        = op3val;
+
+  let Inst{13}   = 1;     // i field = 1
+  let Inst{12}   = x;     // extended registers.
+  let Inst{5-0}  = shcnt;
+}
+
+// Define rr and ri shift instructions with patterns.
+multiclass F3_S<string OpcStr, bits<6> Op3Val, bit XVal, SDNode OpNode,
+                ValueType VT, RegisterClass RC> {
+  def rr : F3_Sr<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, RC:$rs2),
+                 !strconcat(OpcStr, " $rs, $rs2, $rd"),
+                 [(set VT:$rd, (OpNode VT:$rs, VT:$rs2))]>;
+  def ri : F3_Si<2, Op3Val, XVal, (outs RC:$rd), (ins RC:$rs, unknown:$shcnt),
+                 !strconcat(OpcStr, " $rs, $shcnt, $rd"),
+                 [(set VT:$rd, (OpNode VT:$rs, (VT imm:$shcnt)))]>;
+}

Modified: llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td?rev=178525&r1=178524&r2=178525&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td (original)
+++ llvm/trunk/lib/Target/Sparc/SparcInstrInfo.td Mon Apr  1 23:09:12 2013
@@ -816,3 +816,5 @@ def : Pat<(i32 (extloadi16 ADDRri:$src))
 // zextload bool -> zextload byte
 def : Pat<(i32 (zextloadi1 ADDRrr:$src)), (LDUBrr ADDRrr:$src)>;
 def : Pat<(i32 (zextloadi1 ADDRri:$src)), (LDUBri ADDRri:$src)>;
+
+include "SparcInstr64Bit.td"

Modified: llvm/trunk/test/CodeGen/SPARC/64bit.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SPARC/64bit.ll?rev=178525&r1=178524&r2=178525&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/SPARC/64bit.ll (original)
+++ llvm/trunk/test/CodeGen/SPARC/64bit.ll Mon Apr  1 23:09:12 2013
@@ -5,3 +5,17 @@
 define i64 @ret2(i64 %a, i64 %b) {
   ret i64 %b
 }
+
+; CHECK: shl_imm
+; CHECK: sllx %i0, 7, %i0
+define i64 @shl_imm(i64 %a) {
+  %x = shl i64 %a, 7
+  ret i64 %x
+}
+
+; CHECK: sra_reg
+; CHECK: srax %i0, %i1, %i0
+define i64 @sra_reg(i64 %a, i64 %b) {
+  %x = ashr i64 %a, %b
+  ret i64 %x
+}





More information about the llvm-commits mailing list