diff --git a/include/llvm/Support/ELFRelocs/Hexagon.def b/include/llvm/Support/ELFRelocs/Hexagon.def index a698ecb89e1..74e1d405ceb 100644 --- a/include/llvm/Support/ELFRelocs/Hexagon.def +++ b/include/llvm/Support/ELFRelocs/Hexagon.def @@ -98,3 +98,4 @@ ELF_RELOC(R_HEX_LD_GOT_16, 90) 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) diff --git a/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index 8b8eb4aabb0..b6d10f7dc0b 100644 --- a/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -278,6 +278,7 @@ public: 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); } @@ -384,6 +385,9 @@ public: 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); } @@ -1543,6 +1547,18 @@ int HexagonAsmParser::processInstruction(MCInst &Inst, 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: diff --git a/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 208f02f0ef4..48f3e3111a8 100644 --- a/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -264,6 +264,19 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, 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: diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index b209ff87959..6424022d3ec 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -418,6 +418,12 @@ defm addi : Addri_base<"add", add>, ImmRegRel, PredNewRel; 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) diff --git a/lib/Target/Hexagon/HexagonOperands.td b/lib/Target/Hexagon/HexagonOperands.td index fbd29cd4d6d..7224bb62c68 100644 --- a/lib/Target/Hexagon/HexagonOperands.td +++ b/lib/Target/Hexagon/HexagonOperands.td @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// 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"; } @@ -48,6 +49,7 @@ let OperandType = "OPERAND_IMMEDIATE", DecoderMethod = "unsignedImmDecoder" in { def s32Imm : Operand { let ParserMatchClass = s32ImmOperand; let DecoderMethod = "s32ImmDecoder"; } + def s23_2Imm : Operand { let ParserMatchClass = s23_2ImmOperand; } def s8Imm : Operand { let ParserMatchClass = s8ImmOperand; let DecoderMethod = "s8ImmDecoder"; } def s8Imm64 : Operand { let ParserMatchClass = s8Imm64Operand; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp index 4f03c970e2d..944e235e72f 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp @@ -282,6 +282,8 @@ unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx, 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; } } diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h b/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h index 4bbfbec883c..4c97ebbdd34 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonFixupKinds.h @@ -110,6 +110,7 @@ enum Fixups { fixup_Hexagon_TPREL_32_6_X, fixup_Hexagon_TPREL_16_X, fixup_Hexagon_TPREL_11_X, + fixup_Hexagon_23_REG, LastTargetFixupKind, NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index fcc9fcd3e01..d4eb2fc420d 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -550,6 +550,13 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, } } 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; diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp index d3ee31434ea..8a83e7b1b9b 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp @@ -52,12 +52,17 @@ void HexagonMCExpr::setMustNotExtend(bool Val) { } 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); diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h index e16d92609bd..1396f2df02e 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h @@ -29,12 +29,15 @@ public: 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 diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index 9b3d11a8fed..fb585b9fc77 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -431,6 +431,9 @@ bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII, // 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(MO.getExpr()) && + HexagonMCInstrInfo::mustNotExtend(*MO.getExpr())) + return false; int64_t Value; if (!MO.getExpr()->evaluateAsAbsolute(Value)) return true; @@ -665,6 +668,15 @@ void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) { Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask); assert(isMemStoreReorderEnabled(MCI)); } +void HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) { + HexagonMCExpr &HExpr = + const_cast(*llvm::cast(&Expr)); + HExpr.setS23_2_reloc(Val); +} +bool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) { + HexagonMCExpr const &HExpr = *llvm::cast(&Expr); + return HExpr.s23_2_reloc(); +} void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) { assert(isBundle(MCI)); diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h index 6bfcabf45fc..c9162a6aa6a 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h @@ -274,12 +274,14 @@ bool prefersSlot3(MCInstrInfo const &MCII, MCInst const &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); diff --git a/test/MC/Hexagon/iconst.s b/test/MC/Hexagon/iconst.s new file mode 100644 index 00000000000..277c4de8692 --- /dev/null +++ b/test/MC/Hexagon/iconst.s @@ -0,0 +1,6 @@ +# 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