blob: 97020f818561f6f1d51baa6aa7c89b1b873266ac [file] [log] [blame]
bellardb92e5a22003-08-08 23:58:05 +00001/*
2 * Software MMU support
ths5fafdf22007-09-16 21:08:06 +00003 *
Blue Swirlefbf29b2011-09-21 20:00:18 +00004 * Generate helpers used by TCG for qemu_ld/st ops and code load
5 * functions.
6 *
7 * Included from target op helpers and exec.c.
8 *
bellardb92e5a22003-08-08 23:58:05 +00009 * Copyright (c) 2003 Fabrice Bellard
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
Blue Swirl8167ee82009-07-16 20:47:01 +000022 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
bellardb92e5a22003-08-08 23:58:05 +000023 */
Blue Swirl29e922b2010-03-29 19:24:00 +000024#include "qemu-timer.h"
Avi Kivity0e0df1e2012-01-02 00:32:15 +020025#include "memory.h"
Blue Swirl29e922b2010-03-29 19:24:00 +000026
bellardb92e5a22003-08-08 23:58:05 +000027#define DATA_SIZE (1 << SHIFT)
28
29#if DATA_SIZE == 8
30#define SUFFIX q
bellard61382a52003-10-27 21:22:23 +000031#define USUFFIX q
bellardb92e5a22003-08-08 23:58:05 +000032#define DATA_TYPE uint64_t
33#elif DATA_SIZE == 4
34#define SUFFIX l
bellard61382a52003-10-27 21:22:23 +000035#define USUFFIX l
bellardb92e5a22003-08-08 23:58:05 +000036#define DATA_TYPE uint32_t
37#elif DATA_SIZE == 2
38#define SUFFIX w
bellard61382a52003-10-27 21:22:23 +000039#define USUFFIX uw
bellardb92e5a22003-08-08 23:58:05 +000040#define DATA_TYPE uint16_t
41#elif DATA_SIZE == 1
42#define SUFFIX b
bellard61382a52003-10-27 21:22:23 +000043#define USUFFIX ub
bellardb92e5a22003-08-08 23:58:05 +000044#define DATA_TYPE uint8_t
45#else
46#error unsupported data size
47#endif
48
bellardb769d8f2004-10-03 15:07:13 +000049#ifdef SOFTMMU_CODE_ACCESS
50#define READ_ACCESS_TYPE 2
bellard84b7b8e2005-11-28 21:19:04 +000051#define ADDR_READ addr_code
bellardb769d8f2004-10-03 15:07:13 +000052#else
53#define READ_ACCESS_TYPE 0
bellard84b7b8e2005-11-28 21:19:04 +000054#define ADDR_READ addr_read
bellardb769d8f2004-10-03 15:07:13 +000055#endif
56
ths5fafdf22007-09-16 21:08:06 +000057static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
j_mayer6ebbf392007-10-14 07:07:08 +000058 int mmu_idx,
bellard61382a52003-10-27 21:22:23 +000059 void *retaddr);
Anthony Liguoric227f092009-10-01 16:12:16 -050060static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
pbrook2e70f6e2008-06-29 01:03:05 +000061 target_ulong addr,
62 void *retaddr)
bellardb92e5a22003-08-08 23:58:05 +000063{
64 DATA_TYPE res;
65 int index;
Avi Kivity11c7ef02012-01-02 17:21:07 +020066 index = physaddr & (IO_MEM_NB_ENTRIES - 1);
pbrook0f459d12008-06-09 00:20:13 +000067 physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
pbrook2e70f6e2008-06-29 01:03:05 +000068 env->mem_io_pc = (unsigned long)retaddr;
Avi Kivity0e0df1e2012-01-02 00:32:15 +020069 if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
70 && index != io_mem_unassigned.ram_addr
71 && index != io_mem_notdirty.ram_addr
pbrook2e70f6e2008-06-29 01:03:05 +000072 && !can_do_io(env)) {
73 cpu_io_recompile(env, retaddr);
74 }
bellardb92e5a22003-08-08 23:58:05 +000075
aliguoridb8886d2008-11-18 20:09:43 +000076 env->mem_io_vaddr = addr;
bellardb92e5a22003-08-08 23:58:05 +000077#if SHIFT <= 2
Avi Kivityacbbec52011-11-21 12:27:03 +020078 res = io_mem_read(index, physaddr, 1 << SHIFT);
bellardb92e5a22003-08-08 23:58:05 +000079#else
80#ifdef TARGET_WORDS_BIGENDIAN
Avi Kivityacbbec52011-11-21 12:27:03 +020081 res = io_mem_read(index, physaddr, 4) << 32;
82 res |= io_mem_read(index, physaddr + 4, 4);
bellardb92e5a22003-08-08 23:58:05 +000083#else
Avi Kivityacbbec52011-11-21 12:27:03 +020084 res = io_mem_read(index, physaddr, 4);
85 res |= io_mem_read(index, physaddr + 4, 4) << 32;
bellardb92e5a22003-08-08 23:58:05 +000086#endif
87#endif /* SHIFT > 2 */
88 return res;
89}
90
bellardb92e5a22003-08-08 23:58:05 +000091/* handle all cases except unaligned access which span two pages */
bellardd6564692008-01-31 09:22:27 +000092DATA_TYPE REGPARM glue(glue(__ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
93 int mmu_idx)
bellardb92e5a22003-08-08 23:58:05 +000094{
95 DATA_TYPE res;
bellard61382a52003-10-27 21:22:23 +000096 int index;
bellardc27004e2005-01-03 23:35:10 +000097 target_ulong tlb_addr;
Paul Brook355b1942010-04-05 00:28:53 +010098 target_phys_addr_t ioaddr;
99 unsigned long addend;
bellardb92e5a22003-08-08 23:58:05 +0000100 void *retaddr;
ths3b46e622007-09-17 08:09:54 +0000101
bellardb92e5a22003-08-08 23:58:05 +0000102 /* test if there is match for unaligned or IO access */
103 /* XXX: could done more in memory macro in a non portable way */
bellardb92e5a22003-08-08 23:58:05 +0000104 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
105 redo:
j_mayer6ebbf392007-10-14 07:07:08 +0000106 tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
bellardb92e5a22003-08-08 23:58:05 +0000107 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
bellardb92e5a22003-08-08 23:58:05 +0000108 if (tlb_addr & ~TARGET_PAGE_MASK) {
109 /* IO access */
110 if ((addr & (DATA_SIZE - 1)) != 0)
111 goto do_unaligned_access;
pbrook2e70f6e2008-06-29 01:03:05 +0000112 retaddr = GETPC();
Paul Brook355b1942010-04-05 00:28:53 +0100113 ioaddr = env->iotlb[mmu_idx][index];
114 res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
bellard98699962005-11-26 10:29:22 +0000115 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
bellardb92e5a22003-08-08 23:58:05 +0000116 /* slow unaligned access (it spans two pages or IO) */
117 do_unaligned_access:
bellard61382a52003-10-27 21:22:23 +0000118 retaddr = GETPC();
bellarda64d4712005-12-05 19:57:57 +0000119#ifdef ALIGNED_ONLY
j_mayer6ebbf392007-10-14 07:07:08 +0000120 do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000121#endif
ths5fafdf22007-09-16 21:08:06 +0000122 res = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr,
j_mayer6ebbf392007-10-14 07:07:08 +0000123 mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000124 } else {
bellarda64d4712005-12-05 19:57:57 +0000125 /* unaligned/aligned access in the same page */
126#ifdef ALIGNED_ONLY
127 if ((addr & (DATA_SIZE - 1)) != 0) {
128 retaddr = GETPC();
j_mayer6ebbf392007-10-14 07:07:08 +0000129 do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000130 }
131#endif
pbrook0f459d12008-06-09 00:20:13 +0000132 addend = env->tlb_table[mmu_idx][index].addend;
133 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
bellardb92e5a22003-08-08 23:58:05 +0000134 }
135 } else {
136 /* the page is not in the TLB : fill it */
bellard61382a52003-10-27 21:22:23 +0000137 retaddr = GETPC();
bellarda64d4712005-12-05 19:57:57 +0000138#ifdef ALIGNED_ONLY
139 if ((addr & (DATA_SIZE - 1)) != 0)
j_mayer6ebbf392007-10-14 07:07:08 +0000140 do_unaligned_access(addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000141#endif
Blue Swirlbccd9ec2011-07-04 20:57:05 +0000142 tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000143 goto redo;
144 }
145 return res;
146}
147
148/* handle all unaligned cases */
ths5fafdf22007-09-16 21:08:06 +0000149static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
j_mayer6ebbf392007-10-14 07:07:08 +0000150 int mmu_idx,
bellard61382a52003-10-27 21:22:23 +0000151 void *retaddr)
bellardb92e5a22003-08-08 23:58:05 +0000152{
153 DATA_TYPE res, res1, res2;
bellard61382a52003-10-27 21:22:23 +0000154 int index, shift;
Paul Brook355b1942010-04-05 00:28:53 +0100155 target_phys_addr_t ioaddr;
156 unsigned long addend;
bellardc27004e2005-01-03 23:35:10 +0000157 target_ulong tlb_addr, addr1, addr2;
bellardb92e5a22003-08-08 23:58:05 +0000158
bellardb92e5a22003-08-08 23:58:05 +0000159 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
160 redo:
j_mayer6ebbf392007-10-14 07:07:08 +0000161 tlb_addr = env->tlb_table[mmu_idx][index].ADDR_READ;
bellardb92e5a22003-08-08 23:58:05 +0000162 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
bellardb92e5a22003-08-08 23:58:05 +0000163 if (tlb_addr & ~TARGET_PAGE_MASK) {
164 /* IO access */
165 if ((addr & (DATA_SIZE - 1)) != 0)
166 goto do_unaligned_access;
Paul Brook355b1942010-04-05 00:28:53 +0100167 ioaddr = env->iotlb[mmu_idx][index];
168 res = glue(io_read, SUFFIX)(ioaddr, addr, retaddr);
bellard98699962005-11-26 10:29:22 +0000169 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
bellardb92e5a22003-08-08 23:58:05 +0000170 do_unaligned_access:
171 /* slow unaligned access (it spans two pages) */
172 addr1 = addr & ~(DATA_SIZE - 1);
173 addr2 = addr1 + DATA_SIZE;
ths5fafdf22007-09-16 21:08:06 +0000174 res1 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr1,
j_mayer6ebbf392007-10-14 07:07:08 +0000175 mmu_idx, retaddr);
ths5fafdf22007-09-16 21:08:06 +0000176 res2 = glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(addr2,
j_mayer6ebbf392007-10-14 07:07:08 +0000177 mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000178 shift = (addr & (DATA_SIZE - 1)) * 8;
179#ifdef TARGET_WORDS_BIGENDIAN
180 res = (res1 << shift) | (res2 >> ((DATA_SIZE * 8) - shift));
181#else
182 res = (res1 >> shift) | (res2 << ((DATA_SIZE * 8) - shift));
183#endif
bellard6986f882004-01-18 21:53:18 +0000184 res = (DATA_TYPE)res;
bellardb92e5a22003-08-08 23:58:05 +0000185 } else {
186 /* unaligned/aligned access in the same page */
pbrook0f459d12008-06-09 00:20:13 +0000187 addend = env->tlb_table[mmu_idx][index].addend;
188 res = glue(glue(ld, USUFFIX), _raw)((uint8_t *)(long)(addr+addend));
bellardb92e5a22003-08-08 23:58:05 +0000189 }
190 } else {
191 /* the page is not in the TLB : fill it */
Blue Swirlbccd9ec2011-07-04 20:57:05 +0000192 tlb_fill(env, addr, READ_ACCESS_TYPE, mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000193 goto redo;
194 }
195 return res;
196}
197
bellardb769d8f2004-10-03 15:07:13 +0000198#ifndef SOFTMMU_CODE_ACCESS
199
ths5fafdf22007-09-16 21:08:06 +0000200static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
201 DATA_TYPE val,
j_mayer6ebbf392007-10-14 07:07:08 +0000202 int mmu_idx,
bellardb769d8f2004-10-03 15:07:13 +0000203 void *retaddr);
204
Anthony Liguoric227f092009-10-01 16:12:16 -0500205static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
bellardb769d8f2004-10-03 15:07:13 +0000206 DATA_TYPE val,
pbrook0f459d12008-06-09 00:20:13 +0000207 target_ulong addr,
bellardb769d8f2004-10-03 15:07:13 +0000208 void *retaddr)
209{
210 int index;
Avi Kivity11c7ef02012-01-02 17:21:07 +0200211 index = physaddr & (IO_MEM_NB_ENTRIES - 1);
pbrook0f459d12008-06-09 00:20:13 +0000212 physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
Avi Kivity0e0df1e2012-01-02 00:32:15 +0200213 if (index != io_mem_ram.ram_addr && index != io_mem_rom.ram_addr
214 && index != io_mem_unassigned.ram_addr
215 && index != io_mem_notdirty.ram_addr
pbrook2e70f6e2008-06-29 01:03:05 +0000216 && !can_do_io(env)) {
217 cpu_io_recompile(env, retaddr);
218 }
bellardb769d8f2004-10-03 15:07:13 +0000219
pbrook2e70f6e2008-06-29 01:03:05 +0000220 env->mem_io_vaddr = addr;
221 env->mem_io_pc = (unsigned long)retaddr;
bellardb769d8f2004-10-03 15:07:13 +0000222#if SHIFT <= 2
Avi Kivityacbbec52011-11-21 12:27:03 +0200223 io_mem_write(index, physaddr, val, 1 << SHIFT);
bellardb769d8f2004-10-03 15:07:13 +0000224#else
225#ifdef TARGET_WORDS_BIGENDIAN
Avi Kivityacbbec52011-11-21 12:27:03 +0200226 io_mem_write(index, physaddr, (val >> 32), 4);
227 io_mem_write(index, physaddr + 4, (uint32_t)val, 4);
bellardb769d8f2004-10-03 15:07:13 +0000228#else
Avi Kivityacbbec52011-11-21 12:27:03 +0200229 io_mem_write(index, physaddr, (uint32_t)val, 4);
230 io_mem_write(index, physaddr + 4, val >> 32, 4);
bellardb769d8f2004-10-03 15:07:13 +0000231#endif
232#endif /* SHIFT > 2 */
233}
bellardb92e5a22003-08-08 23:58:05 +0000234
bellardd6564692008-01-31 09:22:27 +0000235void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
236 DATA_TYPE val,
237 int mmu_idx)
bellardb92e5a22003-08-08 23:58:05 +0000238{
Paul Brook355b1942010-04-05 00:28:53 +0100239 target_phys_addr_t ioaddr;
240 unsigned long addend;
bellardc27004e2005-01-03 23:35:10 +0000241 target_ulong tlb_addr;
bellardb92e5a22003-08-08 23:58:05 +0000242 void *retaddr;
bellard61382a52003-10-27 21:22:23 +0000243 int index;
ths3b46e622007-09-17 08:09:54 +0000244
bellardb92e5a22003-08-08 23:58:05 +0000245 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
246 redo:
j_mayer6ebbf392007-10-14 07:07:08 +0000247 tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
bellardb92e5a22003-08-08 23:58:05 +0000248 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
bellardb92e5a22003-08-08 23:58:05 +0000249 if (tlb_addr & ~TARGET_PAGE_MASK) {
250 /* IO access */
251 if ((addr & (DATA_SIZE - 1)) != 0)
252 goto do_unaligned_access;
bellardd720b932004-04-25 17:57:43 +0000253 retaddr = GETPC();
Paul Brook355b1942010-04-05 00:28:53 +0100254 ioaddr = env->iotlb[mmu_idx][index];
255 glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
bellard98699962005-11-26 10:29:22 +0000256 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
bellardb92e5a22003-08-08 23:58:05 +0000257 do_unaligned_access:
bellard61382a52003-10-27 21:22:23 +0000258 retaddr = GETPC();
bellarda64d4712005-12-05 19:57:57 +0000259#ifdef ALIGNED_ONLY
j_mayer6ebbf392007-10-14 07:07:08 +0000260 do_unaligned_access(addr, 1, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000261#endif
ths5fafdf22007-09-16 21:08:06 +0000262 glue(glue(slow_st, SUFFIX), MMUSUFFIX)(addr, val,
j_mayer6ebbf392007-10-14 07:07:08 +0000263 mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000264 } else {
265 /* aligned/unaligned access in the same page */
bellarda64d4712005-12-05 19:57:57 +0000266#ifdef ALIGNED_ONLY
267 if ((addr & (DATA_SIZE - 1)) != 0) {
268 retaddr = GETPC();
j_mayer6ebbf392007-10-14 07:07:08 +0000269 do_unaligned_access(addr, 1, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000270 }
271#endif
pbrook0f459d12008-06-09 00:20:13 +0000272 addend = env->tlb_table[mmu_idx][index].addend;
273 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
bellardb92e5a22003-08-08 23:58:05 +0000274 }
275 } else {
276 /* the page is not in the TLB : fill it */
bellard61382a52003-10-27 21:22:23 +0000277 retaddr = GETPC();
bellarda64d4712005-12-05 19:57:57 +0000278#ifdef ALIGNED_ONLY
279 if ((addr & (DATA_SIZE - 1)) != 0)
j_mayer6ebbf392007-10-14 07:07:08 +0000280 do_unaligned_access(addr, 1, mmu_idx, retaddr);
bellarda64d4712005-12-05 19:57:57 +0000281#endif
Blue Swirlbccd9ec2011-07-04 20:57:05 +0000282 tlb_fill(env, addr, 1, mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000283 goto redo;
284 }
285}
286
287/* handles all unaligned cases */
ths5fafdf22007-09-16 21:08:06 +0000288static void glue(glue(slow_st, SUFFIX), MMUSUFFIX)(target_ulong addr,
bellard61382a52003-10-27 21:22:23 +0000289 DATA_TYPE val,
j_mayer6ebbf392007-10-14 07:07:08 +0000290 int mmu_idx,
bellard61382a52003-10-27 21:22:23 +0000291 void *retaddr)
bellardb92e5a22003-08-08 23:58:05 +0000292{
Paul Brook355b1942010-04-05 00:28:53 +0100293 target_phys_addr_t ioaddr;
294 unsigned long addend;
bellardc27004e2005-01-03 23:35:10 +0000295 target_ulong tlb_addr;
bellard61382a52003-10-27 21:22:23 +0000296 int index, i;
bellardb92e5a22003-08-08 23:58:05 +0000297
bellardb92e5a22003-08-08 23:58:05 +0000298 index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
299 redo:
j_mayer6ebbf392007-10-14 07:07:08 +0000300 tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
bellardb92e5a22003-08-08 23:58:05 +0000301 if ((addr & TARGET_PAGE_MASK) == (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
bellardb92e5a22003-08-08 23:58:05 +0000302 if (tlb_addr & ~TARGET_PAGE_MASK) {
303 /* IO access */
304 if ((addr & (DATA_SIZE - 1)) != 0)
305 goto do_unaligned_access;
Paul Brook355b1942010-04-05 00:28:53 +0100306 ioaddr = env->iotlb[mmu_idx][index];
307 glue(io_write, SUFFIX)(ioaddr, val, addr, retaddr);
bellard98699962005-11-26 10:29:22 +0000308 } else if (((addr & ~TARGET_PAGE_MASK) + DATA_SIZE - 1) >= TARGET_PAGE_SIZE) {
bellardb92e5a22003-08-08 23:58:05 +0000309 do_unaligned_access:
310 /* XXX: not efficient, but simple */
balrog6c41b272007-11-17 12:12:29 +0000311 /* Note: relies on the fact that tlb_fill() does not remove the
312 * previous page from the TLB cache. */
balrog7221fa92007-11-17 09:53:42 +0000313 for(i = DATA_SIZE - 1; i >= 0; i--) {
bellardb92e5a22003-08-08 23:58:05 +0000314#ifdef TARGET_WORDS_BIGENDIAN
ths5fafdf22007-09-16 21:08:06 +0000315 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (((DATA_SIZE - 1) * 8) - (i * 8)),
j_mayer6ebbf392007-10-14 07:07:08 +0000316 mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000317#else
ths5fafdf22007-09-16 21:08:06 +0000318 glue(slow_stb, MMUSUFFIX)(addr + i, val >> (i * 8),
j_mayer6ebbf392007-10-14 07:07:08 +0000319 mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000320#endif
321 }
322 } else {
323 /* aligned/unaligned access in the same page */
pbrook0f459d12008-06-09 00:20:13 +0000324 addend = env->tlb_table[mmu_idx][index].addend;
325 glue(glue(st, SUFFIX), _raw)((uint8_t *)(long)(addr+addend), val);
bellardb92e5a22003-08-08 23:58:05 +0000326 }
327 } else {
328 /* the page is not in the TLB : fill it */
Blue Swirlbccd9ec2011-07-04 20:57:05 +0000329 tlb_fill(env, addr, 1, mmu_idx, retaddr);
bellardb92e5a22003-08-08 23:58:05 +0000330 goto redo;
331 }
332}
333
bellardb769d8f2004-10-03 15:07:13 +0000334#endif /* !defined(SOFTMMU_CODE_ACCESS) */
335
336#undef READ_ACCESS_TYPE
bellardb92e5a22003-08-08 23:58:05 +0000337#undef SHIFT
338#undef DATA_TYPE
339#undef SUFFIX
bellard61382a52003-10-27 21:22:23 +0000340#undef USUFFIX
bellardb92e5a22003-08-08 23:58:05 +0000341#undef DATA_SIZE
bellard84b7b8e2005-11-28 21:19:04 +0000342#undef ADDR_READ