Statistics
| Branch: | Revision:

root / softmmu_template.h @ ef5b2344

History | View | Annotate | Download (13.1 kB)

1 b92e5a22 bellard
/*
2 b92e5a22 bellard
 *  Software MMU support
3 5fafdf24 ths
 *
4 efbf29b6 Blue Swirl
 * Generate helpers used by TCG for qemu_ld/st ops and code load
5 efbf29b6 Blue Swirl
 * functions.
6 efbf29b6 Blue Swirl
 *
7 efbf29b6 Blue Swirl
 * Included from target op helpers and exec.c.
8 efbf29b6 Blue Swirl
 *
9 b92e5a22 bellard
 *  Copyright (c) 2003 Fabrice Bellard
10 b92e5a22 bellard
 *
11 b92e5a22 bellard
 * This library is free software; you can redistribute it and/or
12 b92e5a22 bellard
 * modify it under the terms of the GNU Lesser General Public
13 b92e5a22 bellard
 * License as published by the Free Software Foundation; either
14 b92e5a22 bellard
 * version 2 of the License, or (at your option) any later version.
15 b92e5a22 bellard
 *
16 b92e5a22 bellard
 * This library is distributed in the hope that it will be useful,
17 b92e5a22 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 b92e5a22 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 b92e5a22 bellard
 * Lesser General Public License for more details.
20 b92e5a22 bellard
 *
21 b92e5a22 bellard
 * You should have received a copy of the GNU Lesser General Public
22 8167ee88 Blue Swirl
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 b92e5a22 bellard
 */
24 29e922b6 Blue Swirl
#include "qemu-timer.h"
25 0e0df1e2 Avi Kivity
#include "memory.h"
26 29e922b6 Blue Swirl
27 b92e5a22 bellard
#define DATA_SIZE (1 << SHIFT)
28 b92e5a22 bellard
29 b92e5a22 bellard
#if DATA_SIZE == 8
30 b92e5a22 bellard
#define SUFFIX q
31 61382a50 bellard
#define USUFFIX q
32 b92e5a22 bellard
#define DATA_TYPE uint64_t
33 b92e5a22 bellard
#elif DATA_SIZE == 4
34 b92e5a22 bellard
#define SUFFIX l
35 61382a50 bellard
#define USUFFIX l
36 b92e5a22 bellard
#define DATA_TYPE uint32_t
37 b92e5a22 bellard
#elif DATA_SIZE == 2
38 b92e5a22 bellard
#define SUFFIX w
39 61382a50 bellard
#define USUFFIX uw
40 b92e5a22 bellard
#define DATA_TYPE uint16_t
41 b92e5a22 bellard
#elif DATA_SIZE == 1
42 b92e5a22 bellard
#define SUFFIX b
43 61382a50 bellard
#define USUFFIX ub
44 b92e5a22 bellard
#define DATA_TYPE uint8_t
45 b92e5a22 bellard
#else
46 b92e5a22 bellard
#error unsupported data size
47 b92e5a22 bellard
#endif
48 b92e5a22 bellard
49 b769d8fe bellard
#ifdef SOFTMMU_CODE_ACCESS
50 b769d8fe bellard
#define READ_ACCESS_TYPE 2
51 84b7b8e7 bellard
#define ADDR_READ addr_code
52 b769d8fe bellard
#else
53 b769d8fe bellard
#define READ_ACCESS_TYPE 0
54 84b7b8e7 bellard
#define ADDR_READ addr_read
55 b769d8fe bellard
#endif
56 b769d8fe bellard
57 e141ab52 Blue Swirl
#ifndef CONFIG_TCG_PASS_AREG0
58 e141ab52 Blue Swirl
#define ENV_PARAM
59 e141ab52 Blue Swirl
#define ENV_VAR
60 e141ab52 Blue Swirl
#define CPU_PREFIX
61 e141ab52 Blue Swirl
#define HELPER_PREFIX __
62 e141ab52 Blue Swirl
#else
63 e141ab52 Blue Swirl
#define ENV_PARAM CPUArchState *env,
64 e141ab52 Blue Swirl
#define ENV_VAR env,
65 e141ab52 Blue Swirl
#define CPU_PREFIX cpu_
66 e141ab52 Blue Swirl
#define HELPER_PREFIX helper_
67 e141ab52 Blue Swirl
#endif
68 e141ab52 Blue Swirl
69 e141ab52 Blue Swirl
static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
70 e141ab52 Blue Swirl
                                                        target_ulong addr,
