File:  [Qemu by Fabrice Bellard] / qemu / softmmu_header.h
Revision 1.1.1.8 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:17:13 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    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. For
    8:  * 32 and 64 bit cases, also generate floating point functions with
    9:  * the same size.
   10:  *
   11:  * Not used directly but included from softmmu_exec.h and exec-all.h.
   12:  *
   13:  *  Copyright (c) 2003 Fabrice Bellard
   14:  *
   15:  * This library is free software; you can redistribute it and/or
   16:  * modify it under the terms of the GNU Lesser General Public
   17:  * License as published by the Free Software Foundation; either
   18:  * version 2 of the License, or (at your option) any later version.
   19:  *
   20:  * This library is distributed in the hope that it will be useful,
   21:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   23:  * Lesser General Public License for more details.
   24:  *
   25:  * You should have received a copy of the GNU Lesser General Public
   26:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
   27:  */
   28: #if DATA_SIZE == 8
   29: #define SUFFIX q
   30: #define USUFFIX q
   31: #define DATA_TYPE uint64_t
   32: #elif DATA_SIZE == 4
   33: #define SUFFIX l
   34: #define USUFFIX l
   35: #define DATA_TYPE uint32_t
   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: #elif DATA_SIZE == 1
   42: #define SUFFIX b
   43: #define USUFFIX ub
   44: #define DATA_TYPE uint8_t
   45: #define DATA_STYPE int8_t
   46: #else
   47: #error unsupported data size
   48: #endif
   49: 
   50: #if ACCESS_TYPE < (NB_MMU_MODES)
   51: 
   52: #define CPU_MMU_INDEX ACCESS_TYPE
   53: #define MMUSUFFIX _mmu
   54: 
   55: #elif ACCESS_TYPE == (NB_MMU_MODES)
   56: 
   57: #define CPU_MMU_INDEX (cpu_mmu_index(env))
   58: #define MMUSUFFIX _mmu
   59: 
   60: #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
   61: 
   62: #define CPU_MMU_INDEX (cpu_mmu_index(env))
   63: #define MMUSUFFIX _cmmu
   64: 
   65: #else
   66: #error invalid ACCESS_TYPE
   67: #endif
   68: 
   69: #if DATA_SIZE == 8
   70: #define RES_TYPE uint64_t
   71: #else
   72: #define RES_TYPE uint32_t
   73: #endif
   74: 
   75: #if ACCESS_TYPE == (NB_MMU_MODES + 1)
   76: #define ADDR_READ addr_code
   77: #else
   78: #define ADDR_READ addr_read
   79: #endif
   80: 
   81: /* generic load/store macros */
   82: 
   83: static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
   84: {
   85:     int page_index;
   86:     RES_TYPE res;
   87:     target_ulong addr;
   88:     unsigned long physaddr;
   89:     int mmu_idx;
   90: 
   91:     addr = ptr;
   92:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
   93:     mmu_idx = CPU_MMU_INDEX;
   94:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
   95:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
   96:         res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
   97:     } else {
   98:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
   99:         res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
  100:     }
  101:     return res;
  102: }
  103: 
  104: #if DATA_SIZE <= 2
  105: static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
  106: {
  107:     int res, page_index;
  108:     target_ulong addr;
  109:     unsigned long physaddr;
  110:     int mmu_idx;
  111: 
  112:     addr = ptr;
  113:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  114:     mmu_idx = CPU_MMU_INDEX;
  115:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
  116:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
  117:         res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
  118:     } else {
  119:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
  120:         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
  121:     }
  122:     return res;
  123: }
  124: #endif
  125: 
  126: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
  127: 
  128: /* generic store macro */
  129: 
  130: static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
  131: {
  132:     int page_index;
  133:     target_ulong addr;
  134:     unsigned long physaddr;
  135:     int mmu_idx;
  136: 
  137:     addr = ptr;
  138:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
  139:     mmu_idx = CPU_MMU_INDEX;
  140:     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
  141:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
  142:         glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
  143:     } else {
  144:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
  145:         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
  146:     }
  147: }
  148: 
  149: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
  150: 
  151: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
  152: 
  153: #if DATA_SIZE == 8
  154: static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
  155: {
  156:     union {
  157:         float64 d;
  158:         uint64_t i;
  159:     } u;
  160:     u.i = glue(ldq, MEMSUFFIX)(ptr);
  161:     return u.d;
  162: }
  163: 
  164: static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
  165: {
  166:     union {
  167:         float64 d;
  168:         uint64_t i;
  169:     } u;
  170:     u.d = v;
  171:     glue(stq, MEMSUFFIX)(ptr, u.i);
  172: }
  173: #endif /* DATA_SIZE == 8 */
  174: 
  175: #if DATA_SIZE == 4
  176: static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
  177: {
  178:     union {
  179:         float32 f;
  180:         uint32_t i;
  181:     } u;
  182:     u.i = glue(ldl, MEMSUFFIX)(ptr);
  183:     return u.f;
  184: }
  185: 
  186: static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
  187: {
  188:     union {
  189:         float32 f;
  190:         uint32_t i;
  191:     } u;
  192:     u.f = v;
  193:     glue(stl, MEMSUFFIX)(ptr, u.i);
  194: }
  195: #endif /* DATA_SIZE == 4 */
  196: 
  197: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
  198: 
  199: #undef RES_TYPE
  200: #undef DATA_TYPE
  201: #undef DATA_STYPE
  202: #undef SUFFIX
  203: #undef USUFFIX
  204: #undef DATA_SIZE
  205: #undef CPU_MMU_INDEX
  206: #undef MMUSUFFIX
  207: #undef ADDR_READ

unix.superglobalmegacorp.com