Add ENET device to i.MX6 SOC.
[qemu.git] / include / exec / cpu_ldst_template.h
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.
8 *
9 * Not used directly but included from cpu_ldst.h.
10 *
11 * Copyright (c) 2003 Fabrice Bellard
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2 of the License, or (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 */
26 #if DATA_SIZE == 8
27 #define SUFFIX q
28 #define USUFFIX q
29 #define DATA_TYPE uint64_t
30 #define SHIFT 3
31 #elif DATA_SIZE == 4
32 #define SUFFIX l
33 #define USUFFIX l
34 #define DATA_TYPE uint32_t
35 #define SHIFT 2
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 #define SHIFT 1
42 #elif DATA_SIZE == 1
43 #define SUFFIX b
44 #define USUFFIX ub
45 #define DATA_TYPE uint8_t
46 #define DATA_STYPE int8_t
47 #define SHIFT 0
48 #else
49 #error unsupported data size
50 #endif
51
52 #if DATA_SIZE == 8
53 #define RES_TYPE uint64_t
54 #else
55 #define RES_TYPE uint32_t
56 #endif
57
58 #ifdef SOFTMMU_CODE_ACCESS
59 #define ADDR_READ addr_code
60 #define MMUSUFFIX _cmmu
61 #define URETSUFFIX SUFFIX
62 #define SRETSUFFIX SUFFIX
63 #else
64 #define ADDR_READ addr_read
65 #define MMUSUFFIX _mmu
66 #define URETSUFFIX USUFFIX
67 #define SRETSUFFIX glue(s, SUFFIX)
68 #endif
69
70 /* generic load/store macros */
71
72 static inline RES_TYPE
73 glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
74 target_ulong ptr,
75 uintptr_t retaddr)
76 {
77 int page_index;
78 RES_TYPE res;
79 target_ulong addr;
80 int mmu_idx;
81 TCGMemOpIdx oi;
82
83 addr = ptr;
84 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
85 mmu_idx = CPU_MMU_INDEX;
86 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
87 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
88 oi = make_memop_idx(SHIFT, mmu_idx);
89 res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr,
90 oi, retaddr);
91 } else {
92 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
93 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
94 }
95 return res;
96 }
97
98 static inline RES_TYPE
99 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
100 {
101 return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
102 }
103
104 #if DATA_SIZE <= 2
105 static inline int
106 glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
107 target_ulong ptr,
108 uintptr_t retaddr)
109 {
110 int res, page_index;
111 target_ulong addr;
112 int mmu_idx;
113 TCGMemOpIdx oi;
114
115 addr = ptr;
116 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
117 mmu_idx = CPU_MMU_INDEX;
118 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
119 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
120 oi = make_memop_idx(SHIFT, mmu_idx);
121 res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX),
122 MMUSUFFIX)(env, addr, oi, retaddr);
123 } else {
124 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
125 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
126 }
127 return res;
128 }
129
130 static inline int
131 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
132 {
133 return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0);
134 }
135 #endif
136
137 #ifndef SOFTMMU_CODE_ACCESS
138
139 /* generic store macro */
140
141 static inline void
142 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env,
143 target_ulong ptr,
144 RES_TYPE v, uintptr_t retaddr)
145 {
146 int page_index;
147 target_ulong addr;
148 int mmu_idx;
149 TCGMemOpIdx oi;
150
151 addr = ptr;
152 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
153 mmu_idx = CPU_MMU_INDEX;
154 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
155 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
156 oi = make_memop_idx(SHIFT, mmu_idx);
157 glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi,
158 retaddr);
159 } else {
160 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
161 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
162 }
163 }
164
165 static inline void
166 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
167 RES_TYPE v)
168 {
169 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0);
170 }
171
172 #endif /* !SOFTMMU_CODE_ACCESS */
173
174 #undef RES_TYPE
175 #undef DATA_TYPE
176 #undef DATA_STYPE
177 #undef SUFFIX
178 #undef USUFFIX
179 #undef DATA_SIZE
180 #undef MMUSUFFIX
181 #undef ADDR_READ
182 #undef URETSUFFIX
183 #undef SRETSUFFIX
184 #undef SHIFT