[llvm] r347040 - [MSP430] Add more tests for ABI and calling convention

Anton Korobeynikov via llvm-commits llvm-commits at lists.llvm.org
Fri Nov 16 01:47:59 PST 2018


Author: asl
Date: Fri Nov 16 01:47:58 2018
New Revision: 347040

URL: http://llvm.org/viewvc/llvm-project?rev=347040&view=rev
Log:
[MSP430] Add more tests for ABI and calling convention

Patch by Kristina Bessonova!

Differential Revision: https://reviews.llvm.org/D54582


Added:
    llvm/trunk/test/CodeGen/MSP430/callee-saved.ll
    llvm/trunk/test/CodeGen/MSP430/calls.ll
    llvm/trunk/test/CodeGen/MSP430/interrupt.ll
Modified:
    llvm/trunk/test/CodeGen/MSP430/cc_args.ll
    llvm/trunk/test/CodeGen/MSP430/struct-return.ll

Added: llvm/trunk/test/CodeGen/MSP430/callee-saved.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/callee-saved.ll?rev=347040&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/callee-saved.ll (added)
+++ llvm/trunk/test/CodeGen/MSP430/callee-saved.ll Fri Nov 16 01:47:58 2018
@@ -0,0 +1,38 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
+target triple = "msp430-generic-generic"
+
+; Test the r4-r10 callee-saved registers (MSP430 EABI p. 3.2.2).
+
+ at g = global float 0.0
+
+define void @foo() {
+; CHECK-LABEL: foo:
+; CHECK-NOT: push	r15
+; CHECK-NOT: push	r14
+; CHECK-NOT: push	r13
+; CHECK-NOT: push	r12
+; CHECK-NOT: push	r11
+; CHECK: push	r10
+; CHECK: push	r9
+; CHECK: push	r8
+; CHECK: push	r7
+; CHECK: push	r6
+; CHECK: push	r5
+; CHECK: push	r4
+  %t1 = load volatile float, float* @g
+  %t2 = load volatile float, float* @g
+  %t3 = load volatile float, float* @g
+  %t4 = load volatile float, float* @g
+  %t5 = load volatile float, float* @g
+  %t6 = load volatile float, float* @g
+  %t7 = load volatile float, float* @g
+  store volatile float %t1, float* @g
+  store volatile float %t2, float* @g
+  store volatile float %t3, float* @g
+  store volatile float %t4, float* @g
+  store volatile float %t5, float* @g
+  store volatile float %t6, float* @g
+  ret void
+}

Added: llvm/trunk/test/CodeGen/MSP430/calls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/calls.ll?rev=347040&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/calls.ll (added)
+++ llvm/trunk/test/CodeGen/MSP430/calls.ll Fri Nov 16 01:47:58 2018
@@ -0,0 +1,22 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16-a0:16:16"
+target triple = "msp430---elf"
+
+declare i32 @direct(i32 %a)
+
+define i32 @test_direct(i32 %a) nounwind {
+; CHECK-LABEL: test_direct:
+; CHECK: call #direct
+  %1 = call i32 @direct(i32 %a)
+  ret i32 %1
+}
+
+define i16 @test_indirect(i16 (i16)* %a, i16 %b) nounwind {
+; CHECK-LABEL: test_indirect:
+; CHECK: mov	r12, r14
+; CHECK: mov	r13, r12
+; CHECK: call	r14
+  %1 = call i16 %a(i16 %b)
+  ret i16 %1
+}

Modified: llvm/trunk/test/CodeGen/MSP430/cc_args.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/cc_args.ll?rev=347040&r1=347039&r2=347040&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/cc_args.ll (original)
+++ llvm/trunk/test/CodeGen/MSP430/cc_args.ll Fri Nov 16 01:47:58 2018
@@ -54,6 +54,29 @@ entry:
 ; CHECK: call #f_i16_i64_i16
   call void @f_i16_i64_i16(i16 1, i64 72623859790382856, i16 2)
 
