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~