Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(561)

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 961413002: Subzero: Clean up the runtime implementation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Change static helper strings to be char* instead of IceString Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/IceTargetLowering.h ('k') | tests_lit/llvm2ice_tests/fp.pnacl.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceTargetLowering.h ('k') | tests_lit/llvm2ice_tests/fp.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698