Re: [Qemu-devel] [PATCH v4 11/35] cputlb: Move most of iotlb code out of line
Richard Hendersonwrites: > Saves 2k code size off of a cold path. > > Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée > --- > cputlb.c | 37 + > softmmu_template.h | 52 ++-- > 2 files changed, 47 insertions(+), 42 deletions(-) > > diff --git a/cputlb.c b/cputlb.c > index 0c9b77b..1bee47d 100644 > --- a/cputlb.c > +++ b/cputlb.c > @@ -498,6 +498,43 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, > target_ulong addr) > return qemu_ram_addr_from_host_nofail(p); > } > > +static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry, > + target_ulong addr, uintptr_t retaddr, int size) > +{ > +CPUState *cpu = ENV_GET_CPU(env); > +hwaddr physaddr = iotlbentry->addr; > +MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); > +uint64_t val; > + > +physaddr = (physaddr & TARGET_PAGE_MASK) + addr; > +cpu->mem_io_pc = retaddr; > +if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { > +cpu_io_recompile(cpu, retaddr); > +} > + > +cpu->mem_io_vaddr = addr; > +memory_region_dispatch_read(mr, physaddr, , size, iotlbentry->attrs); > +return val; > +} > + > +static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry, > + uint64_t val, target_ulong addr, > + uintptr_t retaddr, int size) > +{ > +CPUState *cpu = ENV_GET_CPU(env); > +hwaddr physaddr = iotlbentry->addr; > +MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); > + > +physaddr = (physaddr & TARGET_PAGE_MASK) + addr; > +if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { > +cpu_io_recompile(cpu, retaddr); > +} > + > +cpu->mem_io_vaddr = addr; > +cpu->mem_io_pc = retaddr; > +memory_region_dispatch_write(mr, physaddr, val, size, iotlbentry->attrs); > +} > + > /* Return true if ADDR is present in the victim tlb, and has been copied > back to the main tlb. */ > static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index, > diff --git a/softmmu_template.h b/softmmu_template.h > index b9532a4..035ffc8 100644 > --- a/softmmu_template.h > +++ b/softmmu_template.h > @@ -112,25 +112,12 @@ > > #ifndef SOFTMMU_CODE_ACCESS > static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, > - CPUIOTLBEntry *iotlbentry, > + size_t mmu_idx, size_t index, >target_ulong addr, >uintptr_t retaddr) > { > -uint64_t val; > -CPUState *cpu = ENV_GET_CPU(env); > -hwaddr physaddr = iotlbentry->addr; > -MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); > - > -physaddr = (physaddr & TARGET_PAGE_MASK) + addr; > -cpu->mem_io_pc = retaddr; > -if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { > -cpu_io_recompile(cpu, retaddr); > -} > - > -cpu->mem_io_vaddr = addr; > -memory_region_dispatch_read(mr, physaddr, , DATA_SIZE, > -iotlbentry->attrs); > -return val; > +CPUIOTLBEntry *iotlbentry = >iotlb[mmu_idx][index]; > +return io_readx(env, iotlbentry, addr, retaddr, DATA_SIZE); > } > #endif > > @@ -161,15 +148,13 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, > target_ulong addr, > > /* Handle an IO access. */ > if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { > -CPUIOTLBEntry *iotlbentry; > if ((addr & (DATA_SIZE - 1)) != 0) { > goto do_unaligned_access; > } > -iotlbentry = >iotlb[mmu_idx][index]; > > /* ??? Note that the io helpers always read data in the target > byte ordering. We should push the LE/BE request down into io. */ > -res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr); > +res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr); > res = TGT_LE(res); > return res; > } > @@ -230,15 +215,13 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, > target_ulong addr, > > /* Handle an IO access. */ > if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { > -CPUIOTLBEntry *iotlbentry; > if ((addr & (DATA_SIZE - 1)) != 0) { > goto do_unaligned_access; > } > -iotlbentry = >iotlb[mmu_idx][index]; > > /* ??? Note that the io helpers always read data in the target > byte ordering. We should push the LE/BE request down into io. */ > -res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr); > +res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr); > res = TGT_BE(res); > return res; > } > @@ -289,24
[Qemu-devel] [PATCH v4 11/35] cputlb: Move most of iotlb code out of line
Saves 2k code size off of a cold path. Signed-off-by: Richard Henderson--- cputlb.c | 37 + softmmu_template.h | 52 ++-- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/cputlb.c b/cputlb.c index 0c9b77b..1bee47d 100644 --- a/cputlb.c +++ b/cputlb.c @@ -498,6 +498,43 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr) return qemu_ram_addr_from_host_nofail(p); } +static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry, + target_ulong addr, uintptr_t retaddr, int size) +{ +CPUState *cpu = ENV_GET_CPU(env); +hwaddr physaddr = iotlbentry->addr; +MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); +uint64_t val; + +physaddr = (physaddr & TARGET_PAGE_MASK) + addr; +cpu->mem_io_pc = retaddr; +if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { +cpu_io_recompile(cpu, retaddr); +} + +cpu->mem_io_vaddr = addr; +memory_region_dispatch_read(mr, physaddr, , size, iotlbentry->attrs); +return val; +} + +static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry, + uint64_t val, target_ulong addr, + uintptr_t retaddr, int size) +{ +CPUState *cpu = ENV_GET_CPU(env); +hwaddr physaddr = iotlbentry->addr; +MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); + +physaddr = (physaddr & TARGET_PAGE_MASK) + addr; +if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { +cpu_io_recompile(cpu, retaddr); +} + +cpu->mem_io_vaddr = addr; +cpu->mem_io_pc = retaddr; +memory_region_dispatch_write(mr, physaddr, val, size, iotlbentry->attrs); +} + /* Return true if ADDR is present in the victim tlb, and has been copied back to the main tlb. */ static bool victim_tlb_hit(CPUArchState *env, size_t mmu_idx, size_t index, diff --git a/softmmu_template.h b/softmmu_template.h index b9532a4..035ffc8 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -112,25 +112,12 @@ #ifndef SOFTMMU_CODE_ACCESS static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env, - CPUIOTLBEntry *iotlbentry, + size_t mmu_idx, size_t index, target_ulong addr, uintptr_t retaddr) { -uint64_t val; -CPUState *cpu = ENV_GET_CPU(env); -hwaddr physaddr = iotlbentry->addr; -MemoryRegion *mr = iotlb_to_region(cpu, physaddr, iotlbentry->attrs); - -physaddr = (physaddr & TARGET_PAGE_MASK) + addr; -cpu->mem_io_pc = retaddr; -if (mr != _mem_rom && mr != _mem_notdirty && !cpu->can_do_io) { -cpu_io_recompile(cpu, retaddr); -} - -cpu->mem_io_vaddr = addr; -memory_region_dispatch_read(mr, physaddr, , DATA_SIZE, -iotlbentry->attrs); -return val; +CPUIOTLBEntry *iotlbentry = >iotlb[mmu_idx][index]; +return io_readx(env, iotlbentry, addr, retaddr, DATA_SIZE); } #endif @@ -161,15 +148,13 @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr, /* Handle an IO access. */ if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { -CPUIOTLBEntry *iotlbentry; if ((addr & (DATA_SIZE - 1)) != 0) { goto do_unaligned_access; } -iotlbentry = >iotlb[mmu_idx][index]; /* ??? Note that the io helpers always read data in the target byte ordering. We should push the LE/BE request down into io. */ -res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr); +res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr); res = TGT_LE(res); return res; } @@ -230,15 +215,13 @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr, /* Handle an IO access. */ if (unlikely(tlb_addr & ~TARGET_PAGE_MASK)) { -CPUIOTLBEntry *iotlbentry; if ((addr & (DATA_SIZE - 1)) != 0) { goto do_unaligned_access; } -iotlbentry = >iotlb[mmu_idx][index]; /* ??? Note that the io helpers always read data in the target byte ordering. We should push the LE/BE request down into io. */ -res = glue(io_read, SUFFIX)(env, iotlbentry, addr, retaddr); +res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr); res = TGT_BE(res); return res; } @@ -289,24 +272,13 @@ WORD_TYPE helper_be_lds_name(CPUArchState *env, target_ulong addr, #endif static inline void glue(io_write, SUFFIX)(CPUArchState *env, - CPUIOTLBEntry *iotlbentry, + size_t mmu_idx, size_t index,