Chromium Code Reviews| 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 3099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3141 OstreamLocker L(Ctx); | 3143 OstreamLocker L(Ctx); |
| 3142 for (const VariableDeclaration *Var : Vars) { | 3144 for (const VariableDeclaration *Var : Vars) { |
| 3143 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { | 3145 if (GlobalContext::matchSymbolName(Var->getName(), TranslateOnly)) { |
| 3144 emitGlobal(*Var, SectionSuffix); | 3146 emitGlobal(*Var, SectionSuffix); |
| 3145 } | 3147 } |
| 3146 } | 3148 } |
| 3147 } break; | 3149 } break; |
| 3148 } | 3150 } |
| 3149 } | 3151 } |
| 3150 | 3152 |
| 3153 namespace { | |
| 3154 template <typename T> struct ConstantPoolEmitterTraits; | |
| 3155 | |
| 3156 static_assert(sizeof(unsigned long long) == 8, | |
|
Jim Stichnoth
2015/09/18 13:59:34
Can you use uint64_t instead of unsigned long long
John
2015/09/18 14:20:25
Sometimes you might run into problems with uint64_
| |
| 3157 "unsigned long long is supposed to be 8 bytes wide."); | |
| 3158 | |
| 3159 // TODO(jpp): implement the following when implementing constant randomization: | |
| 3160 // * template <> struct ConstantPoolEmitterTraits<uint8_t> | |
| 3161 // * template <> struct ConstantPoolEmitterTraits<uint16_t> | |
| 3162 // * template <> struct ConstantPoolEmitterTraits<uint32_t> | |
| 3163 template <> struct ConstantPoolEmitterTraits<float> { | |
| 3164 using ConstantType = ConstantFloat; | |
| 3165 static constexpr Type IceType = IceType_f32; | |
| 3166 // AsmTag and TypeName can't be constexpr because llvm::StringRef is unhappy | |
| 3167 // about them being constexpr. | |
| 3168 static const char AsmTag[]; | |
| 3169 static const char TypeName[]; | |
| 3170 static unsigned long long bitcastToUint64(float Value) { | |
| 3171 static_assert(sizeof(Value) == sizeof(uint32_t), | |
| 3172 "Float should be 4 bytes."); | |
| 3173 uint32_t IntValue = *reinterpret_cast<uint32_t *>(&Value); | |
| 3174 return static_cast<unsigned long long>(IntValue); | |
| 3175 } | |
| 3176 }; | |
| 3177 const char ConstantPoolEmitterTraits<float>::AsmTag[] = ".long"; | |
| 3178 const char ConstantPoolEmitterTraits<float>::TypeName[] = "f32"; | |
| 3179 | |
| 3180 template <> struct ConstantPoolEmitterTraits<double> { | |
| 3181 using ConstantType = ConstantDouble; | |
| 3182 static constexpr Type IceType = IceType_f64; | |
| 3183 static const char AsmTag[]; | |
| 3184 static const char TypeName[]; | |
| 3185 static unsigned long long bitcastToUint64(double Value) { | |
| 3186 static_assert(sizeof(double) == sizeof(unsigned long long), | |
| 3187 "Double should be 8 bytes."); | |
| 3188 return *reinterpret_cast<unsigned long long *>(&Value); | |
| 3189 } | |
| 3190 }; | |
| 3191 const char ConstantPoolEmitterTraits<double>::AsmTag[] = ".quad"; | |
| 3192 const char ConstantPoolEmitterTraits<double>::TypeName[] = "f64"; | |
| 3193 | |
| 3194 template <typename T> | |
| 3195 void emitConstant( | |
| 3196 Ostream &Str, | |
| 3197 const typename ConstantPoolEmitterTraits<T>::ConstantType *Const) { | |
| 3198 using Traits = ConstantPoolEmitterTraits<T>; | |
| 3199 Const->emitPoolLabel(Str); | |
| 3200 Str << ":\n\t" << Traits::AsmTag << "\t0x"; | |
| 3201 T Value = Const->getValue(); | |
| 3202 Str.write_hex(Traits::bitcastToUint64(Value)); | |
| 3203 Str << "\t@" << Traits::TypeName << " " << Value << "\n"; | |
|
Jim Stichnoth
2015/09/18 13:59:34
Optional: It would be cool if, as an end-of-line c
John
2015/09/18 14:20:25
I am already printing the actual FP value (e.g., 1
Jim Stichnoth
2015/09/18 15:39:59
Oh, whoops, sorry.
(sometimes I do prefer printf s
John
2015/09/18 15:42:28
I always prefer printf format string -- they are m
| |
| 3204 } | |
| 3205 | |
| 3206 template <typename T> void emitConstantPool(GlobalContext *Ctx) { | |
| 3207 if (!BuildDefs::dump()) { | |
| 3208 return; | |
| 3209 } | |
| 3210 | |
| 3211 using Traits = ConstantPoolEmitterTraits<T>; | |
| 3212 SizeT Align = | |
| 3213 std::max(static_cast<size_t>(4), typeAlignInBytes(Traits::IceType)); | |
|
Jim Stichnoth
2015/09/18 13:59:34
First, I don't like magic constants like "4" sprin
John
2015/09/18 14:20:25
1) I avoid magic constants, too. However, this is
Jim Stichnoth
2015/09/18 15:39:59
I see, thanks.
| |
| 3214 assert((Align % 4) == 0 && "Constants should be aligned"); | |
| 3215 Ostream &Str = Ctx->getStrEmit(); | |
| 3216 ConstantList Pool = Ctx->getConstantPool(Traits::IceType); | |
| 3217 | |
| 3218 Str << "\t.section\t.rodata.cst" << Align << ",\"aM\",%progbits," << Align | |
| 3219 << "\n" | |
| 3220 << "\t.align\t" << Align << "\n"; | |
| 3221 | |
| 3222 if (Ctx->getFlags().shouldReorderPooledConstants()) { | |
| 3223 // TODO(jpp): add constant pooling. | |
| 3224 UnimplementedError(Ctx->getFlags()); | |
| 3225 } | |
| 3226 | |
| 3227 for (Constant *C : Pool) { | |
| 3228 if (!C->getShouldBePooled()) { | |
| 3229 continue; | |
| 3230 } | |
| 3231 | |
| 3232 emitConstant<T>(Str, llvm::dyn_cast<typename Traits::ConstantType>(C)); | |
| 3233 } | |
| 3234 } | |
| 3235 } // end of anonymous namespace | |
| 3236 | |
| 3151 void TargetDataARM32::lowerConstants() { | 3237 void TargetDataARM32::lowerConstants() { |
| 3152 if (Ctx->getFlags().getDisableTranslation()) | 3238 if (Ctx->getFlags().getDisableTranslation()) |
| 3153 return; | 3239 return; |
| 3154 UnimplementedError(Ctx->getFlags()); | 3240 switch (Ctx->getFlags().getOutFileType()) { |
| 3241 case FT_Elf: | |
| 3242 UnimplementedError(Ctx->getFlags()); | |
| 3243 break; | |
| 3244 case FT_Asm: { | |
| 3245 OstreamLocker L(Ctx); | |
| 3246 emitConstantPool<float>(Ctx); | |
| 3247 emitConstantPool<double>(Ctx); | |
| 3248 break; | |
| 3249 } | |
| 3250 case FT_Iasm: { | |
| 3251 UnimplementedError(Ctx->getFlags()); | |
| 3252 break; | |
| 3253 } | |
| 3254 } | |
| 3155 } | 3255 } |
| 3156 | 3256 |
| 3157 void TargetDataARM32::lowerJumpTables() { | 3257 void TargetDataARM32::lowerJumpTables() { |
| 3158 if (Ctx->getFlags().getDisableTranslation()) | 3258 if (Ctx->getFlags().getDisableTranslation()) |
| 3159 return; | 3259 return; |
| 3160 UnimplementedError(Ctx->getFlags()); | 3260 switch (Ctx->getFlags().getOutFileType()) { |
| 3261 case FT_Elf: | |
| 3262 UnimplementedError(Ctx->getFlags()); | |
| 3263 break; | |
| 3264 case FT_Asm: | |
| 3265 // Already emitted from Cfg | |
| 3266 break; | |
| 3267 case FT_Iasm: { | |
| 3268 UnimplementedError(Ctx->getFlags()); | |
| 3269 break; | |
| 3270 } | |
| 3271 } | |
| 3161 } | 3272 } |
| 3162 | 3273 |
| 3163 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) | 3274 TargetHeaderARM32::TargetHeaderARM32(GlobalContext *Ctx) |
| 3164 : TargetHeaderLowering(Ctx), CPUFeatures(Ctx->getFlags()) {} | 3275 : TargetHeaderLowering(Ctx), CPUFeatures(Ctx->getFlags()) {} |
| 3165 | 3276 |
| 3166 void TargetHeaderARM32::lower() { | 3277 void TargetHeaderARM32::lower() { |
| 3167 OstreamLocker L(Ctx); | 3278 OstreamLocker L(Ctx); |
| 3168 Ostream &Str = Ctx->getStrEmit(); | 3279 Ostream &Str = Ctx->getStrEmit(); |
| 3169 Str << ".syntax unified\n"; | 3280 Str << ".syntax unified\n"; |
| 3170 // Emit build attributes in format: .eabi_attribute TAG, VALUE. See Sec. 2 of | 3281 // 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... | |
| 3203 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; | 3314 << ".eabi_attribute 68, 1 @ Tag_Virtualization_use\n"; |
| 3204 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { | 3315 if (CPUFeatures.hasFeature(TargetARM32Features::HWDivArm)) { |
| 3205 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; | 3316 Str << ".eabi_attribute 44, 2 @ Tag_DIV_use\n"; |
| 3206 } | 3317 } |
| 3207 // Technically R9 is used for TLS with Sandboxing, and we reserve it. | 3318 // Technically R9 is used for TLS with Sandboxing, and we reserve it. |
| 3208 // However, for compatibility with current NaCl LLVM, don't claim that. | 3319 // However, for compatibility with current NaCl LLVM, don't claim that. |
| 3209 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; | 3320 Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; |
| 3210 } | 3321 } |
| 3211 | 3322 |
| 3212 } // end of namespace Ice | 3323 } // end of namespace Ice |
| OLD | NEW |