~ARMMCCodeEmitter() override {}
bool isThumb(const MCSubtargetInfo &STI) const {
- return (STI.getFeatureBits() & ARM::ModeThumb) != 0;
+ return STI.getFeatureBits()[ARM::ModeThumb];
}
bool isThumb2(const MCSubtargetInfo &STI) const {
- return isThumb(STI) && (STI.getFeatureBits() & ARM::FeatureThumb2) != 0;
+ return isThumb(STI) && STI.getFeatureBits()[ARM::FeatureThumb2];
}
bool isTargetMachO(const MCSubtargetInfo &STI) const {
- Triple TT(STI.getTargetTriple());
+ const Triple &TT = STI.getTargetTriple();
return TT.isOSBinFormatMachO();
}
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
- /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
+ /// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
+ /// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
+ uint32_t getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const;
+
/// getCCOutOpValue - Return encoding of the 's' bit.
unsigned getCCOutOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups,
// See ARMELFObjectWriter::ExplicitRelSym and
// ARMELFObjectWriter::GetRelocTypeInner for more details.
MCFixupKind Kind = MCFixupKind(FK_Data_4);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
return 0;
}
// See ARMELFObjectWriter::ExplicitRelSym and
// ARMELFObjectWriter::GetRelocTypeInner for more details.
MCFixupKind Kind = MCFixupKind(FK_Data_4);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
return 0;
}
}
}
- void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ void encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const override;
};
assert(MO.isExpr() && "Unexpected branch target type!");
const MCExpr *Expr = MO.getExpr();
MCFixupKind Kind = MCFixupKind(FixupKind);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
// All of the information is in the fixup.
return 0;
Kind = MCFixupKind(ARM::fixup_t2_ldst_pcrel_12);
else
Kind = MCFixupKind(ARM::fixup_arm_ldst_pcrel_12);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
++MCNumCPRelocations;
} else {
assert(MO.isExpr() && "Unexpected machine operand type!");
const MCExpr *Expr = MO.getExpr();
MCFixupKind Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
++MCNumCPRelocations;
} else
break;
}
- Fixups.push_back(MCFixup::Create(0, E, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, E, Kind, MI.getLoc()));
return 0;
}
// If the expression doesn't have :upper16: or :lower16: on it,
// it's just a plain immediate expression, previously those evaluated to
// the lower 16 bits of the expression regardless of whether
// we have a movt or a movw, but that led to misleadingly results.
- // This is now disallowed in the the AsmParser in validateInstruction()
+ // This is disallowed in the AsmParser in validateInstruction()
// so this should never happen.
llvm_unreachable("expression without :upper16: or :lower16:");
}
assert(MO.isExpr() && "Unexpected machine operand type!");
const MCExpr *Expr = MO.getExpr();
MCFixupKind Kind = MCFixupKind(ARM::fixup_arm_pcrel_10_unscaled);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
++MCNumCPRelocations;
return (Rn << 9) | (1 << 13);
return (MO.getImm() >> 2);
}
-/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm10' operand.
+/// getAddrMode5OpValue - Return encoding info for 'reg +/- (imm8 << 2)' operand.
uint32_t ARMMCCodeEmitter::
getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups,
Kind = MCFixupKind(ARM::fixup_t2_pcrel_10);
else
Kind = MCFixupKind(ARM::fixup_arm_pcrel_10);
- Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc()));
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
+
+ ++MCNumCPRelocations;
+ } else {
+ EncodeAddrModeOpValues(MI, OpIdx, Reg, Imm8, Fixups, STI);
+ isAdd = ARM_AM::getAM5Op(Imm8) == ARM_AM::add;
+ }
+
+ uint32_t Binary = ARM_AM::getAM5Offset(Imm8);
+ // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
+ if (isAdd)
+ Binary |= (1 << 8);
+ Binary |= (Reg << 9);
+ return Binary;
+}
+
+/// getAddrMode5FP16OpValue - Return encoding info for 'reg +/- (imm8 << 1)' operand.
+uint32_t ARMMCCodeEmitter::
+getAddrMode5FP16OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups,
+ const MCSubtargetInfo &STI) const {
+ // {12-9} = reg
+ // {8} = (U)nsigned (add == '1', sub == '0')
+ // {7-0} = imm8
+ unsigned Reg, Imm8;
+ bool isAdd;
+ // If The first operand isn't a register, we have a label reference.
+ const MCOperand &MO = MI.getOperand(OpIdx);
+ if (!MO.isReg()) {
+ Reg = CTX.getRegisterInfo()->getEncodingValue(ARM::PC); // Rn is PC.
+ Imm8 = 0;
+ isAdd = false; // 'U' bit is handled as part of the fixup.
+
+ assert(MO.isExpr() && "Unexpected machine operand type!");
+ const MCExpr *Expr = MO.getExpr();
+ MCFixupKind Kind;
+ if (isThumb2(STI))
+ Kind = MCFixupKind(ARM::fixup_t2_pcrel_9);
+ else
+ Kind = MCFixupKind(ARM::fixup_arm_pcrel_9);
+ Fixups.push_back(MCFixup::create(0, Expr, Kind, MI.getLoc()));
++MCNumCPRelocations;
} else {
}
void ARMMCCodeEmitter::
-EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+encodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
// Pseudo instructions don't get encoded.