xref: /llvm-project/llvm/test/CodeGen/Mips/cconv/return-hard-struct-f128.ll (revision 8663926a544602932d299dda435ed1ef70a05f48)
1; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
2; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi n32 < %s | FileCheck --check-prefixes=ALL,N32 %s
3
4; RUN: llc -mtriple=mips64-linux-gnu -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
5; RUN: llc -mtriple=mips64el-linux-gnu -relocation-model=static -target-abi n64 < %s | FileCheck --check-prefixes=ALL,N64 %s
6
7; Test return of {fp128} agrees with de-facto N32/N64 ABI.
8
9@struct_fp128 = global {fp128} zeroinitializer
10
11define inreg {fp128} @ret_struct_fp128() nounwind {
12entry:
13        %0 = load volatile {fp128}, ptr @struct_fp128
14        ret {fp128} %0
15}
16
17; ALL-LABEL: ret_struct_fp128:
18
19; O32 generates different IR so we don't test it here. It returns the struct
20; indirectly.
21
22; Contrary to the N32/N64 ABI documentation, a struct containing a long double
23; is returned in $f0, and $f1 instead of the usual $f0, and $f2. This is to
24; match the de facto ABI as implemented by GCC.
25; N32-DAG:        lui [[R1:\$[0-9]+]], %hi(struct_fp128)
26; N32-DAG:        ldc1 $f0, %lo(struct_fp128)([[R1]])
27; N32-DAG:        addiu [[R3:\$[0-9]+]], [[R1]], %lo(struct_fp128)
28; N32-DAG:        ldc1  $f1, 8([[R3]])
29
30; N64-DAG:        lui  [[R1:\$[0-9]+]], %highest(struct_fp128)
31; N64-DAG:        ldc1 $f0, %lo(struct_fp128)([[R1]])
32; N64-DAG:        ldc1 $f1, 8([[R1]])
33