71 6ebbf390 j_mayer
                                                        int mmu_idx,
72 20503968 Blue Swirl
                                                        uintptr_t retaddr);
73 e141ab52 Blue Swirl
static inline DATA_TYPE glue(io_read, SUFFIX)(ENV_PARAM
74 e141ab52 Blue Swirl
                                              target_phys_addr_t physaddr,
75 2e70f6ef pbrook
                                              target_ulong addr,
76 20503968 Blue Swirl
                                              uintptr_t retaddr)
77 b92e5a22 bellard
{
78 b92e5a22 bellard
    DATA_TYPE res;
79 37ec01d4 Avi Kivity
    MemoryRegion *mr = iotlb_to_region(physaddr);
80 37ec01d4 Avi Kivity
81 0f459d16 pbrook
    physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
82 20503968 Blue Swirl
    env->mem_io_pc = retaddr;
83 37ec01d4 Avi Kivity
    if (mr != &io_mem_ram && mr != &io_mem_rom
84 37ec01d4 Avi Kivity
        && mr != &io_mem_unassigned
85 37ec01d4 Avi Kivity
        && mr != &io_mem_notdirty
86 2e70f6ef pbrook
            && !can_do_io(env)) {
87 2e70f6ef pbrook
        cpu_io_recompile(env, retaddr);
88 2e70f6ef pbrook
    }
89 b92e5a22 bellard
90 db8886d3 aliguori
    env->mem_io_vaddr = addr;
91 b92e5a22 bellard
#if SHIFT <= 2
92 37ec01d4 Avi Kivity
    res = io_mem_read(mr, physaddr, 1 << SHIFT);
93 b92e5a22 bellard
#else
94 b92e5a22 bellard
#ifdef TARGET_WORDS_BIGENDIAN
95 37ec01d4 Avi Kivity
    res = io_mem_read(mr, physaddr, 4) << 32;
96 37ec01d4 Avi Kivity
    res |= io_mem_read(mr, physaddr + 4, 4);
97 b92e5a22 bellard
#else
98 37ec01d4 Avi Kivity
    res = io_mem_read(mr, physaddr, 4);
99 37ec01d4 Avi Kivity
    res |= io_mem_read(mr, physaddr + 4, 4) << 32;
100 b92e5a22 bellard
#endif
101 b92e5a22 bellard
#endif /* SHIFT > 2 */
102 b92e5a22 bellard
    return res;
103 b92e5a22 bellard
}
104 b92e5a22 bellard
105 b92e5a22 bellard
/* handle all cases except unaligned access which span two pages */
106 e141ab52 Blue Swirl
DATA_TYPE
107 e141ab52 Blue Swirl
glue(glue(glue(HELPER_PREFIX, ld), SUFFIX), MMUSUFFIX)(ENV_PARAM
108 e141ab52 Blue Swirl
                                                       target_ulong addr,
109 e141ab52 Blue Swirl
                                                       int mmu_idx)
