Chromium Code Reviews| 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 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1242 _movp(Dest, T); | 1242 _movp(Dest, T); |
| 1243 } break; | 1243 } break; |
| 1244 case InstArithmetic::Mul: { | 1244 case InstArithmetic::Mul: { |
| 1245 bool TypesAreValidForPmull = | 1245 bool TypesAreValidForPmull = |
| 1246 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16; | 1246 Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16; |
| 1247 bool InstructionSetIsValidForPmull = | 1247 bool InstructionSetIsValidForPmull = |
| 1248 Dest->getType() == IceType_v8i16 || InstructionSet >= SSE4_1; | 1248 Dest->getType() == IceType_v8i16 || InstructionSet >= SSE4_1; |
| 1249 if (TypesAreValidForPmull && InstructionSetIsValidForPmull) { | 1249 if (TypesAreValidForPmull && InstructionSetIsValidForPmull) { |
| 1250 Variable *T = makeReg(Dest->getType()); | 1250 Variable *T = makeReg(Dest->getType()); |
| 1251 _movp(T, Src0); | 1251 _movp(T, Src0); |
| 1252 _pmull(T, legalizeToVar(Src1)); | 1252 _pmull(T, LEGAL_HACK(Src1)); |
| 1253 _movp(Dest, T); | 1253 _movp(Dest, T); |
| 1254 } else if (Dest->getType() == IceType_v4i32) { | 1254 } else if (Dest->getType() == IceType_v4i32) { |
| 1255 // Lowering sequence: | 1255 // Lowering sequence: |
| 1256 // Note: The mask arguments have index 0 on the left. | 1256 // Note: The mask arguments have index 0 on the left. |
| 1257 // | 1257 // |
| 1258 // movups T1, Src0 | 1258 // movups T1, Src0 |
| 1259 // pshufd T2, Src0, {1,0,3,0} | 1259 // pshufd T2, Src0, {1,0,3,0} |
| 1260 // pshufd T3, Src1, {1,0,3,0} | 1260 // pshufd T3, Src1, {1,0,3,0} |
| 1261 // # T1 = {Src0[0] * Src1[0], Src0[2] * Src1[2]} | 1261 // # T1 = {Src0[0] * Src1[0], Src0[2] * Src1[2]} |
| 1262 // pmuludq T1, Src1 | 1262 // pmuludq T1, Src1 |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2152 case IceType_v4f32: { | 2152 case IceType_v4f32: { |
| 2153 _movp(Dest, legalizeToVar(Src0)); | 2153 _movp(Dest, legalizeToVar(Src0)); |
| 2154 } break; | 2154 } break; |
| 2155 } | 2155 } |
| 2156 break; | 2156 break; |
| 2157 } | 2157 } |
| 2158 } | 2158 } |
| 2159 } | 2159 } |
| 2160 | 2160 |
| 2161 void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) { | 2161 void TargetX8632::lowerExtractElement(const InstExtractElement *Inst) { |
| 2162 Operand *SourceVectOperand = Inst->getSrc(0); | 2162 Operand *SourceVectNotLegalized = Inst->getSrc(0); |
| 2163 ConstantInteger *ElementIndex = | 2163 ConstantInteger *ElementIndex = |
| 2164 llvm::dyn_cast<ConstantInteger>(Inst->getSrc(1)); | 2164 llvm::dyn_cast<ConstantInteger>(Inst->getSrc(1)); |
| 2165 // Only constant indices are allowed in PNaCl IR. | 2165 // Only constant indices are allowed in PNaCl IR. |
| 2166 assert(ElementIndex); | 2166 assert(ElementIndex); |
| 2167 | 2167 |
| 2168 unsigned Index = ElementIndex->getValue(); | 2168 unsigned Index = ElementIndex->getValue(); |
| 2169 Type Ty = SourceVectOperand->getType(); | 2169 Type Ty = SourceVectNotLegalized->getType(); |
| 2170 Type ElementTy = typeElementType(Ty); | 2170 Type ElementTy = typeElementType(Ty); |
| 2171 Type InVectorElementTy = getInVectorElementType(Ty); | 2171 Type InVectorElementTy = getInVectorElementType(Ty); |
| 2172 Variable *ExtractedElement = makeReg(InVectorElementTy); | 2172 Variable *ExtractedElementR = makeReg(InVectorElementTy); |
| 2173 | 2173 |
| 2174 // TODO(wala): Determine the best lowering sequences for each type. | 2174 // TODO(wala): Determine the best lowering sequences for each type. |
| 2175 bool CanUsePextr = | 2175 bool CanUsePextr = |
| 2176 Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1; | 2176 Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1; |
| 2177 if (CanUsePextr && Ty != IceType_v4f32) { | 2177 if (CanUsePextr && Ty != IceType_v4f32) { |
| 2178 // Use pextrb, pextrw, or pextrd. | 2178 // Use pextrb, pextrw, or pextrd. |
| 2179 Constant *Mask = Ctx->getConstantInt(IceType_i8, Index); | 2179 Constant *Mask = Ctx->getConstantInt(IceType_i8, Index); |
| 2180 Variable *SourceVectR = legalizeToVar(SourceVectOperand); | 2180 Variable *SourceVectR = legalizeToVar(SourceVectNotLegalized); |
| 2181 _pextr(ExtractedElement, SourceVectR, Mask); | 2181 _pextr(ExtractedElementR, SourceVectR, Mask); |
| 2182 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) { | 2182 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) { |
| 2183 // Use pshufd and movd/movss. | 2183 // Use pshufd and movd/movss. |
| 2184 // | 2184 // |
| 2185 // ALIGNHACK: Force vector operands to registers in instructions that | 2185 // ALIGNHACK: Force vector operands to registers in instructions that |
| 2186 // require aligned memory operands until support for stack alignment | 2186 // require aligned memory operands until support for stack alignment |
| 2187 // is implemented. | 2187 // is implemented. |
| 2188 #define ALIGN_HACK(Vect) legalizeToVar((Vect)) | 2188 #define ALIGN_HACK(Vect) legalizeToVar((Vect)) |
| 2189 Operand *SourceVectRM = | |
| 2190 legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem); | |
| 2189 Variable *T = NULL; | 2191 Variable *T = NULL; |
| 2190 if (Index) { | 2192 if (Index) { |
| 2191 // The shuffle only needs to occur if the element to be extracted | 2193 // The shuffle only needs to occur if the element to be extracted |
| 2192 // is not at the lowest index. | 2194 // is not at the lowest index. |
| 2193 Constant *Mask = Ctx->getConstantInt(IceType_i8, Index); | 2195 Constant *Mask = Ctx->getConstantInt(IceType_i8, Index); |
| 2194 T = makeReg(Ty); | 2196 T = makeReg(Ty); |
| 2195 _pshufd(T, ALIGN_HACK(SourceVectOperand), Mask); | 2197 _pshufd(T, ALIGN_HACK(SourceVectRM), Mask); |
| 2196 } else { | 2198 } else { |
| 2197 T = legalizeToVar(SourceVectOperand); | 2199 T = ALIGN_HACK(SourceVectRM); |
| 2198 } | 2200 } |
| 2199 | 2201 |
| 2200 if (InVectorElementTy == IceType_i32) { | 2202 if (InVectorElementTy == IceType_i32) { |
| 2201 _movd(ExtractedElement, T); | 2203 _movd(ExtractedElementR, T); |
| 2202 } else { // Ty == Icetype_f32 | 2204 } else { // Ty == Icetype_f32 |
| 2203 // TODO(wala): _movss is only used here because _mov does not | 2205 // TODO(wala): _movss is only used here because _mov does not |
| 2204 // allow a vector source and a scalar destination. _mov should be | 2206 // allow a vector source and a scalar destination. _mov should be |
| 2205 // able to be used here. | 2207 // able to be used here. |
| 2206 // _movss is a binary instruction, so the FakeDef is needed to | 2208 // _movss is a binary instruction, so the FakeDef is needed to |
| 2207 // keep the live range analysis consistent. | 2209 // keep the live range analysis consistent. |
| 2208 Context.insert(InstFakeDef::create(Func, ExtractedElement)); | 2210 Context.insert(InstFakeDef::create(Func, ExtractedElementR)); |
| 2209 _movss(ExtractedElement, T); | 2211 _movss(ExtractedElementR, T); |
| 2210 } | 2212 } |
| 2211 #undef ALIGN_HACK | 2213 #undef ALIGN_HACK |
| 2212 } else { | 2214 } else { |
| 2213 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); | 2215 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); |
| 2214 // Spill the value to a stack slot and do the extraction in memory. | 2216 // Spill the value to a stack slot and do the extraction in memory. |
| 2215 // | 2217 // |
| 2216 // TODO(wala): use legalize(SourceVectOperand, Legal_Mem) when | 2218 // TODO(wala): use legalize(SourceVectNotLegalized, Legal_Mem) when |
| 2217 // support for legalizing to mem is implemented. | 2219 // support for legalizing to mem is implemented. |
| 2218 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); | 2220 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); |
| 2219 Slot->setWeight(RegWeight::Zero); | 2221 Slot->setWeight(RegWeight::Zero); |
| 2220 _movp(Slot, legalizeToVar(SourceVectOperand)); | 2222 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); |
| 2221 | 2223 |
| 2222 // Compute the location of the element in memory. | 2224 // Compute the location of the element in memory. |
| 2223 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); | 2225 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); |
| 2224 OperandX8632Mem *Loc = | 2226 OperandX8632Mem *Loc = |
| 2225 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); | 2227 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); |
| 2226 _mov(ExtractedElement, Loc); | 2228 _mov(ExtractedElementR, Loc); |
| 2227 } | 2229 } |
| 2228 | 2230 |
| 2229 if (ElementTy == IceType_i1) { | 2231 if (ElementTy == IceType_i1) { |
| 2230 // Truncate extracted integers to i1s if necessary. | 2232 // Truncate extracted integers to i1s if necessary. |
| 2231 Variable *T = makeReg(IceType_i1); | 2233 Variable *T = makeReg(IceType_i1); |
| 2232 InstCast *Cast = | 2234 InstCast *Cast = |
| 2233 InstCast::create(Func, InstCast::Trunc, T, ExtractedElement); | 2235 InstCast::create(Func, InstCast::Trunc, T, ExtractedElementR); |
| 2234 lowerCast(Cast); | 2236 lowerCast(Cast); |
| 2235 ExtractedElement = T; | 2237 ExtractedElementR = T; |
| 2236 } | 2238 } |
| 2237 | 2239 |
| 2238 // Copy the element to the destination. | 2240 // Copy the element to the destination. |
| 2239 Variable *Dest = Inst->getDest(); | 2241 Variable *Dest = Inst->getDest(); |
| 2240 _mov(Dest, ExtractedElement); | 2242 _mov(Dest, ExtractedElementR); |
| 2241 } | 2243 } |
| 2242 | 2244 |
| 2243 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { | 2245 void TargetX8632::lowerFcmp(const InstFcmp *Inst) { |
| 2244 Operand *Src0 = Inst->getSrc(0); | 2246 Operand *Src0 = Inst->getSrc(0); |
| 2245 Operand *Src1 = Inst->getSrc(1); | 2247 Operand *Src1 = Inst->getSrc(1); |
| 2246 Variable *Dest = Inst->getDest(); | 2248 Variable *Dest = Inst->getDest(); |
| 2247 | 2249 |
| 2248 if (isVectorType(Dest->getType())) { | 2250 if (isVectorType(Dest->getType())) { |
| 2249 InstFcmp::FCond Condition = Inst->getCondition(); | 2251 InstFcmp::FCond Condition = Inst->getCondition(); |
| 2250 size_t Index = static_cast<size_t>(Condition); | 2252 size_t Index = static_cast<size_t>(Condition); |
| 2251 assert(Index < TableFcmpSize); | 2253 assert(Index < TableFcmpSize); |
| 2252 | 2254 |
| 2253 if (TableFcmp[Index].SwapVectorOperands) { | 2255 if (TableFcmp[Index].SwapVectorOperands) { |
| 2254 Operand *T = Src0; | 2256 Operand *T = Src0; |
| 2255 Src0 = Src1; | 2257 Src0 = Src1; |
| 2256 Src1 = T; | 2258 Src1 = T; |
| 2257 } | 2259 } |
| 2258 | 2260 |
| 2259 Variable *T = NULL; | 2261 Variable *T = NULL; |
| 2260 | 2262 |
| 2261 // ALIGNHACK: Without support for stack alignment, both operands to | 2263 if (Condition == InstFcmp::True) { |
| 2262 // cmpps need to be forced into registers. Once support for stack | 2264 // makeVectorOfOnes() requires an integer vector type. |
| 2263 // alignment is implemented, remove LEGAL_HACK. | 2265 T = makeVectorOfMinusOnes(IceType_v4i32); |
| 2266 } else if (Condition == InstFcmp::False) { | |
| 2267 T = makeVectorOfZeros(Dest->getType()); | |
| 2268 } else { | |
| 2269 Operand *Src0RM = legalizeToVar(Src0, Legal_Reg | Legal_Mem); | |
| 2270 Operand *Src1RM = legalizeToVar(Src1, Legal_Reg | Legal_Mem); | |
| 2271 | |
| 2272 // ALIGNHACK: Without support for stack alignment, both operands to | |
| 2273 // cmpps need to be forced into registers. Once support for stack | |
| 2274 // alignment is implemented, remove LEGAL_HACK. | |
| 2264 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) | 2275 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) |
| 2265 switch (Condition) { | 2276 switch (Condition) { |
| 2266 default: { | 2277 default: { |
| 2267 InstX8632Cmpps::CmppsCond Predicate = TableFcmp[Index].Predicate; | 2278 InstX8632Cmpps::CmppsCond Predicate = TableFcmp[Index].Predicate; |
| 2268 assert(Predicate != InstX8632Cmpps::Cmpps_Invalid); | 2279 assert(Predicate != InstX8632Cmpps::Cmpps_Invalid); |
| 2269 T = makeReg(Src0->getType()); | 2280 T = makeReg(Src0RM->getType()); |
| 2270 _movp(T, Src0); | 2281 _movp(T, Src0RM); |
| 2271 _cmpps(T, LEGAL_HACK(Src1), Predicate); | 2282 _cmpps(T, LEGAL_HACK(Src1RM), Predicate); |
| 2272 } break; | 2283 } break; |
| 2273 case InstFcmp::False: | 2284 case InstFcmp::One: { |
| 2274 T = makeVectorOfZeros(Src0->getType()); | 2285 // Check both unequal and ordered. |
| 2275 break; | 2286 T = makeReg(Src0RM->getType()); |
| 2276 case InstFcmp::One: { | 2287 Variable *T2 = makeReg(Src0RM->getType()); |
| 2277 // Check both unequal and ordered. | 2288 Src1RM = LEGAL_HACK(Src1RM); |
| 2278 T = makeReg(Src0->getType()); | 2289 _movp(T, Src0RM); |
| 2279 Variable *T2 = makeReg(Src0->getType()); | 2290 _cmpps(T, Src1RM, InstX8632Cmpps::Cmpps_neq); |
| 2280 Src1 = LEGAL_HACK(Src1); | 2291 _movp(T2, Src0RM); |
| 2281 _movp(T, Src0); | 2292 _cmpps(T2, Src1RM, InstX8632Cmpps::Cmpps_ord); |
| 2282 _cmpps(T, Src1, InstX8632Cmpps::Cmpps_neq); | 2293 _pand(T, T2); |
| 2283 _movp(T2, Src0); | 2294 } break; |
| 2284 _cmpps(T2, Src1, InstX8632Cmpps::Cmpps_ord); | 2295 case InstFcmp::Ueq: { |
| 2285 _pand(T, T2); | 2296 // Check both equal or unordered. |
| 2286 } break; | 2297 T = makeReg(Src0RM->getType()); |
| 2287 case InstFcmp::Ueq: { | 2298 Variable *T2 = makeReg(Src0RM->getType()); |
| 2288 // Check both equal or unordered. | 2299 Src1RM = LEGAL_HACK(Src1RM); |
| 2289 T = makeReg(Src0->getType()); | 2300 _movp(T, Src0RM); |
| 2290 Variable *T2 = makeReg(Src0->getType()); | 2301 _cmpps(T, Src1RM, InstX8632Cmpps::Cmpps_eq); |
| 2291 Src1 = LEGAL_HACK(Src1); | 2302 _movp(T2, Src0RM); |
| 2292 _movp(T, Src0); | 2303 _cmpps(T2, Src1RM, InstX8632Cmpps::Cmpps_unord); |
| 2293 _cmpps(T, Src1, InstX8632Cmpps::Cmpps_eq); | 2304 _por(T, T2); |
| 2294 _movp(T2, Src0); | 2305 } break; |
| 2295 _cmpps(T2, Src1, InstX8632Cmpps::Cmpps_unord); | 2306 } |
| 2296 _por(T, T2); | 2307 #undef LEGAL_HACK |
| 2297 } break; | |
| 2298 case InstFcmp::True: | |
| 2299 T = makeVectorOfMinusOnes(IceType_v4i32); | |
| 2300 break; | |
| 2301 } | 2308 } |
| 2302 #undef LEGAL_HACK | |
| 2303 | 2309 |
| 2304 _movp(Dest, T); | 2310 _movp(Dest, T); |
| 2305 eliminateNextVectorSextInstruction(Dest); | 2311 eliminateNextVectorSextInstruction(Dest); |
| 2306 return; | 2312 return; |
| 2307 } | 2313 } |
| 2308 | 2314 |
| 2309 // Lowering a = fcmp cond, b, c | 2315 // Lowering a = fcmp cond, b, c |
| 2310 // ucomiss b, c /* only if C1 != Br_None */ | 2316 // ucomiss b, c /* only if C1 != Br_None */ |
| 2311 // /* but swap b,c order if SwapOperands==true */ | 2317 // /* but swap b,c order if SwapOperands==true */ |
| 2312 // mov a, <default> | 2318 // mov a, <default> |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2377 Variable *NewSrc1 = Func->makeVariable(NewTy, Context.getNode()); | 2383 Variable *NewSrc1 = Func->makeVariable(NewTy, Context.getNode()); |
| 2378 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); | 2384 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc0, Src0)); |
| 2379 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); | 2385 lowerCast(InstCast::create(Func, InstCast::Sext, NewSrc1, Src1)); |
| 2380 Src0 = NewSrc0; | 2386 Src0 = NewSrc0; |
| 2381 Src1 = NewSrc1; | 2387 Src1 = NewSrc1; |
| 2382 Ty = NewTy; | 2388 Ty = NewTy; |
| 2383 } | 2389 } |
| 2384 | 2390 |
| 2385 InstIcmp::ICond Condition = Inst->getCondition(); | 2391 InstIcmp::ICond Condition = Inst->getCondition(); |
| 2386 | 2392 |
| 2393 Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem); | |
| 2394 Operand *Src1RM = legalize(Src1, Legal_Reg | Legal_Mem); | |
| 2395 | |
| 2387 // SSE2 only has signed comparison operations. Transform unsigned | 2396 // SSE2 only has signed comparison operations. Transform unsigned |
| 2388 // inputs in a manner that allows for the use of signed comparison | 2397 // inputs in a manner that allows for the use of signed comparison |
| 2389 // operations by flipping the high order bits. | 2398 // operations by flipping the high order bits. |
| 2390 if (Condition == InstIcmp::Ugt || Condition == InstIcmp::Uge || | 2399 if (Condition == InstIcmp::Ugt || Condition == InstIcmp::Uge || |
| 2391 Condition == InstIcmp::Ult || Condition == InstIcmp::Ule) { | 2400 Condition == InstIcmp::Ult || Condition == InstIcmp::Ule) { |
| 2392 Variable *T0 = makeReg(Ty); | 2401 Variable *T0 = makeReg(Ty); |
| 2393 Variable *T1 = makeReg(Ty); | 2402 Variable *T1 = makeReg(Ty); |
| 2394 Variable *HighOrderBits = makeVectorOfHighOrderBits(Ty); | 2403 Variable *HighOrderBits = makeVectorOfHighOrderBits(Ty); |
| 2395 _movp(T0, Src0); | 2404 _movp(T0, Src0RM); |
| 2396 _pxor(T0, HighOrderBits); | 2405 _pxor(T0, HighOrderBits); |
| 2397 _movp(T1, Src1); | 2406 _movp(T1, Src1RM); |
| 2398 _pxor(T1, HighOrderBits); | 2407 _pxor(T1, HighOrderBits); |
| 2399 Src0 = T0; | 2408 Src0RM = T0; |
| 2400 Src1 = T1; | 2409 Src1RM = T1; |
| 2401 } | 2410 } |
| 2402 | 2411 |
| 2403 // TODO: ALIGNHACK: Both operands to compare instructions need to be | 2412 // TODO: ALIGNHACK: Both operands to compare instructions need to be |
| 2404 // in registers until stack alignment support is implemented. Once | 2413 // in registers until stack alignment support is implemented. Once |
| 2405 // there is support for stack alignment, LEGAL_HACK can be removed. | 2414 // there is support for stack alignment, LEGAL_HACK can be removed. |
| 2406 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) | 2415 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) |
| 2407 Variable *T = makeReg(Ty); | 2416 Variable *T = makeReg(Ty); |
| 2408 switch (Condition) { | 2417 switch (Condition) { |
| 2409 default: | 2418 default: |
| 2410 llvm_unreachable("unexpected condition"); | 2419 llvm_unreachable("unexpected condition"); |
| 2411 break; | 2420 break; |
| 2412 case InstIcmp::Eq: { | 2421 case InstIcmp::Eq: { |
| 2413 _movp(T, Src0); | 2422 _movp(T, Src0RM); |
| 2414 _pcmpeq(T, LEGAL_HACK(Src1)); | 2423 _pcmpeq(T, LEGAL_HACK(Src1RM)); |
| 2415 } break; | 2424 } break; |
| 2416 case InstIcmp::Ne: { | 2425 case InstIcmp::Ne: { |
| 2417 _movp(T, Src0); | 2426 _movp(T, Src0RM); |
| 2418 _pcmpeq(T, LEGAL_HACK(Src1)); | 2427 _pcmpeq(T, LEGAL_HACK(Src1RM)); |
| 2419 Variable *MinusOne = makeVectorOfMinusOnes(Ty); | 2428 Variable *MinusOne = makeVectorOfMinusOnes(Ty); |
| 2420 _pxor(T, MinusOne); | 2429 _pxor(T, MinusOne); |
| 2421 } break; | 2430 } break; |
| 2422 case InstIcmp::Ugt: | 2431 case InstIcmp::Ugt: |
| 2423 case InstIcmp::Sgt: { | 2432 case InstIcmp::Sgt: { |
| 2424 _movp(T, Src0); | 2433 _movp(T, Src0RM); |
| 2425 _pcmpgt(T, LEGAL_HACK(Src1)); | 2434 _pcmpgt(T, LEGAL_HACK(Src1RM)); |
| 2426 } break; | 2435 } break; |
| 2427 case InstIcmp::Uge: | 2436 case InstIcmp::Uge: |
| 2428 case InstIcmp::Sge: { | 2437 case InstIcmp::Sge: { |
| 2429 // !(Src1 > Src0) | 2438 // !(Src1RM > Src0RM) |
| 2430 _movp(T, Src1); | 2439 _movp(T, Src1RM); |
| 2431 _pcmpgt(T, LEGAL_HACK(Src0)); | 2440 _pcmpgt(T, LEGAL_HACK(Src0RM)); |
| 2432 Variable *MinusOne = makeVectorOfMinusOnes(Ty); | 2441 Variable *MinusOne = makeVectorOfMinusOnes(Ty); |
| 2433 _pxor(T, MinusOne); | 2442 _pxor(T, MinusOne); |
| 2434 } break; | 2443 } break; |
| 2435 case InstIcmp::Ult: | 2444 case InstIcmp::Ult: |
| 2436 case InstIcmp::Slt: { | 2445 case InstIcmp::Slt: { |
| 2437 _movp(T, Src1); | 2446 _movp(T, Src1RM); |
| 2438 _pcmpgt(T, LEGAL_HACK(Src0)); | 2447 _pcmpgt(T, LEGAL_HACK(Src0RM)); |
| 2439 } break; | 2448 } break; |
| 2440 case InstIcmp::Ule: | 2449 case InstIcmp::Ule: |
| 2441 case InstIcmp::Sle: { | 2450 case InstIcmp::Sle: { |
| 2442 // !(Src0 > Src1) | 2451 // !(Src0RM > Src1RM) |
| 2443 _movp(T, Src0); | 2452 _movp(T, Src0RM); |
| 2444 _pcmpgt(T, LEGAL_HACK(Src1)); | 2453 _pcmpgt(T, LEGAL_HACK(Src1RM)); |
| 2445 Variable *MinusOne = makeVectorOfMinusOnes(Ty); | 2454 Variable *MinusOne = makeVectorOfMinusOnes(Ty); |
| 2446 _pxor(T, MinusOne); | 2455 _pxor(T, MinusOne); |
| 2447 } break; | 2456 } break; |
| 2448 } | 2457 } |
| 2449 #undef LEGAL_HACK | 2458 #undef LEGAL_HACK |
| 2450 | 2459 |
| 2451 _movp(Dest, T); | 2460 _movp(Dest, T); |
| 2452 eliminateNextVectorSextInstruction(Dest); | 2461 eliminateNextVectorSextInstruction(Dest); |
| 2453 return; | 2462 return; |
| 2454 } | 2463 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2526 InstX8632Label *Label = InstX8632Label::create(Func, this); | 2535 InstX8632Label *Label = InstX8632Label::create(Func, this); |
| 2527 _cmp(Src0New, Src1); | 2536 _cmp(Src0New, Src1); |
| 2528 _mov(Dest, One); | 2537 _mov(Dest, One); |
| 2529 _br(getIcmp32Mapping(Inst->getCondition()), Label); | 2538 _br(getIcmp32Mapping(Inst->getCondition()), Label); |
| 2530 Context.insert(InstFakeUse::create(Func, Dest)); | 2539 Context.insert(InstFakeUse::create(Func, Dest)); |
| 2531 _mov(Dest, Zero); | 2540 _mov(Dest, Zero); |
| 2532 Context.insert(Label); | 2541 Context.insert(Label); |
| 2533 } | 2542 } |
| 2534 | 2543 |
| 2535 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { | 2544 void TargetX8632::lowerInsertElement(const InstInsertElement *Inst) { |
| 2536 Operand *SourceVectOperand = Inst->getSrc(0); | 2545 Operand *SourceVectNotLegalized = Inst->getSrc(0); |
| 2537 Operand *ElementToInsert = Inst->getSrc(1); | 2546 Operand *ElementToInsertNotLegalized = Inst->getSrc(1); |
| 2538 ConstantInteger *ElementIndex = | 2547 ConstantInteger *ElementIndex = |
| 2539 llvm::dyn_cast<ConstantInteger>(Inst->getSrc(2)); | 2548 llvm::dyn_cast<ConstantInteger>(Inst->getSrc(2)); |
| 2540 // Only constant indices are allowed in PNaCl IR. | 2549 // Only constant indices are allowed in PNaCl IR. |
| 2541 assert(ElementIndex); | 2550 assert(ElementIndex); |
| 2542 unsigned Index = ElementIndex->getValue(); | 2551 unsigned Index = ElementIndex->getValue(); |
| 2543 assert(Index < typeNumElements(SourceVectOperand->getType())); | 2552 assert(Index < typeNumElements(SourceVectNotLegalized->getType())); |
| 2544 | 2553 |
| 2545 Type Ty = SourceVectOperand->getType(); | 2554 Type Ty = SourceVectNotLegalized->getType(); |
| 2546 Type ElementTy = typeElementType(Ty); | 2555 Type ElementTy = typeElementType(Ty); |
| 2547 Type InVectorElementTy = getInVectorElementType(Ty); | 2556 Type InVectorElementTy = getInVectorElementType(Ty); |
| 2548 | 2557 |
| 2549 if (ElementTy == IceType_i1) { | 2558 if (ElementTy == IceType_i1) { |
| 2550 // Expand the element to the appropriate size for it to be inserted | 2559 // Expand the element to the appropriate size for it to be inserted |
| 2551 // in the vector. | 2560 // in the vector. |
| 2552 Variable *Expanded = | 2561 Variable *Expanded = |
| 2553 Func->makeVariable(InVectorElementTy, Context.getNode()); | 2562 Func->makeVariable(InVectorElementTy, Context.getNode()); |
| 2554 InstCast *Cast = | 2563 InstCast *Cast = InstCast::create(Func, InstCast::Zext, Expanded, |
| 2555 InstCast::create(Func, InstCast::Zext, Expanded, ElementToInsert); | 2564 ElementToInsertNotLegalized); |
| 2556 lowerCast(Cast); | 2565 lowerCast(Cast); |
| 2557 ElementToInsert = Expanded; | 2566 ElementToInsertNotLegalized = Expanded; |
| 2558 } | 2567 } |
| 2559 | 2568 |
| 2560 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1) { | 2569 if (Ty == IceType_v8i16 || Ty == IceType_v8i1 || InstructionSet >= SSE4_1) { |
| 2561 // Use insertps, pinsrb, pinsrw, or pinsrd. | 2570 // Use insertps, pinsrb, pinsrw, or pinsrd. |
| 2562 Operand *Element = legalize(ElementToInsert, Legal_Mem | Legal_Reg); | 2571 Operand *ElementRM = |
| 2572 legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem); | |
| 2573 Operand *SourceVectRM = | |
| 2574 legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem); | |
| 2563 Variable *T = makeReg(Ty); | 2575 Variable *T = makeReg(Ty); |
| 2564 _movp(T, SourceVectOperand); | 2576 _movp(T, SourceVectRM); |
| 2565 if (Ty == IceType_v4f32) | 2577 if (Ty == IceType_v4f32) |
| 2566 _insertps(T, Element, Ctx->getConstantInt(IceType_i8, Index << 4)); | 2578 _insertps(T, ElementRM, Ctx->getConstantInt(IceType_i8, Index << 4)); |
| 2567 else | 2579 else |
| 2568 _pinsr(T, Element, Ctx->getConstantInt(IceType_i8, Index)); | 2580 _pinsr(T, ElementRM, Ctx->getConstantInt(IceType_i8, Index)); |
| 2569 _movp(Inst->getDest(), T); | 2581 _movp(Inst->getDest(), T); |
| 2570 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) { | 2582 } else if (Ty == IceType_v4i32 || Ty == IceType_v4f32 || Ty == IceType_v4i1) { |
| 2571 // Use shufps or movss. | 2583 // Use shufps or movss. |
| 2572 Variable *Element = NULL; | 2584 Variable *ElementR = NULL; |
| 2585 Operand *SourceVectRM = | |
| 2586 legalize(SourceVectNotLegalized, Legal_Reg | Legal_Mem); | |
| 2587 | |
| 2573 if (InVectorElementTy == IceType_f32) { | 2588 if (InVectorElementTy == IceType_f32) { |
| 2574 // Element will be in an XMM register since it is floating point. | 2589 // ElementR will be in an XMM register since it is floating point. |
| 2575 Element = legalizeToVar(ElementToInsert); | 2590 ElementR = legalizeToVar(ElementToInsertNotLegalized); |
| 2576 } else { | 2591 } else { |
| 2577 // Copy an integer to an XMM register. | 2592 // Copy an integer to an XMM register. |
| 2578 Operand *T = legalize(ElementToInsert, Legal_Reg | Legal_Mem); | 2593 Operand *T = legalize(ElementToInsertNotLegalized, Legal_Reg | Legal_Mem); |
| 2579 Element = makeReg(Ty); | 2594 ElementR = makeReg(Ty); |
| 2580 _movd(Element, T); | 2595 _movd(ElementR, T); |
| 2581 } | 2596 } |
| 2582 | 2597 |
| 2583 if (Index == 0) { | 2598 if (Index == 0) { |
| 2584 Variable *T = makeReg(Ty); | 2599 Variable *T = makeReg(Ty); |
| 2585 _movp(T, SourceVectOperand); | 2600 _movp(T, SourceVectRM); |
| 2586 _movss(T, Element); | 2601 _movss(T, ElementR); |
| 2587 _movp(Inst->getDest(), T); | 2602 _movp(Inst->getDest(), T); |
| 2588 return; | 2603 return; |
| 2589 } | 2604 } |
| 2590 | 2605 |
| 2591 // shufps treats the source and desination operands as vectors of | 2606 // shufps treats the source and desination operands as vectors of |
| 2592 // four doublewords. The destination's two high doublewords are | 2607 // four doublewords. The destination's two high doublewords are |
| 2593 // selected from the source operand and the two low doublewords are | 2608 // selected from the source operand and the two low doublewords are |
| 2594 // selected from the (original value of) the destination operand. | 2609 // selected from the (original value of) the destination operand. |
| 2595 // An insertelement operation can be effected with a sequence of two | 2610 // An insertelement operation can be effected with a sequence of two |
| 2596 // shufps operations with appropriate masks. In all cases below, | 2611 // shufps operations with appropriate masks. In all cases below, |
| 2597 // Element[0] is being inserted into SourceVectOperand. Indices are | 2612 // Element[0] is being inserted into SourceVectOperand. Indices are |
| 2598 // ordered from left to right. | 2613 // ordered from left to right. |
| 2599 // | 2614 // |
| 2600 // insertelement into index 1 (result is stored in Element): | 2615 // insertelement into index 1 (result is stored in ElementR): |
| 2601 // Element := Element[0, 0] SourceVectOperand[0, 0] | 2616 // ElementR := ElementR[0, 0] SourceVectRM[0, 0] |
| 2602 // Element := Element[3, 0] SourceVectOperand[2, 3] | 2617 // ElementR := ElementR[3, 0] SourceVectRM[2, 3] |
| 2603 // | 2618 // |
| 2604 // insertelement into index 2 (result is stored in T): | 2619 // insertelement into index 2 (result is stored in T): |
| 2605 // T := SourceVectOperand | 2620 // T := SourceVectRM |
| 2606 // Element := Element[0, 0] T[0, 3] | 2621 // ElementR := ElementR[0, 0] T[0, 3] |
| 2607 // T := T[0, 1] Element[0, 3] | 2622 // T := T[0, 1] ElementR[0, 3] |
| 2608 // | 2623 // |
| 2609 // insertelement into index 3 (result is stored in T): | 2624 // insertelement into index 3 (result is stored in T): |
| 2610 // T := SourceVectOperand | 2625 // T := SourceVectRM |
| 2611 // Element := Element[0, 0] T[0, 2] | 2626 // ElementR := ElementR[0, 0] T[0, 2] |
| 2612 // T := T[0, 1] Element[3, 0] | 2627 // T := T[0, 1] ElementR[3, 0] |
| 2613 const unsigned char Mask1[3] = {0, 192, 128}; | 2628 const unsigned char Mask1[3] = {0, 192, 128}; |
| 2614 const unsigned char Mask2[3] = {227, 196, 52}; | 2629 const unsigned char Mask2[3] = {227, 196, 52}; |
| 2615 | 2630 |
| 2616 Constant *Mask1Constant = Ctx->getConstantInt(IceType_i8, Mask1[Index - 1]); | 2631 Constant *Mask1Constant = Ctx->getConstantInt(IceType_i8, Mask1[Index - 1]); |
| 2617 Constant *Mask2Constant = Ctx->getConstantInt(IceType_i8, Mask2[Index - 1]); | 2632 Constant *Mask2Constant = Ctx->getConstantInt(IceType_i8, Mask2[Index - 1]); |
| 2618 | 2633 |
| 2619 // ALIGNHACK: Force vector operands to registers in instructions that | 2634 // ALIGNHACK: Force vector operands to registers in instructions that |
| 2620 // require aligned memory operands until support for stack alignment | 2635 // require aligned memory operands until support for stack alignment |
| 2621 // is implemented. | 2636 // is implemented. |
| 2622 #define ALIGN_HACK(Vect) legalizeToVar((Vect)) | 2637 #define ALIGN_HACK(Vect) legalizeToVar((Vect)) |
| 2623 if (Index == 1) { | 2638 if (Index == 1) { |
| 2624 SourceVectOperand = ALIGN_HACK(SourceVectOperand); | 2639 SourceVectRM = ALIGN_HACK(SourceVectRM); |
| 2625 _shufps(Element, SourceVectOperand, Mask1Constant); | 2640 _shufps(ElementR, SourceVectRM, Mask1Constant); |
| 2626 _shufps(Element, SourceVectOperand, Mask2Constant); | 2641 _shufps(ElementR, SourceVectRM, Mask2Constant); |
| 2627 _movp(Inst->getDest(), Element); | 2642 _movp(Inst->getDest(), ElementR); |
| 2628 } else { | 2643 } else { |
| 2629 Variable *T = makeReg(Ty); | 2644 Variable *T = makeReg(Ty); |
| 2630 _movp(T, SourceVectOperand); | 2645 _movp(T, SourceVectRM); |
| 2631 _shufps(Element, T, Mask1Constant); | 2646 _shufps(ElementR, T, Mask1Constant); |
| 2632 _shufps(T, Element, Mask2Constant); | 2647 _shufps(T, ElementR, Mask2Constant); |
| 2633 _movp(Inst->getDest(), T); | 2648 _movp(Inst->getDest(), T); |
| 2634 } | 2649 } |
| 2635 #undef ALIGN_HACK | 2650 #undef ALIGN_HACK |
| 2636 } else { | 2651 } else { |
| 2637 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); | 2652 assert(Ty == IceType_v16i8 || Ty == IceType_v16i1); |
| 2638 // Spill the value to a stack slot and perform the insertion in | 2653 // Spill the value to a stack slot and perform the insertion in |
| 2639 // memory. | 2654 // memory. |
| 2640 // | 2655 // |
| 2641 // TODO(wala): use legalize(SourceVectOperand, Legal_Mem) when | 2656 // TODO(wala): use legalize(SourceVectRM, Legal_Mem) when |
| 2642 // support for legalizing to mem is implemented. | 2657 // support for legalizing to mem is implemented. |
| 2643 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); | 2658 Variable *Slot = Func->makeVariable(Ty, Context.getNode()); |
| 2644 Slot->setWeight(RegWeight::Zero); | 2659 Slot->setWeight(RegWeight::Zero); |
| 2645 _movp(Slot, legalizeToVar(SourceVectOperand)); | 2660 _movp(Slot, legalizeToVar(SourceVectNotLegalized)); |
| 2646 | 2661 |
| 2647 // Compute the location of the position to insert in memory. | 2662 // Compute the location of the position to insert in memory. |
| 2648 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); | 2663 unsigned Offset = Index * typeWidthInBytes(InVectorElementTy); |
| 2649 OperandX8632Mem *Loc = | 2664 OperandX8632Mem *Loc = |
| 2650 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); | 2665 getMemoryOperandForStackSlot(InVectorElementTy, Slot, Offset); |
| 2651 _store(legalizeToVar(ElementToInsert), Loc); | 2666 _store(legalizeToVar(ElementToInsertNotLegalized), Loc); |
| 2652 | 2667 |
| 2653 Variable *T = makeReg(Ty); | 2668 Variable *T = makeReg(Ty); |
| 2654 _movp(T, Slot); | 2669 _movp(T, Slot); |
| 2655 _movp(Inst->getDest(), T); | 2670 _movp(Inst->getDest(), T); |
| 2656 } | 2671 } |
| 2657 } | 2672 } |
| 2658 | 2673 |
| 2659 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { | 2674 void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
| 2660 switch (Instr->getIntrinsicInfo().ID) { | 2675 switch (Instr->getIntrinsicInfo().ID) { |
| 2661 case Intrinsics::AtomicCmpxchg: { | 2676 case Intrinsics::AtomicCmpxchg: { |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3566 | 3581 |
| 3567 void TargetX8632::lowerSelect(const InstSelect *Inst) { | 3582 void TargetX8632::lowerSelect(const InstSelect *Inst) { |
| 3568 Variable *Dest = Inst->getDest(); | 3583 Variable *Dest = Inst->getDest(); |
| 3569 Operand *SrcT = Inst->getTrueOperand(); | 3584 Operand *SrcT = Inst->getTrueOperand(); |
| 3570 Operand *SrcF = Inst->getFalseOperand(); | 3585 Operand *SrcF = Inst->getFalseOperand(); |
| 3571 Operand *Condition = Inst->getCondition(); | 3586 Operand *Condition = Inst->getCondition(); |
| 3572 | 3587 |
| 3573 if (isVectorType(Dest->getType())) { | 3588 if (isVectorType(Dest->getType())) { |
| 3574 Type SrcTy = SrcT->getType(); | 3589 Type SrcTy = SrcT->getType(); |
| 3575 Variable *T = makeReg(SrcTy); | 3590 Variable *T = makeReg(SrcTy); |
| 3591 Operand *SrcTRM = legalize(SrcT, Legal_Reg | Legal_Mem); | |
| 3592 Operand *SrcFRM = legalize(SrcF, Legal_Reg | Legal_Mem); | |
| 3576 // ALIGNHACK: Until stack alignment support is implemented, vector | 3593 // ALIGNHACK: Until stack alignment support is implemented, vector |
| 3577 // instructions need to have vector operands in registers. Once | 3594 // instructions need to have vector operands in registers. Once |
| 3578 // there is support for stack alignment, LEGAL_HACK can be removed. | 3595 // there is support for stack alignment, LEGAL_HACK can be removed. |
| 3579 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) | 3596 #define LEGAL_HACK(Vect) legalizeToVar((Vect)) |
| 3580 if (InstructionSet >= SSE4_1) { | 3597 if (InstructionSet >= SSE4_1) { |
| 3581 // TODO(wala): If the condition operand is a constant, use blendps | 3598 // TODO(wala): If the condition operand is a constant, use blendps |
| 3582 // or pblendw. | 3599 // or pblendw. |
| 3583 // | 3600 // |
| 3584 // Use blendvps or pblendvb to implement select. | 3601 // Use blendvps or pblendvb to implement select. |
| 3585 if (SrcTy == IceType_v4i1 || SrcTy == IceType_v4i32 || | 3602 if (SrcTy == IceType_v4i1 || SrcTy == IceType_v4i32 || |
| 3586 SrcTy == IceType_v4f32) { | 3603 SrcTy == IceType_v4f32) { |
| 3604 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); | |
| 3587 Variable *xmm0 = makeReg(IceType_v4i32, Reg_xmm0); | 3605 Variable *xmm0 = makeReg(IceType_v4i32, Reg_xmm0); |
| 3588 _movp(xmm0, Condition); | 3606 _movp(xmm0, ConditionRM); |
| 3589 _psll(xmm0, Ctx->getConstantInt(IceType_i8, 31)); | 3607 _psll(xmm0, Ctx->getConstantInt(IceType_i8, 31)); |
| 3590 _movp(T, SrcF); | 3608 _movp(T, SrcFRM); |
| 3591 _blendvps(T, LEGAL_HACK(SrcT), xmm0); | 3609 _blendvps(T, LEGAL_HACK(SrcTRM), xmm0); |
| 3592 _movp(Dest, T); | 3610 _movp(Dest, T); |
| 3593 } else { | 3611 } else { |
| 3594 assert(typeNumElements(SrcTy) == 8 || typeNumElements(SrcTy) == 16); | 3612 assert(typeNumElements(SrcTy) == 8 || typeNumElements(SrcTy) == 16); |
| 3595 Type SignExtTy = Condition->getType() == IceType_v8i1 ? IceType_v8i16 | 3613 Type SignExtTy = Condition->getType() == IceType_v8i1 ? IceType_v8i16 |
| 3596 : IceType_v16i8; | 3614 : IceType_v16i8; |
| 3597 Variable *xmm0 = makeReg(SignExtTy, Reg_xmm0); | 3615 Variable *xmm0 = makeReg(SignExtTy, Reg_xmm0); |
| 3598 lowerCast(InstCast::create(Func, InstCast::Sext, xmm0, Condition)); | 3616 lowerCast(InstCast::create(Func, InstCast::Sext, xmm0, Condition)); |
| 3599 _movp(T, SrcF); | 3617 _movp(T, SrcFRM); |
| 3600 _pblendvb(T, LEGAL_HACK(SrcT), xmm0); | 3618 _pblendvb(T, LEGAL_HACK(SrcTRM), xmm0); |
| 3601 _movp(Dest, T); | 3619 _movp(Dest, T); |
| 3602 } | 3620 } |
| 3603 return; | 3621 return; |
| 3604 } | 3622 } |
| 3605 // Lower select without SSE4.1: | 3623 // Lower select without SSE4.1: |
| 3606 // a=d?b:c ==> | 3624 // a=d?b:c ==> |
| 3607 // if elementtype(d) != i1: | 3625 // if elementtype(d) != i1: |
| 3608 // d=sext(d); | 3626 // d=sext(d); |
| 3609 // a=(b&d)|(c&~d); | 3627 // a=(b&d)|(c&~d); |
| 3610 Variable *T2 = makeReg(SrcTy); | 3628 Variable *T2 = makeReg(SrcTy); |
| 3611 // Sign extend the condition operand if applicable. | 3629 // Sign extend the condition operand if applicable. |
| 3612 if (SrcTy == IceType_v4f32) { | 3630 if (SrcTy == IceType_v4f32) { |
| 3613 // The sext operation takes only integer arguments. | 3631 // The sext operation takes only integer arguments. |
| 3614 Variable *T3 = Func->makeVariable(IceType_v4i32, Context.getNode()); | 3632 Variable *T3 = Func->makeVariable(IceType_v4i32, Context.getNode()); |
| 3615 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); | 3633 lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition)); |
| 3616 _movp(T, T3); | 3634 _movp(T, T3); |
| 3617 } else if (typeElementType(SrcTy) != IceType_i1) { | 3635 } else if (typeElementType(SrcTy) != IceType_i1) { |
| 3618 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); | 3636 lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition)); |
| 3619 } else { | 3637 } else { |
| 3620 _movp(T, Condition); | 3638 Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem); |
| 3639 _movp(T, ConditionRM); | |
| 3621 } | 3640 } |
| 3622 _movp(T2, T); | 3641 _movp(T2, T); |
| 3623 _pand(T, LEGAL_HACK(SrcT)); | 3642 _pand(T, LEGAL_HACK(SrcTRM)); |
| 3624 _pandn(T2, LEGAL_HACK(SrcF)); | 3643 _pandn(T2, LEGAL_HACK(SrcFRM)); |
| 3625 _por(T, T2); | 3644 _por(T, T2); |
| 3626 _movp(Dest, T); | 3645 _movp(Dest, T); |
| 3627 #undef LEGAL_HACK | 3646 #undef LEGAL_HACK |
| 3628 | 3647 |
| 3629 return; | 3648 return; |
| 3630 } | 3649 } |
| 3631 | 3650 |
| 3632 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: | 3651 // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1: |
| 3633 Operand *ConditionRMI = legalize(Condition); | 3652 Operand *ConditionRMI = legalize(Condition); |
| 3634 Constant *Zero = Ctx->getConstantZero(IceType_i32); | 3653 Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3940 | 3959 |
| 3941 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { | 3960 OperandX8632Mem *TargetX8632::FormMemoryOperand(Operand *Operand, Type Ty) { |
| 3942 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); | 3961 OperandX8632Mem *Mem = llvm::dyn_cast<OperandX8632Mem>(Operand); |
| 3943 // It may be the case that address mode optimization already creates | 3962 // It may be the case that address mode optimization already creates |
| 3944 // an OperandX8632Mem, so in that case it wouldn't need another level | 3963 // an OperandX8632Mem, so in that case it wouldn't need another level |
| 3945 // of transformation. | 3964 // of transformation. |
| 3946 if (!Mem) { | 3965 if (!Mem) { |
| 3947 Variable *Base = llvm::dyn_cast<Variable>(Operand); | 3966 Variable *Base = llvm::dyn_cast<Variable>(Operand); |
| 3948 Constant *Offset = llvm::dyn_cast<Constant>(Operand); | 3967 Constant *Offset = llvm::dyn_cast<Constant>(Operand); |
| 3949 assert(Base || Offset); | 3968 assert(Base || Offset); |
| 3969 if (Offset) { | |
| 3970 assert(llvm::isa<ConstantInteger>(Offset) || | |
| 3971 llvm::isa<ConstantRelocatable>(Offset)); | |
| 3972 } | |
| 3950 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); | 3973 Mem = OperandX8632Mem::create(Func, Ty, Base, Offset); |
| 3951 } | 3974 } |
| 3952 return llvm::cast<OperandX8632Mem>(legalize(Mem)); | 3975 return llvm::cast<OperandX8632Mem>(legalize(Mem)); |
| 3953 } | 3976 } |
| 3954 | 3977 |
| 3955 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { | 3978 Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) { |
| 3956 // There aren't any 64-bit integer registers for x86-32. | 3979 // There aren't any 64-bit integer registers for x86-32. |
| 3957 assert(Type != IceType_i64); | 3980 assert(Type != IceType_i64); |
| 3958 Variable *Reg = Func->makeVariable(Type, Context.getNode()); | 3981 Variable *Reg = Func->makeVariable(Type, Context.getNode()); |
| 3959 if (RegNum == Variable::NoRegister) | 3982 if (RegNum == Variable::NoRegister) |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4039 // It would be better to prefix with ".L$" instead of "L$", but | 4062 // It would be better to prefix with ".L$" instead of "L$", but |
| 4040 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 4063 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
| 4041 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 4064 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
| 4042 } | 4065 } |
| 4043 | 4066 |
| 4044 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 4067 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
| 4045 Ostream &Str = Ctx->getStrEmit(); | 4068 Ostream &Str = Ctx->getStrEmit(); |
| 4046 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 4069 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
| 4047 } | 4070 } |
| 4048 | 4071 |
| 4072 void ConstantUndef::emit(GlobalContext *Ctx) const { | |
| 4073 (void)Ctx; | |
|
Jim Stichnoth
2014/07/31 00:52:42
Can you declare the function as "void ConstantUnde
wala
2014/07/31 16:06:04
Done.
| |
| 4074 llvm_unreachable("undef value encountered by emitter."); | |
| 4075 } | |
| 4076 | |
| 4049 TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) | 4077 TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) |
| 4050 : TargetGlobalInitLowering(Ctx) {} | 4078 : TargetGlobalInitLowering(Ctx) {} |
| 4051 | 4079 |
| 4052 namespace { | 4080 namespace { |
| 4053 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } | 4081 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } |
| 4054 } | 4082 } |
| 4055 | 4083 |
| 4056 void TargetGlobalInitX8632::lower(const IceString &Name, SizeT Align, | 4084 void TargetGlobalInitX8632::lower(const IceString &Name, SizeT Align, |
| 4057 bool IsInternal, bool IsConst, | 4085 bool IsInternal, bool IsConst, |
| 4058 bool IsZeroInitializer, SizeT Size, | 4086 bool IsZeroInitializer, SizeT Size, |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4136 for (SizeT i = 0; i < Size; ++i) { | 4164 for (SizeT i = 0; i < Size; ++i) { |
| 4137 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 4165 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 4138 } | 4166 } |
| 4139 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4167 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4140 } | 4168 } |
| 4141 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 4169 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
| 4142 << "\n"; | 4170 << "\n"; |
| 4143 } | 4171 } |
| 4144 | 4172 |
| 4145 } // end of namespace Ice | 4173 } // end of namespace Ice |
| OLD | NEW |