1; RUN: llc < %s -march=avr -mcpu=atmega328p | FileCheck %s 2 3; This test checks a basic 'blinking led' program. 4; It is written for the ATmega328P 5 6; Derived from the following C program (with some cleanups): 7; #include <avr/io.h> 8; 9; void setup_ddr() { 10; DDRB |= _BV(PB5); 11; } 12; 13; void turn_on() { 14; PORTB |= _BV(PB5); 15; } 16; 17; void turn_off() { 18; PORTB &= ~_BV(PB5); 19; } 20; 21; int main() { 22; setup_ddr(); 23; 24; while(1) { 25; turn_on(); 26; turn_off(); 27; } 28; 29; return 0; 30; } 31 32; Sets up the data direction register. 33; CHECK-LABEL: setup_ddr 34define void @setup_ddr() { 35entry: 36 37 ; This should load the value of DDRB, OR it with the bit number and store 38 ; the result back to DDRB. 39 40 ; CHECK: in [[TMPREG:r[0-9]+]], 4 41 ; CHECK-NEXT: ori [[TMPREG]], 32 42 43 ; CHECK-NOT: ori {{r[0-9]+}}, 0 44 45 ; CHECK-NEXT: out 4, [[TMPREG]] 46 ; CHECK-NEXT: ret 47 48 %0 = load volatile i8, i8* inttoptr (i16 36 to i8*), align 1 49 %conv = zext i8 %0 to i16 50 %or = or i16 %conv, 32 51 %conv1 = trunc i16 %or to i8 52 store volatile i8 %conv1, i8* inttoptr (i16 36 to i8*), align 1 53 ret void 54} 55 56; Turns on the LED. 57; CHECK-LABEL: turn_on 58define void @turn_on() { 59entry: 60 61 ; This should load the value of PORTB, OR it with the bit number and store 62 ; the result back to DDRB. 63 64 ; CHECK: in [[TMPREG:r[0-9]+]], 5 65 ; CHECK-NEXT: ori [[TMPREG]], 32 66 67 ; CHECK-NOT: ori {{r[0-9]+}}, 0 68 69 ; CHECK-NEXT: out 5, [[TMPREG]] 70 ; CHECK-NEXT: ret 71 72 %0 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1 73 %conv = zext i8 %0 to i16 74 %or = or i16 %conv, 32 75 %conv1 = trunc i16 %or to i8 76 store volatile i8 %conv1, i8* inttoptr (i16 37 to i8*), align 1 77 ret void 78} 79 80; Turns off the LED. 81; CHECK-LABEL: turn_off 82define void @turn_off() { 83entry: 84 85 ; This should load the value of PORTB, OR it with the bit number and store 86 ; the result back to DDRB. 87 88 89 ; CHECK: in [[TMPREG:r[0-9]+]], 5 90 ; CHECK-NEXT: andi [[TMPREG]], 223 91 ; CHECK-NEXT: andi {{r[0-9]+}}, 0 92 ; CHECK-NEXT: out 5, [[TMPREG]] 93 ; CHECK-NEXT: ret 94 95 %0 = load volatile i8, i8* inttoptr (i16 37 to i8*), align 1 96 %conv = zext i8 %0 to i16 97 %and = and i16 %conv, -33 98 %conv1 = trunc i16 %and to i8 99 store volatile i8 %conv1, i8* inttoptr (i16 37 to i8*), align 1 100 ret void 101} 102 103; CHECK-LABEL: main 104define i16 @main() { 105entry: 106 107 ; CHECK: call setup_ddr 108 call void @setup_ddr() 109 110 br label %while.body 111 112; CHECK-LABEL: LBB3_1 113while.body: 114 115 ; CHECK: call turn_on 116 call void @turn_on() 117 118 ; CHECK-NEXT: call turn_off 119 call void @turn_off() 120 121 ; CHECK-NEXT: rjmp LBB3_1 122 br label %while.body 123} 124