110 b92e5a22 bellard
{
111 b92e5a22 bellard
    DATA_TYPE res;
112 61382a50 bellard
    int index;
113 c27004ec bellard
    target_ulong tlb_addr;
114 355b1943 Paul Brook
    target_phys_addr_t ioaddr;
115 20503968 Blue Swirl
    uintptr_t retaddr;
116 3b46e624 ths
117 b92e5a22 bellard
    /* test if there is match for unaligned or IO access */
118 b92e5a22 bellard
    /* XXX: could done more in memory macro in a non portable way */
119 b92e5a22 bellard
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
120 b92e5a22 bellard
 redo:
121 6ebbf390 j_mayer
    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
122 b92e5a22 bellard
    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
123 b92e5a22 bellard
        if (tlb_addr & ~TARGET_PAGE_MASK) {
124 b92e5a22 bellard
            /* IO access */
125 b92e5a22 bellard
            if ((addr & (DATA_SIZE - 1)) != 0)
126 b92e5a22 bellard
                goto do_unaligned_access;
127 2e70f6ef pbrook
            retaddr = GETPC();
128 37ec01d4 Avi Kivity
            ioaddr = env->iotlb[mmu_idx][index];
129 e141ab52 Blue Swirl
            res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
130 98699967 bellard
        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
131 b92e5a22 bellard
            /* slow unaligned access (it spans two pages or IO) */
132 b92e5a22 bellard
        do_unaligned_access:
133 61382a50 bellard
            retaddr = GETPC();
134 a64d4718 bellard
#ifdef ALIGNED_ONLY
135 e141ab52 Blue Swirl
            do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
136 a64d4718 bellard
#endif
137 e141ab52 Blue Swirl
            res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr,
138 6ebbf390 j_mayer
                                                         mmu_idx, retaddr);
139 b92e5a22 bellard
        } else {
140 a64d4718 bellard
            /* unaligned/aligned access in the same page */
141 b065927a Stefan Weil
            uintptr_t addend;
142 a64d4718 bellard
#ifdef ALIGNED_ONLY
143 a64d4718 bellard
            if ((addr & (DATA_SIZE - 1)) != 0) {
144 a64d4718 bellard
                retaddr = GETPC();
145 e141ab52 Blue Swirl
                do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
146 a64d4718 bellard
            }
147 a64d4718 bellard
#endif
148 0f459d16 pbrook
            addend = env->tlb_table[mmu_idx][index].addend;
149 b065927a Stefan Weil
            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
150 b065927a Stefan Weil
                                                (addr + addend));
151 b92e5a22 bellard
        }
152 b92e5a22 bellard
    } else {
153 b92e5a22 bellard
        /* the page is not in the TLB : fill it */
154 61382a50 bellard
        retaddr = GETPC();
155 a64d4718 bellard
#ifdef ALIGNED_ONLY
156 a64d4718 bellard
        if ((addr & (DATA_SIZE - 1)) != 0)
157 e141ab52 Blue Swirl
            do_unaligned_access(ENV_VAR addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
158 a64d4718 bellard
#endif
159 bccd9ec5 Blue Swirl
        tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
160 b92e5a22 bellard
        goto redo;
161 b92e5a22 bellard
    }
162 b92e5a22 bellard
    return res;
163 b92e5a22 bellard
}
164 b92e5a22 bellard
165 b92e5a22 bellard
/* handle all unaligned cases */
166 e141ab52 Blue Swirl
static DATA_TYPE
167 e141ab52 Blue Swirl
glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_PARAM
168 e141ab52 Blue Swirl
                                       target_ulong addr,
169 e141ab52 Blue Swirl
                                       int mmu_idx,
170 20503968 Blue Swirl
                                       uintptr_t retaddr)
