ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
+ELF_RELOC(R_HEX_23_REG, 94)
bool isf32Ext() const { return false; }
bool iss32Imm() const { return CheckImmRange(32, 0, true, true, false); }
+ bool iss23_2Imm() const { return CheckImmRange(23, 2, true, true, false); }
bool iss8Imm() const { return CheckImmRange(8, 0, true, false, false); }
bool iss8Imm64() const { return CheckImmRange(8, 0, true, true, false); }
bool iss7Imm() const { return CheckImmRange(7, 0, true, false, false); }
void adds32ImmOperands(MCInst &Inst, unsigned N) const {
addSignedImmOperands(Inst, N);
}
+ void adds23_2ImmOperands(MCInst &Inst, unsigned N) const {
+ addSignedImmOperands(Inst, N);
+ }
void adds8ImmOperands(MCInst &Inst, unsigned N) const {
addSignedImmOperands(Inst, N);
}
default:
break;
+ case Hexagon::A2_iconst: {
+ Inst.setOpcode(Hexagon::A2_addi);
+ MCOperand Reg = Inst.getOperand(0);
+ MCOperand S16 = Inst.getOperand(1);
+ HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
+ HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
+ Inst.clear();
+ Inst.addOperand(Reg);
+ Inst.addOperand(MCOperand::createReg(Hexagon::R0));
+ Inst.addOperand(S16);
+ break;
+ }
case Hexagon::M4_mpyrr_addr:
case Hexagon::S4_addi_asl_ri:
case Hexagon::S4_addi_lsr_ri:
switch (Inst.getOpcode()) {
default: return;
+ case Hexagon::A2_iconst: {
+ Inst.setOpcode(Hexagon::A2_addi);
+ MCOperand Reg = Inst.getOperand(0);
+ MCOperand S16 = Inst.getOperand(1);
+ HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
+ HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
+ Inst.clear();
+ Inst.addOperand(Reg);
+ Inst.addOperand(MCOperand::createReg(Hexagon::R0));
+ Inst.addOperand(S16);
+ break;
+ }
+
// "$dst = CONST64(#$src1)",
case Hexagon::CONST64_Float_Real:
case Hexagon::CONST64_Int_Real:
def: Pat<(i32 (add I32:$Rs, s32ImmPred:$s16)),
(i32 (A2_addi I32:$Rs, imm:$s16))>;
+let hasNewValue = 1, hasSideEffects = 0, isPseudo = 1 in
+def A2_iconst
+ : ALU32_ri <(outs IntRegs:$Rd),
+ (ins s23_2Imm:$s23_2),
+ "$Rd = iconst(#$s23_2)"> {}
+
//===----------------------------------------------------------------------===//
// Template class used for the following ALU32 instructions.
// Rd=and(Rs,#s10)
//===----------------------------------------------------------------------===//
def s32ImmOperand : AsmOperandClass { let Name = "s32Imm"; }
+def s23_2ImmOperand : AsmOperandClass { let Name = "s23_2Imm"; }
def s8ImmOperand : AsmOperandClass { let Name = "s8Imm"; }
def s8Imm64Operand : AsmOperandClass { let Name = "s8Imm64"; }
def s6ImmOperand : AsmOperandClass { let Name = "s6Imm"; }
DecoderMethod = "unsignedImmDecoder" in {
def s32Imm : Operand<i32> { let ParserMatchClass = s32ImmOperand;
let DecoderMethod = "s32ImmDecoder"; }
+ def s23_2Imm : Operand<i32> { let ParserMatchClass = s23_2ImmOperand; }
def s8Imm : Operand<i32> { let ParserMatchClass = s8ImmOperand;
let DecoderMethod = "s8ImmDecoder"; }
def s8Imm64 : Operand<i64> { let ParserMatchClass = s8Imm64Operand;
return ELF::R_HEX_TPREL_16_X;
case fixup_Hexagon_TPREL_11_X:
return ELF::R_HEX_TPREL_11_X;
+ case fixup_Hexagon_23_REG:
+ return ELF::R_HEX_23_REG;
}
}
fixup_Hexagon_TPREL_32_6_X,
fixup_Hexagon_TPREL_16_X,
fixup_Hexagon_TPREL_11_X,
+ fixup_Hexagon_23_REG,
LastTargetFixupKind,
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
}
} else
switch (kind) {
+ case MCSymbolRefExpr::VK_None: {
+ if (HexagonMCInstrInfo::s23_2_reloc(*MO.getExpr()))
+ FixupKind = Hexagon::fixup_Hexagon_23_REG;
+ else
+ raise_relocation_error(bits, kind);
+ break;
+ }
case MCSymbolRefExpr::VK_DTPREL:
FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
break;
}
bool HexagonMCExpr::mustNotExtend() const { return MustNotExtend; }
+bool HexagonMCExpr::s23_2_reloc() const { return S23_2_reloc; }
+void HexagonMCExpr::setS23_2_reloc(bool Val) {
+ S23_2_reloc = Val;
+}
+
bool HexagonMCExpr::classof(MCExpr const *E) {
return E->getKind() == MCExpr::Target;
}
HexagonMCExpr::HexagonMCExpr(MCExpr const *Expr)
- : Expr(Expr), MustNotExtend(false), MustExtend(false) {}
+ : Expr(Expr), MustNotExtend(false), MustExtend(false), S23_2_reloc(false) {}
void HexagonMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
Expr->print(OS, MAI);
bool mustExtend() const;
void setMustNotExtend(bool Val = true);
bool mustNotExtend() const;
+ void setS23_2_reloc(bool Val = true);
+ bool s23_2_reloc() const;
private:
HexagonMCExpr(MCExpr const *Expr);
MCExpr const *Expr;
bool MustNotExtend;
bool MustExtend;
+ bool S23_2_reloc;
};
} // end namespace llvm
// object we are going to end up with here for now.
// In the future we probably should add isSymbol(), etc.
assert(!MO.isImm());
+ if (isa<HexagonMCExpr>(MO.getExpr()) &&
+ HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
+ return false;
int64_t Value;
if (!MO.getExpr()->evaluateAsAbsolute(Value))
return true;
Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
assert(isMemStoreReorderEnabled(MCI));
}
+void HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) {
+ HexagonMCExpr &HExpr =
+ const_cast<HexagonMCExpr &>(*llvm::cast<HexagonMCExpr>(&Expr));
+ HExpr.setS23_2_reloc(Val);
+}
+bool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) {
+ HexagonMCExpr const &HExpr = *llvm::cast<HexagonMCExpr>(&Expr);
+ return HExpr.s23_2_reloc();
+}
void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
assert(isBundle(MCI));
// Replace the instructions inside MCB, represented by Candidate
void replaceDuplex(MCContext &Context, MCInst &MCB, DuplexCandidate Candidate);
+bool s23_2_reloc(MCExpr const &Expr);
// Marks a bundle as endloop0
void setInnerLoop(MCInst &MCI);
void setMemReorderDisabled(MCInst &MCI);
void setMemStoreReorderEnabled(MCInst &MCI);
void setMustExtend(MCExpr &Expr, bool Val = true);
void setMustNotExtend(MCExpr const &Expr, bool Val = true);
+void setS23_2_reloc(MCExpr const &Expr, bool Val = true);
// Marks a bundle as endloop1
void setOuterLoop(MCInst &MCI);
--- /dev/null
+# RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d -r - | FileCheck %s
+
+a:
+# CHECK: r0 = add(r0, #0)
+# CHECK: R_HEX_23_REG
+r0 = iconst(#a)
\ No newline at end of file