OLD | NEW |
1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// | 1 //===- subzero/src/IceTargetLoweringX8632.cpp - x86-32 lowering -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the TargetLoweringX8632 class, which | 10 // This file implements the TargetLoweringX8632 class, which |
(...skipping 1324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 // variant to avoid liveness problems. T_3 doesn't need special | 1335 // variant to avoid liveness problems. T_3 doesn't need special |
1336 // treatment because it is reassigned via _sar instead of _mov. | 1336 // treatment because it is reassigned via _sar instead of _mov. |
1337 _mov_nonkillable(T_2, T_3); | 1337 _mov_nonkillable(T_2, T_3); |
1338 _sar(T_3, SignExtend); | 1338 _sar(T_3, SignExtend); |
1339 Context.insert(Label); | 1339 Context.insert(Label); |
1340 _mov(DestLo, T_2); | 1340 _mov(DestLo, T_2); |
1341 _mov(DestHi, T_3); | 1341 _mov(DestHi, T_3); |
1342 } break; | 1342 } break; |
1343 case InstArithmetic::Udiv: { | 1343 case InstArithmetic::Udiv: { |
1344 const SizeT MaxSrcs = 2; | 1344 const SizeT MaxSrcs = 2; |
1345 InstCall *Call = makeHelperCall("__udivdi3", Dest, MaxSrcs); | 1345 InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs); |
1346 Call->addArg(Inst->getSrc(0)); | 1346 Call->addArg(Inst->getSrc(0)); |
1347 Call->addArg(Inst->getSrc(1)); | 1347 Call->addArg(Inst->getSrc(1)); |
1348 lowerCall(Call); | 1348 lowerCall(Call); |
1349 } break; | 1349 } break; |
1350 case InstArithmetic::Sdiv: { | 1350 case InstArithmetic::Sdiv: { |
1351 const SizeT MaxSrcs = 2; | 1351 const SizeT MaxSrcs = 2; |
1352 InstCall *Call = makeHelperCall("__divdi3", Dest, MaxSrcs); | 1352 InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs); |
1353 Call->addArg(Inst->getSrc(0)); | 1353 Call->addArg(Inst->getSrc(0)); |
1354 Call->addArg(Inst->getSrc(1)); | 1354 Call->addArg(Inst->getSrc(1)); |
1355 lowerCall(Call); | 1355 lowerCall(Call); |
1356 } break; | 1356 } break; |
1357 case InstArithmetic::Urem: { | 1357 case InstArithmetic::Urem: { |
1358 const SizeT MaxSrcs = 2; | 1358 const SizeT MaxSrcs = 2; |
1359 InstCall *Call = makeHelperCall("__umoddi3", Dest, MaxSrcs); | 1359 InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs); |
1360 Call->addArg(Inst->getSrc(0)); | 1360 Call->addArg(Inst->getSrc(0)); |
1361 Call->addArg(Inst->getSrc(1)); | 1361 Call->addArg(Inst->getSrc(1)); |
1362 lowerCall(Call); | 1362 lowerCall(Call); |
1363 } break; | 1363 } break; |
1364 case InstArithmetic::Srem: { | 1364 case InstArithmetic::Srem: { |
1365 const SizeT MaxSrcs = 2; | 1365 const SizeT MaxSrcs = 2; |
1366 InstCall *Call = makeHelperCall("__moddi3", Dest, MaxSrcs); | 1366 InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs); |
1367 Call->addArg(Inst->getSrc(0)); | 1367 Call->addArg(Inst->getSrc(0)); |
1368 Call->addArg(Inst->getSrc(1)); | 1368 Call->addArg(Inst->getSrc(1)); |
1369 lowerCall(Call); | 1369 lowerCall(Call); |
1370 } break; | 1370 } break; |
1371 case InstArithmetic::Fadd: | 1371 case InstArithmetic::Fadd: |
1372 case InstArithmetic::Fsub: | 1372 case InstArithmetic::Fsub: |
1373 case InstArithmetic::Fmul: | 1373 case InstArithmetic::Fmul: |
1374 case InstArithmetic::Fdiv: | 1374 case InstArithmetic::Fdiv: |
1375 case InstArithmetic::Frem: | 1375 case InstArithmetic::Frem: |
1376 llvm_unreachable("FP instruction with i64 type"); | 1376 llvm_unreachable("FP instruction with i64 type"); |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1657 _mov(Dest, T); | 1657 _mov(Dest, T); |
1658 break; | 1658 break; |
1659 case InstArithmetic::Fdiv: | 1659 case InstArithmetic::Fdiv: |
1660 _mov(T, Src0); | 1660 _mov(T, Src0); |
1661 _divss(T, Src1); | 1661 _divss(T, Src1); |
1662 _mov(Dest, T); | 1662 _mov(Dest, T); |
1663 break; | 1663 break; |
1664 case InstArithmetic::Frem: { | 1664 case InstArithmetic::Frem: { |
1665 const SizeT MaxSrcs = 2; | 1665 const SizeT MaxSrcs = 2; |
1666 Type Ty = Dest->getType(); | 1666 Type Ty = Dest->getType(); |
1667 InstCall *Call = makeHelperCall( | 1667 InstCall *Call = |
1668 isFloat32Asserting32Or64(Ty) ? "fmodf" : "fmod", Dest, MaxSrcs); | 1668 makeHelperCall(isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64, |
| 1669 Dest, MaxSrcs); |
1669 Call->addArg(Src0); | 1670 Call->addArg(Src0); |
1670 Call->addArg(Src1); | 1671 Call->addArg(Src1); |
1671 return lowerCall(Call); | 1672 return lowerCall(Call); |
1672 } break; | 1673 } break; |
1673 } | 1674 } |
1674 } | 1675 } |
1675 } | 1676 } |
1676 | 1677 |
1677 void TargetX8632::lowerAssign(const InstAssign *Inst) { | 1678 void TargetX8632::lowerAssign(const InstAssign *Inst) { |
1678 Variable *Dest = Inst->getDest(); | 1679 Variable *Dest = Inst->getDest(); |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2090 } else if (Dest->getType() == IceType_i64) { | 2091 } else if (Dest->getType() == IceType_i64) { |
2091 // Use a helper for converting floating-point values to 64-bit | 2092 // Use a helper for converting floating-point values to 64-bit |
2092 // integers. SSE2 appears to have no way to convert from xmm | 2093 // integers. SSE2 appears to have no way to convert from xmm |
2093 // registers to something like the edx:eax register pair, and | 2094 // registers to something like the edx:eax register pair, and |
2094 // gcc and clang both want to use x87 instructions complete with | 2095 // gcc and clang both want to use x87 instructions complete with |
2095 // temporary manipulation of the status word. This helper is | 2096 // temporary manipulation of the status word. This helper is |
2096 // not needed for x86-64. | 2097 // not needed for x86-64. |
2097 split64(Dest); | 2098 split64(Dest); |
2098 const SizeT MaxSrcs = 1; | 2099 const SizeT MaxSrcs = 1; |
2099 Type SrcType = Inst->getSrc(0)->getType(); | 2100 Type SrcType = Inst->getSrc(0)->getType(); |
2100 InstCall *Call = makeHelperCall( | 2101 InstCall *Call = |
2101 isFloat32Asserting32Or64(SrcType) ? "cvtftosi64" : "cvtdtosi64", Dest, | 2102 makeHelperCall(isFloat32Asserting32Or64(SrcType) ? H_fptosi_f32_i64 |
2102 MaxSrcs); | 2103 : H_fptosi_f64_i64, |
2103 // TODO: Call the correct compiler-rt helper function. | 2104 Dest, MaxSrcs); |
2104 Call->addArg(Inst->getSrc(0)); | 2105 Call->addArg(Inst->getSrc(0)); |
2105 lowerCall(Call); | 2106 lowerCall(Call); |
2106 } else { | 2107 } else { |
2107 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2108 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2108 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2109 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2109 Variable *T_1 = makeReg(IceType_i32); | 2110 Variable *T_1 = makeReg(IceType_i32); |
2110 Variable *T_2 = makeReg(Dest->getType()); | 2111 Variable *T_2 = makeReg(Dest->getType()); |
2111 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); | 2112 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); |
2112 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2113 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2113 if (Dest->getType() == IceType_i1) | 2114 if (Dest->getType() == IceType_i1) |
2114 _and(T_2, Ctx->getConstantInt1(1)); | 2115 _and(T_2, Ctx->getConstantInt1(1)); |
2115 _mov(Dest, T_2); | 2116 _mov(Dest, T_2); |
2116 } | 2117 } |
2117 break; | 2118 break; |
2118 case InstCast::Fptoui: | 2119 case InstCast::Fptoui: |
2119 if (isVectorType(Dest->getType())) { | 2120 if (isVectorType(Dest->getType())) { |
2120 assert(Dest->getType() == IceType_v4i32 && | 2121 assert(Dest->getType() == IceType_v4i32 && |
2121 Inst->getSrc(0)->getType() == IceType_v4f32); | 2122 Inst->getSrc(0)->getType() == IceType_v4f32); |
2122 const SizeT MaxSrcs = 1; | 2123 const SizeT MaxSrcs = 1; |
2123 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); | 2124 InstCall *Call = makeHelperCall(H_fptoui_4xi32_f32, Dest, MaxSrcs); |
2124 Call->addArg(Inst->getSrc(0)); | 2125 Call->addArg(Inst->getSrc(0)); |
2125 lowerCall(Call); | 2126 lowerCall(Call); |
2126 } else if (Dest->getType() == IceType_i64 || | 2127 } else if (Dest->getType() == IceType_i64 || |
2127 Dest->getType() == IceType_i32) { | 2128 Dest->getType() == IceType_i32) { |
2128 // Use a helper for both x86-32 and x86-64. | 2129 // Use a helper for both x86-32 and x86-64. |
2129 split64(Dest); | 2130 split64(Dest); |
2130 const SizeT MaxSrcs = 1; | 2131 const SizeT MaxSrcs = 1; |
2131 Type DestType = Dest->getType(); | 2132 Type DestType = Dest->getType(); |
2132 Type SrcType = Inst->getSrc(0)->getType(); | 2133 Type SrcType = Inst->getSrc(0)->getType(); |
2133 IceString DstSubstring = (isInt32Asserting32Or64(DestType) ? "32" : "64"); | 2134 IceString TargetString; |
2134 IceString SrcSubstring = (isFloat32Asserting32Or64(SrcType) ? "f" : "d"); | 2135 if (isInt32Asserting32Or64(DestType)) { |
2135 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 | 2136 TargetString = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i32 |
2136 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; | 2137 : H_fptoui_f64_i32; |
2137 // TODO: Call the correct compiler-rt helper function. | 2138 } else { |
| 2139 TargetString = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64 |
| 2140 : H_fptoui_f64_i64; |
| 2141 } |
2138 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 2142 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
2139 Call->addArg(Inst->getSrc(0)); | 2143 Call->addArg(Inst->getSrc(0)); |
2140 lowerCall(Call); | 2144 lowerCall(Call); |
2141 return; | 2145 return; |
2142 } else { | 2146 } else { |
2143 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2147 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2144 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type | 2148 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type |
2145 Variable *T_1 = makeReg(IceType_i32); | 2149 Variable *T_1 = makeReg(IceType_i32); |
2146 Variable *T_2 = makeReg(Dest->getType()); | 2150 Variable *T_2 = makeReg(Dest->getType()); |
2147 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); | 2151 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); |
2148 _mov(T_2, T_1); // T_1 and T_2 may have different integer types | 2152 _mov(T_2, T_1); // T_1 and T_2 may have different integer types |
2149 if (Dest->getType() == IceType_i1) | 2153 if (Dest->getType() == IceType_i1) |
2150 _and(T_2, Ctx->getConstantInt1(1)); | 2154 _and(T_2, Ctx->getConstantInt1(1)); |
2151 _mov(Dest, T_2); | 2155 _mov(Dest, T_2); |
2152 } | 2156 } |
2153 break; | 2157 break; |
2154 case InstCast::Sitofp: | 2158 case InstCast::Sitofp: |
2155 if (isVectorType(Dest->getType())) { | 2159 if (isVectorType(Dest->getType())) { |
2156 assert(Dest->getType() == IceType_v4f32 && | 2160 assert(Dest->getType() == IceType_v4f32 && |
2157 Inst->getSrc(0)->getType() == IceType_v4i32); | 2161 Inst->getSrc(0)->getType() == IceType_v4i32); |
2158 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2162 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2159 Variable *T = makeReg(Dest->getType()); | 2163 Variable *T = makeReg(Dest->getType()); |
2160 _cvt(T, Src0RM, InstX8632Cvt::Dq2ps); | 2164 _cvt(T, Src0RM, InstX8632Cvt::Dq2ps); |
2161 _movp(Dest, T); | 2165 _movp(Dest, T); |
2162 } else if (Inst->getSrc(0)->getType() == IceType_i64) { | 2166 } else if (Inst->getSrc(0)->getType() == IceType_i64) { |
2163 // Use a helper for x86-32. | 2167 // Use a helper for x86-32. |
2164 const SizeT MaxSrcs = 1; | 2168 const SizeT MaxSrcs = 1; |
2165 Type DestType = Dest->getType(); | 2169 Type DestType = Dest->getType(); |
2166 InstCall *Call = makeHelperCall( | 2170 InstCall *Call = |
2167 isFloat32Asserting32Or64(DestType) ? "cvtsi64tof" : "cvtsi64tod", | 2171 makeHelperCall(isFloat32Asserting32Or64(DestType) ? H_sitofp_i64_f32 |
2168 Dest, MaxSrcs); | 2172 : H_sitofp_i64_f64, |
| 2173 Dest, MaxSrcs); |
2169 // TODO: Call the correct compiler-rt helper function. | 2174 // TODO: Call the correct compiler-rt helper function. |
2170 Call->addArg(Inst->getSrc(0)); | 2175 Call->addArg(Inst->getSrc(0)); |
2171 lowerCall(Call); | 2176 lowerCall(Call); |
2172 return; | 2177 return; |
2173 } else { | 2178 } else { |
2174 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); | 2179 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); |
2175 // Sign-extend the operand. | 2180 // Sign-extend the operand. |
2176 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2181 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
2177 Variable *T_1 = makeReg(IceType_i32); | 2182 Variable *T_1 = makeReg(IceType_i32); |
2178 Variable *T_2 = makeReg(Dest->getType()); | 2183 Variable *T_2 = makeReg(Dest->getType()); |
2179 if (Src0RM->getType() == IceType_i32) | 2184 if (Src0RM->getType() == IceType_i32) |
2180 _mov(T_1, Src0RM); | 2185 _mov(T_1, Src0RM); |
2181 else | 2186 else |
2182 _movsx(T_1, Src0RM); | 2187 _movsx(T_1, Src0RM); |
2183 _cvt(T_2, T_1, InstX8632Cvt::Si2ss); | 2188 _cvt(T_2, T_1, InstX8632Cvt::Si2ss); |
2184 _mov(Dest, T_2); | 2189 _mov(Dest, T_2); |
2185 } | 2190 } |
2186 break; | 2191 break; |
2187 case InstCast::Uitofp: { | 2192 case InstCast::Uitofp: { |
2188 Operand *Src0 = Inst->getSrc(0); | 2193 Operand *Src0 = Inst->getSrc(0); |
2189 if (isVectorType(Src0->getType())) { | 2194 if (isVectorType(Src0->getType())) { |
2190 assert(Dest->getType() == IceType_v4f32 && | 2195 assert(Dest->getType() == IceType_v4f32 && |
2191 Src0->getType() == IceType_v4i32); | 2196 Src0->getType() == IceType_v4i32); |
2192 const SizeT MaxSrcs = 1; | 2197 const SizeT MaxSrcs = 1; |
2193 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs); | 2198 InstCall *Call = makeHelperCall(H_uitofp_4xi32_4xf32, Dest, MaxSrcs); |
2194 Call->addArg(Src0); | 2199 Call->addArg(Src0); |
2195 lowerCall(Call); | 2200 lowerCall(Call); |
2196 } else if (Src0->getType() == IceType_i64 || | 2201 } else if (Src0->getType() == IceType_i64 || |
2197 Src0->getType() == IceType_i32) { | 2202 Src0->getType() == IceType_i32) { |
2198 // Use a helper for x86-32 and x86-64. Also use a helper for | 2203 // Use a helper for x86-32 and x86-64. Also use a helper for |
2199 // i32 on x86-32. | 2204 // i32 on x86-32. |
2200 const SizeT MaxSrcs = 1; | 2205 const SizeT MaxSrcs = 1; |
2201 Type DestType = Dest->getType(); | 2206 Type DestType = Dest->getType(); |
2202 IceString SrcSubstring = | 2207 IceString TargetString; |
2203 (isInt32Asserting32Or64(Src0->getType()) ? "32" : "64"); | 2208 if (isInt32Asserting32Or64(Src0->getType())) { |
2204 IceString DstSubstring = (isFloat32Asserting32Or64(DestType) ? "f" : "d"); | 2209 TargetString = isFloat32Asserting32Or64(DestType) ? H_uitofp_i32_f32 |
2205 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod | 2210 : H_uitofp_i32_f64; |
2206 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; | 2211 } else { |
2207 // TODO: Call the correct compiler-rt helper function. | 2212 TargetString = isFloat32Asserting32Or64(DestType) ? H_uitofp_i64_f32 |
| 2213 : H_uitofp_i64_f64; |
| 2214 } |
2208 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); | 2215 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); |
2209 Call->addArg(Src0); | 2216 Call->addArg(Src0); |
2210 lowerCall(Call); | 2217 lowerCall(Call); |
2211 return; | 2218 return; |
2212 } else { | 2219 } else { |
2213 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2220 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
2214 // Zero-extend the operand. | 2221 // Zero-extend the operand. |
2215 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 | 2222 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 |
2216 Variable *T_1 = makeReg(IceType_i32); | 2223 Variable *T_1 = makeReg(IceType_i32); |
2217 Variable *T_2 = makeReg(Dest->getType()); | 2224 Variable *T_2 = makeReg(Dest->getType()); |
(...skipping 11 matching lines...) Expand all Loading... |
2229 if (Dest->getType() == Src0->getType()) { | 2236 if (Dest->getType() == Src0->getType()) { |
2230 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); | 2237 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); |
2231 lowerAssign(Assign); | 2238 lowerAssign(Assign); |
2232 return; | 2239 return; |
2233 } | 2240 } |
2234 switch (Dest->getType()) { | 2241 switch (Dest->getType()) { |
2235 default: | 2242 default: |
2236 llvm_unreachable("Unexpected Bitcast dest type"); | 2243 llvm_unreachable("Unexpected Bitcast dest type"); |
2237 case IceType_i8: { | 2244 case IceType_i8: { |
2238 assert(Src0->getType() == IceType_v8i1); | 2245 assert(Src0->getType() == IceType_v8i1); |
2239 InstCall *Call = makeHelperCall("Sz_bitcast_v8i1_to_i8", Dest, 1); | 2246 InstCall *Call = makeHelperCall(H_bitcast_8xi1_i8, Dest, 1); |
2240 Call->addArg(Src0); | 2247 Call->addArg(Src0); |
2241 lowerCall(Call); | 2248 lowerCall(Call); |
2242 } break; | 2249 } break; |
2243 case IceType_i16: { | 2250 case IceType_i16: { |
2244 assert(Src0->getType() == IceType_v16i1); | 2251 assert(Src0->getType() == IceType_v16i1); |
2245 InstCall *Call = makeHelperCall("Sz_bitcast_v16i1_to_i16", Dest, 1); | 2252 InstCall *Call = makeHelperCall(H_bitcast_16xi1_i16, Dest, 1); |
2246 Call->addArg(Src0); | 2253 Call->addArg(Src0); |
2247 lowerCall(Call); | 2254 lowerCall(Call); |
2248 } break; | 2255 } break; |
2249 case IceType_i32: | 2256 case IceType_i32: |
2250 case IceType_f32: { | 2257 case IceType_f32: { |
2251 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | 2258 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); |
2252 Type DestType = Dest->getType(); | 2259 Type DestType = Dest->getType(); |
2253 Type SrcType = Src0RM->getType(); | 2260 Type SrcType = Src0RM->getType(); |
2254 (void)DestType; | 2261 (void)DestType; |
2255 assert((DestType == IceType_i32 && SrcType == IceType_f32) || | 2262 assert((DestType == IceType_i32 && SrcType == IceType_f32) || |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2323 // SpillLo is considered a "use" of Spill so define Spill before it | 2330 // SpillLo is considered a "use" of Spill so define Spill before it |
2324 // is used. | 2331 // is used. |
2325 Context.insert(InstFakeDef::create(Func, Spill)); | 2332 Context.insert(InstFakeDef::create(Func, Spill)); |
2326 _store(T_Lo, SpillLo); | 2333 _store(T_Lo, SpillLo); |
2327 _mov(T_Hi, hiOperand(Src0)); | 2334 _mov(T_Hi, hiOperand(Src0)); |
2328 _store(T_Hi, SpillHi); | 2335 _store(T_Hi, SpillHi); |
2329 _movq(Dest, Spill); | 2336 _movq(Dest, Spill); |
2330 } break; | 2337 } break; |
2331 case IceType_v8i1: { | 2338 case IceType_v8i1: { |
2332 assert(Src0->getType() == IceType_i8); | 2339 assert(Src0->getType() == IceType_i8); |
2333 InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1); | 2340 InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1); |
2334 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 2341 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
2335 // Arguments to functions are required to be at least 32 bits wide. | 2342 // Arguments to functions are required to be at least 32 bits wide. |
2336 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); | 2343 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); |
2337 Call->addArg(Src0AsI32); | 2344 Call->addArg(Src0AsI32); |
2338 lowerCall(Call); | 2345 lowerCall(Call); |
2339 } break; | 2346 } break; |
2340 case IceType_v16i1: { | 2347 case IceType_v16i1: { |
2341 assert(Src0->getType() == IceType_i16); | 2348 assert(Src0->getType() == IceType_i16); |
2342 InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1); | 2349 InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1); |
2343 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); | 2350 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); |
2344 // Arguments to functions are required to be at least 32 bits wide. | 2351 // Arguments to functions are required to be at least 32 bits wide. |
2345 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); | 2352 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); |
2346 Call->addArg(Src0AsI32); | 2353 Call->addArg(Src0AsI32); |
2347 lowerCall(Call); | 2354 lowerCall(Call); |
2348 } break; | 2355 } break; |
2349 case IceType_v8i16: | 2356 case IceType_v8i16: |
2350 case IceType_v16i8: | 2357 case IceType_v16i8: |
2351 case IceType_v4i32: | 2358 case IceType_v4i32: |
2352 case IceType_v4f32: { | 2359 case IceType_v4f32: { |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3006 Variable *T = nullptr; | 3013 Variable *T = nullptr; |
3007 _mov(T, Val); | 3014 _mov(T, Val); |
3008 _rol(T, Eight); | 3015 _rol(T, Eight); |
3009 _mov(Dest, T); | 3016 _mov(Dest, T); |
3010 } | 3017 } |
3011 return; | 3018 return; |
3012 } | 3019 } |
3013 case Intrinsics::Ctpop: { | 3020 case Intrinsics::Ctpop: { |
3014 Variable *Dest = Instr->getDest(); | 3021 Variable *Dest = Instr->getDest(); |
3015 Operand *Val = Instr->getArg(0); | 3022 Operand *Val = Instr->getArg(0); |
3016 InstCall *Call = | 3023 InstCall *Call = makeHelperCall(isInt32Asserting32Or64(Val->getType()) |
3017 makeHelperCall(isInt32Asserting32Or64(Val->getType()) ? "__popcountsi2" | 3024 ? H_call_ctpop_i32 |
3018 : "__popcountdi2", | 3025 : H_call_ctpop_i64, |
3019 Dest, 1); | 3026 Dest, 1); |
3020 Call->addArg(Val); | 3027 Call->addArg(Val); |
3021 lowerCall(Call); | 3028 lowerCall(Call); |
3022 // The popcount helpers always return 32-bit values, while the intrinsic's | 3029 // The popcount helpers always return 32-bit values, while the intrinsic's |
3023 // signature matches the native POPCNT instruction and fills a 64-bit reg | 3030 // signature matches the native POPCNT instruction and fills a 64-bit reg |
3024 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case | 3031 // (in 64-bit mode). Thus, clear the upper bits of the dest just in case |
3025 // the user doesn't do that in the IR. If the user does that in the IR, | 3032 // the user doesn't do that in the IR. If the user does that in the IR, |
3026 // then this zero'ing instruction is dead and gets optimized out. | 3033 // then this zero'ing instruction is dead and gets optimized out. |
3027 if (Val->getType() == IceType_i64) { | 3034 if (Val->getType() == IceType_i64) { |
3028 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); | 3035 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); |
3029 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3036 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
(...skipping 29 matching lines...) Expand all Loading... |
3059 SecondVal = loOperand(Val); | 3066 SecondVal = loOperand(Val); |
3060 } else { | 3067 } else { |
3061 FirstVal = Val; | 3068 FirstVal = Val; |
3062 } | 3069 } |
3063 const bool IsCttz = true; | 3070 const bool IsCttz = true; |
3064 lowerCountZeros(IsCttz, Val->getType(), Instr->getDest(), FirstVal, | 3071 lowerCountZeros(IsCttz, Val->getType(), Instr->getDest(), FirstVal, |
3065 SecondVal); | 3072 SecondVal); |
3066 return; | 3073 return; |
3067 } | 3074 } |
3068 case Intrinsics::Longjmp: { | 3075 case Intrinsics::Longjmp: { |
3069 InstCall *Call = makeHelperCall("longjmp", nullptr, 2); | 3076 InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2); |
3070 Call->addArg(Instr->getArg(0)); | 3077 Call->addArg(Instr->getArg(0)); |
3071 Call->addArg(Instr->getArg(1)); | 3078 Call->addArg(Instr->getArg(1)); |
3072 lowerCall(Call); | 3079 lowerCall(Call); |
3073 return; | 3080 return; |
3074 } | 3081 } |
3075 case Intrinsics::Memcpy: { | 3082 case Intrinsics::Memcpy: { |
3076 // In the future, we could potentially emit an inline memcpy/memset, etc. | 3083 // In the future, we could potentially emit an inline memcpy/memset, etc. |
3077 // for intrinsic calls w/ a known length. | 3084 // for intrinsic calls w/ a known length. |
3078 InstCall *Call = makeHelperCall("memcpy", nullptr, 3); | 3085 InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3); |
3079 Call->addArg(Instr->getArg(0)); | 3086 Call->addArg(Instr->getArg(0)); |
3080 Call->addArg(Instr->getArg(1)); | 3087 Call->addArg(Instr->getArg(1)); |
3081 Call->addArg(Instr->getArg(2)); | 3088 Call->addArg(Instr->getArg(2)); |
3082 lowerCall(Call); | 3089 lowerCall(Call); |
3083 return; | 3090 return; |
3084 } | 3091 } |
3085 case Intrinsics::Memmove: { | 3092 case Intrinsics::Memmove: { |
3086 InstCall *Call = makeHelperCall("memmove", nullptr, 3); | 3093 InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3); |
3087 Call->addArg(Instr->getArg(0)); | 3094 Call->addArg(Instr->getArg(0)); |
3088 Call->addArg(Instr->getArg(1)); | 3095 Call->addArg(Instr->getArg(1)); |
3089 Call->addArg(Instr->getArg(2)); | 3096 Call->addArg(Instr->getArg(2)); |
3090 lowerCall(Call); | 3097 lowerCall(Call); |
3091 return; | 3098 return; |
3092 } | 3099 } |
3093 case Intrinsics::Memset: { | 3100 case Intrinsics::Memset: { |
3094 // The value operand needs to be extended to a stack slot size | 3101 // The value operand needs to be extended to a stack slot size |
3095 // because the PNaCl ABI requires arguments to be at least 32 bits | 3102 // because the PNaCl ABI requires arguments to be at least 32 bits |
3096 // wide. | 3103 // wide. |
3097 Operand *ValOp = Instr->getArg(1); | 3104 Operand *ValOp = Instr->getArg(1); |
3098 assert(ValOp->getType() == IceType_i8); | 3105 assert(ValOp->getType() == IceType_i8); |
3099 Variable *ValExt = Func->makeVariable(stackSlotType()); | 3106 Variable *ValExt = Func->makeVariable(stackSlotType()); |
3100 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); | 3107 lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp)); |
3101 InstCall *Call = makeHelperCall("memset", nullptr, 3); | 3108 InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3); |
3102 Call->addArg(Instr->getArg(0)); | 3109 Call->addArg(Instr->getArg(0)); |
3103 Call->addArg(ValExt); | 3110 Call->addArg(ValExt); |
3104 Call->addArg(Instr->getArg(2)); | 3111 Call->addArg(Instr->getArg(2)); |
3105 lowerCall(Call); | 3112 lowerCall(Call); |
3106 return; | 3113 return; |
3107 } | 3114 } |
3108 case Intrinsics::NaClReadTP: { | 3115 case Intrinsics::NaClReadTP: { |
3109 if (Ctx->getFlags().getUseSandboxing()) { | 3116 if (Ctx->getFlags().getUseSandboxing()) { |
3110 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3117 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
3111 Operand *Src = | 3118 Operand *Src = |
3112 OperandX8632Mem::create(Func, IceType_i32, nullptr, Zero, nullptr, 0, | 3119 OperandX8632Mem::create(Func, IceType_i32, nullptr, Zero, nullptr, 0, |
3113 OperandX8632Mem::SegReg_GS); | 3120 OperandX8632Mem::SegReg_GS); |
3114 Variable *Dest = Instr->getDest(); | 3121 Variable *Dest = Instr->getDest(); |
3115 Variable *T = nullptr; | 3122 Variable *T = nullptr; |
3116 _mov(T, Src); | 3123 _mov(T, Src); |
3117 _mov(Dest, T); | 3124 _mov(Dest, T); |
3118 } else { | 3125 } else { |
3119 InstCall *Call = makeHelperCall("__nacl_read_tp", Instr->getDest(), 0); | 3126 InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0); |
3120 lowerCall(Call); | 3127 lowerCall(Call); |
3121 } | 3128 } |
3122 return; | 3129 return; |
3123 } | 3130 } |
3124 case Intrinsics::Setjmp: { | 3131 case Intrinsics::Setjmp: { |
3125 InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1); | 3132 InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1); |
3126 Call->addArg(Instr->getArg(0)); | 3133 Call->addArg(Instr->getArg(0)); |
3127 lowerCall(Call); | 3134 lowerCall(Call); |
3128 return; | 3135 return; |
3129 } | 3136 } |
3130 case Intrinsics::Sqrt: { | 3137 case Intrinsics::Sqrt: { |
3131 Operand *Src = legalize(Instr->getArg(0)); | 3138 Operand *Src = legalize(Instr->getArg(0)); |
3132 Variable *Dest = Instr->getDest(); | 3139 Variable *Dest = Instr->getDest(); |
3133 Variable *T = makeReg(Dest->getType()); | 3140 Variable *T = makeReg(Dest->getType()); |
3134 _sqrtss(T, Src); | 3141 _sqrtss(T, Src); |
3135 _mov(Dest, T); | 3142 _mov(Dest, T); |
(...skipping 1630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4766 case FT_Asm: | 4773 case FT_Asm: |
4767 case FT_Iasm: { | 4774 case FT_Iasm: { |
4768 OstreamLocker L(Ctx); | 4775 OstreamLocker L(Ctx); |
4769 emitConstantPool<PoolTypeConverter<float>>(Ctx); | 4776 emitConstantPool<PoolTypeConverter<float>>(Ctx); |
4770 emitConstantPool<PoolTypeConverter<double>>(Ctx); | 4777 emitConstantPool<PoolTypeConverter<double>>(Ctx); |
4771 } break; | 4778 } break; |
4772 } | 4779 } |
4773 } | 4780 } |
4774 | 4781 |
4775 } // end of namespace Ice | 4782 } // end of namespace Ice |
OLD | NEW |