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 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 153 { | 153 { |
| 154 // Define a temporary set of enum values based on low-level | 154 // Define a temporary set of enum values based on low-level |
| 155 // table entries. | 155 // table entries. |
| 156 enum _tmp_enum { | 156 enum _tmp_enum { |
| 157 #define X(tag, cvt, sdss, width) _tmp_##tag, | 157 #define X(tag, cvt, sdss, width) _tmp_##tag, |
| 158 ICETYPEX8632_TABLE | 158 ICETYPEX8632_TABLE |
| 159 #undef X | 159 #undef X |
| 160 _num | 160 _num |
| 161 }; | 161 }; |
| 162 // Define a set of constants based on high-level table entries. | 162 // Define a set of constants based on high-level table entries. |
| 163 #define X(tag, size, align, str) static const int _table1_##tag = tag; | 163 #define X(tag, size, align, elts, elty, str) \ |
| 164 static const int _table1_##tag = tag; | |
| 164 ICETYPE_TABLE; | 165 ICETYPE_TABLE; |
| 165 #undef X | 166 #undef X |
| 166 // Define a set of constants based on low-level table entries, | 167 // Define a set of constants based on low-level table entries, |
| 167 // and ensure the table entry keys are consistent. | 168 // and ensure the table entry keys are consistent. |
| 168 #define X(tag, cvt, sdss, width) \ | 169 #define X(tag, cvt, sdss, width) \ |
| 169 static const int _table2_##tag = _tmp_##tag; \ | 170 static const int _table2_##tag = _tmp_##tag; \ |
| 170 STATIC_ASSERT(_table1_##tag == _table2_##tag); | 171 STATIC_ASSERT(_table1_##tag == _table2_##tag); |
| 171 ICETYPEX8632_TABLE; | 172 ICETYPEX8632_TABLE; |
| 172 #undef X | 173 #undef X |
| 173 // Repeat the static asserts with respect to the high-level | 174 // Repeat the static asserts with respect to the high-level |
| 174 // table entries in case the high-level table has extra entries. | 175 // table entries in case the high-level table has extra entries. |
| 175 #define X(tag, size, align, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); | 176 #define X(tag, size, align, elts, elty, str) \ |
| 177 STATIC_ASSERT(_table1_##tag == _table2_##tag); | |
| 176 ICETYPE_TABLE; | 178 ICETYPE_TABLE; |
| 177 #undef X | 179 #undef X |
| 178 } | 180 } |
| 179 } | 181 } |
| 180 | 182 |
| 181 } // end of anonymous namespace | 183 } // end of anonymous namespace |
| 182 | 184 |
| 183 TargetX8632::TargetX8632(Cfg *Func) | 185 TargetX8632::TargetX8632(Cfg *Func) |
| 184 : TargetLowering(Func), IsEbpBasedFrame(false), FrameSizeLocals(0), | 186 : TargetLowering(Func), IsEbpBasedFrame(false), FrameSizeLocals(0), |
| 185 LocalsSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), | 187 LocalsSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), |
| 186 PhysicalRegisters(VarList(Reg_NUM)) { | 188 PhysicalRegisters(VarList(Reg_NUM)) { |
| 187 // TODO: Don't initialize IntegerRegisters and friends every time. | 189 // TODO: Don't initialize IntegerRegisters and friends every time. |
| 188 // Instead, initialize in some sort of static initializer for the | 190 // Instead, initialize in some sort of static initializer for the |
| 189 // class. | 191 // class. |
| 190 llvm::SmallBitVector IntegerRegisters(Reg_NUM); | 192 llvm::SmallBitVector IntegerRegisters(Reg_NUM); |
| 191 llvm::SmallBitVector IntegerRegistersI8(Reg_NUM); | 193 llvm::SmallBitVector IntegerRegistersI8(Reg_NUM); |
| 192 llvm::SmallBitVector FloatRegisters(Reg_NUM); | 194 llvm::SmallBitVector FloatRegisters(Reg_NUM); |
| 195 llvm::SmallBitVector VectorRegisters(Reg_NUM); | |
| 193 llvm::SmallBitVector InvalidRegisters(Reg_NUM); | 196 llvm::SmallBitVector InvalidRegisters(Reg_NUM); |
| 194 ScratchRegs.resize(Reg_NUM); | 197 ScratchRegs.resize(Reg_NUM); |
| 195 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ | 198 #define X(val, init, name, name16, name8, scratch, preserved, stackptr, \ |
| 196 frameptr, isI8, isInt, isFP) \ | 199 frameptr, isI8, isInt, isFP) \ |
| 197 IntegerRegisters[val] = isInt; \ | 200 IntegerRegisters[val] = isInt; \ |
| 198 IntegerRegistersI8[val] = isI8; \ | 201 IntegerRegistersI8[val] = isI8; \ |
| 199 FloatRegisters[val] = isFP; \ | 202 FloatRegisters[val] = isFP; \ |
| 203 VectorRegisters[val] = isFP; \ | |
|
jvoung (off chromium)
2014/07/07 22:48:51
Is there any reason to have a separate VectorRegis
wala
2014/07/07 23:11:20
It's for clarity.
| |
| 200 ScratchRegs[val] = scratch; | 204 ScratchRegs[val] = scratch; |
| 201 REGX8632_TABLE; | 205 REGX8632_TABLE; |
| 202 #undef X | 206 #undef X |
| 203 TypeToRegisterSet[IceType_void] = InvalidRegisters; | 207 TypeToRegisterSet[IceType_void] = InvalidRegisters; |
| 204 TypeToRegisterSet[IceType_i1] = IntegerRegistersI8; | 208 TypeToRegisterSet[IceType_i1] = IntegerRegistersI8; |
| 205 TypeToRegisterSet[IceType_i8] = IntegerRegistersI8; | 209 TypeToRegisterSet[IceType_i8] = IntegerRegistersI8; |
| 206 TypeToRegisterSet[IceType_i16] = IntegerRegisters; | 210 TypeToRegisterSet[IceType_i16] = IntegerRegisters; |
| 207 TypeToRegisterSet[IceType_i32] = IntegerRegisters; | 211 TypeToRegisterSet[IceType_i32] = IntegerRegisters; |
| 208 TypeToRegisterSet[IceType_i64] = IntegerRegisters; | 212 TypeToRegisterSet[IceType_i64] = IntegerRegisters; |
| 209 TypeToRegisterSet[IceType_f32] = FloatRegisters; | 213 TypeToRegisterSet[IceType_f32] = FloatRegisters; |
| 210 TypeToRegisterSet[IceType_f64] = FloatRegisters; | 214 TypeToRegisterSet[IceType_f64] = FloatRegisters; |
| 215 TypeToRegisterSet[IceType_v4i1] = VectorRegisters; | |
| 216 TypeToRegisterSet[IceType_v8i1] = VectorRegisters; | |
| 217 TypeToRegisterSet[IceType_v16i1] = VectorRegisters; | |
| 218 TypeToRegisterSet[IceType_v16i8] = VectorRegisters; | |
| 219 TypeToRegisterSet[IceType_v8i16] = VectorRegisters; | |
| 220 TypeToRegisterSet[IceType_v4i32] = VectorRegisters; | |
| 221 TypeToRegisterSet[IceType_v4f32] = VectorRegisters; | |
| 211 } | 222 } |
| 212 | 223 |
| 213 void TargetX8632::translateO2() { | 224 void TargetX8632::translateO2() { |
| 214 GlobalContext *Context = Func->getContext(); | 225 GlobalContext *Context = Func->getContext(); |
| 215 | 226 |
| 216 // Lower Phi instructions. | 227 // Lower Phi instructions. |
| 217 Timer T_placePhiLoads; | 228 Timer T_placePhiLoads; |
| 218 Func->placePhiLoads(); | 229 Func->placePhiLoads(); |
| 219 if (Func->hasError()) | 230 if (Func->hasError()) |
| 220 return; | 231 return; |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 break; | 1321 break; |
| 1311 case IceType_i64: | 1322 case IceType_i64: |
| 1312 eax = makeReg(IceType_i32, Reg_eax); | 1323 eax = makeReg(IceType_i32, Reg_eax); |
| 1313 edx = makeReg(IceType_i32, Reg_edx); | 1324 edx = makeReg(IceType_i32, Reg_edx); |
| 1314 break; | 1325 break; |
| 1315 case IceType_f32: | 1326 case IceType_f32: |
| 1316 case IceType_f64: | 1327 case IceType_f64: |
| 1317 // Leave eax==edx==NULL, and capture the result with the fstp | 1328 // Leave eax==edx==NULL, and capture the result with the fstp |
| 1318 // instruction. | 1329 // instruction. |
| 1319 break; | 1330 break; |
| 1331 case IceType_v4i1: | |
| 1332 case IceType_v8i1: | |
| 1333 case IceType_v16i1: | |
| 1334 case IceType_v16i8: | |
| 1335 case IceType_v8i16: | |
| 1336 case IceType_v4i32: | |
| 1337 case IceType_v4f32: { | |
| 1338 // TODO(wala): Handle return values of vector type in the caller. | |
| 1339 IceString Ty; | |
| 1340 llvm::raw_string_ostream BaseOS(Ty); | |
| 1341 Ostream OS(&BaseOS); | |
| 1342 OS << Dest->getType(); | |
| 1343 Func->setError("Unhandled dest type: " + BaseOS.str()); | |
| 1344 return; | |
| 1345 } | |
| 1320 } | 1346 } |
| 1321 } | 1347 } |
| 1322 // TODO(stichnot): LEAHACK: remove Legal_All (and use default) once | 1348 // TODO(stichnot): LEAHACK: remove Legal_All (and use default) once |
| 1323 // a proper emitter is used. | 1349 // a proper emitter is used. |
| 1324 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_All); | 1350 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_All); |
| 1325 Inst *NewCall = InstX8632Call::create(Func, eax, CallTarget); | 1351 Inst *NewCall = InstX8632Call::create(Func, eax, CallTarget); |
| 1326 Context.insert(NewCall); | 1352 Context.insert(NewCall); |
| 1327 if (edx) | 1353 if (edx) |
| 1328 Context.insert(InstFakeDef::create(Func, edx)); | 1354 Context.insert(InstFakeDef::create(Func, edx)); |
| 1329 | 1355 |
| (...skipping 936 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2266 if (Inst->hasRetValue()) { | 2292 if (Inst->hasRetValue()) { |
| 2267 Operand *Src0 = legalize(Inst->getRetValue()); | 2293 Operand *Src0 = legalize(Inst->getRetValue()); |
| 2268 if (Src0->getType() == IceType_i64) { | 2294 if (Src0->getType() == IceType_i64) { |
| 2269 Variable *eax = legalizeToVar(loOperand(Src0), false, Reg_eax); | 2295 Variable *eax = legalizeToVar(loOperand(Src0), false, Reg_eax); |
| 2270 Variable *edx = legalizeToVar(hiOperand(Src0), false, Reg_edx); | 2296 Variable *edx = legalizeToVar(hiOperand(Src0), false, Reg_edx); |
| 2271 Reg = eax; | 2297 Reg = eax; |
| 2272 Context.insert(InstFakeUse::create(Func, edx)); | 2298 Context.insert(InstFakeUse::create(Func, edx)); |
| 2273 } else if (Src0->getType() == IceType_f32 || | 2299 } else if (Src0->getType() == IceType_f32 || |
| 2274 Src0->getType() == IceType_f64) { | 2300 Src0->getType() == IceType_f64) { |
| 2275 _fld(Src0); | 2301 _fld(Src0); |
| 2302 } else if (isVectorType(Src0->getType())) { | |
| 2303 Reg = legalizeToVar(Src0, false, Reg_xmm0); | |
| 2276 } else { | 2304 } else { |
| 2277 _mov(Reg, Src0, Reg_eax); | 2305 _mov(Reg, Src0, Reg_eax); |
| 2278 } | 2306 } |
| 2279 } | 2307 } |
| 2280 _ret(Reg); | 2308 _ret(Reg); |
| 2281 // Add a fake use of esp to make sure esp stays alive for the entire | 2309 // Add a fake use of esp to make sure esp stays alive for the entire |
| 2282 // function. Otherwise post-call esp adjustments get dead-code | 2310 // function. Otherwise post-call esp adjustments get dead-code |
| 2283 // eliminated. TODO: Are there more places where the fake use | 2311 // eliminated. TODO: Are there more places where the fake use |
| 2284 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not | 2312 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not |
| 2285 // have a ret instruction. | 2313 // have a ret instruction. |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2387 _br(Inst->getLabelDefault()); | 2415 _br(Inst->getLabelDefault()); |
| 2388 } | 2416 } |
| 2389 | 2417 |
| 2390 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { | 2418 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { |
| 2391 const SizeT MaxSrcs = 0; | 2419 const SizeT MaxSrcs = 0; |
| 2392 Variable *Dest = NULL; | 2420 Variable *Dest = NULL; |
| 2393 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); | 2421 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); |
| 2394 lowerCall(Call); | 2422 lowerCall(Call); |
| 2395 } | 2423 } |
| 2396 | 2424 |
| 2425 // Helper for legalize() to emit the right code to lower an operand to a | |
| 2426 // register of the appropriate type. | |
| 2427 Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) { | |
| 2428 Type Ty = Src->getType(); | |
| 2429 Variable *Reg = makeReg(Ty, RegNum); | |
| 2430 if (isVectorType(Src->getType())) { | |
| 2431 _movp(Reg, Src); | |
| 2432 } else { | |
| 2433 _mov(Reg, Src); | |
| 2434 } | |
| 2435 return Reg; | |
| 2436 } | |
| 2437 | |
| 2397 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, | 2438 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, |
| 2398 bool AllowOverlap, int32_t RegNum) { | 2439 bool AllowOverlap, int32_t RegNum) { |
| 2399 // Assert that a physical register is allowed. To date, all calls | 2440 // Assert that a physical register is allowed. To date, all calls |
| 2400 // to legalize() allow a physical register. If a physical register | 2441 // to legalize() allow a physical register. If a physical register |
| 2401 // needs to be explicitly disallowed, then new code will need to be | 2442 // needs to be explicitly disallowed, then new code will need to be |
| 2402 // written to force a spill. | 2443 // written to force a spill. |
| 2403 assert(Allowed & Legal_Reg); | 2444 assert(Allowed & Legal_Reg); |
| 2404 // If we're asking for a specific physical register, make sure we're | 2445 // If we're asking for a specific physical register, make sure we're |
| 2405 // not allowing any other operand kinds. (This could be future | 2446 // not allowing any other operand kinds. (This could be future |
| 2406 // work, e.g. allow the shl shift amount to be either an immediate | 2447 // work, e.g. allow the shl shift amount to be either an immediate |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2419 if (Index) { | 2460 if (Index) { |
| 2420 RegIndex = legalizeToVar(Index, true); | 2461 RegIndex = legalizeToVar(Index, true); |
| 2421 } | 2462 } |
| 2422 if (Base != RegBase || Index != RegIndex) { | 2463 if (Base != RegBase || Index != RegIndex) { |
| 2423 From = OperandX8632Mem::create( | 2464 From = OperandX8632Mem::create( |
| 2424 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, | 2465 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, |
| 2425 Mem->getShift(), Mem->getSegmentRegister()); | 2466 Mem->getShift(), Mem->getSegmentRegister()); |
| 2426 } | 2467 } |
| 2427 | 2468 |
| 2428 if (!(Allowed & Legal_Mem)) { | 2469 if (!(Allowed & Legal_Mem)) { |
| 2429 Variable *Reg = makeReg(From->getType(), RegNum); | 2470 From = copyToReg(From, RegNum); |
| 2430 _mov(Reg, From, RegNum); | |
| 2431 From = Reg; | |
| 2432 } | 2471 } |
| 2433 return From; | 2472 return From; |
| 2434 } | 2473 } |
| 2435 if (llvm::isa<Constant>(From)) { | 2474 if (llvm::isa<Constant>(From)) { |
| 2436 if (llvm::isa<ConstantUndef>(From)) { | 2475 if (llvm::isa<ConstantUndef>(From)) { |
| 2437 // Lower undefs to zero. Another option is to lower undefs to an | 2476 // Lower undefs to zero. Another option is to lower undefs to an |
| 2438 // uninitialized register; however, using an uninitialized register | 2477 // uninitialized register; however, using an uninitialized register |
| 2439 // results in less predictable code. | 2478 // results in less predictable code. |
| 2440 // | 2479 // |
| 2441 // If in the future the implementation is changed to lower undef | 2480 // If in the future the implementation is changed to lower undef |
| 2442 // values to uninitialized registers, a FakeDef will be needed: | 2481 // values to uninitialized registers, a FakeDef will be needed: |
| 2443 // Context.insert(InstFakeDef::create(Func, Reg)); | 2482 // Context.insert(InstFakeDef::create(Func, Reg)); |
| 2444 // This is in order to ensure that the live range of Reg is not | 2483 // This is in order to ensure that the live range of Reg is not |
| 2445 // overestimated. If the constant being lowered is a 64 bit value, | 2484 // overestimated. If the constant being lowered is a 64 bit value, |
| 2446 // then the result should be split and the lo and hi components will | 2485 // then the result should be split and the lo and hi components will |
| 2447 // need to go in uninitialized registers. | 2486 // need to go in uninitialized registers. |
| 2448 From = Ctx->getConstantZero(From->getType()); | 2487 |
| 2488 if (isVectorType(From->getType())) { | |
| 2489 // There is no support for loading or emitting vector constants, so | |
| 2490 // undef values are instead initialized in registers. | |
| 2491 Variable *Reg = makeReg(From->getType(), RegNum); | |
| 2492 // Insert a FakeDef, since otherwise the live range of Reg might | |
| 2493 // be overestimated. | |
| 2494 Context.insert(InstFakeDef::create(Func, Reg)); | |
| 2495 _pxor(Reg, Reg); | |
| 2496 return Reg; | |
| 2497 } else { | |
| 2498 From = Ctx->getConstantZero(From->getType()); | |
| 2499 } | |
| 2449 } | 2500 } |
| 2450 bool NeedsReg = false; | 2501 bool NeedsReg = false; |
| 2451 if (!(Allowed & Legal_Imm)) | 2502 if (!(Allowed & Legal_Imm)) |
| 2452 // Immediate specifically not allowed | 2503 // Immediate specifically not allowed |
| 2453 NeedsReg = true; | 2504 NeedsReg = true; |
| 2454 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper | 2505 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
| 2455 // emitter is used. | 2506 // emitter is used. |
| 2456 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) | 2507 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) |
| 2457 // Relocatable specifically not allowed | 2508 // Relocatable specifically not allowed |
| 2458 NeedsReg = true; | 2509 NeedsReg = true; |
| 2459 if (!(Allowed & Legal_Mem) && | 2510 if (!(Allowed & Legal_Mem) && |
| 2460 (From->getType() == IceType_f32 || From->getType() == IceType_f64)) | 2511 (From->getType() == IceType_f32 || From->getType() == IceType_f64)) |
| 2461 // On x86, FP constants are lowered to mem operands. | 2512 // On x86, FP constants are lowered to mem operands. |
| 2462 NeedsReg = true; | 2513 NeedsReg = true; |
| 2463 if (NeedsReg) { | 2514 if (NeedsReg) { |
| 2464 Variable *Reg = makeReg(From->getType(), RegNum); | 2515 From = copyToReg(From, RegNum); |
| 2465 _mov(Reg, From); | |
| 2466 From = Reg; | |
| 2467 } | 2516 } |
| 2468 return From; | 2517 return From; |
| 2469 } | 2518 } |
| 2470 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { | 2519 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { |
| 2471 // We need a new physical register for the operand if: | 2520 // We need a new physical register for the operand if: |
| 2472 // Mem is not allowed and Var->getRegNum() is unknown, or | 2521 // Mem is not allowed and Var->getRegNum() is unknown, or |
| 2473 // RegNum is required and Var->getRegNum() doesn't match. | 2522 // RegNum is required and Var->getRegNum() doesn't match. |
| 2474 if ((!(Allowed & Legal_Mem) && !Var->hasReg()) || | 2523 if ((!(Allowed & Legal_Mem) && !Var->hasReg()) || |
| 2475 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { | 2524 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
| 2476 Variable *Reg = makeReg(From->getType(), RegNum); | 2525 Variable *Reg = copyToReg(From, RegNum); |
| 2477 if (RegNum == Variable::NoRegister) { | 2526 if (RegNum == Variable::NoRegister) { |
| 2478 Reg->setPreferredRegister(Var, AllowOverlap); | 2527 Reg->setPreferredRegister(Var, AllowOverlap); |
| 2479 } | 2528 } |
| 2480 _mov(Reg, From); | |
| 2481 From = Reg; | 2529 From = Reg; |
| 2482 } | 2530 } |
| 2483 return From; | 2531 return From; |
| 2484 } | 2532 } |
| 2485 llvm_unreachable("Unhandled operand kind in legalize()"); | 2533 llvm_unreachable("Unhandled operand kind in legalize()"); |
| 2486 return From; | 2534 return From; |
| 2487 } | 2535 } |
| 2488 | 2536 |
| 2489 // Provide a trivial wrapper to legalize() for this common usage. | 2537 // Provide a trivial wrapper to legalize() for this common usage. |
| 2490 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, | 2538 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2572 } | 2620 } |
| 2573 assert(AvailableTypedRegisters.any()); | 2621 assert(AvailableTypedRegisters.any()); |
| 2574 int32_t RegNum = AvailableTypedRegisters.find_first(); | 2622 int32_t RegNum = AvailableTypedRegisters.find_first(); |
| 2575 Var->setRegNum(RegNum); | 2623 Var->setRegNum(RegNum); |
| 2576 AvailableRegisters[RegNum] = false; | 2624 AvailableRegisters[RegNum] = false; |
| 2577 } | 2625 } |
| 2578 } | 2626 } |
| 2579 } | 2627 } |
| 2580 } | 2628 } |
| 2581 | 2629 |
| 2630 template <> void ConstantInteger::emit(GlobalContext *Ctx) const { | |
| 2631 Ostream &Str = Ctx->getStrEmit(); | |
| 2632 Str << getValue(); | |
| 2633 } | |
| 2634 | |
| 2582 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { | 2635 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { |
| 2583 Ostream &Str = Ctx->getStrEmit(); | 2636 Ostream &Str = Ctx->getStrEmit(); |
| 2584 // It would be better to prefix with ".L$" instead of "L$", but | 2637 // It would be better to prefix with ".L$" instead of "L$", but |
| 2585 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 2638 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
| 2586 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 2639 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
| 2587 } | 2640 } |
| 2588 | 2641 |
| 2589 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 2642 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
| 2590 Ostream &Str = Ctx->getStrEmit(); | 2643 Ostream &Str = Ctx->getStrEmit(); |
| 2591 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 2644 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2681 for (SizeT i = 0; i < Size; ++i) { | 2734 for (SizeT i = 0; i < Size; ++i) { |
| 2682 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; | 2735 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 2683 } | 2736 } |
| 2684 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 2737 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 2685 } | 2738 } |
| 2686 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName | 2739 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
| 2687 << "\n"; | 2740 << "\n"; |
| 2688 } | 2741 } |
| 2689 | 2742 |
| 2690 } // end of namespace Ice | 2743 } // end of namespace Ice |
| OLD | NEW |