diff options
Diffstat (limited to 'llvm/lib')
4 files changed, 30 insertions, 15 deletions
diff --git a/llvm/lib/MC/ConstantPools.cpp b/llvm/lib/MC/ConstantPools.cpp index f979dad47da..41ce68bfe0a 100644 --- a/llvm/lib/MC/ConstantPools.cpp +++ b/llvm/lib/MC/ConstantPools.cpp @@ -24,21 +24,22 @@ using namespace llvm; void ConstantPool::emitEntries(MCStreamer &Streamer) { if (Entries.empty()) return; - Streamer.EmitCodeAlignment(4); // align to 4-byte address 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); + Streamer.EmitCodeAlignment(I->Size); // align naturally + Streamer.EmitLabel(I->Label); + Streamer.EmitValue(I->Value, 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)); + Entries.push_back( { CPEntryLabel, Value, Size } ); return MCSymbolRefExpr::Create(CPEntryLabel, Context); } @@ -89,7 +90,9 @@ void AssemblerConstantPools::emitForCurrentSection(MCStreamer &Streamer) { } 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); } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index fddecbbd70d..37e92961ff0 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/STLExtras.h" @@ -3067,13 +3068,18 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, if (getParser().parseExpression(SubExprVal)) return true; + if (Operands.size() < 2 || + !static_cast<AArch64Operand &>(*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<MCConstantExpr>(SubExprVal) && Operands.size() >= 2 && - static_cast<AArch64Operand &>(*Operands[1]).isReg()) { - bool IsXReg = AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains( - Operands[1]->getReg()); + if (isa<MCConstantExpr>(SubExprVal)) { uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue(); uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16; while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) { @@ -3089,9 +3095,14 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, ShiftAmt, true, S, E, Ctx)); return false; } + APInt Simm = APInt(64, Imm << ShiftAmt); + // check if the immediate is an unsigned or signed 32-bit int for W regs + if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32))) + return Error(Loc, "Immediate too large for register"); } // 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; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp index f9aeb35b649..dcc1a3c9f05 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.cpp @@ -28,8 +28,9 @@ AArch64TargetStreamer::~AArch64TargetStreamer() {} // 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() { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp index ad3f1caae34..8acd7aff6bc 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMTargetStreamer.cpp @@ -28,7 +28,7 @@ ARMTargetStreamer::~ARMTargetStreamer() {} // The constant pool handling is shared by all ARMTargetStreamer // implementations. const MCExpr *ARMTargetStreamer::addConstantPoolEntry(const MCExpr *Expr) { - return ConstantPools->addEntry(Streamer, Expr); + return ConstantPools->addEntry(Streamer, Expr, 4); } void ARMTargetStreamer::emitCurrentConstantPool() { |