Index: include/llvm/MC/ConstantPools.h =================================================================== --- include/llvm/MC/ConstantPools.h +++ include/llvm/MC/ConstantPools.h @@ -25,18 +25,20 @@ // A class to keep track of assembler-generated constant pools that are use to // implement the ldr-pseudo. class ConstantPool { - typedef SmallVector, 4> EntryVecTy; + unsigned MaxAlignment; + typedef SmallVector, 4> EntryVecTy; EntryVecTy Entries; public: // Initialize a new empty constant pool - ConstantPool() {} + ConstantPool(); // Add a new entry to the constant pool in the next slot. // \param Value is the new entry to put in the constant pool. // // \returns a MCExpr that references the newly inserted value - const MCExpr *addEntry(const MCExpr *Value, MCContext &Context); + const MCExpr *addEntry(const MCExpr *Value, MCContext &Context, + unsigned Size = 4); // Emit the contents of the constant pool using the provided streamer. void emitEntries(MCStreamer &Streamer); @@ -69,7 +71,8 @@ void emitAll(MCStreamer &Streamer); void emitForCurrentSection(MCStreamer &Streamer); - const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr); + const MCExpr *addEntry(MCStreamer &Streamer, const MCExpr *Expr, + unsigned Size = 4); private: ConstantPool *getConstantPool(const MCSection *Section); Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -97,7 +97,7 @@ /// Callback used to implement the ldr= pseudo. /// Add a new entry to the constant pool for the current section and return an /// MCExpr that can be used to refer to the constant pool location. - const MCExpr *addConstantPoolEntry(const MCExpr *); + const MCExpr *addConstantPoolEntry(const MCExpr *, unsigned Size); /// Callback used to implemnt the .ltorg directive. /// Emit contents of constant pool for the current section. Index: lib/MC/ConstantPools.cpp =================================================================== --- lib/MC/ConstantPools.cpp +++ lib/MC/ConstantPools.cpp @@ -20,25 +20,35 @@ // // ConstantPool implementation // +ConstantPool::ConstantPool() : MaxAlignment(4) {}; // Emit the contents of the constant pool using the provided streamer. void ConstantPool::emitEntries(MCStreamer &Streamer) { + unsigned Alignment = 0; if (Entries.empty()) return; - Streamer.EmitCodeAlignment(4); // align to 4-byte address + Streamer.EmitCodeAlignment(MaxAlignment); // align naturally Streamer.EmitDataRegion(MCDR_DataRegion); for (EntryVecTy::const_iterator I = Entries.begin(), E = Entries.end(); I != E; ++I) { - Streamer.EmitLabel(I->first); - Streamer.EmitValue(I->second, 4); + unsigned Size = std::get<2>(*I); + if (Alignment && Size > Alignment) + Streamer.EmitCodeAlignment(Size); + Alignment = (Alignment + Size) % MaxAlignment; + Streamer.EmitLabel(std::get<0>(*I)); + Streamer.EmitValue(std::get<1>(*I), Size); } Streamer.EmitDataRegion(MCDR_DataRegionEnd); Entries.clear(); } -const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context) { +const MCExpr *ConstantPool::addEntry(const MCExpr *Value, MCContext &Context, + unsigned Size) { MCSymbol *CPEntryLabel = Context.CreateTempSymbol(); - Entries.push_back(std::make_pair(CPEntryLabel, Value)); + if (Size > MaxAlignment) + MaxAlignment = Size; + + Entries.push_back(std::make_tuple(CPEntryLabel, Value, Size)); return MCSymbolRefExpr::Create(CPEntryLabel, Context); } @@ -89,7 +99,9 @@ } const MCExpr *AssemblerConstantPools::addEntry(MCStreamer &Streamer, - const MCExpr *Expr) { + const MCExpr *Expr, + unsigned Size) { const MCSection *Section = Streamer.getCurrentSection().first; - return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext()); + return getOrCreateConstantPool(Section).addEntry(Expr, Streamer.getContext(), + Size); } Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3049,13 +3049,15 @@ if (getParser().parseExpression(SubExprVal)) return true; + if (Operands.size() < 2 || + !static_cast(*Operands[1]).isReg()) + return true; + bool IsXReg = AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(Operands[1]->getReg()); + MCContext& Ctx = getContext(); E = SMLoc::getFromPointer(Loc.getPointer() - 1); // If the op is an imm and can be fit into a mov, then replace ldr with mov. - if (isa(SubExprVal) && Operands.size() >= 2 && - static_cast(*Operands[1]).isReg()) { - bool IsXReg = AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( - Operands[1]->getReg()); + if (isa(SubExprVal)) { uint64_t Imm = (cast(SubExprVal))->getValue(); uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { @@ -3073,7 +3075,9 @@ } } // If it is a label or an imm that cannot fit in a movz, put it into CP. - const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal); + const MCExpr *CPLoc = getTargetStreamer().addConstantPoolEntry(SubExprVal, + IsXReg ? 8 + : 4); Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx)); return false; } Index: lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp @@ -28,8 +28,9 @@ // The constant pool handling is shared by all AArch64TargetStreamer // implementations. -const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { - return ConstantPools->addEntry(Streamer, Expr); +const MCExpr *AArch64TargetStreamer::addConstantPoolEntry(const MCExpr *Expr, + unsigned Size) { + return ConstantPools->addEntry(Streamer, Expr, Size); } void AArch64TargetStreamer::emitCurrentConstantPool() { Index: test/MC/AArch64/ldr-pseudo.s =================================================================== --- test/MC/AArch64/ldr-pseudo.s +++ test/MC/AArch64/ldr-pseudo.s @@ -162,6 +162,19 @@ // CHECK: ldr w0, .Ltmp[[TMP15:[0-9]+]] adds w0, w0, #1 +// usage with 64-bit constants +.section m, "ax", @progbits +// CHECK-LABEL: f16: +f16: + ldr x0, =0x0102030405060708 +// CHECK: ldr x0, .Ltmp[[TMP16:[0-9]+]] + adds x0, x0, #1 + ldr w0, =bar +// CHECK: ldr w0, .Ltmp[[TMP17:[0-9]+]] + ldr x0, =bar+4 +// CHECK: ldr x0, .Ltmp[[TMP18:[0-9]+]] + adds x0, x0, #1 + // // Constant Pools // @@ -229,3 +242,13 @@ // CHECK: .word 65545 // CHECK: .Ltmp[[TMP15]] // CHECK: .word bar+4 + +// CHECK: .section m,"ax",@progbits +// CHECK: .align 3 +// CHECK: .Ltmp[[TMP16]] +// CHECK: .xword 72623859790382856 +// CHECK: .Ltmp[[TMP17]] +// CHECK: .word bar +// CHECK: .align 3 +// CHECK: .Ltmp[[TMP18]] +// CHECK: .xword bar+4