From 94b590f8faf4dbba406f263e6a839882b0c68a94 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 1 May 2012 20:43:21 +0000 Subject: [PATCH] ARM: allow vanilla expressions for movw/movt. Expressions for movw/movt don't always have an :upper16: or :lower16: on them and that's ok. When they don't, it's just a plain [0-65536] immediate result, effectively the same as a :lower16: variant kind. rdar://10550147 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@155941 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ARM/MCTargetDesc/ARMMCCodeEmitter.cpp | 20 +++++++++++++++---- test/MC/ARM/arm_fixups.s | 5 +++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp index 1589a5d2194..31f43fe11c9 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp @@ -861,11 +861,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(E); E = ARM16Expr->getSubExpr(); - MCFixupKind Kind; switch (ARM16Expr->getKind()) { default: llvm_unreachable("Unsupported ARMFixup"); case ARMMCExpr::VK_ARM_HI16: @@ -891,9 +891,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:: diff --git a/test/MC/ARM/arm_fixups.s b/test/MC/ARM/arm_fixups.s index 74dfb99ef2a..99eb3c53941 100644 --- a/test/MC/ARM/arm_fixups.s +++ b/test/MC/ARM/arm_fixups.s @@ -15,3 +15,8 @@ @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movw_lo16 @ CHECK: movt r9, :upper16:_foo @ encoding: [A,0x90'A',0b0100AAAA,0xe3] @ CHECK: @ fixup A - offset: 0, value: _foo, kind: fixup_arm_movt_hi16 + + mov r2, fred + +@ CHECK: movw r2, fred @ encoding: [A,0x20'A',0b0000AAAA,0xe3] +@ CHECK: @ fixup A - offset: 0, value: fred, kind: fixup_arm_movw_lo16