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