Statistics
| Branch: | Revision:

root / target-mips / op_mem.c @ aa0bf00b

History | View | Annotate | Download (7.5 kB)

1 6af0bf9c bellard
/*
2 6af0bf9c bellard
 *  MIPS emulation memory micro-operations for qemu.
3 5fafdf24 ths
 *
4 6af0bf9c bellard
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5 6af0bf9c bellard
 *
6 6af0bf9c bellard
 * This library is free software; you can redistribute it and/or
7 6af0bf9c bellard
 * modify it under the terms of the GNU Lesser General Public
8 6af0bf9c bellard
 * License as published by the Free Software Foundation; either
9 6af0bf9c bellard
 * version 2 of the License, or (at your option) any later version.
10 6af0bf9c bellard
 *
11 6af0bf9c bellard
 * This library is distributed in the hope that it will be useful,
12 6af0bf9c bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 6af0bf9c bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 6af0bf9c bellard
 * Lesser General Public License for more details.
15 6af0bf9c bellard
 *
16 6af0bf9c bellard
 * You should have received a copy of the GNU Lesser General Public
17 6af0bf9c bellard
 * License along with this library; if not, write to the Free Software
18 6af0bf9c bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 6af0bf9c bellard
 */
20 6af0bf9c bellard
21 4ad40f36 bellard
/* "half" load and stores.  We must do the memory access inline,
22 4ad40f36 bellard
   or fault handling won't work.  */
23 4e9f8537 ths
24 4e9f8537 ths
#ifdef TARGET_WORDS_BIGENDIAN
25 4e9f8537 ths
#define GET_LMASK(v) ((v) & 3)
26 4e9f8537 ths
#define GET_OFFSET(addr, offset) (addr + (offset))
27 4e9f8537 ths
#else
28 4e9f8537 ths
#define GET_LMASK(v) (((v) & 3) ^ 3)
29 4e9f8537 ths
#define GET_OFFSET(addr, offset) (addr - (offset))
30 4e9f8537 ths
#endif
31 4e9f8537 ths
32 6af0bf9c bellard
void glue(op_lwl, MEMSUFFIX) (void)
33 6af0bf9c bellard
{
34 4e9f8537 ths
    target_ulong tmp;
35 4e9f8537 ths
36 4e9f8537 ths
    tmp = glue(ldub, MEMSUFFIX)(T0);
37 7d307e9e ths
    T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
38 4e9f8537 ths
39 4e9f8537 ths
    if (GET_LMASK(T0) <= 2) {
40 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
41 4e9f8537 ths
        T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
42 4e9f8537 ths
    }
43 4e9f8537 ths
44 4e9f8537 ths
    if (GET_LMASK(T0) <= 1) {
45 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
46 4e9f8537 ths
        T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
47 4e9f8537 ths
    }
48 4e9f8537 ths
49 4e9f8537 ths
    if (GET_LMASK(T0) == 0) {
50 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
51 4e9f8537 ths
        T1 = (T1 & 0xFFFFFF00) | tmp;
52 4e9f8537 ths
    }
53 7d307e9e ths
    T1 = (int32_t)T1;
54 8f6f6026 ths
    FORCE_RET();
55 6af0bf9c bellard
}
56 6af0bf9c bellard
57 6af0bf9c bellard
void glue(op_lwr, MEMSUFFIX) (void)
58 6af0bf9c bellard
{
59 4e9f8537 ths
    target_ulong tmp;
60 4e9f8537 ths
61 4e9f8537 ths
    tmp = glue(ldub, MEMSUFFIX)(T0);
62 4e9f8537 ths
    T1 = (T1 & 0xFFFFFF00) | tmp;
63 4e9f8537 ths
64 4e9f8537 ths
    if (GET_LMASK(T0) >= 1) {
65 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
66 4e9f8537 ths
        T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
67 4e9f8537 ths
    }
68 4e9f8537 ths
69 4e9f8537 ths
    if (GET_LMASK(T0) >= 2) {
70 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
71 4e9f8537 ths
        T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
72 4e9f8537 ths
    }
73 4e9f8537 ths
74 4e9f8537 ths
    if (GET_LMASK(T0) == 3) {
75 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
76 4e9f8537 ths
        T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
77 4e9f8537 ths
    }
78 7d307e9e ths
    T1 = (int32_t)T1;
79 8f6f6026 ths
    FORCE_RET();
80 6af0bf9c bellard
}
81 6af0bf9c bellard
82 6af0bf9c bellard
void glue(op_swl, MEMSUFFIX) (void)
83 6af0bf9c bellard
{
84 4e9f8537 ths
    glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24));
