llvm.org GIT mirror llvm / e7bc8f5
[Hexagon] Adding relocation for code size, cold path optimization allowing a 23-bit 4-byte aligned relocation to be a valid instruction encoding. The usual way to get a 32-bit relocation is to use a constant extender which doubles the size of the instruction, 4 bytes to 8 bytes. Another way is to put a .word32 and mix code and data within a function. The disadvantage is it's not a valid instruction encoding and jumping over it causes prefetch stalls inside the hardware. This relocation packs a 23-bit value in to an "r0 = add(rX, #a)" instruction by overwriting the source register bits. Since r0 is the return value register, if this instruction is placed after a function call which return void, r0 will be filled with an undefined value, the prefetch won't be confused, and the callee can access the constant value by way of the link register. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261006 91177308-0d34-0410-b5e6-96231b3b80d8 Colin LeMahieu 4 years ago
13 changed file(s) with 77 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
9797 ELF_RELOC(R_HEX_LD_GOT_32_6_X, 91)
9898 ELF_RELOC(R_HEX_LD_GOT_16_X, 92)
9999 ELF_RELOC(R_HEX_LD_GOT_11_X, 93)
100 ELF_RELOC(R_HEX_23_REG, 94)
277277
278278 bool isf32Ext() const { return false; }
279279 bool iss32Imm() const { return CheckImmRange(32, 0, true, true, false); }
280 bool iss23_2Imm() const { return CheckImmRange(23, 2, true, true, false); }
280281 bool iss8Imm() const { return CheckImmRange(8, 0, true, false, false); }
281282 bool iss8Imm64() const { return CheckImmRange(8, 0, true, true, false); }
282283 bool iss7Imm() const { return CheckImmRange(7, 0, true, false, false); }
381382 }
382383
383384 void adds32ImmOperands(MCInst &Inst, unsigned N) const {
385 addSignedImmOperands(Inst, N);
386 }
387 void adds23_2ImmOperands(MCInst &Inst, unsigned N) const {
384388 addSignedImmOperands(Inst, N);
385389 }
386390 void adds8ImmOperands(MCInst &Inst, unsigned N) const {
15421546 default:
15431547 break;
15441548
1549 case Hexagon::A2_iconst: {
1550 Inst.setOpcode(Hexagon::A2_addi);
1551 MCOperand Reg = Inst.getOperand(0);
1552 MCOperand S16 = Inst.getOperand(1);
1553 HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
1554 HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
1555 Inst.clear();
1556 Inst.addOperand(Reg);
1557 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1558 Inst.addOperand(S16);
1559 break;
1560 }
15451561 case Hexagon::M4_mpyrr_addr:
15461562 case Hexagon::S4_addi_asl_ri:
15471563 case Hexagon::S4_addi_lsr_ri:
263263 switch (Inst.getOpcode()) {
264264 default: return;
265265
266 case Hexagon::A2_iconst: {
267 Inst.setOpcode(Hexagon::A2_addi);
268 MCOperand Reg = Inst.getOperand(0);
269 MCOperand S16 = Inst.getOperand(1);
270 HexagonMCInstrInfo::setMustNotExtend(*S16.getExpr());
271 HexagonMCInstrInfo::setS23_2_reloc(*S16.getExpr());
272 Inst.clear();
273 Inst.addOperand(Reg);
274 Inst.addOperand(MCOperand::createReg(Hexagon::R0));
275 Inst.addOperand(S16);
276 break;
277 }
278
266279 // "$dst = CONST64(#$src1)",
267280 case Hexagon::CONST64_Float_Real:
268281 case Hexagon::CONST64_Int_Real:
416416
417417 def: Pat<(i32 (add I32:$Rs, s32ImmPred:$s16)),
418418 (i32 (A2_addi I32:$Rs, imm:$s16))>;
419
420 let hasNewValue = 1, hasSideEffects = 0, isPseudo = 1 in
421 def A2_iconst
422 : ALU32_ri <(outs IntRegs:$Rd),
423 (ins s23_2Imm:$s23_2),
424 "$Rd = iconst(#$s23_2)"> {}
419425
420426 //===----------------------------------------------------------------------===//
421427 // Template class used for the following ALU32 instructions.
77 //===----------------------------------------------------------------------===//
88
99 def s32ImmOperand : AsmOperandClass { let Name = "s32Imm"; }
10 def s23_2ImmOperand : AsmOperandClass { let Name = "s23_2Imm"; }
1011 def s8ImmOperand : AsmOperandClass { let Name = "s8Imm"; }
1112 def s8Imm64Operand : AsmOperandClass { let Name = "s8Imm64"; }
1213 def s6ImmOperand : AsmOperandClass { let Name = "s6Imm"; }
4748 DecoderMethod = "unsignedImmDecoder" in {
4849 def s32Imm : Operand { let ParserMatchClass = s32ImmOperand;
4950 let DecoderMethod = "s32ImmDecoder"; }
51 def s23_2Imm : Operand { let ParserMatchClass = s23_2ImmOperand; }
5052 def s8Imm : Operand { let ParserMatchClass = s8ImmOperand;
5153 let DecoderMethod = "s8ImmDecoder"; }
5254 def s8Imm64 : Operand { let ParserMatchClass = s8Imm64Operand;
281281 return ELF::R_HEX_TPREL_16_X;
282282 case fixup_Hexagon_TPREL_11_X:
283283 return ELF::R_HEX_TPREL_11_X;
284 case fixup_Hexagon_23_REG:
285 return ELF::R_HEX_23_REG;
284286 }
285287 }
286288
109109 fixup_Hexagon_TPREL_32_6_X,
110110 fixup_Hexagon_TPREL_16_X,
111111 fixup_Hexagon_TPREL_11_X,
112 fixup_Hexagon_23_REG,
112113
113114 LastTargetFixupKind,
114115 NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
549549 }
550550 } else
551551 switch (kind) {
552 case MCSymbolRefExpr::VK_None: {
553 if (HexagonMCInstrInfo::s23_2_reloc(*MO.getExpr()))
554 FixupKind = Hexagon::fixup_Hexagon_23_REG;
555 else
556 raise_relocation_error(bits, kind);
557 break;
558 }
552559 case MCSymbolRefExpr::VK_DTPREL:
553560 FixupKind = Hexagon::fixup_Hexagon_DTPREL_16;
554561 break;
5151 }
5252 bool HexagonMCExpr::mustNotExtend() const { return MustNotExtend; }
5353
54 bool HexagonMCExpr::s23_2_reloc() const { return S23_2_reloc; }
55 void HexagonMCExpr::setS23_2_reloc(bool Val) {
56 S23_2_reloc = Val;
57 }
58
5459 bool HexagonMCExpr::classof(MCExpr const *E) {
5560 return E->getKind() == MCExpr::Target;
5661 }
5762
5863 HexagonMCExpr::HexagonMCExpr(MCExpr const *Expr)
59 : Expr(Expr), MustNotExtend(false), MustExtend(false) {}
64 : Expr(Expr), MustNotExtend(false), MustExtend(false), S23_2_reloc(false) {}
6065
6166 void HexagonMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
6267 Expr->print(OS, MAI);
2828 bool mustExtend() const;
2929 void setMustNotExtend(bool Val = true);
3030 bool mustNotExtend() const;
31 void setS23_2_reloc(bool Val = true);
32 bool s23_2_reloc() const;
3133
3234 private:
3335 HexagonMCExpr(MCExpr const *Expr);
3436 MCExpr const *Expr;
3537 bool MustNotExtend;
3638 bool MustExtend;
39 bool S23_2_reloc;
3740 };
3841 } // end namespace llvm
3942
430430 // object we are going to end up with here for now.
431431 // In the future we probably should add isSymbol(), etc.
432432 assert(!MO.isImm());
433 if (isa(MO.getExpr()) &&
434 HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
435 return false;
433436 int64_t Value;
434437 if (!MO.getExpr()->evaluateAsAbsolute(Value))
435438 return true;
664667 Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
665668 assert(isMemStoreReorderEnabled(MCI));
666669 }
670 void HexagonMCInstrInfo::setS23_2_reloc(MCExpr const &Expr, bool Val) {
671 HexagonMCExpr &HExpr =
672 const_cast(*llvm::cast(&Expr));
673 HExpr.setS23_2_reloc(Val);
674 }
675 bool HexagonMCInstrInfo::s23_2_reloc(MCExpr const &Expr) {
676 HexagonMCExpr const &HExpr = *llvm::cast(&Expr);
677 return HExpr.s23_2_reloc();
678 }
667679
668680 void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
669681 assert(isBundle(MCI));
273273 // Replace the instructions inside MCB, represented by Candidate
274274 void replaceDuplex(MCContext &Context, MCInst &MCB, DuplexCandidate Candidate);
275275
276 bool s23_2_reloc(MCExpr const &Expr);
276277 // Marks a bundle as endloop0
277278 void setInnerLoop(MCInst &MCI);
278279 void setMemReorderDisabled(MCInst &MCI);
279280 void setMemStoreReorderEnabled(MCInst &MCI);
280281 void setMustExtend(MCExpr &Expr, bool Val = true);
281282 void setMustNotExtend(MCExpr const &Expr, bool Val = true);
283 void setS23_2_reloc(MCExpr const &Expr, bool Val = true);
282284
283285 // Marks a bundle as endloop1
284286 void setOuterLoop(MCInst &MCI);
0 # RUN: llvm-mc -triple=hexagon -filetype=obj %s | llvm-objdump -d -r - | FileCheck %s
1
2 a:
3 # CHECK: r0 = add(r0, #0)
4 # CHECK: R_HEX_23_REG
5 r0 = iconst(#a)