171 b92e5a22 bellard
{
172 b92e5a22 bellard
    DATA_TYPE res, res1, res2;
173 61382a50 bellard
    int index, shift;
174 355b1943 Paul Brook
    target_phys_addr_t ioaddr;
175 c27004ec bellard
    target_ulong tlb_addr, addr1, addr2;
176 b92e5a22 bellard
177 b92e5a22 bellard
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
178 b92e5a22 bellard
 redo:
179 6ebbf390 j_mayer
    tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
180 b92e5a22 bellard
    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
181 b92e5a22 bellard
        if (tlb_addr & ~TARGET_PAGE_MASK) {
182 b92e5a22 bellard
            /* IO access */
183 b92e5a22 bellard
            if ((addr & (DATA_SIZE - 1)) != 0)
184 b92e5a22 bellard
                goto do_unaligned_access;
185 37ec01d4 Avi Kivity
            ioaddr = env->iotlb[mmu_idx][index];
186 e141ab52 Blue Swirl
            res = glue(io_read, SUFFIX)(ENV_VAR ioaddr, addr, retaddr);
187 98699967 bellard
        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
188 b92e5a22 bellard
        do_unaligned_access:
189 b92e5a22 bellard
            /* slow unaligned access (it spans two pages) */
190 b92e5a22 bellard
            addr1 = addr & ~(DATA_SIZE - 1);
191 b92e5a22 bellard
            addr2 = addr1 + DATA_SIZE;
192 e141ab52 Blue Swirl
            res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr1,
193 6ebbf390 j_mayer
                                                          mmu_idx, retaddr);
194 e141ab52 Blue Swirl
            res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(ENV_VAR addr2,
195 6ebbf390 j_mayer
                                                          mmu_idx, retaddr);
196 b92e5a22 bellard
            shift = (addr & (DATA_SIZE - 1)) * 8;
197 b92e5a22 bellard
#ifdef TARGET_WORDS_BIGENDIAN
198 b92e5a22 bellard
            res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
199 b92e5a22 bellard
#else
200 b92e5a22 bellard
            res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
201 b92e5a22 bellard
#endif
202 6986f88c bellard
            res = (DATA_TYPE)res;
203 b92e5a22 bellard
        } else {
204 b92e5a22 bellard
            /* unaligned/aligned access in the same page */
205 b065927a Stefan Weil
            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
206 b065927a Stefan Weil
            res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(intptr_t)
207 b065927a Stefan Weil
                                                (addr + addend));
208 b92e5a22 bellard
        }
209 b92e5a22 bellard
    } else {
210 b92e5a22 bellard
        /* the page is not in the TLB : fill it */
211 bccd9ec5 Blue Swirl
        tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
212 b92e5a22 bellard
        goto redo;
213 b92e5a22 bellard
    }
214 b92e5a22 bellard
    return res;
215 b92e5a22 bellard
}
216 b92e5a22 bellard
217 b769d8fe bellard
#ifndef SOFTMMU_CODE_ACCESS
218 b769d8fe bellard
219 e141ab52 Blue Swirl
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
220 e141ab52 Blue Swirl
                                                   target_ulong addr,
221 5fafdf24 ths
                                                   DATA_TYPE val,
222 6ebbf390 j_mayer
                                                   int mmu_idx,
223 20503968 Blue Swirl
                                                   uintptr_t retaddr);
224 b769d8fe bellard
225 e141ab52 Blue Swirl
static inline void glue(io_write, SUFFIX)(ENV_PARAM
226 e141ab52 Blue Swirl
                                          target_phys_addr_t physaddr,
227 b769d8fe bellard
                                          DATA_TYPE val,
228 0f459d16 pbrook
                                          target_ulong addr,
229 20503968 Blue Swirl
                                          uintptr_t retaddr)
230 b769d8fe bellard
{
231 37ec01d4 Avi Kivity
    MemoryRegion *mr = iotlb_to_region(physaddr);
232 37ec01d4 Avi Kivity
233 0f459d16 pbrook
    physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
234 37ec01d4 Avi Kivity
    if (mr != &io_mem_ram && mr != &io_mem_rom
235 37ec01d4 Avi Kivity
        && mr != &io_mem_unassigned
236 37ec01d4 Avi Kivity
        && mr != &io_mem_notdirty
237 2e70f6ef pbrook
            && !can_do_io(env)) {
238 2e70f6ef pbrook
        cpu_io_recompile(env, retaddr);
239 2e70f6ef pbrook
    }
240 b769d8fe bellard
241 2e70f6ef pbrook
    env->mem_io_vaddr = addr;
242 20503968 Blue Swirl
    env->mem_io_pc = retaddr;
243 b769d8fe bellard
#if SHIFT <= 2
244 37ec01d4 Avi Kivity
    io_mem_write(mr, physaddr, val, 1 << SHIFT);
245 b769d8fe bellard
#else
246 b769d8fe bellard
#ifdef TARGET_WORDS_BIGENDIAN
247 37ec01d4 Avi Kivity
    io_mem_write(mr, physaddr, (val >> 32), 4);
248 37ec01d4 Avi Kivity
    io_mem_write(mr, physaddr + 4, (uint32_t)val, 4);
249 b769d8fe bellard
#else
250 37ec01d4 Avi Kivity
    io_mem_write(mr, physaddr, (uint32_t)val, 4);
251 37ec01d4 Avi Kivity
    io_mem_write(mr, physaddr + 4, val >> 32, 4);
252 b769d8fe bellard
#endif
253 b769d8fe bellard
#endif /* SHIFT > 2 */
254 b769d8fe bellard
}
255 b92e5a22 bellard
256 e141ab52 Blue Swirl
void glue(glue(glue(HELPER_PREFIX, st), SUFFIX), MMUSUFFIX)(ENV_PARAM
257 e141ab52 Blue Swirl
                                                            target_ulong addr,
258 e141ab52 Blue Swirl
                                                            DATA_TYPE val,
259 e141ab52 Blue Swirl
                                                            int mmu_idx)
