const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const {
const static MCFixupKindInfo Infos[] = {
- // name off bits flags
- { "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
+// This table *must* be in the order that the fixup_* kinds are defined in
+// ARMFixupKinds.h.
+//
+// Name Offset (bits) Size (bits) Flags
+{ "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
+ MCFixupKindInfo::FKF_IsAligned},
+{ "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAligned},
- { "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
+{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel |
MCFixupKindInfo::FKF_IsAligned},
- { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel },
- { "fixup_arm_movt_hi16", 0, 16, 0 },
- { "fixup_arm_movw_lo16", 0, 16, 0 },
+{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_thumb_bcc", 1, 8, MCFixupKindInfo::FKF_IsPCRel },
+{ "fixup_arm_movt_hi16", 0, 16, 0 },
+{ "fixup_arm_movw_lo16", 0, 16, 0 },
};
if (Kind < FirstTargetFixupKind)
uint32_t getThumbBLXTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
+ /// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
+ uint32_t getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+ /// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
+ uint32_t getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
uint32_t getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
+ /// getTAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand.
+ uint32_t getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
/// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2'
/// operand.
uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
uint32_t getAddrModeThumbSPOpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
- /// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
- uint32_t getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
- uint32_t getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
-
- /// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
- uint32_t getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &Fixups) const;
+ /// getAddrModeSOpValue - Encode the t_addrmode_s# operands.
+ uint32_t getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &) const;
/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
uint32_t getAddrModePCOpValue(const MCInst &MI, unsigned OpIdx,
Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal);
return Binary;
}
-
+
/// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value.
unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const {
return new ARMMCCodeEmitter(TM, Ctx);
}
-/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
+/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing
+/// instructions, and rewrite them to their Thumb2 form if we are currently in
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
if (Subtarget.isThumb2()) {
- // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
+ // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved
// to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are
// set to 1111.
unsigned Bit24 = EncodedValue & 0x01000000;
EncodedValue |= Bit28;
EncodedValue |= 0x0F000000;
}
-
+
return EncodedValue;
}
/// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
+/// instructions, and rewrite them to their Thumb2 form if we are currently in
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
EncodedValue &= 0xF0FFFFFF;
EncodedValue |= 0x09000000;
}
-
+
return EncodedValue;
}
/// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup
-/// instructions, and rewrite them to their Thumb2 form if we are currently in
+/// instructions, and rewrite them to their Thumb2 form if we are currently in
/// Thumb2 mode.
unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI,
unsigned EncodedValue) const {
EncodedValue &= 0x00FFFFFF;
EncodedValue |= 0xEE000000;
}
-
+
return EncodedValue;
}
return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_blx, Fixups);
}
+/// getThumbBRTargetOpValue - Return encoding info for Thumb branch target.
+uint32_t ARMMCCodeEmitter::
+getThumbBRTargetOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_br, Fixups);
+}
+
+/// getThumbBCCTargetOpValue - Return encoding info for Thumb branch target.
+uint32_t ARMMCCodeEmitter::
+getThumbBCCTargetOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_thumb_bcc, Fixups);
+}
+
/// getThumbCBTargetOpValue - Return encoding info for Thumb branch target.
uint32_t ARMMCCodeEmitter::
getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx,
Fixups);
}
+/// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand.
+uint32_t ARMMCCodeEmitter::
+getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO1 = MI.getOperand(OpIdx);
+ const MCOperand &MO2 = MI.getOperand(OpIdx+1);
+ unsigned Rn = getARMRegisterNumbering(MO1.getReg());
+ unsigned Rm = getARMRegisterNumbering(MO2.getReg());
+ return (Rm << 3) | Rn;
+}
+
/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand.
uint32_t ARMMCCodeEmitter::
getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
Expr = MO.getExpr();
else
Expr = MO2.getExpr();
-
+
const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
MCFixupKind Kind;
if (Subtarget.isThumb2())
uint32_t ARMMCCodeEmitter::
getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const {
- // {17-13} = reg
- // {12} = (U)nsigned (add == '1', sub == '0')
- // {11-0} = imm8
+ // {12-9} = reg
+ // {8} = (U)nsigned (add == '1', sub == '0')
+ // {7-0} = imm8
unsigned Reg, Imm8;
bool isAdd = true;
// If The first operand isn't a register, we have a label reference.
uint32_t Binary = (Imm8 >> 2) & 0xff;
// Immediate is always encoded as positive. The 'U' bit controls add vs sub.
if (isAdd)
- Binary |= (1 << 9);
+ Binary |= (1 << 8);
Binary |= (Reg << 9);
return Binary;
}
SmallVectorImpl<MCFixup> &Fixups) const {
// {20-16} = imm{15-12}
// {11-0} = imm{11-0}
- const MCOperand &MO = MI.getOperand(OpIdx);
+ const MCOperand &MO = MI.getOperand(OpIdx);
if (MO.isImm()) {
return static_cast<unsigned>(MO.getImm());
- } else if (const MCSymbolRefExpr *Expr =
+ } else if (const MCSymbolRefExpr *Expr =
dyn_cast<MCSymbolRefExpr>(MO.getExpr())) {
MCFixupKind Kind;
switch (Expr->getKind()) {
}
/// getAddrModeSOpValue - Encode the t_addrmode_s# operands.
-static unsigned getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx,
- unsigned Scale) {
+uint32_t ARMMCCodeEmitter::
+getAddrModeSOpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &) const {
// [Rn, Rm]
// {5-3} = Rm
// {2-0} = Rn
const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
unsigned Rn = getARMRegisterNumbering(MO.getReg());
- unsigned Imm5 = (MO1.getImm() / Scale) & 0x1f;
+ unsigned Imm5 = MO1.getImm();
if (MO2.getReg() != 0)
// Is an immediate.
Imm5 = getARMRegisterNumbering(MO2.getReg());
- return (Imm5 << 3) | Rn;
-}
-
-/// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &) const {
- return getAddrModeSOpValue(MI, OpIdx, 4);
-}
-
-/// getAddrModeS2OpValue - Return encoding for t_addrmode_s2 operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModeS2OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &) const {
- return getAddrModeSOpValue(MI, OpIdx, 2);
-}
-
-/// getAddrModeS1OpValue - Return encoding for t_addrmode_s1 operands.
-uint32_t ARMMCCodeEmitter::
-getAddrModeS1OpValue(const MCInst &MI, unsigned OpIdx,
- SmallVectorImpl<MCFixup> &) const {
- return getAddrModeSOpValue(MI, OpIdx, 1);
+ return ((Imm5 & 0x1f) << 3) | Rn;
}
/// getAddrModePCOpValue - Return encoding for t_addrmode_pc operands.
SmallVectorImpl<MCFixup> &Fixups) const {
const MCOperand &MO1 = MI.getOperand(OpNum);
const MCOperand &MO2 = MI.getOperand(OpNum+1);
- const MCOperand &MO3 = MI.getOperand(OpNum+2);
-
+ const MCOperand &MO3 = MI.getOperand(OpNum+2);
+
// Encoded as [Rn, Rm, imm].
// FIXME: Needs fixup support.
unsigned Value = getARMRegisterNumbering(MO1.getReg());
Value |= getARMRegisterNumbering(MO2.getReg());
Value <<= 2;
Value |= MO3.getImm();
-
+
return Value;
}
// FIXME: Needs fixup support.
unsigned Value = getARMRegisterNumbering(MO1.getReg());
-
+
// Even though the immediate is 8 bits long, we need 9 bits in order
// to represent the (inverse of the) sign bit.
Value <<= 9;