From 4cc91dba12d0461b0fd31b02bdb53c1a2ee87088 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 29 Mar 2005 19:30:47 +0000 Subject: [PATCH] gas/testsuite/ 2005-03-29 H.J. Lu * gas/i386/i386.exp: Run segment and inval-seg for i386. Run x86-64-segment and x86-64-inval-seg for x86-64. * gas/i386/intel.d: Expect movw for moving between memory and segment register. * gas/i386/naked.d: Likewise. * gas/i386/opcode.d: Likewise. * gas/i386/x86-64-opcode.d: Likewise. * gas/i386/opcode.s: Use movw for moving between memory and segment register. * gas/i386/x86-64-opcode.s: Likewise. * : Likewise. * gas/i386/inval-seg.l: New. * gas/i386/inval-seg.s: New. * gas/i386/segment.l: New. * gas/i386/segment.s: New. * gas/i386/x86-64-inval-seg.l: New. * gas/i386/x86-64-inval-seg.s: New. * gas/i386/x86-64-segment.l: New. * gas/i386/x86-64-segment.s: New. include/opcode/ 2005-03-29 H.J. Lu * i386.h (i386_optab): Don't allow the `l' suffix for moving moving between memory and segment register. Allow movq for moving between general-purpose register and segment register. opcodes/ 2005-03-29 H.J. Lu * i386-dis.c (SEG_Fixup): New. (Sv): New. (dis386): Use "Sv" for 0x8c and 0x8e. --- gas/testsuite/ChangeLog | 26 +++++++++++ gas/testsuite/gas/i386/i386.exp | 4 ++ gas/testsuite/gas/i386/intel.d | 6 +-- gas/testsuite/gas/i386/inval-seg.l | 10 +++++ gas/testsuite/gas/i386/inval-seg.s | 4 ++ gas/testsuite/gas/i386/naked.d | 4 +- gas/testsuite/gas/i386/opcode.d | 6 +-- gas/testsuite/gas/i386/opcode.s | 4 +- gas/testsuite/gas/i386/segment.l | 10 +++++ gas/testsuite/gas/i386/segment.s | 9 ++++ gas/testsuite/gas/i386/x86-64-inval-seg.l | 14 ++++++ gas/testsuite/gas/i386/x86-64-inval-seg.s | 6 +++ gas/testsuite/gas/i386/x86-64-opcode.d | 27 +++++------ gas/testsuite/gas/i386/x86-64-opcode.s | 26 +++++------ gas/testsuite/gas/i386/x86-64-segment.l | 12 +++++ gas/testsuite/gas/i386/x86-64-segment.s | 12 +++++ include/opcode/ChangeLog | 6 +++ include/opcode/i386.h | 14 ++++-- opcodes/ChangeLog | 6 +++ opcodes/i386-dis.c | 55 ++++++++++++++++++++++- 20 files changed, 212 insertions(+), 49 deletions(-) create mode 100644 gas/testsuite/gas/i386/inval-seg.l create mode 100644 gas/testsuite/gas/i386/inval-seg.s create mode 100644 gas/testsuite/gas/i386/segment.l create mode 100644 gas/testsuite/gas/i386/segment.s create mode 100644 gas/testsuite/gas/i386/x86-64-inval-seg.l create mode 100644 gas/testsuite/gas/i386/x86-64-inval-seg.s create mode 100644 gas/testsuite/gas/i386/x86-64-segment.l create mode 100644 gas/testsuite/gas/i386/x86-64-segment.s diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 5559174aae8..9a03b9dbdb0 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,29 @@ +2005-03-29 H.J. Lu + + * gas/i386/i386.exp: Run segment and inval-seg for i386. Run + x86-64-segment and x86-64-inval-seg for x86-64. + + * gas/i386/intel.d: Expect movw for moving between memory and + segment register. + * gas/i386/naked.d: Likewise. + * gas/i386/opcode.d: Likewise. + * gas/i386/x86-64-opcode.d: Likewise. + + * gas/i386/opcode.s: Use movw for moving between memory and + segment register. + * gas/i386/x86-64-opcode.s: Likewise. + + * : Likewise. + + * gas/i386/inval-seg.l: New. + * gas/i386/inval-seg.s: New. + * gas/i386/segment.l: New. + * gas/i386/segment.s: New. + * gas/i386/x86-64-inval-seg.l: New. + * gas/i386/x86-64-inval-seg.s: New. + * gas/i386/x86-64-segment.l: New. + * gas/i386/x86-64-segment.s: New. + 2005-03-29 Daniel Jacobowitz * gas/arm/tls.s, gas/arm/tls.d: New files. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 1cb1af3b6b3..24ca1a6d711 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -42,6 +42,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_list_test "float" "-al" run_list_test "general" "-al --listing-lhs-width=2" run_list_test "inval" "-al" + run_list_test "segment" "-al" + run_list_test "inval-seg" "-al" run_list_test "modrm" "-al --listing-lhs-width=2" run_dump_test "naked" run_dump_test "opcode" @@ -120,6 +122,8 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "x86-64-opcode" run_dump_test "x86-64-rip" run_list_test "x86-64-inval" "-al" + run_list_test "x86-64-segment" "-al" + run_list_test "x86-64-inval-seg" "-al" # For ELF targets verify that @unwind works. if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"] diff --git a/gas/testsuite/gas/i386/intel.d b/gas/testsuite/gas/i386/intel.d index 3fb927051bc..02b1a0a197f 100644 --- a/gas/testsuite/gas/i386/intel.d +++ b/gas/testsuite/gas/i386/intel.d @@ -138,9 +138,9 @@ Disassembly of section .text: 1a3: 89 90 90 90 90 90 [ ]*mov %edx,0x90909090\(%eax\) 1a9: 8a 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dl 1af: 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%edx - 1b5: 8c 90 90 90 90 90 [ ]*movl %ss,0x90909090\(%eax\) + 1b5: 8c 90 90 90 90 90 [ ]*movw %ss,0x90909090\(%eax\) 1bb: 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%edx - 1c1: 8e 90 90 90 90 90 [ ]*movl 0x90909090\(%eax\),%ss + 1c1: 8e 90 90 90 90 90 [ ]*movw 0x90909090\(%eax\),%ss 1c7: 8f 80 90 90 90 90 [ ]*popl 0x90909090\(%eax\) 1cd: 90 [ ]*nop 1ce: 91 [ ]*xchg %eax,%ecx @@ -481,7 +481,7 @@ Disassembly of section .text: 7be: 66 87 90 90 90 90 90 [ ]*xchg %dx,0x90909090\(%eax\) 7c5: 66 89 90 90 90 90 90 [ ]*mov %dx,0x90909090\(%eax\) 7cc: 66 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dx - 7d3: 8c 90 90 90 90 90 [ ]*mov[l ] %ss,0x90909090\(%eax\) + 7d3: 8c 90 90 90 90 90 [ ]*mov[w ] %ss,0x90909090\(%eax\) 7d9: 66 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%dx 7e0: 66 8f 80 90 90 90 90 [ ]*popw 0x90909090\(%eax\) 7e7: 66 91 [ ]*xchg %ax,%cx diff --git a/gas/testsuite/gas/i386/inval-seg.l b/gas/testsuite/gas/i386/inval-seg.l new file mode 100644 index 00000000000..efe190e9998 --- /dev/null +++ b/gas/testsuite/gas/i386/inval-seg.l @@ -0,0 +1,10 @@ +.*: Assembler messages: +.*:3: Error: .* +.*:4: Error: .* +GAS LISTING .* + + + 1 [ ]* .text + 2 [ ]*# All the following should be illegal + 3 [ ]* movl %ds,\(%eax\) + 4 [ ]* movl \(%eax\),%ds diff --git a/gas/testsuite/gas/i386/inval-seg.s b/gas/testsuite/gas/i386/inval-seg.s new file mode 100644 index 00000000000..4cc222145e8 --- /dev/null +++ b/gas/testsuite/gas/i386/inval-seg.s @@ -0,0 +1,4 @@ + .text +# All the following should be illegal + movl %ds,(%eax) + movl (%eax),%ds diff --git a/gas/testsuite/gas/i386/naked.d b/gas/testsuite/gas/i386/naked.d index 206e3002b15..b516db8c5b2 100644 --- a/gas/testsuite/gas/i386/naked.d +++ b/gas/testsuite/gas/i386/naked.d @@ -11,8 +11,8 @@ Disassembly of section .text: a: b2 20 [ ]*mov \$0x20,%dl c: bb 00 00 00 00 [ ]*mov \$0x0,%ebx d: (R_386_)?(dir)?32 .text 11: d9 c9 [ ]*fxch %st\(1\) - 13: 36 8c a4 81 d2 04 00 00 [ ]*movl %fs,%ss:0x4d2\(%ecx,%eax,4\) - 1b: 8c 2c ed 00 00 00 00 [ ]*movl %gs,0x0\(,%ebp,8\) + 13: 36 8c a4 81 d2 04 00 00 [ ]*movw %fs,%ss:0x4d2\(%ecx,%eax,4\) + 1b: 8c 2c ed 00 00 00 00 [ ]*movw %gs,0x0\(,%ebp,8\) 22: 26 88 25 00 00 00 00 [ ]*mov %ah,%es:0x0 29: 2e 8b 74 14 80 [ ]*mov %cs:0xffffff80\(%esp,%edx,1\),%esi 2e: f3 65 a5 [ ]*repz movsl %gs:\(%esi\),%es:\(%edi\) diff --git a/gas/testsuite/gas/i386/opcode.d b/gas/testsuite/gas/i386/opcode.d index cf91a77e808..808ddc5371a 100644 --- a/gas/testsuite/gas/i386/opcode.d +++ b/gas/testsuite/gas/i386/opcode.d @@ -137,9 +137,9 @@ Disassembly of section .text: 1a3: 89 90 90 90 90 90 [ ]*mov %edx,0x90909090\(%eax\) 1a9: 8a 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dl 1af: 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%edx - 1b5: 8c 90 90 90 90 90 [ ]*movl %ss,0x90909090\(%eax\) + 1b5: 8c 90 90 90 90 90 [ ]*movw %ss,0x90909090\(%eax\) 1bb: 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%edx - 1c1: 8e 90 90 90 90 90 [ ]*movl 0x90909090\(%eax\),%ss + 1c1: 8e 90 90 90 90 90 [ ]*movw 0x90909090\(%eax\),%ss 1c7: 8f 80 90 90 90 90 [ ]*popl 0x90909090\(%eax\) 1cd: 90 [ ]*nop 1ce: 91 [ ]*xchg %eax,%ecx @@ -480,7 +480,7 @@ Disassembly of section .text: 7be: 66 87 90 90 90 90 90 [ ]*xchg %dx,0x90909090\(%eax\) 7c5: 66 89 90 90 90 90 90 [ ]*mov %dx,0x90909090\(%eax\) 7cc: 66 8b 90 90 90 90 90 [ ]*mov 0x90909090\(%eax\),%dx - 7d3: 8c 90 90 90 90 90 [ ]*mov[l ] %ss,0x90909090\(%eax\) + 7d3: 8c 90 90 90 90 90 [ ]*mov[w ] %ss,0x90909090\(%eax\) 7d9: 66 8d 90 90 90 90 90 [ ]*lea 0x90909090\(%eax\),%dx 7e0: 66 8f 80 90 90 90 90 [ ]*popw 0x90909090\(%eax\) 7e7: 66 91 [ ]*xchg %ax,%cx diff --git a/gas/testsuite/gas/i386/opcode.s b/gas/testsuite/gas/i386/opcode.s index e3fbdfe9d2a..8d7cd050f16 100644 --- a/gas/testsuite/gas/i386/opcode.s +++ b/gas/testsuite/gas/i386/opcode.s @@ -130,9 +130,9 @@ foo: mov %edx,0x90909090(%eax) mov 0x90909090(%eax),%dl mov 0x90909090(%eax),%edx - movl %ss,0x90909090(%eax) + movw %ss,0x90909090(%eax) lea 0x90909090(%eax),%edx - movl 0x90909090(%eax),%ss + movw 0x90909090(%eax),%ss popl 0x90909090(%eax) xchg %eax,%eax xchg %eax,%ecx diff --git a/gas/testsuite/gas/i386/segment.l b/gas/testsuite/gas/i386/segment.l new file mode 100644 index 00000000000..59c081e3059 --- /dev/null +++ b/gas/testsuite/gas/i386/segment.l @@ -0,0 +1,10 @@ + 1 .psize 0 + 2 .text + 3 # test segment reg insns with memory operand + 4 0000 8C18 movw %ds,\(%eax\) + 5 0002 8C18 mov %ds,\(%eax\) + 6 0004 8E18 movw \(%eax\),%ds + 7 0006 8E18 mov \(%eax\),%ds + 8 # Force a good alignment. + 9 0008 00000000 .p2align 4,0 + 9 00000000 diff --git a/gas/testsuite/gas/i386/segment.s b/gas/testsuite/gas/i386/segment.s new file mode 100644 index 00000000000..6c2850ccc70 --- /dev/null +++ b/gas/testsuite/gas/i386/segment.s @@ -0,0 +1,9 @@ +.psize 0 +.text +# test segment reg insns with memory operand + movw %ds,(%eax) + mov %ds,(%eax) + movw (%eax),%ds + mov (%eax),%ds + # Force a good alignment. + .p2align 4,0 diff --git a/gas/testsuite/gas/i386/x86-64-inval-seg.l b/gas/testsuite/gas/i386/x86-64-inval-seg.l new file mode 100644 index 00000000000..adef5d41d44 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-inval-seg.l @@ -0,0 +1,14 @@ +.*: Assembler messages: +.*:3: Error: .* +.*:4: Error: .* +.*:5: Error: .* +.*:6: Error: .* +GAS LISTING .* + + + 1 [ ]* .text + 2 [ ]*# All the following should be illegal + 3 [ ]* movq %ds,\(%rax\) + 4 [ ]* movl %ds,\(%rax\) + 5 [ ]* movq \(%rax\),%ds + 6 [ ]* movl \(%rax\),%ds diff --git a/gas/testsuite/gas/i386/x86-64-inval-seg.s b/gas/testsuite/gas/i386/x86-64-inval-seg.s new file mode 100644 index 00000000000..bb547422364 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-inval-seg.s @@ -0,0 +1,6 @@ + .text +# All the following should be illegal + movq %ds,(%rax) + movl %ds,(%rax) + movq (%rax),%ds + movl (%rax),%ds diff --git a/gas/testsuite/gas/i386/x86-64-opcode.d b/gas/testsuite/gas/i386/x86-64-opcode.d index 671876d8f54..13d58be1bdb 100644 --- a/gas/testsuite/gas/i386/x86-64-opcode.d +++ b/gas/testsuite/gas/i386/x86-64-opcode.d @@ -16,22 +16,16 @@ Disassembly of section .text: [ ]*[0-9a-f]+:[ ]+cf[ ]+iret[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+66 cf[ ]+iretw[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+48 cf[ ]+iretq[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 08[ ]+movl?[ ]+%cs,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 08[ ]+movl?[ ]+%cs,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 10[ ]+movl?[ ]+%ss,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 10[ ]+movl?[ ]+%ss,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 20[ ]+movl?[ ]+%fs,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 20[ ]+movl?[ ]+%fs,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 08[ ]+movl?[ ]+%cs,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 08[ ]+movl?[ ]+%cs,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 10[ ]+movl?[ ]+%ss,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 10[ ]+movl?[ ]+%ss,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8c 20[ ]+movl?[ ]+%fs,\(%r8\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8c 20[ ]+movl?[ ]+%fs,\(%rax\)[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8e 10[ ]+movl?[ ]+\(%r8\),%ss[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8e 10[ ]+movl?[ ]+\(%rax\),%ss[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+41 8e 20[ ]+movl?[ ]+\(%r8\),%fs[ ]*(#.*)* -[ ]*[0-9a-f]+:[ ]+8e 20[ ]+movl?[ ]+\(%rax\),%fs[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+41 8c 08[ ]+movw?[ ]+%cs,\(%r8\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+8c 08[ ]+movw?[ ]+%cs,\(%rax\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+41 8c 10[ ]+movw?[ ]+%ss,\(%r8\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+8c 10[ ]+movw?[ ]+%ss,\(%rax\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+41 8c 20[ ]+movw?[ ]+%fs,\(%r8\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+8c 20[ ]+movw?[ ]+%fs,\(%rax\)[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+41 8e 10[ ]+movw?[ ]+\(%r8\),%ss[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+8e 10[ ]+movw?[ ]+\(%rax\),%ss[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+41 8e 20[ ]+movw?[ ]+\(%r8\),%fs[ ]*(#.*)* +[ ]*[0-9a-f]+:[ ]+8e 20[ ]+movw?[ ]+\(%rax\),%fs[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+41 c6 00 00[ ]+movb[ ]+\$0[x0]*,\(%r8\)[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+c6 00 00[ ]+movb[ ]+\$0[x0]*,\(%rax\)[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+66 41 c7 00 00 70[ ]+movw[ ]+\$0x7000,\(%r8\)[ ]*(#.*)* @@ -274,5 +268,4 @@ Disassembly of section .text: [ ]*[0-9a-f]+:[ ]+e7 00[ ]+out[ ]+%eax,\$0[x0]*[ ]*(#.*)* [ ]*[0-9a-f]+:[ ]+00 00[ ]+.* [ ]*[0-9a-f]+:[ ]+00 00[ ]+.* -[ ]*[0-9a-f]+:[ ]+00 00[ ]+.* [ *]... diff --git a/gas/testsuite/gas/i386/x86-64-opcode.s b/gas/testsuite/gas/i386/x86-64-opcode.s index 839a2c3b632..8b132b39046 100644 --- a/gas/testsuite/gas/i386/x86-64-opcode.s +++ b/gas/testsuite/gas/i386/x86-64-opcode.s @@ -20,22 +20,16 @@ # CMP # MOV - MOVw %cs,(%r8) # 66 -- -- 41 8C 08 ; REX to access upper reg. O16 for 16-bit operand size - MOVw %cs,(%rax) # 66 -- -- -- 8C 08 ; O16 for 16-bit operand size - MOVw %ss,(%r8) # 66 -- -- 41 8C 10 ; REX to access upper reg. O16 for 16-bit operand size - MOVw %ss,(%rax) # 66 -- -- -- 8C 10 ; O16 for 16-bit operand size - MOVw %fs,(%r8) # 66 -- -- 41 8C 20 ; REX to access upper reg. O16 for 16-bit operand size - MOVw %fs,(%rax) # 66 -- -- -- 8C 20 ; O16 for 16-bit operand size - MOVl %cs,(%r8) # -- -- -- 41 8C 08 ; REX to access upper reg. - MOVl %cs,(%rax) # -- -- -- -- 8C 08 - MOVl %ss,(%r8) # -- -- -- 41 8C 10 ; REX to access upper reg. - MOVl %ss,(%rax) # -- -- -- -- 8C 10 - MOVl %fs,(%r8) # -- -- -- 41 8C 20 ; REX to access upper reg. - MOVl %fs,(%rax) # -- -- -- -- 8C 20 - MOVl (%r8),%ss # -- -- -- 41 8E 10 ; REX to access upper reg. - MOVl (%rax),%ss # -- -- -- -- 8E 10 - MOVl (%r8),%fs # -- -- -- 41 8E 20 ; REX to access upper reg. - MOVl (%rax),%fs # -- -- -- -- 8E 20 + MOVw %cs,(%r8) # -- -- -- 41 8C 08 ; REX to access upper reg. + MOVw %cs,(%rax) # -- -- -- -- 8C 08 + MOVw %ss,(%r8) # -- -- -- 41 8C 10 ; REX to access upper reg. + MOVw %ss,(%rax) # -- -- -- -- 8C 10 + MOVw %fs,(%r8) # -- -- -- 41 8C 20 ; REX to access upper reg. + MOVw %fs,(%rax) # -- -- -- -- 8C 20 + MOVw (%r8),%ss # -- -- -- 41 8E 10 ; REX to access upper reg. + MOVw (%rax),%ss # -- -- -- -- 8E 10 + MOVw (%r8),%fs # -- -- -- 41 8E 20 ; REX to access upper reg. + MOVw (%rax),%fs # -- -- -- -- 8E 20 MOVb $0,(%r8) # -- -- -- 41 C6 00 00 ; REX to access upper reg. MOVb $0,(%rax) # -- -- -- -- C6 00 00 MOVw $0x7000,(%r8) # 66 -- -- 41 C7 00 00 70 ; REX to access upper reg. O16 for 16-bit operand size diff --git a/gas/testsuite/gas/i386/x86-64-segment.l b/gas/testsuite/gas/i386/x86-64-segment.l new file mode 100644 index 00000000000..4056fde869e --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-segment.l @@ -0,0 +1,12 @@ + 1 .psize 0 + 2 .text + 3 # test segment reg insns with memory operand + 4 0000 8C18 movw %ds,\(%rax\) + 5 0002 8C18 mov %ds,\(%rax\) + 6 0004 8E18 movw \(%rax\),%ds + 7 0006 8E18 mov \(%rax\),%ds + 8 # test segment reg insns with REX + 9 0008 488CD8 movq %ds,%rax + 10 000b 488ED8 movq %rax,%ds + 11 # Force a good alignment. + 12 000e 0000 .p2align 4,0 diff --git a/gas/testsuite/gas/i386/x86-64-segment.s b/gas/testsuite/gas/i386/x86-64-segment.s new file mode 100644 index 00000000000..16fcd761906 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-segment.s @@ -0,0 +1,12 @@ +.psize 0 +.text +# test segment reg insns with memory operand + movw %ds,(%rax) + mov %ds,(%rax) + movw (%rax),%ds + mov (%rax),%ds +# test segment reg insns with REX + movq %ds,%rax + movq %rax,%ds + # Force a good alignment. + .p2align 4,0 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index 7844fee9f8b..fb5d2525948 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,9 @@ +2005-03-29 H.J. Lu + + * i386.h (i386_optab): Don't allow the `l' suffix for moving + moving between memory and segment register. Allow movq for + moving between general-purpose register and segment register. + 2005-02-09 Jan Beulich PR gas/707 diff --git a/include/opcode/i386.h b/include/opcode/i386.h index 052f1272c8d..4de2771e259 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -98,11 +98,13 @@ static const template i386_optab[] = are set to an implementation defined value (on the Pentium Pro, the implementation defined value is zero). */ { "mov", 2, 0x8c, X, 0, wl_Suf|Modrm, { SReg2, WordReg|InvMem, 0 } }, -{ "mov", 2, 0x8c, X, 0, wl_Suf|Modrm|IgnoreSize, { SReg2, WordMem, 0 } }, +{ "mov", 2, 0x8c, X, 0, w_Suf|Modrm|IgnoreSize, { SReg2, WordMem, 0 } }, { "mov", 2, 0x8c, X, Cpu386, wl_Suf|Modrm, { SReg3, WordReg|InvMem, 0 } }, -{ "mov", 2, 0x8c, X, Cpu386, wl_Suf|Modrm|IgnoreSize, { SReg3, WordMem, 0 } }, -{ "mov", 2, 0x8e, X, 0, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg2, 0 } }, -{ "mov", 2, 0x8e, X, Cpu386, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg3, 0 } }, +{ "mov", 2, 0x8c, X, Cpu386, w_Suf|Modrm|IgnoreSize, { SReg3, WordMem, 0 } }, +{ "mov", 2, 0x8e, X, 0, wl_Suf|Modrm|IgnoreSize, { WordReg, SReg2, 0 } }, +{ "mov", 2, 0x8e, X, 0, w_Suf|Modrm|IgnoreSize, { WordMem, SReg2, 0 } }, +{ "mov", 2, 0x8e, X, Cpu386, wl_Suf|Modrm|IgnoreSize, { WordReg, SReg3, 0 } }, +{ "mov", 2, 0x8e, X, Cpu386, w_Suf|Modrm|IgnoreSize, { WordMem, SReg3, 0 } }, /* Move to/from control debug registers. In the 16 or 32bit modes they are 32bit. In the 64bit mode they are 64bit.*/ { "mov", 2, 0x0f20, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Control, Reg32|InvMem, 0} }, @@ -1003,6 +1005,10 @@ static const template i386_optab[] = {"movq", 2, 0x88, X, Cpu64, NoSuf|D|W|Modrm|Size64,{ Reg64, Reg64|AnyMem, 0 } }, {"movq", 2, 0xc6, 0, Cpu64, NoSuf|W|Modrm|Size64, { Imm32S, Reg64|WordMem, 0 } }, {"movq", 2, 0xb0, X, Cpu64, NoSuf|W|ShortForm|Size64,{ Imm64, Reg64, 0 } }, +/* The segment register moves accept Reg64 so that a segment register + can be copied to a 64 bit register, and vice versa. */ +{"movq", 2, 0x8c, X, Cpu64, NoSuf|Modrm|Size64, { SReg2|SReg3, Reg64|InvMem, 0 } }, +{"movq", 2, 0x8e, X, Cpu64, NoSuf|Modrm|Size64, { Reg64, SReg2|SReg3, 0 } }, /* Move to/from control debug registers. In the 16 or 32bit modes they are 32bit. In the 64bit mode they are 64bit.*/ {"movq", 2, 0x0f20, X, Cpu64, NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Control, Reg64|InvMem, 0} }, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 86eca6aacab..29fbf986df5 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2005-03-29 H.J. Lu + + * i386-dis.c (SEG_Fixup): New. + (Sv): New. + (dis386): Use "Sv" for 0x8c and 0x8e. + 2005-03-21 Jan-Benedict Glaw Nick Clifton diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 24e5a393ed2..a2a5a06f726 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -97,6 +97,7 @@ static void SIMD_Fixup (int, int); static void PNI_Fixup (int, int); static void INVLPG_Fixup (int, int); static void BadOp (void); +static void SEG_Fixup (int, int); struct dis_private { /* Points to first byte not fetched. */ @@ -221,6 +222,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Cm OP_C, m_mode #define Dm OP_D, m_mode #define Td OP_T, d_mode +#define Sv SEG_Fixup, v_mode #define RMeAX OP_REG, eAX_reg #define RMeBX OP_REG, eBX_reg @@ -642,9 +644,9 @@ static const struct dis386 dis386[] = { { "movS", Ev, Gv, XX }, { "movB", Gb, Eb, XX }, { "movS", Gv, Ev, XX }, - { "movQ", Ev, Sw, XX }, + { "movQ", Sv, Sw, XX }, { "leaS", Gv, M, XX }, - { "movQ", Sw, Ev, XX }, + { "movQ", Sw, Sv, XX }, { "popU", Ev, XX, XX }, /* 90 */ { "nop", NOP_Fixup, 0, XX, XX }, @@ -4411,3 +4413,52 @@ BadOp (void) codep = insn_codep + 1; oappend ("(bad)"); } + +static void +SEG_Fixup (int extrachar, int sizeflag) +{ + if (mod == 3) + { + /* We need to add a proper suffix with + + movw %ds,%ax + movl %ds,%eax + movq %ds,%rax + movw %ax,%ds + movl %eax,%ds + movq %rax,%ds + */ + const char *suffix; + + if (prefixes & PREFIX_DATA) + suffix = "w"; + else + { + USED_REX (REX_MODE64); + if (rex & REX_MODE64) + suffix = "q"; + else + suffix = "l"; + } + strcat (obuf, suffix); + } + else + { + /* We need to fix the suffix for + + movw %ds,(%eax) + movw %ds,(%rax) + movw (%eax),%ds + movw (%rax),%ds + + Override "mov[l|q]". */ + char *p = obuf + strlen (obuf) - 1; + + /* We might not have a suffix. */ + if (*p == 'v') + ++p; + *p = 'w'; + } + + OP_E (extrachar, sizeflag); +} -- 2.30.2