Pull in r265122 from upstream llvm trunk (by James Molloy):
Fix for pr24346: arm asm label calculation error in sub Some ARM instructions encode 32-bit immediates as a 8-bit integer (0-255) and a 4-bit rotation (0-30, even) in its least significant 12 bits. The original fixup, FK_Data_4, patches the instruction by the value bit-to-bit, regardless of the encoding. For example, assuming the label L1 and L2 are 0x0 and 0x104 respectively, the following instruction: add r0, r0, #(L2 - L1) ; expects 0x104, i.e., 260 would be assembled to the following, which adds 1 to r0, instead of 260: e2800104 add r0, r0, #4, 2 ; equivalently 1 The new fixup kind fixup_arm_mod_imm takes care of the encoding: e2800f41 add r0, r0, #260 Patch by Ting-Yuan Huang! This fixes label calculation for ARM assembly, and is needed to enable ARM assembly sources for OpenSSL. Requested by: jkim MFC after: 3 days
This commit is contained in:
parent
6975a721d1
commit
6ca8079c85
@ -90,6 +90,7 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
|
||||
{"fixup_arm_movw_lo16", 0, 20, 0},
|
||||
{"fixup_t2_movt_hi16", 0, 20, 0},
|
||||
{"fixup_t2_movw_lo16", 0, 20, 0},
|
||||
{"fixup_arm_mod_imm", 0, 12, 0},
|
||||
};
|
||||
const static MCFixupKindInfo InfosBE[ARM::NumTargetFixupKinds] = {
|
||||
// This table *must* be in the order that the fixup_* kinds are defined in
|
||||
@ -133,6 +134,7 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
|
||||
{"fixup_arm_movw_lo16", 12, 20, 0},
|
||||
{"fixup_t2_movt_hi16", 12, 20, 0},
|
||||
{"fixup_t2_movw_lo16", 12, 20, 0},
|
||||
{"fixup_arm_mod_imm", 20, 12, 0},
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
@ -624,6 +626,13 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
|
||||
|
||||
return Value;
|
||||
}
|
||||
case ARM::fixup_arm_mod_imm:
|
||||
Value = ARM_AM::getSOImmVal(Value);
|
||||
if (Ctx && Value >> 12) {
|
||||
Ctx->reportError(Fixup.getLoc(), "out of range immediate fixup value");
|
||||
return 0;
|
||||
}
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -690,6 +699,7 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
|
||||
case FK_Data_2:
|
||||
case ARM::fixup_arm_thumb_br:
|
||||
case ARM::fixup_arm_thumb_cb:
|
||||
case ARM::fixup_arm_mod_imm:
|
||||
return 2;
|
||||
|
||||
case ARM::fixup_arm_pcrel_10_unscaled:
|
||||
@ -766,6 +776,7 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
|
||||
case ARM::fixup_arm_movw_lo16:
|
||||
case ARM::fixup_t2_movt_hi16:
|
||||
case ARM::fixup_t2_movw_lo16:
|
||||
case ARM::fixup_arm_mod_imm:
|
||||
// Instruction size is 4 bytes.
|
||||
return 4;
|
||||
}
|
||||
|
@ -100,6 +100,9 @@ enum Fixups {
|
||||
fixup_t2_movt_hi16, // :upper16:
|
||||
fixup_t2_movw_lo16, // :lower16:
|
||||
|
||||
// fixup_arm_mod_imm - Fixup for mod_imm
|
||||
fixup_arm_mod_imm,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
|
@ -312,12 +312,8 @@ public:
|
||||
// Support for fixups (MCFixup)
|
||||
if (MO.isExpr()) {
|
||||
const MCExpr *Expr = MO.getExpr();
|
||||
// In instruction code this value always encoded as lowest 12 bits,
|
||||
// so we don't have to perform any specific adjustments.
|
||||
// Due to requirements of relocatable records we have to use FK_Data_4.
|
||||
// See ARMELFObjectWriter::ExplicitRelSym and
|
||||
// ARMELFObjectWriter::GetRelocTypeInner for more details.
|
||||
MCFixupKind Kind = MCFixupKind(FK_Data_4);
|
||||
// Fixups resolve to plain values that need to be encoded.
|
||||
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_mod_imm);
|
||||
Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#define FREEBSD_CC_VERSION 1200001
|
||||
#define FREEBSD_CC_VERSION 1200002
|
||||
|
Loading…
x
Reference in New Issue
Block a user