From c4a530c52970c9fdd3a6c0315503a058e132f073 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 2 Mar 2005 08:01:32 +0000 Subject: [PATCH] gas/ 2005-03-02 Jan Beulich * config/tc-i386.c (build_modrm_byte): Add lock prefix for cr8...15 accesses. (parse_register): Allow cr8...15 in all modes. gas/testsuite/ 2005-03-02 Jan Beulich * gas/i386/cr-err.[ls]: New. * gas/i386/crx.[ds]: New. * gas/i386/i386.exp: Run new tests. opcodes/ 2005-03-02 Jan Beulich * i386-dis.c (print_insn): Suppress lock prefix printing for cr8...15 accesses. (OP_C): Consider lock prefix in non-64-bit modes. --- gas/ChangeLog | 6 ++++++ gas/config/tc-i386.c | 8 ++++++++ gas/testsuite/ChangeLog | 6 ++++++ gas/testsuite/gas/i386/cr-err.l | 29 +++++++++++++++++++++++++++ gas/testsuite/gas/i386/cr-err.s | 35 +++++++++++++++++++++++++++++++++ gas/testsuite/gas/i386/crx.d | 20 +++++++++++++++++++ gas/testsuite/gas/i386/crx.s | 18 +++++++++++++++++ gas/testsuite/gas/i386/i386.exp | 3 ++- opcodes/ChangeLog | 6 ++++++ opcodes/i386-dis.c | 17 ++++++++++++---- 10 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 gas/testsuite/gas/i386/cr-err.l create mode 100644 gas/testsuite/gas/i386/cr-err.s create mode 100644 gas/testsuite/gas/i386/crx.d create mode 100644 gas/testsuite/gas/i386/crx.s diff --git a/gas/ChangeLog b/gas/ChangeLog index a12b38985a..759c9be61b 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2005-03-02 Jan Beulich + + * config/tc-i386.c (build_modrm_byte): Add lock prefix for cr8...15 + accesses. + (parse_register): Allow cr8...15 in all modes. + 2005-03-02 Jan Beulich * config/tc-i386.c (intel_e11): If not followed by T_PTR, treat T_BYTE diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 37c40734b6..b116ee4f51 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2868,6 +2868,13 @@ build_modrm_byte () if ((i.op[source].regs->reg_flags & RegRex) != 0) i.rex |= REX_EXTX; } + if (flag_code != CODE_64BIT && (i.rex & (REX_EXTX | REX_EXTZ))) + { + if (!((i.types[0] | i.types[1]) & Control)) + abort (); + i.rex &= ~(REX_EXTX | REX_EXTZ); + add_prefix (LOCK_PREFIX_OPCODE); + } } else { /* If it's not 2 reg operands... */ @@ -5040,6 +5047,7 @@ parse_register (reg_string, end_op) if (r != NULL && ((r->reg_flags & (RegRex64 | RegRex)) | (r->reg_type & Reg64)) != 0 + && (r->reg_type != Control || !(cpu_arch_flags & CpuSledgehammer)) && flag_code != CODE_64BIT) return (const reg_entry *) NULL; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 641368d604..0f91ee78ef 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-03-02 Jan Beulich + + * gas/i386/cr-err.[ls]: New. + * gas/i386/crx.[ds]: New. + * gas/i386/i386.exp: Run new tests. + 2005-03-02 Jan Beulich * gas/i386/intelok.d: Add -r to objdump options. Adjust expectations. diff --git a/gas/testsuite/gas/i386/cr-err.l b/gas/testsuite/gas/i386/cr-err.l new file mode 100644 index 0000000000..4aa1358ac1 --- /dev/null +++ b/gas/testsuite/gas/i386/cr-err.l @@ -0,0 +1,29 @@ +.*: Assembler messages: +.*:[0-9]+: Error: .\(%cr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%cr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%cr8\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%cr15\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%db0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%db7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%dr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%dr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%tr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(%tr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(cr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(cr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(cr8\). is not a valid base/index expression +.*:[0-9]+: Error: .\(cr15\). is not a valid base/index expression +.*:[0-9]+: Error: .\(db0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(db7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(dr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(dr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\(tr0\). is not a valid base/index expression +.*:[0-9]+: Error: .\(tr7\). is not a valid base/index expression +.*:[0-9]+: Error: .\[cr0\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[cr7\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[cr8\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[cr15\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[dr0\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[dr7\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[tr0\]. is not a valid base/index expression +.*:[0-9]+: Error: .\[tr7\]. is not a valid base/index expression diff --git a/gas/testsuite/gas/i386/cr-err.s b/gas/testsuite/gas/i386/cr-err.s new file mode 100644 index 0000000000..5c45c32aa3 --- /dev/null +++ b/gas/testsuite/gas/i386/cr-err.s @@ -0,0 +1,35 @@ +.text + +_start: + movl (%cr0), %eax + movl %eax, (%cr7) + movl (%cr8), %eax + movl %eax, (%cr15) + movl (%db0), %eax + movl %eax, (%db7) + movl (%dr0), %eax + movl %eax, (%dr7) + movl (%tr0), %eax + movl %eax, (%tr7) + +.att_syntax noprefix + movl (cr0), eax + movl eax, (cr7) + movl (cr8), eax + movl eax, (cr15) + movl (db0), eax + movl eax, (db7) + movl (dr0), eax + movl eax, (dr7) + movl (tr0), eax + movl eax, (tr7) + +.intel_syntax noprefix + mov eax, [cr0] + mov [cr7], eax + mov eax, [cr8] + mov [cr15], eax + mov eax, [dr0] + mov [dr7], eax + mov eax, [tr0] + mov [tr7], eax diff --git a/gas/testsuite/gas/i386/crx.d b/gas/testsuite/gas/i386/crx.d new file mode 100644 index 0000000000..11e007a9aa --- /dev/null +++ b/gas/testsuite/gas/i386/crx.d @@ -0,0 +1,20 @@ +#objdump: -dw +#name: i386 cr8+ + +.*: +file format .* + +Disassembly of section .text: + +0+ <_start>: +[ ]*[0-9a-f]+: f0 0f 20 c0[ ]+movl?[ ]+?%cr8,%eax +[ ]*[0-9a-f]+: f0 0f 20 c7[ ]+movl?[ ]+?%cr8,%edi +[ ]*[0-9a-f]+: f0 0f 22 c0[ ]+movl?[ ]+?%eax,%cr8 +[ ]*[0-9a-f]+: f0 0f 22 c7[ ]+movl?[ ]+?%edi,%cr8 +[ ]*[0-9a-f]+: f0 0f 20 c0[ ]+movl?[ ]+?%cr8,%eax +[ ]*[0-9a-f]+: f0 0f 20 c7[ ]+movl?[ ]+?%cr8,%edi +[ ]*[0-9a-f]+: f0 0f 22 c0[ ]+movl?[ ]+?%eax,%cr8 +[ ]*[0-9a-f]+: f0 0f 22 c7[ ]+movl?[ ]+?%edi,%cr8 +[ ]*[0-9a-f]+: f0 0f 20 c0[ ]+movl?[ ]+?%cr8,%eax +[ ]*[0-9a-f]+: f0 0f 20 c7[ ]+movl?[ ]+?%cr8,%edi +[ ]*[0-9a-f]+: f0 0f 22 c0[ ]+movl?[ ]+?%eax,%cr8 +[ ]*[0-9a-f]+: f0 0f 22 c7[ ]+movl?[ ]+?%edi,%cr8 diff --git a/gas/testsuite/gas/i386/crx.s b/gas/testsuite/gas/i386/crx.s new file mode 100644 index 0000000000..e0a78fd12c --- /dev/null +++ b/gas/testsuite/gas/i386/crx.s @@ -0,0 +1,18 @@ +.text +_start: + movl %cr8, %eax + movl %cr8, %edi + movl %eax, %cr8 + movl %edi, %cr8 + +.att_syntax noprefix + movl cr8, eax + movl cr8, edi + movl eax, cr8 + movl edi, cr8 + +.intel_syntax noprefix + mov eax, cr8 + mov edi, cr8 + mov cr8, eax + mov cr8, edi diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index 98b6ea66bb..1cb1af3b6b 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -68,8 +68,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_32_check]] run_dump_test "divide" } - run_dump_test "padlock" + run_dump_test "crx" + run_list_test "cr-err" "" # These tests require support for 8 and 16 bit relocs, # so we only run them for ELF and COFF targets. diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index e8c62ade31..21bd04eed3 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,9 @@ +2005-03-02 Jan Beulich + + * i386-dis.c (print_insn): Suppress lock prefix printing for cr8...15 + accesses. + (OP_C): Consider lock prefix in non-64-bit modes. + 2005-02-24 Alan Modra * cris-dis.c (format_hex): Remove ineffective warning fix. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 0e9ce49e25..51204ba281 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -1956,7 +1956,7 @@ print_insn (bfd_vma pc, disassemble_info *info) int i; char *first, *second, *third; int needcomma; - unsigned char uses_SSE_prefix; + unsigned char uses_SSE_prefix, uses_LOCK_prefix; int sizeflag; const char *p; struct dis_private priv; @@ -2128,12 +2128,14 @@ print_insn (bfd_vma pc, disassemble_info *info) dp = &dis386_twobyte[*++codep]; need_modrm = twobyte_has_modrm[*codep]; uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; + uses_LOCK_prefix = (*codep & ~0x02) == 0x20; } else { dp = &dis386[*codep]; need_modrm = onebyte_has_modrm[*codep]; uses_SSE_prefix = 0; + uses_LOCK_prefix = 0; } codep++; @@ -2147,7 +2149,7 @@ print_insn (bfd_vma pc, disassemble_info *info) oappend ("repnz "); used_prefixes |= PREFIX_REPNZ; } - if (prefixes & PREFIX_LOCK) + if (!uses_LOCK_prefix && (prefixes & PREFIX_LOCK)) { oappend ("lock "); used_prefixes |= PREFIX_LOCK; @@ -3993,9 +3995,16 @@ static void OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) { int add = 0; - USED_REX (REX_EXTX); if (rex & REX_EXTX) - add = 8; + { + USED_REX (REX_EXTX); + add = 8; + } + else if (!mode_64bit && (prefixes & PREFIX_LOCK)) + { + used_prefixes |= PREFIX_LOCK; + add = 8; + } sprintf (scratchbuf, "%%cr%d", reg + add); oappend (scratchbuf + intel_syntax); }