llvm.org GIT mirror llvm / 656d5d5
[X86] Don't ignore 0x66 prefix on relative jumps in 64-bit mode. Fix opcode selection of relative jumps in 16-bit mode. Treat jno/jo like other jcc instructions. The behavior in 64-bit mode is different between Intel and AMD CPUs. Intel ignores the 0x66 prefix. AMD does not. objump doesn't ignore the 0x66 prefix. Since LLVM aims to match objdump behavior, we should do the same. While I was trying to fix this I had change brtarget16/32 to use ENCODING_IW/ID instead of ENCODING_Iv to get the 0x66+REX.W case to act sort of sanely. It's still wrong, but that's a problem for another day. The change in encoding exposed the fact that 16-bit mode disassembly of relative jumps was creating JMP_4 with a 2 byte immediate. It should have been JMP_2. From just printing you can't tell the difference, but if you dumped the encoding it wouldn't have matched what we started with. While fixing that, it exposed that jo/jno opcodes were missing from the switch that this patch deleted and there were no test cases for them. Fixes PR38537. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339622 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 1 year, 11 months ago
3 changed file(s) with 64 addition(s) and 79 deletion(s). Raw diff Collapse all Expand all
982982 insn->opcode == 0xE3)
983983 attrMask ^= ATTR_ADSIZE;
984984
985 /*
986 * In 64-bit mode all f64 superscripted opcodes ignore opcode size prefix
987 * CALL/JMP/JCC instructions need to ignore 0x66 and consume 4 bytes
988 */
989
990 if ((insn->mode == MODE_64BIT) && insn->hasOpSize) {
991 switch (insn->opcode) {
992 case 0xE8:
993 case 0xE9:
994 // Take care of psubsb and other mmx instructions.
995 if (insn->opcodeType == ONEBYTE) {
996 attrMask ^= ATTR_OPSIZE;
997 insn->immediateSize = 4;
998 insn->displacementSize = 4;
999 }
1000 break;
1001 case 0x82:
1002 case 0x83:
1003 case 0x84:
1004 case 0x85:
1005 case 0x86:
1006 case 0x87:
1007 case 0x88:
1008 case 0x89:
1009 case 0x8A:
1010 case 0x8B:
1011 case 0x8C:
1012 case 0x8D:
1013 case 0x8E:
1014 case 0x8F:
1015 // Take care of lea and three byte ops.
1016 if (insn->opcodeType == TWOBYTE) {
1017 attrMask ^= ATTR_OPSIZE;
1018 insn->immediateSize = 4;
1019 insn->displacementSize = 4;
1020 }
1021 break;
1022 }
1023 }
985 // If we're in 16-bit mode and this is one of the relative jumps and opsize
986 // prefix isn't present, we need to force the opsize attribute since the
987 // prefix is inverted relative to 32-bit mode.
988 if (insn->mode == MODE_16BIT && !insn->hasOpSize &&
989 insn->opcodeType == ONEBYTE &&
990 (insn->opcode == 0xE8 || insn->opcode == 0xE9))
991 attrMask |= ATTR_OPSIZE;
992
993 if (insn->mode == MODE_16BIT && !insn->hasOpSize &&
994 insn->opcodeType == TWOBYTE &&
995 insn->opcode >= 0x80 && insn->opcode <= 0x8F)
996 attrMask |= ATTR_OPSIZE;
1024997
1025998 if (getIDWithAttrMask(&instructionID, insn, attrMask))
1026999 return -1;
325325 # CHECK: movq %rax, 1515870810
326326 0x67, 0x48 0xa3 0x5a 0x5a 0x5a 0x5a
327327
328 # CHECK: callq -32769
329 0x66 0xe8 0xff 0x7f 0xff 0xff
330
331 # CHECK: callq -32769
332 0x66 0x66 0x48 0xe8 0xff 0x7f 0xff 0xff
328 # CHECK: callw 32767
329 0x66 0xe8 0xff 0x7f
330
331 # CHECK: callw 32767
332 0x66 0x66 0x48 0xe8 0xff 0x7f
333333
334334 # CHECK: jmp -32769
335335 0xe9 0xff 0x7f 0xff 0xff
336336
337 # CHECK: jmp -32769
338 0x66 0xe9 0xff 0x7f 0xff 0xff
339
340 # CHECK: jmp -32769
341 0x66 0x66 0x48 0xe9 0xff 0x7f 0xff 0xff
337 # CHECK: jmp 32767
338 0x66 0xe9 0xff 0x7f
339
340 # CHECK: jmp 32767
341 0x66 0x66 0x48 0xe9 0xff 0x7f
342
343 # CHECK: jo -32769
344 0x0f 0x80 0xff 0x7f 0xff 0xff
345
346 # CHECK: jo 32767
347 0x66 0x0f 0x80 0xff 0x7f
348
349 # CHECK: jno -32769
350 0x0f 0x81 0xff 0x7f 0xff 0xff
351
352 # CHECK: jno 32767
353 0x66 0x0f 0x81 0xff 0x7f
342354
343355 # CHECK: jb -32769
344356 0x0f 0x82 0xff 0x7f 0xff 0xff
345357
346 # CHECK: jb -32769
347 0x66 0x0f 0x82 0xff 0x7f 0xff 0xff
358 # CHECK: jb 32767
359 0x66 0x0f 0x82 0xff 0x7f
348360
349361 # CHECK: jae -32769
350362 0x0f 0x83 0xff 0x7f 0xff 0xff
351363
352 # CHECK: jae -32769
353 0x66 0x0f 0x83 0xff 0x7f 0xff 0xff
364 # CHECK: jae 32767
365 0x66 0x0f 0x83 0xff 0x7f
354366
355367 # CHECK: je -32769
356368 0x0f 0x84 0xff 0x7f 0xff 0xff
357369
358 # CHECK: je -32769
359 0x66 0x0f 0x84 0xff 0x7f 0xff 0xff
370 # CHECK: je 32767
371 0x66 0x0f 0x84 0xff 0x7f
360372
361373 # CHECK: jne -32769
362374 0x0f 0x85 0xff 0x7f 0xff 0xff
363375
364 # CHECK: jne -32769
365 0x66 0x0f 0x85 0xff 0x7f 0xff 0xff
376 # CHECK: jne 32767
377 0x66 0x0f 0x85 0xff 0x7f
366378
367379 # CHECK: jbe -32769
368380 0x0f 0x86 0xff 0x7f 0xff 0xff
369381
370 # CHECK: jbe -32769
371 0x66 0x0f 0x86 0xff 0x7f 0xff 0xff
382 # CHECK: jbe 32767
383 0x66 0x0f 0x86 0xff 0x7f
372384
373385 # CHECK: ja -32769
374386 0x0f 0x87 0xff 0x7f 0xff 0xff
375387
376 # CHECK: ja -32769
377 0x66 0x0f 0x87 0xff 0x7f 0xff 0xff
388 # CHECK: ja 32767
389 0x66 0x0f 0x87 0xff 0x7f
378390
379391 # CHECK: js -32769
380392 0x0f 0x88 0xff 0x7f 0xff 0xff
381393
382 # CHECK: js -32769
383 0x66 0x0f 0x88 0xff 0x7f 0xff 0xff
394 # CHECK: js 32767
395 0x66 0x0f 0x88 0xff 0x7f
384396
385397 # CHECK: jns -32769
386398 0x0f 0x89 0xff 0x7f 0xff 0xff
387399
388 # CHECK: jns -32769
389 0x66 0x0f 0x89 0xff 0x7f 0xff 0xff
400 # CHECK: jns 32767
401 0x66 0x0f 0x89 0xff 0x7f
390402
391403 # CHECK: jp -32769
392404 0x0f 0x8a 0xff 0x7f 0xff 0xff
393405
394 # CHECK: jp -32769
395 0x66 0x0f 0x8a 0xff 0x7f 0xff 0xff
406 # CHECK: jp 32767
407 0x66 0x0f 0x8a 0xff 0x7f
396408
397409 # CHECK: jnp -32769
398410 0x0f 0x8b 0xff 0x7f 0xff 0xff
399411
400 # CHECK: jnp -32769
401 0x66 0x0f 0x8b 0xff 0x7f 0xff 0xff
412 # CHECK: jnp 32767
413 0x66 0x0f 0x8b 0xff 0x7f
402414
403415 # CHECK: jl -32769
404416 0x0f 0x8c 0xff 0x7f 0xff 0xff
405417
406 # CHECK: jl -32769
407 0x66 0x0f 0x8c 0xff 0x7f 0xff 0xff
418 # CHECK: jl 32767
419 0x66 0x0f 0x8c 0xff 0x7f
408420
409421 # CHECK: jge -32769
410422 0x0f 0x8d 0xff 0x7f 0xff 0xff
411423
412 # CHECK: jge -32769
413 0x66 0x0f 0x8d 0xff 0x7f 0xff 0xff
424 # CHECK: jge 32767
425 0x66 0x0f 0x8d 0xff 0x7f
414426
415427 # CHECK: jle -32769
416428 0x0f 0x8e 0xff 0x7f 0xff 0xff
417429
418 # CHECK: jle -32769
419 0x66 0x0f 0x8e 0xff 0x7f 0xff 0xff
430 # CHECK: jle 32767
431 0x66 0x0f 0x8e 0xff 0x7f
420432
421433 # CHECK: jg -32769
422434 0x0f 0x8f 0xff 0x7f 0xff 0xff
423435
424 # CHECK: jg -32769
425 0x66 0x0f 0x8f 0xff 0x7f 0xff 0xff
436 # CHECK: jg 32767
437 0x66 0x0f 0x8f 0xff 0x7f
426438
427439 # CHECK: lcallw *-32769(%rip)
428440 0x66 0xff 0x1d 0xff 0x7f 0xff 0xff
11311131 ENCODING("i64i32imm_pcrel", ENCODING_ID)
11321132 ENCODING("i16imm_pcrel", ENCODING_IW)
11331133 ENCODING("i32imm_pcrel", ENCODING_ID)
1134 ENCODING("brtarget32", ENCODING_Iv)
1135 ENCODING("brtarget16", ENCODING_Iv)
1134 ENCODING("brtarget32", ENCODING_ID)
1135 ENCODING("brtarget16", ENCODING_IW)
11361136 ENCODING("brtarget8", ENCODING_IB)
11371137 ENCODING("i64imm", ENCODING_IO)
11381138 ENCODING("offset16_8", ENCODING_Ia)