llvm.org GIT mirror llvm / a4959f3
First round of fixes for the x86 fixes for the x86 move accumulator from/to memory offset instructions. -Assembly parser now properly check the size of the memory operation specified in intel syntax. So 'mov word ptr [5], al' is no longer accepted. -x86-32 disassembly of these instructions no longer sign extends the 32-bit address immediate based on size. -Intel syntax printing prints the ptr size and places brackets around the address immediate. Known remaining issues with these instructions: -Segment override prefix is not supported. PR16962 and PR16961. -Immediate size should be changed by address size prefix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189201 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 6 years ago
10 changed file(s) with 226 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
848848 !getMemIndexReg() && getMemScale() == 1;
849849 }
850850
851 bool isMemOffs8() const {
852 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
853 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 8);
854 }
855 bool isMemOffs16() const {
856 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
857 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 16);
858 }
859 bool isMemOffs32() const {
860 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
861 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 32);
862 }
863 bool isMemOffs64() const {
864 return Kind == Memory && !getMemSegReg() && !getMemBaseReg() &&
865 !getMemIndexReg() && getMemScale() == 1 && (!Mem.Size || Mem.Size == 64);
866 }
867
851868 bool isReg() const { return Kind == Register; }
852869
853870 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
922939 }
923940
924941 void addAbsMemOperands(MCInst &Inst, unsigned N) const {
942 assert((N == 1) && "Invalid number of operands!");
943 // Add as immediates when possible.
944 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
945 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
946 else
947 Inst.addOperand(MCOperand::CreateExpr(getMemDisp()));
948 }
949
950 void addMemOffs8Operands(MCInst &Inst, unsigned N) const {
951 addMemOffsOperands(Inst, N);
952 }
953 void addMemOffs16Operands(MCInst &Inst, unsigned N) const {
954 addMemOffsOperands(Inst, N);
955 }
956 void addMemOffs32Operands(MCInst &Inst, unsigned N) const {
957 addMemOffsOperands(Inst, N);
958 }
959 void addMemOffs64Operands(MCInst &Inst, unsigned N) const {
960 addMemOffsOperands(Inst, N);
961 }
962
963 void addMemOffsOperands(MCInst &Inst, unsigned N) const {
925964 assert((N == 1) && "Invalid number of operands!");
926965 // Add as immediates when possible.
927966 if (const MCConstantExpr *CE = dyn_cast(getMemDisp()))
230230 default:
231231 break;
232232 case 1:
233 type = TYPE_MOFFS8;
233 if(immediate & 0x80)
234 immediate |= ~(0xffull);
234235 break;
235236 case 2:
236 type = TYPE_MOFFS16;
237 if(immediate & 0x8000)
238 immediate |= ~(0xffffull);
237239 break;
238240 case 4:
239 type = TYPE_MOFFS32;
241 if(immediate & 0x80000000)
242 immediate |= ~(0xffffffffull);
240243 break;
241244 case 8:
242 type = TYPE_MOFFS64;
243245 break;
244246 }
245247 }
262264 Opcode != X86::VMPSADBWrri && Opcode != X86::VDPPSYrri &&
263265 Opcode != X86::VDPPSYrmi && Opcode != X86::VDPPDrri &&
264266 Opcode != X86::VINSERTPSrr)
265 type = TYPE_MOFFS8;
267 if(immediate & 0x80)
268 immediate |= ~(0xffull);
266269 break;
267270 case ENCODING_IW:
268 type = TYPE_MOFFS16;
271 if(immediate & 0x8000)
272 immediate |= ~(0xffffull);
269273 break;
270274 case ENCODING_ID:
271 type = TYPE_MOFFS32;
275 if(immediate & 0x80000000)
276 immediate |= ~(0xffffffffull);
272277 break;
273278 case ENCODING_IO:
274 type = TYPE_MOFFS64;
275279 break;
276280 }
277281 }
291295 case TYPE_REL8:
292296 isBranch = true;
293297 pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize;
294 // fall through to sign extend the immediate if needed.
295 case TYPE_MOFFS8:
296298 if(immediate & 0x80)
297299 immediate |= ~(0xffull);
298 break;
299 case TYPE_MOFFS16:
300 if(immediate & 0x8000)
301 immediate |= ~(0xffffull);
302300 break;
303301 case TYPE_REL32:
304302 case TYPE_REL64:
305303 isBranch = true;
306304 pcrel = insn.startLocation + insn.immediateOffset + insn.immediateSize;
307 // fall through to sign extend the immediate if needed.
308 case TYPE_MOFFS32:
309305 if(immediate & 0x80000000)
310306 immediate |= ~(0xffffffffull);
311307 break;
312 case TYPE_MOFFS64:
313308 default:
314309 // operand is 64 bits wide. Do nothing.
315310 break;
214214
215215 O << markup(">");
216216 }
217
218 void X86ATTInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
219 raw_ostream &O) {
220 const MCOperand &DispSpec = MI->getOperand(Op);
221
222 O << markup("
223
224 if (DispSpec.isImm()) {
225 O << formatImm(DispSpec.getImm());
226 } else {
227 assert(DispSpec.isExpr() && "non-immediate displacement?");
228 O << *DispSpec.getExpr();
229 }
230
231 O << markup(">");
232 }
4141 void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &OS);
4242 void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &OS);
4343 void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
44
44 void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &OS);
45
4546 void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
4647 printMemReference(MI, OpNo, O);
4748 }
8586 void printf512mem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
8687 printMemReference(MI, OpNo, O);
8788 }
89
90 void printMemOffs8(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
91 printMemOffset(MI, OpNo, O);
92 }
93 void printMemOffs16(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
94 printMemOffset(MI, OpNo, O);
95 }
96 void printMemOffs32(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
97 printMemOffset(MI, OpNo, O);
98 }
99 void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
100 printMemOffset(MI, OpNo, O);
101 }
88102 };
89103
90104 }
199199
200200 O << ']';
201201 }
202
203 void X86IntelInstPrinter::printMemOffset(const MCInst *MI, unsigned Op,
204 raw_ostream &O) {
205 const MCOperand &DispSpec = MI->getOperand(Op);
206
207 O << '[';
208
209 if (DispSpec.isImm()) {
210 O << formatImm(DispSpec.getImm());
211 } else {
212 assert(DispSpec.isExpr() && "non-immediate displacement?");
213 O << *DispSpec.getExpr();
214 }
215
216 O << ']';
217 }
3838 void printSSECC(const MCInst *MI, unsigned Op, raw_ostream &O);
3939 void printAVXCC(const MCInst *MI, unsigned Op, raw_ostream &O);
4040 void printPCRelImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
41
41 void printMemOffset(const MCInst *MI, unsigned OpNo, raw_ostream &O);
42
4243 void printopaquemem(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
4344 O << "opaque ptr ";
4445 printMemReference(MI, OpNo, O);
9697 O << "zmmword ptr ";
9798 printMemReference(MI, OpNo, O);
9899 }
100
101 void printMemOffs8(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
102 O << "byte ptr ";
103 printMemOffset(MI, OpNo, O);
104 }
105 void printMemOffs16(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
106 O << "word ptr ";
107 printMemOffset(MI, OpNo, O);
108 }
109 void printMemOffs32(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
110 O << "dword ptr ";
111 printMemOffset(MI, OpNo, O);
112 }
113 void printMemOffs64(const MCInst *MI, unsigned OpNo, raw_ostream &O) {
114 O << "qword ptr ";
115 printMemOffset(MI, OpNo, O);
116 }
99117 };
100118
101119 }
438438 def i32imm_pcrel : Operand;
439439 def i16imm_pcrel : Operand;
440440
441 def offset8 : Operand;
442 def offset16 : Operand;
443 def offset32 : Operand;
444 def offset64 : Operand;
445
446441 // Branch targets have OtherVT type and print as pc-relative values.
447442 def brtarget : Operand;
448443 def brtarget8 : Operand;
449444
450445 }
446
447 def X86MemOffs8AsmOperand : AsmOperandClass {
448 let Name = "MemOffs8";
449 let SuperClasses = [X86Mem8AsmOperand];
450 }
451 def X86MemOffs16AsmOperand : AsmOperandClass {
452 let Name = "MemOffs16";
453 let SuperClasses = [X86Mem16AsmOperand];
454 }
455 def X86MemOffs32AsmOperand : AsmOperandClass {
456 let Name = "MemOffs32";
457 let SuperClasses = [X86Mem32AsmOperand];
458 }
459 def X86MemOffs64AsmOperand : AsmOperandClass {
460 let Name = "MemOffs64";
461 let SuperClasses = [X86Mem64AsmOperand];
462 }
463
464 let OperandType = "OPERAND_MEMORY" in {
465 def offset8 : Operand {
466 let ParserMatchClass = X86MemOffs8AsmOperand;
467 let PrintMethod = "printMemOffs8"; }
468 def offset16 : Operand {
469 let ParserMatchClass = X86MemOffs16AsmOperand;
470 let PrintMethod = "printMemOffs16"; }
471 def offset32 : Operand {
472 let ParserMatchClass = X86MemOffs32AsmOperand;
473 let PrintMethod = "printMemOffs32"; }
474 def offset64 : Operand {
475 let ParserMatchClass = X86MemOffs64AsmOperand;
476 let PrintMethod = "printMemOffs64"; }
477 }
478
451479
452480 def SSECC : Operand {
453481 let PrintMethod = "printSSECC";
11031131 // These forms all have full 64-bit absolute addresses in their instructions
11041132 // and use the movabs mnemonic to indicate this specific form.
11051133 let mayLoad = 1 in {
1106 def MOV64o8a : RIi64_NOREX<0xA0, RawFrm, (outs), (ins offset64:$src),
1134 def MOV64o8a : RIi64_NOREX<0xA0, RawFrm, (outs), (ins offset8:$src),
11071135 "movabs{b}\t{$src, %al|al, $src}", []>,
11081136 Requires<[In64BitMode]>;
1109 def MOV64o16a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset64:$src),
1137 def MOV64o16a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset16:$src),
11101138 "movabs{w}\t{$src, %ax|ax, $src}", []>, OpSize,
11111139 Requires<[In64BitMode]>;
1112 def MOV64o32a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset64:$src),
1140 def MOV64o32a : RIi64_NOREX<0xA1, RawFrm, (outs), (ins offset32:$src),
11131141 "movabs{l}\t{$src, %eax|eax, $src}", []>,
11141142 Requires<[In64BitMode]>;
11151143 def MOV64o64a : RIi64<0xA1, RawFrm, (outs), (ins offset64:$src),
11181146 }
11191147
11201148 let mayStore = 1 in {
1121 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrm, (outs offset64:$dst), (ins),
1149 def MOV64ao8 : RIi64_NOREX<0xA2, RawFrm, (outs offset8:$dst), (ins),
11221150 "movabs{b}\t{%al, $dst|$dst, al}", []>,
11231151 Requires<[In64BitMode]>;
1124 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrm, (outs offset64:$dst), (ins),
1152 def MOV64ao16 : RIi64_NOREX<0xA3, RawFrm, (outs offset16:$dst), (ins),
11251153 "movabs{w}\t{%ax, $dst|$dst, ax}", []>, OpSize,
11261154 Requires<[In64BitMode]>;
1127 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrm, (outs offset64:$dst), (ins),
1155 def MOV64ao32 : RIi64_NOREX<0xA3, RawFrm, (outs offset32:$dst), (ins),
11281156 "movabs{l}\t{%eax, $dst|$dst, eax}", []>,
11291157 Requires<[In64BitMode]>;
11301158 def MOV64ao64 : RIi64<0xA3, RawFrm, (outs offset64:$dst), (ins),
0 # RUN: llvm-mc --disassemble %s -triple=i386 --output-asm-variant=1 | FileCheck %s
11
2 # CHECK: sgdt
2 # CHECK: sgdt opaque ptr [eax]
33 0x0f 0x01 0x00
44
5 # CHECK: sidt
5 # CHECK: sidt opaque ptr [eax]
66 0x0f 0x01 0x08
77
8 # CHECK: lgdt
8 # CHECK: lgdt opaque ptr [eax]
99 0x0f 0x01 0x10
1010
11 # CHECK: lidt
11 # CHECK: lidt opaque ptr [eax]
1212 0x0f 0x01 0x18
13
14 # CHECK: mov al, byte ptr [878082192]
15 0xa0 0x90 0x78 0x56 0x34
16
17 # CHECK: mov ax, word ptr [878082192]
18 0x66 0xa1 0x90 0x78 0x56 0x34
19
20 # CHECK: mov eax, dword ptr [878082192]
21 0xa1 0x90 0x78 0x56 0x34
22
23 # CHECK: mov byte ptr [878082192], al
24 0xa2 0x90 0x78 0x56 0x34
25
26 # CHECK: mov word ptr [878082192], ax
27 0x66 0xa3 0x90 0x78 0x56 0x34
28
29 # CHECK: mov dword ptr [878082192], eax
30 0xa3 0x90 0x78 0x56 0x34
118118
119119 # CHECK: xsaveopt64 opaque ptr [rax]
120120 0x48 0x0f 0xae 0x30
121
122 # CHECK: movabs al, byte ptr [-6066930261531658096]
123 0xa0 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
124
125 # CHECK: movabs al, byte ptr [-6066930261531658096]
126 0x48 0xa0 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
127
128 # CHECK: movabs ax, word ptr [-6066930261531658096]
129 0x66 0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
130
131 # CHECK: movabs eax, dword ptr [-6066930261531658096]
132 0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
133
134 # CHECK: movabs rax, qword ptr [-6066930261531658096]
135 0x48 0xa1 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
136
137 # CHECK: movabs byte ptr [-6066930261531658096], al
138 0xa2 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
139
140 # CHECK: movabs byte ptr [-6066930261531658096], al
141 0x48 0xa2 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
142
143 # CHECK: movabs word ptr [-6066930261531658096], ax
144 0x66 0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
145
146 # CHECK: movabs dword ptr [-6066930261531658096], eax
147 0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
148
149 # CHECK: movabs qword ptr [-6066930261531658096], rax
150 0x48 0xa3 0x90 0x78 0x56 0x34 0x12 0xef 0xcd 0xab
647647
648648 # CHECK: adoxl (%eax), %eax
649649 0xf3 0x0f 0x38 0xf6 0x00
650
651 # CHECK: movb 878082192, %al
652 0xa0 0x90 0x78 0x56 0x34
653
654 # CHECK: movw 878082192, %ax
655 0x66 0xa1 0x90 0x78 0x56 0x34
656
657 # CHECK: movl 878082192, %eax
658 0xa1 0x90 0x78 0x56 0x34
659
660 # CHECK: movb %al, 878082192
661 0xa2 0x90 0x78 0x56 0x34
662
663 # CHECK: movw %ax, 878082192
664 0x66 0xa3 0x90 0x78 0x56 0x34
665
666 # CHECK: movl %eax, 878082192
667 0xa3 0x90 0x78 0x56 0x34