+; Check that r15 is not used and the last i32 argument passed through the stack.
+; CHECK: mov	#258, 10(r1)
+; CHECK: mov	#772, 8(r1)
+; CHECK: mov	#258, 6(r1)
+; CHECK: mov	#772, 4(r1)
+; CHECK: mov	#1286, 2(r1)
+; CHECK: mov	#1800, 0(r1)
+; CHECK: mov	#1, r12
+; CHECK: mov	#772, r13
+; CHECK: mov	#258, r14
+  call void @f_i16_i64_i32_i32(i16 1, i64 72623859790382856, i32 16909060, i32 16909060)
+
+; CHECK: mov	#258, 6(r1)
+; CHECK: mov	#772, 4(r1)
+; CHECK: mov	#1286, 2(r1)
+; CHECK: mov	#1800, 0(r1)
+; CHECK: mov	#1800, r12
+; CHECK: mov	#1286, r13
+; CHECK: mov	#772, r14
+; CHECK: mov	#258, r15
+; CHECK: call	#f_i64_i64
+  call void @f_i64_i64(i64 72623859790382856, i64 72623859790382856)
+
   ret void
 }
 
@@ -136,4 +159,60 @@ define void @f_i16_i64_i16(i16 %a, i64 %
   ret void
 }
 
+define void @f_i64_i64(i64 %a, i64 %b) #0 {
+; CHECK: f_i64_i64:
+; CHECK: mov	r15, &g_i64+6
+; CHECK: mov	r14, &g_i64+4
+; CHECK: mov	r13, &g_i64+2
+; CHECK: mov	r12, &g_i64
+  store volatile i64 %a, i64* @g_i64, align 2
+; CHECK: mov	10(r4), &g_i64+6
+; CHECK: mov	8(r4), &g_i64+4
+; CHECK: mov	6(r4), &g_i64+2
+; CHECK: mov	4(r4), &g_i64
+  store volatile i64 %b, i64* @g_i64, align 2
+  ret void
+}
+
+define void @f_i16_i64_i32_i32(i16 %a, i64 %b, i32 %c, i32 %d) #0 {
+; CHECK-LABEL: f_i16_i64_i32_i32:
+; CHECK: mov	r12, &g_i16
+  store volatile i16 %a, i16* @g_i16, align 2
+; CHECK: mov	10(r4), &g_i64+6
+; CHECK: mov	8(r4), &g_i64+4
+; CHECK: mov	6(r4), &g_i64+2
+; CHECK: mov	4(r4), &g_i64
+  store volatile i64 %b, i64* @g_i64, align 2
+; CHECK: mov	r14, &g_i32+2
+; CHECK: mov	r13, &g_i32
+  store volatile i32 %c, i32* @g_i32, align 2
+; CHECK: mov	14(r4), &g_i32+2
+; CHECK: mov	12(r4), &g_i32
+  store volatile i32 %d, i32* @g_i32, align 2
+  ret void
+}
+; MSP430 EABI p. 6.3
+; For helper functions which take two long long arguments
+; the first argument is passed in R8::R11 and the second argument
+; is in R12::R15.
+
+ at g_i64_2 = common global i64 0, align 2
+
+define i64 @helper_call_i64() #0 {
+  %1 = load i64, i64* @g_i64, align 2
+  %2 = load i64, i64* @g_i64_2, align 2
+; CHECK-LABEL: helper_call_i64:
+; CHECK: mov	&g_i64, r8
+; CHECK: mov	&g_i64+2, r9
+; CHECK: mov	&g_i64+4, r10
+; CHECK: mov	&g_i64+6, r11
+; CHECK: mov	&g_i64_2, r12
+; CHECK: mov	&g_i64_2+2, r13
+; CHECK: mov	&g_i64_2+4, r14
+; CHECK: mov	&g_i64_2+6, r15
+; CHECK: call	#__mspabi_divlli
+  %3 = sdiv i64 %1, %2
+  ret i64 %3
+}
+
 attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" }