85 4e9f8537 ths
86 4e9f8537 ths
    if (GET_LMASK(T0) <= 2)
87 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16));
88 4e9f8537 ths
89 4e9f8537 ths
    if (GET_LMASK(T0) <= 1)
90 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8));
91 4e9f8537 ths
92 4e9f8537 ths
    if (GET_LMASK(T0) == 0)
93 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1);
94 4e9f8537 ths
95 8f6f6026 ths
    FORCE_RET();
96 6af0bf9c bellard
}
97 6af0bf9c bellard
98 6af0bf9c bellard
void glue(op_swr, MEMSUFFIX) (void)
99 6af0bf9c bellard
{
100 4e9f8537 ths
    glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
101 4e9f8537 ths
102 4e9f8537 ths
    if (GET_LMASK(T0) >= 1)
103 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
104 4e9f8537 ths
105 4e9f8537 ths
    if (GET_LMASK(T0) >= 2)
106 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
107 4e9f8537 ths
108 4e9f8537 ths
    if (GET_LMASK(T0) == 3)
109 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
110 4e9f8537 ths
111 8f6f6026 ths
    FORCE_RET();
112 6af0bf9c bellard
}
113 6af0bf9c bellard
114 d26bc211 ths
#if defined(TARGET_MIPS64)
115 c570fd16 ths
/* "half" load and stores.  We must do the memory access inline,
116 c570fd16 ths
   or fault handling won't work.  */
117 4e9f8537 ths
118 4e9f8537 ths
#ifdef TARGET_WORDS_BIGENDIAN
119 4e9f8537 ths
#define GET_LMASK64(v) ((v) & 7)
120 4e9f8537 ths
#else
121 4e9f8537 ths
#define GET_LMASK64(v) (((v) & 7) ^ 7)
122 4e9f8537 ths
#endif
123 4e9f8537 ths
124 c570fd16 ths
void glue(op_ldl, MEMSUFFIX) (void)
125 c570fd16 ths
{
126 4e9f8537 ths
    uint64_t tmp;
127 4e9f8537 ths
128 4e9f8537 ths
    tmp = glue(ldub, MEMSUFFIX)(T0);
129 4e9f8537 ths
    T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
130 4e9f8537 ths
131 4e9f8537 ths
    if (GET_LMASK64(T0) <= 6) {
132 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
133 4e9f8537 ths
        T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
134 4e9f8537 ths
    }
135 4e9f8537 ths
136 4e9f8537 ths
    if (GET_LMASK64(T0) <= 5) {
137 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
138 4e9f8537 ths
        T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
139 4e9f8537 ths
    }
140 4e9f8537 ths
141 4e9f8537 ths
    if (GET_LMASK64(T0) <= 4) {
142 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
143 4e9f8537 ths
        T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
144 4e9f8537 ths
    }
145 4e9f8537 ths
146 4e9f8537 ths
    if (GET_LMASK64(T0) <= 3) {
147 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4));
148 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
149 4e9f8537 ths
    }
150 4e9f8537 ths
151 4e9f8537 ths
    if (GET_LMASK64(T0) <= 2) {
152 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5));
153 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
154 4e9f8537 ths
    }
155 4e9f8537 ths
156 4e9f8537 ths
    if (GET_LMASK64(T0) <= 1) {
157 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6));
158 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
159 4e9f8537 ths
    }
160 4e9f8537 ths
161 4e9f8537 ths
    if (GET_LMASK64(T0) == 0) {
162 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7));
163 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
164 4e9f8537 ths
    }
165 4e9f8537 ths
166 8f6f6026 ths
    FORCE_RET();
167 c570fd16 ths
}
168 c570fd16 ths
169 c570fd16 ths
void glue(op_ldr, MEMSUFFIX) (void)
170 c570fd16 ths
{
171 4e9f8537 ths
    uint64_t tmp;
172 4e9f8537 ths
173 4e9f8537 ths
    tmp = glue(ldub, MEMSUFFIX)(T0);
174 4e9f8537 ths
    T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
175 4e9f8537 ths
176 4e9f8537 ths
    if (GET_LMASK64(T0) >= 1) {
177 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
178 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp  << 8);
179 4e9f8537 ths
    }
