14055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka// RUN: %clang -target mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
24055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka// RUN: %clang -target mips64el-unknown-linux -O3 -S -mabi=n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64
3dda91e0c4b794b1054a6672a6267942ec72d387fAkira Hatanaka// RUN: %clang -target mipsel-unknown-linux -mfp64 -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
4f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
5f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanakatypedef struct {
6f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka  double d;
7f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka  long double ld;
8f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka} S0;
9f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
10a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka// Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries.
11f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
12176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64-LABEL: define void @foo1(i32 signext %a0, i64, double inreg %a1.coerce0, i64 inreg %a1.coerce1, i64 inreg %a1.coerce2, i64 inreg %a1.coerce3, double inreg %a2.coerce0, i64 inreg %a2.coerce1, i64 inreg %a2.coerce2, i64 inreg %a2.coerce3, i32 signext %b, i64, double inreg %a3.coerce0, i64 inreg %a3.coerce1, i64 inreg %a3.coerce2, i64 inreg %a3.coerce3)
13176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: tail call void @foo2(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, double inreg %a1.coerce0, i64 inreg %a1.coerce1, i64 inreg %a1.coerce2, i64 inreg %a1.coerce3, double inreg %a2.coerce0, i64 inreg %a2.coerce1, i64 inreg %a2.coerce2, i64 inreg %a2.coerce3, i32 signext 3, i64 undef, double inreg %a3.coerce0, i64 inreg %a3.coerce1, i64 inreg %a3.coerce2, i64 inreg %a3.coerce3)
14176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: declare void @foo2(i32 signext, i32 signext, i32 signext, i64, double inreg, i64 inreg, i64 inreg, i64 inreg, double inreg, i64 inreg, i64 inreg, i64 inreg, i32 signext, i64, double inreg, i64 inreg, i64 inreg, i64 inreg)
15f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
16f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanakaextern void foo2(int, int, int, S0, S0, int, S0);
17f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
18f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanakavoid foo1(int a0, S0 a1, S0 a2, int b, S0 a3) {
19f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka  foo2(1, 2, a0, a1, a2, 3, a3);
20f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka}
21f0cc2087b18c48b17c2f647c88a3e7eef19285fdAkira Hatanaka
22a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka// Insert padding before long double argument.
23a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka//
24176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64-LABEL: define void @foo3(i32 signext %a0, i64, fp128 %a1)
25176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: tail call void @foo4(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, fp128 %a1)
26176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: declare void @foo4(i32 signext, i32 signext, i32 signext, i64, fp128)
27a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka
28a33fd393d5255716e904fed021f87260095ed00aAkira Hatanakaextern void foo4(int, int, int, long double);
29a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka
30a33fd393d5255716e904fed021f87260095ed00aAkira Hatanakavoid foo3(int a0, long double a1) {
31a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka  foo4(1, 2, a0, a1);
32a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka}
33a33fd393d5255716e904fed021f87260095ed00aAkira Hatanaka
34cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka// Insert padding after hidden argument.
35cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka//
3693ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// N64-LABEL: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0)
37176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: call void @foo6(%struct.S0* sret %agg.result, i32 signext 1, i32 signext 2, i64 undef, fp128 %a0)
38176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// N64: declare void @foo6(%struct.S0* sret, i32 signext, i32 signext, i64, fp128)
39cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka
40cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanakaextern S0 foo6(int, int, long double);
41cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka
42cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira HatanakaS0 foo5(long double a0) {
43e9c876044b7fe9560128a41d511426c014bf5d3fAkira Hatanaka  return foo6(1, 2, a0);
44cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka}
45cc66254946ec86a2ec94ff9c8db96b05a364a94fAkira Hatanaka
464055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka// Do not insert padding if ABI is O32.
474055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka//
4893ab6bf534fb6c26563c00f28a8fc5581bb71dfdStephen Lin// O32-LABEL: define void @foo7(float %a0, double %a1)
494055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka// O32: declare void @foo8(float, double)
504055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka
514055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanakaextern void foo8(float, double);
524055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka
534055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanakavoid foo7(float a0, double a1) {
544055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka  foo8(a0 + 1.0f, a1 + 2.0);
554055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka}
564055cfc46a5beb13d0daeace53ac3fe56a1f4ad1Akira Hatanaka
57550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka// O32-LABEL: define void @foo9()
58176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// O32: declare void @foo10(i32 signext, i32
59550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka
60550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanakatypedef struct __attribute__((aligned(16))) {
61550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka  int a;
62550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka} S16;
63550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka
64550ed2077e11ac183380478769c8ddc932ce3168Akira HatanakaS16 s16;
65550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka
66550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanakavoid foo10(int, S16);
67550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka
68550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanakavoid foo9(void) {
69550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka  foo10(1, s16);
70550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka}
71550ed2077e11ac183380478769c8ddc932ce3168Akira Hatanaka
72