Added: llvm/trunk/test/CodeGen/MSP430/interrupt.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/interrupt.ll?rev=347040&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/interrupt.ll (added)
+++ llvm/trunk/test/CodeGen/MSP430/interrupt.ll Fri Nov 16 01:47:58 2018
@@ -0,0 +1,49 @@
+; RUN: llc < %s | FileCheck %s
+
+target datalayout = "e-m:e-p:16:16-i32:16-i64:16-f32:16-f64:16-a:8-n8:16-S16"
+target triple = "msp430-generic-generic"
+
+ at llvm.used = appending global [1 x i8*] [i8* bitcast (void ()* @ISR to i8*)], section "llvm.metadata"
+
+; MSP430 EABI p. 3.9
+; Interrupt functions must save all the registers that are used, even those
+; that are normally considered callee-saved.
+
+; To return from an interrupt function, the function must execute the special
+; instruction RETI, which restores the SR register and branches to the PC where
+; the interrupt occurred.
+
+ at g = global float 0.0
+
+define msp430_intrcc void @ISR() #0 {
+entry:
+; CHECK-LABEL: ISR:
+; CHECK: push	r15
+; CHECK: push	r14
+; CHECK: push	r13
+; CHECK: push	r12
+; CHECK: push	r11
+; CHECK: push	r10
+; CHECK: push	r9
+; CHECK: push	r8
+; CHECK: push	r7
+; CHECK: push	r6
+; CHECK: push	r5
+; CHECK: push	r4
+  %t1 = load volatile float, float* @g
+  %t2 = load volatile float, float* @g
+  %t3 = load volatile float, float* @g
+  %t4 = load volatile float, float* @g
+  %t5 = load volatile float, float* @g
+  %t6 = load volatile float, float* @g
+  %t7 = load volatile float, float* @g
+  store volatile float %t1, float* @g
+  store volatile float %t2, float* @g
+  store volatile float %t3, float* @g
+  store volatile float %t4, float* @g
+  store volatile float %t5, float* @g
+  store volatile float %t6, float* @g
+; CHECK: reti
+  ret void
+}
+

Modified: llvm/trunk/test/CodeGen/MSP430/struct-return.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MSP430/struct-return.ll?rev=347040&r1=347039&r2=347040&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/MSP430/struct-return.ll (original)
+++ llvm/trunk/test/CodeGen/MSP430/struct-return.ll Fri Nov 16 01:47:58 2018
@@ -3,7 +3,7 @@
 target datalayout = "e-p:16:16:16-i8:8:8-i16:16:16-i32:16:32-n8:16"
 target triple = "msp430---elf"
 
-; Allow simple structures to be returned by value.
+; Pass large structures by reference (MSP430 EABI p. 3.5)
 
 %s = type { i64, i64 }
 
@@ -17,7 +17,39 @@ define %s @fred() #0 {
 ; CHECK: mov	#772, 4(r12)
 ; CHECK: mov	#1286, 2(r12)
 ; CHECK: mov	#1800, 0(r12)
-  ret %s {i64 72623859790382856, i64 651345242494996224} 
+  ret %s {i64 72623859790382856, i64 651345242494996224}
+}
+
+%struct.S = type { i16, i16, i16 }
+
+ at a = common global i16 0, align 2
+ at b = common global i16 0, align 2
+ at c = common global i16 0, align 2
+
+define void @test() #1 {
+; CHECK-LABEL: test:
+  %1 = alloca %struct.S, align 2
+; CHECK:      mov	r1, r12
+; CHECK-NEXT: call	#sret
+  call void @sret(%struct.S* nonnull sret %1) #3
+  ret void
+}
+
+define void @sret(%struct.S* noalias nocapture sret) #0 {
+; CHECK-LABEL: sret:
+; CHECK: mov	&a, 0(r12)
+; CHECK: mov	&b, 2(r12)
+; CHECK: mov	&c, 4(r12)
+  %2 = getelementptr inbounds %struct.S, %struct.S* %0, i16 0, i32 0
+  %3 = load i16, i16* @a, align 2
+  store i16 %3, i16* %2, align 2
+  %4 = getelementptr inbounds %struct.S, %struct.S* %0, i16 0, i32 1
+  %5 = load i16, i16* @b, align 2
+  store i16 %5, i16* %4, align 2
+  %6 = getelementptr inbounds %struct.S, %struct.S* %0, i16 0, i32 2
+  %7 = load i16, i16* @c, align 2
+  store i16 %7, i16* %6, align 2
+  ret void
 }
 
 attributes #0 = { nounwind }




More information about the llvm-commits mailing list