180 4e9f8537 ths
181 4e9f8537 ths
    if (GET_LMASK64(T0) >= 2) {
182 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
183 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
184 4e9f8537 ths
    }
185 4e9f8537 ths
186 4e9f8537 ths
    if (GET_LMASK64(T0) >= 3) {
187 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
188 4e9f8537 ths
        T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
189 4e9f8537 ths
    }
190 4e9f8537 ths
191 4e9f8537 ths
    if (GET_LMASK64(T0) >= 4) {
192 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4));
193 4e9f8537 ths
        T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
194 4e9f8537 ths
    }
195 4e9f8537 ths
196 4e9f8537 ths
    if (GET_LMASK64(T0) >= 5) {
197 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5));
198 4e9f8537 ths
        T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
199 4e9f8537 ths
    }
200 4e9f8537 ths
201 4e9f8537 ths
    if (GET_LMASK64(T0) >= 6) {
202 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6));
203 4e9f8537 ths
        T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
204 4e9f8537 ths
    }
205 4e9f8537 ths
206 4e9f8537 ths
    if (GET_LMASK64(T0) == 7) {
207 4e9f8537 ths
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7));
208 4e9f8537 ths
        T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
209 4e9f8537 ths
    }
210 4e9f8537 ths
211 8f6f6026 ths
    FORCE_RET();
212 c570fd16 ths
}
213 c570fd16 ths
214 c570fd16 ths
void glue(op_sdl, MEMSUFFIX) (void)
215 c570fd16 ths
{
216 4e9f8537 ths
    glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56));
217 4e9f8537 ths
218 4e9f8537 ths
    if (GET_LMASK64(T0) <= 6)
219 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48));
220 4e9f8537 ths
221 4e9f8537 ths
    if (GET_LMASK64(T0) <= 5)
222 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40));
223 4e9f8537 ths
224 4e9f8537 ths
    if (GET_LMASK64(T0) <= 4)
225 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32));
226 4e9f8537 ths
227 4e9f8537 ths
    if (GET_LMASK64(T0) <= 3)
228 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24));
229 4e9f8537 ths
230 4e9f8537 ths
    if (GET_LMASK64(T0) <= 2)
231 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16));
232 4e9f8537 ths
233 4e9f8537 ths
    if (GET_LMASK64(T0) <= 1)
234 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8));
235 4e9f8537 ths
236 4e9f8537 ths
    if (GET_LMASK64(T0) <= 0)
237 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1);
238 4e9f8537 ths
239 8f6f6026 ths
    FORCE_RET();
240 c570fd16 ths
}
241 c570fd16 ths
242 c570fd16 ths
void glue(op_sdr, MEMSUFFIX) (void)
243 c570fd16 ths
{
244 4e9f8537 ths
    glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
245 4e9f8537 ths
246 4e9f8537 ths
    if (GET_LMASK64(T0) >= 1)
247 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
248 4e9f8537 ths
249 4e9f8537 ths
    if (GET_LMASK64(T0) >= 2)
250 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
251 4e9f8537 ths
252 4e9f8537 ths
    if (GET_LMASK64(T0) >= 3)
253 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
254 4e9f8537 ths
255 4e9f8537 ths
    if (GET_LMASK64(T0) >= 4)
256 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32));
257 4e9f8537 ths
258 4e9f8537 ths
    if (GET_LMASK64(T0) >= 5)
259 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40));
260 4e9f8537 ths
261 4e9f8537 ths
    if (GET_LMASK64(T0) >= 6)
262 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48));
263 4e9f8537 ths
264 4e9f8537 ths
    if (GET_LMASK64(T0) == 7)
265 4e9f8537 ths
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56));
266 4e9f8537 ths
267 8f6f6026 ths
    FORCE_RET();
268 c570fd16 ths
}
269 d26bc211 ths
#endif /* TARGET_MIPS64 */
270 c570fd16 ths
271 5a5012ec ths
void glue(op_luxc1, MEMSUFFIX) (void)
272 5a5012ec ths
{
273 93b12ccc ths
    DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
274 8f6f6026 ths
    FORCE_RET();
275 5a5012ec ths
}
276 5a5012ec ths
void glue(op_suxc1, MEMSUFFIX) (void)
277 5a5012ec ths
{
278 93b12ccc ths
    glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
279 8f6f6026 ths
    FORCE_RET();
280 5a5012ec ths
}