Initial support for some Thumb2 instructions.
Patch by Viktor Kutuzov and Anton Korzh from Access Softek, Inc.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73622 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/ARM/thumb2-add.ll b/test/CodeGen/ARM/thumb2-add.ll
new file mode 100644
index 0000000..d4f408f
--- /dev/null
+++ b/test/CodeGen/ARM/thumb2-add.ll
@@ -0,0 +1,50 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #255
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #256
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #257
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #4094
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #4095
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep #4096
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep add | grep lsl | grep #8
+
+define i32 @t2ADDrc_255(i32 %lhs) {
+    %Rd = add i32 %lhs, 255;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrc_256(i32 %lhs) {
+    %Rd = add i32 %lhs, 256;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrc_257(i32 %lhs) {
+    %Rd = add i32 %lhs, 257;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrc_4094(i32 %lhs) {
+    %Rd = add i32 %lhs, 4094;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrc_4095(i32 %lhs) {
+    %Rd = add i32 %lhs, 4095;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrc_4096(i32 %lhs) {
+    %Rd = add i32 %lhs, 4096;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrr(i32 %lhs, i32 %rhs) {
+    %Rd = add i32 %lhs, %rhs;
+    ret i32 %Rd
+}
+
+define i32 @t2ADDrs(i32 %lhs, i32 %rhs) {
+    %tmp = shl i32 %rhs, 8
+    %Rd = add i32 %lhs, %tmp;
+    ret i32 %Rd
+}
+
diff --git a/test/CodeGen/ARM/thumb2-mov.ll b/test/CodeGen/ARM/thumb2-mov.ll
new file mode 100644
index 0000000..0c4c596
--- /dev/null
+++ b/test/CodeGen/ARM/thumb2-mov.ll
@@ -0,0 +1,127 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #11206827
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #2868947712
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #2880154539
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #251658240
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #3948544
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov | grep movt
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #258
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep #4026531840
+
+; Test #<const>
+
+; var 2.1 - 0x00ab00ab
+define i32 @t2_const_var2_1_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 11206827 ; 0x00ab00ab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_1_fail_1(i32 %lhs) {
+    %ret = add i32 %lhs, 11206843 ; 0x00ab00bb
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_1_fail_2(i32 %lhs) {
+    %ret = add i32 %lhs, 27984043 ; 0x01ab00ab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_1_fail_3(i32 %lhs) {
+    %ret = add i32 %lhs, 27984299 ; 0x01ab01ab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_1_fail_4(i32 %lhs) {
+    %ret = add i32 %lhs, 28027649 ; 0x01abab01
+    ret i32 %ret
+}
+
+; var 2.2 - 0xab00ab00
+define i32 @t2_const_var2_2_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 2868947712 ; 0xab00ab00
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_2_fail_1(i32 %lhs) {
+    %ret = add i32 %lhs, 2868951552 ; 0xab00ba00
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_2_fail_2(i32 %lhs) {
+    %ret = add i32 %lhs, 2868947728 ; 0xab00ab10
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_2_fail_3(i32 %lhs) {
+    %ret = add i32 %lhs, 2869996304 ; 0xab10ab10
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_2_fail_4(i32 %lhs) {
+    %ret = add i32 %lhs, 279685904 ; 0x10abab10
+    ret i32 %ret
+}
+
+; var 2.3 - 0xabababab
+define i32 @t2_const_var2_3_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 2880154539 ; 0xabababab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_3_fail_1(i32 %lhs) {
+    %ret = add i32 %lhs, 2880154554 ; 0xabababba
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_3_fail_2(i32 %lhs) {
+    %ret = add i32 %lhs, 2880158379 ; 0xababbaab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_3_fail_3(i32 %lhs) {
+    %ret = add i32 %lhs, 2881137579 ; 0xabbaabab
+    ret i32 %ret
+}
+
+define i32 @t2_const_var2_3_fail_4(i32 %lhs) {
+    %ret = add i32 %lhs, 3131812779 ; 0xbaababab
+    ret i32 %ret
+}
+
+; var 3 - 0x0F000000
+define i32 @t2_const_var3_1_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 251658240 ; 0x0F000000
+    ret i32 %ret
+}
+
+define i32 @t2_const_var3_2_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 3948544 ; 0b00000000001111000100000000000000
+    ret i32 %ret
+}
+
+define i32 @t2_const_var3_2_fail_1(i32 %lhs) {
+    %ret = add i32 %lhs, 3940352 ; 0b00000000001111000010000000000000
+    ret i32 %ret
+}
+
+define i32 @t2_const_var3_3_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 258 ; 0b00000000000000000000000100000010
+    ret i32 %ret
+}
+
+define i32 @t2_const_var3_4_ok_1(i32 %lhs) {
+    %ret = add i32 %lhs, 4026531840 ; 0xF0000000
+    ret i32 %ret
+}
+
diff --git a/test/CodeGen/ARM/thumb2-mov2.ll b/test/CodeGen/ARM/thumb2-mov2.ll
new file mode 100644
index 0000000..d2f8c0b
--- /dev/null
+++ b/test/CodeGen/ARM/thumb2-mov2.ll
@@ -0,0 +1,65 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt | grep #1234
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt | grep #1234
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt | grep #1234
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep movt | grep #1234
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov  | grep movt
+
+define i32 @t2MOVTi16_ok_1(i32 %a) {
+    %1 = and i32 %a, 65535
+    %2 = shl i32 1234, 16
+    %3 = or  i32 %1, %2
+
+    ret i32 %3
+}
+
+define i32 @t2MOVTi16_test_1(i32 %a) {
+    %1 = shl i32  255,   8
+    %2 = shl i32 1234,   8
+    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
+    %4 = shl i32   %2,   8  ; This gives us (1234 << 16) in %4
+    %5 = and i32   %a,  %3
+    %6 = or  i32   %4,  %5
+
+    ret i32 %6
+}
+
+define i32 @t2MOVTi16_test_2(i32 %a) {
+    %1 = shl i32  255,   8
+    %2 = shl i32 1234,   8
+    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
+    %4 = shl i32   %2,   6
+    %5 = and i32   %a,  %3
+    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
+    %7 = or  i32   %5,  %6
+
+    ret i32 %7
+}
+
+define i32 @t2MOVTi16_test_3(i32 %a) {
+    %1 = shl i32  255,   8
+    %2 = shl i32 1234,   8
+    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
+    %4 = shl i32   %2,   6
+    %5 = and i32   %a,  %3
+    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
+    %7 = lshr i32  %6,   6
+    %8 = shl i32   %7,   6
+    %9 = or  i32   %5,  %8
+
+    ret i32 %9
+}
+
+define i32 @t2MOVTi16_test_nomatch_1(i32 %a) {
+    %1 = shl i32  255,   8
+    %2 = shl i32 1234,   8
+    %3 = or  i32   %1, 255  ; This give us 0xFFFF in %3
+    %4 = shl i32   %2,   6
+    %5 = and i32   %a,  %3
+    %6 = shl i32   %4,   2  ; This gives us (1234 << 16) in %6
+    %7 = lshr i32  %6,   3
+    %8 = or  i32   %5,  %7
+
+    ret i32 %8
+}
+
+
diff --git a/test/CodeGen/ARM/thumb2-shifter.ll b/test/CodeGen/ARM/thumb2-shifter.ll
new file mode 100644
index 0000000..f9ec506
--- /dev/null
+++ b/test/CodeGen/ARM/thumb2-shifter.ll
@@ -0,0 +1,40 @@
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsl
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep lsr
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep asr
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep ror
+; RUN: llvm-as < %s | llc -march=thumb -mattr=+thumb2 | grep mov
+
+define i32 @t2ADDrs_lsl(i32 %X, i32 %Y) {
+        %A = shl i32 %Y, 16
+        %B = add i32 %X, %A
+        ret i32 %B
+}
+
+define i32 @t2ADDrs_lsr(i32 %X, i32 %Y) {
+        %A = lshr i32 %Y, 16
+        %B = add i32 %X, %A
+        ret i32 %B
+}
+
+define i32 @t2ADDrs_asr(i32 %X, i32 %Y) {
+        %A = ashr i32 %Y, 16
+        %B = add i32 %X, %A
+        ret i32 %B
+}
+
+; i32 ror(n) = (x >> n) | (x << (32 - n))
+define i32 @t2ADDrs_ror(i32 %X, i32 %Y) {
+        %A = lshr i32 %Y, 16
+        %B = shl  i32 %Y, 16
+        %C = or   i32 %B, %A
+        %R = add  i32 %X, %C
+        ret i32 %R
+}
+
+define i32 @t2ADDrs_noRegShift(i32 %X, i32 %Y, i8 %sh) {
+        %shift.upgrd.1 = zext i8 %sh to i32
+        %A = shl i32 %Y, %shift.upgrd.1
+        %B = add i32 %X, %A
+        ret i32 %B
+}
+