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

Side by Side Diff: src/IceTargetLoweringX8632.cpp

Issue 353553004: Add support for vector types and vector constants. (Closed) Base URL: https://gerrit.chromium.org/gerrit/p/native_client/pnacl-subzero.git@master
Patch Set: 1) Fix alignment in type table. 2) Add VECT128_BYTES constant. 3) add _movp() function. Created 6 years, 6 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 #undef X 78 #undef X
79 }; 79 };
80 const size_t TableIcmp64Size = llvm::array_lengthof(TableIcmp64); 80 const size_t TableIcmp64Size = llvm::array_lengthof(TableIcmp64);
81 81
82 InstX8632Br::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) { 82 InstX8632Br::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
83 size_t Index = static_cast<size_t>(Cond); 83 size_t Index = static_cast<size_t>(Cond);
84 assert(Index < TableIcmp32Size); 84 assert(Index < TableIcmp32Size);
85 return TableIcmp32[Index].Mapping; 85 return TableIcmp32[Index].Mapping;
86 } 86 }
87 87
88 // Returns the type name as a valid assembly label.
89 IceString typeAsmLabel(Type Ty) {
90 IceString Result;
91 llvm::raw_string_ostream BaseOS(Result);
Jim Stichnoth 2014/06/27 18:30:16 I'd like to avoid unnecessarily building LLVM stre
wala 2014/06/27 21:09:19 To avoid snprintf, this function could emit the va
Karl 2014/07/01 20:31:55 I find this statement about not using raw_string_o
92 Ostream OS(&BaseOS);
93 unsigned NumElements = typeNumElements(Ty);
94 if (NumElements > 1) {
95 OS << "v" << NumElements;
96 }
97 OS << typeElementType(Ty);
98 return BaseOS.str();
99 }
100
88 // In some cases, there are x-macros tables for both high-level and 101 // In some cases, there are x-macros tables for both high-level and
89 // low-level instructions/operands that use the same enum key value. 102 // low-level instructions/operands that use the same enum key value.
90 // The tables are kept separate to maintain a proper separation 103 // The tables are kept separate to maintain a proper separation
91 // between abstraction layers. There is a risk that the tables 104 // between abstraction layers. There is a risk that the tables
92 // could get out of sync if enum values are reordered or if entries 105 // could get out of sync if enum values are reordered or if entries
93 // are added or deleted. This dummy function uses static_assert to 106 // are added or deleted. This dummy function uses static_assert to
94 // ensure everything is kept in sync. 107 // ensure everything is kept in sync.
95 void xMacroIntegrityCheck() { 108 void xMacroIntegrityCheck() {
96 // Validate the enum values in FCMPX8632_TABLE. 109 // Validate the enum values in FCMPX8632_TABLE.
97 { 110 {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 { 166 {
154 // Define a temporary set of enum values based on low-level 167 // Define a temporary set of enum values based on low-level
155 // table entries. 168 // table entries.
156 enum _tmp_enum { 169 enum _tmp_enum {
157 #define X(tag, cvt, sdss, width) _tmp_##tag, 170 #define X(tag, cvt, sdss, width) _tmp_##tag,
158 ICETYPEX8632_TABLE 171 ICETYPEX8632_TABLE
159 #undef X 172 #undef X
160 _num 173 _num
161 }; 174 };
162 // Define a set of constants based on high-level table entries. 175 // Define a set of constants based on high-level table entries.
163 #define X(tag, size, align, str) static const int _table1_##tag = tag; 176 #define X(tag, size, align, elts, elty, str) \
177 static const int _table1_##tag = tag;
164 ICETYPE_TABLE; 178 ICETYPE_TABLE;
165 #undef X 179 #undef X
166 // Define a set of constants based on low-level table entries, 180 // Define a set of constants based on low-level table entries,
167 // and ensure the table entry keys are consistent. 181 // and ensure the table entry keys are consistent.
168 #define X(tag, cvt, sdss, width) \ 182 #define X(tag, cvt, sdss, width) \
169 static const int _table2_##tag = _tmp_##tag; \ 183 static const int _table2_##tag = _tmp_##tag; \
170 STATIC_ASSERT(_table1_##tag == _table2_##tag); 184 STATIC_ASSERT(_table1_##tag == _table2_##tag);
171 ICETYPEX8632_TABLE; 185 ICETYPEX8632_TABLE;
172 #undef X 186 #undef X
173 // Repeat the static asserts with respect to the high-level 187 // Repeat the static asserts with respect to the high-level
174 // table entries in case the high-level table has extra entries. 188 // table entries in case the high-level table has extra entries.
175 #define X(tag, size, align, str) STATIC_ASSERT(_table1_##tag == _table2_##tag); 189 #define X(tag, size, align, elts, elty, str) \
190 STATIC_ASSERT(_table1_##tag == _table2_##tag);
176 ICETYPE_TABLE; 191 ICETYPE_TABLE;
177 #undef X 192 #undef X
178 } 193 }
179 } 194 }
180 195
181 } // end of anonymous namespace 196 } // end of anonymous namespace
182 197
183 TargetX8632::TargetX8632(Cfg *Func) 198 TargetX8632::TargetX8632(Cfg *Func)
184 : TargetLowering(Func), IsEbpBasedFrame(false), FrameSizeLocals(0), 199 : TargetLowering(Func), IsEbpBasedFrame(false), FrameSizeLocals(0),
185 LocalsSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false), 200 LocalsSizeBytes(0), NextLabelNumber(0), ComputedLiveRanges(false),
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 typedef ConstantDouble IceType; 689 typedef ConstantDouble IceType;
675 static const Type Ty = IceType_f64; 690 static const Type Ty = IceType_f64;
676 static const char *TypeName; 691 static const char *TypeName;
677 static const char *AsmTag; 692 static const char *AsmTag;
678 static const char *PrintfString; 693 static const char *PrintfString;
679 }; 694 };
680 const char *PoolTypeConverter<double>::TypeName = "double"; 695 const char *PoolTypeConverter<double>::TypeName = "double";
681 const char *PoolTypeConverter<double>::AsmTag = ".quad"; 696 const char *PoolTypeConverter<double>::AsmTag = ".quad";
682 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; 697 const char *PoolTypeConverter<double>::PrintfString = "0x%llx";
683 698
684 template <typename T> void TargetX8632::emitConstantPool() const { 699 template <typename T> void TargetX8632::emitScalarConstantPool() const {
685 Ostream &Str = Ctx->getStrEmit(); 700 Ostream &Str = Ctx->getStrEmit();
686 Type Ty = T::Ty; 701 Type Ty = T::Ty;
687 SizeT Align = typeAlignInBytes(Ty); 702 SizeT Align = typeAlignInBytes(Ty);
688 ConstantList Pool = Ctx->getConstantPool(Ty); 703 ConstantList Pool = Ctx->getConstantPool(Ty);
689 704
690 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align 705 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align
691 << "\n"; 706 << "\n";
692 Str << "\t.align\t" << Align << "\n"; 707 Str << "\t.align\t" << Align << "\n";
693 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E; 708 for (ConstantList::const_iterator I = Pool.begin(), E = Pool.end(); I != E;
694 ++I) { 709 ++I) {
695 typename T::IceType *Const = llvm::cast<typename T::IceType>(*I); 710 typename T::IceType *Const = llvm::cast<typename T::IceType>(*I);
696 typename T::PrimitiveFpType Value = Const->getValue(); 711 typename T::PrimitiveFpType Value = Const->getValue();
697 // Use memcpy() to copy bits from Value into RawValue in a way 712 // Use memcpy() to copy bits from Value into RawValue in a way
698 // that avoids breaking strict-aliasing rules. 713 // that avoids breaking strict-aliasing rules.
699 typename T::PrimitiveIntType RawValue; 714 typename T::PrimitiveIntType RawValue;
700 memcpy(&RawValue, &Value, sizeof(Value)); 715 memcpy(&RawValue, &Value, sizeof(Value));
701 char buf[30]; 716 char buf[30];
702 int CharsPrinted = 717 int CharsPrinted =
703 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); 718 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue);
704 assert(CharsPrinted >= 0 && 719 assert(CharsPrinted >= 0 &&
705 (size_t)CharsPrinted < llvm::array_lengthof(buf)); 720 (size_t)CharsPrinted < llvm::array_lengthof(buf));
706 (void)CharsPrinted; // avoid warnings if asserts are disabled 721 (void)CharsPrinted; // avoid warnings if asserts are disabled
707 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; 722 Str << "L$" << Ty << "$" << Const->getPoolEntryID() << ":\n";
708 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " 723 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
709 << Value << "\n"; 724 << Value << "\n";
710 } 725 }
711 } 726 }
712 727
728 void TargetX8632::emitVectorConstantPool() const {
729 Ostream &Str = Ctx->getStrEmit();
jvoung (off chromium) 2014/06/26 23:33:46 You could just make a local variable "Align = 16"
Jim Stichnoth 2014/06/27 18:30:16 Is it appropriate to reuse VECT128_BYTES for this
wala 2014/06/27 21:09:19 I'll do this, and then explain that we naturally a
730 Str << "\t.section\t.rodata.cst" << 16 << ",\"aM\",@progbits," << 16 << "\n";
731 Str << "\t.align\t" << 16 << "\n";
732
733 // Emit each (128 bit) vector.
734 ConstantList Vectors = Ctx->getConstantPool(IceType_v8i16);
jvoung (off chromium) 2014/06/26 23:33:46 Could add a comment that all non-i1 vectors are in
wala 2014/06/27 21:09:19 I will add the comment. I'm unsure how to avoid th
735 for (ConstantList::const_iterator I = Vectors.begin(), E = Vectors.end();
736 I != E; ++I) {
737 ConstantVector *Vector = llvm::cast<ConstantVector>(*I);
738 Vect128 Value = Vector->getValue();
739 assert(Value.size() == VECT128_BYTES);
740 const char *Data = Value.data();
741 Str << "L$" << typeAsmLabel(Vector->getType()) << "$"
742 << Vector->getPoolEntryID() << ":\n";
743 for (unsigned Element = 0; Element != 4; ++Element) {
744 uint32_t RawValue;
745 memcpy(&RawValue, &Data[4 * Element], 4);
746 char buf[30];
747 int CharsPrinted =
748 snprintf(buf, llvm::array_lengthof(buf), "0x%x", RawValue);
749 assert(CharsPrinted >= 0 &&
750 (size_t)CharsPrinted < llvm::array_lengthof(buf));
751 Str << "\t"
752 << ".long"
753 << "\t" << buf << "\t"
754 << "\n";
755 }
756 }
757
758 // Emit each I1 vector expanded to a 128 bit constant.
759 ConstantList BitVectors = Ctx->getConstantPool(IceType_v4i1);
760 for (ConstantList::const_iterator I = BitVectors.begin(),
761 E = BitVectors.end();
762 I != E; ++I) {
763 ConstantBitVector *BitVector = llvm::cast<ConstantBitVector>(*I);
764 BitVect Value = BitVector->getValue();
765 Str << "L$" << typeAsmLabel(BitVector->getType()) << "$"
766 << BitVector->getPoolEntryID() << ":\n";
767 const char *AsmString = NULL;
768 switch (BitVector->getType()) {
769 default:
770 llvm_unreachable("Unknown type");
771 case IceType_v4i1:
772 AsmString = ".long";
773 break;
774 case IceType_v8i1:
775 AsmString = ".short";
776 break;
777 case IceType_v16i1:
778 AsmString = ".byte";
779 break;
780 }
781 unsigned NumElements = Value.size();
782 for (unsigned Element = 0; Element != NumElements; ++Element) {
783 Str << "\t" << AsmString << "\t"
784 << "0x";
785 Str << (Value[Element] ? "1" : "0");
786 Str << "\t"
787 << "\n";
788 }
789 }
790 }
791
713 void TargetX8632::emitConstants() const { 792 void TargetX8632::emitConstants() const {
714 emitConstantPool<PoolTypeConverter<float> >(); 793 emitScalarConstantPool<PoolTypeConverter<float> >();
715 emitConstantPool<PoolTypeConverter<double> >(); 794 emitScalarConstantPool<PoolTypeConverter<double> >();
795 emitVectorConstantPool();
716 796
717 // No need to emit constants from the int pool since (for x86) they 797 // No need to emit constants from the int pool since (for x86) they
718 // are embedded as immediates in the instructions. 798 // are embedded as immediates in the instructions.
719 } 799 }
720 800
721 void TargetX8632::split64(Variable *Var) { 801 void TargetX8632::split64(Variable *Var) {
722 switch (Var->getType()) { 802 switch (Var->getType()) {
723 default: 803 default:
724 return; 804 return;
725 case IceType_i64: 805 case IceType_i64:
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 } 1370 }
1291 StackOffset += typeWidthInBytesOnStack(Arg->getType()); 1371 StackOffset += typeWidthInBytesOnStack(Arg->getType());
1292 } 1372 }
1293 // Generate the call instruction. Assign its result to a temporary 1373 // Generate the call instruction. Assign its result to a temporary
1294 // with high register allocation weight. 1374 // with high register allocation weight.
1295 Variable *Dest = Instr->getDest(); 1375 Variable *Dest = Instr->getDest();
1296 Variable *eax = NULL; // doubles as RegLo as necessary 1376 Variable *eax = NULL; // doubles as RegLo as necessary
1297 Variable *edx = NULL; 1377 Variable *edx = NULL;
1298 if (Dest) { 1378 if (Dest) {
1299 switch (Dest->getType()) { 1379 switch (Dest->getType()) {
1380 case IceType_v4i1:
1381 case IceType_v8i1:
1382 case IceType_v16i1:
1383 case IceType_v16i8:
1384 case IceType_v8i16:
1385 case IceType_v4i32:
1386 case IceType_v4f32:
1300 case IceType_NUM: 1387 case IceType_NUM:
1301 llvm_unreachable("Invalid Call dest type"); 1388 llvm_unreachable("Invalid Call dest type");
1302 break; 1389 break;
1303 case IceType_void: 1390 case IceType_void:
1304 break; 1391 break;
1305 case IceType_i1: 1392 case IceType_i1:
1306 case IceType_i8: 1393 case IceType_i8:
1307 case IceType_i16: 1394 case IceType_i16:
1308 case IceType_i32: 1395 case IceType_i32:
1309 eax = makeReg(Dest->getType(), Reg_eax); 1396 eax = makeReg(Dest->getType(), Reg_eax);
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 if (Inst->hasRetValue()) { 2351 if (Inst->hasRetValue()) {
2265 Operand *Src0 = legalize(Inst->getRetValue()); 2352 Operand *Src0 = legalize(Inst->getRetValue());
2266 if (Src0->getType() == IceType_i64) { 2353 if (Src0->getType() == IceType_i64) {
2267 Variable *eax = legalizeToVar(loOperand(Src0), false, Reg_eax); 2354 Variable *eax = legalizeToVar(loOperand(Src0), false, Reg_eax);
2268 Variable *edx = legalizeToVar(hiOperand(Src0), false, Reg_edx); 2355 Variable *edx = legalizeToVar(hiOperand(Src0), false, Reg_edx);
2269 Reg = eax; 2356 Reg = eax;
2270 Context.insert(InstFakeUse::create(Func, edx)); 2357 Context.insert(InstFakeUse::create(Func, edx));
2271 } else if (Src0->getType() == IceType_f32 || 2358 } else if (Src0->getType() == IceType_f32 ||
2272 Src0->getType() == IceType_f64) { 2359 Src0->getType() == IceType_f64) {
2273 _fld(Src0); 2360 _fld(Src0);
2361 } else if (typeNumElements(Src0->getType()) > 1) {
2362 Reg = legalizeToVar(Src0, false, Reg_xmm0);
2274 } else { 2363 } else {
2275 _mov(Reg, Src0, Reg_eax); 2364 _mov(Reg, Src0, Reg_eax);
2276 } 2365 }
2277 } 2366 }
2278 _ret(Reg); 2367 _ret(Reg);
2279 // Add a fake use of esp to make sure esp stays alive for the entire 2368 // Add a fake use of esp to make sure esp stays alive for the entire
2280 // function. Otherwise post-call esp adjustments get dead-code 2369 // function. Otherwise post-call esp adjustments get dead-code
2281 // eliminated. TODO: Are there more places where the fake use 2370 // eliminated. TODO: Are there more places where the fake use
2282 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not 2371 // should be inserted? E.g. "void f(int n){while(1) g(n);}" may not
2283 // have a ret instruction. 2372 // have a ret instruction.
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2385 _br(Inst->getLabelDefault()); 2474 _br(Inst->getLabelDefault());
2386 } 2475 }
2387 2476
2388 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) { 2477 void TargetX8632::lowerUnreachable(const InstUnreachable * /*Inst*/) {
2389 const SizeT MaxSrcs = 0; 2478 const SizeT MaxSrcs = 0;
2390 Variable *Dest = NULL; 2479 Variable *Dest = NULL;
2391 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs); 2480 InstCall *Call = makeHelperCall("ice_unreachable", Dest, MaxSrcs);
2392 lowerCall(Call); 2481 lowerCall(Call);
2393 } 2482 }
2394 2483
2484 // Helper for legalize() to emit the right code to lower an operand to a
2485 // register of the appropriate type.
2486 Variable *TargetX8632::copyToReg(Operand *Src, int32_t RegNum) {
2487 Type Ty = Src->getType();
2488 Variable *Reg = makeReg(Ty, RegNum);
2489 if (typeNumElements(Ty) > 1) {
jvoung (off chromium) 2014/06/26 23:33:46 Maybe there should be some inlineable "isVectorTyp
wala 2014/06/27 21:09:19 I agree.
2490 _movp(Reg, Src);
2491 } else {
2492 _mov(Reg, Src);
2493 }
2494 return Reg;
2495 }
2496
2395 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed, 2497 Operand *TargetX8632::legalize(Operand *From, LegalMask Allowed,
2396 bool AllowOverlap, int32_t RegNum) { 2498 bool AllowOverlap, int32_t RegNum) {
2397 // Assert that a physical register is allowed. To date, all calls 2499 // Assert that a physical register is allowed. To date, all calls
2398 // to legalize() allow a physical register. If a physical register 2500 // to legalize() allow a physical register. If a physical register
2399 // needs to be explicitly disallowed, then new code will need to be 2501 // needs to be explicitly disallowed, then new code will need to be
2400 // written to force a spill. 2502 // written to force a spill.
2401 assert(Allowed & Legal_Reg); 2503 assert(Allowed & Legal_Reg);
2402 // If we're asking for a specific physical register, make sure we're 2504 // If we're asking for a specific physical register, make sure we're
2403 // not allowing any other operand kinds. (This could be future 2505 // not allowing any other operand kinds. (This could be future
2404 // work, e.g. allow the shl shift amount to be either an immediate 2506 // work, e.g. allow the shl shift amount to be either an immediate
(...skipping 12 matching lines...) Expand all
2417 if (Index) { 2519 if (Index) {
2418 RegIndex = legalizeToVar(Index, true); 2520 RegIndex = legalizeToVar(Index, true);
2419 } 2521 }
2420 if (Base != RegBase || Index != RegIndex) { 2522 if (Base != RegBase || Index != RegIndex) {
2421 From = OperandX8632Mem::create( 2523 From = OperandX8632Mem::create(
2422 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex, 2524 Func, Mem->getType(), RegBase, Mem->getOffset(), RegIndex,
2423 Mem->getShift(), Mem->getSegmentRegister()); 2525 Mem->getShift(), Mem->getSegmentRegister());
2424 } 2526 }
2425 2527
2426 if (!(Allowed & Legal_Mem)) { 2528 if (!(Allowed & Legal_Mem)) {
2427 Variable *Reg = makeReg(From->getType(), RegNum); 2529 From = copyToReg(From, RegNum);
2428 _mov(Reg, From, RegNum);
2429 From = Reg;
2430 } 2530 }
2431 return From; 2531 return From;
2432 } 2532 }
2433 if (llvm::isa<Constant>(From)) { 2533 if (llvm::isa<Constant>(From)) {
2434 if (llvm::isa<ConstantUndef>(From)) { 2534 if (llvm::isa<ConstantUndef>(From)) {
2435 // Lower undefs to zero. Another option is to lower undefs to an 2535 // Lower undefs to zero. Another option is to lower undefs to an
2436 // uninitialized register; however, using an uninitialized register 2536 // uninitialized register; however, using an uninitialized register
2437 // results in less predictable code. 2537 // results in less predictable code.
2438 // 2538 //
2439 // If in the future the implementation is changed to lower undef 2539 // If in the future the implementation is changed to lower undef
2440 // values to uninitialized registers, a FakeDef will be needed: 2540 // values to uninitialized registers, a FakeDef will be needed:
2441 // Context.insert(InstFakeDef::create(Func, Reg)); 2541 // Context.insert(InstFakeDef::create(Func, Reg));
2442 // This is in order to ensure that the live range of Reg is not 2542 // 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, 2543 // 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 2544 // then the result should be split and the lo and hi components will
2445 // need to go in uninitialized registers. 2545 // need to go in uninitialized registers.
2446 From = Ctx->getConstantZero(From->getType()); 2546 From = Ctx->getConstantZero(From->getType());
2447 } 2547 }
2448 bool NeedsReg = 2548 bool NeedsReg =
2449 !(Allowed & Legal_Imm) || 2549 !(Allowed & Legal_Imm) ||
2450 // ConstantFloat and ConstantDouble are actually memory operands. 2550 // ConstantFloat, ConstantDouble, and vector constants are
2551 // actually memory operands.
2451 (!(Allowed & Legal_Mem) && 2552 (!(Allowed & Legal_Mem) &&
2452 (From->getType() == IceType_f32 || From->getType() == IceType_f64)); 2553 (From->getType() == IceType_f32 || From->getType() == IceType_f64 ||
2554 typeNumElements(From->getType()) > 1));
2453 if (NeedsReg) { 2555 if (NeedsReg) {
2454 Variable *Reg = makeReg(From->getType(), RegNum); 2556 From = copyToReg(From, RegNum);
2455 _mov(Reg, From);
2456 From = Reg;
2457 } 2557 }
2458 return From; 2558 return From;
2459 } 2559 }
2460 if (Variable *Var = llvm::dyn_cast<Variable>(From)) { 2560 if (Variable *Var = llvm::dyn_cast<Variable>(From)) {
2461 // We need a new physical register for the operand if: 2561 // We need a new physical register for the operand if:
2462 // Mem is not allowed and Var->getRegNum() is unknown, or 2562 // Mem is not allowed and Var->getRegNum() is unknown, or
2463 // RegNum is required and Var->getRegNum() doesn't match. 2563 // RegNum is required and Var->getRegNum() doesn't match.
2464 if ((!(Allowed & Legal_Mem) && !Var->hasReg()) || 2564 if ((!(Allowed & Legal_Mem) && !Var->hasReg()) ||
2465 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { 2565 (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
2466 Variable *Reg = makeReg(From->getType(), RegNum); 2566 Variable *Reg = copyToReg(From, RegNum);
2467 if (RegNum == Variable::NoRegister) { 2567 if (RegNum == Variable::NoRegister) {
2468 Reg->setPreferredRegister(Var, AllowOverlap); 2568 Reg->setPreferredRegister(Var, AllowOverlap);
2469 } 2569 }
2470 _mov(Reg, From);
2471 From = Reg; 2570 From = Reg;
2472 } 2571 }
2473 return From; 2572 return From;
2474 } 2573 }
2475 llvm_unreachable("Unhandled operand kind in legalize()"); 2574 llvm_unreachable("Unhandled operand kind in legalize()");
2476 return From; 2575 return From;
2477 } 2576 }
2478 2577
2479 // Provide a trivial wrapper to legalize() for this common usage. 2578 // Provide a trivial wrapper to legalize() for this common usage.
2480 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap, 2579 Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2562 } 2661 }
2563 assert(AvailableTypedRegisters.any()); 2662 assert(AvailableTypedRegisters.any());
2564 int32_t RegNum = AvailableTypedRegisters.find_first(); 2663 int32_t RegNum = AvailableTypedRegisters.find_first();
2565 Var->setRegNum(RegNum); 2664 Var->setRegNum(RegNum);
2566 AvailableRegisters[RegNum] = false; 2665 AvailableRegisters[RegNum] = false;
2567 } 2666 }
2568 } 2667 }
2569 } 2668 }
2570 } 2669 }
2571 2670
2671 template <> void ConstantInteger::emit(GlobalContext *Ctx) const {
2672 Ostream &Str = Ctx->getStrEmit();
2673 Str << getValue();
2674 }
2675
2572 template <> void ConstantFloat::emit(GlobalContext *Ctx) const { 2676 template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
2573 Ostream &Str = Ctx->getStrEmit(); 2677 Ostream &Str = Ctx->getStrEmit();
2574 // It would be better to prefix with ".L$" instead of "L$", but 2678 // It would be better to prefix with ".L$" instead of "L$", but
2575 // llvm-mc doesn't parse "dword ptr [.L$foo]". 2679 // llvm-mc doesn't parse "dword ptr [.L$foo]".
2576 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]"; 2680 Str << "dword ptr [L$" << IceType_f32 << "$" << getPoolEntryID() << "]";
2577 } 2681 }
2578 2682
2579 template <> void ConstantDouble::emit(GlobalContext *Ctx) const { 2683 template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
2580 Ostream &Str = Ctx->getStrEmit(); 2684 Ostream &Str = Ctx->getStrEmit();
2581 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]"; 2685 Str << "qword ptr [L$" << IceType_f64 << "$" << getPoolEntryID() << "]";
2582 } 2686 }
2583 2687
2688 template <> void ConstantVector::emit(GlobalContext *Ctx) const {
2689 Ostream &Str = Ctx->getStrEmit();
2690 Str << "xmmword ptr [L$" << typeAsmLabel(getType()) << "$" << getPoolEntryID()
2691 << "]";
2692 }
2693
2694 template <> void ConstantBitVector::emit(GlobalContext *Ctx) const {
2695 Ostream &Str = Ctx->getStrEmit();
2696 Str << "xmmword ptr [L$" << typeAsmLabel(getType()) << "$" << getPoolEntryID()
2697 << "]";
2698 }
2699
2584 } // end of namespace Ice 2700 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698