diff options
5 files changed, 66 insertions, 16 deletions
diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index becc086c81b..b6201ebf038 100644 --- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -1756,8 +1756,8 @@ int HexagonAsmParser::processInstruction(MCInst &Inst, TmpInst.setOpcode(Hexagon::L2_loadrdgp); TmpInst.addOperand(MO_0); - TmpInst.addOperand( - MCOperand::createExpr(MCSymbolRefExpr::create(Sym, getContext()))); + TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create( + MCSymbolRefExpr::create(Sym, getContext()), getContext()))); Inst = TmpInst; } } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td index 500f5f340f9..85d57baecd8 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV4.td @@ -2543,6 +2543,14 @@ class T_StoreAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp, !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, /* u16_0Imm */ addr{15-0}))); + let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, + !if (!eq(ImmOpStr, "u16_2Imm"), 18, + !if (!eq(ImmOpStr, "u16_1Imm"), 17, + /* u16_0Imm */ 16))); + let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, + !if (!eq(ImmOpStr, "u16_2Imm"), 2, + !if (!eq(ImmOpStr, "u16_1Imm"), 1, + /* u16_0Imm */ 0))); // Store upper-half and store doubleword cannot be NV. let isNVStorable = !if (!eq(mnemonic, "memd"), 0, !if(isHalf,0,1)); let Uses = !if (isAbs, [], [GP]); @@ -2651,6 +2659,14 @@ class T_StoreAbsGP_NV <string mnemonic, Operand ImmOp, bits<2>MajOp> !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, /* u16_0Imm */ addr{15-0}))); + let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, + !if (!eq(ImmOpStr, "u16_2Imm"), 18, + !if (!eq(ImmOpStr, "u16_1Imm"), 17, + /* u16_0Imm */ 16))); + let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, + !if (!eq(ImmOpStr, "u16_2Imm"), 2, + !if (!eq(ImmOpStr, "u16_1Imm"), 1, + /* u16_0Imm */ 0))); let IClass = 0b0100; let Inst{27} = 1; @@ -2822,6 +2838,14 @@ class T_LoadAbsGP <string mnemonic, RegisterClass RC, Operand ImmOp, !if (!eq(ImmOpStr, "u16_2Imm"), addr{17-2}, !if (!eq(ImmOpStr, "u16_1Imm"), addr{16-1}, /* u16_0Imm */ addr{15-0}))); + let opExtentBits = !if (!eq(ImmOpStr, "u16_3Imm"), 19, + !if (!eq(ImmOpStr, "u16_2Imm"), 18, + !if (!eq(ImmOpStr, "u16_1Imm"), 17, + /* u16_0Imm */ 16))); + let opExtentAlign = !if (!eq(ImmOpStr, "u16_3Imm"), 3, + !if (!eq(ImmOpStr, "u16_2Imm"), 2, + !if (!eq(ImmOpStr, "u16_1Imm"), 1, + /* u16_0Imm */ 0))); let IClass = 0b0100; diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp index cfb5165e590..18a408ed89e 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp @@ -521,7 +521,31 @@ unsigned HexagonMCCodeEmitter::getExprOpValue(const MCInst &MI, if (HexagonMCInstrInfo::s23_2_reloc(*MO.getExpr())) FixupKind = Hexagon::fixup_Hexagon_23_REG; else - raise_relocation_error(bits, kind); + if (MCID.mayStore() || MCID.mayLoad()) { + for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; + ++ImpUses) { + if (*ImpUses != Hexagon::GP) + continue; + switch (HexagonMCInstrInfo::getAccessSize(MCII, MI)) { + case HexagonII::MemAccessSize::ByteAccess: + FixupKind = fixup_Hexagon_GPREL16_0; + break; + case HexagonII::MemAccessSize::HalfWordAccess: + FixupKind = fixup_Hexagon_GPREL16_1; + break; + case HexagonII::MemAccessSize::WordAccess: + FixupKind = fixup_Hexagon_GPREL16_2; + break; + case HexagonII::MemAccessSize::DoubleWordAccess: + FixupKind = fixup_Hexagon_GPREL16_3; + break; + default: + raise_relocation_error(bits, kind); + } + } + } + else + raise_relocation_error(bits, kind); break; } case MCSymbolRefExpr::VK_DTPREL: diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp index b3fc43a249d..74c007c9a59 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp @@ -707,6 +707,17 @@ bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) { HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr); return HExpr.mustNotExtend(); } +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::dyn_cast<HexagonMCExpr>(&Expr); + if (!HExpr) + return false; + return HExpr->s23_2_reloc(); +} void HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) { MCInst Nop; @@ -772,15 +783,6 @@ 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<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)); diff --git a/llvm/test/MC/Hexagon/relocations.s b/llvm/test/MC/Hexagon/relocations.s index 8b90bc7c0cd..d52c37a66cc 100644 --- a/llvm/test/MC/Hexagon/relocations.s +++ b/llvm/test/MC/Hexagon/relocations.s @@ -30,19 +30,19 @@ r_hex_8: # CHECK: R_HEX_GPREL16_0 r_hex_gprel16_0: -{ r0 = memb (#undefined@gotrel) } +{ r0 = memb (gp+#undefined) } # CHECK: R_HEX_GPREL16_1 r_hex_gprel16_1: -{ r0 = memh (#undefined@gotrel) } +{ r0 = memh (gp+#undefined) } # CHECK: R_HEX_GPREL16_2 r_hex_gprel16_2: -{ r0 = memw (#undefined@gotrel) } +{ r0 = memw (gp+#undefined) } # CHECK: R_HEX_GPREL16_3 r_hex_gprel16_3: -{ r1:0 = memd (#undefined@gotrel) } +{ r1:0 = memd (gp+#undefined) } # CHECK: R_HEX_B13_PCREL r_hex_b13_pcrel: |