Statistics
| Branch: | Revision:

root / include / exec / softmmu_header.h @ ce603d8e

History | View | Annotate | Download (5.5 kB)

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
84
glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
85
{
86
    int page_index;
87
    RES_TYPE res;
88
    target_ulong addr;
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(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
97
    } else {
98
        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
99
        res = glue(glue(ld, USUFFIX), _raw)(hostaddr);
100
    }
101
    return res;
102
}
103

    
104
#if DATA_SIZE <= 2
105
static inline int
106
glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
107
{
108
    int res, page_index;
109
    target_ulong addr;
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(helper_ld, SUFFIX),
118
                               MMUSUFFIX)(env, addr, mmu_idx);
119
    } else {
120
        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
121
        res = glue(glue(lds, SUFFIX), _raw)(hostaddr);
122
    }
123
    return res;
124
}
125
#endif
126

    
127
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
128

    
129
/* generic store macro */
130

    
131
static inline void
132
glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
133
                                      RES_TYPE v)
134
{
135
    int page_index;
136
    target_ulong addr;
137
    int mmu_idx;
138

    
139
    addr = ptr;
140
    page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
141
    mmu_idx = CPU_MMU_INDEX;
142
    if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
143
                 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
144
        glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
145
    } else {
146
        uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
147
        glue(glue(st, SUFFIX), _raw)(hostaddr, v);
148
    }
149
}
150

    
151
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
152

    
153
#if ACCESS_TYPE != (NB_MMU_MODES + 1)
154

    
155
#if DATA_SIZE == 8
156
static inline float64 glue(cpu_ldfq, MEMSUFFIX)(CPUArchState *env,
157
                                                target_ulong ptr)
158
{
159
    union {
160
        float64 d;
161
        uint64_t i;
162
    } u;
163
    u.i = glue(cpu_ldq, MEMSUFFIX)(env, ptr);
164
    return u.d;
165
}
166

    
167
static inline void glue(cpu_stfq, MEMSUFFIX)(CPUArchState *env,
168
                                             target_ulong ptr, float64 v)
169
{
170
    union {
171
        float64 d;
172
        uint64_t i;
173
    } u;
174
    u.d = v;
175
    glue(cpu_stq, MEMSUFFIX)(env, ptr, u.i);
176
}
177
#endif /* DATA_SIZE == 8 */
178

    
179
#if DATA_SIZE == 4
180
static inline float32 glue(cpu_ldfl, MEMSUFFIX)(CPUArchState *env,
181
                                                target_ulong ptr)
182
{
183
    union {
184
        float32 f;
185
        uint32_t i;
186
    } u;
187
    u.i = glue(cpu_ldl, MEMSUFFIX)(env, ptr);
188
    return u.f;
189
}
190

    
191
static inline void glue(cpu_stfl, MEMSUFFIX)(CPUArchState *env,
192
                                             target_ulong ptr, float32 v)
193
{
194
    union {
195
        float32 f;
196
        uint32_t i;
197
    } u;
198
    u.f = v;
199
    glue(cpu_stl, MEMSUFFIX)(env, ptr, u.i);
200
}
201
#endif /* DATA_SIZE == 4 */
202

    
203
#endif /* ACCESS_TYPE != (NB_MMU_MODES + 1) */
204

    
205
#undef RES_TYPE
206
#undef DATA_TYPE
207
#undef DATA_STYPE
208
#undef SUFFIX
209
#undef USUFFIX
210
#undef DATA_SIZE
211
#undef CPU_MMU_INDEX
212
#undef MMUSUFFIX
213
#undef ADDR_READ