On 03/24/2010 10:07 AM, Richard Henderson wrote: > 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; > }; ... > 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))
On 03/24/2010 11:00 AM, Blue Swirl wrote: > One trick is to define a fixed offset (about half CPUState size) and > make env point to CPUState + offset. Then the negative part of the > offset space can be used efficiently. But this just doubles the space > that can be accessed fast, so it's not a big win. A good idea. We can eliminate the cpu_large_state_offset from above via: struct CPUSmallCommonState { // most of the stuff from CPU_COMMON. } __attribute__((aligned)); struct CPUXYZPrivateState { // all the cpu-specific stuff }; struct CPUXYZSmallState { CPUXYZPrivateState p; CPUSmallCommonState s; }; struct CPUXYZAllState { CPUXYZSmallState s; CPULargeCommonState l; // ARG0 register points here. }; register void *biased_env __asm__(AREG0); static inline CPUXYZPrivateState *get_env_cpu_private(void) { return &((CPUXYZSmallState *)biased_env - 1)->p; } static inline CPUSmallCommonState *get_env_common_small(void) { return (CPUSmallCommonState *)biased_env - 1; } static inline CPULargeCommonState *get_env_common_large(void) { return (CPULargeCommonState *)biased_env; } r~