Annotation of qemu/softmmu_header.h, revision 1.1.1.9

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: 
1.1.1.9 ! root       81: #ifndef CONFIG_TCG_PASS_AREG0
        !            82: #define ENV_PARAM
        !            83: #define ENV_VAR
        !            84: #define CPU_PREFIX
        !            85: #define HELPER_PREFIX __
        !            86: #else
        !            87: #define ENV_PARAM CPUArchState *env,
        !            88: #define ENV_VAR env,
        !            89: #define CPU_PREFIX cpu_
        !            90: #define HELPER_PREFIX helper_
        !            91: #endif
        !            92: 
1.1       root       93: /* generic load/store macros */
                     94: 
1.1.1.9 ! root       95: static inline RES_TYPE
        !            96: glue(glue(glue(CPU_PREFIX, ld), USUFFIX), MEMSUFFIX)(ENV_PARAM
        !            97:                                                      target_ulong ptr)
1.1       root       98: {
1.1.1.5   root       99:     int page_index;
1.1       root      100:     RES_TYPE res;
                    101:     target_ulong addr;
1.1.1.4   root      102:     int mmu_idx;
1.1       root      103: 
                    104:     addr = ptr;
1.1.1.5   root      105:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root      106:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root      107:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                    108:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.9 ! root      109:         res = glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_VAR
        !           110:                                                                      addr,
        !           111:                                                                      mmu_idx);
1.1       root      112:     } else {
1.1.1.9 ! root      113:         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
        !           114:         res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
1.1       root      115:     }
                    116:     return res;
                    117: }
                    118: 
                    119: #if DATA_SIZE <= 2
1.1.1.9 ! root      120: static inline int
        !           121: glue(glue(glue(CPU_PREFIX, lds), SUFFIX), MEMSUFFIX)(ENV_PARAM
        !           122:                                                      target_ulong ptr)
1.1       root      123: {
1.1.1.5   root      124:     int res, page_index;
1.1       root      125:     target_ulong addr;
1.1.1.4   root      126:     int mmu_idx;
1.1       root      127: 
                    128:     addr = ptr;
1.1.1.5   root      129:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root      130:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root      131:     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                    132:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.9 ! root      133:         res = (DATA_STYPE)glue(glue(glue(HELPER_PREFIX, ld), SUFFIX),
        !           134:                                MMUSUFFIX)(ENV_VAR addr, mmu_idx);
1.1       root      135:     } else {
1.1.1.9 ! root      136:         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
        !           137:         res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
1.1       root      138:     }
                    139:     return res;
                    140: }
                    141: #endif
                    142: 
1.1.1.4   root      143: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
1.1.1.2   root      144: 
1.1       root      145: /* generic store macro */
                    146: 
1.1.1.9 ! root      147: static inline void
        !           148: glue(glue(glue(CPU_PREFIX, st), SUFFIX), MEMSUFFIX)(ENV_PARAM target_ulong ptr,
        !           149:                                                     RES_TYPE v)
1.1       root      150: {
1.1.1.5   root      151:     int page_index;
1.1       root      152:     target_ulong addr;
1.1.1.4   root      153:     int mmu_idx;
1.1       root      154: 
                    155:     addr = ptr;
1.1.1.5   root      156:     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1.1.1.4   root      157:     mmu_idx = CPU_MMU_INDEX;
1.1.1.5   root      158:     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
                    159:                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
1.1.1.9 ! root      160:         glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_VAR addr, v,
        !           161:                                                                mmu_idx);
1.1       root      162:     } else {
1.1.1.9 ! root      163:         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
        !           164:         glue(glue(st, SUFFIX), _raw)(hostaddr, v);
1.1       root      165:     }
                    166: }
                    167: 
1.1.1.4   root      168: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
1.1.1.2   root      169: 
1.1.1.4   root      170: #if ACCESS_TYPE != (NB_MMU_MODES + 1)
1.1       root      171: 
                    172: #if DATA_SIZE == 8
1.1.1.9 ! root      173: static inline float64 glue(glue(CPU_PREFIX, ldfq), MEMSUFFIX)(ENV_PARAM
        !           174:                                                               target_ulong ptr)
1.1       root      175: {
                    176:     union {
1.1.1.2   root      177:         float64 d;
1.1       root      178:         uint64_t i;
                    179:     } u;
1.1.1.9 ! root      180:     u.i = glue(glue(CPU_PREFIX, ldq), MEMSUFFIX)(ENV_VAR ptr);
1.1       root      181:     return u.d;
                    182: }
                    183: 
1.1.1.9 ! root      184: static inline void glue(glue(CPU_PREFIX, stfq), MEMSUFFIX)(ENV_PARAM
        !           185:                                                            target_ulong ptr,
        !           186:                                                            float64 v)
1.1       root      187: {
                    188:     union {
1.1.1.2   root      189:         float64 d;
1.1       root      190:         uint64_t i;
                    191:     } u;
                    192:     u.d = v;
1.1.1.9 ! root      193:     glue(glue(CPU_PREFIX, stq), MEMSUFFIX)(ENV_VAR ptr, u.i);
1.1       root      194: }
                    195: #endif /* DATA_SIZE == 8 */
                    196: 
                    197: #if DATA_SIZE == 4
1.1.1.9 ! root      198: static inline float32 glue(glue(CPU_PREFIX, ldfl), MEMSUFFIX)(ENV_PARAM
        !           199:                                                               target_ulong ptr)
1.1       root      200: {
                    201:     union {
1.1.1.2   root      202:         float32 f;
1.1       root      203:         uint32_t i;
                    204:     } u;
1.1.1.9 ! root      205:     u.i = glue(glue(CPU_PREFIX, ldl), MEMSUFFIX)(ENV_VAR ptr);
1.1       root      206:     return u.f;
                    207: }
                    208: 
1.1.1.9 ! root      209: static inline void glue(glue(CPU_PREFIX, stfl), MEMSUFFIX)(ENV_PARAM
        !           210:                                                            target_ulong ptr,
        !           211:                                                            float32 v)
1.1       root      212: {
                    213:     union {
1.1.1.2   root      214:         float32 f;
1.1       root      215:         uint32_t i;
                    216:     } u;
                    217:     u.f = v;
1.1.1.9 ! root      218:     glue(glue(CPU_PREFIX, stl), MEMSUFFIX)(ENV_VAR ptr, u.i);
1.1       root      219: }
                    220: #endif /* DATA_SIZE == 4 */
                    221: 
1.1.1.4   root      222: #endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
1.1.1.2   root      223: 
1.1       root      224: #undef RES_TYPE
                    225: #undef DATA_TYPE
                    226: #undef DATA_STYPE
                    227: #undef SUFFIX
                    228: #undef USUFFIX
                    229: #undef DATA_SIZE
1.1.1.4   root      230: #undef CPU_MMU_INDEX
1.1       root      231: #undef MMUSUFFIX
1.1.1.2   root      232: #undef ADDR_READ
1.1.1.9 ! root      233: #undef ENV_PARAM
        !           234: #undef ENV_VAR
        !           235: #undef CPU_PREFIX
        !           236: #undef HELPER_PREFIX

unix.superglobalmegacorp.com