These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / 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