1071 lines · plain
1; RUN: llc -mtriple=mips-linux -relocation-model=static < %s \2; RUN: | FileCheck --check-prefixes=ALL,O32 %s3; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s \4; RUN: | FileCheck --check-prefixes=ALL,O32 %s5 6; RUN-TODO: llc -mtriple=mips64 -relocation-model=static -target-abi o32 < %s \7; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s8; RUN-TODO: llc -mtriple=mips64el -relocation-model=static -target-abi o32 < %s \9; RUN-TODO: | FileCheck --check-prefixes=ALL,O32 %s10 11; RUN: llc -mtriple=mips64-linux -relocation-model=static -target-abi n32 < %s \12; RUN: | FileCheck --check-prefixes=ALL,NEW,N32,NEW-BE %s13; RUN: llc -mtriple=mips64el-linux -relocation-model=static -target-abi n32 < %s \14; RUN: | FileCheck --check-prefixes=ALL,NEW,N32,NEW-LE %s15 16; RUN: llc -mtriple=mips64 -relocation-model=static -target-abi n64 < %s \17; RUN: | FileCheck --check-prefixes=ALL,NEW,N64,NEW-BE %s18; RUN: llc -mtriple=mips64el -relocation-model=static -target-abi n64 < %s \19; RUN: | FileCheck --check-prefixes=ALL,NEW,N64,NEW-LE %s20 21@hwords = global [3 x i16] zeroinitializer, align 122@words = global [3 x i32] zeroinitializer, align 123@dwords = global [3 x i64] zeroinitializer, align 124 25define void @fn_i16_dotdotdot_i16(i16 %a, ...) {26entry:27; ALL-LABEL: fn_i16_dotdotdot_i16:28 29; Set up the stack with an 8-byte local area. N32/N64 must also make room for30; the argument save area (56 bytes).31; O32: addiu [[SP:\$sp]], $sp, -832; N32: addiu [[SP:\$sp]], $sp, -6433; N64: daddiu [[SP:\$sp]], $sp, -6434 35; Save variable argument portion on the stack36; O32-DAG: sw $7, 20([[SP]])37; O32-DAG: sw $6, 16([[SP]])38; O32-DAG: sw $5, 12([[SP]])39 40; NEW-DAG: sd $11, 56([[SP]])41; NEW-DAG: sd $10, 48([[SP]])42; NEW-DAG: sd $9, 40([[SP]])43; NEW-DAG: sd $8, 32([[SP]])44; NEW-DAG: sd $7, 24([[SP]])45; NEW-DAG: sd $6, 16([[SP]])46; NEW-DAG: sd $5, 8([[SP]])47 48; Initialize variable argument pointer.49; For O32, the offset is 12 due to the 4 bytes used to store local variables,50; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first51; fixed argument.52; For N32/N64, it is only 8 since the fixed arguments do not reserve stack53; space.54; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 1255; O32-DAG: sw [[VA]], 0([[SP]])56 57; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 858; N32-DAG: sw [[VA]], 0([[SP]])59 60; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 861; N64-DAG: sd [[VA]], 0([[SP]])62 63; ALL: teqi $zero, 164 65; Increment [[VA]]66; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])67; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 468; O32-DAG: sw [[VA2]], 0([[SP]])69 70; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])71; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 872; N32-DAG: sw [[VA2]], 0([[SP]])73 74; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])75; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 876; N64-DAG: sd [[VA2]], 0([[SP]])77 78; Load the first argument from the variable portion.79; This has used the stack pointer directly rather than the [[VA]] we just set80; up.81; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte82; order.83; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])84 85; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])86; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])87 88; Copy the arg to the global89; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)90 91; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)92 93; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)94 95; ALL-DAG: sh [[ARG1]], 2([[GV]])96 97; ALL: teqi $zero, 298 99; Increment [[VA]] again.100; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])101; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4102; O32-DAG: sw [[VA2]], 0([[SP]])103 104; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])105; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8106; N32-DAG: sw [[VA3]], 0([[SP]])107 108; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])109; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8110; N64-DAG: sd [[VA3]], 0([[SP]])111 112; Load the second argument from the variable portion.113; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])114 115; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])116; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])117 118; Copy the arg to the global119; ALL-DAG: sh [[ARG2]], 4([[GV]])120 121 %ap = alloca ptr, align 8122 call void @llvm.va_start(ptr %ap)123 124 call void asm sideeffect "teqi $$zero, 1", ""()125 %arg1 = va_arg ptr %ap, i16126 %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1127 store volatile i16 %arg1, ptr %e1, align 2128 129 call void asm sideeffect "teqi $$zero, 2", ""()130 %arg2 = va_arg ptr %ap, i16131 %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2132 store volatile i16 %arg2, ptr %e2, align 2133 134 call void @llvm.va_end(ptr %ap)135 136 ret void137}138 139define void @fn_i16_dotdotdot_i32(i16 %a, ...) {140entry:141; ALL-LABEL: fn_i16_dotdotdot_i32:142 143; Set up the stack with an 8-byte local area. N32/N64 must also make room for144; the argument save area (56 bytes).145; O32: addiu [[SP:\$sp]], $sp, -8146; N32: addiu [[SP:\$sp]], $sp, -64147; N64: daddiu [[SP:\$sp]], $sp, -64148 149; Save variable argument portion on the stack150; O32-DAG: sw $7, 20([[SP]])151; O32-DAG: sw $6, 16([[SP]])152; O32-DAG: sw $5, 12([[SP]])153 154; NEW-DAG: sd $11, 56([[SP]])155; NEW-DAG: sd $10, 48([[SP]])156; NEW-DAG: sd $9, 40([[SP]])157; NEW-DAG: sd $8, 32([[SP]])158; NEW-DAG: sd $7, 24([[SP]])159; NEW-DAG: sd $6, 16([[SP]])160; NEW-DAG: sd $5, 8([[SP]])161 162; Initialize variable argument pointer.163; For O32, the offset is 12 due to the 4 bytes used to store local variables,164; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first165; fixed argument.166; For N32/N64, it is only 8 since the fixed arguments do not reserve stack167; space.168; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 12169; O32-DAG: sw [[VA]], 0([[SP]])170 171; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8172; N32-DAG: sw [[VA]], 0([[SP]])173 174; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8175; N64-DAG: sd [[VA]], 0([[SP]])176 177; ALL: teqi $zero, 1178 179; Increment [[VA]]180; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])181; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4182; O32-DAG: sw [[VA2]], 0([[SP]])183 184; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])185; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8186; N32-DAG: sw [[VA2]], 0([[SP]])187 188; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])189; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8190; N64-DAG: sd [[VA2]], 0([[SP]])191 192; Load the first argument from the variable portion.193; This has used the stack pointer directly rather than the [[VA]] we just set194; up.195; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte196; order.197; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])198 199; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])200; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])201 202; Copy the arg to the global203; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)204 205; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)206 207; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)208 209; ALL-DAG: sw [[ARG1]], 4([[GV]])210 211; ALL: teqi $zero, 2212 213; Increment [[VA]] again.214; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])215; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4216; O32-DAG: sw [[VA2]], 0([[SP]])217 218; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])219; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8220; N32-DAG: sw [[VA3]], 0([[SP]])221 222; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])223; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8224; N64-DAG: sd [[VA3]], 0([[SP]])225 226; Load the second argument from the variable portion.227; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])228 229; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])230; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])231 232; Copy the arg to the global233; ALL-DAG: sw [[ARG2]], 8([[GV]])234 235 %ap = alloca ptr, align 8236 call void @llvm.va_start(ptr %ap)237 238 call void asm sideeffect "teqi $$zero, 1", ""()239 %arg1 = va_arg ptr %ap, i32240 %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1241 store volatile i32 %arg1, ptr %e1, align 4242 243 call void asm sideeffect "teqi $$zero, 2", ""()244 %arg2 = va_arg ptr %ap, i32245 %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2246 store volatile i32 %arg2, ptr %e2, align 4247 248 call void @llvm.va_end(ptr %ap)249 250 ret void251}252 253define void @fn_i16_dotdotdot_i64(i16 %a, ...) {254entry:255; ALL-LABEL: fn_i16_dotdotdot_i64:256 257; Set up the stack with an 8-byte local area. N32/N64 must also make room for258; the argument save area (56 bytes).259; O32: addiu [[SP:\$sp]], $sp, -8260; N32: addiu [[SP:\$sp]], $sp, -64261; N64: daddiu [[SP:\$sp]], $sp, -64262 263; Save variable argument portion on the stack264; O32-DAG: sw $7, 20([[SP]])265; O32-DAG: sw $6, 16([[SP]])266; O32-DAG: sw $5, 12([[SP]])267 268; NEW-DAG: sd $11, 56([[SP]])269; NEW-DAG: sd $10, 48([[SP]])270; NEW-DAG: sd $9, 40([[SP]])271; NEW-DAG: sd $8, 32([[SP]])272; NEW-DAG: sd $7, 24([[SP]])273; NEW-DAG: sd $6, 16([[SP]])274; NEW-DAG: sd $5, 8([[SP]])275 276; Initialize variable argument pointer.277; For O32, the offset is 12 due to the 4 bytes used to store local variables,278; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first279; fixed argument.280; For N32/N64, it is only 8 since the fixed arguments do not reserve stack281; space.282; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 12283; O32-DAG: sw [[VA]], 0([[SP]])284 285; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8286; N32-DAG: sw [[VA]], 0([[SP]])287 288; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8289; N64-DAG: sd [[VA]], 0([[SP]])290 291; ALL: teqi $zero, 1292 293; Increment [[VA]] (and realign pointer for O32)294; O32: lw [[VA:\$[0-9]+]], 0([[SP]])295; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7296; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8297; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]298; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4299; O32-DAG: sw [[VA2]], 0([[SP]])300 301; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])302; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8303; N32-DAG: sw [[VA2]], 0([[SP]])304 305; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])306; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8307; N64-DAG: sd [[VA2]], 0([[SP]])308 309; Load the first argument from the variable portion and copy it to the global.310; This has used the stack pointer directly rather than the [[VA]] we just set311; up.312; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte313; order.314; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)315; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])316; O32-DAG: sw [[ARG1]], 8([[GV]])317; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8318; O32-DAG: sw [[VA3]], 0([[SP]])319; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])320; O32-DAG: sw [[ARG1]], 12([[GV]])321 322; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)323; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)324; NEW-DAG: ld [[ARG1:\$[0-9]+]], 0([[VA]])325; NEW-DAG: sd [[ARG1]], 8([[GV]])326 327; ALL: teqi $zero, 2328 329; Increment [[VA]] again.330; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.331; O32: lw [[VA:\$[0-9]+]], 0([[SP]])332; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7333; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]334; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4335; O32-DAG: sw [[VA2]], 0([[SP]])336 337; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])338; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8339; N32-DAG: sw [[VA3]], 0([[SP]])340 341; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])342; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8343; N64-DAG: sd [[VA3]], 0([[SP]])344 345; Load the second argument from the variable portion and copy it to the global.346; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])347; O32-DAG: sw [[ARG2]], 16([[GV]])348; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8349; O32-DAG: sw [[VA3]], 0([[SP]])350; O32-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])351; O32-DAG: sw [[ARG2]], 20([[GV]])352 353; NEW-DAG: ld [[ARG2:\$[0-9]+]], 0([[VA2]])354; NEW-DAG: sd [[ARG2]], 16([[GV]])355 356 %ap = alloca ptr, align 8357 call void @llvm.va_start(ptr %ap)358 359 call void asm sideeffect "teqi $$zero, 1", ""()360 %arg1 = va_arg ptr %ap, i64361 %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 1362 store volatile i64 %arg1, ptr %e1, align 8363 364 call void asm sideeffect "teqi $$zero, 2", ""()365 %arg2 = va_arg ptr %ap, i64366 %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 2367 store volatile i64 %arg2, ptr %e2, align 8368 369 call void @llvm.va_end(ptr %ap)370 371 ret void372}373 374define void @fn_i32_dotdotdot_i16(i32 %a, ...) {375entry:376; ALL-LABEL: fn_i32_dotdotdot_i16:377 378; Set up the stack with an 8-byte local area. N32/N64 must also make room for379; the argument save area (56 bytes).380; O32: addiu [[SP:\$sp]], $sp, -8381; N32: addiu [[SP:\$sp]], $sp, -64382; N64: daddiu [[SP:\$sp]], $sp, -64383 384; Save variable argument portion on the stack385; O32-DAG: sw $7, 20([[SP]])386; O32-DAG: sw $6, 16([[SP]])387; O32-DAG: sw $5, 12([[SP]])388 389; NEW-DAG: sd $11, 56([[SP]])390; NEW-DAG: sd $10, 48([[SP]])391; NEW-DAG: sd $9, 40([[SP]])392; NEW-DAG: sd $8, 32([[SP]])393; NEW-DAG: sd $7, 24([[SP]])394; NEW-DAG: sd $6, 16([[SP]])395; NEW-DAG: sd $5, 8([[SP]])396 397; Initialize variable argument pointer.398; For O32, the offset is 12 due to the 4 bytes used to store local variables,399; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first400; fixed argument.401; For N32/N64, it is only 8 since the fixed arguments do not reserve stack402; space.403; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 12404; O32-DAG: sw [[VA]], 0([[SP]])405 406; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8407; N32-DAG: sw [[VA]], 0([[SP]])408 409; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8410; N64-DAG: sd [[VA]], 0([[SP]])411 412; ALL: teqi $zero, 1413 414; Increment [[VA]]415; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])416; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4417; O32-DAG: sw [[VA2]], 0([[SP]])418 419; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])420; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8421; N32-DAG: sw [[VA2]], 0([[SP]])422 423; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])424; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8425; N64-DAG: sd [[VA2]], 0([[SP]])426 427; Load the first argument from the variable portion.428; This has used the stack pointer directly rather than the [[VA]] we just set429; up.430; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte431; order.432; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])433 434; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])435; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])436 437; Copy the arg to the global438; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)439 440; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)441 442; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)443 444; ALL-DAG: sh [[ARG1]], 2([[GV]])445 446; ALL: teqi $zero, 2447 448; Increment [[VA]] again.449; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])450; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4451; O32-DAG: sw [[VA2]], 0([[SP]])452 453; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])454; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8455; N32-DAG: sw [[VA3]], 0([[SP]])456 457; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])458; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8459; N64-DAG: sd [[VA3]], 0([[SP]])460 461; Load the second argument from the variable portion.462; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])463 464; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])465; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])466 467; Copy the arg to the global468; ALL-DAG: sh [[ARG2]], 4([[GV]])469 470 %ap = alloca ptr, align 8471 call void @llvm.va_start(ptr %ap)472 473 call void asm sideeffect "teqi $$zero, 1", ""()474 %arg1 = va_arg ptr %ap, i16475 %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1476 store volatile i16 %arg1, ptr %e1, align 2477 478 call void asm sideeffect "teqi $$zero, 2", ""()479 %arg2 = va_arg ptr %ap, i16480 %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2481 store volatile i16 %arg2, ptr %e2, align 2482 483 call void @llvm.va_end(ptr %ap)484 485 ret void486}487 488define void @fn_i32_dotdotdot_i32(i32 %a, ...) {489entry:490; ALL-LABEL: fn_i32_dotdotdot_i32:491 492; Set up the stack with an 8-byte local area. N32/N64 must also make room for493; the argument save area (56 bytes).494; O32: addiu [[SP:\$sp]], $sp, -8495; N32: addiu [[SP:\$sp]], $sp, -64496; N64: daddiu [[SP:\$sp]], $sp, -64497 498; Save variable argument portion on the stack499; O32-DAG: sw $7, 20([[SP]])500; O32-DAG: sw $6, 16([[SP]])501; O32-DAG: sw $5, 12([[SP]])502 503; NEW-DAG: sd $11, 56([[SP]])504; NEW-DAG: sd $10, 48([[SP]])505; NEW-DAG: sd $9, 40([[SP]])506; NEW-DAG: sd $8, 32([[SP]])507; NEW-DAG: sd $7, 24([[SP]])508; NEW-DAG: sd $6, 16([[SP]])509; NEW-DAG: sd $5, 8([[SP]])510 511; Initialize variable argument pointer.512; For O32, the offset is 12 due to the 4 bytes used to store local variables,513; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first514; fixed argument.515; For N32/N64, it is only 8 since the fixed arguments do not reserve stack516; space.517; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 12518; O32-DAG: sw [[VA]], 0([[SP]])519 520; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8521; N32-DAG: sw [[VA]], 0([[SP]])522 523; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8524; N64-DAG: sd [[VA]], 0([[SP]])525 526; ALL: teqi $zero, 1527 528; Increment [[VA]]529; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])530; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4531; O32-DAG: sw [[VA2]], 0([[SP]])532 533; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])534; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8535; N32-DAG: sw [[VA2]], 0([[SP]])536 537; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])538; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8539; N64-DAG: sd [[VA2]], 0([[SP]])540 541; Load the first argument from the variable portion.542; This has used the stack pointer directly rather than the [[VA]] we just set543; up.544; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte545; order.546; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])547 548; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])549; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])550 551; Copy the arg to the global552; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)553 554; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)555 556; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)557 558; ALL-DAG: sw [[ARG1]], 4([[GV]])559 560; ALL: teqi $zero, 2561 562; Increment [[VA]] again.563; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])564; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4565; O32-DAG: sw [[VA2]], 0([[SP]])566 567; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])568; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8569; N32-DAG: sw [[VA3]], 0([[SP]])570 571; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])572; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8573; N64-DAG: sd [[VA3]], 0([[SP]])574 575; Load the second argument from the variable portion.576; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])577 578; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])579; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])580 581; Copy the arg to the global582; ALL-DAG: sw [[ARG2]], 8([[GV]])583 584 %ap = alloca ptr, align 8585 call void @llvm.va_start(ptr %ap)586 587 call void asm sideeffect "teqi $$zero, 1", ""()588 %arg1 = va_arg ptr %ap, i32589 %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1590 store volatile i32 %arg1, ptr %e1, align 4591 592 call void asm sideeffect "teqi $$zero, 2", ""()593 %arg2 = va_arg ptr %ap, i32594 %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2595 store volatile i32 %arg2, ptr %e2, align 4596 597 call void @llvm.va_end(ptr %ap)598 599 ret void600}601 602define void @fn_i32_dotdotdot_i64(i32 %a, ...) {603entry:604; ALL-LABEL: fn_i32_dotdotdot_i64:605 606; Set up the stack with an 8-byte local area. N32/N64 must also make room for607; the argument save area (56 bytes).608; O32: addiu [[SP:\$sp]], $sp, -8609; N32: addiu [[SP:\$sp]], $sp, -64610; N64: daddiu [[SP:\$sp]], $sp, -64611 612; Save variable argument portion on the stack613; O32-DAG: sw $7, 20([[SP]])614; O32-DAG: sw $6, 16([[SP]])615; O32-DAG: sw $5, 12([[SP]])616 617; NEW-DAG: sd $11, 56([[SP]])618; NEW-DAG: sd $10, 48([[SP]])619; NEW-DAG: sd $9, 40([[SP]])620; NEW-DAG: sd $8, 32([[SP]])621; NEW-DAG: sd $7, 24([[SP]])622; NEW-DAG: sd $6, 16([[SP]])623; NEW-DAG: sd $5, 8([[SP]])624 625; Initialize variable argument pointer.626; For O32, the offset is 12 due to the 4 bytes used to store local variables,627; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first628; fixed argument.629; For N32/N64, it is only 8 since the fixed arguments do not reserve stack630; space.631; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 12632; O32-DAG: sw [[VA]], 0([[SP]])633 634; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8635; N32-DAG: sw [[VA]], 0([[SP]])636 637; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8638; N64-DAG: sd [[VA]], 0([[SP]])639 640; ALL: teqi $zero, 1641 642; Increment [[VA]] (and realign pointer for O32)643; O32: lw [[VA:\$[0-9]+]], 0([[SP]])644; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7645; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8646; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]647; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4648; O32-DAG: sw [[VA2]], 0([[SP]])649 650; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])651; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8652; N32-DAG: sw [[VA2]], 0([[SP]])653 654; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])655; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8656; N64-DAG: sd [[VA2]], 0([[SP]])657 658; Load the first argument from the variable portion and copy it to the global.659; This has used the stack pointer directly rather than the [[VA]] we just set660; up.661; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte662; order.663; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)664; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])665; O32-DAG: sw [[ARG1]], 8([[GV]])666; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8667; O32-DAG: sw [[VA3]], 0([[SP]])668; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])669; O32-DAG: sw [[ARG1]], 12([[GV]])670 671; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)672; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)673; NEW-DAG: ld [[ARG1:\$[0-9]+]], 0([[VA]])674; NEW-DAG: sd [[ARG1]], 8([[GV]])675 676; ALL: teqi $zero, 2677 678; Increment [[VA]] again.679; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.680; O32: lw [[VA:\$[0-9]+]], 0([[SP]])681; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7682; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]683; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4684; O32-DAG: sw [[VA2]], 0([[SP]])685 686; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])687; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8688; N32-DAG: sw [[VA3]], 0([[SP]])689 690; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])691; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8692; N64-DAG: sd [[VA3]], 0([[SP]])693 694; Load the second argument from the variable portion and copy it to the global.695; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])696; O32-DAG: sw [[ARG2]], 16([[GV]])697; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 8698; O32-DAG: sw [[VA3]], 0([[SP]])699; O32-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])700; O32-DAG: sw [[ARG2]], 20([[GV]])701 702; NEW-DAG: ld [[ARG2:\$[0-9]+]], 0([[VA2]])703; NEW-DAG: sd [[ARG2]], 16([[GV]])704 705 %ap = alloca ptr, align 8706 call void @llvm.va_start(ptr %ap)707 708 call void asm sideeffect "teqi $$zero, 1", ""()709 %arg1 = va_arg ptr %ap, i64710 %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 1711 store volatile i64 %arg1, ptr %e1, align 8712 713 call void asm sideeffect "teqi $$zero, 2", ""()714 %arg2 = va_arg ptr %ap, i64715 %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 2716 store volatile i64 %arg2, ptr %e2, align 8717 718 call void @llvm.va_end(ptr %ap)719 720 ret void721}722 723define void @fn_i64_dotdotdot_i16(i64 %a, ...) {724entry:725; ALL-LABEL: fn_i64_dotdotdot_i16:726 727; Set up the stack with an 8-byte local area. N32/N64 must also make room for728; the argument save area (56 bytes).729; O32: addiu [[SP:\$sp]], $sp, -8730; N32: addiu [[SP:\$sp]], $sp, -64731; N64: daddiu [[SP:\$sp]], $sp, -64732 733; Save variable argument portion on the stack734; O32-DAG: sw $7, 20([[SP]])735; O32-DAG: sw $6, 16([[SP]])736 737; NEW-DAG: sd $11, 56([[SP]])738; NEW-DAG: sd $10, 48([[SP]])739; NEW-DAG: sd $9, 40([[SP]])740; NEW-DAG: sd $8, 32([[SP]])741; NEW-DAG: sd $7, 24([[SP]])742; NEW-DAG: sd $6, 16([[SP]])743; NEW-DAG: sd $5, 8([[SP]])744 745; Initialize variable argument pointer.746; For O32, the offset is 16 due to the 4 bytes used to store local variables,747; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the748; first fixed argument.749; For N32/N64, it is only 8 since the fixed arguments do not reserve stack750; space.751; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 16752; O32-DAG: sw [[VA]], 0([[SP]])753 754; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8755; N32-DAG: sw [[VA]], 0([[SP]])756 757; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8758; N64-DAG: sd [[VA]], 0([[SP]])759 760; ALL: teqi $zero, 1761 762; Increment [[VA]]763; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])764; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4765; O32-DAG: sw [[VA2]], 0([[SP]])766 767; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])768; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8769; N32-DAG: sw [[VA2]], 0([[SP]])770 771; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])772; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8773; N64-DAG: sd [[VA2]], 0([[SP]])774 775; Load the first argument from the variable portion.776; This has used the stack pointer directly rather than the [[VA]] we just set777; up.778; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte779; order.780; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])781 782; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])783; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])784 785; Copy the arg to the global786; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)787 788; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)789 790; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)791 792; ALL-DAG: sh [[ARG1]], 2([[GV]])793 794; ALL: teqi $zero, 2795 796; Increment [[VA]] again.797; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])798; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4799; O32-DAG: sw [[VA2]], 0([[SP]])800 801; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])802; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8803; N32-DAG: sw [[VA3]], 0([[SP]])804 805; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])806; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8807; N64-DAG: sd [[VA3]], 0([[SP]])808 809; Load the second argument from the variable portion.810; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])811 812; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])813; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])814 815; Copy the arg to the global816; ALL-DAG: sh [[ARG2]], 4([[GV]])817 818 %ap = alloca ptr, align 8819 call void @llvm.va_start(ptr %ap)820 821 call void asm sideeffect "teqi $$zero, 1", ""()822 %arg1 = va_arg ptr %ap, i16823 %e1 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 1824 store volatile i16 %arg1, ptr %e1, align 2825 826 call void asm sideeffect "teqi $$zero, 2", ""()827 %arg2 = va_arg ptr %ap, i16828 %e2 = getelementptr [3 x i16], ptr @hwords, i32 0, i32 2829 store volatile i16 %arg2, ptr %e2, align 2830 831 call void @llvm.va_end(ptr %ap)832 833 ret void834}835 836define void @fn_i64_dotdotdot_i32(i64 %a, ...) {837entry:838; ALL-LABEL: fn_i64_dotdotdot_i32:839 840; Set up the stack with an 8-byte local area. N32/N64 must also make room for841; the argument save area (56 bytes).842; O32: addiu [[SP:\$sp]], $sp, -8843; N32: addiu [[SP:\$sp]], $sp, -64844; N64: daddiu [[SP:\$sp]], $sp, -64845 846; Save variable argument portion on the stack847; O32-DAG: sw $7, 20([[SP]])848; O32-DAG: sw $6, 16([[SP]])849 850; NEW-DAG: sd $11, 56([[SP]])851; NEW-DAG: sd $10, 48([[SP]])852; NEW-DAG: sd $9, 40([[SP]])853; NEW-DAG: sd $8, 32([[SP]])854; NEW-DAG: sd $7, 24([[SP]])855; NEW-DAG: sd $6, 16([[SP]])856; NEW-DAG: sd $5, 8([[SP]])857 858; Initialize variable argument pointer.859; For O32, the offset is 16 due to the 4 bytes used to store local variables,860; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the861; first fixed argument.862; For N32/N64, it is only 8 since the fixed arguments do not reserve stack863; space.864; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 16865; O32-DAG: sw [[VA]], 0([[SP]])866 867; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8868; N32-DAG: sw [[VA]], 0([[SP]])869 870; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8871; N64-DAG: sd [[VA]], 0([[SP]])872 873; ALL: teqi $zero, 1874 875; Increment [[VA]]876; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])877; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4878; O32-DAG: sw [[VA2]], 0([[SP]])879 880; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])881; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8882; N32-DAG: sw [[VA2]], 0([[SP]])883 884; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])885; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8886; N64-DAG: sd [[VA2]], 0([[SP]])887 888; Load the first argument from the variable portion.889; This has used the stack pointer directly rather than the [[VA]] we just set890; up.891; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte892; order.893; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])894 895; NEW-LE-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])896; NEW-BE-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA]])897 898; Copy the arg to the global899; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)900 901; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)902 903; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)904 905; ALL-DAG: sw [[ARG1]], 4([[GV]])906 907; ALL: teqi $zero, 2908 909; Increment [[VA]] again.910; O32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])911; O32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 4912; O32-DAG: sw [[VA2]], 0([[SP]])913 914; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])915; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 8916; N32-DAG: sw [[VA3]], 0([[SP]])917 918; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])919; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 8920; N64-DAG: sd [[VA3]], 0([[SP]])921 922; Load the second argument from the variable portion.923; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])924 925; NEW-LE-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA2]])926; NEW-BE-DAG: lw [[ARG2:\$[0-9]+]], 4([[VA2]])927 928; Copy the arg to the global929; ALL-DAG: sw [[ARG2]], 8([[GV]])930 931 %ap = alloca ptr, align 8932 call void @llvm.va_start(ptr %ap)933 934 call void asm sideeffect "teqi $$zero, 1", ""()935 %arg1 = va_arg ptr %ap, i32936 %e1 = getelementptr [3 x i32], ptr @words, i32 0, i32 1937 store volatile i32 %arg1, ptr %e1, align 4938 939 call void asm sideeffect "teqi $$zero, 2", ""()940 %arg2 = va_arg ptr %ap, i32941 %e2 = getelementptr [3 x i32], ptr @words, i32 0, i32 2942 store volatile i32 %arg2, ptr %e2, align 4943 944 call void @llvm.va_end(ptr %ap)945 946 ret void947}948 949define void @fn_i64_dotdotdot_i64(i64 %a, ...) {950entry:951; ALL-LABEL: fn_i64_dotdotdot_i64:952 953; Set up the stack with an 8-byte local area. N32/N64 must also make room for954; the argument save area (56 bytes).955; O32: addiu [[SP:\$sp]], $sp, -8956; N32: addiu [[SP:\$sp]], $sp, -64957; N64: daddiu [[SP:\$sp]], $sp, -64958 959; Save variable argument portion on the stack960; O32-DAG: sw $7, 20([[SP]])961; O32-DAG: sw $6, 16([[SP]])962 963; NEW-DAG: sd $11, 56([[SP]])964; NEW-DAG: sd $10, 48([[SP]])965; NEW-DAG: sd $9, 40([[SP]])966; NEW-DAG: sd $8, 32([[SP]])967; NEW-DAG: sd $7, 24([[SP]])968; NEW-DAG: sd $6, 16([[SP]])969; NEW-DAG: sd $5, 8([[SP]])970 971; Initialize variable argument pointer.972; For O32, the offset is 16 due to the 4 bytes used to store local variables,973; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the974; first fixed argument.975; For N32/N64, it is only 8 since the fixed arguments do not reserve stack976; space.977; O32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 16978; O32-DAG: sw [[VA]], 0([[SP]])979 980; N32-DAG: addiu [[VA:\$[0-9]+]], [[SP]], 8981; N32-DAG: sw [[VA]], 0([[SP]])982 983; N64-DAG: daddiu [[VA:\$[0-9]+]], [[SP]], 8984; N64-DAG: sd [[VA]], 0([[SP]])985 986; ALL: teqi $zero, 1987 988; Increment [[VA]] (and realign pointer for O32)989; O32: lw [[VA:\$[0-9]+]], 0([[SP]])990; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7991; O32-DAG: addiu [[VA_TMP1:\$[0-9]+]], $zero, -8992; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]993; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 4994; O32-DAG: sw [[VA2]], 0([[SP]])995 996; N32-DAG: lw [[VA:\$[0-9]+]], 0([[SP]])997; N32-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 8998; N32-DAG: sw [[VA2]], 0([[SP]])999 1000; N64-DAG: ld [[VA:\$[0-9]+]], 0([[SP]])1001; N64-DAG: addiu [[VA2:\$[0-9]+]], [[VA]], 81002; N64-DAG: sd [[VA2]], 0([[SP]])1003 1004; Load the first argument from the variable portion and copy it to the global.1005; This has used the stack pointer directly rather than the [[VA]] we just set1006; up.1007; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte1008; order.1009; O32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)1010; O32-DAG: lw [[ARG1:\$[0-9]+]], 0([[VA]])1011; O32-DAG: sw [[ARG1]], 8([[GV]])1012; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 81013; O32-DAG: sw [[VA3]], 0([[SP]])1014; O32-DAG: lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])1015; O32-DAG: sw [[ARG1]], 12([[GV]])1016 1017; N32-DAG: addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)1018; N64-DAG: daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)1019; NEW-DAG: ld [[ARG1:\$[0-9]+]], 0([[VA]])1020; NEW-DAG: sd [[ARG1]], 8([[GV]])1021 1022; ALL: teqi $zero, 21023 1024; Increment [[VA]] again.1025; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.1026; O32: lw [[VA:\$[0-9]+]], 0([[SP]])1027; O32-DAG: addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 71028; O32-DAG: and [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]1029; O32-DAG: ori [[VA2:\$[0-9]+]], [[VA_TMP2]], 41030; O32-DAG: sw [[VA2]], 0([[SP]])1031 1032; N32-DAG: lw [[VA2:\$[0-9]+]], 0([[SP]])1033; N32-DAG: addiu [[VA3:\$[0-9]+]], [[VA2]], 81034; N32-DAG: sw [[VA3]], 0([[SP]])1035 1036; N64-DAG: ld [[VA2:\$[0-9]+]], 0([[SP]])1037; N64-DAG: daddiu [[VA3:\$[0-9]+]], [[VA2]], 81038; N64-DAG: sd [[VA3]], 0([[SP]])1039 1040; Load the second argument from the variable portion and copy it to the global.1041; O32-DAG: lw [[ARG2:\$[0-9]+]], 0([[VA]])1042; O32-DAG: addiu [[VA3:\$[0-9]+]], [[VA_TMP2]], 81043; O32-DAG: sw [[VA3]], 0([[SP]])1044; O32-DAG: lw [[ARG3:\$[0-9]+]], 4([[VA_TMP2]])1045; O32-DAG: sw [[ARG3]], 20([[GV]])1046; O32-DAG: sw [[ARG2]], 16([[GV]])1047 1048; NEW-DAG: ld [[ARG2:\$[0-9]+]], 0([[VA2]])1049; NEW-DAG: sd [[ARG2]], 16([[GV]])1050 1051 %ap = alloca ptr, align 81052 call void @llvm.va_start(ptr %ap)1053 1054 call void asm sideeffect "teqi $$zero, 1", ""()1055 %arg1 = va_arg ptr %ap, i641056 %e1 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 11057 store volatile i64 %arg1, ptr %e1, align 81058 1059 call void asm sideeffect "teqi $$zero, 2", ""()1060 %arg2 = va_arg ptr %ap, i641061 %e2 = getelementptr [3 x i64], ptr @dwords, i32 0, i32 21062 store volatile i64 %arg2, ptr %e2, align 81063 1064 call void @llvm.va_end(ptr %ap)1065 1066 ret void1067}1068 1069declare void @llvm.va_start(ptr)1070declare void @llvm.va_end(ptr)1071