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

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: 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
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 2079 matching lines...) Expand 10 before | Expand all | Expand 10 after
2090 } else if (Dest->getType() == IceType_i64) { 2090 } else if (Dest->getType() == IceType_i64) {
2091 // Use a helper for converting floating-point values to 64-bit 2091 // Use a helper for converting floating-point values to 64-bit
2092 // integers. SSE2 appears to have no way to convert from xmm 2092 // integers. SSE2 appears to have no way to convert from xmm
2093 // registers to something like the edx:eax register pair, and 2093 // registers to something like the edx:eax register pair, and
2094 // gcc and clang both want to use x87 instructions complete with 2094 // gcc and clang both want to use x87 instructions complete with
2095 // temporary manipulation of the status word. This helper is 2095 // temporary manipulation of the status word. This helper is
2096 // not needed for x86-64. 2096 // not needed for x86-64.
2097 split64(Dest); 2097 split64(Dest);
2098 const SizeT MaxSrcs = 1; 2098 const SizeT MaxSrcs = 1;
2099 Type SrcType = Inst->getSrc(0)->getType(); 2099 Type SrcType = Inst->getSrc(0)->getType();
2100 InstCall *Call = makeHelperCall( 2100 InstCall *Call = makeHelperCall(isFloat32Asserting32Or64(SrcType)
2101 isFloat32Asserting32Or64(SrcType) ? "cvtftosi64" : "cvtdtosi64", Dest, 2101 ? "__Sz_fptosi_f32_i64"
Mircea Trofin 2015/02/28 00:45:35 Do we expect to use these strings anywhere else, s
Jim Stichnoth 2015/02/28 02:35:44 Good point. It's likely that these and more will
Mircea Trofin 2015/02/28 03:28:56 Why would the use during lowering be faster?
Jim Stichnoth 2015/02/28 04:44:28 I'm assuming that copying a constant IceString (i.
2102 MaxSrcs); 2102 : "__Sz_fptosi_f64_i64",
2103 // TODO: Call the correct compiler-rt helper function. 2103 Dest, MaxSrcs);
2104 Call->addArg(Inst->getSrc(0)); 2104 Call->addArg(Inst->getSrc(0));
2105 lowerCall(Call); 2105 lowerCall(Call);
2106 } else { 2106 } else {
2107 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2107 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2108 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2108 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
2109 Variable *T_1 = makeReg(IceType_i32); 2109 Variable *T_1 = makeReg(IceType_i32);
2110 Variable *T_2 = makeReg(Dest->getType()); 2110 Variable *T_2 = makeReg(Dest->getType());
2111 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); 2111 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
2112 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 2112 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
2113 if (Dest->getType() == IceType_i1) 2113 if (Dest->getType() == IceType_i1)
2114 _and(T_2, Ctx->getConstantInt1(1)); 2114 _and(T_2, Ctx->getConstantInt1(1));
2115 _mov(Dest, T_2); 2115 _mov(Dest, T_2);
2116 } 2116 }
2117 break; 2117 break;
2118 case InstCast::Fptoui: 2118 case InstCast::Fptoui:
2119 if (isVectorType(Dest->getType())) { 2119 if (isVectorType(Dest->getType())) {
2120 assert(Dest->getType() == IceType_v4i32 && 2120 assert(Dest->getType() == IceType_v4i32 &&
2121 Inst->getSrc(0)->getType() == IceType_v4f32); 2121 Inst->getSrc(0)->getType() == IceType_v4f32);
2122 const SizeT MaxSrcs = 1; 2122 const SizeT MaxSrcs = 1;
2123 InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs); 2123 InstCall *Call = makeHelperCall("__Sz_fptoui_4xi32_f32", Dest, MaxSrcs);
2124 Call->addArg(Inst->getSrc(0)); 2124 Call->addArg(Inst->getSrc(0));
2125 lowerCall(Call); 2125 lowerCall(Call);
2126 } else if (Dest->getType() == IceType_i64 || 2126 } else if (Dest->getType() == IceType_i64 ||
2127 Dest->getType() == IceType_i32) { 2127 Dest->getType() == IceType_i32) {
2128 // Use a helper for both x86-32 and x86-64. 2128 // Use a helper for both x86-32 and x86-64.
2129 split64(Dest); 2129 split64(Dest);
2130 const SizeT MaxSrcs = 1; 2130 const SizeT MaxSrcs = 1;
2131 Type DestType = Dest->getType(); 2131 Type DestType = Dest->getType();
2132 Type SrcType = Inst->getSrc(0)->getType(); 2132 Type SrcType = Inst->getSrc(0)->getType();
2133 IceString DstSubstring = (isInt32Asserting32Or64(DestType) ? "32" : "64"); 2133 IceString TargetString;
2134 IceString SrcSubstring = (isFloat32Asserting32Or64(SrcType) ? "f" : "d"); 2134 if (isInt32Asserting32Or64(DestType)) {
2135 // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64 2135 TargetString = isFloat32Asserting32Or64(SrcType)
2136 IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring; 2136 ? "__Sz_fptoui_f32_i32"
2137 // TODO: Call the correct compiler-rt helper function. 2137 : "__Sz_fptoui_f64_i32";
2138 } else {
2139 TargetString = isFloat32Asserting32Or64(SrcType)
2140 ? "__Sz_fptoui_f32_i64"
2141 : "__Sz_fptoui_f64_i64";
2142 }
2138 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 2143 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
2139 Call->addArg(Inst->getSrc(0)); 2144 Call->addArg(Inst->getSrc(0));
2140 lowerCall(Call); 2145 lowerCall(Call);
2141 return; 2146 return;
2142 } else { 2147 } else {
2143 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2148 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2144 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type 2149 // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
2145 Variable *T_1 = makeReg(IceType_i32); 2150 Variable *T_1 = makeReg(IceType_i32);
2146 Variable *T_2 = makeReg(Dest->getType()); 2151 Variable *T_2 = makeReg(Dest->getType());
2147 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si); 2152 _cvt(T_1, Src0RM, InstX8632Cvt::Tss2si);
2148 _mov(T_2, T_1); // T_1 and T_2 may have different integer types 2153 _mov(T_2, T_1); // T_1 and T_2 may have different integer types
2149 if (Dest->getType() == IceType_i1) 2154 if (Dest->getType() == IceType_i1)
2150 _and(T_2, Ctx->getConstantInt1(1)); 2155 _and(T_2, Ctx->getConstantInt1(1));
2151 _mov(Dest, T_2); 2156 _mov(Dest, T_2);
2152 } 2157 }
2153 break; 2158 break;
2154 case InstCast::Sitofp: 2159 case InstCast::Sitofp:
2155 if (isVectorType(Dest->getType())) { 2160 if (isVectorType(Dest->getType())) {
2156 assert(Dest->getType() == IceType_v4f32 && 2161 assert(Dest->getType() == IceType_v4f32 &&
2157 Inst->getSrc(0)->getType() == IceType_v4i32); 2162 Inst->getSrc(0)->getType() == IceType_v4i32);
2158 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2163 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2159 Variable *T = makeReg(Dest->getType()); 2164 Variable *T = makeReg(Dest->getType());
2160 _cvt(T, Src0RM, InstX8632Cvt::Dq2ps); 2165 _cvt(T, Src0RM, InstX8632Cvt::Dq2ps);
2161 _movp(Dest, T); 2166 _movp(Dest, T);
2162 } else if (Inst->getSrc(0)->getType() == IceType_i64) { 2167 } else if (Inst->getSrc(0)->getType() == IceType_i64) {
2163 // Use a helper for x86-32. 2168 // Use a helper for x86-32.
2164 const SizeT MaxSrcs = 1; 2169 const SizeT MaxSrcs = 1;
2165 Type DestType = Dest->getType(); 2170 Type DestType = Dest->getType();
2166 InstCall *Call = makeHelperCall( 2171 InstCall *Call = makeHelperCall(isFloat32Asserting32Or64(DestType)
2167 isFloat32Asserting32Or64(DestType) ? "cvtsi64tof" : "cvtsi64tod", 2172 ? "__Sz_sitofp_i64_f32"
2168 Dest, MaxSrcs); 2173 : "__Sz_sitofp_i64_f64",
2174 Dest, MaxSrcs);
2169 // TODO: Call the correct compiler-rt helper function. 2175 // TODO: Call the correct compiler-rt helper function.
2170 Call->addArg(Inst->getSrc(0)); 2176 Call->addArg(Inst->getSrc(0));
2171 lowerCall(Call); 2177 lowerCall(Call);
2172 return; 2178 return;
2173 } else { 2179 } else {
2174 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); 2180 Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
2175 // Sign-extend the operand. 2181 // Sign-extend the operand.
2176 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2 2182 // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2
2177 Variable *T_1 = makeReg(IceType_i32); 2183 Variable *T_1 = makeReg(IceType_i32);
2178 Variable *T_2 = makeReg(Dest->getType()); 2184 Variable *T_2 = makeReg(Dest->getType());
2179 if (Src0RM->getType() == IceType_i32) 2185 if (Src0RM->getType() == IceType_i32)
2180 _mov(T_1, Src0RM); 2186 _mov(T_1, Src0RM);
2181 else 2187 else
2182 _movsx(T_1, Src0RM); 2188 _movsx(T_1, Src0RM);
2183 _cvt(T_2, T_1, InstX8632Cvt::Si2ss); 2189 _cvt(T_2, T_1, InstX8632Cvt::Si2ss);
2184 _mov(Dest, T_2); 2190 _mov(Dest, T_2);
2185 } 2191 }
2186 break; 2192 break;
2187 case InstCast::Uitofp: { 2193 case InstCast::Uitofp: {
2188 Operand *Src0 = Inst->getSrc(0); 2194 Operand *Src0 = Inst->getSrc(0);
2189 if (isVectorType(Src0->getType())) { 2195 if (isVectorType(Src0->getType())) {
2190 assert(Dest->getType() == IceType_v4f32 && 2196 assert(Dest->getType() == IceType_v4f32 &&
2191 Src0->getType() == IceType_v4i32); 2197 Src0->getType() == IceType_v4i32);
2192 const SizeT MaxSrcs = 1; 2198 const SizeT MaxSrcs = 1;
2193 InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs); 2199 InstCall *Call = makeHelperCall("__Sz_uitofp_4xi32_4xf32", Dest, MaxSrcs);
2194 Call->addArg(Src0); 2200 Call->addArg(Src0);
2195 lowerCall(Call); 2201 lowerCall(Call);
2196 } else if (Src0->getType() == IceType_i64 || 2202 } else if (Src0->getType() == IceType_i64 ||
2197 Src0->getType() == IceType_i32) { 2203 Src0->getType() == IceType_i32) {
2198 // Use a helper for x86-32 and x86-64. Also use a helper for 2204 // Use a helper for x86-32 and x86-64. Also use a helper for
2199 // i32 on x86-32. 2205 // i32 on x86-32.
2200 const SizeT MaxSrcs = 1; 2206 const SizeT MaxSrcs = 1;
2201 Type DestType = Dest->getType(); 2207 Type DestType = Dest->getType();
2202 IceString SrcSubstring = 2208 IceString TargetString;
2203 (isInt32Asserting32Or64(Src0->getType()) ? "32" : "64"); 2209 if (isInt32Asserting32Or64(Src0->getType())) {
2204 IceString DstSubstring = (isFloat32Asserting32Or64(DestType) ? "f" : "d"); 2210 TargetString = isFloat32Asserting32Or64(DestType)
2205 // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod 2211 ? "__Sz_uitofp_i32_f32"
2206 IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring; 2212 : "__Sz_uitofp_i32_f64";
2207 // TODO: Call the correct compiler-rt helper function. 2213 } else {
2214 TargetString = isFloat32Asserting32Or64(DestType)
2215 ? "__Sz_uitofp_i64_f32"
2216 : "__Sz_uitofp_i64_f64";
2217 }
2208 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs); 2218 InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
2209 Call->addArg(Src0); 2219 Call->addArg(Src0);
2210 lowerCall(Call); 2220 lowerCall(Call);
2211 return; 2221 return;
2212 } else { 2222 } else {
2213 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2223 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2214 // Zero-extend the operand. 2224 // Zero-extend the operand.
2215 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2 2225 // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2
2216 Variable *T_1 = makeReg(IceType_i32); 2226 Variable *T_1 = makeReg(IceType_i32);
2217 Variable *T_2 = makeReg(Dest->getType()); 2227 Variable *T_2 = makeReg(Dest->getType());
(...skipping 11 matching lines...) Expand all
2229 if (Dest->getType() == Src0->getType()) { 2239 if (Dest->getType() == Src0->getType()) {
2230 InstAssign *Assign = InstAssign::create(Func, Dest, Src0); 2240 InstAssign *Assign = InstAssign::create(Func, Dest, Src0);
2231 lowerAssign(Assign); 2241 lowerAssign(Assign);
2232 return; 2242 return;
2233 } 2243 }
2234 switch (Dest->getType()) { 2244 switch (Dest->getType()) {
2235 default: 2245 default:
2236 llvm_unreachable("Unexpected Bitcast dest type"); 2246 llvm_unreachable("Unexpected Bitcast dest type");
2237 case IceType_i8: { 2247 case IceType_i8: {
2238 assert(Src0->getType() == IceType_v8i1); 2248 assert(Src0->getType() == IceType_v8i1);
2239 InstCall *Call = makeHelperCall("Sz_bitcast_v8i1_to_i8", Dest, 1); 2249 InstCall *Call = makeHelperCall("__Sz_bitcast_8xi1_i8", Dest, 1);
2240 Call->addArg(Src0); 2250 Call->addArg(Src0);
2241 lowerCall(Call); 2251 lowerCall(Call);
2242 } break; 2252 } break;
2243 case IceType_i16: { 2253 case IceType_i16: {
2244 assert(Src0->getType() == IceType_v16i1); 2254 assert(Src0->getType() == IceType_v16i1);
2245 InstCall *Call = makeHelperCall("Sz_bitcast_v16i1_to_i16", Dest, 1); 2255 InstCall *Call = makeHelperCall("__Sz_bitcast_16xi1_i16", Dest, 1);
2246 Call->addArg(Src0); 2256 Call->addArg(Src0);
2247 lowerCall(Call); 2257 lowerCall(Call);
2248 } break; 2258 } break;
2249 case IceType_i32: 2259 case IceType_i32:
2250 case IceType_f32: { 2260 case IceType_f32: {
2251 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); 2261 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
2252 Type DestType = Dest->getType(); 2262 Type DestType = Dest->getType();
2253 Type SrcType = Src0RM->getType(); 2263 Type SrcType = Src0RM->getType();
2254 (void)DestType; 2264 (void)DestType;
2255 assert((DestType == IceType_i32 && SrcType == IceType_f32) || 2265 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 2333 // SpillLo is considered a "use" of Spill so define Spill before it
2324 // is used. 2334 // is used.
2325 Context.insert(InstFakeDef::create(Func, Spill)); 2335 Context.insert(InstFakeDef::create(Func, Spill));
2326 _store(T_Lo, SpillLo); 2336 _store(T_Lo, SpillLo);
2327 _mov(T_Hi, hiOperand(Src0)); 2337 _mov(T_Hi, hiOperand(Src0));
2328 _store(T_Hi, SpillHi); 2338 _store(T_Hi, SpillHi);
2329 _movq(Dest, Spill); 2339 _movq(Dest, Spill);
2330 } break; 2340 } break;
2331 case IceType_v8i1: { 2341 case IceType_v8i1: {
2332 assert(Src0->getType() == IceType_i8); 2342 assert(Src0->getType() == IceType_i8);
2333 InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1); 2343 InstCall *Call = makeHelperCall("__Sz_bitcast_i8_8xi1", Dest, 1);
2334 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); 2344 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2335 // Arguments to functions are required to be at least 32 bits wide. 2345 // Arguments to functions are required to be at least 32 bits wide.
2336 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2346 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2337 Call->addArg(Src0AsI32); 2347 Call->addArg(Src0AsI32);
2338 lowerCall(Call); 2348 lowerCall(Call);
2339 } break; 2349 } break;
2340 case IceType_v16i1: { 2350 case IceType_v16i1: {
2341 assert(Src0->getType() == IceType_i16); 2351 assert(Src0->getType() == IceType_i16);
2342 InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1); 2352 InstCall *Call = makeHelperCall("__Sz_bitcast_i16_16xi1", Dest, 1);
2343 Variable *Src0AsI32 = Func->makeVariable(stackSlotType()); 2353 Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
2344 // Arguments to functions are required to be at least 32 bits wide. 2354 // Arguments to functions are required to be at least 32 bits wide.
2345 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0)); 2355 lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
2346 Call->addArg(Src0AsI32); 2356 Call->addArg(Src0AsI32);
2347 lowerCall(Call); 2357 lowerCall(Call);
2348 } break; 2358 } break;
2349 case IceType_v8i16: 2359 case IceType_v8i16:
2350 case IceType_v16i8: 2360 case IceType_v16i8:
2351 case IceType_v4i32: 2361 case IceType_v4i32:
2352 case IceType_v4f32: { 2362 case IceType_v4f32: {
(...skipping 2413 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 case FT_Asm: 4776 case FT_Asm:
4767 case FT_Iasm: { 4777 case FT_Iasm: {
4768 OstreamLocker L(Ctx); 4778 OstreamLocker L(Ctx);
4769 emitConstantPool<PoolTypeConverter<float>>(Ctx); 4779 emitConstantPool<PoolTypeConverter<float>>(Ctx);
4770 emitConstantPool<PoolTypeConverter<double>>(Ctx); 4780 emitConstantPool<PoolTypeConverter<double>>(Ctx);
4771 } break; 4781 } break;
4772 } 4782 }
4773 } 4783 }
4774 4784
4775 } // end of namespace Ice 4785 } // end of namespace Ice
OLDNEW
« runtime/szrt.c ('K') | « runtime/szrt_ll.ll ('k') | tests_lit/llvm2ice_tests/fp.pnacl.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698