Annotation of qemu/softmmu_header.h, revision 1.1.1.8

1.1       root        1: /*
                      2:  *  Software MMU support
1.1.1.4   root        3:  *
1.1.1.8 ! root        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:  *
1.1       root       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
1.1.1.6   root       26:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       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: 
1.1.1.4   root       50: #if ACCESS_TYPE < (NB_MMU_MODES)
1.1       root       51: 
1.1.1.4   root       52: #define CPU_MMU_INDEX ACCESS_TYPE
1.1       root       53: #define MMUSUFFIX _mmu
                     54: 
1.1.1.4   root       55: #elif ACCESS_TYPE == (NB_MMU_MODES)
1.1       root       56: 
1.1.1.4   root       57: #define CPU_MMU_INDEX (cpu_mmu_index(env))
1.1       root       58: #define MMUSUFFIX _mmu
                     59: 
1.1.1.4   root       60: #elif ACCESS_TYPE == (NB_MMU_MODES + 1)
1.1       root       61: 
1.1.1.4   root       62: #define CPU_MMU_INDEX (cpu_mmu_index(env))
1.1       root       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
1.1.1.7   root       72: #define RES_TYPE uint32_t
1.1       root       73: #endif
                     74: 
1.1.1.4   root       75: #if ACCESS_TYPE == (NB_MMU_MODES + 1)
1.1.1.2   root       76: #define ADDR_READ addr_code
                     77: #else
                     78: #define ADDR_READ addr_read
                     79: #endif
1.1       root       80: 
                     81: /* generic load/store macros */
                     82: 
                     83: static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
                     84: {
1.1.1.5   root       85:     int page_index;
1.1       root       86:     RES_TYPE res;
                     87:     target_ulong addr;
                     88:     unsigned long physaddr;
1.1.1.4   root       89:     int mmu_idx;
1.1       root       90: 
                     91:     addr = ptr;
1.1.1.5   root       92:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root       93:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root       94:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                     95:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.4   root       96:         res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
1.1       root       97:     } else {
1.1.1.5   root       98:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
1.1       root       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: {
1.1.1.5   root      107:     int res, page_index;
1.1       root      108:     target_ulong addr;
                    109:     unsigned long physaddr;
1.1.1.4   root      110:     int mmu_idx;
1.1       root      111: 
                    112:     addr = ptr;
1.1.1.5   root      113:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root      114:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root      115:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                    116:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.4   root      117:         res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
1.1       root      118:     } else {
1.1.1.5   root      119:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
1.1       root      120:         res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
                    121:     }
                    122:     return res;
                    123: }
                    124: #endif
                    125: 
1.1.1.4   root      126: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
1.1.1.2   root      127: 
1.1       root      128: /* generic store macro */
                    129: 
                    130: static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
                    131: {
1.1.1.5   root      132:     int page_index;
1.1       root      133:     target_ulong addr;
                    134:     unsigned long physaddr;
1.1.1.4   root      135:     int mmu_idx;
1.1       root      136: 
                    137:     addr = ptr;
1.1.1.5   root      138:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root      139:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root      140:     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
                    141:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.4   root      142:         glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
1.1       root      143:     } else {
1.1.1.5   root      144:         physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
1.1       root      145:         glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
                    146:     }
                    147: }
                    148: 
1.1.1.4   root      149: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
1.1.1.2   root      150: 
1.1.1.4   root      151: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
1.1       root      152: 
                    153: #if DATA_SIZE == 8
1.1.1.2   root      154: static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
1.1       root      155: {
                    156:     union {
1.1.1.2   root      157:         float64 d;
1.1       root      158:         uint64_t i;
                    159:     } u;
                    160:     u.i = glue(ldq, MEMSUFFIX)(ptr);
                    161:     return u.d;
                    162: }
                    163: 
1.1.1.2   root      164: static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
1.1       root      165: {
                    166:     union {
1.1.1.2   root      167:         float64 d;
1.1       root      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
1.1.1.2   root      176: static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
1.1       root      177: {
                    178:     union {
1.1.1.2   root      179:         float32 f;
1.1       root      180:         uint32_t i;
                    181:     } u;
                    182:     u.i = glue(ldl, MEMSUFFIX)(ptr);
                    183:     return u.f;
                    184: }
                    185: 
1.1.1.2   root      186: static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
1.1       root      187: {
                    188:     union {
1.1.1.2   root      189:         float32 f;
1.1       root      190:         uint32_t i;
                    191:     } u;
                    192:     u.f = v;
                    193:     glue(stl, MEMSUFFIX)(ptr, u.i);
                    194: }
                    195: #endif /* DATA_SIZE == 4 */
                    196: 
1.1.1.4   root      197: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
1.1.1.2   root      198: 
1.1       root      199: #undef RES_TYPE
                    200: #undef DATA_TYPE
                    201: #undef DATA_STYPE
                    202: #undef SUFFIX
                    203: #undef USUFFIX
                    204: #undef DATA_SIZE
1.1.1.4   root      205: #undef CPU_MMU_INDEX
1.1       root      206: #undef MMUSUFFIX
1.1.1.2   root      207: #undef ADDR_READ

unix.superglobalmegacorp.com