llvm.org GIT mirror llvm / 3bc4397
[X86] Remove the single AdSize indicator and replace it with separate AdSize16/32/64 flags. This removes a hardcoded list of instructions in the CodeEmitter. Eventually I intend to remove the predicates on the affected instructions since in any given mode two of them are valid if we supported addr32/addr16 prefixes in the assembler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224809 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 4 years ago
8 changed file(s) with 119 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
327327 OpSizeShift = 7,
328328 OpSizeMask = 0x3 << OpSizeShift,
329329
330 OpSize16 = 1 << OpSizeShift,
331 OpSize32 = 2 << OpSizeShift,
332
333 // AsSize - Set if this instruction requires an operand size prefix (0x67),
334 // which most often indicates that the instruction address 16 bit address
335 // instead of 32 bit address (or 32 bit address in 64 bit mode).
330 OpSizeFixed = 0 << OpSizeShift,
331 OpSize16 = 1 << OpSizeShift,
332 OpSize32 = 2 << OpSizeShift,
333
334 // AsSize - AdSizeX implies this instruction determines its need of 0x67
335 // prefix from a normal ModRM memory operand. The other types indicate that
336 // an operand is encoded with a specific width and a prefix is needed if
337 // it differs from the current mode.
336338 AdSizeShift = OpSizeShift + 2,
337 AdSize = 1 << AdSizeShift,
339 AdSizeMask = 0x3 << AdSizeShift,
340
341 AdSizeX = 1 << AdSizeShift,
342 AdSize16 = 1 << AdSizeShift,
343 AdSize32 = 2 << AdSizeShift,
344 AdSize64 = 3 << AdSizeShift,
338345
339346 //===------------------------------------------------------------------===//
340347 // OpPrefix - There are several prefix bytes that are used as opcode
341348 // extensions. These are 0x66, 0xF3, and 0xF2. If this field is 0 there is
342349 // no prefix.
343350 //
344 OpPrefixShift = AdSizeShift + 1,
351 OpPrefixShift = AdSizeShift + 2,
345352 OpPrefixMask = 0x7 << OpPrefixShift,
346353
347354 // PS, PD - Prefix code for packed single and double precision vector
11981198
11991199 // Emit the address size opcode prefix as needed.
12001200 bool need_address_override;
1201 // The AdSize prefix is only for 32-bit and 64-bit modes. Hm, perhaps we
1202 // should introduce an AdSize16 bit instead of having seven special cases?
1203 if ((!is16BitMode(STI) && TSFlags & X86II::AdSize) ||
1204 (is16BitMode(STI) && (MI.getOpcode() == X86::JECXZ_32 ||
1205 MI.getOpcode() == X86::MOV8o8a ||
1206 MI.getOpcode() == X86::MOV16o16a ||
1207 MI.getOpcode() == X86::MOV32o32a ||
1208 MI.getOpcode() == X86::MOV8ao8 ||
1209 MI.getOpcode() == X86::MOV16ao16 ||
1210 MI.getOpcode() == X86::MOV32ao32))) {
1201 uint64_t AdSize = TSFlags & X86II::AdSizeMask;
1202 if ((is16BitMode(STI) && AdSize == X86II::AdSize32) ||
1203 (is32BitMode(STI) && AdSize == X86II::AdSize16) ||
1204 (is64BitMode(STI) && AdSize == X86II::AdSize32)) {
12111205 need_address_override = true;
12121206 } else if (MemoryOperand < 0) {
12131207 need_address_override = false;
105105 // jecxz.
106106 let Uses = [CX] in
107107 def JCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
108 "jcxz\t$dst", [], IIC_JCXZ>, AdSize, Requires<[Not64BitMode]>;
108 "jcxz\t$dst", [], IIC_JCXZ>, AdSize16, Requires<[Not64BitMode]>;
109109 let Uses = [ECX] in
110110 def JECXZ_32 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
111 "jecxz\t$dst", [], IIC_JCXZ>, Requires<[Not64BitMode]>;
111 "jecxz\t$dst", [], IIC_JCXZ>, AdSize32, Requires<[Not64BitMode]>;
112112
113113 // J*CXZ instruction: 64-bit versions of this instruction for the asmparser.
114114 // In 64-bit mode, the address size prefix is jecxz and the unprefixed version
115115 // is jrcxz.
116116 let Uses = [ECX] in
117117 def JECXZ_64 : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
118 "jecxz\t$dst", [], IIC_JCXZ>, AdSize, Requires<[In64BitMode]>;
118 "jecxz\t$dst", [], IIC_JCXZ>, AdSize32, Requires<[In64BitMode]>;
119119 let Uses = [RCX] in
120120 def JRCXZ : Ii8PCRel<0xE3, RawFrm, (outs), (ins brtarget8:$dst),
121 "jrcxz\t$dst", [], IIC_JCXZ>, Requires<[In64BitMode]>;
121 "jrcxz\t$dst", [], IIC_JCXZ>, AdSize64, Requires<[In64BitMode]>;
122122 }
123123
124124 // Indirect branches
145145 def OpSize16 : OperandSize<1>; // Needs 0x66 prefix in 32-bit mode.
146146 def OpSize32 : OperandSize<2>; // Needs 0x66 prefix in 16-bit mode.
147147
148 // Address size for encodings that change based on mode.
149 class AddressSize val> {
150 bits<2> Value = val;
151 }
152 def AdSizeX : AddressSize<0>; // Address size determined using addr operand.
153 def AdSize16 : AddressSize<1>; // Encodes a 16-bit address.
154 def AdSize32 : AddressSize<2>; // Encodes a 32-bit address.
155 def AdSize64 : AddressSize<3>; // Encodes a 64-bit address.
156
148157 // Prefix byte classes which are used to indicate to the ad-hoc machine code
149158 // emitter that various prefix bytes are required.
150159 class OpSize16 { OperandSize OpSize = OpSize16; }
151160 class OpSize32 { OperandSize OpSize = OpSize32; }
152 class AdSize { bit hasAdSizePrefix = 1; }
161 class AdSize16 { AddressSize AdSize = AdSize16; }
162 class AdSize32 { AddressSize AdSize = AdSize32; }
163 class AdSize64 { AddressSize AdSize = AdSize64; }
153164 class REX_W { bit hasREX_WPrefix = 1; }
154165 class LOCK { bit hasLockPrefix = 1; }
155166 class REP { bit hasREPPrefix = 1; }
230241 // AsmString from the parser, but still disassemble.
231242
232243 OperandSize OpSize = OpSizeFixed; // Does this instruction's encoding change
233 // based on operand size of the mode
244 // based on operand size of the mode?
234245 bits<2> OpSizeBits = OpSize.Value;
235 bit hasAdSizePrefix = 0; // Does this inst have a 0x67 prefix?
246 AddressSize AdSize = AdSizeX; // Does this instruction's encoding change
247 // based on address size of the mode?
248 bits<2> AdSizeBits = AdSize.Value;
236249
237250 Prefix OpPrefix = NoPrfx; // Which prefix byte does this inst have?
238251 bits<3> OpPrefixBits = OpPrefix.Value;
283296 CD8_EltSize,
284297 !srl(VectSize, CD8_Form{1-0}))), 0);
285298
286 // TSFlags layout should be kept in sync with X86InstrInfo.h.
299 // TSFlags layout should be kept in sync with X86BaseInfo.h.
287300 let TSFlags{6-0} = FormBits;
288301 let TSFlags{8-7} = OpSizeBits;
289 let TSFlags{9} = hasAdSizePrefix;
290 let TSFlags{12-10} = OpPrefixBits;
291 let TSFlags{15-13} = OpMapBits;
292 let TSFlags{16} = hasREX_WPrefix;
293 let TSFlags{20-17} = ImmT.Value;
294 let TSFlags{23-21} = FPForm.Value;
295 let TSFlags{24} = hasLockPrefix;
296 let TSFlags{25} = hasREPPrefix;
297 let TSFlags{27-26} = ExeDomain.Value;
298 let TSFlags{29-28} = OpEncBits;
299 let TSFlags{37-30} = Opcode;
300 let TSFlags{38} = hasVEX_WPrefix;
301 let TSFlags{39} = hasVEX_4V;
302 let TSFlags{40} = hasVEX_4VOp3;
303 let TSFlags{41} = hasVEX_i8ImmReg;
304 let TSFlags{42} = hasVEX_L;
305 let TSFlags{43} = ignoresVEX_L;
306 let TSFlags{44} = hasEVEX_K;
307 let TSFlags{45} = hasEVEX_Z;
308 let TSFlags{46} = hasEVEX_L2;
309 let TSFlags{47} = hasEVEX_B;
302 let TSFlags{10-9} = AdSizeBits;
303 let TSFlags{13-11} = OpPrefixBits;
304 let TSFlags{16-14} = OpMapBits;
305 let TSFlags{17} = hasREX_WPrefix;
306 let TSFlags{21-18} = ImmT.Value;
307 let TSFlags{24-22} = FPForm.Value;
308 let TSFlags{25} = hasLockPrefix;
309 let TSFlags{26} = hasREPPrefix;
310 let TSFlags{28-27} = ExeDomain.Value;
311 let TSFlags{30-29} = OpEncBits;
312 let TSFlags{38-31} = Opcode;
313 let TSFlags{39} = hasVEX_WPrefix;
314 let TSFlags{40} = hasVEX_4V;
315 let TSFlags{41} = hasVEX_4VOp3;
316 let TSFlags{42} = hasVEX_i8ImmReg;
317 let TSFlags{43} = hasVEX_L;
318 let TSFlags{44} = ignoresVEX_L;
319 let TSFlags{45} = hasEVEX_K;
320 let TSFlags{46} = hasEVEX_Z;
321 let TSFlags{47} = hasEVEX_L2;
322 let TSFlags{48} = hasEVEX_B;
310323 // If we run out of TSFlags bits, it's possible to encode this in 3 bits.
311 let TSFlags{54-48} = CD8_Scale;
312 let TSFlags{55} = has3DNow0F0FOpcode;
313 let TSFlags{56} = hasMemOp4Prefix;
314 let TSFlags{57} = hasEVEX_RC;
324 let TSFlags{55-49} = CD8_Scale;
325 let TSFlags{56} = has3DNow0F0FOpcode;
326 let TSFlags{57} = hasMemOp4Prefix;
327 let TSFlags{58} = hasEVEX_RC;
315328 }
316329
317330 class PseudoI pattern>
12401240 let SchedRW = [WriteALU] in {
12411241 let mayLoad = 1 in {
12421242 let Defs = [AL] in
1243 def MOV8o8a : Ii32 <0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1243 def MOV8o8a : Ii32<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
12441244 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1245 Requires<[In32BitMode]>;
1245 AdSize32, Requires<[In32BitMode]>;
12461246 let Defs = [AX] in
1247 def MOV16o16a : Ii32 <0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1248 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1249 OpSize16, Requires<[In32BitMode]>;
1247 def MOV16o16a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1248 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1249 OpSize16, AdSize32, Requires<[In32BitMode]>;
12501250 let Defs = [EAX] in
1251 def MOV32o32a : Ii32 <0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1252 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1253 OpSize32, Requires<[In32BitMode]>;
1251 def MOV32o32a : Ii32<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1252 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1253 OpSize32, AdSize32, Requires<[In32BitMode]>;
12541254
12551255 let Defs = [AL] in
1256 def MOV8o8a_16 : Ii16 <0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1257 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1258 AdSize, Requires<[In16BitMode]>;
1256 def MOV8o8a_16 : Ii16<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
1257 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
1258 AdSize16, Requires<[In16BitMode]>;
12591259 let Defs = [AX] in
1260 def MOV16o16a_16 : Ii16 <0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1261 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1262 OpSize16, AdSize, Requires<[In16BitMode]>;
1260 def MOV16o16a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
1261 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>,
1262 OpSize16, AdSize16, Requires<[In16BitMode]>;
12631263 let Defs = [EAX] in
1264 def MOV32o32a_16 : Ii16 <0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1265 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1266 AdSize, OpSize32, Requires<[In16BitMode]>;
1264 def MOV32o32a_16 : Ii16<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
1265 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
1266 AdSize16, OpSize32, Requires<[In16BitMode]>;
12671267 }
12681268 let mayStore = 1 in {
12691269 let Uses = [AL] in
1270 def MOV8ao8 : Ii32 <0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1270 def MOV8ao8 : Ii32<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
12711271 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1272 Requires<[In32BitMode]>;
1272 AdSize32, Requires<[In32BitMode]>;
12731273 let Uses = [AX] in
1274 def MOV16ao16 : Ii32 <0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1275 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1276 OpSize16, Requires<[In32BitMode]>;
1274 def MOV16ao16 : Ii32<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1275 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1276 OpSize16, AdSize32, Requires<[In32BitMode]>;
12771277 let Uses = [EAX] in
1278 def MOV32ao32 : Ii32 <0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1279 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1280 OpSize32, Requires<[In32BitMode]>;
1278 def MOV32ao32 : Ii32<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1279 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1280 OpSize32, AdSize32, Requires<[In32BitMode]>;
12811281
12821282 let Uses = [AL] in
1283 def MOV8ao8_16 : Ii16 <0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1284 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1285 AdSize, Requires<[In16BitMode]>;
1283 def MOV8ao8_16 : Ii16<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
1284 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
1285 AdSize16, Requires<[In16BitMode]>;
12861286 let Uses = [AX] in
1287 def MOV16ao16_16 : Ii16 <0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1288 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1289 OpSize16, AdSize, Requires<[In16BitMode]>;
1287 def MOV16ao16_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
1288 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>,
1289 OpSize16, AdSize16, Requires<[In16BitMode]>;
12901290 let Uses = [EAX] in
1291 def MOV32ao32_16 : Ii16 <0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1292 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1293 OpSize32, AdSize, Requires<[In16BitMode]>;
1291 def MOV32ao32_16 : Ii16<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
1292 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
1293 OpSize32, AdSize16, Requires<[In16BitMode]>;
12941294 }
12951295 }
12961296
13001300 let Defs = [AL] in
13011301 def MOV64o8a : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
13021302 "movabs{b}\t{$src, %al|al, $src}", []>,
1303 Requires<[In64BitMode]>;
1303 AdSize64, Requires<[In64BitMode]>;
13041304 let Defs = [AX] in
13051305 def MOV64o16a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
13061306 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize16,
1307 Requires<[In64BitMode]>;
1307 AdSize64, Requires<[In64BitMode]>;
13081308 let Defs = [EAX] in
13091309 def MOV64o32a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
13101310 "movabs{l}\t{$src, %eax|eax, $src}", []>, OpSize32,
1311 Requires<[In64BitMode]>;
1311 AdSize64, Requires<[In64BitMode]>;
13121312 let Defs = [RAX] in
13131313 def MOV64o64a : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64:$src),
13141314 "movabs{q}\t{$src, %rax|rax, $src}", []>,
1315 Requires<[In64BitMode]>;
1315 AdSize64, Requires<[In64BitMode]>;
13161316 }
13171317
13181318 let mayStore = 1 in {
13191319 let Uses = [AL] in
13201320 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
13211321 "movabs{b}\t{%al, $dst|$dst, al}", []>,
1322 Requires<[In64BitMode]>;
1322 AdSize64, Requires<[In64BitMode]>;
13231323 let Uses = [AX] in
13241324 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
13251325 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize16,
1326 Requires<[In64BitMode]>;
1326 AdSize64, Requires<[In64BitMode]>;
13271327 let Uses = [EAX] in
13281328 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
13291329 "movabs{l}\t{%eax, $dst|$dst, eax}", []>, OpSize32,
1330 Requires<[In64BitMode]>;
1330 AdSize64, Requires<[In64BitMode]>;
13311331 let Uses = [RAX] in
13321332 def MOV64ao64 : RIi64<0xA3, RawFrmMemOffs, (outs offset64:$dst), (ins),
13331333 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
1334 Requires<[In64BitMode]>;
1334 AdSize64, Requires<[In64BitMode]>;
13351335 }
13361336 } // hasSideEffects = 0
13371337
821821 InstructionSpecifier &previousInfo =
822822 InstructionSpecifiers[decision.instructionIDs[index]];
823823
824 // FIXME this doesn't actually work. The MCInsts the disassembler
825 // create don't encode re-encode correctly. They just manage to mostly
826 // print correctly.
824827 // Instructions such as MOV8ao8 and MOV8ao8_16 differ only in the
825828 // presence of the AdSize prefix. However, the disassembler doesn't
826829 // care about that difference in the instruction definition; it
118118 enum {
119119 OpSize16 = 1, OpSize32 = 2
120120 };
121
122 enum {
123 AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
124 };
121125 }
122126
123127 using namespace X86Disassembler;
193197 Encoding = byteFromRec(Rec, "OpEncBits");
194198
195199 OpSize = byteFromRec(Rec, "OpSizeBits");
196 HasAdSizePrefix = Rec->getValueAsBit("hasAdSizePrefix");
200 AdSize = byteFromRec(Rec, "AdSizeBits");
197201 HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
198202 HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
199203 HasVEX_4VOp3 = Rec->getValueAsBit("hasVEX_4VOp3");
409413 insnContext = IC_64BIT_XS_OPSIZE;
410414 else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
411415 insnContext = IC_64BIT_OPSIZE;
412 else if (HasAdSizePrefix)
416 else if (AdSize == X86Local::AdSize32)
413417 insnContext = IC_64BIT_ADSIZE;
414418 else if (HasREX_WPrefix && OpPrefix == X86Local::XS)
415419 insnContext = IC_64BIT_REXW_XS;
430434 insnContext = IC_XS_OPSIZE;
431435 else if (OpSize == X86Local::OpSize16 || OpPrefix == X86Local::PD)
432436 insnContext = IC_OPSIZE;
433 else if (HasAdSizePrefix)
437 else if (AdSize == X86Local::AdSize16)
434438 insnContext = IC_ADSIZE;
435439 else if (OpPrefix == X86Local::XD)
436440 insnContext = IC_XD;
4949 uint8_t Encoding;
5050 /// The OpSize field from the record
5151 uint8_t OpSize;
52 /// The hasAdSizePrefix field from the record
53 bool HasAdSizePrefix;
52 /// The AdSize field from the record
53 uint8_t AdSize;
5454 /// The hasREX_WPrefix field from the record
5555 bool HasREX_WPrefix;
5656 /// The hasVEX_4V field from the record