Home | History | Annotate | Download | only in cconv
      1 ; RUN: llc -mtriple=mips-linux -relocation-model=static < %s | FileCheck --check-prefixes=ALL,O32,O32-BE %s
      2 ; RUN: llc -mtriple=mipsel-linux -relocation-model=static < %s | FileCheck --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 --check-prefixes=ALL,NEW,N32,NEW-BE %s
      8 ; RUN: llc -mtriple=mips64el-linux -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,NEW,N32,NEW-LE %s
      9 
     10 ; RUN: llc -march=mips64 -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,NEW,N64,NEW-BE %s
     11 ; RUN: llc -march=mips64el -relocation-model=static -target-abi n64 < %s | FileCheck --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:       ld [[GV:\$[0-9]+]], %got_disp(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:       ld [[GV:\$[0-9]+]], %got_disp(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]])
    319 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
    320 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    321 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    322 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    323 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    324 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
    325 
    326 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    327 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
    328 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
    329 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
    330 
    331 ; ALL: teqi $zero, 2
    332 
    333 ; Increment [[VA]] again.
    334 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
    335 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    336 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    337 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    338 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    339 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    340 
    341 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    342 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    343 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    344 
    345 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    346 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    347 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    348 
    349 ; Load the second argument from the variable portion and copy it to the global.
    350 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    351 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
    352 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    353 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    354 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    355 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    356 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
    357 
    358 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
    359 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
    360 
    361   %ap = alloca i8*, align 8
    362   %ap2 = bitcast i8** %ap to i8*
    363   call void @llvm.va_start(i8* %ap2)
    364 
    365   call void asm sideeffect "teqi $$zero, 1", ""()
    366   %arg1 = va_arg i8** %ap, i64
    367   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
    368   store volatile i64 %arg1, i64* %e1, align 8
    369 
    370   call void asm sideeffect "teqi $$zero, 2", ""()
    371   %arg2 = va_arg i8** %ap, i64
    372   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
    373   store volatile i64 %arg2, i64* %e2, align 8
    374 
    375   call void @llvm.va_end(i8* %ap2)
    376 
    377   ret void
    378 }
    379 
    380 define void @fn_i32_dotdotdot_i16(i32 %a, ...) {
    381 entry:
    382 ; ALL-LABEL: fn_i32_dotdotdot_i16:
    383 
    384 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    385 ; the argument save area (56 bytes).
    386 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    387 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    388 ; N64:           daddiu [[SP:\$sp]], $sp, -64
    389 
    390 ; Save variable argument portion on the stack
    391 ; O32-DAG:       sw $7, 20([[SP]])
    392 ; O32-DAG:       sw $6, 16([[SP]])
    393 ; O32-DAG:       sw $5, 12([[SP]])
    394 
    395 ; NEW-DAG:       sd $11, 56([[SP]])
    396 ; NEW-DAG:       sd $10, 48([[SP]])
    397 ; NEW-DAG:       sd $9, 40([[SP]])
    398 ; NEW-DAG:       sd $8, 32([[SP]])
    399 ; NEW-DAG:       sd $7, 24([[SP]])
    400 ; NEW-DAG:       sd $6, 16([[SP]])
    401 ; NEW-DAG:       sd $5, 8([[SP]])
    402 
    403 ; Initialize variable argument pointer.
    404 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    405 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    406 ; fixed argument.
    407 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    408 ; space.
    409 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    410 ; O32-DAG:       sw [[VA]], 0([[SP]])
    411 
    412 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    413 ; N32-DAG:       sw [[VA]], 0([[SP]])
    414 
    415 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    416 ; N64-DAG:       sd [[VA]], 0([[SP]])
    417 
    418 ; Store [[VA]]
    419 ; O32-DAG:       sw [[VA]], 0([[SP]])
    420 
    421 ; ALL: teqi $zero, 1
    422 
    423 ; Increment [[VA]]
    424 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    425 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    426 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    427 
    428 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    429 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    430 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    431 
    432 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    433 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    434 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    435 
    436 ; Load the first argument from the variable portion.
    437 ; This has used the stack pointer directly rather than the [[VA]] we just set
    438 ; up.
    439 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    440 ; order.
    441 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    442 
    443 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    444 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    445 
    446 ; Copy the arg to the global
    447 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    448 
    449 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    450 
    451 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
    452 
    453 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
    454 
    455 ; ALL: teqi $zero, 2
    456 
    457 ; Increment [[VA]] again.
    458 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    459 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    460 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    461 
    462 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    463 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    464 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    465 
    466 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    467 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    468 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    469 
    470 ; Load the second argument from the variable portion.
    471 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    472 
    473 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    474 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    475 
    476 ; Copy the arg to the global
    477 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
    478 
    479   %ap = alloca i8*, align 8
    480   %ap2 = bitcast i8** %ap to i8*
    481   call void @llvm.va_start(i8* %ap2)
    482 
    483   call void asm sideeffect "teqi $$zero, 1", ""()
    484   %arg1 = va_arg i8** %ap, i16
    485   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
    486   store volatile i16 %arg1, i16* %e1, align 2
    487 
    488   call void asm sideeffect "teqi $$zero, 2", ""()
    489   %arg2 = va_arg i8** %ap, i16
    490   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
    491   store volatile i16 %arg2, i16* %e2, align 2
    492 
    493   call void @llvm.va_end(i8* %ap2)
    494 
    495   ret void
    496 }
    497 
    498 define void @fn_i32_dotdotdot_i32(i32 %a, ...) {
    499 entry:
    500 ; ALL-LABEL: fn_i32_dotdotdot_i32:
    501 
    502 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    503 ; the argument save area (56 bytes).
    504 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    505 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    506 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    507 
    508 ; Save variable argument portion on the stack
    509 ; O32-DAG:       sw $7, 20([[SP]])
    510 ; O32-DAG:       sw $6, 16([[SP]])
    511 ; O32-DAG:       sw $5, 12([[SP]])
    512 
    513 ; NEW-DAG:       sd $11, 56([[SP]])
    514 ; NEW-DAG:       sd $10, 48([[SP]])
    515 ; NEW-DAG:       sd $9, 40([[SP]])
    516 ; NEW-DAG:       sd $8, 32([[SP]])
    517 ; NEW-DAG:       sd $7, 24([[SP]])
    518 ; NEW-DAG:       sd $6, 16([[SP]])
    519 ; NEW-DAG:       sd $5, 8([[SP]])
    520 
    521 ; Initialize variable argument pointer.
    522 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    523 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    524 ; fixed argument.
    525 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    526 ; space.
    527 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    528 ; O32-DAG:       sw [[VA]], 0([[SP]])
    529 
    530 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    531 ; N32-DAG:       sw [[VA]], 0([[SP]])
    532 
    533 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    534 ; N64-DAG:       sd [[VA]], 0([[SP]])
    535 
    536 ; Store [[VA]]
    537 ; O32-DAG:       sw [[VA]], 0([[SP]])
    538 
    539 ; ALL: teqi $zero, 1
    540 
    541 ; Increment [[VA]]
    542 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    543 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    544 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    545 
    546 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    547 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    548 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    549 
    550 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    551 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    552 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    553 
    554 ; Load the first argument from the variable portion.
    555 ; This has used the stack pointer directly rather than the [[VA]] we just set
    556 ; up.
    557 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    558 ; order.
    559 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    560 
    561 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    562 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    563 
    564 ; Copy the arg to the global
    565 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    566 
    567 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    568 
    569 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
    570 
    571 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
    572 
    573 ; ALL: teqi $zero, 2
    574 
    575 ; Increment [[VA]] again.
    576 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    577 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    578 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    579 
    580 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    581 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    582 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    583 
    584 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    585 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    586 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    587 
    588 ; Load the second argument from the variable portion.
    589 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    590 
    591 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    592 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    593 
    594 ; Copy the arg to the global
    595 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
    596 
    597   %ap = alloca i8*, align 8
    598   %ap2 = bitcast i8** %ap to i8*
    599   call void @llvm.va_start(i8* %ap2)
    600 
    601   call void asm sideeffect "teqi $$zero, 1", ""()
    602   %arg1 = va_arg i8** %ap, i32
    603   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
    604   store volatile i32 %arg1, i32* %e1, align 4
    605 
    606   call void asm sideeffect "teqi $$zero, 2", ""()
    607   %arg2 = va_arg i8** %ap, i32
    608   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
    609   store volatile i32 %arg2, i32* %e2, align 4
    610 
    611   call void @llvm.va_end(i8* %ap2)
    612 
    613   ret void
    614 }
    615 
    616 define void @fn_i32_dotdotdot_i64(i32 %a, ...) {
    617 entry:
    618 ; ALL-LABEL: fn_i32_dotdotdot_i64:
    619 
    620 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    621 ; the argument save area (56 bytes).
    622 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    623 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    624 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    625 
    626 ; Save variable argument portion on the stack
    627 ; O32-DAG:       sw $7, 20([[SP]])
    628 ; O32-DAG:       sw $6, 16([[SP]])
    629 ; O32-DAG:       sw $5, 12([[SP]])
    630 
    631 ; NEW-DAG:       sd $11, 56([[SP]])
    632 ; NEW-DAG:       sd $10, 48([[SP]])
    633 ; NEW-DAG:       sd $9, 40([[SP]])
    634 ; NEW-DAG:       sd $8, 32([[SP]])
    635 ; NEW-DAG:       sd $7, 24([[SP]])
    636 ; NEW-DAG:       sd $6, 16([[SP]])
    637 ; NEW-DAG:       sd $5, 8([[SP]])
    638 
    639 ; Initialize variable argument pointer.
    640 ; For O32, the offset is 12 due to the 4 bytes used to store local variables,
    641 ; 4 bytes padding to maintain stack alignment, and the 4 byte slot for the first
    642 ; fixed argument.
    643 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    644 ; space.
    645 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 12
    646 ; O32-DAG:       sw [[VA]], 0([[SP]])
    647 
    648 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    649 ; N32-DAG:       sw [[VA]], 0([[SP]])
    650 
    651 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    652 ; N64-DAG:       sd [[VA]], 0([[SP]])
    653 
    654 ; Store [[VA]]
    655 ; O32-DAG:       sw [[VA]], 0([[SP]])
    656 
    657 ; ALL: teqi $zero, 1
    658 
    659 ; Increment [[VA]] (and realign pointer for O32)
    660 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    661 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    662 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
    663 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    664 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    665 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    666 
    667 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    668 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    669 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    670 
    671 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    672 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    673 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    674 
    675 ; Load the first argument from the variable portion and copy it to the global.
    676 ; This has used the stack pointer directly rather than the [[VA]] we just set
    677 ; up.
    678 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    679 ; order.
    680 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    681 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    682 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
    683 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    684 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    685 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    686 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    687 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
    688 
    689 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
    690 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
    691 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
    692 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
    693 
    694 ; ALL: teqi $zero, 2
    695 
    696 ; Increment [[VA]] again.
    697 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
    698 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
    699 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
    700 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
    701 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
    702 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    703 
    704 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    705 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    706 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    707 
    708 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    709 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    710 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    711 
    712 ; Load the second argument from the variable portion and copy it to the global.
    713 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    714 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
    715 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    716 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    717 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    718 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    719 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
    720 
    721 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
    722 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
    723 
    724   %ap = alloca i8*, align 8
    725   %ap2 = bitcast i8** %ap to i8*
    726   call void @llvm.va_start(i8* %ap2)
    727 
    728   call void asm sideeffect "teqi $$zero, 1", ""()
    729   %arg1 = va_arg i8** %ap, i64
    730   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
    731   store volatile i64 %arg1, i64* %e1, align 8
    732 
    733   call void asm sideeffect "teqi $$zero, 2", ""()
    734   %arg2 = va_arg i8** %ap, i64
    735   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
    736   store volatile i64 %arg2, i64* %e2, align 8
    737 
    738   call void @llvm.va_end(i8* %ap2)
    739 
    740   ret void
    741 }
    742 
    743 define void @fn_i64_dotdotdot_i16(i64 %a, ...) {
    744 entry:
    745 ; ALL-LABEL: fn_i64_dotdotdot_i16:
    746 
    747 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    748 ; the argument save area (56 bytes).
    749 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    750 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    751 ; N64:           daddiu [[SP:\$sp]], $sp, -64
    752 
    753 ; Save variable argument portion on the stack
    754 ; O32-DAG:       sw $7, 20([[SP]])
    755 ; O32-DAG:       sw $6, 16([[SP]])
    756 
    757 ; NEW-DAG:       sd $11, 56([[SP]])
    758 ; NEW-DAG:       sd $10, 48([[SP]])
    759 ; NEW-DAG:       sd $9, 40([[SP]])
    760 ; NEW-DAG:       sd $8, 32([[SP]])
    761 ; NEW-DAG:       sd $7, 24([[SP]])
    762 ; NEW-DAG:       sd $6, 16([[SP]])
    763 ; NEW-DAG:       sd $5, 8([[SP]])
    764 
    765 ; Initialize variable argument pointer.
    766 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
    767 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
    768 ; first fixed argument.
    769 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    770 ; space.
    771 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
    772 ; O32-DAG:       sw [[VA]], 0([[SP]])
    773 
    774 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    775 ; N32-DAG:       sw [[VA]], 0([[SP]])
    776 
    777 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    778 ; N64-DAG:       sd [[VA]], 0([[SP]])
    779 
    780 ; Store [[VA]]
    781 ; O32-DAG:       sw [[VA]], 0([[SP]])
    782 
    783 ; ALL: teqi $zero, 1
    784 
    785 ; Increment [[VA]]
    786 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    787 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    788 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    789 
    790 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    791 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    792 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    793 
    794 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    795 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    796 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    797 
    798 ; Load the first argument from the variable portion.
    799 ; This has used the stack pointer directly rather than the [[VA]] we just set
    800 ; up.
    801 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    802 ; order.
    803 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    804 
    805 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    806 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    807 
    808 ; Copy the arg to the global
    809 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    810 
    811 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(hwords)
    812 
    813 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(hwords)(
    814 
    815 ; ALL-DAG:       sh [[ARG1]], 2([[GV]])
    816 
    817 ; ALL: teqi $zero, 2
    818 
    819 ; Increment [[VA]] again.
    820 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    821 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    822 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    823 
    824 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    825 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    826 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    827 
    828 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    829 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    830 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    831 
    832 ; Load the second argument from the variable portion.
    833 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    834 
    835 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    836 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    837 
    838 ; Copy the arg to the global
    839 ; ALL-DAG:       sh [[ARG2]], 4([[GV]])
    840 
    841   %ap = alloca i8*, align 8
    842   %ap2 = bitcast i8** %ap to i8*
    843   call void @llvm.va_start(i8* %ap2)
    844 
    845   call void asm sideeffect "teqi $$zero, 1", ""()
    846   %arg1 = va_arg i8** %ap, i16
    847   %e1 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 1
    848   store volatile i16 %arg1, i16* %e1, align 2
    849 
    850   call void asm sideeffect "teqi $$zero, 2", ""()
    851   %arg2 = va_arg i8** %ap, i16
    852   %e2 = getelementptr [3 x i16], [3 x i16]* @hwords, i32 0, i32 2
    853   store volatile i16 %arg2, i16* %e2, align 2
    854 
    855   call void @llvm.va_end(i8* %ap2)
    856 
    857   ret void
    858 }
    859 
    860 define void @fn_i64_dotdotdot_i32(i64 %a, ...) {
    861 entry:
    862 ; ALL-LABEL: fn_i64_dotdotdot_i32:
    863 
    864 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    865 ; the argument save area (56 bytes).
    866 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    867 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    868 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    869 
    870 ; Save variable argument portion on the stack
    871 ; O32-DAG:       sw $7, 20([[SP]])
    872 ; O32-DAG:       sw $6, 16([[SP]])
    873 
    874 ; NEW-DAG:       sd $11, 56([[SP]])
    875 ; NEW-DAG:       sd $10, 48([[SP]])
    876 ; NEW-DAG:       sd $9, 40([[SP]])
    877 ; NEW-DAG:       sd $8, 32([[SP]])
    878 ; NEW-DAG:       sd $7, 24([[SP]])
    879 ; NEW-DAG:       sd $6, 16([[SP]])
    880 ; NEW-DAG:       sd $5, 8([[SP]])
    881 
    882 ; Initialize variable argument pointer.
    883 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
    884 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
    885 ; first fixed argument.
    886 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
    887 ; space.
    888 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
    889 ; O32-DAG:       sw [[VA]], 0([[SP]])
    890 
    891 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
    892 ; N32-DAG:       sw [[VA]], 0([[SP]])
    893 
    894 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
    895 ; N64-DAG:       sd [[VA]], 0([[SP]])
    896 
    897 ; Store [[VA]]
    898 ; O32-DAG:       sw [[VA]], 0([[SP]])
    899 
    900 ; ALL: teqi $zero, 1
    901 
    902 ; Increment [[VA]]
    903 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    904 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    905 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    906 
    907 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    908 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    909 ; N32-DAG:       sw [[VA2]], 0([[SP]])
    910 
    911 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
    912 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
    913 ; N64-DAG:       sd [[VA2]], 0([[SP]])
    914 
    915 ; Load the first argument from the variable portion.
    916 ; This has used the stack pointer directly rather than the [[VA]] we just set
    917 ; up.
    918 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
    919 ; order.
    920 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
    921 
    922 ; NEW-LE-DAG:    lw [[ARG1:\$[0-9]+]], 0([[VA]])
    923 ; NEW-BE-DAG:    lw [[ARG1:\$[0-9]+]], 4([[VA]])
    924 
    925 ; Copy the arg to the global
    926 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    927 
    928 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(words)
    929 
    930 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(words)(
    931 
    932 ; ALL-DAG:       sw [[ARG1]], 4([[GV]])
    933 
    934 ; ALL: teqi $zero, 2
    935 
    936 ; Increment [[VA]] again.
    937 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
    938 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
    939 ; O32-DAG:       sw [[VA2]], 0([[SP]])
    940 
    941 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
    942 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
    943 ; N32-DAG:       sw [[VA3]], 0([[SP]])
    944 
    945 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
    946 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
    947 ; N64-DAG:       sd [[VA3]], 0([[SP]])
    948 
    949 ; Load the second argument from the variable portion.
    950 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
    951 
    952 ; NEW-LE-DAG:    lw [[ARG2:\$[0-9]+]], 0([[VA2]])
    953 ; NEW-BE-DAG:    lw [[ARG2:\$[0-9]+]], 4([[VA2]])
    954 
    955 ; Copy the arg to the global
    956 ; ALL-DAG:       sw [[ARG2]], 8([[GV]])
    957 
    958   %ap = alloca i8*, align 8
    959   %ap2 = bitcast i8** %ap to i8*
    960   call void @llvm.va_start(i8* %ap2)
    961 
    962   call void asm sideeffect "teqi $$zero, 1", ""()
    963   %arg1 = va_arg i8** %ap, i32
    964   %e1 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 1
    965   store volatile i32 %arg1, i32* %e1, align 4
    966 
    967   call void asm sideeffect "teqi $$zero, 2", ""()
    968   %arg2 = va_arg i8** %ap, i32
    969   %e2 = getelementptr [3 x i32], [3 x i32]* @words, i32 0, i32 2
    970   store volatile i32 %arg2, i32* %e2, align 4
    971 
    972   call void @llvm.va_end(i8* %ap2)
    973 
    974   ret void
    975 }
    976 
    977 define void @fn_i64_dotdotdot_i64(i64 %a, ...) {
    978 entry:
    979 ; ALL-LABEL: fn_i64_dotdotdot_i64:
    980 
    981 ; Set up the stack with an 8-byte local area. N32/N64 must also make room for
    982 ; the argument save area (56 bytes).
    983 ; O32:           addiu  [[SP:\$sp]], $sp, -8
    984 ; N32:           addiu  [[SP:\$sp]], $sp, -64
    985 ; N64:           daddiu  [[SP:\$sp]], $sp, -64
    986 
    987 ; Save variable argument portion on the stack
    988 ; O32-DAG:       sw $7, 20([[SP]])
    989 ; O32-DAG:       sw $6, 16([[SP]])
    990 
    991 ; NEW-DAG:       sd $11, 56([[SP]])
    992 ; NEW-DAG:       sd $10, 48([[SP]])
    993 ; NEW-DAG:       sd $9, 40([[SP]])
    994 ; NEW-DAG:       sd $8, 32([[SP]])
    995 ; NEW-DAG:       sd $7, 24([[SP]])
    996 ; NEW-DAG:       sd $6, 16([[SP]])
    997 ; NEW-DAG:       sd $5, 8([[SP]])
    998 
    999 ; Initialize variable argument pointer.
   1000 ; For O32, the offset is 16 due to the 4 bytes used to store local variables,
   1001 ; 4 bytes padding to maintain stack alignment, and the two 4 byte slots for the
   1002 ; first fixed argument.
   1003 ; For N32/N64, it is only 8 since the fixed arguments do not reserve stack
   1004 ; space.
   1005 ; O32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 16
   1006 ; O32-DAG:       sw [[VA]], 0([[SP]])
   1007 
   1008 ; N32-DAG:       addiu [[VA:\$[0-9]+]], [[SP]], 8
   1009 ; N32-DAG:       sw [[VA]], 0([[SP]])
   1010 
   1011 ; N64-DAG:       daddiu [[VA:\$[0-9]+]], [[SP]], 8
   1012 ; N64-DAG:       sd [[VA]], 0([[SP]])
   1013 
   1014 ; Store [[VA]]
   1015 ; O32-DAG:       sw [[VA]], 0([[SP]])
   1016 
   1017 ; ALL: teqi $zero, 1
   1018 
   1019 ; Increment [[VA]] (and realign pointer for O32)
   1020 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
   1021 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
   1022 ; O32-DAG:       addiu [[VA_TMP1:\$[0-9]+]], $zero, -8
   1023 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
   1024 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
   1025 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1026 
   1027 ; N32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
   1028 ; N32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
   1029 ; N32-DAG:       sw [[VA2]], 0([[SP]])
   1030 
   1031 ; N64-DAG:       ld [[VA:\$[0-9]+]], 0([[SP]])
   1032 ; N64-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 8
   1033 ; N64-DAG:       sd [[VA2]], 0([[SP]])
   1034 
   1035 ; Load the first argument from the variable portion and copy it to the global.
   1036 ; This has used the stack pointer directly rather than the [[VA]] we just set
   1037 ; up.
   1038 ; Big-endian mode for N32/N64 must add an additional 4 to the offset due to byte
   1039 ; order.
   1040 ; O32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
   1041 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
   1042 ; O32-DAG:       sw [[ARG1]], 8([[GV]])
   1043 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
   1044 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
   1045 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1046 ; O32-DAG:       lw [[ARG1:\$[0-9]+]], 0([[VA]])
   1047 ; O32-DAG:       sw [[ARG1]], 12([[GV]])
   1048 
   1049 ; N32-DAG:       addiu [[GV:\$[0-9]+]], ${{[0-9]+}}, %lo(dwords)
   1050 ; N64-DAG:       ld [[GV:\$[0-9]+]], %got_disp(dwords)(
   1051 ; NEW-DAG:       ld [[ARG1:\$[0-9]+]], 0([[VA]])
   1052 ; NEW-DAG:       sd [[ARG1]], 8([[GV]])
   1053 
   1054 ; ALL: teqi $zero, 2
   1055 
   1056 ; Increment [[VA]] again.
   1057 ; FIXME: We're still aligned from the last one but CodeGen doesn't spot that.
   1058 ; O32:           lw [[VA:\$[0-9]+]], 0([[SP]])
   1059 ; O32-DAG:       addiu [[VA_TMP0:\$[0-9]+]], [[VA]], 7
   1060 ; O32-DAG:       and   [[VA_TMP2:\$[0-9]+]], [[VA_TMP0]], [[VA_TMP1]]
   1061 ; O32-DAG:       ori   [[VA2:\$[0-9]+]], [[VA_TMP2]], 4
   1062 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1063 
   1064 ; N32-DAG:       lw [[VA2:\$[0-9]+]], 0([[SP]])
   1065 ; N32-DAG:       addiu [[VA3:\$[0-9]+]], [[VA2]], 8
   1066 ; N32-DAG:       sw [[VA3]], 0([[SP]])
   1067 
   1068 ; N64-DAG:       ld [[VA2:\$[0-9]+]], 0([[SP]])
   1069 ; N64-DAG:       daddiu [[VA3:\$[0-9]+]], [[VA2]], 8
   1070 ; N64-DAG:       sd [[VA3]], 0([[SP]])
   1071 
   1072 ; Load the second argument from the variable portion and copy it to the global.
   1073 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
   1074 ; O32-DAG:       sw [[ARG2]], 16([[GV]])
   1075 ; O32-DAG:       lw [[VA:\$[0-9]+]], 0([[SP]])
   1076 ; O32-DAG:       addiu [[VA2:\$[0-9]+]], [[VA]], 4
   1077 ; O32-DAG:       sw [[VA2]], 0([[SP]])
   1078 ; O32-DAG:       lw [[ARG2:\$[0-9]+]], 0([[VA]])
   1079 ; O32-DAG:       sw [[ARG2]], 20([[GV]])
   1080 
   1081 ; NEW-DAG:       ld [[ARG2:\$[0-9]+]], 0([[VA2]])
   1082 ; NEW-DAG:       sd [[ARG2]], 16([[GV]])
   1083 
   1084   %ap = alloca i8*, align 8
   1085   %ap2 = bitcast i8** %ap to i8*
   1086   call void @llvm.va_start(i8* %ap2)
   1087 
   1088   call void asm sideeffect "teqi $$zero, 1", ""()
   1089   %arg1 = va_arg i8** %ap, i64
   1090   %e1 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 1
   1091   store volatile i64 %arg1, i64* %e1, align 8
   1092 
   1093   call void asm sideeffect "teqi $$zero, 2", ""()
   1094   %arg2 = va_arg i8** %ap, i64
   1095   %e2 = getelementptr [3 x i64], [3 x i64]* @dwords, i32 0, i32 2
   1096   store volatile i64 %arg2, i64* %e2, align 8
   1097 
   1098   call void @llvm.va_end(i8* %ap2)
   1099 
   1100   ret void
   1101 }
   1102 
   1103 declare void @llvm.va_start(i8*)
   1104 declare void @llvm.va_end(i8*)
   1105