llvm.org GIT mirror llvm / 85026d9
Allow x86 mov instructions to/from memory with absolute address to be encoded and disassembled with a segment override prefix. Fixes PR16962. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199364 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 6 years ago
12 changed file(s) with 130 addition(s) and 60 deletion(s). Raw diff Collapse all Expand all
922922 }
923923
924924 bool isMemOffs8() const {
925 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
925 return Kind == Memory && !getMemBaseReg() &&
926926 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
927927 }
928928 bool isMemOffs16() const {
929 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
929 return Kind == Memory && !getMemBaseReg() &&
930930 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
931931 }
932932 bool isMemOffs32() const {
933 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
933 return Kind == Memory && !getMemBaseReg() &&
934934 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
935935 }
936936 bool isMemOffs64() const {
937 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
937 return Kind == Memory && !getMemBaseReg() &&
938938 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
939939 }
940940
10141014 }
10151015
10161016 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
1017 assert((N == 1) && "Invalid number of operands!");
1017 assert((N == 2) && "Invalid number of operands!");
10181018 // Add as immediates when possible.
10191019 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
10201020 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
10211021 else
10221022 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
1023 Inst.addOperand(MCOperand::CreateReg(getMemSegReg()));
10231024 }
10241025
10251026 static X86Operand *CreateToken(StringRef Str, SMLoc Loc) {
205205 const MCDisassembler *Dis = static_cast(Decoder);
206206 Dis->tryAddingPcLoadReferenceComment(Value, Address);
207207 }
208
209 static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
210 0, // SEG_OVERRIDE_NONE
211 X86::CS,
212 X86::SS,
213 X86::DS,
214 X86::ES,
215 X86::FS,
216 X86::GS
217 };
208218
209219 /// translateImmediate - Appends an immediate operand to an MCInst.
210220 ///
314324 insn.immediateOffset, insn.immediateSize,
315325 mcInst, Dis))
316326 mcInst.addOperand(MCOperand::CreateImm(immediate));
327
328 if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
329 type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
330 MCOperand segmentReg;
331 segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]);
332 mcInst.addOperand(segmentReg);
333 }
317334 }
318335
319336 /// translateRMRegister - Translates a register stored in the R/M field of the
521538 }
522539
523540 displacement = MCOperand::CreateImm(insn.displacement);
524
525 static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
526 0, // SEG_OVERRIDE_NONE
527 X86::CS,
528 X86::SS,
529 X86::DS,
530 X86::ES,
531 X86::FS,
532 X86::GS
533 };
534
541
535542 segmentReg = MCOperand::CreateReg(segmentRegnums[insn.segmentOverride]);
536543
537544 mcInst.addOperand(baseReg);
228228 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
229229 raw_ostream &O) {
230230 const MCOperand &DispSpec = MI->getOperand(Op);
231 const MCOperand &SegReg = MI->getOperand(Op+1);
231232
232233 O << markup("
234
235 // If this has a segment register, print it.
236 if (SegReg.getReg()) {
237 printOperand(MI, Op+1, O);
238 O << ':';
239 }
233240
234241 if (DispSpec.isImm()) {
235242 O << formatImm(DispSpec.getImm());
214214 void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
215215 raw_ostream &O) {
216216 const MCOperand &DispSpec = MI->getOperand(Op);
217 const MCOperand &SegReg = MI->getOperand(Op+1);
218
219 // If this has a segment register, print it.
220 if (SegReg.getReg()) {
221 printOperand(MI, Op+1, O);
222 O << ':';
223 }
217224
218225 O << '[';
219226
253253 /// to specify a source, which in this case is memory.
254254 ///
255255 MRMSrcMem = 6,
256
257 /// RawFrmMemOffs - This form is for instructions that store an absolute
258 /// memory offset as an immediate with a possible segment override.
259 RawFrmMemOffs = 7,
256260
257261 /// MRM[0-7][rm] - These forms are used to represent instructions that use
258262 /// a Mod/RM byte, and use the middle field to hold extended opcode
606610 case X86II::MRMSrcReg:
607611 case X86II::RawFrmImm8:
608612 case X86II::RawFrmImm16:
613 case X86II::RawFrmMemOffs:
609614 return -1;
610615 case X86II::MRMDestMem:
611616 return 0;
157157 const MCInst &MI, const MCInstrDesc &Desc,
158158 raw_ostream &OS) const;
159159
160 void EmitSegmentOverridePrefix(uint64_t TSFlags, unsigned &CurByte,
161 int MemOperand, const MCInst &MI,
162 raw_ostream &OS) const;
160 void EmitSegmentOverridePrefix(unsigned &CurByte, unsigned SegOperand,
161 const MCInst &MI, raw_ostream &OS) const;
163162
164163 void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
165164 const MCInst &MI, const MCInstrDesc &Desc,
976975 }
977976
978977 // Emit segment override opcode prefix as needed.
979 EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS);
978 if (MemOperand >= 0)
979 EmitSegmentOverridePrefix(CurByte, MemOperand+X86::AddrSegmentReg, MI, OS);
980980
981981 if (!HasEVEX) {
982982 // VEX opcode prefix can have 2 or 3 bytes
11331133 }
11341134
11351135 /// EmitSegmentOverridePrefix - Emit segment override opcode prefix as needed
1136 void X86MCCodeEmitter::EmitSegmentOverridePrefix(uint64_t TSFlags,
1137 unsigned &CurByte, int MemOperand,
1138 const MCInst &MI,
1139 raw_ostream &OS) const {
1140 if (MemOperand < 0)
1141 return; // No memory operand
1142
1136 void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte,
1137 unsigned SegOperand,
1138 const MCInst &MI,
1139 raw_ostream &OS) const {
11431140 // Check for explicit segment override on memory operand.
1144 switch (MI.getOperand(MemOperand+X86::AddrSegmentReg).getReg()) {
1141 switch (MI.getOperand(SegOperand).getReg()) {
11451142 default: llvm_unreachable("Unknown segment register!");
11461143 case 0: break;
11471144 case X86::CS: EmitByte(0x2E, CurByte, OS); break;
11671164 EmitByte(0xF0, CurByte, OS);
11681165
11691166 // Emit segment override opcode prefix as needed.
1170 EmitSegmentOverridePrefix(TSFlags, CurByte, MemOperand, MI, OS);
1167 if (MemOperand >= 0)
1168 EmitSegmentOverridePrefix(CurByte, MemOperand+X86::AddrSegmentReg, MI, OS);
11711169
11721170 // Emit the repeat opcode prefix as needed.
11731171 if ((TSFlags & X86II::Op0Mask) == X86II::REP)
13351333 llvm_unreachable("Pseudo instruction shouldn't be emitted");
13361334 case X86II::RawFrm:
13371335 EmitByte(BaseOpcode, CurByte, OS);
1336 break;
1337 case X86II::RawFrmMemOffs:
1338 // Emit segment override opcode prefix as needed.
1339 EmitSegmentOverridePrefix(CurByte, 1, MI, OS);
1340 EmitByte(BaseOpcode, CurByte, OS);
1341 EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
1342 X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
1343 CurByte, OS, Fixups);
1344 ++CurOp; // skip segment operand
13381345 break;
13391346 case X86II::RawFrmImm8:
13401347 EmitByte(BaseOpcode, CurByte, OS);
2020 def Pseudo : Format<0>; def RawFrm : Format<1>;
2121 def AddRegFrm : Format<2>; def MRMDestReg : Format<3>;
2222 def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
23 def MRMSrcMem : Format<6>;
23 def MRMSrcMem : Format<6>; def RawFrmMemOffs : Format<7>;
2424 def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
2525 def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
2626 def MRM6r : Format<22>; def MRM7r : Format<23>;
466466 }
467467
468468 let OperandType = "OPERAND_MEMORY" in {
469 def offset8 : Operand64> {
469 def offset8 : OperandPTR> {
470470 let ParserMatchClass = X86MemOffs8AsmOperand;
471 let MIOperandInfo = (ops i64imm, i8imm);
471472 let PrintMethod = "printMemOffs8"; }
472 def offset16 : Operand64> {
473 def offset16 : OperandPTR> {
473474 let ParserMatchClass = X86MemOffs16AsmOperand;
475 let MIOperandInfo = (ops i64imm, i8imm);
474476 let PrintMethod = "printMemOffs16"; }
475 def offset32 : Operand64> {
477 def offset32 : OperandPTR> {
476478 let ParserMatchClass = X86MemOffs32AsmOperand;
479 let MIOperandInfo = (ops i64imm, i8imm);
477480 let PrintMethod = "printMemOffs32"; }
478 def offset64 : Operand64> {
481 def offset64 : OperandPTR> {
479482 let ParserMatchClass = X86MemOffs64AsmOperand;
483 let MIOperandInfo = (ops i64imm, i8imm);
480484 let PrintMethod = "printMemOffs64"; }
481485 }
482486
11451149 /// 32-bit offset from the segment base. These are only valid in x86-32 mode.
11461150 let SchedRW = [WriteALU] in {
11471151 let mayLoad = 1 in {
1148 def MOV8o8a : Ii32 <0xA0, RawFrm, (outs), (ins offset8:$src),
1152 def MOV8o8a : Ii32 <0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
11491153 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
11501154 Requires<[In32BitMode]>;
1151 def MOV16o16a : Ii32 <0xA1, RawFrm, (outs), (ins offset16:$src),
1155 def MOV16o16a : Ii32 <0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
11521156 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>, OpSize,
11531157 Requires<[In32BitMode]>;
1154 def MOV32o32a : Ii32 <0xA1, RawFrm, (outs), (ins offset32:$src),
1158 def MOV32o32a : Ii32 <0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
11551159 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
11561160 OpSize16, Requires<[In32BitMode]>;
11571161
1158 def MOV8o8a_16 : Ii16 <0xA0, RawFrm, (outs), (ins offset8:$src),
1162 def MOV8o8a_16 : Ii16 <0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
11591163 "mov{b}\t{$src, %al|al, $src}", [], IIC_MOV_MEM>,
11601164 AdSize, Requires<[In16BitMode]>;
1161 def MOV16o16a_16 : Ii16 <0xA1, RawFrm, (outs), (ins offset16:$src),
1165 def MOV16o16a_16 : Ii16 <0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
11621166 "mov{w}\t{$src, %ax|ax, $src}", [], IIC_MOV_MEM>, OpSize,
11631167 AdSize, Requires<[In16BitMode]>;
1164 def MOV32o32a_16 : Ii16 <0xA1, RawFrm, (outs), (ins offset32:$src),
1168 def MOV32o32a_16 : Ii16 <0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
11651169 "mov{l}\t{$src, %eax|eax, $src}", [], IIC_MOV_MEM>,
11661170 AdSize, OpSize16, Requires<[In16BitMode]>;
11671171 }
11681172 let mayStore = 1 in {
1169 def MOV8ao8 : Ii32 <0xA2, RawFrm, (outs offset8:$dst), (ins),
1173 def MOV8ao8 : Ii32 <0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
11701174 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
11711175 Requires<[In32BitMode]>;
1172 def MOV16ao16 : Ii32 <0xA3, RawFrm, (outs offset16:$dst), (ins),
1176 def MOV16ao16 : Ii32 <0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
11731177 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>, OpSize,
11741178 Requires<[In32BitMode]>;
1175 def MOV32ao32 : Ii32 <0xA3, RawFrm, (outs offset32:$dst), (ins),
1179 def MOV32ao32 : Ii32 <0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
11761180 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
11771181 OpSize16, Requires<[In32BitMode]>;
11781182
1179 def MOV8ao8_16 : Ii16 <0xA2, RawFrm, (outs offset8:$dst), (ins),
1183 def MOV8ao8_16 : Ii16 <0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
11801184 "mov{b}\t{%al, $dst|$dst, al}", [], IIC_MOV_MEM>,
11811185 AdSize, Requires<[In16BitMode]>;
1182 def MOV16ao16_16 : Ii16 <0xA3, RawFrm, (outs offset16:$dst), (ins),
1186 def MOV16ao16_16 : Ii16 <0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
11831187 "mov{w}\t{%ax, $dst|$dst, ax}", [], IIC_MOV_MEM>, OpSize,
11841188 AdSize, Requires<[In16BitMode]>;
1185 def MOV32ao32_16 : Ii16 <0xA3, RawFrm, (outs offset32:$dst), (ins),
1189 def MOV32ao32_16 : Ii16 <0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
11861190 "mov{l}\t{%eax, $dst|$dst, eax}", [], IIC_MOV_MEM>,
11871191 OpSize16, AdSize, Requires<[In16BitMode]>;
11881192 }
11911195 // These forms all have full 64-bit absolute addresses in their instructions
11921196 // and use the movabs mnemonic to indicate this specific form.
11931197 let mayLoad = 1 in {
1194 def MOV64o8a : RIi64_NOREX<0xA0, RawFrm, (outs), (ins offset8:$src),
1198 def MOV64o8a : RIi64_NOREX<0xA0, RawFrmMemOffs, (outs), (ins offset8:$src),
11951199 "movabs{b}\t{$src, %al|al, $src}", []>,
11961200 Requires<[In64BitMode]>;
1197 def MOV64o16a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset16:$src),
1201 def MOV64o16a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset16:$src),
11981202 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize,
11991203 Requires<[In64BitMode]>;
1200 def MOV64o32a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset32:$src),
1204 def MOV64o32a : RIi64_NOREX<0xA1, RawFrmMemOffs, (outs), (ins offset32:$src),
12011205 "movabs{l}\t{$src, %eax|eax, $src}", []>,
12021206 Requires<[In64BitMode]>;
1203 def MOV64o64a : RIi64<0xA1, RawFrm, (outs), (ins offset64:$src),
1207 def MOV64o64a : RIi64<0xA1, RawFrmMemOffs, (outs), (ins offset64:$src),
12041208 "movabs{q}\t{$src, %rax|rax, $src}", []>,
12051209 Requires<[In64BitMode]>;
12061210 }
12071211
12081212 let mayStore = 1 in {
1209 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrm, (outs offset8:$dst), (ins),
1213 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrmMemOffs, (outs offset8:$dst), (ins),
12101214 "movabs{b}\t{%al, $dst|$dst, al}", []>,
12111215 Requires<[In64BitMode]>;
1212 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrm, (outs offset16:$dst), (ins),
1216 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset16:$dst), (ins),
12131217 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize,
12141218 Requires<[In64BitMode]>;
1215 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrm, (outs offset32:$dst), (ins),
1219 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrmMemOffs, (outs offset32:$dst), (ins),
12161220 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
12171221 Requires<[In64BitMode]>;
1218 def MOV64ao64 : RIi64<0xA3, RawFrm, (outs offset64:$dst), (ins),
1222 def MOV64ao64 : RIi64<0xA3, RawFrmMemOffs, (outs offset64:$dst), (ins),
12191223 "movabs{q}\t{%rax, $dst|$dst, rax}", []>,
12201224 Requires<[In64BitMode]>;
12211225 }
695695
696696 # CHECK: vmovq %xmm0, %xmm0
697697 0xc5 0xfa 0x7e 0xc0
698
699 # CHECK: movl %fs:0, %eax
700 0x64 0xa1 0x00 0x00 0x00 0x00
329329 // CHECK: encoding: [0x9b]
330330 fwait
331331
332 // CHECK: [0x65,0x66,0x8b,0x06,0x7c,0x00]
333 // FIXME: This is a correct bug poor encoding: Use 65 66 a1 7c 00
332 // CHECK: [0x66,0x65,0xa1,0x7c,0x00]
334333 movl %gs:124, %eax
335334
336335 // CHECK: pusha
437437 fwait
438438
439439 // rdar://7873482
440 // CHECK: [0x65,0x8b,0x05,0x7c,0x00,0x00,0x00]
441 // FIXME: This is a correct bug poor encoding: Use 65 a1 7c 00 00 00
440 // CHECK: [0x65,0xa1,0x7c,0x00,0x00,0x00]
442441 movl %gs:124, %eax
442
443 // CHECK: [0x65,0xa3,0x7c,0x00,0x00,0x00]
444 movl %eax, %gs:124
443445
444446 // CHECK: pushal
445447 // CHECK: encoding: [0x60]
5858 MRMDestMem = 4,
5959 MRMSrcReg = 5,
6060 MRMSrcMem = 6,
61 RawFrmMemOffs = 7,
6162 MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
6263 MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
6364 MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
6465 MRM4m = 28, MRM5m = 29, MRM6m = 30, MRM7m = 31,
65 MRMInitReg = 32,
6666 RawFrmImm8 = 43,
6767 RawFrmImm16 = 44,
6868 #define MAP(from, to) MRM_##from = to,
630630 unsigned physicalOperandIndex = 0;
631631
632632 switch (Form) {
633 default: llvm_unreachable("Unhandled form");
633634 case X86Local::RawFrm:
634635 // Operand 1 (optional) is an address or immediate.
635636 // Operand 2 (optional) is an immediate.
637638 "Unexpected number of operands for RawFrm");
638639 HANDLE_OPTIONAL(relocation)
639640 HANDLE_OPTIONAL(immediate)
641 break;
642 case X86Local::RawFrmMemOffs:
643 // Operand 1 is an address.
644 HANDLE_OPERAND(relocation);
640645 break;
641646 case X86Local::AddRegFrm:
642647 // Operand 1 is added to the opcode.
839844 HANDLE_OPERAND(relocation)
840845 }
841846 break;
842 case X86Local::MRMInitReg:
847 case X86Local::MRM_C1:
848 case X86Local::MRM_C2:
849 case X86Local::MRM_C3:
850 case X86Local::MRM_C4:
851 case X86Local::MRM_C8:
852 case X86Local::MRM_C9:
853 case X86Local::MRM_CA:
854 case X86Local::MRM_CB:
855 case X86Local::MRM_E8:
856 case X86Local::MRM_F0:
857 case X86Local::MRM_F9:
858 case X86Local::MRM_D0:
859 case X86Local::MRM_D1:
860 case X86Local::MRM_D4:
861 case X86Local::MRM_D5:
862 case X86Local::MRM_D6:
863 case X86Local::MRM_D8:
864 case X86Local::MRM_D9:
865 case X86Local::MRM_DA:
866 case X86Local::MRM_DB:
867 case X86Local::MRM_DC:
868 case X86Local::MRM_DD:
869 case X86Local::MRM_DE:
870 case X86Local::MRM_DF:
843871 // Ignored.
844872 break;
845873 }