Statistics
| Branch: | Revision:

root / target-mips / op_mem.c @ aa0bf00b

History | View | Annotate | Download (7.5 kB)

1
/*
2
 *  MIPS emulation memory micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2004-2005 Jocelyn Mayer
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20

    
21
/* "half" load and stores.  We must do the memory access inline,
22
   or fault handling won't work.  */
23

    
24
#ifdef TARGET_WORDS_BIGENDIAN
25
#define GET_LMASK(v) ((v) & 3)
26
#define GET_OFFSET(addr, offset) (addr + (offset))
27
#else
28
#define GET_LMASK(v) (((v) & 3) ^ 3)
29
#define GET_OFFSET(addr, offset) (addr - (offset))
30
#endif
31

    
32
void glue(op_lwl, MEMSUFFIX) (void)
33
{
34
    target_ulong tmp;
35

    
36
    tmp = glue(ldub, MEMSUFFIX)(T0);
37
    T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
38

    
39
    if (GET_LMASK(T0) <= 2) {
40
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
41
        T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
42
    }
43

    
44
    if (GET_LMASK(T0) <= 1) {
45
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
46
        T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
47
    }
48

    
49
    if (GET_LMASK(T0) == 0) {
50
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
51
        T1 = (T1 & 0xFFFFFF00) | tmp;
52
    }
53
    T1 = (int32_t)T1;
54
    FORCE_RET();
55
}
56

    
57
void glue(op_lwr, MEMSUFFIX) (void)
58
{
59
    target_ulong tmp;
60

    
61
    tmp = glue(ldub, MEMSUFFIX)(T0);
62
    T1 = (T1 & 0xFFFFFF00) | tmp;
63

    
64
    if (GET_LMASK(T0) >= 1) {
65
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
66
        T1 = (T1 & 0xFFFF00FF) | (tmp << 8);
67
    }
68

    
69
    if (GET_LMASK(T0) >= 2) {
70
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
71
        T1 = (T1 & 0xFF00FFFF) | (tmp << 16);
72
    }
73

    
74
    if (GET_LMASK(T0) == 3) {
75
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
76
        T1 = (T1 & 0x00FFFFFF) | (tmp << 24);
77
    }
78
    T1 = (int32_t)T1;
79
    FORCE_RET();
80
}
81

    
82
void glue(op_swl, MEMSUFFIX) (void)
83
{
84
    glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 24));
85

    
86
    if (GET_LMASK(T0) <= 2)
87
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16));
88

    
89
    if (GET_LMASK(T0) <= 1)
90
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8));
91

    
92
    if (GET_LMASK(T0) == 0)
93
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)T1);
94

    
95
    FORCE_RET();
96
}
97

    
98
void glue(op_swr, MEMSUFFIX) (void)
99
{
100
    glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
101

    
102
    if (GET_LMASK(T0) >= 1)
103
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
104

    
105
    if (GET_LMASK(T0) >= 2)
106
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
107

    
108
    if (GET_LMASK(T0) == 3)
109
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
110

    
111
    FORCE_RET();
112
}
113

    
114
#if defined(TARGET_MIPS64)
115
/* "half" load and stores.  We must do the memory access inline,
116
   or fault handling won't work.  */
117

    
118
#ifdef TARGET_WORDS_BIGENDIAN
119
#define GET_LMASK64(v) ((v) & 7)
120
#else
121
#define GET_LMASK64(v) (((v) & 7) ^ 7)
122
#endif
123

    
124
void glue(op_ldl, MEMSUFFIX) (void)
125
{
126
    uint64_t tmp;
127

    
128
    tmp = glue(ldub, MEMSUFFIX)(T0);
129
    T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
130

    
131
    if (GET_LMASK64(T0) <= 6) {
132
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 1));
133
        T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
134
    }
135

    
136
    if (GET_LMASK64(T0) <= 5) {
137
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 2));
138
        T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
139
    }
