[AVR] Add calling convention CodeGen tests
authorDylan McKay <dylanmckay34@gmail.com>
Sun, 11 Dec 2016 07:09:45 +0000 (07:09 +0000)
committerDylan McKay <dylanmckay34@gmail.com>
Sun, 11 Dec 2016 07:09:45 +0000 (07:09 +0000)
This adds CodeGen tests for the AVR C calling convention.

llvm-svn: 289369

llvm/test/CodeGen/AVR/calling-conv/c/basic.ll [new file with mode: 0644]
llvm/test/CodeGen/AVR/calling-conv/c/return.ll [new file with mode: 0644]
llvm/test/CodeGen/AVR/calling-conv/c/stack.ll [new file with mode: 0644]

diff --git a/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll b/llvm/test/CodeGen/AVR/calling-conv/c/basic.ll
new file mode 100644 (file)
index 0000000..a5d4676
--- /dev/null
@@ -0,0 +1,99 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; CHECK-LABEL: ret_void_args_i8
+define void @ret_void_args_i8(i8 %a) {
+  ; CHECK: sts 4, r24
+  store volatile i8 %a, i8* inttoptr (i64 4 to i8*)
+  ret void
+}
+
+; CHECK-LABEL: ret_void_args_i8_i32
+define void @ret_void_args_i8_i32(i8 %a, i32 %b) {
+  ; CHECK:      sts     4, r24
+  store volatile i8 %a, i8* inttoptr (i64 4 to i8*)
+
+  ; CHECK-NEXT: sts     8, r23
+  ; CHECK-NEXT: sts     7, r22
+  ; CHECK-NEXT: sts     6, r21
+  ; CHECK-NEXT: sts     5, r20
+  store volatile i32 %b, i32* inttoptr (i64 5 to i32*)
+  ret void
+}
+
+; CHECK-LABEL: ret_void_args_i8_i8_i8_i8
+define void @ret_void_args_i8_i8_i8_i8(i8 %a, i8 %b, i8 %c, i8 %d) {
+  ; CHECK:      sts     4, r24
+  store volatile i8 %a, i8* inttoptr (i64 4 to i8*)
+  ; CHECK-NEXT: sts     5, r22
+  store volatile i8 %b, i8* inttoptr (i64 5 to i8*)
+  ; CHECK-NEXT: sts     6, r20
+  store volatile i8 %c, i8* inttoptr (i64 6 to i8*)
+  ; CHECK-NEXT: sts     7, r18
+  store volatile i8 %d, i8* inttoptr (i64 7 to i8*)
+  ret void
+}
+
+; CHECK-LABEL: ret_void_args_i32_16_i8
+define void @ret_void_args_i32_16_i8(i32 %a, i16 %b, i8 %c) {
+  ; CHECK:      sts     7, r25
+  ; CHECK-NEXT: sts     6, r24
+  ; CHECK-NEXT: sts     5, r23
+  ; CHECK-NEXT: sts     4, r22
+  store volatile i32 %a, i32* inttoptr (i64 4 to i32*)
+
+  ; CHECK-NEXT: sts     5, r21
+  ; CHECK-NEXT: sts     4, r20
+  store volatile i16 %b, i16* inttoptr (i64 4 to i16*)
+
+  ; CHECK-NEXT: sts     4, r18
+  store volatile i8 %c, i8* inttoptr (i64 4 to i8*)
+  ret void
+}
+
+; CHECK-LABEL: ret_void_args_i64
+define void @ret_void_args_i64(i64 %a) {
+  ; CHECK:      sts     11, r25
+  ; CHECK-NEXT: sts     10, r24
+  ; CHECK-NEXT: sts     9, r23
+  ; CHECK-NEXT: sts     8, r22
+  ; CHECK-NEXT: sts     7, r21
+  ; CHECK-NEXT: sts     6, r20
+  ; CHECK-NEXT: sts     5, r19
+  ; CHECK-NEXT: sts     4, r18
+  store volatile i64 %a, i64* inttoptr (i64 4 to i64*)
+  ret void
+}
+
+; CHECK-LABEL: ret_void_args_i64_i64
+define void @ret_void_args_i64_i64(i64 %a, i64 %b) {
+  ; CHECK:      sts     11, r25
+  ; CHECK-NEXT: sts     10, r24
+  ; CHECK-NEXT: sts     9, r23
+  ; CHECK-NEXT: sts     8, r22
+  ; CHECK-NEXT: sts     7, r21
+  ; CHECK-NEXT: sts     6, r20
+  ; CHECK-NEXT: sts     5, r19
+  ; CHECK-NEXT: sts     4, r18
+  store volatile i64 %a, i64* inttoptr (i64 4 to i64*)
+
+  ; CHECK-NEXT: sts     11, r17
+  ; CHECK-NEXT: sts     10, r16
+  ; CHECK-NEXT: sts     9, r15
+  ; CHECK-NEXT: sts     8, r14
+  ; CHECK-NEXT: sts     7, r13
+  ; CHECK-NEXT: sts     6, r12
+  ; CHECK-NEXT: sts     5, r11
+  ; CHECK-NEXT: sts     4, r10
+  store volatile i64 %b, i64* inttoptr (i64 4 to i64*)
+  ret void
+}
+
+; This is exactly enough to hit the limit of what can be passed
+; completely in registers.
+; CHECK-LABEL: ret_void_args_i64_i64_i16
+define void @ret_void_args_i64_i64_i16(i64 %a, i64 %b, i16 %c) {
+  ; CHECK:      sts     5, r9
+  ; CHECK-NEXT: sts     4, r8
+  store volatile i16 %c, i16* inttoptr (i64 4 to i16*)
+  ret void
+}
diff --git a/llvm/test/CodeGen/AVR/calling-conv/c/return.ll b/llvm/test/CodeGen/AVR/calling-conv/c/return.ll
new file mode 100644 (file)
index 0000000..1d240b8
--- /dev/null
@@ -0,0 +1,36 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; CHECK-LABEL: ret_i8
+define i8 @ret_i8() {
+  ; CHECK: ldi r24, 64
+  ret i8 64
+}
+
+; CHECK-LABEL: ret_i16
+define i16 @ret_i16() {
+  ; CHECK:      ldi     r24, 0
+  ; CHECK-NEXT: ldi     r25, 4
+  ret i16 1024
+}
+
+; CHECK-LABEL: ret_i32
+define i32 @ret_i32() {
+  ; CHECK:      ldi     r22, 78
+  ; CHECK-NEXT: ldi     r23, 97
+  ; CHECK-NEXT: ldi     r24, 188
+  ; CHECK-NEXT: ldi     r25, 0
+  ret i32 12345678
+}
+
+; CHECK-LABEL: ret_i64
+define i64 @ret_i64() {
+  ; CHECK:      ldi     r18, 0
+  ; CHECK-NEXT: ldi     r19, 255
+  ; CHECK-NEXT: mov     r20, r18
+  ; CHECK-NEXT: mov     r21, r19
+  ; CHECK-NEXT: mov     r22, r18
+  ; CHECK-NEXT: mov     r23, r19
+  ; CHECK-NEXT: mov     r24, r18
+  ; CHECK-NEXT: mov     r25, r19
+  ret i64 18374966859414961920
+}
diff --git a/llvm/test/CodeGen/AVR/calling-conv/c/stack.ll b/llvm/test/CodeGen/AVR/calling-conv/c/stack.ll
new file mode 100644 (file)
index 0000000..00ff7d1
--- /dev/null
@@ -0,0 +1,32 @@
+; RUN: llc < %s -march=avr | FileCheck %s
+
+; CHECK-LABEL: ret_void_args_i64_i64_i32
+define void @ret_void_args_i64_i64_i32(i64 %a, i64 %b, i32 %c) {
+  ; We're goign to clobber PTRREG Y
+  ; CHECK:      push    r28
+  ; CHECK-NEXT: push    r29
+
+  ; Load the stack pointer into Y.
+  ; CHECK-NEXT: in      r28, 61
+  ; CHECK-NEXT: in      r29, 62
+
+  ; Load the top two bytes from the 32-bit int.
+  ; CHECK-NEXT: ldd     r24, Y+7
+  ; CHECK-NEXT: ldd     r25, Y+8
+  ; Store the top two bytes of the 32-bit int to memory.
+  ; CHECK-NEXT: sts     7, r25
+  ; CHECK-NEXT: sts     6, r24
+
+  ; Load the bottom two bytes from the 32-bit int.
+  ; CHECK-NEXT: ldd     r24, Y+5
+  ; CHECK-NEXT: ldd     r25, Y+6
+  ; Store the bottom two bytes of the 32-bit int to memory.
+  ; CHECK-NEXT: sts     5, r25
+  ; CHECK-NEXT: sts     4, r24
+
+  ; Restore PTRREG Y
+  ; CHECK-NEXT: pop     r29
+  ; CHECK-NEXT: pop     r28
+  store volatile i32 %c, i32* inttoptr (i64 4 to i32*)
+  ret void
+}