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 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1312 eax = makeReg(IceType_i32, Reg_eax); | 1312 eax = makeReg(IceType_i32, Reg_eax); |
1313 edx = makeReg(IceType_i32, Reg_edx); | 1313 edx = makeReg(IceType_i32, Reg_edx); |
1314 break; | 1314 break; |
1315 case IceType_f32: | 1315 case IceType_f32: |
1316 case IceType_f64: | 1316 case IceType_f64: |
1317 // Leave eax==edx==NULL, and capture the result with the fstp | 1317 // Leave eax==edx==NULL, and capture the result with the fstp |
1318 // instruction. | 1318 // instruction. |
1319 break; | 1319 break; |
1320 } | 1320 } |
1321 } | 1321 } |
1322 Operand *CallTarget = legalize(Instr->getCallTarget()); | 1322 // TODO(stichnot): LEAHACK: remove Legal_All (and use default) once |
| 1323 // a proper emitter is used. |
| 1324 Operand *CallTarget = legalize(Instr->getCallTarget(), Legal_All); |
1323 Inst *NewCall = InstX8632Call::create(Func, eax, CallTarget); | 1325 Inst *NewCall = InstX8632Call::create(Func, eax, CallTarget); |
1324 Context.insert(NewCall); | 1326 Context.insert(NewCall); |
1325 if (edx) | 1327 if (edx) |
1326 Context.insert(InstFakeDef::create(Func, edx)); | 1328 Context.insert(InstFakeDef::create(Func, edx)); |
1327 | 1329 |
1328 // Add the appropriate offset to esp. | 1330 // Add the appropriate offset to esp. |
1329 if (StackOffset) { | 1331 if (StackOffset) { |
1330 Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp); | 1332 Variable *esp = Func->getTarget()->getPhysicalRegister(Reg_esp); |
1331 _add(esp, Ctx->getConstantInt(IceType_i32, StackOffset)); | 1333 _add(esp, Ctx->getConstantInt(IceType_i32, StackOffset)); |
1332 } | 1334 } |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2438 // | 2440 // |
2439 // If in the future the implementation is changed to lower undef | 2441 // If in the future the implementation is changed to lower undef |
2440 // values to uninitialized registers, a FakeDef will be needed: | 2442 // values to uninitialized registers, a FakeDef will be needed: |
2441 // Context.insert(InstFakeDef::create(Func, Reg)); | 2443 // Context.insert(InstFakeDef::create(Func, Reg)); |
2442 // This is in order to ensure that the live range of Reg is not | 2444 // This is in order to ensure that the live range of Reg is not |
2443 // overestimated. If the constant being lowered is a 64 bit value, | 2445 // overestimated. If the constant being lowered is a 64 bit value, |
2444 // then the result should be split and the lo and hi components will | 2446 // then the result should be split and the lo and hi components will |
2445 // need to go in uninitialized registers. | 2447 // need to go in uninitialized registers. |
2446 From = Ctx->getConstantZero(From->getType()); | 2448 From = Ctx->getConstantZero(From->getType()); |
2447 } | 2449 } |
2448 bool NeedsReg = | 2450 bool NeedsReg = false; |
2449 !(Allowed & Legal_Imm) || | 2451 if (!(Allowed & Legal_Imm)) |
2450 // ConstantFloat and ConstantDouble are actually memory operands. | 2452 // Immediate specifically not allowed |
2451 (!(Allowed & Legal_Mem) && | 2453 NeedsReg = true; |
2452 (From->getType() == IceType_f32 || From->getType() == IceType_f64)); | 2454 // TODO(stichnot): LEAHACK: remove Legal_Reloc once a proper |
| 2455 // emitter is used. |
| 2456 if (!(Allowed & Legal_Reloc) && llvm::isa<ConstantRelocatable>(From)) |
| 2457 // Relocatable specifically not allowed |
| 2458 NeedsReg = true; |
| 2459 if (!(Allowed & Legal_Mem) && |
| 2460 (From->getType() == IceType_f32 || From->getType() == IceType_f64)) |
| 2461 // On x86, FP constants are lowered to mem operands. |
| 2462 NeedsReg = true; |
2453 if (NeedsReg) { | 2463 if (NeedsReg) { |
2454 Variable *Reg = makeReg(From->getType(), RegNum); | 2464 Variable *Reg = makeReg(From->getType(), RegNum); |
2455 _mov(Reg, From); | 2465 _mov(Reg, From); |
2456 From = Reg; | 2466 From = Reg; |
2457 } | 2467 } |
2458 return From; | 2468 return From; |
2459 } | 2469 } |
2460 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { | 2470 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { |
2461 // We need a new physical register for the operand if: | 2471 // We need a new physical register for the operand if: |
2462 // Mem is not allowed and Var->getRegNum() is unknown, or | 2472 // Mem is not allowed and Var->getRegNum() is unknown, or |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2574 // It would be better to prefix with ".L$" instead of "L$", but | 2584 // It would be better to prefix with ".L$" instead of "L$", but |
2575 // llvm-mc doesn't parse "dword ptr [.L$foo]". | 2585 // llvm-mc doesn't parse "dword ptr [.L$foo]". |
2576 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; | 2586 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; |
2577 } | 2587 } |
2578 | 2588 |
2579 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { | 2589 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { |
2580 Ostream &Str = Ctx->getStrEmit(); | 2590 Ostream &Str = Ctx->getStrEmit(); |
2581 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; | 2591 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; |
2582 } | 2592 } |
2583 | 2593 |
| 2594 TargetGlobalInitX8632::TargetGlobalInitX8632(GlobalContext *Ctx) |
| 2595 : TargetGlobalInitLowering(Ctx) {} |
| 2596 |
| 2597 namespace { |
| 2598 char hexdigit(unsigned X) { return X < 10 ? '0' + X : 'A' + X - 10; } |
| 2599 } |
| 2600 |
| 2601 void TargetGlobalInitX8632::lower(const IceString &Name, SizeT Align, |
| 2602 bool IsInternal, bool IsConst, |
| 2603 bool IsZeroInitializer, SizeT Size, |
| 2604 const char *Data, bool DisableTranslation) { |
| 2605 if (Ctx->isVerbose()) { |
| 2606 // TODO: Consider moving the dump output into the driver to be |
| 2607 // reused for all targets. |
| 2608 Ostream &Str = Ctx->getStrDump(); |
| 2609 Str << "@" << Name << " = " << (IsInternal ? "internal" : "external"); |
| 2610 Str << (IsConst ? " constant" : " global"); |
| 2611 Str << " [" << Size << " x i8] "; |
| 2612 if (IsZeroInitializer) { |
| 2613 Str << "zeroinitializer"; |
| 2614 } else { |
| 2615 Str << "c\""; |
| 2616 // Code taken from PrintEscapedString() in AsmWriter.cpp. Keep |
| 2617 // the strings in the same format as the .ll file for practical |
| 2618 // diffing. |
| 2619 for (uint64_t i = 0; i < Size; ++i) { |
| 2620 unsigned char C = Data[i]; |
| 2621 if (isprint(C) && C != '\\' && C != '"') |
| 2622 Str << C; |
| 2623 else |
| 2624 Str << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); |
| 2625 } |
| 2626 Str << "\""; |
| 2627 } |
| 2628 Str << ", align " << Align << "\n"; |
| 2629 } |
| 2630 |
| 2631 if (DisableTranslation) |
| 2632 return; |
| 2633 |
| 2634 Ostream &Str = Ctx->getStrEmit(); |
| 2635 // constant: |
| 2636 // .section .rodata,"a",@progbits |
| 2637 // .align ALIGN |
| 2638 // .byte ... |
| 2639 // .size NAME, SIZE |
| 2640 |
| 2641 // non-constant: |
| 2642 // .data |
| 2643 // .align ALIGN |
| 2644 // .byte ... |
| 2645 // .size NAME, SIZE |
| 2646 |
| 2647 // zeroinitializer (constant): |
| 2648 // (.section or .data as above) |
| 2649 // .align ALIGN |
| 2650 // .zero SIZE |
| 2651 // .size NAME, SIZE |
| 2652 |
| 2653 // zeroinitializer (non-constant): |
| 2654 // (.section or .data as above) |
| 2655 // .comm NAME, SIZE, ALIGN |
| 2656 // .local NAME |
| 2657 |
| 2658 IceString MangledName = Ctx->mangleName(Name); |
| 2659 // Start a new section. |
| 2660 if (IsConst) { |
| 2661 Str << "\t.section\t.rodata,\"a\",@progbits\n"; |
| 2662 } else { |
| 2663 Str << "\t.type\t" << MangledName << ",@object\n"; |
| 2664 Str << "\t.data\n"; |
| 2665 } |
| 2666 if (IsZeroInitializer) { |
| 2667 if (IsConst) { |
| 2668 Str << "\t.align\t" << Align << "\n"; |
| 2669 Str << MangledName << ":\n"; |
| 2670 Str << "\t.zero\t" << Size << "\n"; |
| 2671 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 2672 } else { |
| 2673 // TODO(stichnot): Put the appropriate non-constant |
| 2674 // zeroinitializers in a .bss section to reduce object size. |
| 2675 Str << "\t.comm\t" << MangledName << ", " << Size << ", " << Align |
| 2676 << "\n"; |
| 2677 } |
| 2678 } else { |
| 2679 Str << "\t.align\t" << Align << "\n"; |
| 2680 Str << MangledName << ":\n"; |
| 2681 for (SizeT i = 0; i < Size; ++i) { |
| 2682 Str << "\t.byte\t" << (((unsigned)Data[i]) & 0xff) << "\n"; |
| 2683 } |
| 2684 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 2685 } |
| 2686 Str << "\t" << (IsInternal ? ".local" : ".global") << "\t" << MangledName |
| 2687 << "\n"; |
| 2688 } |
| 2689 |
2584 } // end of namespace Ice | 2690 } // end of namespace Ice |
OLD | NEW |