From owner-freebsd-emulation@FreeBSD.ORG Wed Jan 24 06:11:59 2007 Return-Path: X-Original-To: freebsd-emulation@FreeBSD.org Delivered-To: freebsd-emulation@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id EE47716A403; Wed, 24 Jan 2007 06:11:58 +0000 (UTC) (envelope-from bde@zeta.org.au) Received: from mailout2.pacific.net.au (mailout2-3.pacific.net.au [61.8.2.226]) by mx1.freebsd.org (Postfix) with ESMTP id 811D213C44C; Wed, 24 Jan 2007 06:11:58 +0000 (UTC) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.2.163]) by mailout2.pacific.net.au (Postfix) with ESMTP id 540C66E0DA; Wed, 24 Jan 2007 17:11:53 +1100 (EST) Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) by mailproxy2.pacific.net.au (Postfix) with ESMTP id C33652742A; Wed, 24 Jan 2007 17:11:53 +1100 (EST) Date: Wed, 24 Jan 2007 17:11:47 +1100 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: Tijl Coosemans In-Reply-To: <200701232343.47316.tijl@ulyssis.org> Message-ID: <20070124160934.V36320@delplex.bde.org> References: <790a9fff0701211041j1176d00gd6dd75d0989cf4ec@mail.gmail.com> <200701232113.50766.tijl@ulyssis.org> <200701231555.57521.jkim@FreeBSD.org> <200701232343.47316.tijl@ulyssis.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-emulation@FreeBSD.org, Jung-uk Kim Subject: Re: linuxolator: tls_test results amd64 X-BeenThere: freebsd-emulation@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Development of Emulators of other operating systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Jan 2007 06:11:59 -0000 On Tue, 23 Jan 2007, Tijl Coosemans wrote: > On Tuesday 23 January 2007 21:55, Jung-uk Kim wrote: >> On Tuesday 23 January 2007 03:13 pm, Tijl Coosemans wrote: >>> On Tuesday 23 January 2007 20:00, Jung-uk Kim wrote: >>>> Second problem is MSR_KGSBASE is scrubbed by something during >>>> context switch, i.e., it becomes 0 some times. >>> >>> You mean: >>> >>> *kernel sets gsbase and switches back to user mode >>> *user program does things >> >> Yes. BTW, glibc seems to use movw instead of movl to load %gs. I >> don't know if that makes difference, though. It may have some >> effect when glibc is built with -mtls-direct-seg-refs flag. Need >> confirmation. > > I think there's no difference between movw and movl. The first stores > a 16 bit value in %gs, the second stores the lower 16 bits of a 32 bit > value. movl is a workaround for pessimizations and/or bugs in old versions of gas. Old versions of gas didn't understand operand sizes so they generated pessimal operand size prefixes and in general (for other instructions) made a mess when the source and target operands have different sizes. Gas now detects mismatched sizes but allows them in this case: %%% GAS LISTING gas.s page 1 1 0000 8EE8 movl %eax,%gs 2 0002 8EE8 mov %eax,%gs 3 0004 8EE8 movw %ax,%gs 4 0006 8EE8 mov %ax,%gs 5 6 0008 8E2D0000 movl 0,%gs 6 0000 7 000e 8E2D0000 mov 0,%gs 7 0000 8 0014 8E2D0000 movw 0,%gs 8 0000 %%% so the old workaround has no effect. When I wrote my i386 assembler, I thought that the 32-bit source value couldn't even exist for the case of move from memory. It makes a difference whether the load is a 16-bit or 32-bit one. If it is 32-bit, despite there not being an operand size prefix in 32-bit mode, then it might trap where a 16-bit load would not, because only the 32-bit load crosses a segment or page boundary. I think it is always 16-bit. Thus asking for a 32-bit move to a segment register is just bogus. My assembler enforces this: %%% ... 00001 mov dword ds,eax ***** ^mismatched size ***** ^mismatched size 00002 mov ds,eax ***** ^mismatched size 00003 0000 8ED8 mov word ds,ax 00004 0002 8ED8 mov ds,ax 00005 00006 0004 67 8E1E 0000 mov dword ds,[0] ***** ^mismatched size 00007 0009 67 8E1E 0000 mov ds,[0] 00008 000E 67 8E1E 0000 mov ds,[0] ... %%% My assembler doesn't generate an operand size prefix, but generates an address size prefix to optimize the loads from address 0 for space. This is possible because these address is known to fit in 16 bits. I don't know how to make gas do this (cc -Os doesn't give it). So if a 32-bit store is different and you actually want it, neither assembler supports it directly (you have to manually add an operand size prefix explicitly). Moves _from_ segment registers are completely different. For push of a segment register, you normally want a 32-bit access to keep the stack aligned and perhaps to avoid leaving garbage on the stack. mov of a segment register to memory is little different. Even pop of a segment is little different -- it increments the stack pointer by 4 for compatibility with push, but I think it doesn't access the upper 16 bits. IIRC, 32-bit writes of segment registers to another register or memory write CPU-dependent garbage to the top 32 bits. Newer CPUs are more likely to write 0's and older CPUs are more likely to write pure garbage. The garbage is most visible in debugger output. Gas now gets this right by determining the operand sizes correctly and generating the operand size prefix iff it is necessary. It generates the operand size prefix as necessary for popw in 32-bit mode, so the prefix is not completely unnecessary for loads -- it is necessary to do the correct stack adjustment. Gas doesn't generate any operand sizes for mov's to memory, and I think the memory access size is always 16 despite this, the same as for mov's from memoery. FreeBSD still uses movl from segment registers in most places to ensure not getting an operand size prefixes. Unnecessary operand size prefixes cost more on older CPUs. On newer CPUs they get decoded into nothing before reaching final pipeline stages. My assembler has always got this completely wrong (except probably in Linux versions that I haven't looked at), at least for push (and pop too) and for mov's to registers. It enforces a 16-bit operand size for everything. This is especially broken for push/pop in 32-bit mode. Some of the CPU behaviours (especially for movl from a segreg to a general register) seem to be only documented in newer CPU manuals. I've never seen or wrote documentation for the asm behaviours and have to write the above programs to remember what they are. Bruce