]> granicus.if.org Git - llvm/commitdiff
[AVR] Implement stacksave/stackrestore by expanding (PR31342)
authorDylan McKay <dylanmckay34@gmail.com>
Sun, 5 Feb 2017 21:35:45 +0000 (21:35 +0000)
committerDylan McKay <dylanmckay34@gmail.com>
Sun, 5 Feb 2017 21:35:45 +0000 (21:35 +0000)
Summary:
Authored by Florian Zeitz.

This implements the missing stacksave/stackrestore intrinsics via expansion.

Output of `llc -O0 -march=avr ~/devel/llvm/test/CodeGen/Generic/stacksave-restore.ll` for sanity checking (comments mine):

```
.text
.file ".../llvm/test/CodeGen/Generic/stacksave-restore.ll"
.globl test
.p2align 1
.type test,@function
test:                                   ; @test
; BB#0:
push r28
push r29

in r28, 61
in r29, 62
sbiw r28, 4
in r0, 63
cli
out 62, r29
out 63, r0
out 61, r28

in r18, 61
in r19, 62

mov r20, r22
mov r21, r23

in r30, 61
in r31, 62

lsl r22
rol r23
lsl r22
rol r23
in r26, 61
in r27, 62
sub r26, r22
sbc r27, r23
andi r26, 252
in r0, 63
cli
out 62, r27
out 63, r0
out 61, r26

in r0, 63
cli
out 62, r31
out 63, r0
out 61, r30

in r30, 61
in r31, 62
sub r30, r22
sbc r31, r23
andi r30, 252
in r0, 63
cli
out 62, r31
out 63, r0
out 61, r30

std Y+3, r24                ; 2-byte Folded Spill
std Y+4, r25                ; 2-byte Folded Spill

mov r24, r26
mov r25, r27

in r0, 63
cli
out 62, r19
out 63, r0
out 61, r18

std Y+1, r20                ; 2-byte Folded Spill
std Y+2, r21                ; 2-byte Folded Spill

adiw r28, 4
in r0, 63
cli
out 62, r29
out 63, r0
out 61, r28

pop r29
pop r28
ret
.Lfunc_end0:
.size test, .Lfunc_end0-test
```

Reviewers: dylanmckay

Reviewed By: dylanmckay

Subscribers: llvm-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@294146 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/AVR/AVRISelLowering.cpp
test/CodeGen/AVR/intrinsics/stacksave-restore.ll [new file with mode: 0644]

index fa2a391820636141c58edcf11e3328ce475b3d96..0f0d1de89a6533700b4425c60a4cab3c1c1e90fb 100644 (file)
@@ -48,6 +48,8 @@ AVRTargetLowering::AVRTargetLowering(AVRTargetMachine &tm)
   setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
   setOperationAction(ISD::BlockAddress, MVT::i16, Custom);
 
+  setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
+  setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
 
diff --git a/test/CodeGen/AVR/intrinsics/stacksave-restore.ll b/test/CodeGen/AVR/intrinsics/stacksave-restore.ll
new file mode 100644 (file)
index 0000000..3985f49
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: llc -O0 < %s -march=avr | FileCheck %s
+
+; CHECK-LABEL: foo
+define void @foo() {
+entry:
+  br label %save
+
+; CHECK-LABEL: save
+; CHECK: in [[SREG1:r[0-9]+]], 61
+; CHECK-NEXT: in [[SREG2:r[0-9]+]], 62
+save:
+  %saved = call i8* @llvm.stacksave()
+  br label %restore
+
+; CHECK-LABEL: restore
+; CHECK: in r0, 63
+; CHECK-NEXT: cli
+; CHECK-NEXT: out 62, [[SREG2]]
+; CHECK-NEXT: out 63, r0
+; CHECK-NEXT: out 61, [[SREG1]]
+restore:
+  call void @llvm.stackrestore(i8* %saved)
+  ret void
+}
+
+declare i8* @llvm.stacksave()
+declare void @llvm.stackrestore(i8* %ptr)