1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mattr=avr6,sram -mtriple=avr < %s | FileCheck %s --check-prefix=AVR 3; RUN: llc -mcpu=attiny10 -mtriple=avr < %s | FileCheck %s --check-prefix=TINY 4 5;TODO: test returning byval structs 6; TODO: test naked functions 7 8define void @return_void() { 9; AVR-LABEL: return_void: 10; AVR: ; %bb.0: 11; AVR-NEXT: ret 12; 13; TINY-LABEL: return_void: 14; TINY: ; %bb.0: 15; TINY-NEXT: ret 16 ret void 17} 18 19define i8 @return8_imm() { 20; AVR-LABEL: return8_imm: 21; AVR: ; %bb.0: 22; AVR-NEXT: ldi r24, 5 23; AVR-NEXT: ret 24; 25; TINY-LABEL: return8_imm: 26; TINY: ; %bb.0: 27; TINY-NEXT: ldi r24, 5 28; TINY-NEXT: ret 29 ret i8 5 30} 31 32define i8 @return8_arg(i8 %x) { 33; AVR-LABEL: return8_arg: 34; AVR: ; %bb.0: 35; AVR-NEXT: ret 36; 37; TINY-LABEL: return8_arg: 38; TINY: ; %bb.0: 39; TINY-NEXT: ret 40 ret i8 %x 41} 42 43define i8 @return8_arg2(i8 %x, i8 %y, i8 %z) { 44; AVR-LABEL: return8_arg2: 45; AVR: ; %bb.0: 46; AVR-NEXT: mov r24, r20 47; AVR-NEXT: ret 48; 49; TINY-LABEL: return8_arg2: 50; TINY: ; %bb.0: 51; TINY-NEXT: mov r24, r20 52; TINY-NEXT: ret 53 ret i8 %z 54} 55 56define i16 @return16_imm() { 57; AVR-LABEL: return16_imm: 58; AVR: ; %bb.0: 59; AVR-NEXT: ldi r24, 57 60; AVR-NEXT: ldi r25, 48 61; AVR-NEXT: ret 62; 63; TINY-LABEL: return16_imm: 64; TINY: ; %bb.0: 65; TINY-NEXT: ldi r24, 57 66; TINY-NEXT: ldi r25, 48 67; TINY-NEXT: ret 68 ret i16 12345 69} 70 71define i16 @return16_arg(i16 %x) { 72; AVR-LABEL: return16_arg: 73; AVR: ; %bb.0: 74; AVR-NEXT: ret 75; 76; TINY-LABEL: return16_arg: 77; TINY: ; %bb.0: 78; TINY-NEXT: ret 79 ret i16 %x 80} 81 82define i16 @return16_arg2(i16 %x, i16 %y, i16 %z) { 83; AVR-LABEL: return16_arg2: 84; AVR: ; %bb.0: 85; AVR-NEXT: movw r24, r20 86; AVR-NEXT: ret 87; 88; TINY-LABEL: return16_arg2: 89; TINY: ; %bb.0: 90; TINY-NEXT: mov r24, r20 91; TINY-NEXT: mov r25, r21 92; TINY-NEXT: ret 93 ret i16 %z 94} 95 96define i32 @return32_imm() { 97; AVR-LABEL: return32_imm: 98; AVR: ; %bb.0: 99; AVR-NEXT: ldi r22, 21 100; AVR-NEXT: ldi r23, 205 101; AVR-NEXT: ldi r24, 91 102; AVR-NEXT: ldi r25, 7 103; AVR-NEXT: ret 104; 105; TINY-LABEL: return32_imm: 106; TINY: ; %bb.0: 107; TINY-NEXT: ldi r22, 21 108; TINY-NEXT: ldi r23, 205 109; TINY-NEXT: ldi r24, 91 110; TINY-NEXT: ldi r25, 7 111; TINY-NEXT: ret 112 ret i32 123456789 113} 114 115define i32 @return32_arg(i32 %x) { 116; AVR-LABEL: return32_arg: 117; AVR: ; %bb.0: 118; AVR-NEXT: ret 119; 120; TINY-LABEL: return32_arg: 121; TINY: ; %bb.0: 122; TINY-NEXT: ret 123 ret i32 %x 124} 125 126define i32 @return32_arg2(i32 %x, i32 %y, i32 %z) { 127; AVR-LABEL: return32_arg2: 128; AVR: ; %bb.0: 129; AVR-NEXT: movw r22, r14 130; AVR-NEXT: movw r24, r16 131; AVR-NEXT: ret 132; 133; TINY-LABEL: return32_arg2: 134; TINY: ; %bb.0: 135; TINY-NEXT: push r28 136; TINY-NEXT: push r29 137; TINY-NEXT: in r28, 61 138; TINY-NEXT: in r29, 62 139; TINY-NEXT: in r16, 63 140; TINY-NEXT: subi r28, 247 141; TINY-NEXT: sbci r29, 255 142; TINY-NEXT: ld r22, Y+ 143; TINY-NEXT: ld r23, Y+ 144; TINY-NEXT: subi r28, 2 145; TINY-NEXT: sbci r29, 0 146; TINY-NEXT: subi r28, 9 147; TINY-NEXT: sbci r29, 0 148; TINY-NEXT: out 63, r16 149; TINY-NEXT: in r16, 63 150; TINY-NEXT: subi r28, 245 151; TINY-NEXT: sbci r29, 255 152; TINY-NEXT: ld r24, Y+ 153; TINY-NEXT: ld r25, Y+ 154; TINY-NEXT: subi r28, 2 155; TINY-NEXT: sbci r29, 0 156; TINY-NEXT: subi r28, 11 157; TINY-NEXT: sbci r29, 0 158; TINY-NEXT: out 63, r16 159; TINY-NEXT: pop r29 160; TINY-NEXT: pop r28 161; TINY-NEXT: ret 162 ret i32 %z 163} 164 165define i64 @return64_imm() { 166; AVR-LABEL: return64_imm: 167; AVR: ; %bb.0: 168; AVR-NEXT: ldi r18, 204 169; AVR-NEXT: ldi r19, 204 170; AVR-NEXT: ldi r20, 104 171; AVR-NEXT: ldi r21, 37 172; AVR-NEXT: ldi r22, 25 173; AVR-NEXT: ldi r23, 22 174; AVR-NEXT: ldi r24, 236 175; AVR-NEXT: ldi r25, 190 176; AVR-NEXT: ret 177; 178; TINY-LABEL: return64_imm: 179; TINY: ; %bb.0: 180; TINY-NEXT: ldi r20, 236 181; TINY-NEXT: ldi r21, 190 182; TINY-NEXT: mov r30, r24 183; TINY-NEXT: mov r31, r25 184; TINY-NEXT: subi r30, 250 185; TINY-NEXT: sbci r31, 255 186; TINY-NEXT: st Z+, r20 187; TINY-NEXT: st Z+, r21 188; TINY-NEXT: subi r30, 8 189; TINY-NEXT: sbci r31, 0 190; TINY-NEXT: ldi r24, 25 191; TINY-NEXT: ldi r25, 22 192; TINY-NEXT: subi r30, 252 193; TINY-NEXT: sbci r31, 255 194; TINY-NEXT: st Z+, r24 195; TINY-NEXT: st Z+, r25 196; TINY-NEXT: subi r30, 6 197; TINY-NEXT: sbci r31, 0 198; TINY-NEXT: ldi r24, 104 199; TINY-NEXT: ldi r25, 37 200; TINY-NEXT: subi r30, 254 201; TINY-NEXT: sbci r31, 255 202; TINY-NEXT: st Z+, r24 203; TINY-NEXT: st Z+, r25 204; TINY-NEXT: subi r30, 4 205; TINY-NEXT: sbci r31, 0 206; TINY-NEXT: ldi r24, 204 207; TINY-NEXT: ldi r25, 204 208; TINY-NEXT: st Z+, r24 209; TINY-NEXT: st Z+, r25 210; TINY-NEXT: ret 211 ret i64 13757395258967641292 212} 213 214define i64 @return64_arg(i64 %x) { 215; AVR-LABEL: return64_arg: 216; AVR: ; %bb.0: 217; AVR-NEXT: ret 218; 219; TINY-LABEL: return64_arg: 220; TINY: ; %bb.0: 221; TINY-NEXT: push r28 222; TINY-NEXT: push r29 223; TINY-NEXT: in r28, 61 224; TINY-NEXT: in r29, 62 225; TINY-NEXT: in r16, 63 226; TINY-NEXT: subi r28, 245 227; TINY-NEXT: sbci r29, 255 228; TINY-NEXT: ld r20, Y+ 229; TINY-NEXT: ld r21, Y+ 230; TINY-NEXT: subi r28, 2 231; TINY-NEXT: sbci r29, 0 232; TINY-NEXT: subi r28, 11 233; TINY-NEXT: sbci r29, 0 234; TINY-NEXT: out 63, r16 235; TINY-NEXT: mov r30, r24 236; TINY-NEXT: mov r31, r25 237; TINY-NEXT: subi r30, 250 238; TINY-NEXT: sbci r31, 255 239; TINY-NEXT: st Z+, r20 240; TINY-NEXT: st Z+, r21 241; TINY-NEXT: subi r30, 8 242; TINY-NEXT: sbci r31, 0 243; TINY-NEXT: in r16, 63 244; TINY-NEXT: subi r28, 247 245; TINY-NEXT: sbci r29, 255 246; TINY-NEXT: ld r24, Y+ 247; TINY-NEXT: ld r25, Y+ 248; TINY-NEXT: subi r28, 2 249; TINY-NEXT: sbci r29, 0 250; TINY-NEXT: subi r28, 9 251; TINY-NEXT: sbci r29, 0 252; TINY-NEXT: out 63, r16 253; TINY-NEXT: subi r30, 252 254; TINY-NEXT: sbci r31, 255 255; TINY-NEXT: st Z+, r24 256; TINY-NEXT: st Z+, r25 257; TINY-NEXT: subi r30, 6 258; TINY-NEXT: sbci r31, 0 259; TINY-NEXT: in r16, 63 260; TINY-NEXT: subi r28, 249 261; TINY-NEXT: sbci r29, 255 262; TINY-NEXT: ld r24, Y+ 263; TINY-NEXT: ld r25, Y+ 264; TINY-NEXT: subi r28, 2 265; TINY-NEXT: sbci r29, 0 266; TINY-NEXT: subi r28, 7 267; TINY-NEXT: sbci r29, 0 268; TINY-NEXT: out 63, r16 269; TINY-NEXT: subi r30, 254 270; TINY-NEXT: sbci r31, 255 271; TINY-NEXT: st Z+, r24 272; TINY-NEXT: st Z+, r25 273; TINY-NEXT: subi r30, 4 274; TINY-NEXT: sbci r31, 0 275; TINY-NEXT: in r16, 63 276; TINY-NEXT: subi r28, 251 277; TINY-NEXT: sbci r29, 255 278; TINY-NEXT: ld r24, Y+ 279; TINY-NEXT: ld r25, Y+ 280; TINY-NEXT: subi r28, 2 281; TINY-NEXT: sbci r29, 0 282; TINY-NEXT: subi r28, 5 283; TINY-NEXT: sbci r29, 0 284; TINY-NEXT: out 63, r16 285; TINY-NEXT: st Z+, r24 286; TINY-NEXT: st Z+, r25 287; TINY-NEXT: pop r29 288; TINY-NEXT: pop r28 289; TINY-NEXT: ret 290 ret i64 %x 291} 292 293define i64 @return64_arg2(i64 %x, i64 %y, i64 %z) { 294; AVR-LABEL: return64_arg2: 295; AVR: ; %bb.0: 296; AVR-NEXT: push r28 297; AVR-NEXT: push r29 298; AVR-NEXT: in r28, 61 299; AVR-NEXT: in r29, 62 300; AVR-NEXT: ldd r18, Y+5 301; AVR-NEXT: ldd r19, Y+6 302; AVR-NEXT: ldd r20, Y+7 303; AVR-NEXT: ldd r21, Y+8 304; AVR-NEXT: ldd r22, Y+9 305; AVR-NEXT: ldd r23, Y+10 306; AVR-NEXT: ldd r24, Y+11 307; AVR-NEXT: ldd r25, Y+12 308; AVR-NEXT: pop r29 309; AVR-NEXT: pop r28 310; AVR-NEXT: ret 311; 312; TINY-LABEL: return64_arg2: 313; TINY: ; %bb.0: 314; TINY-NEXT: push r28 315; TINY-NEXT: push r29 316; TINY-NEXT: in r28, 61 317; TINY-NEXT: in r29, 62 318; TINY-NEXT: in r16, 63 319; TINY-NEXT: subi r28, 229 320; TINY-NEXT: sbci r29, 255 321; TINY-NEXT: ld r20, Y+ 322; TINY-NEXT: ld r21, Y+ 323; TINY-NEXT: subi r28, 2 324; TINY-NEXT: sbci r29, 0 325; TINY-NEXT: subi r28, 27 326; TINY-NEXT: sbci r29, 0 327; TINY-NEXT: out 63, r16 328; TINY-NEXT: mov r30, r24 329; TINY-NEXT: mov r31, r25 330; TINY-NEXT: subi r30, 250 331; TINY-NEXT: sbci r31, 255 332; TINY-NEXT: st Z+, r20 333; TINY-NEXT: st Z+, r21 334; TINY-NEXT: subi r30, 8 335; TINY-NEXT: sbci r31, 0 336; TINY-NEXT: in r16, 63 337; TINY-NEXT: subi r28, 231 338; TINY-NEXT: sbci r29, 255 339; TINY-NEXT: ld r24, Y+ 340; TINY-NEXT: ld r25, Y+ 341; TINY-NEXT: subi r28, 2 342; TINY-NEXT: sbci r29, 0 343; TINY-NEXT: subi r28, 25 344; TINY-NEXT: sbci r29, 0 345; TINY-NEXT: out 63, r16 346; TINY-NEXT: subi r30, 252 347; TINY-NEXT: sbci r31, 255 348; TINY-NEXT: st Z+, r24 349; TINY-NEXT: st Z+, r25 350; TINY-NEXT: subi r30, 6 351; TINY-NEXT: sbci r31, 0 352; TINY-NEXT: in r16, 63 353; TINY-NEXT: subi r28, 233 354; TINY-NEXT: sbci r29, 255 355; TINY-NEXT: ld r24, Y+ 356; TINY-NEXT: ld r25, Y+ 357; TINY-NEXT: subi r28, 2 358; TINY-NEXT: sbci r29, 0 359; TINY-NEXT: subi r28, 23 360; TINY-NEXT: sbci r29, 0 361; TINY-NEXT: out 63, r16 362; TINY-NEXT: subi r30, 254 363; TINY-NEXT: sbci r31, 255 364; TINY-NEXT: st Z+, r24 365; TINY-NEXT: st Z+, r25 366; TINY-NEXT: subi r30, 4 367; TINY-NEXT: sbci r31, 0 368; TINY-NEXT: in r16, 63 369; TINY-NEXT: subi r28, 235 370; TINY-NEXT: sbci r29, 255 371; TINY-NEXT: ld r24, Y+ 372; TINY-NEXT: ld r25, Y+ 373; TINY-NEXT: subi r28, 2 374; TINY-NEXT: sbci r29, 0 375; TINY-NEXT: subi r28, 21 376; TINY-NEXT: sbci r29, 0 377; TINY-NEXT: out 63, r16 378; TINY-NEXT: st Z+, r24 379; TINY-NEXT: st Z+, r25 380; TINY-NEXT: pop r29 381; TINY-NEXT: pop r28 382; TINY-NEXT: ret 383 ret i64 %z 384} 385 386define i32 @return64_trunc(i32 %a, i32 %b, i32 %c, i64 %d) { 387; AVR-LABEL: return64_trunc: 388; AVR: ; %bb.0: 389; AVR-NEXT: push r28 390; AVR-NEXT: push r29 391; AVR-NEXT: in r28, 61 392; AVR-NEXT: in r29, 62 393; AVR-NEXT: ldd r22, Y+5 394; AVR-NEXT: ldd r23, Y+6 395; AVR-NEXT: ldd r24, Y+7 396; AVR-NEXT: ldd r25, Y+8 397; AVR-NEXT: pop r29 398; AVR-NEXT: pop r28 399; AVR-NEXT: ret 400; 401; TINY-LABEL: return64_trunc: 402; TINY: ; %bb.0: 403; TINY-NEXT: push r28 404; TINY-NEXT: push r29 405; TINY-NEXT: in r28, 61 406; TINY-NEXT: in r29, 62 407; TINY-NEXT: in r16, 63 408; TINY-NEXT: subi r28, 243 409; TINY-NEXT: sbci r29, 255 410; TINY-NEXT: ld r22, Y+ 411; TINY-NEXT: ld r23, Y+ 412; TINY-NEXT: subi r28, 2 413; TINY-NEXT: sbci r29, 0 414; TINY-NEXT: subi r28, 13 415; TINY-NEXT: sbci r29, 0 416; TINY-NEXT: out 63, r16 417; TINY-NEXT: in r16, 63 418; TINY-NEXT: subi r28, 241 419; TINY-NEXT: sbci r29, 255 420; TINY-NEXT: ld r24, Y+ 421; TINY-NEXT: ld r25, Y+ 422; TINY-NEXT: subi r28, 2 423; TINY-NEXT: sbci r29, 0 424; TINY-NEXT: subi r28, 15 425; TINY-NEXT: sbci r29, 0 426; TINY-NEXT: out 63, r16 427; TINY-NEXT: pop r29 428; TINY-NEXT: pop r28 429; TINY-NEXT: ret 430 %result = trunc i64 %d to i32 431 ret i32 %result 432} 433 434define avr_intrcc void @interrupt_handler() { 435; AVR-LABEL: interrupt_handler: 436; AVR: ; %bb.0: 437; AVR-NEXT: sei 438; AVR-NEXT: push r0 439; AVR-NEXT: in r0, 63 440; AVR-NEXT: push r0 441; AVR-NEXT: pop r0 442; AVR-NEXT: out 63, r0 443; AVR-NEXT: pop r0 444; AVR-NEXT: reti 445; 446; TINY-LABEL: interrupt_handler: 447; TINY: ; %bb.0: 448; TINY-NEXT: sei 449; TINY-NEXT: push r16 450; TINY-NEXT: in r16, 63 451; TINY-NEXT: push r16 452; TINY-NEXT: pop r16 453; TINY-NEXT: out 63, r16 454; TINY-NEXT: pop r16 455; TINY-NEXT: reti 456 ret void 457} 458 459define avr_signalcc void @signal_handler() { 460; AVR-LABEL: signal_handler: 461; AVR: ; %bb.0: 462; AVR-NEXT: push r0 463; AVR-NEXT: in r0, 63 464; AVR-NEXT: push r0 465; AVR-NEXT: pop r0 466; AVR-NEXT: out 63, r0 467; AVR-NEXT: pop r0 468; AVR-NEXT: reti 469; 470; TINY-LABEL: signal_handler: 471; TINY: ; %bb.0: 472; TINY-NEXT: push r16 473; TINY-NEXT: in r16, 63 474; TINY-NEXT: push r16 475; TINY-NEXT: pop r16 476; TINY-NEXT: out 63, r16 477; TINY-NEXT: pop r16 478; TINY-NEXT: reti 479 ret void 480} 481