[llvm] r301794 - [AVR] Implement non-constant bit rotations

Dylan McKay via llvm-commits llvm-commits at lists.llvm.org
Mon May 1 02:48:56 PDT 2017


Author: dylanmckay
Date: Mon May  1 04:48:55 2017
New Revision: 301794

URL: http://llvm.org/viewvc/llvm-project?rev=301794&view=rev
Log:
[AVR] Implement non-constant bit rotations

This lets us do bit rotations of variable amount.

Added:
    llvm/trunk/test/CodeGen/AVR/rot.ll
Modified:
    llvm/trunk/lib/Target/AVR/AVRISelLowering.cpp
    llvm/trunk/lib/Target/AVR/AVRISelLowering.h
    llvm/trunk/lib/Target/AVR/AVRInstrInfo.td

Modified: llvm/trunk/lib/Target/AVR/AVRISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRISelLowering.cpp?rev=301794&r1=301793&r2=301794&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/AVR/AVRISelLowering.cpp Mon May  1 04:48:55 2017
@@ -79,6 +79,11 @@ AVRTargetLowering::AVRTargetLowering(AVR
   setOperationAction(ISD::SRA_PARTS, MVT::i16, Expand);
   setOperationAction(ISD::SRL_PARTS, MVT::i16, Expand);
 
+  setOperationAction(ISD::ROTL, MVT::i8, Custom);
+  setOperationAction(ISD::ROTL, MVT::i16, Custom);
+  setOperationAction(ISD::ROTR, MVT::i8, Custom);
+  setOperationAction(ISD::ROTR, MVT::i16, Custom);
+
   setOperationAction(ISD::BR_CC, MVT::i8, Custom);
   setOperationAction(ISD::BR_CC, MVT::i16, Custom);
   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
@@ -273,6 +278,12 @@ SDValue AVRTargetLowering::LowerShifts(S
     case ISD::SRL:
       return DAG.getNode(AVRISD::LSRLOOP, dl, VT, N->getOperand(0),
                          N->getOperand(1));
+    case ISD::ROTL:
+      return DAG.getNode(AVRISD::ROLLOOP, dl, VT, N->getOperand(0),
+                         N->getOperand(1));
+    case ISD::ROTR:
+      return DAG.getNode(AVRISD::RORLOOP, dl, VT, N->getOperand(0),
+                         N->getOperand(1));
     case ISD::SRA:
       return DAG.getNode(AVRISD::ASRLOOP, dl, VT, N->getOperand(0),
                          N->getOperand(1));
@@ -1440,6 +1451,22 @@ MachineBasicBlock *AVRTargetLowering::in
     Opc = AVR::LSRWRd;
     RC = &AVR::DREGSRegClass;
     break;
+  case AVR::Rol8:
+    Opc = AVR::ROLRd;
+    RC = &AVR::GPR8RegClass;
+    break;
+  case AVR::Rol16:
+    Opc = AVR::ROLWRd;
+    RC = &AVR::DREGSRegClass;
+    break;
+  case AVR::Ror8:
+    Opc = AVR::RORRd;
+    RC = &AVR::GPR8RegClass;
+    break;
+  case AVR::Ror16:
+    Opc = AVR::RORWRd;
+    RC = &AVR::DREGSRegClass;
+    break;
   }
 
   const BasicBlock *LLVM_BB = BB->getBasicBlock();
@@ -1552,6 +1579,10 @@ AVRTargetLowering::EmitInstrWithCustomIn
   case AVR::Lsl16:
   case AVR::Lsr8:
   case AVR::Lsr16:
+  case AVR::Rol8:
+  case AVR::Rol16:
+  case AVR::Ror8:
+  case AVR::Ror16:
   case AVR::Asr8:
   case AVR::Asr16:
     return insertShift(MI, MBB);

Modified: llvm/trunk/lib/Target/AVR/AVRISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRISelLowering.h?rev=301794&r1=301793&r2=301794&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRISelLowering.h (original)
+++ llvm/trunk/lib/Target/AVR/AVRISelLowering.h Mon May  1 04:48:55 2017
@@ -43,6 +43,8 @@ enum NodeType {
   ROL,     ///< Bit rotate left.
   LSLLOOP, ///< A loop of single logical shift left instructions.
   LSRLOOP, ///< A loop of single logical shift right instructions.
+  ROLLOOP, ///< A loop of single left bit rotate instructions.
+  RORLOOP, ///< A loop of single right bit rotate instructions.
   ASRLOOP, ///< A loop of single arithmetic shift right instructions.
   /// AVR conditional branches. Operand 0 is the chain operand, operand 1
   /// is the block to branch if condition is true, operand 2 is the

Modified: llvm/trunk/lib/Target/AVR/AVRInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AVR/AVRInstrInfo.td?rev=301794&r1=301793&r2=301794&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AVR/AVRInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AVR/AVRInstrInfo.td Mon May  1 04:48:55 2017
@@ -64,6 +64,8 @@ def AVRasr : SDNode<"AVRISD::ASR", SDTIn
 // Pseudo shift nodes for non-constant shift amounts.
 def AVRlslLoop : SDNode<"AVRISD::LSLLOOP", SDTIntShiftOp>;
 def AVRlsrLoop : SDNode<"AVRISD::LSRLOOP", SDTIntShiftOp>;
+def AVRrolLoop : SDNode<"AVRISD::ROLLOOP", SDTIntShiftOp>;
+def AVRrorLoop : SDNode<"AVRISD::RORLOOP", SDTIntShiftOp>;
 def AVRasrLoop : SDNode<"AVRISD::ASRLOOP", SDTIntShiftOp>;
 
 //===----------------------------------------------------------------------===//
@@ -1932,7 +1934,6 @@ def Lsr8 : ShiftPseudo<
   [(set i8:$dst, (AVRlsrLoop i8:$src, i8:$cnt))]
 >;
 
-
 def Lsr16 : ShiftPseudo<
   (outs DREGS:$dst),
    (ins DREGS:$src, GPR8:$cnt),
@@ -1940,6 +1941,34 @@ def Lsr16 : ShiftPseudo<
    [(set i16:$dst, (AVRlsrLoop i16:$src, i8:$cnt))]
 >;
 
+def Rol8 : ShiftPseudo<
+  (outs GPR8:$dst),
+  (ins GPR8:$src, GPR8:$cnt),
+  "# Rol8 PSEUDO",
+  [(set i8:$dst, (AVRrolLoop i8:$src, i8:$cnt))]
+>;
+
+def Rol16 : ShiftPseudo<
+  (outs DREGS:$dst),
+  (ins DREGS:$src, GPR8:$cnt),
+  "# Rol16 PSEUDO",
+  [(set i16:$dst, (AVRrolLoop i16:$src, i8:$cnt))]
+>;
+
+def Ror8 : ShiftPseudo<
+  (outs GPR8:$dst),
+  (ins GPR8:$src, GPR8:$cnt),
+  "# Ror8 PSEUDO",
+  [(set i8:$dst, (AVRrorLoop i8:$src, i8:$cnt))]
+>;
+
+def Ror16 : ShiftPseudo<
+  (outs DREGS:$dst),
+  (ins DREGS:$src, GPR8:$cnt),
+  "# Ror16 PSEUDO",
+  [(set i16:$dst, (AVRrorLoop i16:$src, i8:$cnt))]
+>;
+
 def Asr8 : ShiftPseudo<
   (outs GPR8:$dst),
   (ins GPR8:$src, GPR8:$cnt),

Added: llvm/trunk/test/CodeGen/AVR/rot.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/AVR/rot.ll?rev=301794&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/AVR/rot.ll (added)
+++ llvm/trunk/test/CodeGen/AVR/rot.ll Mon May  1 04:48:55 2017
@@ -0,0 +1,55 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; Bit rotation tests.
+
+; CHECK-LABEL: rol8:
+define i8 @rol8(i8 %val, i8 %amt) {
+  ; CHECK:      andi r22, 7
+
+  ; CHECK-NEXT: cp r22, r0
+  ; CHECK-NEXT: breq LBB0_2
+
+; CHECK-NEXT: LBB0_1:
+  ; CHECK-NEXT: rol r24
+  ; CHECK-NEXT: subi r22, 1
+  ; CHECK-NEXT: brne LBB0_1
+
+; CHECK-NEXT:LBB0_2:
+  ; CHECK-NEXT: ret
+  %mod = urem i8 %amt, 8
+
+  %inv = sub i8 8, %mod
+  %parta = shl i8 %val, %mod
+  %partb = lshr i8 %val, %inv
+
+  %rotl = or i8 %parta, %partb
+
+  ret i8 %rotl
+}
+
+
+; CHECK-LABEL: ror8:
+define i8 @ror8(i8 %val, i8 %amt) {
+  ; CHECK:      andi r22, 7
+
+  ; CHECK-NEXT: cp r22, r0
+  ; CHECK-NEXT: breq LBB1_2
+
+; CHECK-NEXT: LBB1_1:
+  ; CHECK-NEXT: ror r24
+  ; CHECK-NEXT: subi r22, 1
+  ; CHECK-NEXT: brne LBB1_1
+
+; CHECK-NEXT:LBB1_2:
+  ; CHECK-NEXT: ret
+  %mod = urem i8 %amt, 8
+
+  %inv = sub i8 8, %mod
+  %parta = lshr i8 %val, %mod
+  %partb = shl i8 %val, %inv
+
+  %rotr = or i8 %parta, %partb
+
+  ret i8 %rotr
+}
+




More information about the llvm-commits mailing list