1; RUN: llc < %s -march=avr | FileCheck %s 2 3@count = global i8 0 4 5define avr_intrcc void @interrupt_handler() { 6; CHECK-LABEL: interrupt_handler: 7; CHECK: sei 8; CHECK-NEXT: push r0 9; CHECK-NEXT: push r1 10; CHECK-NEXT: in r0, 63 11; CHECK-NEXT: push r0 12; CHECK-NEXT: clr r1 13; CHECK: pop r0 14; CHECK-NEXT: out 63, r0 15; CHECK-NEXT: pop r1 16; CHECK-NEXT: pop r0 17; CHECK-NEXT: reti 18 ret void 19} 20 21define void @interrupt_handler_via_ir_attribute() #0 { 22; CHECK-LABEL: interrupt_handler_via_ir_attribute: 23; CHECK: sei 24; CHECK-NEXT: push r0 25; CHECK-NEXT: push r1 26; CHECK-NEXT: in r0, 63 27; CHECK-NEXT: push r0 28; CHECK-NEXT: clr r1 29; CHECK: pop r0 30; CHECK-NEXT: out 63, r0 31; CHECK-NEXT: pop r1 32; CHECK-NEXT: pop r0 33; CHECK-NEXT: reti 34 ret void 35} 36 37define avr_signalcc void @signal_handler() { 38; CHECK-LABEL: signal_handler: 39; CHECK-NOT: sei 40; CHECK: push r0 41; CHECK-NEXT: push r1 42; CHECK-NEXT: in r0, 63 43; CHECK-NEXT: push r0 44; CHECK-NEXT: clr r1 45; CHECK: pop r0 46; CHECK-NEXT: out 63, r0 47; CHECK-NEXT: pop r1 48; CHECK-NEXT: pop r0 49; CHECK-NEXT: reti 50 ret void 51} 52 53define void @signal_handler_via_attribute() #1 { 54; CHECK-LABEL: signal_handler_via_attribute: 55; CHECK-NOT: sei 56; CHECK: push r0 57; CHECK-NEXT: push r1 58; CHECK-NEXT: in r0, 63 59; CHECK-NEXT: push r0 60; CHECK-NEXT: clr r1 61; CHECK: pop r0 62; CHECK-NEXT: out 63, r0 63; CHECK-NEXT: pop r1 64; CHECK-NEXT: pop r0 65; CHECK-NEXT: reti 66 ret void 67} 68 69define avr_intrcc void @interrupt_alloca() { 70; CHECK-LABEL: interrupt_alloca: 71; CHECK: sei 72; CHECK-NEXT: push r0 73; CHECK-NEXT: push r1 74; CHECK-NEXT: in r0, 63 75; CHECK-NEXT: push r0 76; CHECK-NEXT: clr r1 77; CHECK: push r28 78; CHECK-NEXT: push r29 79; CHECK-NEXT: in r28, 61 80; CHECK-NEXT: in r29, 62 81; CHECK-NEXT: sbiw r28, 1 82; CHECK-NEXT: in r0, 63 83; CHECK-NEXT: cli 84; CHECK-NEXT: out 62, r29 85; CHECK-NEXT: out 63, r0 86; CHECK-NEXT: out 61, r28 87; CHECK: adiw r28, 1 88; CHECK-NEXT: in r0, 63 89; CHECK-NEXT: cli 90; CHECK-NEXT: out 62, r29 91; CHECK-NEXT: out 63, r0 92; CHECK-NEXT: out 61, r28 93; CHECK-NEXT: pop r29 94; CHECK-NEXT: pop r28 95; CHECK: pop r0 96; CHECK-NEXT: out 63, r0 97; CHECK-NEXT: pop r1 98; CHECK-NEXT: pop r0 99; CHECK-NEXT: reti 100 alloca i8 101 ret void 102} 103 104define void @signal_handler_with_increment() #1 { 105; CHECK-LABEL: signal_handler_with_increment: 106; CHECK: push r0 107; CHECK-NEXT: push r1 108; CHECK-NEXT: in r0, 63 109; CHECK-NEXT: push r0 110; CHECK-NEXT: clr r1 111; CHECK-NEXT: push r24 112; CHECK-NEXT: lds r24, count 113; CHECK-NEXT: inc r24 114; CHECK-NEXT: sts count, r24 115; CHECK-NEXT: pop r24 116; CHECK-NEXT: pop r0 117; CHECK-NEXT: out 63, r0 118; CHECK-NEXT: pop r1 119; CHECK-NEXT: pop r0 120; CHECK-NEXT: reti 121 %old = load volatile i8, i8* @count 122 %new = add i8 %old, 1 123 store volatile i8 %new, i8* @count 124 ret void 125} 126 127declare void @foo() 128 129; When a signal handler calls a function, it must push/pop all call clobbered 130; registers. 131define void @signal_handler_with_call() #1 { 132; CHECK-LABEL: signal_handler_with_call: 133; CHECK: push r0 134; CHECK-NEXT: push r1 135; CHECK-NEXT: in r0, 63 136; CHECK-NEXT: push r0 137; CHECK-NEXT: clr r1 138; CHECK-NEXT: push r18 139; CHECK-NEXT: push r19 140; CHECK-NEXT: push r20 141; CHECK-NEXT: push r21 142; CHECK-NEXT: push r22 143; CHECK-NEXT: push r23 144; CHECK-NEXT: push r24 145; CHECK-NEXT: push r25 146; CHECK-NEXT: push r26 147; CHECK-NEXT: push r27 148; CHECK-NEXT: push r30 149; CHECK-NEXT: push r31 150; CHECK-NEXT: call foo 151; CHECK-NEXT: pop r31 152; CHECK-NEXT: pop r30 153; CHECK-NEXT: pop r27 154; CHECK-NEXT: pop r26 155; CHECK-NEXT: pop r25 156; CHECK-NEXT: pop r24 157; CHECK-NEXT: pop r23 158; CHECK-NEXT: pop r22 159; CHECK-NEXT: pop r21 160; CHECK-NEXT: pop r20 161; CHECK-NEXT: pop r19 162; CHECK-NEXT: pop r18 163; CHECK-NEXT: pop r0 164; CHECK-NEXT: out 63, r0 165; CHECK-NEXT: pop r1 166; CHECK-NEXT: pop r0 167; CHECK-NEXT: reti 168 call void @foo() 169 ret void 170} 171 172attributes #0 = { "interrupt" } 173attributes #1 = { "signal" } 174