140

    
141
    if (GET_LMASK64(T0) <= 4) {
142
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 3));
143
        T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
144
    }
145

    
146
    if (GET_LMASK64(T0) <= 3) {
147
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 4));
148
        T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
149
    }
150

    
151
    if (GET_LMASK64(T0) <= 2) {
152
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 5));
153
        T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
154
    }
155

    
156
    if (GET_LMASK64(T0) <= 1) {
157
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 6));
158
        T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
159
    }
160

    
161
    if (GET_LMASK64(T0) == 0) {
162
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, 7));
163
        T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
164
    }
165

    
166
    FORCE_RET();
167
}
168

    
169
void glue(op_ldr, MEMSUFFIX) (void)
170
{
171
    uint64_t tmp;
172

    
173
    tmp = glue(ldub, MEMSUFFIX)(T0);
174
    T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
175

    
176
    if (GET_LMASK64(T0) >= 1) {
177
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -1));
178
        T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp  << 8);
179
    }
180

    
181
    if (GET_LMASK64(T0) >= 2) {
182
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -2));
183
        T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
184
    }
185

    
186
    if (GET_LMASK64(T0) >= 3) {
187
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -3));
188
        T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
189
    }
190

    
191
    if (GET_LMASK64(T0) >= 4) {
192
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -4));
193
        T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
194
    }
195

    
196
    if (GET_LMASK64(T0) >= 5) {
197
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -5));
198
        T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
199
    }
200

    
201
    if (GET_LMASK64(T0) >= 6) {
202
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -6));
203
        T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
204
    }
205

    
206
    if (GET_LMASK64(T0) == 7) {
207
        tmp = glue(ldub, MEMSUFFIX)(GET_OFFSET(T0, -7));
208
        T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
209
    }
210

    
211
    FORCE_RET();
212
}
213

    
214
void glue(op_sdl, MEMSUFFIX) (void)
215
{
216
    glue(stb, MEMSUFFIX)(T0, (uint8_t)(T1 >> 56));
217

    
218
    if (GET_LMASK64(T0) <= 6)
219
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48));
220

    
221
    if (GET_LMASK64(T0) <= 5)
222
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40));
223

    
224
    if (GET_LMASK64(T0) <= 4)
225
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32));
226

    
227
    if (GET_LMASK64(T0) <= 3)
228
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24));
229

    
230
    if (GET_LMASK64(T0) <= 2)
231
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16));
232

    
233
    if (GET_LMASK64(T0) <= 1)
234
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8));
235

    
236
    if (GET_LMASK64(T0) <= 0)
237
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, 7), (uint8_t)T1);
238

    
239
    FORCE_RET();
240
}
241

    
242
void glue(op_sdr, MEMSUFFIX) (void)
243
{
244
    glue(stb, MEMSUFFIX)(T0, (uint8_t)T1);
245

    
246
    if (GET_LMASK64(T0) >= 1)
247
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8));
248

    
249
    if (GET_LMASK64(T0) >= 2)
250
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16));
251

    
252
    if (GET_LMASK64(T0) >= 3)
253
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24));
254

    
255
    if (GET_LMASK64(T0) >= 4)
256
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32));
257

    
258
    if (GET_LMASK64(T0) >= 5)
259
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40));
260

    
261
    if (GET_LMASK64(T0) >= 6)
262
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48));
263

    
264
    if (GET_LMASK64(T0) == 7)
265
        glue(stb, MEMSUFFIX)(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56));
266

    
267
    FORCE_RET();
268
}
269
#endif /* TARGET_MIPS64 */
270

    
271
void glue(op_luxc1, MEMSUFFIX) (void)
272
{
273
    DT0 = glue(ldq, MEMSUFFIX)(T0 & ~0x7);
274
    FORCE_RET();
275
}
276
void glue(op_suxc1, MEMSUFFIX) (void)
277
{
278
    glue(stq, MEMSUFFIX)(T0 & ~0x7, DT0);
279
    FORCE_RET();
280
}