Home | History | Annotate | Download | only in cconv
      1 ; RUN: llc -mtriple=mips-linux -relocation-model=static < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,O32,O32-BE %s
      2 ; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,O32,O32-LE %s
      3 
      4 ; RUN-TODO: llc -march=mips64 -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
      5 ; RUN-TODO: llc -march=mips64el -relocation-model=static -target-abi o32 < %s | FileCheck --check-prefixes=ALL,O32 %s
      6 
      7 ; RUN: llc -mtriple=mips64-linux -relocation-model=static -target-abi n32 < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,NEW,N32,NEW-BE %s
      8 ; RUN: llc -mtriple=mips64el-linux -relocation-model=static -target-abi n32 < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,NEW,N32,NEW-LE %s
      9 
     10 ; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,NEW,N64,NEW-BE %s
     11 ; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck -allow-deprecated-dag-overlap --check-prefixes=ALL,NEW,N64,NEW-LE %s
     12 
     13 @hwords = global [3 x i16] zeroinitializer, align 1
     14 @words  = global [3 x i32] zeroinitializer, align 1
     15 @dwords = global [3 x i64] zeroinitializer, align 1
     16 
     17 define void @fn_i16_dotdotdot_i16(i16 %a, ...) {
     18 entry:
     19 ; ALL-LABEL: fn_i16_dotdotdot_i16:
     20 
     21 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
     22 ; the argument save area (56 bytes).
     23 ; O32:           addiu  [[SP:\$sp]], $sp, -8
     24 ; N32:           addiu  [[SP:\$sp]], $sp, -64
     25 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
     26 
     27 ; Save variable argument portion on the stack
     28 ; O32-DAG:       sw $7, 20([[SP]])
     29 ; O32-DAG:       sw $6, 16([[SP]])
     30 ; O32-DAG:       sw $5, 12([[SP]])
     31 
     32 ; NEW-DAG:       sd $11, 56([[SP]])
     33 ; NEW-DAG:       sd $10, 48([[SP]])
     34 ; NEW-DAG:       sd $9, 40([[SP]])
     35 ; NEW-DAG:       sd $8, 32([[SP]])
     36 ; NEW-DAG:       sd $7, 24([[SP]])
     37 ; NEW-DAG:       sd $6, 16([[SP]])
     38 ; NEW-DAG:       sd $5, 8([[SP]])
     39 
     40 ; Initialize variable argument pointer.
     41 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
     42 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
     43 ; fixed argument.
     44 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
     45 ; space.
     46 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
     47 ; O32-DAG:       sw [[VA]], 0([[SP]])
     48 
     49 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
     50 ; N32-DAG:       sw [[VA]], 0([[SP]])
     51 
     52 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
     53 ; N64-DAG:       sd [[VA]], 0([[SP]])
     54 
     55 ; Store [[VA]]
     56 ; O32-DAG:       sw [[VA]], 0([[SP]])
     57 
     58 ; ALL: teqi $zero, 1
     59 
     60 ; Increment [[VA]]
     61 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
     62 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
     63 ; O32-DAG:       sw [[VA2]], 0([[SP]])
     64 
     65 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
     66 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
     67 ; N32-DAG:       sw [[VA2]], 0([[SP]])
     68 
     69 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
     70 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
     71 ; N64-DAG:       sd [[VA2]], 0([[SP]])
     72 
     73 ; Load the first argument from the variable portion.
     74 ; This has used the stack pointer directly rather than the [[VA]] we just set
     75 ; up.
     76 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
     77 ; order.
     78 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
     79 
     80 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
     81 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
     82 
     83 ; Copy the arg to the global
     84 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
     85 
     86 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
     87 
     88 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
     89 
     90 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
     91 
     92 ; ALL: teqi $zero, 2
     93 
     94 ; Increment [[VA]] again.
     95 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
     96 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
     97 ; O32-DAG:       sw [[VA2]], 0([[SP]])
     98 
     99 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    100 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    101 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    102 
    103 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    104 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    105 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    106 
    107 ; Load the second argument from the variable portion.
    108 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    109 
    110 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    111 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    112 
    113 ; Copy the arg to the global
    114 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
    115 
    116   %ap = alloca i8*, align 8
    117   %ap2 = bitcast i8** %ap to i8*
    118   call void @llvm.va_start(i8* %ap2)
    119 
    120   call void asm sideeffect "teqi $$zero, 1", ""()
    121   %arg1 = va_arg i8** %ap, i16
    122   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
    123   store volatile i16 %arg1, i16* %e1, align 2
    124 
    125   call void asm sideeffect "teqi $$zero, 2", ""()
    126   %arg2 = va_arg i8** %ap, i16
    127   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
    128   store volatile i16 %arg2, i16* %e2, align 2
    129 
    130   call void @llvm.va_end(i8* %ap2)
    131 
    132   ret void
    133 }
    134 
    135 define void @fn_i16_dotdotdot_i32(i16 %a, ...) {
    136 entry:
    137 ; ALL-LABEL: fn_i16_dotdotdot_i32:
    138 
    139 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    140 ; the argument save area (56 bytes).
    141 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    142 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    143 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    144 
    145 ; Save variable argument portion on the stack
    146 ; O32-DAG:       sw $7, 20([[SP]])
    147 ; O32-DAG:       sw $6, 16([[SP]])
    148 ; O32-DAG:       sw $5, 12([[SP]])
    149 
    150 ; NEW-DAG:       sd $11, 56([[SP]])
    151 ; NEW-DAG:       sd $10, 48([[SP]])
    152 ; NEW-DAG:       sd $9, 40([[SP]])
    153 ; NEW-DAG:       sd $8, 32([[SP]])
    154 ; NEW-DAG:       sd $7, 24([[SP]])
    155 ; NEW-DAG:       sd $6, 16([[SP]])
    156 ; NEW-DAG:       sd $5, 8([[SP]])
    157 
    158 ; Initialize variable argument pointer.
    159 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    160 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    161 ; fixed argument.
    162 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    163 ; space.
    164 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    165 ; O32-DAG:       sw [[VA]], 0([[SP]])
    166 
    167 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    168 ; N32-DAG:       sw [[VA]], 0([[SP]])
    169 
    170 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    171 ; N64-DAG:       sd [[VA]], 0([[SP]])
    172 
    173 ; Store [[VA]]
    174 ; O32-DAG:       sw [[VA]], 0([[SP]])
    175 
    176 ; ALL: teqi $zero, 1
    177 
    178 ; Increment [[VA]]
    179 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    180 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    181 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    182 
    183 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    184 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    185 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    186 
    187 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    188 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    189 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    190 
    191 ; Load the first argument from the variable portion.
    192 ; This has used the stack pointer directly rather than the [[VA]] we just set
    193 ; up.
    194 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    195 ; order.
    196 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    197 
    198 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    199 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    200 
    201 ; Copy the arg to the global
    202 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    203 
    204 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    205 
    206 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    207 
    208 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
    209 
    210 ; ALL: teqi $zero, 2
    211 
    212 ; Increment [[VA]] again.
    213 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    214 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    215 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    216 
    217 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    218 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    219 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    220 
    221 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    222 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    223 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    224 
    225 ; Load the second argument from the variable portion.
    226 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    227 
    228 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    229 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    230 
    231 ; Copy the arg to the global
    232 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
    233 
    234   %ap = alloca i8*, align 8
    235   %ap2 = bitcast i8** %ap to i8*
    236   call void @llvm.va_start(i8* %ap2)
    237 
    238   call void asm sideeffect "teqi $$zero, 1", ""()
    239   %arg1 = va_arg i8** %ap, i32
    240   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
    241   store volatile i32 %arg1, i32* %e1, align 4
    242 
    243   call void asm sideeffect "teqi $$zero, 2", ""()
    244   %arg2 = va_arg i8** %ap, i32
    245   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
    246   store volatile i32 %arg2, i32* %e2, align 4
    247 
    248   call void @llvm.va_end(i8* %ap2)
    249 
    250   ret void
    251 }
    252 
    253 define void @fn_i16_dotdotdot_i64(i16 %a, ...) {
    254 entry:
    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 for
    258 ; the argument save area (56 bytes).
    259 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    260 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    261 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    262 
    263 ; Save variable argument portion on the stack
    264 ; 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 first
    279 ; fixed argument.
    280 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    281 ; space.
    282 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    283 ; O32-DAG:       sw [[VA]], 0([[SP]])
    284 
    285 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    286 ; N32-DAG:       sw [[VA]], 0([[SP]])
    287 
    288 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    289 ; N64-DAG:       sd [[VA]], 0([[SP]])
    290 
    291 ; Store [[VA]]
    292 ; O32-DAG:       sw [[VA]], 0([[SP]])
    293 
    294 ; ALL: teqi $zero, 1
    295 
    296 ; Increment [[VA]] (and realign pointer for O32)
    297 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    298 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    299 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
    300 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    301 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    302 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    303 
    304 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    305 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    306 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    307 
    308 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    309 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    310 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    311 
    312 ; Load the first argument from the variable portion and copy it to the global.
    313 ; This has used the stack pointer directly rather than the [[VA]] we just set
    314 ; up.
    315 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    316 ; order.
    317 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    318 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
    319 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
    320 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
    321 ; O32-DAG:       sw [[VA3]], 0([[SP]])
    322 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
    323 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
    324 
    325 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    326 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    327 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
    328 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
    329 
    330 ; ALL: teqi $zero, 2
    331 
    332 ; Increment [[VA]] again.
    333 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
    334 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    335 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    336 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    337 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    338 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    339 
    340 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    341 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    342 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    343 
    344 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    345 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    346 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    347 
    348 ; Load the second argument from the variable portion and copy it to the global.
    349 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    350 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
    351 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
    352 ; O32-DAG:       sw [[VA3]], 0([[SP]])
    353 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
    354 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
    355 
    356 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
    357 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
    358 
    359   %ap = alloca i8*, align 8
    360   %ap2 = bitcast i8** %ap to i8*
    361   call void @llvm.va_start(i8* %ap2)
    362 
    363   call void asm sideeffect "teqi $$zero, 1", ""()
    364   %arg1 = va_arg i8** %ap, i64
    365   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
    366   store volatile i64 %arg1, i64* %e1, align 8
    367 
    368   call void asm sideeffect "teqi $$zero, 2", ""()
    369   %arg2 = va_arg i8** %ap, i64
    370   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
    371   store volatile i64 %arg2, i64* %e2, align 8
    372 
    373   call void @llvm.va_end(i8* %ap2)
    374 
    375   ret void
    376 }
    377 
    378 define void @fn_i32_dotdotdot_i16(i32 %a, ...) {
    379 entry:
    380 ; ALL-LABEL: fn_i32_dotdotdot_i16:
    381 
    382 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    383 ; the argument save area (56 bytes).
    384 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    385 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    386 ; N64:           daddiu [[SP:\$sp]], $sp, -64
    387 
    388 ; Save variable argument portion on the stack
    389 ; O32-DAG:       sw $7, 20([[SP]])
    390 ; O32-DAG:       sw $6, 16([[SP]])
    391 ; O32-DAG:       sw $5, 12([[SP]])
    392 
    393 ; NEW-DAG:       sd $11, 56([[SP]])
    394 ; NEW-DAG:       sd $10, 48([[SP]])
    395 ; NEW-DAG:       sd $9, 40([[SP]])
    396 ; NEW-DAG:       sd $8, 32([[SP]])
    397 ; NEW-DAG:       sd $7, 24([[SP]])
    398 ; NEW-DAG:       sd $6, 16([[SP]])
    399 ; NEW-DAG:       sd $5, 8([[SP]])
    400 
    401 ; Initialize variable argument pointer.
    402 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    403 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    404 ; fixed argument.
    405 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    406 ; space.
    407 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    408 ; O32-DAG:       sw [[VA]], 0([[SP]])
    409 
    410 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    411 ; N32-DAG:       sw [[VA]], 0([[SP]])
    412 
    413 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    414 ; N64-DAG:       sd [[VA]], 0([[SP]])
    415 
    416 ; Store [[VA]]
    417 ; O32-DAG:       sw [[VA]], 0([[SP]])
    418 
    419 ; ALL: teqi $zero, 1
    420 
    421 ; Increment [[VA]]
    422 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    423 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    424 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    425 
    426 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    427 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    428 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    429 
    430 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    431 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    432 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    433 
    434 ; Load the first argument from the variable portion.
    435 ; This has used the stack pointer directly rather than the [[VA]] we just set
    436 ; up.
    437 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    438 ; order.
    439 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    440 
    441 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    442 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    443 
    444 ; Copy the arg to the global
    445 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    446 
    447 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    448 
    449 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    450 
    451 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
    452 
    453 ; ALL: teqi $zero, 2
    454 
    455 ; Increment [[VA]] again.
    456 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    457 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    458 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    459 
    460 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    461 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    462 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    463 
    464 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    465 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    466 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    467 
    468 ; Load the second argument from the variable portion.
    469 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    470 
    471 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    472 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    473 
    474 ; Copy the arg to the global
    475 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
    476 
    477   %ap = alloca i8*, align 8
    478   %ap2 = bitcast i8** %ap to i8*
    479   call void @llvm.va_start(i8* %ap2)
    480 
    481   call void asm sideeffect "teqi $$zero, 1", ""()
    482   %arg1 = va_arg i8** %ap, i16
    483   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
    484   store volatile i16 %arg1, i16* %e1, align 2
    485 
    486   call void asm sideeffect "teqi $$zero, 2", ""()
    487   %arg2 = va_arg i8** %ap, i16
    488   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
    489   store volatile i16 %arg2, i16* %e2, align 2
    490 
    491   call void @llvm.va_end(i8* %ap2)
    492 
    493   ret void
    494 }
    495 
    496 define void @fn_i32_dotdotdot_i32(i32 %a, ...) {
    497 entry:
    498 ; ALL-LABEL: fn_i32_dotdotdot_i32:
    499 
    500 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    501 ; the argument save area (56 bytes).
    502 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    503 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    504 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    505 
    506 ; Save variable argument portion on the stack
    507 ; O32-DAG:       sw $7, 20([[SP]])
    508 ; O32-DAG:       sw $6, 16([[SP]])
    509 ; O32-DAG:       sw $5, 12([[SP]])
    510 
    511 ; NEW-DAG:       sd $11, 56([[SP]])
    512 ; NEW-DAG:       sd $10, 48([[SP]])
    513 ; NEW-DAG:       sd $9, 40([[SP]])
    514 ; NEW-DAG:       sd $8, 32([[SP]])
    515 ; NEW-DAG:       sd $7, 24([[SP]])
    516 ; NEW-DAG:       sd $6, 16([[SP]])
    517 ; NEW-DAG:       sd $5, 8([[SP]])
    518 
    519 ; Initialize variable argument pointer.
    520 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    521 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    522 ; fixed argument.
    523 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    524 ; space.
    525 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    526 ; O32-DAG:       sw [[VA]], 0([[SP]])
    527 
    528 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    529 ; N32-DAG:       sw [[VA]], 0([[SP]])
    530 
    531 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    532 ; N64-DAG:       sd [[VA]], 0([[SP]])
    533 
    534 ; Store [[VA]]
    535 ; O32-DAG:       sw [[VA]], 0([[SP]])
    536 
    537 ; ALL: teqi $zero, 1
    538 
    539 ; Increment [[VA]]
    540 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    541 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    542 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    543 
    544 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    545 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    546 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    547 
    548 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    549 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    550 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    551 
    552 ; Load the first argument from the variable portion.
    553 ; This has used the stack pointer directly rather than the [[VA]] we just set
    554 ; up.
    555 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    556 ; order.
    557 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    558 
    559 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    560 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    561 
    562 ; Copy the arg to the global
    563 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    564 
    565 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    566 
    567 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    568 
    569 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
    570 
    571 ; ALL: teqi $zero, 2
    572 
    573 ; Increment [[VA]] again.
    574 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    575 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    576 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    577 
    578 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    579 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    580 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    581 
    582 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    583 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    584 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    585 
    586 ; Load the second argument from the variable portion.
    587 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    588 
    589 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    590 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    591 
    592 ; Copy the arg to the global
    593 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
    594 
    595   %ap = alloca i8*, align 8
    596   %ap2 = bitcast i8** %ap to i8*
    597   call void @llvm.va_start(i8* %ap2)
    598 
    599   call void asm sideeffect "teqi $$zero, 1", ""()
    600   %arg1 = va_arg i8** %ap, i32
    601   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
    602   store volatile i32 %arg1, i32* %e1, align 4
    603 
    604   call void asm sideeffect "teqi $$zero, 2", ""()
    605   %arg2 = va_arg i8** %ap, i32
    606   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
    607   store volatile i32 %arg2, i32* %e2, align 4
    608 
    609   call void @llvm.va_end(i8* %ap2)
    610 
    611   ret void
    612 }
    613 
    614 define void @fn_i32_dotdotdot_i64(i32 %a, ...) {
    615 entry:
    616 ; ALL-LABEL: fn_i32_dotdotdot_i64:
    617 
    618 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    619 ; the argument save area (56 bytes).
    620 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    621 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    622 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    623 
    624 ; Save variable argument portion on the stack
    625 ; O32-DAG:       sw $7, 20([[SP]])
    626 ; O32-DAG:       sw $6, 16([[SP]])
    627 ; O32-DAG:       sw $5, 12([[SP]])
    628 
    629 ; NEW-DAG:       sd $11, 56([[SP]])
    630 ; NEW-DAG:       sd $10, 48([[SP]])
    631 ; NEW-DAG:       sd $9, 40([[SP]])
    632 ; NEW-DAG:       sd $8, 32([[SP]])
    633 ; NEW-DAG:       sd $7, 24([[SP]])
    634 ; NEW-DAG:       sd $6, 16([[SP]])
    635 ; NEW-DAG:       sd $5, 8([[SP]])
    636 
    637 ; Initialize variable argument pointer.
    638 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    639 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    640 ; fixed argument.
    641 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    642 ; space.
    643 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    644 ; O32-DAG:       sw [[VA]], 0([[SP]])
    645 
    646 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    647 ; N32-DAG:       sw [[VA]], 0([[SP]])
    648 
    649 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    650 ; N64-DAG:       sd [[VA]], 0([[SP]])
    651 
    652 ; Store [[VA]]
    653 ; O32-DAG:       sw [[VA]], 0([[SP]])
    654 
    655 ; ALL: teqi $zero, 1
    656 
    657 ; Increment [[VA]] (and realign pointer for O32)
    658 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    659 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    660 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
    661 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    662 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    663 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    664 
    665 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    666 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    667 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    668 
    669 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    670 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    671 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    672 
    673 ; Load the first argument from the variable portion and copy it to the global.
    674 ; This has used the stack pointer directly rather than the [[VA]] we just set
    675 ; up.
    676 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    677 ; order.
    678 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    679 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA_TMP2]])
    680 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
    681 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
    682 ; O32-DAG:       sw [[VA3]], 0([[SP]])
    683 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
    684 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
    685 
    686 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    687 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    688 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
    689 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
    690 
    691 ; ALL: teqi $zero, 2
    692 
    693 ; Increment [[VA]] again.
    694 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
    695 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    696 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    697 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    698 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    699 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    700 
    701 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    702 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    703 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    704 
    705 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    706 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    707 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    708 
    709 ; Load the second argument from the variable portion and copy it to the global.
    710 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    711 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
    712 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
    713 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    714 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
    715 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
    716 
    717 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
    718 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
    719 
    720   %ap = alloca i8*, align 8
    721   %ap2 = bitcast i8** %ap to i8*
    722   call void @llvm.va_start(i8* %ap2)
    723 
    724   call void asm sideeffect "teqi $$zero, 1", ""()
    725   %arg1 = va_arg i8** %ap, i64
    726   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
    727   store volatile i64 %arg1, i64* %e1, align 8
    728 
    729   call void asm sideeffect "teqi $$zero, 2", ""()
    730   %arg2 = va_arg i8** %ap, i64
    731   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
    732   store volatile i64 %arg2, i64* %e2, align 8
    733 
    734   call void @llvm.va_end(i8* %ap2)
    735 
    736   ret void
    737 }
    738 
    739 define void @fn_i64_dotdotdot_i16(i64 %a, ...) {
    740 entry:
    741 ; ALL-LABEL: fn_i64_dotdotdot_i16:
    742 
    743 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    744 ; the argument save area (56 bytes).
    745 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    746 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    747 ; N64:           daddiu [[SP:\$sp]], $sp, -64
    748 
    749 ; Save variable argument portion on the stack
    750 ; O32-DAG:       sw $7, 20([[SP]])
    751 ; O32-DAG:       sw $6, 16([[SP]])
    752 
    753 ; NEW-DAG:       sd $11, 56([[SP]])
    754 ; NEW-DAG:       sd $10, 48([[SP]])
    755 ; NEW-DAG:       sd $9, 40([[SP]])
    756 ; NEW-DAG:       sd $8, 32([[SP]])
    757 ; NEW-DAG:       sd $7, 24([[SP]])
    758 ; NEW-DAG:       sd $6, 16([[SP]])
    759 ; NEW-DAG:       sd $5, 8([[SP]])
    760 
    761 ; Initialize variable argument pointer.
    762 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
    763 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
    764 ; first fixed argument.
    765 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    766 ; space.
    767 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
    768 ; O32-DAG:       sw [[VA]], 0([[SP]])
    769 
    770 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    771 ; N32-DAG:       sw [[VA]], 0([[SP]])
    772 
    773 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    774 ; N64-DAG:       sd [[VA]], 0([[SP]])
    775 
    776 ; Store [[VA]]
    777 ; O32-DAG:       sw [[VA]], 0([[SP]])
    778 
    779 ; ALL: teqi $zero, 1
    780 
    781 ; Increment [[VA]]
    782 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    783 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    784 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    785 
    786 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    787 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    788 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    789 
    790 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    791 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    792 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    793 
    794 ; Load the first argument from the variable portion.
    795 ; This has used the stack pointer directly rather than the [[VA]] we just set
    796 ; up.
    797 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    798 ; order.
    799 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    800 
    801 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    802 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    803 
    804 ; Copy the arg to the global
    805 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    806 
    807 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    808 
    809 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    810 
    811 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
    812 
    813 ; ALL: teqi $zero, 2
    814 
    815 ; Increment [[VA]] again.
    816 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    817 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    818 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    819 
    820 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    821 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    822 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    823 
    824 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    825 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    826 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    827 
    828 ; Load the second argument from the variable portion.
    829 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    830 
    831 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    832 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    833 
    834 ; Copy the arg to the global
    835 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
    836 
    837   %ap = alloca i8*, align 8
    838   %ap2 = bitcast i8** %ap to i8*
    839   call void @llvm.va_start(i8* %ap2)
    840 
    841   call void asm sideeffect "teqi $$zero, 1", ""()
    842   %arg1 = va_arg i8** %ap, i16
    843   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
    844   store volatile i16 %arg1, i16* %e1, align 2
    845 
    846   call void asm sideeffect "teqi $$zero, 2", ""()
    847   %arg2 = va_arg i8** %ap, i16
    848   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
    849   store volatile i16 %arg2, i16* %e2, align 2
    850 
    851   call void @llvm.va_end(i8* %ap2)
    852 
    853   ret void
    854 }
    855 
    856 define void @fn_i64_dotdotdot_i32(i64 %a, ...) {
    857 entry:
    858 ; ALL-LABEL: fn_i64_dotdotdot_i32:
    859 
    860 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    861 ; the argument save area (56 bytes).
    862 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    863 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    864 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    865 
    866 ; Save variable argument portion on the stack
    867 ; O32-DAG:       sw $7, 20([[SP]])
    868 ; O32-DAG:       sw $6, 16([[SP]])
    869 
    870 ; NEW-DAG:       sd $11, 56([[SP]])
    871 ; NEW-DAG:       sd $10, 48([[SP]])
    872 ; NEW-DAG:       sd $9, 40([[SP]])
    873 ; NEW-DAG:       sd $8, 32([[SP]])
    874 ; NEW-DAG:       sd $7, 24([[SP]])
    875 ; NEW-DAG:       sd $6, 16([[SP]])
    876 ; NEW-DAG:       sd $5, 8([[SP]])
    877 
    878 ; Initialize variable argument pointer.
    879 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
    880 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
    881 ; first fixed argument.
    882 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    883 ; space.
    884 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
    885 ; O32-DAG:       sw [[VA]], 0([[SP]])
    886 
    887 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    888 ; N32-DAG:       sw [[VA]], 0([[SP]])
    889 
    890 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    891 ; N64-DAG:       sd [[VA]], 0([[SP]])
    892 
    893 ; Store [[VA]]
    894 ; O32-DAG:       sw [[VA]], 0([[SP]])
    895 
    896 ; ALL: teqi $zero, 1
    897 
    898 ; Increment [[VA]]
    899 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    900 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    901 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    902 
    903 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    904 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    905 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    906 
    907 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    908 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    909 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    910 
    911 ; Load the first argument from the variable portion.
    912 ; This has used the stack pointer directly rather than the [[VA]] we just set
    913 ; up.
    914 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    915 ; order.
    916 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    917 
    918 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    919 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    920 
    921 ; Copy the arg to the global
    922 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    923 
    924 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    925 
    926 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    927 
    928 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
    929 
    930 ; ALL: teqi $zero, 2
    931 
    932 ; Increment [[VA]] again.
    933 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    934 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    935 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    936 
    937 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    938 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    939 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    940 
    941 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    942 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    943 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    944 
    945 ; Load the second argument from the variable portion.
    946 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    947 
    948 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    949 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    950 
    951 ; Copy the arg to the global
    952 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
    953 
    954   %ap = alloca i8*, align 8
    955   %ap2 = bitcast i8** %ap to i8*
    956   call void @llvm.va_start(i8* %ap2)
    957 
    958   call void asm sideeffect "teqi $$zero, 1", ""()
    959   %arg1 = va_arg i8** %ap, i32
    960   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
    961   store volatile i32 %arg1, i32* %e1, align 4
    962 
    963   call void asm sideeffect "teqi $$zero, 2", ""()
    964   %arg2 = va_arg i8** %ap, i32
    965   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
    966   store volatile i32 %arg2, i32* %e2, align 4
    967 
    968   call void @llvm.va_end(i8* %ap2)
    969 
    970   ret void
    971 }
    972 
    973 define void @fn_i64_dotdotdot_i64(i64 %a, ...) {
    974 entry:
    975 ; ALL-LABEL: fn_i64_dotdotdot_i64:
    976 
    977 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    978 ; the argument save area (56 bytes).
    979 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    980 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    981 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    982 
    983 ; Save variable argument portion on the stack
    984 ; O32-DAG:       sw $7, 20([[SP]])
    985 ; O32-DAG:       sw $6, 16([[SP]])
    986 
    987 ; NEW-DAG:       sd $11, 56([[SP]])
    988 ; NEW-DAG:       sd $10, 48([[SP]])
    989 ; NEW-DAG:       sd $9, 40([[SP]])
    990 ; NEW-DAG:       sd $8, 32([[SP]])
    991 ; NEW-DAG:       sd $7, 24([[SP]])
    992 ; NEW-DAG:       sd $6, 16([[SP]])
    993 ; NEW-DAG:       sd $5, 8([[SP]])
    994 
    995 ; Initialize variable argument pointer.
    996 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
    997 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
    998 ; first fixed argument.
    999 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
   1000 ; space.
   1001 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
   1002 ; O32-DAG:       sw [[VA]], 0([[SP]])
   1003 
   1004 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
   1005 ; N32-DAG:       sw [[VA]], 0([[SP]])
   1006 
   1007 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
   1008 ; N64-DAG:       sd [[VA]], 0([[SP]])
   1009 
   1010 ; Store [[VA]]
   1011 ; O32-DAG:       sw [[VA]], 0([[SP]])
   1012 
   1013 ; ALL: teqi $zero, 1
   1014 
   1015 ; Increment [[VA]] (and realign pointer for O32)
   1016 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
   1017 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
   1018 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
   1019 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
   1020 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
   1021 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1022 
   1023 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
   1024 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
   1025 ; N32-DAG:       sw [[VA2]], 0([[SP]])
   1026 
   1027 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
   1028 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
   1029 ; N64-DAG:       sd [[VA2]], 0([[SP]])
   1030 
   1031 ; Load the first argument from the variable portion and copy it to the global.
   1032 ; This has used the stack pointer directly rather than the [[VA]] we just set
   1033 ; up.
   1034 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
   1035 ; order.
   1036 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
   1037 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
   1038 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
   1039 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
   1040 ; O32-DAG:       sw [[VA3]], 0([[SP]])
   1041 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 4([[VA_TMP2]])
   1042 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
   1043 
   1044 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
   1045 ; N64-DAG:       daddiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
   1046 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
   1047 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
   1048 
   1049 ; ALL: teqi $zero, 2
   1050 
   1051 ; Increment [[VA]] again.
   1052 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
   1053 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
   1054 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
   1055 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
   1056 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
   1057 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1058 
   1059 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
   1060 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
   1061 ; N32-DAG:       sw [[VA3]], 0([[SP]])
   1062 
   1063 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
   1064 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
   1065 ; N64-DAG:       sd [[VA3]], 0([[SP]])
   1066 
   1067 ; Load the second argument from the variable portion and copy it to the global.
   1068 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
   1069 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
   1070 ; O32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 4
   1071 ; O32-DAG:       sw [[VA3]], 0([[SP]])
   1072 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 4([[VA_TMP2]])
   1073 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
   1074 
   1075 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
   1076 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
   1077 
   1078   %ap = alloca i8*, align 8
   1079   %ap2 = bitcast i8** %ap to i8*
   1080   call void @llvm.va_start(i8* %ap2)
   1081 
   1082   call void asm sideeffect "teqi $$zero, 1", ""()
   1083   %arg1 = va_arg i8** %ap, i64
   1084   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
   1085   store volatile i64 %arg1, i64* %e1, align 8
   1086 
   1087   call void asm sideeffect "teqi $$zero, 2", ""()
   1088   %arg2 = va_arg i8** %ap, i64
   1089   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
   1090   store volatile i64 %arg2, i64* %e2, align 8
   1091 
   1092   call void @llvm.va_end(i8* %ap2)
   1093 
   1094   ret void
   1095 }
   1096 
   1097 declare void @llvm.va_start(i8*)
   1098 declare void @llvm.va_end(i8*)
   1099