From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NuU3R-00035a-Ay for qemu-devel@nongnu.org; Wed, 24 Mar 2010 13:07:41 -0400 Received: from [140.186.70.92] (port=36975 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NuU3P-00035M-Uk for qemu-devel@nongnu.org; Wed, 24 Mar 2010 13:07:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1NuU3O-0007RS-3u for qemu-devel@nongnu.org; Wed, 24 Mar 2010 13:07:39 -0400 Received: from are.twiddle.net ([75.149.56.221]:55371) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1NuU3N-0007RF-UH for qemu-devel@nongnu.org; Wed, 24 Mar 2010 13:07:38 -0400 Message-ID: <4BAA46D8.1080505@twiddle.net> Date: Wed, 24 Mar 2010 10:07:36 -0700 From: Richard Henderson MIME-Version: 1.0 Subject: Re: [Qemu-devel] Re: Compile files only once: some planning References: <4BA9DFAA.3070107@redhat.com> <4BA9F52C.6070309@twiddle.net> <4BAA25A7.7000201@redhat.com> In-Reply-To: <4BAA25A7.7000201@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paolo Bonzini Cc: Blue Swirl , qemu-devel On 03/24/2010 07:45 AM, Paolo Bonzini wrote: > On 03/24/2010 12:19 PM, Richard Henderson wrote: >> On 03/24/2010 02:47 AM, Paolo Bonzini wrote: >>> 1) make CPUState define only common fields. Include CPUState at the >>> beginning of each per-target CPUXYZState. >> >> Irritatingly, the common fields contain quite big TLBs. And the >> offsets from the start of env affect the compactness of the code >> generated from TCG. We really really want the general registers >> to come first to make sure that those offsets fit the host's >> reg+offset addressing mode. > > What about adding a 512-bytes (or more) block or something like that at > the beginning of CPUState with a union, so you can put the per-target > stuff there? I think that would be confusing. What might be just as good (although possibly just as confusing) is to move the big members into a different structure. E.g. struct CPUSmallCommonState { // most of the stuff from CPU_COMMON. // sorted for some thought of padding elimination. ;-) }; struct CPULargeCommonState { CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE]; struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; jmp_buf jmp_env; }; struct CPUXYZSmallState { CPUSmallCommonState common_s; // the rest of the cpu-specific stuff. }; struct CPUXYZLargeState { CPUXYZSmallState s; CPUBigCommonState common_l; }; extern int cpu_large_state_offset = offsetof(CPUXYZLargeState, common_l); Now. If you're compiling a file for which cpu-specific code is ok: register CPUXYZLargeState *env __asm__(AREG0); #define ENV_SMALL_COMMON_STATE (&env->s.common_s) #define ENV_LARGE_COMMON_STATE (&env->common_l) If you're compiling a file which is supposed to be independant of cpu: register CPUSmallCommonState *env __asm__(AREG0); #define ENV_SMALL_COMMON_STATE (env) #define ENV_LARGE_COMMON_STATE ((CPULargeCommonState *)((char *)env + cpu_large_state_offset)) For the gcc-compiled code, the addition of the cpu_large_state_offset is probably more or less on par in efficiency with indirection. But for TCG generated code, the variable read happens at code generation time, which means we *still* have a constant in the generated code. r~