[AVR] Implement non-constant bit rotations

This lets us do bit rotations of variable amount.

llvm-svn: 301794
diff --git a/llvm/test/CodeGen/AVR/rot.ll b/llvm/test/CodeGen/AVR/rot.ll
new file mode 100644
index 0000000..e43daf3
--- /dev/null
+++ b/llvm/test/CodeGen/AVR/rot.ll
@@ -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
+}
+