OLD | NEW |
1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// | 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 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 /// \file | 10 /// \file |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
23 #include "IceInstARM32.h" | 23 #include "IceInstARM32.h" |
24 #include "IceLiveness.h" | 24 #include "IceLiveness.h" |
25 #include "IceOperand.h" | 25 #include "IceOperand.h" |
26 #include "IcePhiLoweringImpl.h" | 26 #include "IcePhiLoweringImpl.h" |
27 #include "IceRegistersARM32.h" | 27 #include "IceRegistersARM32.h" |
28 #include "IceTargetLoweringARM32.def" | 28 #include "IceTargetLoweringARM32.def" |
29 #include "IceUtils.h" | 29 #include "IceUtils.h" |
30 #include "llvm/Support/MathExtras.h" | 30 #include "llvm/Support/MathExtras.h" |
31 | 31 |
| 32 #include <algorithm> |
| 33 |
32 namespace Ice { | 34 namespace Ice { |
33 | 35 |
34 namespace { | 36 namespace { |
35 | 37 |
36 // UnimplementedError is defined as a macro so that we can get actual line | 38 // UnimplementedError is defined as a macro so that we can get actual line |
37 // numbers. | 39 // numbers. |
38 #define UnimplementedError(Flags) \ | 40 #define UnimplementedError(Flags) \ |
39 do { \ | 41 do { \ |
40 if (!static_cast<const ClFlags &>(Flags).getSkipUnimplemented()) { \ | 42 if (!static_cast<const ClFlags &>(Flags).getSkipUnimplemented()) { \ |
41 /* Use llvm_unreachable instead of report_fatal_error, which gives \ | 43 /* Use llvm_unreachable instead of report_fatal_error, which gives \ |
(...skipping 3063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3105 OstreamLocker L(Ctx); | 3107 OstreamLocker L(Ctx); |
3106 for (const VariableDeclaration *Var : Vars) { | 3108 for (const VariableDeclaration *Var : Vars) { |
3107 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 3109 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
3108 emitGlobal(*Var, SectionSuffix); | 3110 emitGlobal(*Var, SectionSuffix); |
3109 } | 3111 } |
3110 } | 3112 } |
3111 } break; | 3113 } break; |
3112 } | 3114 } |
3113 } | 3115 } |
3114 | 3116 |
| 3117 namespace { |
| 3118 template <typename T> struct ConstantPoolEmitterTraits; |
| 3119 |
| 3120 static_assert(sizeof(uint64_t) == 8, |
| 3121 "uint64_t is supposed to be 8 bytes wide."); |
| 3122 |
| 3123 // TODO(jpp): implement the following when implementing constant randomization: |
| 3124 // * template <> struct ConstantPoolEmitterTraits<uint8_t> |
| 3125 // * template <> struct ConstantPoolEmitterTraits<uint16_t> |
| 3126 // * template <> struct ConstantPoolEmitterTraits<uint32_t> |
| 3127 template <> struct ConstantPoolEmitterTraits<float> { |
| 3128 using ConstantType = ConstantFloat; |
| 3129 static constexpr Type IceType = IceType_f32; |
| 3130 // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy |
| 3131 // about them being constexpr. |
| 3132 static const char AsmTag[]; |
| 3133 static const char TypeName[]; |
| 3134 static uint64_t bitcastToUint64(float Value) { |
| 3135 static_assert(sizeof(Value) == sizeof(uint32_t), |
| 3136 "Float should be 4 bytes."); |
| 3137 uint32_t IntValue = *reinterpret_cast<uint32_t *>(&Value); |
| 3138 return static_cast<uint64_t>(IntValue); |
| 3139 } |
| 3140 }; |
| 3141 const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".long"; |
| 3142 const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32"; |
| 3143 |
| 3144 template <> struct ConstantPoolEmitterTraits<double> { |
| 3145 using ConstantType = ConstantDouble; |
| 3146 static constexpr Type IceType = IceType_f64; |
| 3147 static const char AsmTag[]; |
| 3148 static const char TypeName[]; |
| 3149 static uint64_t bitcastToUint64(double Value) { |
| 3150 static_assert(sizeof(double) == sizeof(uint64_t), |
| 3151 "Double should be 8 bytes."); |
| 3152 return *reinterpret_cast<uint64_t *>(&Value); |
| 3153 } |
| 3154 }; |
| 3155 const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad"; |
| 3156 const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64"; |
| 3157 |
| 3158 template <typename T> |
| 3159 void emitConstant( |
| 3160 Ostream &Str, |
| 3161 const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) { |
| 3162 using Traits = ConstantPoolEmitterTraits<T>; |
| 3163 Const->emitPoolLabel(Str); |
| 3164 Str << ":\n\t" << Traits::AsmTag << "\t0x"; |
| 3165 T Value = Const->getValue(); |
| 3166 Str.write_hex(Traits::bitcastToUint64(Value)); |
| 3167 Str << "\t@" << Traits::TypeName << " " << Value << "\n"; |
| 3168 } |
| 3169 |
| 3170 template <typename T> void emitConstantPool(GlobalContext *Ctx) { |
| 3171 if (!BuildDefs::dump()) { |
| 3172 return; |
| 3173 } |
| 3174 |
| 3175 using Traits = ConstantPoolEmitterTraits<T>; |
| 3176 static constexpr size_t MinimumAlignment = 4; |
| 3177 SizeT Align = std::max(MinimumAlignment, typeAlignInBytes(Traits::IceType)); |
| 3178 assert((Align % 4) == 0 && "Constants should be aligned"); |
| 3179 Ostream &Str = Ctx->getStrEmit(); |
| 3180 ConstantList Pool = Ctx->getConstantPool(Traits::IceType); |
| 3181 |
| 3182 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align |
| 3183 << "\n" |
| 3184 << "\t.align\t" << Align << "\n"; |
| 3185 |
| 3186 if (Ctx->getFlags().shouldReorderPooledConstants()) { |
| 3187 // TODO(jpp): add constant pooling. |
| 3188 UnimplementedError(Ctx->getFlags()); |
| 3189 } |
| 3190 |
| 3191 for (Constant *C : Pool) { |
| 3192 if (!C->getShouldBePooled()) { |
| 3193 continue; |
| 3194 } |
| 3195 |
| 3196 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); |
| 3197 } |
| 3198 } |
| 3199 } // end of anonymous namespace |
| 3200 |
3115 void TargetDataARM32::lowerConstants() { | 3201 void TargetDataARM32::lowerConstants() { |
3116 if (Ctx->getFlags().getDisableTranslation()) | 3202 if (Ctx->getFlags().getDisableTranslation()) |
3117 return; | 3203 return; |
3118 UnimplementedError(Ctx->getFlags()); | 3204 switch (Ctx->getFlags().getOutFileType()) { |
| 3205 case FT_Elf: |
| 3206 UnimplementedError(Ctx->getFlags()); |
| 3207 break; |
| 3208 case FT_Asm: { |
| 3209 OstreamLocker L(Ctx); |
| 3210 emitConstantPool<float>(Ctx); |
| 3211 emitConstantPool<double>(Ctx); |
| 3212 break; |
| 3213 } |
| 3214 case FT_Iasm: { |
| 3215 UnimplementedError(Ctx->getFlags()); |
| 3216 break; |
| 3217 } |
| 3218 } |
3119 } | 3219 } |
3120 | 3220 |
3121 void TargetDataARM32::lowerJumpTables() { | 3221 void TargetDataARM32::lowerJumpTables() { |
3122 if (Ctx->getFlags().getDisableTranslation()) | 3222 if (Ctx->getFlags().getDisableTranslation()) |
3123 return; | 3223 return; |
3124 UnimplementedError(Ctx->getFlags()); | 3224 switch (Ctx->getFlags().getOutFileType()) { |
| 3225 case FT_Elf: |
| 3226 UnimplementedError(Ctx->getFlags()); |
| 3227 break; |
| 3228 case FT_Asm: |
| 3229 // Already emitted from Cfg |
| 3230 break; |
| 3231 case FT_Iasm: { |
| 3232 UnimplementedError(Ctx->getFlags()); |
| 3233 break; |
| 3234 } |
| 3235 } |
3125 } | 3236 } |
3126 | 3237 |
3127 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) | 3238 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) |
3128 : TargetHeaderLowering(Ctx), CPUFeatures(Ctx->getFlags()) {} | 3239 : TargetHeaderLowering(Ctx), CPUFeatures(Ctx->getFlags()) {} |
3129 | 3240 |
3130 void TargetHeaderARM32::lower() { | 3241 void TargetHeaderARM32::lower() { |
3131 OstreamLocker L(Ctx); | 3242 OstreamLocker L(Ctx); |
3132 Ostream &Str = Ctx->getStrEmit(); | 3243 Ostream &Str = Ctx->getStrEmit(); |
3133 Str << ".syntax unified\n"; | 3244 Str << ".syntax unified\n"; |
3134 // Emit build attributes in format: .eabi_attribute TAG, VALUE. See Sec. 2 of | 3245 // Emit build attributes in format: .eabi_attribute TAG, VALUE. See Sec. 2 of |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3167 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 3278 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
3168 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3279 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
3169 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 3280 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
3170 } | 3281 } |
3171 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3282 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
3172 // However, for compatibility with current NaCl LLVM, don't claim that. | 3283 // However, for compatibility with current NaCl LLVM, don't claim that. |
3173 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 3284 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
3174 } | 3285 } |
3175 | 3286 |
3176 } // end of namespace Ice | 3287 } // end of namespace Ice |
OLD | NEW |