qemu/include/exec/cpu_ldst_template.h
<<
>>
Prefs
   1/*
   2 *  Software MMU support
   3 *
   4 * Generate inline load/store functions for one MMU mode and data
   5 * size.
   6 *
   7 * Generate a store function as well as signed and unsigned loads.
   8 *
   9 * Not used directly but included from cpu_ldst.h.
  10 *
  11 *  Copyright (c) 2003 Fabrice Bellard
  12 *
  13 * This library is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU Lesser General Public
  15 * License as published by the Free Software Foundation; either
  16 * version 2 of the License, or (at your option) any later version.
  17 *
  18 * This library is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  21 * Lesser General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU Lesser General Public
  24 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  25 */
  26#if DATA_SIZE == 8
  27#define SUFFIX q
  28#define USUFFIX q
  29#define DATA_TYPE uint64_t
  30#define SHIFT 3
  31#elif DATA_SIZE == 4
  32#define SUFFIX l
  33#define USUFFIX l
  34#define DATA_TYPE uint32_t
  35#define SHIFT 2
  36#elif DATA_SIZE == 2
  37#define SUFFIX w
  38#define USUFFIX uw
  39#define DATA_TYPE uint16_t
  40#define DATA_STYPE int16_t
  41#define SHIFT 1
  42#elif DATA_SIZE == 1
  43#define SUFFIX b
  44#define USUFFIX ub
  45#define DATA_TYPE uint8_t
  46#define DATA_STYPE int8_t
  47#define SHIFT 0
  48#else
  49#error unsupported data size
  50#endif
  51
  52#if DATA_SIZE == 8
  53#define RES_TYPE uint64_t
  54#else
  55#define RES_TYPE uint32_t
  56#endif
  57
  58#ifdef SOFTMMU_CODE_ACCESS
  59#define ADDR_READ addr_code
  60#define MMUSUFFIX _cmmu
  61#define URETSUFFIX SUFFIX
  62#define SRETSUFFIX SUFFIX
  63#else
  64#define ADDR_READ addr_read
  65#define MMUSUFFIX _mmu
  66#define URETSUFFIX USUFFIX
  67#define SRETSUFFIX glue(s, SUFFIX)
  68#endif
  69
  70/* generic load/store macros */
  71
  72static inline RES_TYPE
  73glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
  74                                                  target_ulong ptr,
  75                                                  uintptr_t retaddr)
  76{
  77    int page_index;
  78    RES_TYPE res;
  79    target_ulong addr;
  80    int mmu_idx;
  81    TCGMemOpIdx oi;
  82
  83    addr = ptr;
  84    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  85    mmu_idx = CPU_MMU_INDEX;
  86    if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
  87                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
  88        oi = make_memop_idx(SHIFT, mmu_idx);
  89        res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
  90                                                            oi, retaddr);
  91    } else {
  92        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
  93        res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
  94    }
  95    return res;
  96}
  97
  98static inline RES_TYPE
  99glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 100{
 101    return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
 102}
 103
 104#if DATA_SIZE <= 2
 105static inline int
 106glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
 107                                                  target_ulong ptr,
 108                                                  uintptr_t retaddr)
 109{
 110    int res, page_index;
 111    target_ulong addr;
 112    int mmu_idx;
 113    TCGMemOpIdx oi;
 114
 115    addr = ptr;
 116    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 117    mmu_idx = CPU_MMU_INDEX;
 118    if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
 119                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
 120        oi = make_memop_idx(SHIFT, mmu_idx);
 121        res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
 122                               MMUSUFFIX)(env, addr, oi, retaddr);
 123    } else {
 124        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
 125        res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
 126    }
 127    return res;
 128}
 129
 130static inline int
 131glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
 132{
 133    return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
 134}
 135#endif
 136
 137#ifndef SOFTMMU_CODE_ACCESS
 138
 139/* generic store macro */
 140
 141static inline void
 142glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
 143                                                 target_ulong ptr,
 144                                                 RES_TYPE v, uintptr_t retaddr)
 145{
 146    int page_index;
 147    target_ulong addr;
 148    int mmu_idx;
 149    TCGMemOpIdx oi;
 150
 151    addr = ptr;
 152    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
 153    mmu_idx = CPU_MMU_INDEX;
 154    if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
 155                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
 156        oi = make_memop_idx(SHIFT, mmu_idx);
 157        glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
 158                                                     retaddr);
 159    } else {
 160        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
 161        glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
 162    }
 163}
 164
 165static inline void
 166glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
 167                                      RES_TYPE v)
 168{
 169    glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
 170}
 171
 172#endif /* !SOFTMMU_CODE_ACCESS */
 173
 174#undef RES_TYPE
 175#undef DATA_TYPE
 176#undef DATA_STYPE
 177#undef SUFFIX
 178#undef USUFFIX
 179#undef DATA_SIZE
 180#undef MMUSUFFIX
 181#undef ADDR_READ
 182#undef URETSUFFIX
 183#undef SRETSUFFIX
 184#undef SHIFT
 185