llvm.org GIT mirror llvm / 6b00c9f
Fix branch relaxation in 16-bit mode. Thread through MCSubtargetInfo to relaxInstruction function allowing relaxation to generate jumps with 16-bit sized immediates in 16-bit mode. This fixes PR22097. Reviewers: dwmw2, tstellarAMD, craig.topper, jyknight Subscribers: jfb, arsenm, jyknight, llvm-commits, dsanders Differential Revision: http://reviews.llvm.org/D20830 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@275068 91177308-0d34-0410-b5e6-96231b3b80d8 Nirav Dave 4 years ago
17 changed file(s) with 118 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
101101 ///
102102 /// \param Inst The instruction to relax, which may be the same as the
103103 /// output.
104 /// \param STI the subtarget information for the associated instruction.
104105 /// \param [out] Res On return, the relaxed instruction.
105 virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const = 0;
106 virtual void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
107 MCInst &Res) const = 0;
106108
107109 /// @}
108110
764764 // Relax the fragment.
765765
766766 MCInst Relaxed;
767 getBackend().relaxInstruction(F.getInst(), Relaxed);
767 getBackend().relaxInstruction(F.getInst(), F.getSubtargetInfo(), Relaxed);
768768
769769 // Encode the new instruction.
770770 //
251251 if (Assembler.getRelaxAll() ||
252252 (Assembler.isBundlingEnabled() && Sec->isBundleLocked())) {
253253 MCInst Relaxed;
254 getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
254 getAssembler().getBackend().relaxInstruction(Inst, STI, Relaxed);
255255 while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
256 getAssembler().getBackend().relaxInstruction(Relaxed, Relaxed);
256 getAssembler().getBackend().relaxInstruction(Relaxed, STI, Relaxed);
257257 EmitInstToData(Relaxed, STI);
258258 return;
259259 }
7777 bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
7878 const MCRelaxableFragment *DF,
7979 const MCAsmLayout &Layout) const override;
80 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override;
80 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
81 MCInst &Res) const override;
8182 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
8283
8384 void HandleAssemblerFlag(MCAssemblerFlag Flag) {}
312313 }
313314
314315 void AArch64AsmBackend::relaxInstruction(const MCInst &Inst,
316 const MCSubtargetInfo &STI,
315317 MCInst &Res) const {
316318 llvm_unreachable("AArch64AsmBackend::relaxInstruction() unimplemented");
317319 }
5252 const MCAsmLayout &Layout) const override {
5353 return false;
5454 }
55 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {
55 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
56 MCInst &Res) const override {
5657 assert(!"Not implemented");
5758 }
5859 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
257257 return reasonForFixupRelaxation(Fixup, Value);
258258 }
259259
260 void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
260 void ARMAsmBackend::relaxInstruction(const MCInst &Inst,
261 const MCSubtargetInfo &STI,
262 MCInst &Res) const {
261263 unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
262264
263265 // Sanity check w/ diagnostic if we get here w/ a bogus instruction.
6262 const MCRelaxableFragment *DF,
6363 const MCAsmLayout &Layout) const override;
6464
65 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override;
65 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
66 MCInst &Res) const override;
6667
6768 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
6869
4646
4747 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
4848
49 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
49 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
50 MCInst &Res) const override {}
5051
5152 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
5253 };
633633 llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced");
634634 }
635635
636 void relaxInstruction(MCInst const & Inst,
637 MCInst & Res) const override {
636 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
637 MCInst &Res) const override {
638638 assert(HexagonMCInstrInfo::isBundle(Inst) &&
639639 "Hexagon relaxInstruction only works on bundles");
640640
6868
6969 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
7070
71 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
71 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
72 MCInst &Res) const override {}
7273
7374 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
7475 };
7474 /// \param Inst - The instruction to relax, which may be the same
7575 /// as the output.
7676 /// \param [out] Res On return, the relaxed instruction.
77 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
77 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
78 MCInst &Res) const override {}
7879
7980 /// @}
8081
167167 llvm_unreachable("relaxInstruction() unimplemented");
168168 }
169169
170
171 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {
170 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
171 MCInst &Res) const override {
172172 // FIXME.
173173 llvm_unreachable("relaxInstruction() unimplemented");
174174 }
247247 llvm_unreachable("fixupNeedsRelaxation() unimplemented");
248248 return false;
249249 }
250 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {
250 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
251 MCInst &Res) const override {
251252 // FIXME.
252253 llvm_unreachable("relaxInstruction() unimplemented");
253254 }
5757 const MCAsmLayout &Layout) const override {
5858 return false;
5959 }
60 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {
60 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
61 MCInst &Res) const override {
6162 llvm_unreachable("SystemZ does do not have assembler relaxation");
6263 }
6364 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
5454
5555 bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
5656
57 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override {}
57 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
58 MCInst &Res) const override {}
5859
5960 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
6061 };
130130 const MCRelaxableFragment *DF,
131131 const MCAsmLayout &Layout) const override;
132132
133 void relaxInstruction(const MCInst &Inst, MCInst &Res) const override;
133 void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
134 MCInst &Res) const override;
134135
135136 bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
136137 };
137138 } // end anonymous namespace
138139
139 static unsigned getRelaxedOpcodeBranch(unsigned Op) {
140 static unsigned getRelaxedOpcodeBranch(const MCInst &Inst, bool is16BitMode) {
141 unsigned Op = Inst.getOpcode();
140142 switch (Op) {
141143 default:
142144 return Op;
143
144 case X86::JAE_1: return X86::JAE_4;
145 case X86::JA_1: return X86::JA_4;
146 case X86::JBE_1: return X86::JBE_4;
147 case X86::JB_1: return X86::JB_4;
148 case X86::JE_1: return X86::JE_4;
149 case X86::JGE_1: return X86::JGE_4;
150 case X86::JG_1: return X86::JG_4;
151 case X86::JLE_1: return X86::JLE_4;
152 case X86::JL_1: return X86::JL_4;
153 case X86::JMP_1: return X86::JMP_4;
154 case X86::JNE_1: return X86::JNE_4;
155 case X86::JNO_1: return X86::JNO_4;
156 case X86::JNP_1: return X86::JNP_4;
157 case X86::JNS_1: return X86::JNS_4;
158 case X86::JO_1: return X86::JO_4;
159 case X86::JP_1: return X86::JP_4;
160 case X86::JS_1: return X86::JS_4;
161 }
162 }
163
164 static unsigned getRelaxedOpcodeArith(unsigned Op) {
145 case X86::JAE_1:
146 return (is16BitMode) ? X86::JAE_2 : X86::JAE_4;
147 case X86::JA_1:
148 return (is16BitMode) ? X86::JA_2 : X86::JA_4;
149 case X86::JBE_1:
150 return (is16BitMode) ? X86::JBE_2 : X86::JBE_4;
151 case X86::JB_1:
152 return (is16BitMode) ? X86::JB_2 : X86::JB_4;
153 case X86::JE_1:
154 return (is16BitMode) ? X86::JE_2 : X86::JE_4;
155 case X86::JGE_1:
156 return (is16BitMode) ? X86::JGE_2 : X86::JGE_4;
157 case X86::JG_1:
158 return (is16BitMode) ? X86::JG_2 : X86::JG_4;
159 case X86::JLE_1:
160 return (is16BitMode) ? X86::JLE_2 : X86::JLE_4;
161 case X86::JL_1:
162 return (is16BitMode) ? X86::JL_2 : X86::JL_4;
163 case X86::JMP_1:
164 return (is16BitMode) ? X86::JMP_2 : X86::JMP_4;
165 case X86::JNE_1:
166 return (is16BitMode) ? X86::JNE_2 : X86::JNE_4;
167 case X86::JNO_1:
168 return (is16BitMode) ? X86::JNO_2 : X86::JNO_4;
169 case X86::JNP_1:
170 return (is16BitMode) ? X86::JNP_2 : X86::JNP_4;
171 case X86::JNS_1:
172 return (is16BitMode) ? X86::JNS_2 : X86::JNS_4;
173 case X86::JO_1:
174 return (is16BitMode) ? X86::JO_2 : X86::JO_4;
175 case X86::JP_1:
176 return (is16BitMode) ? X86::JP_2 : X86::JP_4;
177 case X86::JS_1:
178 return (is16BitMode) ? X86::JS_2 : X86::JS_4;
179 }
180 }
181
182 static unsigned getRelaxedOpcodeArith(const MCInst &Inst) {
183 unsigned Op = Inst.getOpcode();
165184 switch (Op) {
166185 default:
167186 return Op;
245264 }
246265 }
247266
248 static unsigned getRelaxedOpcode(unsigned Op) {
249 unsigned R = getRelaxedOpcodeArith(Op);
250 if (R != Op)
267 static unsigned getRelaxedOpcode(const MCInst &Inst, bool is16BitMode) {
268 unsigned R = getRelaxedOpcodeArith(Inst);
269 if (R != Inst.getOpcode())
251270 return R;
252 return getRelaxedOpcodeBranch(Op);
271 return getRelaxedOpcodeBranch(Inst, is16BitMode);
253272 }
254273
255274 bool X86AsmBackend::mayNeedRelaxation(const MCInst &Inst) const {
256 // Branches can always be relaxed.
257 if (getRelaxedOpcodeBranch(Inst.getOpcode()) != Inst.getOpcode())
275 // Branches can always be relaxed in either mode.
276 if (getRelaxedOpcodeBranch(Inst, false) != Inst.getOpcode())
258277 return true;
259278
260279 // Check if this instruction is ever relaxable.
261 if (getRelaxedOpcodeArith(Inst.getOpcode()) == Inst.getOpcode())
280 if (getRelaxedOpcodeArith(Inst) == Inst.getOpcode())
262281 return false;
263282
264283
281300
282301 // FIXME: Can tblgen help at all here to verify there aren't other instructions
283302 // we can relax?
284 void X86AsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const {
303 void X86AsmBackend::relaxInstruction(const MCInst &Inst,
304 const MCSubtargetInfo &STI,
305 MCInst &Res) const {
285306 // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
286 unsigned RelaxedOp = getRelaxedOpcode(Inst.getOpcode());
307 bool is16BitMode = STI.getFeatureBits()[X86::Mode16Bit];
308 unsigned RelaxedOp = getRelaxedOpcode(Inst, is16BitMode);
287309
288310 if (RelaxedOp == Inst.getOpcode()) {
289311 SmallString<256> Tmp;
0 # RUN: llvm-mc -filetype=obj -triple=i386-unknown-unknown %s -o %t
1 # RUN: llvm-objdump -r -D -section .text.bar -triple i386-unknown-unknown-code16 %t | FileCheck --check-prefix=CHECK16 %s
2 # RUN: llvm-objdump -r -D -section .text.baz -triple i386-unknown-unknown %t | FileCheck --check-prefix=CHECK32 %s
3 .text
4 .section .text.foo,"",@progbits
5
6 .code16
7 .globl foo
8 foo:
9 nop
10
11 .section .text.bar,"",@progbits
12 .globl bar16
13 bar16:
14 jmp foo
15
16 .section .text.baz,"",@progbits
17 .code32
18 .globl baz32
19 baz32:
20 jmp foo
21
22
23
24
25 // CHECK16-LABEL: bar16
26 // CHECK16-NEXT: e9 fe ff jmp -2
27 // CHECK32-LABEL: baz32
28 // CHECK32-NEXT: e9 fc ff ff ff jmp -4
29
30