Revision b6a8c26b

/dev/null
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 */

Also available in: Unified diff