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 |