llvm.org GIT mirror llvm / 674140f
]x86] Allow segment and address-size overrides for CMPS[BWLQ] (PR9385) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199806 91177308-0d34-0410-b5e6-96231b3b80d8 David Woodhouse 6 years ago
7 changed file(s) with 110 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
587587 MCStreamer &Out, unsigned &ErrorInfo,
588588 bool MatchingInlineAsm);
589589
590 /// doSrcDstMatch - Returns true if operands are matching in their
591 /// word size (%si and %di, %esi and %edi, etc.). Order depends on
592 /// the parsing mode (Intel vs. AT&T).
593 bool doSrcDstMatch(X86Operand &Op1, X86Operand &Op2);
594
590595 /// isSrcOp - Returns true if operand is either (%rsi) or %ds:%(rsi)
591596 /// in 64bit mode or (%esi) or %es:(%esi) in 32bit mode.
592597 bool isSrcOp(X86Operand &Op);
11481153 };
11491154
11501155 } // end anonymous namespace.
1156
1157 bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
1158 {
1159 // Return true and let a normal complaint about bogus operands happen.
1160 if (!Op1.isMem() || !Op2.isMem())
1161 return true;
1162
1163 // Actually these might be the other way round if Intel syntax is
1164 // being used. It doesn't matter.
1165 unsigned diReg = Op1.Mem.BaseReg;
1166 unsigned siReg = Op2.Mem.BaseReg;
1167
1168 if (X86MCRegisterClasses[X86::GR16RegClassID].contains(siReg))
1169 return X86MCRegisterClasses[X86::GR16RegClassID].contains(diReg);
1170 if (X86MCRegisterClasses[X86::GR32RegClassID].contains(siReg))
1171 return X86MCRegisterClasses[X86::GR32RegClassID].contains(diReg);
1172 if (X86MCRegisterClasses[X86::GR64RegClassID].contains(siReg))
1173 return X86MCRegisterClasses[X86::GR64RegClassID].contains(diReg);
1174 // Again, return true and let another error happen.
1175 return true;
1176 }
11511177
11521178 bool X86AsmParser::isSrcOp(X86Operand &Op) {
11531179 unsigned basereg =
23682394 Name == "scasl" || Name == "scasd" || Name == "scasq"))
23692395 Operands.push_back(DefaultMemDIOperand(NameLoc));
23702396
2397 // Add default SI and DI operands to "cmps[bwlq]".
2398 if (Name.startswith("cmps") &&
2399 (Name == "cmps" || Name == "cmpsb" || Name == "cmpsw" ||
2400 Name == "cmpsl" || Name == "cmpsd" || Name == "cmpsq")) {
2401 if (Operands.size() == 1) {
2402 if (isParsingIntelSyntax()) {
2403 Operands.push_back(DefaultMemSIOperand(NameLoc));
2404 Operands.push_back(DefaultMemDIOperand(NameLoc));
2405 } else {
2406 Operands.push_back(DefaultMemDIOperand(NameLoc));
2407 Operands.push_back(DefaultMemSIOperand(NameLoc));
2408 }
2409 } else if (Operands.size() == 3) {
2410 X86Operand &Op = *(X86Operand*)Operands.begin()[1];
2411 X86Operand &Op2 = *(X86Operand*)Operands.begin()[2];
2412 if (!doSrcDstMatch(Op, Op2))
2413 return Error(Op.getStartLoc(),
2414 "mismatching source and destination index registers");
2415 }
2416 }
2417
23712418 // FIXME: Hack to handle recognize s{hr,ar,hl} $1, . Canonicalize to
23722419 // "shift ".
23732420 if ((Name.startswith("shr") || Name.startswith("sar") ||
265265 /// RawFrmDst - This form is for instructions that use the destination index
266266 /// register DI/EDI/ESI.
267267 RawFrmDst = 9,
268
269 /// RawFrmSrc - This form is for instructions that use the the source index
270 /// register SI/ESI/ERI with a possible segment override, and also the
271 /// destination index register DI/ESI/RDI.
272 RawFrmDstSrc = 10,
268273
269274 /// MRM[0-7][rm] - These forms are used to represent instructions that use
270275 /// a Mod/RM byte, and use the middle field to hold extended opcode
621626 case X86II::RawFrmMemOffs:
622627 case X86II::RawFrmSrc:
623628 case X86II::RawFrmDst:
629 case X86II::RawFrmDstSrc:
624630 return -1;
625631 case X86II::MRMDestMem:
626632 return 0;
13161316 llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!");
13171317 case X86II::Pseudo:
13181318 llvm_unreachable("Pseudo instruction shouldn't be emitted");
1319 case X86II::RawFrmDstSrc: {
1320 unsigned diReg = MI.getOperand(0).getReg();
1321 unsigned siReg = MI.getOperand(1).getReg();
1322 assert(((siReg == X86::SI && diReg == X86::DI) ||
1323 (siReg == X86::ESI && diReg == X86::EDI) ||
1324 (siReg == X86::RSI && diReg == X86::RDI)) &&
1325 "SI and DI register sizes do not match");
1326 // Emit segment override opcode prefix as needed (not for %ds).
1327 if (MI.getOperand(2).getReg() != X86::DS)
1328 EmitSegmentOverridePrefix(CurByte, 2, MI, OS);
1329 // Emit OpSize prefix as needed.
1330 if ((!is32BitMode() && siReg == X86::ESI) ||
1331 (is32BitMode() && siReg == X86::SI))
1332 EmitByte(0x67, CurByte, OS);
1333 CurOp += 3; // Consume operands.
1334 EmitByte(BaseOpcode, CurByte, OS);
1335 break;
1336 }
13191337 case X86II::RawFrmSrc: {
13201338 unsigned siReg = MI.getOperand(0).getReg();
13211339 // Emit segment override opcode prefix as needed (not for %ds).
2222 def MRMDestMem : Format<4>; def MRMSrcReg : Format<5>;
2323 def MRMSrcMem : Format<6>; def RawFrmMemOffs : Format<7>;
2424 def RawFrmSrc : Format<8>; def RawFrmDst : Format<9>;
25 def RawFrmDstSrc: Format<10>;
2526 def MRM0r : Format<16>; def MRM1r : Format<17>; def MRM2r : Format<18>;
2627 def MRM3r : Format<19>; def MRM4r : Format<20>; def MRM5r : Format<21>;
2728 def MRM6r : Format<22>; def MRM7r : Format<23>;
11651165 def SCAS64 : RI<0xAF, RawFrmDst, (outs), (ins dstidx64:$dst),
11661166 "scasq\t{$dst, %rax|rax, $dst}", [], IIC_SCAS>;
11671167
1168 def CMPS8 : I<0xA6, RawFrm, (outs), (ins), "cmpsb", [], IIC_CMPS>;
1169 def CMPS16 : I<0xA7, RawFrm, (outs), (ins), "cmpsw", [], IIC_CMPS>, OpSize;
1170 def CMPS32 : I<0xA7, RawFrm, (outs), (ins), "cmps{l|d}", [], IIC_CMPS>,
1171 OpSize16;
1172 def CMPS64 : RI<0xA7, RawFrm, (outs), (ins), "cmpsq", [], IIC_CMPS>;
1168 def CMPS8 : I<0xA6, RawFrmDstSrc, (outs), (ins dstidx8:$dst, srcidx8:$src),
1169 "cmpsb\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
1170 def CMPS16 : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx16:$dst, srcidx16:$src),
1171 "cmpsw\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize;
1172 def CMPS32 : I<0xA7, RawFrmDstSrc, (outs), (ins dstidx32:$dst, srcidx32:$src),
1173 "cmps{l|d}\t{$dst, $src|$src, $dst}", [], IIC_CMPS>, OpSize16;
1174 def CMPS64 : RI<0xA7, RawFrmDstSrc, (outs), (ins dstidx64:$dst, srcidx64:$src),
1175 "cmpsq\t{$dst, $src|$src, $dst}", [], IIC_CMPS>;
11731176 } // SchedRW
11741177
11751178 //===----------------------------------------------------------------------===//
9393 // ERR64: invalid 16-bit base register
9494 // 16: scasw %es:(%di), %ax # encoding: [0xaf]
9595 // 32: scasw %es:(%di), %ax # encoding: [0x66,0x67,0xaf]
96
97 cmpsb
98 // 64: cmpsb %es:(%rdi), (%rsi) # encoding: [0xa6]
99 // 32: cmpsb %es:(%edi), (%esi) # encoding: [0xa6]
100 // 16: cmpsb %es:(%di), (%si) # encoding: [0xa6]
101
102 cmpsw (%edi), (%esi)
103 // 64: cmpsw %es:(%edi), (%esi) # encoding: [0x66,0x67,0xa7]
104 // 32: cmpsw %es:(%edi), (%esi) # encoding: [0x66,0xa7]
105 // 16: cmpsw %es:(%edi), (%esi) # encoding: [0x67,0xa7]
106
107 cmpsb (%di), (%esi)
108 // ERR64: invalid 16-bit base register
109 // ERR32: mismatching source and destination
110 // ERR16: mismatching source and destination
111
112 cmpsl %es:(%edi), %ss:(%esi)
113 // 64: cmpsl %es:(%edi), %ss:(%esi) # encoding: [0x36,0x67,0xa7]
114 // 32: cmpsl %es:(%edi), %ss:(%esi) # encoding: [0x36,0xa7]
115 // 16: cmpsl %es:(%edi), %ss:(%esi) # encoding: [0x66,0x36,0x67,0xa7]
116
117 cmpsq (%rdi), (%rsi)
118 // 64: cmpsq %es:(%rdi), (%rsi) # encoding: [0x48,0xa7]
119 // ERR32: 64-bit
120 // ERR16: 64-bit
6161 RawFrmMemOffs = 7,
6262 RawFrmSrc = 8,
6363 RawFrmDst = 9,
64 RawFrmDstSrc = 10,
6465 MRM0r = 16, MRM1r = 17, MRM2r = 18, MRM3r = 19,
6566 MRM4r = 20, MRM5r = 21, MRM6r = 22, MRM7r = 23,
6667 MRM0m = 24, MRM1m = 25, MRM2m = 26, MRM3m = 27,
637638 case X86Local::RawFrmDst:
638639 HANDLE_OPERAND(relocation);
639640 return;
641 case X86Local::RawFrmDstSrc:
642 HANDLE_OPERAND(relocation);
643 HANDLE_OPERAND(relocation);
644 return;
640645 case X86Local::RawFrm:
641646 // Operand 1 (optional) is an address or immediate.
642647 // Operand 2 (optional) is an immediate.