diff options
Diffstat (limited to 'lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp')
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 10d1c48..1964bcd 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -336,6 +336,7 @@ public: } // end anonymous namespace MCCodeEmitter *llvm::createARMMCCodeEmitter(const MCInstrInfo &MCII, + const MCRegisterInfo &MRI, const MCSubtargetInfo &STI, MCContext &Ctx) { return new ARMMCCodeEmitter(MCII, STI, Ctx); @@ -861,11 +862,11 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, // Handle :upper16: and :lower16: assembly prefixes. const MCExpr *E = MO.getExpr(); + MCFixupKind Kind; if (E->getKind() == MCExpr::Target) { const ARMMCExpr *ARM16Expr = cast<ARMMCExpr>(E); E = ARM16Expr->getSubExpr(); - MCFixupKind Kind; switch (ARM16Expr->getKind()) { default: llvm_unreachable("Unsupported ARMFixup"); case ARMMCExpr::VK_ARM_HI16: @@ -891,9 +892,21 @@ ARMMCCodeEmitter::getHiLo16ImmOpValue(const MCInst &MI, unsigned OpIdx, } Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); return 0; - }; - - llvm_unreachable("Unsupported MCExpr type in MCOperand!"); + } + // If the expression doesn't have :upper16: or :lower16: on it, + // it's just a plain immediate expression, and those evaluate to + // the lower 16 bits of the expression regardless of whether + // we have a movt or a movw. + if (!isTargetDarwin() && EvaluateAsPCRel(E)) + Kind = MCFixupKind(isThumb2() + ? ARM::fixup_t2_movw_lo16_pcrel + : ARM::fixup_arm_movw_lo16_pcrel); + else + Kind = MCFixupKind(isThumb2() + ? ARM::fixup_t2_movw_lo16 + : ARM::fixup_arm_movw_lo16); + Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc())); + return 0; } uint32_t ARMMCCodeEmitter:: @@ -1192,8 +1205,7 @@ getSORegImmOpValue(const MCInst &MI, unsigned OpIdx, // Encode shift_imm bit[11:7]. Binary |= SBits << 4; unsigned Offset = ARM_AM::getSORegOffset(MO1.getImm()); - assert(Offset && "Offset must be in range 1-32!"); - if (Offset == 32) Offset = 0; + assert(Offset < 32 && "Offset must be in range 0-31!"); return Binary | (Offset << 7); } |