260 b92e5a22 bellard
{
261 355b1943 Paul Brook
    target_phys_addr_t ioaddr;
262 c27004ec bellard
    target_ulong tlb_addr;
263 20503968 Blue Swirl
    uintptr_t retaddr;
264 61382a50 bellard
    int index;
265 3b46e624 ths
266 b92e5a22 bellard
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
267 b92e5a22 bellard
 redo:
268 6ebbf390 j_mayer
    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
269 b92e5a22 bellard
    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
270 b92e5a22 bellard
        if (tlb_addr & ~TARGET_PAGE_MASK) {
271 b92e5a22 bellard
            /* IO access */
272 b92e5a22 bellard
            if ((addr & (DATA_SIZE - 1)) != 0)
273 b92e5a22 bellard
                goto do_unaligned_access;
274 d720b93d bellard
            retaddr = GETPC();
275 37ec01d4 Avi Kivity
            ioaddr = env->iotlb[mmu_idx][index];
276 e141ab52 Blue Swirl
            glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
277 98699967 bellard
        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
278 b92e5a22 bellard
        do_unaligned_access:
279 61382a50 bellard
            retaddr = GETPC();
280 a64d4718 bellard
#ifdef ALIGNED_ONLY
281 e141ab52 Blue Swirl
            do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
282 a64d4718 bellard
#endif
283 e141ab52 Blue Swirl
            glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_VAR addr, val,
284 6ebbf390 j_mayer
                                                   mmu_idx, retaddr);
285 b92e5a22 bellard
        } else {
286 b92e5a22 bellard
            /* aligned/unaligned access in the same page */
287 b065927a Stefan Weil
            uintptr_t addend;
288 a64d4718 bellard
#ifdef ALIGNED_ONLY
289 a64d4718 bellard
            if ((addr & (DATA_SIZE - 1)) != 0) {
290 a64d4718 bellard
                retaddr = GETPC();
291 e141ab52 Blue Swirl
                do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
292 a64d4718 bellard
            }
293 a64d4718 bellard
#endif
294 0f459d16 pbrook
            addend = env->tlb_table[mmu_idx][index].addend;
295 b065927a Stefan Weil
            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
296 b065927a Stefan Weil
                                         (addr + addend), val);
297 b92e5a22 bellard
        }
298 b92e5a22 bellard
    } else {
299 b92e5a22 bellard
        /* the page is not in the TLB : fill it */
300 61382a50 bellard
        retaddr = GETPC();
301 a64d4718 bellard
#ifdef ALIGNED_ONLY
302 a64d4718 bellard
        if ((addr & (DATA_SIZE - 1)) != 0)
303 e141ab52 Blue Swirl
            do_unaligned_access(ENV_VAR addr, 1, mmu_idx, retaddr);
304 a64d4718 bellard
#endif
305 bccd9ec5 Blue Swirl
        tlb_fill(env, addr, 1, mmu_idx, retaddr);
306 b92e5a22 bellard
        goto redo;
307 b92e5a22 bellard
    }
