Add qemu 2.4.0
[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 #elif DATA_SIZE == 4
31 #define SUFFIX l
32 #define USUFFIX l
33 #define DATA_TYPE uint32_t
34 #elif DATA_SIZE == 2
35 #define SUFFIX w
36 #define USUFFIX uw
37 #define DATA_TYPE uint16_t
38 #define DATA_STYPE int16_t
39 #elif DATA_SIZE == 1
40 #define SUFFIX b
41 #define USUFFIX ub
42 #define DATA_TYPE uint8_t
43 #define DATA_STYPE int8_t
44 #else
45 #error unsupported data size
46 #endif
47
48 #if DATA_SIZE == 8
49 #define RES_TYPE uint64_t
50 #else
51 #define RES_TYPE uint32_t
52 #endif
53
54 #ifdef SOFTMMU_CODE_ACCESS
55 #define ADDR_READ addr_code
56 #define MMUSUFFIX _cmmu
57 #else
58 #define ADDR_READ addr_read
59 #define MMUSUFFIX _mmu
60 #endif
61
62 /* generic load/store macros */
63
64 static inline RES_TYPE
65 glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
66 {
67     int page_index;
68     RES_TYPE res;
69     target_ulong addr;
70     int mmu_idx;
71
72     addr = ptr;
73     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
74     mmu_idx = CPU_MMU_INDEX;
75     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
76                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
77         res = glue(glue(helper_ld, SUFFIX), MMUSUFFIX)(env, addr, mmu_idx);
78     } else {
79         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
80         res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr);
81     }
82     return res;
83 }
84
85 #if DATA_SIZE <= 2
86 static inline int
87 glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr)
88 {
89     int res, page_index;
90     target_ulong addr;
91     int mmu_idx;
92
93     addr = ptr;
94     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
95     mmu_idx = CPU_MMU_INDEX;
96     if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ !=
97                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
98         res = (DATA_STYPE)glue(glue(helper_ld, SUFFIX),
99                                MMUSUFFIX)(env, addr, mmu_idx);
100     } else {
101         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
102         res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr);
103     }
104     return res;
105 }
106 #endif
107
108 #ifndef SOFTMMU_CODE_ACCESS
109
110 /* generic store macro */
111
112 static inline void
113 glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr,
114                                       RES_TYPE v)
115 {
116     int page_index;
117     target_ulong addr;
118     int mmu_idx;
119
120     addr = ptr;
121     page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
122     mmu_idx = CPU_MMU_INDEX;
123     if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write !=
124                  (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) {
125         glue(glue(helper_st, SUFFIX), MMUSUFFIX)(env, addr, v, mmu_idx);
126     } else {
127         uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend;
128         glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v);
129     }
130 }
131
132 #endif /* !SOFTMMU_CODE_ACCESS */
133
134 #undef RES_TYPE
135 #undef DATA_TYPE
136 #undef DATA_STYPE
137 #undef SUFFIX
138 #undef USUFFIX
139 #undef DATA_SIZE
140 #undef MMUSUFFIX
141 #undef ADDR_READ