LLVM 24.0.0git
X86EncodingOptimization.cpp
Go to the documentation of this file.
1//===-- X86EncodingOptimization.cpp - X86 Encoding optimization -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains the implementation of the X86 encoding optimization
10//
11//===----------------------------------------------------------------------===//
12
15#include "X86BaseInfo.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCInst.h"
18#include "llvm/MC/MCInstrDesc.h"
20
21using namespace llvm;
22
24 unsigned OpIdx1, OpIdx2;
25 unsigned Opcode = MI.getOpcode();
26 unsigned NewOpc = 0;
27#define FROM_TO(FROM, TO, IDX1, IDX2) \
28 case X86::FROM: \
29 NewOpc = X86::TO; \
30 OpIdx1 = IDX1; \
31 OpIdx2 = IDX2; \
32 break;
33#define TO_REV(FROM) FROM_TO(FROM, FROM##_REV, 0, 1)
34 switch (Opcode) {
35 default: {
36 // If the instruction is a commutable arithmetic instruction we might be
37 // able to commute the operands to get a 2 byte VEX prefix.
38 uint64_t TSFlags = Desc.TSFlags;
39 if (!Desc.isCommutable() || (TSFlags & X86II::EncodingMask) != X86II::VEX ||
40 (TSFlags & X86II::OpMapMask) != X86II::TB ||
41 (TSFlags & X86II::FormMask) != X86II::MRMSrcReg ||
42 (TSFlags & X86II::REX_W) || !(TSFlags & X86II::VEX_4V) ||
43 MI.getNumOperands() != 3)
44 return false;
45 // These two are not truly commutable.
46 if (Opcode == X86::VMOVHLPSrr || Opcode == X86::VUNPCKHPDrr)
47 return false;
48 OpIdx1 = 1;
49 OpIdx2 = 2;
50 break;
51 }
52 case X86::VCMPPDrri:
53 case X86::VCMPPDYrri:
54 case X86::VCMPPSrri:
55 case X86::VCMPPSYrri:
56 case X86::VCMPSDrri:
57 case X86::VCMPSSrri: {
58 // A symbolic predicate is not known until link time, so whether the
59 // operands commute cannot be decided here. Leave the encoding alone.
60 if (!MI.getOperand(3).isImm())
61 return false;
62 switch (MI.getOperand(3).getImm() & 0x7) {
63 default:
64 return false;
65 case 0x00: // EQUAL
66 case 0x03: // UNORDERED
67 case 0x04: // NOT EQUAL
68 case 0x07: // ORDERED
69 OpIdx1 = 1;
70 OpIdx2 = 2;
71 break;
72 }
73 break;
74 }
75 // Commute operands to get a smaller encoding by using VEX.R instead of
76 // VEX.B if one of the registers is extended, but other isn't.
77 FROM_TO(VMOVZPQILo2PQIrr, VMOVPQI2QIrr, 0, 1)
78 TO_REV(VMOVAPDrr)
79 TO_REV(VMOVAPDYrr)
80 TO_REV(VMOVAPSrr)
81 TO_REV(VMOVAPSYrr)
82 TO_REV(VMOVDQArr)
83 TO_REV(VMOVDQAYrr)
84 TO_REV(VMOVDQUrr)
85 TO_REV(VMOVDQUYrr)
86 TO_REV(VMOVUPDrr)
87 TO_REV(VMOVUPDYrr)
88 TO_REV(VMOVUPSrr)
89 TO_REV(VMOVUPSYrr)
90#undef TO_REV
91#define TO_REV(FROM) FROM_TO(FROM, FROM##_REV, 0, 2)
92 TO_REV(VMOVSDrr)
93 TO_REV(VMOVSSrr)
94#undef TO_REV
95#undef FROM_TO
96 }
97 if (X86II::isX86_64ExtendedReg(MI.getOperand(OpIdx1).getReg()) ||
98 !X86II::isX86_64ExtendedReg(MI.getOperand(OpIdx2).getReg()))
99 return false;
100 if (NewOpc)
101 MI.setOpcode(NewOpc);
102 else
103 std::swap(MI.getOperand(OpIdx1), MI.getOperand(OpIdx2));
104 return true;
105}
106
107// NOTE: We may write this as an InstAlias if it's only used by AsmParser. See
108// validateTargetOperandClass.
110 unsigned NewOpc;
111#define TO_IMM1(FROM) \
112 case X86::FROM##i: \
113 NewOpc = X86::FROM##1; \
114 break; \
115 case X86::FROM##i_EVEX: \
116 NewOpc = X86::FROM##1_EVEX; \
117 break; \
118 case X86::FROM##i_ND: \
119 NewOpc = X86::FROM##1_ND; \
120 break;
121 switch (MI.getOpcode()) {
122 default:
123 return false;
124 TO_IMM1(RCR8r)
125 TO_IMM1(RCR16r)
126 TO_IMM1(RCR32r)
127 TO_IMM1(RCR64r)
128 TO_IMM1(RCL8r)
129 TO_IMM1(RCL16r)
130 TO_IMM1(RCL32r)
131 TO_IMM1(RCL64r)
132 TO_IMM1(RCR8m)
133 TO_IMM1(RCR16m)
134 TO_IMM1(RCR32m)
135 TO_IMM1(RCR64m)
136 TO_IMM1(RCL8m)
137 TO_IMM1(RCL16m)
138 TO_IMM1(RCL32m)
139 TO_IMM1(RCL64m)
140#undef TO_IMM1
141#define TO_IMM1(FROM) \
142 case X86::FROM##i: \
143 NewOpc = X86::FROM##1; \
144 break; \
145 case X86::FROM##i_EVEX: \
146 NewOpc = X86::FROM##1_EVEX; \
147 break; \
148 case X86::FROM##i_NF: \
149 NewOpc = X86::FROM##1_NF; \
150 break; \
151 case X86::FROM##i_ND: \
152 NewOpc = X86::FROM##1_ND; \
153 break; \
154 case X86::FROM##i_NF_ND: \
155 NewOpc = X86::FROM##1_NF_ND; \
156 break;
157 TO_IMM1(ROR8r)
158 TO_IMM1(ROR16r)
159 TO_IMM1(ROR32r)
160 TO_IMM1(ROR64r)
161 TO_IMM1(ROL8r)
162 TO_IMM1(ROL16r)
163 TO_IMM1(ROL32r)
164 TO_IMM1(ROL64r)
165 TO_IMM1(SAR8r)
166 TO_IMM1(SAR16r)
167 TO_IMM1(SAR32r)
168 TO_IMM1(SAR64r)
169 TO_IMM1(SHR8r)
170 TO_IMM1(SHR16r)
171 TO_IMM1(SHR32r)
172 TO_IMM1(SHR64r)
173 TO_IMM1(SHL8r)
174 TO_IMM1(SHL16r)
175 TO_IMM1(SHL32r)
176 TO_IMM1(SHL64r)
177 TO_IMM1(ROR8m)
178 TO_IMM1(ROR16m)
179 TO_IMM1(ROR32m)
180 TO_IMM1(ROR64m)
181 TO_IMM1(ROL8m)
182 TO_IMM1(ROL16m)
183 TO_IMM1(ROL32m)
184 TO_IMM1(ROL64m)
185 TO_IMM1(SAR8m)
186 TO_IMM1(SAR16m)
187 TO_IMM1(SAR32m)
188 TO_IMM1(SAR64m)
189 TO_IMM1(SHR8m)
190 TO_IMM1(SHR16m)
191 TO_IMM1(SHR32m)
192 TO_IMM1(SHR64m)
193 TO_IMM1(SHL8m)
194 TO_IMM1(SHL16m)
195 TO_IMM1(SHL32m)
196 TO_IMM1(SHL64m)
197#undef TO_IMM1
198 }
199 MCOperand &LastOp = MI.getOperand(MI.getNumOperands() - 1);
200 if (!LastOp.isImm() || LastOp.getImm() != 1)
201 return false;
202 MI.setOpcode(NewOpc);
203 MI.erase(&LastOp);
204 return true;
205}
206
208 unsigned Opc1;
209 unsigned Opc2;
210#define FROM_TO(FROM, TO1, TO2) \
211 case X86::FROM: \
212 Opc1 = X86::TO1; \
213 Opc2 = X86::TO2; \
214 break;
215 switch (MI.getOpcode()) {
216 default:
217 return false;
218 FROM_TO(VPCMPBZ128rmi, VPCMPEQBZ128rm, VPCMPGTBZ128rm)
219 FROM_TO(VPCMPBZ128rmik, VPCMPEQBZ128rmk, VPCMPGTBZ128rmk)
220 FROM_TO(VPCMPBZ128rri, VPCMPEQBZ128rr, VPCMPGTBZ128rr)
221 FROM_TO(VPCMPBZ128rrik, VPCMPEQBZ128rrk, VPCMPGTBZ128rrk)
222 FROM_TO(VPCMPBZ256rmi, VPCMPEQBZ256rm, VPCMPGTBZ256rm)
223 FROM_TO(VPCMPBZ256rmik, VPCMPEQBZ256rmk, VPCMPGTBZ256rmk)
224 FROM_TO(VPCMPBZ256rri, VPCMPEQBZ256rr, VPCMPGTBZ256rr)
225 FROM_TO(VPCMPBZ256rrik, VPCMPEQBZ256rrk, VPCMPGTBZ256rrk)
226 FROM_TO(VPCMPBZrmi, VPCMPEQBZrm, VPCMPGTBZrm)
227 FROM_TO(VPCMPBZrmik, VPCMPEQBZrmk, VPCMPGTBZrmk)
228 FROM_TO(VPCMPBZrri, VPCMPEQBZrr, VPCMPGTBZrr)
229 FROM_TO(VPCMPBZrrik, VPCMPEQBZrrk, VPCMPGTBZrrk)
230 FROM_TO(VPCMPDZ128rmi, VPCMPEQDZ128rm, VPCMPGTDZ128rm)
231 FROM_TO(VPCMPDZ128rmbi, VPCMPEQDZ128rmb, VPCMPGTDZ128rmb)
232 FROM_TO(VPCMPDZ128rmbik, VPCMPEQDZ128rmbk, VPCMPGTDZ128rmbk)
233 FROM_TO(VPCMPDZ128rmik, VPCMPEQDZ128rmk, VPCMPGTDZ128rmk)
234 FROM_TO(VPCMPDZ128rri, VPCMPEQDZ128rr, VPCMPGTDZ128rr)
235 FROM_TO(VPCMPDZ128rrik, VPCMPEQDZ128rrk, VPCMPGTDZ128rrk)
236 FROM_TO(VPCMPDZ256rmi, VPCMPEQDZ256rm, VPCMPGTDZ256rm)
237 FROM_TO(VPCMPDZ256rmbi, VPCMPEQDZ256rmb, VPCMPGTDZ256rmb)
238 FROM_TO(VPCMPDZ256rmbik, VPCMPEQDZ256rmbk, VPCMPGTDZ256rmbk)
239 FROM_TO(VPCMPDZ256rmik, VPCMPEQDZ256rmk, VPCMPGTDZ256rmk)
240 FROM_TO(VPCMPDZ256rri, VPCMPEQDZ256rr, VPCMPGTDZ256rr)
241 FROM_TO(VPCMPDZ256rrik, VPCMPEQDZ256rrk, VPCMPGTDZ256rrk)
242 FROM_TO(VPCMPDZrmi, VPCMPEQDZrm, VPCMPGTDZrm)
243 FROM_TO(VPCMPDZrmbi, VPCMPEQDZrmb, VPCMPGTDZrmb)
244 FROM_TO(VPCMPDZrmbik, VPCMPEQDZrmbk, VPCMPGTDZrmbk)
245 FROM_TO(VPCMPDZrmik, VPCMPEQDZrmk, VPCMPGTDZrmk)
246 FROM_TO(VPCMPDZrri, VPCMPEQDZrr, VPCMPGTDZrr)
247 FROM_TO(VPCMPDZrrik, VPCMPEQDZrrk, VPCMPGTDZrrk)
248 FROM_TO(VPCMPQZ128rmi, VPCMPEQQZ128rm, VPCMPGTQZ128rm)
249 FROM_TO(VPCMPQZ128rmbi, VPCMPEQQZ128rmb, VPCMPGTQZ128rmb)
250 FROM_TO(VPCMPQZ128rmbik, VPCMPEQQZ128rmbk, VPCMPGTQZ128rmbk)
251 FROM_TO(VPCMPQZ128rmik, VPCMPEQQZ128rmk, VPCMPGTQZ128rmk)
252 FROM_TO(VPCMPQZ128rri, VPCMPEQQZ128rr, VPCMPGTQZ128rr)
253 FROM_TO(VPCMPQZ128rrik, VPCMPEQQZ128rrk, VPCMPGTQZ128rrk)
254 FROM_TO(VPCMPQZ256rmi, VPCMPEQQZ256rm, VPCMPGTQZ256rm)
255 FROM_TO(VPCMPQZ256rmbi, VPCMPEQQZ256rmb, VPCMPGTQZ256rmb)
256 FROM_TO(VPCMPQZ256rmbik, VPCMPEQQZ256rmbk, VPCMPGTQZ256rmbk)
257 FROM_TO(VPCMPQZ256rmik, VPCMPEQQZ256rmk, VPCMPGTQZ256rmk)
258 FROM_TO(VPCMPQZ256rri, VPCMPEQQZ256rr, VPCMPGTQZ256rr)
259 FROM_TO(VPCMPQZ256rrik, VPCMPEQQZ256rrk, VPCMPGTQZ256rrk)
260 FROM_TO(VPCMPQZrmi, VPCMPEQQZrm, VPCMPGTQZrm)
261 FROM_TO(VPCMPQZrmbi, VPCMPEQQZrmb, VPCMPGTQZrmb)
262 FROM_TO(VPCMPQZrmbik, VPCMPEQQZrmbk, VPCMPGTQZrmbk)
263 FROM_TO(VPCMPQZrmik, VPCMPEQQZrmk, VPCMPGTQZrmk)
264 FROM_TO(VPCMPQZrri, VPCMPEQQZrr, VPCMPGTQZrr)
265 FROM_TO(VPCMPQZrrik, VPCMPEQQZrrk, VPCMPGTQZrrk)
266 FROM_TO(VPCMPWZ128rmi, VPCMPEQWZ128rm, VPCMPGTWZ128rm)
267 FROM_TO(VPCMPWZ128rmik, VPCMPEQWZ128rmk, VPCMPGTWZ128rmk)
268 FROM_TO(VPCMPWZ128rri, VPCMPEQWZ128rr, VPCMPGTWZ128rr)
269 FROM_TO(VPCMPWZ128rrik, VPCMPEQWZ128rrk, VPCMPGTWZ128rrk)
270 FROM_TO(VPCMPWZ256rmi, VPCMPEQWZ256rm, VPCMPGTWZ256rm)
271 FROM_TO(VPCMPWZ256rmik, VPCMPEQWZ256rmk, VPCMPGTWZ256rmk)
272 FROM_TO(VPCMPWZ256rri, VPCMPEQWZ256rr, VPCMPGTWZ256rr)
273 FROM_TO(VPCMPWZ256rrik, VPCMPEQWZ256rrk, VPCMPGTWZ256rrk)
274 FROM_TO(VPCMPWZrmi, VPCMPEQWZrm, VPCMPGTWZrm)
275 FROM_TO(VPCMPWZrmik, VPCMPEQWZrmk, VPCMPGTWZrmk)
276 FROM_TO(VPCMPWZrri, VPCMPEQWZrr, VPCMPGTWZrr)
277 FROM_TO(VPCMPWZrrik, VPCMPEQWZrrk, VPCMPGTWZrrk)
278#undef FROM_TO
279 }
280 MCOperand &LastOp = MI.getOperand(MI.getNumOperands() - 1);
281 if (!LastOp.isImm())
282 return false;
283 int64_t Imm = LastOp.getImm();
284 unsigned NewOpc;
285 if (Imm == 0)
286 NewOpc = Opc1;
287 else if(Imm == 6)
288 NewOpc = Opc2;
289 else
290 return false;
291 MI.setOpcode(NewOpc);
292 MI.erase(&LastOp);
293 return true;
294}
295
297 unsigned NewOpc;
298#define FROM_TO(FROM, TO, R0, R1) \
299 case X86::FROM: \
300 if (MI.getOperand(0).getReg() != X86::R0 || \
301 MI.getOperand(1).getReg() != X86::R1) \
302 return false; \
303 NewOpc = X86::TO; \
304 break;
305 switch (MI.getOpcode()) {
306 default:
307 return false;
308 FROM_TO(MOVSX16rr8, CBW, AX, AL) // movsbw %al, %ax --> cbtw
309 FROM_TO(MOVSX32rr16, CWDE, EAX, AX) // movswl %ax, %eax --> cwtl
310 FROM_TO(MOVSX64rr32, CDQE, RAX, EAX) // movslq %eax, %rax --> cltq
311#undef FROM_TO
312 }
313 MI.clear();
314 MI.setOpcode(NewOpc);
315 return true;
316}
317
318bool X86::optimizeINCDEC(MCInst &MI, bool In64BitMode) {
319 if (In64BitMode)
320 return false;
321 unsigned NewOpc;
322 // If we aren't in 64-bit mode we can use the 1-byte inc/dec instructions.
323#define FROM_TO(FROM, TO) \
324 case X86::FROM: \
325 NewOpc = X86::TO; \
326 break;
327 switch (MI.getOpcode()) {
328 default:
329 return false;
330 FROM_TO(DEC16r, DEC16r_alt)
331 FROM_TO(DEC32r, DEC32r_alt)
332 FROM_TO(INC16r, INC16r_alt)
333 FROM_TO(INC32r, INC32r_alt)
334 }
335 MI.setOpcode(NewOpc);
336 return true;
337}
338
340 return Reg == X86::AL || Reg == X86::AX || Reg == X86::EAX || Reg == X86::RAX;
341}
342
343/// Simplify things like MOV32rm to MOV32o32a.
344bool X86::optimizeMOV(MCInst &MI, bool In64BitMode) {
345 // Don't make these simplifications in 64-bit mode; other assemblers don't
346 // perform them because they make the code larger.
347 if (In64BitMode)
348 return false;
349 unsigned NewOpc;
350 // We don't currently select the correct instruction form for instructions
351 // which have a short %eax, etc. form. Handle this by custom lowering, for
352 // now.
353 //
354 // Note, we are currently not handling the following instructions:
355 // MOV64ao8, MOV64o8a
356 // XCHG16ar, XCHG32ar, XCHG64ar
357 switch (MI.getOpcode()) {
358 default:
359 return false;
360 FROM_TO(MOV8mr_NOREX, MOV8o32a)
361 FROM_TO(MOV8mr, MOV8o32a)
362 FROM_TO(MOV8rm_NOREX, MOV8ao32)
363 FROM_TO(MOV8rm, MOV8ao32)
364 FROM_TO(MOV16mr, MOV16o32a)
365 FROM_TO(MOV16rm, MOV16ao32)
366 FROM_TO(MOV32mr, MOV32o32a)
367 FROM_TO(MOV32rm, MOV32ao32)
368 }
369 bool IsStore = MI.getOperand(0).isReg() && MI.getOperand(1).isReg();
370 unsigned AddrBase = IsStore;
371 unsigned RegOp = IsStore ? 0 : 5;
372 unsigned AddrOp = AddrBase + 3;
373 // Check whether the destination register can be fixed.
374 MCRegister Reg = MI.getOperand(RegOp).getReg();
375 if (!isARegister(Reg))
376 return false;
377 // Check whether this is an absolute address.
378 // FIXME: We know TLVP symbol refs aren't, but there should be a better way
379 // to do this here.
380 bool Absolute = true;
381 if (MI.getOperand(AddrOp).isExpr()) {
382 const MCExpr *MCE = MI.getOperand(AddrOp).getExpr();
383 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(MCE))
384 if (SRE->getSpecifier() == X86::S_TLVP)
385 Absolute = false;
386 }
387 if (Absolute && (MI.getOperand(AddrBase + X86::AddrBaseReg).getReg() ||
388 MI.getOperand(AddrBase + X86::AddrScaleAmt).getImm() != 1 ||
389 MI.getOperand(AddrBase + X86::AddrIndexReg).getReg()))
390 return false;
391 // If so, rewrite the instruction.
392 MCOperand Saved = MI.getOperand(AddrOp);
393 MCOperand Seg = MI.getOperand(AddrBase + X86::AddrSegmentReg);
394 MI.clear();
395 MI.setOpcode(NewOpc);
396 MI.addOperand(Saved);
397 MI.addOperand(Seg);
398 return true;
399}
400
401/// Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with
402/// a short fixed-register form.
404 unsigned NewOpc;
405 switch (MI.getOpcode()) {
406 default:
407 return false;
408 FROM_TO(ADC8ri, ADC8i8)
409 FROM_TO(ADC16ri, ADC16i16)
410 FROM_TO(ADC32ri, ADC32i32)
411 FROM_TO(ADC64ri32, ADC64i32)
412 FROM_TO(ADD8ri, ADD8i8)
413 FROM_TO(ADD16ri, ADD16i16)
414 FROM_TO(ADD32ri, ADD32i32)
415 FROM_TO(ADD64ri32, ADD64i32)
416 FROM_TO(AND8ri, AND8i8)
417 FROM_TO(AND16ri, AND16i16)
418 FROM_TO(AND32ri, AND32i32)
419 FROM_TO(AND64ri32, AND64i32)
420 FROM_TO(CMP8ri, CMP8i8)
421 FROM_TO(CMP16ri, CMP16i16)
422 FROM_TO(CMP32ri, CMP32i32)
423 FROM_TO(CMP64ri32, CMP64i32)
424 FROM_TO(OR8ri, OR8i8)
425 FROM_TO(OR16ri, OR16i16)
426 FROM_TO(OR32ri, OR32i32)
427 FROM_TO(OR64ri32, OR64i32)
428 FROM_TO(SBB8ri, SBB8i8)
429 FROM_TO(SBB16ri, SBB16i16)
430 FROM_TO(SBB32ri, SBB32i32)
431 FROM_TO(SBB64ri32, SBB64i32)
432 FROM_TO(SUB8ri, SUB8i8)
433 FROM_TO(SUB16ri, SUB16i16)
434 FROM_TO(SUB32ri, SUB32i32)
435 FROM_TO(SUB64ri32, SUB64i32)
436 FROM_TO(TEST8ri, TEST8i8)
437 FROM_TO(TEST16ri, TEST16i16)
438 FROM_TO(TEST32ri, TEST32i32)
439 FROM_TO(TEST64ri32, TEST64i32)
440 FROM_TO(XOR8ri, XOR8i8)
441 FROM_TO(XOR16ri, XOR16i16)
442 FROM_TO(XOR32ri, XOR32i32)
443 FROM_TO(XOR64ri32, XOR64i32)
444 }
445 // Check whether the destination register can be fixed.
446 MCRegister Reg = MI.getOperand(0).getReg();
447 if (!isARegister(Reg))
448 return false;
449
450 // If so, rewrite the instruction.
451 MCOperand Saved = MI.getOperand(MI.getNumOperands() - 1);
452 MI.clear();
453 MI.setOpcode(NewOpc);
454 MI.addOperand(Saved);
455 return true;
456}
457
458unsigned X86::getOpcodeForShortImmediateForm(unsigned Opcode) {
459#define ENTRY(LONG, SHORT) \
460 case X86::LONG: \
461 return X86::SHORT;
462 switch (Opcode) {
463 default:
464 return Opcode;
465#include "X86EncodingOptimizationForImmediate.def"
466 }
467}
468
469unsigned X86::getOpcodeForLongImmediateForm(unsigned Opcode) {
470#define ENTRY(LONG, SHORT) \
471 case X86::SHORT: \
472 return X86::LONG;
473 switch (Opcode) {
474 default:
475 return Opcode;
476#include "X86EncodingOptimizationForImmediate.def"
477 }
478}
479
481 unsigned NewOpc;
482#define ENTRY(LONG, SHORT) \
483 case X86::LONG: \
484 NewOpc = X86::SHORT; \
485 break;
486 switch (MI.getOpcode()) {
487 default:
488 return false;
489#include "X86EncodingOptimizationForImmediate.def"
490 }
491 unsigned SkipOperands = X86::isCCMPCC(MI.getOpcode()) ? 2 : 0;
492 MCOperand &LastOp = MI.getOperand(MI.getNumOperands() - 1 - SkipOperands);
493 if (LastOp.isExpr()) {
495 if (!SRE || SRE->getSpecifier() != X86::S_ABS8)
496 return false;
497 } else if (LastOp.isImm()) {
498 if (!isInt<8>(LastOp.getImm()))
499 return false;
500 }
501 MI.setOpcode(NewOpc);
502 return true;
503}
504
506 // We may optimize twice here.
507 bool ShortImm = optimizeToShortImmediateForm(MI);
508 bool FixedReg = optimizeToFixedRegisterForm(MI);
509 return ShortImm || FixedReg;
510}
Fixup Statepoint Caller Saved
IRTranslator LLVM IR MI
Register Reg
static bool optimizeToShortImmediateForm(MCInst &MI)
#define FROM_TO(FROM, TO, IDX1, IDX2)
static bool optimizeToFixedRegisterForm(MCInst &MI)
Simplify FOO $imm, %{al,ax,eax,rax} to FOO $imm, for instruction with a short fixed-register form.
#define TO_IMM1(FROM)
#define TO_REV(FROM)
static bool isARegister(MCRegister Reg)
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Describe properties that are true of each instruction in the target description file.
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
Represent a reference to a symbol from inside an expression.
Definition MCExpr.h:190
uint16_t getSpecifier() const
Definition MCExpr.h:232
@ VEX
VEX - encoding using 0xC4/0xC5.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ MRMSrcReg
MRMSrcReg - This form is used for instructions that use the Mod/RM byte to specify a source,...
bool isX86_64ExtendedReg(MCRegister Reg)
bool optimizeToFixedRegisterOrShortImmediateForm(MCInst &MI)
bool optimizeMOV(MCInst &MI, bool In64BitMode)
Simplify things like MOV32rm to MOV32o32a.
bool optimizeMOVSX(MCInst &MI)
bool optimizeVPCMPWithImmediateOneOrSix(MCInst &MI)
bool optimizeShiftRotateWithImmediateOne(MCInst &MI)
bool optimizeInstFromVEX3ToVEX2(MCInst &MI, const MCInstrDesc &Desc)
unsigned getOpcodeForLongImmediateForm(unsigned Opcode)
bool optimizeINCDEC(MCInst &MI, bool In64BitMode)
unsigned getOpcodeForShortImmediateForm(unsigned Opcode)
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
Op::Description Desc
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880