308 b92e5a22 bellard
}
309 b92e5a22 bellard
310 b92e5a22 bellard
/* handles all unaligned cases */
311 e141ab52 Blue Swirl
static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(ENV_PARAM
312 e141ab52 Blue Swirl
                                                   target_ulong addr,
313 61382a50 bellard
                                                   DATA_TYPE val,
314 6ebbf390 j_mayer
                                                   int mmu_idx,
315 20503968 Blue Swirl
                                                   uintptr_t retaddr)
316 b92e5a22 bellard
{
317 355b1943 Paul Brook
    target_phys_addr_t ioaddr;
318 c27004ec bellard
    target_ulong tlb_addr;
319 61382a50 bellard
    int index, i;
320 b92e5a22 bellard
321 b92e5a22 bellard
    index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
322 b92e5a22 bellard
 redo:
323 6ebbf390 j_mayer
    tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
324 b92e5a22 bellard
    if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
325 b92e5a22 bellard
        if (tlb_addr & ~TARGET_PAGE_MASK) {
326 b92e5a22 bellard
            /* IO access */
327 b92e5a22 bellard
            if ((addr & (DATA_SIZE - 1)) != 0)
328 b92e5a22 bellard
                goto do_unaligned_access;
329 37ec01d4 Avi Kivity
            ioaddr = env->iotlb[mmu_idx][index];
330 e141ab52 Blue Swirl
            glue(io_write, SUFFIX)(ENV_VAR ioaddr, val, addr, retaddr);
331 98699967 bellard
        } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
332 b92e5a22 bellard
        do_unaligned_access:
333 b92e5a22 bellard
            /* XXX: not efficient, but simple */
334 6c41b272 balrog
            /* Note: relies on the fact that tlb_fill() does not remove the
335 6c41b272 balrog
             * previous page from the TLB cache.  */
336 7221fa98 balrog
            for(i = DATA_SIZE - 1; i >= 0; i--) {
337 b92e5a22 bellard
#ifdef TARGET_WORDS_BIGENDIAN
338 e141ab52 Blue Swirl
                glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
339 e141ab52 Blue Swirl
                                          val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
340 6ebbf390 j_mayer
                                          mmu_idx, retaddr);
341 b92e5a22 bellard
#else
342 e141ab52 Blue Swirl
                glue(slow_stb, MMUSUFFIX)(ENV_VAR addr + i,
343 e141ab52 Blue Swirl
                                          val >> (i * 8),
344 6ebbf390 j_mayer
                                          mmu_idx, retaddr);
345 b92e5a22 bellard
#endif
346 b92e5a22 bellard
            }
347 b92e5a22 bellard
        } else {
348 b92e5a22 bellard
            /* aligned/unaligned access in the same page */
349 b065927a Stefan Weil
            uintptr_t addend = env->tlb_table[mmu_idx][index].addend;
350 b065927a Stefan Weil
            glue(glue(st, SUFFIX), _raw)((uint8_t *)(intptr_t)
351 b065927a Stefan Weil
                                         (addr + addend), val);
352 b92e5a22 bellard
        }
353 b92e5a22 bellard
    } else {
354 b92e5a22 bellard
        /* the page is not in the TLB : fill it */
355 bccd9ec5 Blue Swirl
        tlb_fill(env, addr, 1, mmu_idx, retaddr);
356 b92e5a22 bellard
        goto redo;
357 b92e5a22 bellard
    }
358 b92e5a22 bellard
}
359 b92e5a22 bellard
360 b769d8fe bellard
#endif /* !defined(SOFTMMU_CODE_ACCESS) */
361 b769d8fe bellard
362 b769d8fe bellard
#undef READ_ACCESS_TYPE
363 b92e5a22 bellard
#undef SHIFT
364 b92e5a22 bellard
#undef DATA_TYPE
365 b92e5a22 bellard
#undef SUFFIX
366 61382a50 bellard
#undef USUFFIX
367 b92e5a22 bellard
#undef DATA_SIZE
368 84b7b8e7 bellard
#undef ADDR_READ
369 e141ab52 Blue Swirl
#undef ENV_PARAM
370 e141ab52 Blue Swirl
#undef ENV_VAR
371 e141ab52 Blue Swirl
#undef CPU_PREFIX
372 e141ab52 Blue Swirl
#undef HELPER_PREFIX