PATCH: PR gas/1874: mwait/monitor don't work in 64bit
H. J. Lu
hjl@lucon.org
Thu Nov 17 23:14:00 GMT 2005
More information about the Binutils mailing list
Thu Nov 17 23:14:00 GMT 2005
- Previous message (by thread): PATCH: PR gas/1874: mwait/monitor don't work in 64bit
- Next message (by thread): PATCH: PR gas/1874: mwait/monitor don't work in 64bit
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, Nov 17, 2005 at 12:06:13PM -0800, H. J. Lu wrote: > On Thu, Nov 17, 2005 at 06:05:57PM +0100, Jan Beulich wrote: > > >>> "H. J. Lu" <hjl@lucon.org> 17.11.05 17:44:06 >>> > > >On Thu, Nov 17, 2005 at 10:30:05AM +0100, Jan Beulich wrote: > > >> > > >> Regarding the patch, I don't think hard-coding the address size > > >> override for 16-bit operation of monitor is appropriate - under > > .code16 > > >> this is not going to produce the desired effect (and likewise is > > the > > >> opposite 32-bit operation in 16-bit mode then missing the override). > > The > > >> base problem here is that monitor's address operand, when > > explicitly > > > > > >The opcode is the same for both 32bit and 64bit modes. The address > > > size ovverride only changes the size of EAX/RAX. I don't see how > > >".code16" can be used with it. As for ".code32", it works fine: > > > > Why shouldn't BIOS code be using this? This would likely require > > .code16. > > > > monitor/mwait work in 16bit mode. The address size override prefix can > be used to change the AX size. This patch support memory as the first > operand of monitor. > I really don't like to use memory operand for monitor. Here is the new patch without memory operand. H.J. ---- gas/ 2005-11-17 H.J. Lu <hongjiu.lu@intel.com> * config/tc-i386.c (match_template): Handle monitor. (process_suffix): Likewise. gas/testsuite/ 2005-11-17 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * gas/i386/i386.exp: Add x86-64-prescott for 64bit. * gas/i386/prescott.s: Test address size override for monitor. * gas/i386/prescott.d: Updated. * gas/i386/x86-64-prescott.d: New file. * gas/i386/x86-64-prescott.s: Likewise. include/opcode/ 2005-11-17 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * i386.h (i386_optab): Add 64bit support for monitor and mwait. opcodes/ 2005-11-17 H.J. Lu <hongjiu.lu@intel.com> PR gas/1874 * i386-dis.c (PNI_Fixup): Add 64bit and address size override support for monitor and mwait. --- binutils/gas/config/tc-i386.c.pni 2005-11-11 10:48:52.000000000 -0800 +++ binutils/gas/config/tc-i386.c 2005-11-17 15:00:03.000000000 -0800 @@ -2274,10 +2274,15 @@ match_template () overlap1 = i.types[1] & t->operand_types[1]; if (!MATCH (overlap0, i.types[0], t->operand_types[0]) || !MATCH (overlap1, i.types[1], t->operand_types[1]) - || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0], - t->operand_types[0], - overlap1, i.types[1], - t->operand_types[1])) + /* monitor in SSE3 is a very special case. The first + register and the second register may have differnet + sizes. */ + || !((t->base_opcode == 0x0f01 + && t->extension_opcode == 0xc8) + || CONSISTENT_REGISTER_MATCH (overlap0, i.types[0], + t->operand_types[0], + overlap1, i.types[1], + t->operand_types[1]))) { /* Check if other direction is valid ... */ if ((t->opcode_modifier & (D | FloatD)) == 0) @@ -2545,12 +2550,24 @@ process_suffix (void) /* Now select between word & dword operations via the operand size prefix, except for instructions that will ignore this prefix anyway. */ - if (i.suffix != QWORD_MNEM_SUFFIX - && i.suffix != LONG_DOUBLE_MNEM_SUFFIX - && !(i.tm.opcode_modifier & (IgnoreSize | FloatMF)) - && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) - || (flag_code == CODE_64BIT - && (i.tm.opcode_modifier & JumpByte)))) + if (i.tm.base_opcode == 0x0f01 && i.tm.extension_opcode == 0xc8) + { + /* monitor in SSE3 is a very special case. The default size + of AX is the size of mode. The address size override + prefix will change the size of AX. */ + if (((flag_code == CODE_16BIT || flag_code == CODE_64BIT) + && (i.op->regs[0].reg_type & Reg32)) + || (flag_code == CODE_32BIT + && i.op->regs[0].reg_type & Reg16)) + if (!add_prefix (ADDR_PREFIX_OPCODE)) + return 0; + } + else if (i.suffix != QWORD_MNEM_SUFFIX + && i.suffix != LONG_DOUBLE_MNEM_SUFFIX + && !(i.tm.opcode_modifier & (IgnoreSize | FloatMF)) + && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) + || (flag_code == CODE_64BIT + && (i.tm.opcode_modifier & JumpByte)))) { unsigned int prefix = DATA_PREFIX_OPCODE; --- binutils/gas/testsuite/gas/i386/i386.exp.pni 2005-11-11 10:48:53.000000000 -0800 +++ binutils/gas/testsuite/gas/i386/i386.exp 2005-11-15 15:37:50.000000000 -0800 @@ -131,6 +131,7 @@ if [expr ([istarget "i*86-*-*"] || [ista run_dump_test "svme64" run_dump_test "x86-64-vmx" run_dump_test "immed64" + run_dump_test "x86-64-prescott" # For ELF targets verify that @unwind works. if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"] --- binutils/gas/testsuite/gas/i386/prescott.d.pni 2004-06-23 08:06:57.000000000 -0700 +++ binutils/gas/testsuite/gas/i386/prescott.d 2005-11-17 15:06:52.000000000 -0800 @@ -32,5 +32,6 @@ Disassembly of section .text: 62: f3 0f 12 dc [ ]*movsldup %xmm4,%xmm3 66: 0f 01 c9 [ ]*mwait %eax,%ecx 69: 0f 01 c9 [ ]*mwait %eax,%ecx - 6c: 00 00 [ ]*add %al,\(%eax\) + 6c: 67 0f 01 c8 [ ]*monitor %ax,%ecx,%edx + 70: 67 0f 01 c8 [ ]*monitor %ax,%ecx,%edx ... --- binutils/gas/testsuite/gas/i386/prescott.s.pni 2004-06-23 08:06:58.000000000 -0700 +++ binutils/gas/testsuite/gas/i386/prescott.s 2005-11-17 15:02:25.000000000 -0800 @@ -29,4 +29,7 @@ foo: mwait mwait %eax,%ecx + monitor %ax,%ecx,%edx + addr16 monitor + .p2align 4,0 --- binutils/gas/testsuite/gas/i386/x86-64-prescott.d.pni 2005-11-15 15:33:49.000000000 -0800 +++ binutils/gas/testsuite/gas/i386/x86-64-prescott.d 2005-11-17 15:02:46.000000000 -0800 @@ -0,0 +1,37 @@ +#objdump: -dw +#name: x86-64 prescott + +.*: +file format .* + +Disassembly of section .text: + +0+000 <foo>: + 0: 66 0f d0 01 [ ]*addsubpd \(%rcx\),%xmm0 + 4: 66 0f d0 ca [ ]*addsubpd %xmm2,%xmm1 + 8: f2 0f d0 13 [ ]*addsubps \(%rbx\),%xmm2 + c: f2 0f d0 dc [ ]*addsubps %xmm4,%xmm3 + 10: df 88 90 90 90 90 [ ]*fisttp 0xffffffff90909090\(%rax\) + 16: db 88 90 90 90 90 [ ]*fisttpl 0xffffffff90909090\(%rax\) + 1c: dd 88 90 90 90 90 [ ]*fisttpll 0xffffffff90909090\(%rax\) + 22: 66 0f 7c 65 00 [ ]*haddpd 0x0\(%rbp\),%xmm4 + 27: 66 0f 7c ee [ ]*haddpd %xmm6,%xmm5 + 2b: f2 0f 7c 37 [ ]*haddps \(%rdi\),%xmm6 + 2f: f2 0f 7c f8 [ ]*haddps %xmm0,%xmm7 + 33: 66 0f 7d c1 [ ]*hsubpd %xmm1,%xmm0 + 37: 66 0f 7d 0a [ ]*hsubpd \(%rdx\),%xmm1 + 3b: f2 0f 7d d2 [ ]*hsubps %xmm2,%xmm2 + 3f: f2 0f 7d 1c 24 [ ]*hsubps \(%rsp\),%xmm3 + 44: f2 0f f0 2e [ ]*lddqu \(%rsi\),%xmm5 + 48: 0f 01 c8 [ ]*monitor %rax,%rcx,%rdx + 4b: 0f 01 c8 [ ]*monitor %rax,%rcx,%rdx + 4e: f2 0f 12 f7 [ ]*movddup %xmm7,%xmm6 + 52: f2 0f 12 38 [ ]*movddup \(%rax\),%xmm7 + 56: f3 0f 16 01 [ ]*movshdup \(%rcx\),%xmm0 + 5a: f3 0f 16 ca [ ]*movshdup %xmm2,%xmm1 + 5e: f3 0f 12 13 [ ]*movsldup \(%rbx\),%xmm2 + 62: f3 0f 12 dc [ ]*movsldup %xmm4,%xmm3 + 66: 0f 01 c9 [ ]*mwait %rax,%rcx + 69: 0f 01 c9 [ ]*mwait %rax,%rcx + 6c: 67 0f 01 c8 [ ]*monitor %eax,%rcx,%rdx + 70: 67 0f 01 c8 [ ]*monitor %eax,%rcx,%rdx + ... --- binutils/gas/testsuite/gas/i386/x86-64-prescott.s.pni 2005-11-15 15:33:47.000000000 -0800 +++ binutils/gas/testsuite/gas/i386/x86-64-prescott.s 2005-11-17 15:03:00.000000000 -0800 @@ -0,0 +1,35 @@ +#Prescott New Instructions + + .text +foo: + addsubpd (%rcx),%xmm0 + addsubpd %xmm2,%xmm1 + addsubps (%rbx),%xmm2 + addsubps %xmm4,%xmm3 + fisttp 0x90909090(%rax) + fisttpl 0x90909090(%rax) + fisttpll 0x90909090(%rax) + haddpd 0x0(%rbp),%xmm4 + haddpd %xmm6,%xmm5 + haddps (%rdi),%xmm6 + haddps %xmm0,%xmm7 + hsubpd %xmm1,%xmm0 + hsubpd (%rdx),%xmm1 + hsubps %xmm2,%xmm2 + hsubps (%rsp,1),%xmm3 + lddqu (%rsi),%xmm5 + monitor + monitor %rax,%rcx,%rdx + movddup %xmm7,%xmm6 + movddup (%rax),%xmm7 + movshdup (%rcx),%xmm0 + movshdup %xmm2,%xmm1 + movsldup (%rbx),%xmm2 + movsldup %xmm4,%xmm3 + mwait + mwait %rax,%rcx + + monitor %eax,%rcx,%rdx + addr32 monitor + + .p2align 4,0 --- binutils/include/opcode/i386.h.pni 2005-07-27 08:41:15.000000000 -0700 +++ binutils/include/opcode/i386.h 2005-11-17 15:09:47.000000000 -0800 @@ -1346,14 +1346,24 @@ static const template i386_optab[] = {"hsubps", 2, 0xf20f7d, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"lddqu", 2, 0xf20ff0, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { LLongMem, RegXMM, 0 } }, {"monitor", 0, 0x0f01, 0xc8, CpuPNI, NoSuf|ImmExt, { 0, 0, 0} }, -/* Need to ensure only "monitor %eax,%ecx,%edx" is accepted. */ -{"monitor", 3, 0x0f01, 0xc8, CpuPNI, NoSuf|ImmExt, { Reg32, Reg32, Reg32} }, +/* monitor is very special. CX and DX are always 64bits with zero upper + 32bits in 64bit mode, and 32bits in 16bit and 32bit modes. The + address size override prefix can be used to overrride the AX size in + all modes. */ +/* Need to ensure only "monitor %eax/%ax,%ecx,%edx" is accepted. */ +{"monitor", 3, 0x0f01, 0xc8, CpuPNI|CpuNo64, NoSuf|ImmExt, { Reg16|Reg32, Reg32, Reg32 } }, +/* Need to ensure only "monitor %rax/%eax,%rcx,%rdx" is accepted. */ +{"monitor", 3, 0x0f01, 0xc8, CpuPNI|Cpu64, NoSuf|ImmExt|NoRex64, { Reg32|Reg64, Reg64, Reg64 } }, {"movddup", 2, 0xf20f12, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"movshdup", 2, 0xf30f16, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"movsldup", 2, 0xf30f12, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"mwait", 0, 0x0f01, 0xc9, CpuPNI, NoSuf|ImmExt, { 0, 0, 0} }, +/* mwait is very special. AX and CX are always 64bits with zero upper + 32bits in 64bit mode, and 32bits in 16bit and 32bit modes. */ /* Need to ensure only "mwait %eax,%ecx" is accepted. */ -{"mwait", 2, 0x0f01, 0xc9, CpuPNI, NoSuf|ImmExt, { Reg32, Reg32, 0} }, +{"mwait", 2, 0x0f01, 0xc9, CpuPNI|CpuNo64, NoSuf|ImmExt, { Reg32, Reg32, 0} }, +/* Need to ensure only "mwait %rax,%rcx" is accepted. */ +{"mwait", 2, 0x0f01, 0xc9, CpuPNI|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, Reg64, 0} }, /* VMX instructions. */ {"vmcall", 0, 0x0f01, 0xc1, CpuVMX, NoSuf|ImmExt, { 0, 0, 0} }, --- binutils/opcodes/i386-dis.c.pni 2005-11-11 10:48:50.000000000 -0800 +++ binutils/opcodes/i386-dis.c 2005-11-17 14:52:31.000000000 -0800 @@ -4412,18 +4412,30 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSE if (mod == 3 && reg == 1 && rm <= 1) { /* Override "sidt". */ - char *p = obuf + strlen (obuf) - 4; + size_t olen = strlen (obuf); + char *p = obuf + olen - 4; + const char **names = mode_64bit ? names64 : names32; /* We might have a suffix when disassembling with -Msuffix. */ if (*p == 'i') --p; + /* Remove "addr16/addr32" if we aren't in Intel mode. */ + if (!intel_syntax + && (prefixes & PREFIX_ADDR) + && olen >= (4 + 7) + && *(p - 1) == ' ' + && strncmp (p - 7, "addr", 4) == 0 + && (strncmp (p - 3, "16", 2) == 0 + || strncmp (p - 3, "32", 2) == 0)) + p -= 7; + if (rm) { /* mwait %eax,%ecx */ strcpy (p, "mwait"); if (!intel_syntax) - strcpy (op1out, names32[0]); + strcpy (op1out, names[0]); } else { @@ -4431,21 +4443,21 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSE strcpy (p, "monitor"); if (!intel_syntax) { - if (!mode_64bit) - strcpy (op1out, names32[0]); - else if (!(prefixes & PREFIX_ADDR)) - strcpy (op1out, names64[0]); + const char **op1_names; + if (!(prefixes & PREFIX_ADDR)) + op1_names = names; else { - strcpy (op1out, names32[0]); + op1_names = mode_64bit ? names32 : names16; used_prefixes |= PREFIX_ADDR; } - strcpy (op3out, names32[2]); + strcpy (op1out, op1_names[0]); + strcpy (op3out, names[2]); } } if (!intel_syntax) { - strcpy (op2out, names32[1]); + strcpy (op2out, names[1]); two_source_ops = 1; }
- Previous message (by thread): PATCH: PR gas/1874: mwait/monitor don't work in 64bit
- Next message (by thread): PATCH: PR gas/1874: mwait/monitor don't work in 64bit
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list