| 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 951 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 continue; | 962 continue; |
| 963 if (CalleeSaves[j] && RegsUsed[j]) { | 963 if (CalleeSaves[j] && RegsUsed[j]) { |
| 964 _pop(getPhysicalRegister(j)); | 964 _pop(getPhysicalRegister(j)); |
| 965 } | 965 } |
| 966 } | 966 } |
| 967 } | 967 } |
| 968 | 968 |
| 969 template <typename T> struct PoolTypeConverter {}; | 969 template <typename T> struct PoolTypeConverter {}; |
| 970 | 970 |
| 971 template <> struct PoolTypeConverter<float> { | 971 template <> struct PoolTypeConverter<float> { |
| 972 typedef float PrimitiveFpType; | |
| 973 typedef uint32_t PrimitiveIntType; | 972 typedef uint32_t PrimitiveIntType; |
| 974 typedef ConstantFloat IceType; | 973 typedef ConstantFloat IceType; |
| 975 static const Type Ty = IceType_f32; | 974 static const Type Ty = IceType_f32; |
| 976 static const char *TypeName; | 975 static const char *TypeName; |
| 977 static const char *AsmTag; | 976 static const char *AsmTag; |
| 978 static const char *PrintfString; | 977 static const char *PrintfString; |
| 979 }; | 978 }; |
| 980 const char *PoolTypeConverter<float>::TypeName = "float"; | 979 const char *PoolTypeConverter<float>::TypeName = "float"; |
| 981 const char *PoolTypeConverter<float>::AsmTag = ".long"; | 980 const char *PoolTypeConverter<float>::AsmTag = ".long"; |
| 982 const char *PoolTypeConverter<float>::PrintfString = "0x%x"; | 981 const char *PoolTypeConverter<float>::PrintfString = "0x%x"; |
| 983 | 982 |
| 984 template <> struct PoolTypeConverter<double> { | 983 template <> struct PoolTypeConverter<double> { |
| 985 typedef double PrimitiveFpType; | |
| 986 typedef uint64_t PrimitiveIntType; | 984 typedef uint64_t PrimitiveIntType; |
| 987 typedef ConstantDouble IceType; | 985 typedef ConstantDouble IceType; |
| 988 static const Type Ty = IceType_f64; | 986 static const Type Ty = IceType_f64; |
| 989 static const char *TypeName; | 987 static const char *TypeName; |
| 990 static const char *AsmTag; | 988 static const char *AsmTag; |
| 991 static const char *PrintfString; | 989 static const char *PrintfString; |
| 992 }; | 990 }; |
| 993 const char *PoolTypeConverter<double>::TypeName = "double"; | 991 const char *PoolTypeConverter<double>::TypeName = "double"; |
| 994 const char *PoolTypeConverter<double>::AsmTag = ".quad"; | 992 const char *PoolTypeConverter<double>::AsmTag = ".quad"; |
| 995 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; | 993 const char *PoolTypeConverter<double>::PrintfString = "0x%llx"; |
| 996 | 994 |
| 997 template <typename T> void TargetX8632::emitConstantPool() const { | 995 template <typename T> void TargetX8632::emitConstantPool() const { |
| 998 // Note: Still used by emit IAS. | 996 // Note: Still used by emit IAS. |
| 999 Ostream &Str = Ctx->getStrEmit(); | 997 Ostream &Str = Ctx->getStrEmit(); |
| 1000 Type Ty = T::Ty; | 998 Type Ty = T::Ty; |
| 1001 SizeT Align = typeAlignInBytes(Ty); | 999 SizeT Align = typeAlignInBytes(Ty); |
| 1002 ConstantList Pool = Ctx->getConstantPool(Ty); | 1000 ConstantList Pool = Ctx->getConstantPool(Ty); |
| 1003 | 1001 |
| 1004 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align | 1002 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",@progbits," << Align |
| 1005 << "\n"; | 1003 << "\n"; |
| 1006 Str << "\t.align\t" << Align << "\n"; | 1004 Str << "\t.align\t" << Align << "\n"; |
| 1007 for (Constant *C : Pool) { | 1005 for (Constant *C : Pool) { |
| 1008 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); | 1006 typename T::IceType *Const = llvm::cast<typename T::IceType>(C); |
| 1009 typename T::PrimitiveFpType Value = Const->getValue(); | 1007 typename T::IceType::PrimType Value = Const->getValue(); |
| 1010 // Use memcpy() to copy bits from Value into RawValue in a way | 1008 // Use memcpy() to copy bits from Value into RawValue in a way |
| 1011 // that avoids breaking strict-aliasing rules. | 1009 // that avoids breaking strict-aliasing rules. |
| 1012 typename T::PrimitiveIntType RawValue; | 1010 typename T::PrimitiveIntType RawValue; |
| 1013 memcpy(&RawValue, &Value, sizeof(Value)); | 1011 memcpy(&RawValue, &Value, sizeof(Value)); |
| 1014 char buf[30]; | 1012 char buf[30]; |
| 1015 int CharsPrinted = | 1013 int CharsPrinted = |
| 1016 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); | 1014 snprintf(buf, llvm::array_lengthof(buf), T::PrintfString, RawValue); |
| 1017 assert(CharsPrinted >= 0 && | 1015 assert(CharsPrinted >= 0 && |
| 1018 (size_t)CharsPrinted < llvm::array_lengthof(buf)); | 1016 (size_t)CharsPrinted < llvm::array_lengthof(buf)); |
| 1019 (void)CharsPrinted; // avoid warnings if asserts are disabled | 1017 (void)CharsPrinted; // avoid warnings if asserts are disabled |
| 1020 Str << ".L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; | 1018 Str << ".L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; |
| 1021 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " | 1019 Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " |
| 1022 << Value << "\n"; | 1020 << Value << "\n"; |
| 1023 } | 1021 } |
| 1024 } | 1022 } |
| 1025 | 1023 |
| 1026 void TargetX8632::emitConstants() const { | 1024 void TargetX8632::emitConstants() const { |
| 1027 // Note: Still used by emit IAS. | |
| 1028 emitConstantPool<PoolTypeConverter<float>>(); | |
| 1029 emitConstantPool<PoolTypeConverter<double>>(); | |
| 1030 | |
| 1031 // No need to emit constants from the int pool since (for x86) they | 1025 // No need to emit constants from the int pool since (for x86) they |
| 1032 // are embedded as immediates in the instructions. | 1026 // are embedded as immediates in the instructions, just emit float/double. |
| 1027 if (Ctx->getFlags().UseELFWriter) { |
| 1028 ELFObjectWriter *Writer = Ctx->getObjectWriter(); |
| 1029 Writer->writeConstantPool<ConstantFloat>(IceType_f32); |
| 1030 Writer->writeConstantPool<ConstantDouble>(IceType_f64); |
| 1031 } else { |
| 1032 emitConstantPool<PoolTypeConverter<float>>(); |
| 1033 emitConstantPool<PoolTypeConverter<double>>(); |
| 1034 } |
| 1033 } | 1035 } |
| 1034 | 1036 |
| 1035 void TargetX8632::split64(Variable *Var) { | 1037 void TargetX8632::split64(Variable *Var) { |
| 1036 switch (Var->getType()) { | 1038 switch (Var->getType()) { |
| 1037 default: | 1039 default: |
| 1038 return; | 1040 return; |
| 1039 case IceType_i64: | 1041 case IceType_i64: |
| 1040 // TODO: Only consider F64 if we need to push each half when | 1042 // TODO: Only consider F64 if we need to push each half when |
| 1041 // passing as an argument to a function call. Note that each half | 1043 // passing as an argument to a function call. Note that each half |
| 1042 // is still typed as I32. | 1044 // is still typed as I32. |
| (...skipping 3674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4717 } else if (IsConstant || IsExternal) | 4719 } else if (IsConstant || IsExternal) |
| 4718 Str << "\t.zero\t" << Size << "\n"; | 4720 Str << "\t.zero\t" << Size << "\n"; |
| 4719 // Size is part of .comm. | 4721 // Size is part of .comm. |
| 4720 | 4722 |
| 4721 if (IsConstant || HasNonzeroInitializer || IsExternal) | 4723 if (IsConstant || HasNonzeroInitializer || IsExternal) |
| 4722 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; | 4724 Str << "\t.size\t" << MangledName << ", " << Size << "\n"; |
| 4723 // Size is part of .comm. | 4725 // Size is part of .comm. |
| 4724 } | 4726 } |
| 4725 | 4727 |
| 4726 } // end of namespace Ice | 4728 } // end of namespace Ice |
| OLD | NEW |