softmmu_header.h 4.79 KB
Newer Older
1 2
/*
 *  Software MMU support
3
 *
4 5 6 7 8 9 10 11 12 13 14 15 16
 *  Copyright (c) 2003 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 19 20
 */
#if DATA_SIZE == 8
#define SUFFIX q
bellard's avatar
bellard committed
21
#define USUFFIX q
22 23 24
#define DATA_TYPE uint64_t
#elif DATA_SIZE == 4
#define SUFFIX l
bellard's avatar
bellard committed
25
#define USUFFIX l
26 27 28
#define DATA_TYPE uint32_t
#elif DATA_SIZE == 2
#define SUFFIX w
bellard's avatar
bellard committed
29
#define USUFFIX uw
30 31 32 33
#define DATA_TYPE uint16_t
#define DATA_STYPE int16_t
#elif DATA_SIZE == 1
#define SUFFIX b
bellard's avatar
bellard committed
34
#define USUFFIX ub
35 36 37 38 39 40
#define DATA_TYPE uint8_t
#define DATA_STYPE int8_t
#else
#error unsupported data size
#endif

41
#if ACCESS_TYPE < (NB_MMU_MODES)
bellard's avatar
bellard committed
42

43
#define CPU_MMU_INDEX ACCESS_TYPE
bellard's avatar
bellard committed
44 45
#define MMUSUFFIX _mmu

46
#elif ACCESS_TYPE == (NB_MMU_MODES)
bellard's avatar
bellard committed
47

48
#define CPU_MMU_INDEX (cpu_mmu_index(env))
bellard's avatar
bellard committed
49 50
#define MMUSUFFIX _mmu

51
#elif ACCESS_TYPE == (NB_MMU_MODES + 1)
bellard's avatar
bellard committed
52

53
#define CPU_MMU_INDEX (cpu_mmu_index(env))
bellard's avatar
bellard committed
54 55
#define MMUSUFFIX _cmmu

56
#else
bellard's avatar
bellard committed
57
#error invalid ACCESS_TYPE
58 59 60 61 62 63 64 65
#endif

#if DATA_SIZE == 8
#define RES_TYPE uint64_t
#else
#define RES_TYPE int
#endif

66
#if ACCESS_TYPE == (NB_MMU_MODES + 1)
bellard's avatar
bellard committed
67 68 69 70
#define ADDR_READ addr_code
#else
#define ADDR_READ addr_read
#endif
71

bellard's avatar
bellard committed
72 73
/* generic load/store macros */

bellard's avatar
bellard committed
74
static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(target_ulong ptr)
75
{
76
    int page_index;
77
    RES_TYPE res;
bellard's avatar
bellard committed
78 79
    target_ulong addr;
    unsigned long physaddr;
80
    int mmu_idx;
bellard's avatar
bellard committed
81

bellard's avatar
bellard committed
82
    addr = ptr;
83
    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
84
    mmu_idx = CPU_MMU_INDEX;
85 86
    if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
87
        res = glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
88
    } else {
89
        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
bellard's avatar
bellard committed
90
        res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)physaddr);
91 92 93 94 95
    }
    return res;
}

#if DATA_SIZE <= 2
bellard's avatar
bellard committed
96
static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(target_ulong ptr)
97
{
98
    int res, page_index;
bellard's avatar
bellard committed
99 100
    target_ulong addr;
    unsigned long physaddr;
101
    int mmu_idx;
bellard's avatar
bellard committed
102

bellard's avatar
bellard committed
103
    addr = ptr;
104
    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
105
    mmu_idx = CPU_MMU_INDEX;
106 107
    if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
108
        res = (DATA_STYPE)glue(glue(__ld, SUFFIX), MMUSUFFIX)(addr, mmu_idx);
109
    } else {
110
        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
111 112 113 114 115 116
        res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr);
    }
    return res;
}
#endif

117
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
bellard's avatar
bellard committed
118

bellard's avatar
bellard committed
119 120
/* generic store macro */

bellard's avatar
bellard committed
121
static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(target_ulong ptr, RES_TYPE v)
122
{
123
    int page_index;
bellard's avatar
bellard committed
124 125
    target_ulong addr;
    unsigned long physaddr;
126
    int mmu_idx;
bellard's avatar
bellard committed
127

bellard's avatar
bellard committed
128
    addr = ptr;
129
    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
130
    mmu_idx = CPU_MMU_INDEX;
131 132
    if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
133
        glue(glue(__st, SUFFIX), MMUSUFFIX)(addr, v, mmu_idx);
134
    } else {
135
        physaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
136 137 138 139
        glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v);
    }
}

140
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
bellard's avatar
bellard committed
141

142
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
bellard's avatar
bellard committed
143

bellard's avatar
bellard committed
144
#if DATA_SIZE == 8
145
static inline float64 glue(ldfq, MEMSUFFIX)(target_ulong ptr)
bellard's avatar
bellard committed
146 147
{
    union {
148
        float64 d;
bellard's avatar
bellard committed
149 150 151 152 153 154
        uint64_t i;
    } u;
    u.i = glue(ldq, MEMSUFFIX)(ptr);
    return u.d;
}

155
static inline void glue(stfq, MEMSUFFIX)(target_ulong ptr, float64 v)
bellard's avatar
bellard committed
156 157
{
    union {
158
        float64 d;
bellard's avatar
bellard committed
159 160 161 162 163 164 165 166
        uint64_t i;
    } u;
    u.d = v;
    glue(stq, MEMSUFFIX)(ptr, u.i);
}
#endif /* DATA_SIZE == 8 */

#if DATA_SIZE == 4
167
static inline float32 glue(ldfl, MEMSUFFIX)(target_ulong ptr)
bellard's avatar
bellard committed
168 169
{
    union {
170
        float32 f;
bellard's avatar
bellard committed
171 172 173 174 175 176
        uint32_t i;
    } u;
    u.i = glue(ldl, MEMSUFFIX)(ptr);
    return u.f;
}

177
static inline void glue(stfl, MEMSUFFIX)(target_ulong ptr, float32 v)
bellard's avatar
bellard committed
178 179
{
    union {
180
        float32 f;
bellard's avatar
bellard committed
181 182 183 184 185 186 187
        uint32_t i;
    } u;
    u.f = v;
    glue(stl, MEMSUFFIX)(ptr, u.i);
}
#endif /* DATA_SIZE == 4 */

188
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
bellard's avatar
bellard committed
189

190 191 192 193
#undef RES_TYPE
#undef DATA_TYPE
#undef DATA_STYPE
#undef SUFFIX
bellard's avatar
bellard committed
194
#undef USUFFIX
195
#undef DATA_SIZE
196
#undef CPU_MMU_INDEX
bellard's avatar
bellard committed
197
#undef MMUSUFFIX
bellard's avatar
bellard committed
198
#undef ADDR_READ