]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/patches/patch-r262261-llvm-r199028-sparc.diff
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / patches / patch-r262261-llvm-r199028-sparc.diff
1 Pull in r199028 from upstream llvm trunk (by Jakob Stoklund Olesen):
2
3   The SPARCv9 ABI returns a float in %f0.
4
5   This is different from the argument passing convention which puts the
6   first float argument in %f1.
7
8   With this patch, all returned floats are treated as if the 'inreg' flag
9   were set. This means multiple float return values get packed in %f0,
10   %f1, %f2, ...
11
12   Note that when returning a struct in registers, clang will set the
13   'inreg' flag on the return value, so that behavior is unchanged. This
14   also happens when returning a float _Complex.
15
16 Introduced here: http://svnweb.freebsd.org/changeset/base/262261
17
18 Index: test/CodeGen/SPARC/64abi.ll
19 ===================================================================
20 --- test/CodeGen/SPARC/64abi.ll
21 +++ test/CodeGen/SPARC/64abi.ll
22 @@ -180,7 +180,7 @@ define void @call_inreg_fi(i32* %p, i32 %i1, float
23  }
24  
25  ; CHECK: inreg_ff
26 -; CHECK: fsubs %f0, %f1, %f1
27 +; CHECK: fsubs %f0, %f1, %f0
28  define float @inreg_ff(float inreg %a0,   ; %f0
29                         float inreg %a1) { ; %f1
30    %rv = fsub float %a0, %a1
31 @@ -262,10 +262,10 @@ define void @call_ret_i64_pair(i64* %i0) {
32    ret void
33  }
34  
35 -; This is not a C struct, each member uses 8 bytes.
36 +; This is not a C struct, the i32 member uses 8 bytes, but the float only 4.
37  ; CHECK: ret_i32_float_pair
38  ; CHECK: ld [%i2], %i0
39 -; CHECK: ld [%i3], %f3
40 +; CHECK: ld [%i3], %f2
41  define { i32, float } @ret_i32_float_pair(i32 %a0, i32 %a1,
42                                            i32* %p, float* %q) {
43    %r1 = load i32* %p
44 @@ -279,7 +279,7 @@ define { i32, float } @ret_i32_float_pair(i32 %a0,
45  ; CHECK: call_ret_i32_float_pair
46  ; CHECK: call ret_i32_float_pair
47  ; CHECK: st %o0, [%i0]
48 -; CHECK: st %f3, [%i1]
49 +; CHECK: st %f2, [%i1]
50  define void @call_ret_i32_float_pair(i32* %i0, float* %i1) {
51    %rv = call { i32, float } @ret_i32_float_pair(i32 undef, i32 undef,
52                                                  i32* undef, float* undef)
53 Index: test/CodeGen/SPARC/constpool.ll
54 ===================================================================
55 --- test/CodeGen/SPARC/constpool.ll
56 +++ test/CodeGen/SPARC/constpool.ll
57 @@ -21,7 +21,7 @@ entry:
58  ; abs44: add %[[R1]], %m44(.LCPI0_0), %[[R2:[gilo][0-7]]]
59  ; abs44: sllx %[[R2]], 12, %[[R3:[gilo][0-7]]]
60  ; abs44: retl
61 -; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f1
62 +; abs44: ld [%[[R3]]+%l44(.LCPI0_0)], %f0
63  
64  
65  ; abs64: floatCP
66 @@ -31,7 +31,7 @@ entry:
67  ; abs64: add %[[R3]], %hm(.LCPI0_0), %[[R4:[gilo][0-7]]]
68  ; abs64: sllx %[[R4]], 32, %[[R5:[gilo][0-7]]]
69  ; abs64: retl
70 -; abs64: ld [%[[R5]]+%[[R2]]], %f1
71 +; abs64: ld [%[[R5]]+%[[R2]]], %f0
72  
73  
74  ; v8pic32: floatCP
75 @@ -50,7 +50,7 @@ entry:
76  ; v9pic32: sethi %hi(.LCPI0_0), %[[R1:[gilo][0-7]]]
77  ; v9pic32: add %[[R1]], %lo(.LCPI0_0), %[[Goffs:[gilo][0-7]]]
78  ; v9pic32: ldx [%[[GOT:[gilo][0-7]]]+%[[Goffs]]], %[[Gaddr:[gilo][0-7]]]
79 -; v9pic32: ld [%[[Gaddr]]], %f1
80 +; v9pic32: ld [%[[Gaddr]]], %f0
81  ; v9pic32: ret
82  ; v9pic32: restore
83  
84 Index: test/CodeGen/SPARC/64cond.ll
85 ===================================================================
86 --- test/CodeGen/SPARC/64cond.ll
87 +++ test/CodeGen/SPARC/64cond.ll
88 @@ -80,7 +80,7 @@ entry:
89  ; CHECK: selectf32_xcc
90  ; CHECK: cmp %i0, %i1
91  ; CHECK: fmovsg %xcc, %f5, %f7
92 -; CHECK: fmovs %f7, %f1
93 +; CHECK: fmovs %f7, %f0
94  define float @selectf32_xcc(i64 %x, i64 %y, float %a, float %b) {
95  entry:
96    %tobool = icmp sgt i64 %x, %y
97 Index: lib/Target/Sparc/SparcISelLowering.cpp
98 ===================================================================
99 --- lib/Target/Sparc/SparcISelLowering.cpp
100 +++ lib/Target/Sparc/SparcISelLowering.cpp
101 @@ -254,7 +254,7 @@ SparcTargetLowering::LowerReturn_64(SDValue Chain,
102                   DAG.getTarget(), RVLocs, *DAG.getContext());
103  
104    // Analyze return values.
105 -  CCInfo.AnalyzeReturn(Outs, CC_Sparc64);
106 +  CCInfo.AnalyzeReturn(Outs, RetCC_Sparc64);
107  
108    SDValue Flag;
109    SmallVector<SDValue, 4> RetOps(1, Chain);
110 @@ -1258,7 +1258,7 @@ SparcTargetLowering::LowerCall_64(TargetLowering::
111    if (CLI.Ins.size() == 1 && CLI.Ins[0].VT == MVT::f32 && CLI.CS == 0)
112      CLI.Ins[0].Flags.setInReg();
113  
114 -  RVInfo.AnalyzeCallResult(CLI.Ins, CC_Sparc64);
115 +  RVInfo.AnalyzeCallResult(CLI.Ins, RetCC_Sparc64);
116  
117    // Copy all of the result registers out of their specified physreg.
118    for (unsigned i = 0; i != RVLocs.size(); ++i) {
119 Index: lib/Target/Sparc/SparcCallingConv.td
120 ===================================================================
121 --- lib/Target/Sparc/SparcCallingConv.td
122 +++ lib/Target/Sparc/SparcCallingConv.td
123 @@ -103,7 +103,7 @@ def RetCC_Sparc32 : CallingConv<[
124  // Function return values are passed exactly like function arguments, except a
125  // struct up to 32 bytes in size can be returned in registers.
126  
127 -// Function arguments AND return values.
128 +// Function arguments AND most return values.
129  def CC_Sparc64 : CallingConv<[
130    // The frontend uses the inreg flag to indicate i32 and float arguments from
131    // structs. These arguments are not promoted to 64 bits, but they can still
132 @@ -118,6 +118,15 @@ def CC_Sparc64 : CallingConv<[
133    CCCustom<"CC_Sparc64_Full">
134  ]>;
135  
136 +def RetCC_Sparc64 : CallingConv<[
137 +  // A single f32 return value always goes in %f0. The ABI doesn't specify what
138 +  // happens to multiple f32 return values outside a struct.
139 +  CCIfType<[f32], CCCustom<"CC_Sparc64_Half">>,
140 +
141 +  // Otherwise, return values are passed exactly like arguments.
142 +  CCDelegateTo<CC_Sparc64>
143 +]>;
144 +
145  // Callee-saved registers are handled by the register window mechanism.
146  def CSR : CalleeSavedRegs<(add)> {
147    let OtherPreserved = (add (sequence "I%u", 0, 7),