From: H.J. Lu Date: Wed, 10 Sep 2014 16:38:31 +0000 (-0700) Subject: Properly handle suffix for iret and sysret X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4b4c407a349620e4a6b9cb36b77778fccb7ff00f;p=binutils-gdb.git Properly handle suffix for iret and sysret gas/testsuite/ * gas/i386/i386.exp: Run suffix-intel, x86-64-suffix and x86-64-suffix-intel. * gas/i386/suffix.s: Add tests for iret and sysret. * gas/i386/suffix.d: Updated. * gas/i386/suffix-intel.d: New file. * gas/i386/x86-64-suffix-intel.d: Likewise. * gas/i386/x86-64-suffix.d: Likewise. * gas/i386/x86-64-suffix.s: Likewise. opcodes/ * i386-dis.c (dis386): Replace "P" with "%LP" for iret and sysret. (putop): Handle "%LP". --- diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d705f8a0838..f67448b5a25 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2014-09-10 H.J. Lu + + * gas/i386/i386.exp: Run suffix-intel, x86-64-suffix and + x86-64-suffix-intel. + + * gas/i386/suffix.s: Add tests for iret and sysret. + * gas/i386/suffix.d: Updated. + + * gas/i386/suffix-intel.d: New file. + * gas/i386/x86-64-suffix-intel.d: Likewise. + * gas/i386/x86-64-suffix.d: Likewise. + * gas/i386/x86-64-suffix.s: Likewise. + 2014-09-10 Alan Modra * gas/arm/got_prel.d: Adjust for changed section header placement. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 680d28cf4f6..444642628f8 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -73,6 +73,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "vmfunc" run_dump_test "smx" run_dump_test "suffix" + run_dump_test "suffix-intel" run_dump_test "immed32" run_dump_test "equ" run_dump_test "divide" @@ -627,6 +628,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-avx512dq" run_dump_test "x86-64-avx512dq_vl-intel" run_dump_test "x86-64-avx512dq_vl" + run_dump_test "x86-64-suffix" + run_dump_test "x86-64-suffix-intel" if { ![istarget "*-*-aix*"] && ![istarget "*-*-beos*"] diff --git a/gas/testsuite/gas/i386/suffix-intel.d b/gas/testsuite/gas/i386/suffix-intel.d new file mode 100644 index 00000000000..b20d927a70c --- /dev/null +++ b/gas/testsuite/gas/i386/suffix-intel.d @@ -0,0 +1,26 @@ +#source: suffix.s +#objdump: -dw -Msuffix,intel +#name: i386 suffix (Intel mode) + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: 0f 01 c8 monitor +[ ]*[a-f0-9]+: 0f 01 c9 mwait +[ ]*[a-f0-9]+: 0f 01 c1 vmcall +[ ]*[a-f0-9]+: 0f 01 c2 vmlaunch +[ ]*[a-f0-9]+: 0f 01 c3 vmresume +[ ]*[a-f0-9]+: 0f 01 c4 vmxoff +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 0f 07 sysretd +#pass diff --git a/gas/testsuite/gas/i386/suffix.d b/gas/testsuite/gas/i386/suffix.d index fa57bb7e265..44be5ed7f71 100644 --- a/gas/testsuite/gas/i386/suffix.d +++ b/gas/testsuite/gas/i386/suffix.d @@ -5,11 +5,21 @@ Disassembly of section .text: -0+000 : - 0: 0f 01 c8 [ ]*monitor %eax,%ecx,%edx - 3: 0f 01 c9 [ ]*mwait %eax,%ecx - 6: 0f 01 c1 [ ]*vmcall - 9: 0f 01 c2 [ ]*vmlaunch - c: 0f 01 c3 [ ]*vmresume - f: 0f 01 c4 [ ]*vmxoff - ... +0+ : +[ ]*[a-f0-9]+: 0f 01 c8 monitor %eax,%ecx,%edx +[ ]*[a-f0-9]+: 0f 01 c9 mwait %eax,%ecx +[ ]*[a-f0-9]+: 0f 01 c1 vmcall +[ ]*[a-f0-9]+: 0f 01 c2 vmlaunch +[ ]*[a-f0-9]+: 0f 01 c3 vmresume +[ ]*[a-f0-9]+: 0f 01 c4 vmxoff +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 0f 07 sysretl +#pass diff --git a/gas/testsuite/gas/i386/suffix.s b/gas/testsuite/gas/i386/suffix.s index 2ce1c3dcd80..7f2864d8ed4 100644 --- a/gas/testsuite/gas/i386/suffix.s +++ b/gas/testsuite/gas/i386/suffix.s @@ -10,4 +10,15 @@ foo: vmresume vmxoff - .p2align 4,0 + iretw + iretl + iret + sysretl + sysret + + .intel_syntax noprefix + iretw + iretd + iret + sysretd + sysret diff --git a/gas/testsuite/gas/i386/x86-64-suffix-intel.d b/gas/testsuite/gas/i386/x86-64-suffix-intel.d new file mode 100644 index 00000000000..32fcb19f46c --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-suffix-intel.d @@ -0,0 +1,30 @@ +#source: x86-64-suffix.s +#objdump: -dw -Msuffix,intel +#name: x86-64 suffix (Intel mode) + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: 0f 01 c8 monitor +[ ]*[a-f0-9]+: 0f 01 c9 mwait +[ ]*[a-f0-9]+: 0f 01 c1 vmcall +[ ]*[a-f0-9]+: 0f 01 c2 vmlaunch +[ ]*[a-f0-9]+: 0f 01 c3 vmresume +[ ]*[a-f0-9]+: 0f 01 c4 vmxoff +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: 48 cf iretq +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 48 0f 07 sysretq +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: cf iretd +[ ]*[a-f0-9]+: 48 cf iretq +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 0f 07 sysretd +[ ]*[a-f0-9]+: 48 0f 07 sysretq +#pass diff --git a/gas/testsuite/gas/i386/x86-64-suffix.d b/gas/testsuite/gas/i386/x86-64-suffix.d new file mode 100644 index 00000000000..f0b645cfe75 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-suffix.d @@ -0,0 +1,29 @@ +#objdump: -dwMsuffix +#name: x86-64 rep prefix (with suffixes) + +.*: +file format .* + +Disassembly of section .text: + +0+ : +[ ]*[a-f0-9]+: 0f 01 c8 monitor %rax,%rcx,%rdx +[ ]*[a-f0-9]+: 0f 01 c9 mwait %rax,%rcx +[ ]*[a-f0-9]+: 0f 01 c1 vmcall +[ ]*[a-f0-9]+: 0f 01 c2 vmlaunch +[ ]*[a-f0-9]+: 0f 01 c3 vmresume +[ ]*[a-f0-9]+: 0f 01 c4 vmxoff +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: 48 cf iretq +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 48 0f 07 sysretq +[ ]*[a-f0-9]+: 66 cf iretw +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: cf iretl +[ ]*[a-f0-9]+: 48 cf iretq +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 0f 07 sysretl +[ ]*[a-f0-9]+: 48 0f 07 sysretq +#pass diff --git a/gas/testsuite/gas/i386/x86-64-suffix.s b/gas/testsuite/gas/i386/x86-64-suffix.s new file mode 100644 index 00000000000..d5838217146 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-suffix.s @@ -0,0 +1,28 @@ +# Disassembling with -Msuffix. + + .text +foo: + monitor + mwait + + vmcall + vmlaunch + vmresume + vmxoff + + iretw + iretl + iret + iretq + sysretl + sysret + sysretq + + .intel_syntax noprefix + iretw + iretd + iret + iretq + sysretd + sysret + sysretq diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 83118a58200..09fb297f5c5 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,8 @@ +2014-09-10 H.J. Lu + + * i386-dis.c (dis386): Replace "P" with "%LP" for iret and sysret. + (putop): Handle "%LP". + 2014-09-03 Jiong Wang * aarch64-tbl.h (aarch64_opcode_table): Update encoding for mrs/msr. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 34bb61d11ba..79abe09cc4c 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -2397,6 +2397,9 @@ struct dis386 { "LS" => print "abs" in 64bit mode and behave as 'S' otherwise "LV" => print "abs" for 64bit operand and behave as 'S' otherwise "LW" => print 'd', 'q' depending on the VEX.W bit + "LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has + an operand size prefix, or suffix_always is true. print + 'q' if rex prefix is present. Many of the above letters print nothing in Intel mode. See "putop" for the details. @@ -2638,7 +2641,7 @@ static const struct dis386 dis386[] = { { "int3", { XX } }, { "int", { Ib } }, { X86_64_TABLE (X86_64_CE) }, - { "iretP", { XX } }, + { "iret%LP", { XX } }, /* d0 */ { REG_TABLE (REG_D0) }, { REG_TABLE (REG_D1) }, @@ -2704,7 +2707,7 @@ static const struct dis386 dis386_twobyte[] = { { Bad_Opcode }, { "syscall", { XX } }, { "clts", { XX } }, - { "sysretP", { XX } }, + { "sysret%LP", { XX } }, /* 08 */ { "invd", { XX } }, { "wbinvd", { XX } }, @@ -13835,32 +13838,62 @@ case_L: break; } /* Fall through. */ + goto case_P; case 'P': - if (intel_syntax) + if (l == 0 && len == 1) { - if ((rex & REX_W) == 0 - && (prefixes & PREFIX_DATA)) +case_P: + if (intel_syntax) { - if ((sizeflag & DFLAG) == 0) - *obufp++ = 'w'; - used_prefixes |= (prefixes & PREFIX_DATA); + if ((rex & REX_W) == 0 + && (prefixes & PREFIX_DATA)) + { + if ((sizeflag & DFLAG) == 0) + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } + break; + } + if ((prefixes & PREFIX_DATA) + || (rex & REX_W) + || (sizeflag & SUFFIX_ALWAYS)) + { + USED_REX (REX_W); + if (rex & REX_W) + *obufp++ = 'q'; + else + { + if (sizeflag & DFLAG) + *obufp++ = 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } } - break; } - if ((prefixes & PREFIX_DATA) - || (rex & REX_W) - || (sizeflag & SUFFIX_ALWAYS)) + else { - USED_REX (REX_W); - if (rex & REX_W) - *obufp++ = 'q'; - else + if (l != 1 || len != 2 || last[0] != 'L') + { + SAVE_LAST (*p); + break; + } + + if ((prefixes & PREFIX_DATA) + || (rex & REX_W) + || (sizeflag & SUFFIX_ALWAYS)) { - if (sizeflag & DFLAG) - *obufp++ = 'l'; - else - *obufp++ = 'w'; - used_prefixes |= (prefixes & PREFIX_DATA); + USED_REX (REX_W); + if (rex & REX_W) + *obufp++ = 'q'; + else + { + if (sizeflag & DFLAG) + *obufp++ = intel_syntax ? 'd' : 'l'; + else + *obufp++ = 'w'; + used_prefixes |= (prefixes & PREFIX_DATA); + } } } break;