Statistics
| Branch: | Revision:

root / target-ppc / op_helper_mem.h @ d9bce9d9

History | View | Annotate | Download (8.4 kB)

1
/*
2
 *  PowerPC emulation micro-operations helpers for qemu.
3
 *
4
 *  Copyright (c) 2003-2007 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
/* Multiple word / string load and store */
22
static inline target_ulong glue(ld32r, MEMSUFFIX) (target_ulong EA)
23
{
24
    uint32_t tmp = glue(ldl, MEMSUFFIX)(EA);
25
    return ((tmp & 0xFF000000UL) >> 24) | ((tmp & 0x00FF0000UL) >> 8) |
26
        ((tmp & 0x0000FF00UL) << 8) | ((tmp & 0x000000FFUL) << 24);
27
}
28

    
29
static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, target_ulong data)
30
{
31
    uint32_t tmp =
32
        ((data & 0xFF000000UL) >> 24) | ((data & 0x00FF0000UL) >> 8) |
33
        ((data & 0x0000FF00UL) << 8) | ((data & 0x000000FFUL) << 24);
34
    glue(stl, MEMSUFFIX)(EA, tmp);
35
}
36

    
37
void glue(do_lmw, MEMSUFFIX) (int dst)
38
{
39
    for (; dst < 32; dst++, T0 += 4) {
40
        ugpr(dst) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
41
    }
42
}
43

    
44
#if defined(TARGET_PPC64)
45
void glue(do_lmw_64, MEMSUFFIX) (int dst)
46
{
47
    for (; dst < 32; dst++, T0 += 4) {
48
        ugpr(dst) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
49
    }
50
}
51
#endif
52

    
53
void glue(do_stmw, MEMSUFFIX) (int src)
54
{
55
    for (; src < 32; src++, T0 += 4) {
56
        glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src));
57
    }
58
}
59

    
60
#if defined(TARGET_PPC64)
61
void glue(do_stmw_64, MEMSUFFIX) (int src)
62
{
63
    for (; src < 32; src++, T0 += 4) {
64
        glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src));
65
    }
66
}
67
#endif
68

    
69
void glue(do_lmw_le, MEMSUFFIX) (int dst)
70
{
71
    for (; dst < 32; dst++, T0 += 4) {
72
        ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
73
    }
74
}
75

    
76
#if defined(TARGET_PPC64)
77
void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
78
{
79
    for (; dst < 32; dst++, T0 += 4) {
80
        ugpr(dst) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
81
    }
82
}
83
#endif
84

    
85
void glue(do_stmw_le, MEMSUFFIX) (int src)
86
{
87
    for (; src < 32; src++, T0 += 4) {
88
        glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src));
89
    }
90
}
91

    
92
#if defined(TARGET_PPC64)
93
void glue(do_stmw_le_64, MEMSUFFIX) (int src)
94
{
95
    for (; src < 32; src++, T0 += 4) {
96
        glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src));
97
    }
98
}
99
#endif
100

    
101
void glue(do_lsw, MEMSUFFIX) (int dst)
102
{
103
    uint32_t tmp;
104
    int sh;
105

    
106
    for (; T1 > 3; T1 -= 4, T0 += 4) {
107
        ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint32_t)T0);
108
        if (unlikely(dst == 32))
109
            dst = 0;
110
    }
111
    if (unlikely(T1 != 0)) {
112
        tmp = 0;
113
        for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
114
            tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
115
        }
116
        ugpr(dst) = tmp;
117
    }
118
}
119

    
120
#if defined(TARGET_PPC64)
121
void glue(do_lsw_64, MEMSUFFIX) (int dst)
122
{
123
    uint32_t tmp;
124
    int sh;
125

    
126
    for (; T1 > 3; T1 -= 4, T0 += 4) {
127
        ugpr(dst++) = glue(ldl, MEMSUFFIX)((uint64_t)T0);
128
        if (unlikely(dst == 32))
129
            dst = 0;
130
    }
131
    if (unlikely(T1 != 0)) {
132
        tmp = 0;
133
        for (sh = 24; T1 > 0; T1--, T0++, sh -= 8) {
134
            tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
135
        }
136
        ugpr(dst) = tmp;
137
    }
138
}
139
#endif
140

    
141
void glue(do_stsw, MEMSUFFIX) (int src)
142
{
143
    int sh;
144

    
145
    for (; T1 > 3; T1 -= 4, T0 += 4) {
146
        glue(stl, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
147
        if (unlikely(src == 32))
148
            src = 0;
149
    }
150
    if (unlikely(T1 != 0)) {
151
        for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
152
            glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
153
    }
154
}
155

    
156
#if defined(TARGET_PPC64)
157
void glue(do_stsw_64, MEMSUFFIX) (int src)
158
{
159
    int sh;
160

    
161
    for (; T1 > 3; T1 -= 4, T0 += 4) {
162
        glue(stl, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
163
        if (unlikely(src == 32))
164
            src = 0;
165
    }
166
    if (unlikely(T1 != 0)) {
167
        for (sh = 24; T1 > 0; T1--, T0++, sh -= 8)
168
            glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
169
    }
170
}
171
#endif
172

    
173
void glue(do_lsw_le, MEMSUFFIX) (int dst)
174
{
175
    uint32_t tmp;
176
    int sh;
177

    
178
    for (; T1 > 3; T1 -= 4, T0 += 4) {
179
        ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint32_t)T0);
180
        if (unlikely(dst == 32))
181
            dst = 0;
182
    }
183
    if (unlikely(T1 != 0)) {
184
        tmp = 0;
185
        for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
186
            tmp |= glue(ldub, MEMSUFFIX)((uint32_t)T0) << sh;
187
        }
188
        ugpr(dst) = tmp;
189
    }
190
}
191

    
192
#if defined(TARGET_PPC64)
193
void glue(do_lsw_le_64, MEMSUFFIX) (int dst)
194
{
195
    uint32_t tmp;
196
    int sh;
197

    
198
    for (; T1 > 3; T1 -= 4, T0 += 4) {
199
        ugpr(dst++) = glue(ld32r, MEMSUFFIX)((uint64_t)T0);
200
        if (unlikely(dst == 32))
201
            dst = 0;
202
    }
203
    if (unlikely(T1 != 0)) {
204
        tmp = 0;
205
        for (sh = 0; T1 > 0; T1--, T0++, sh += 8) {
206
            tmp |= glue(ldub, MEMSUFFIX)((uint64_t)T0) << sh;
207
        }
208
        ugpr(dst) = tmp;
209
    }
210
}
211
#endif
212

    
213
void glue(do_stsw_le, MEMSUFFIX) (int src)
214
{
215
    int sh;
216

    
217
    for (; T1 > 3; T1 -= 4, T0 += 4) {
218
        glue(st32r, MEMSUFFIX)((uint32_t)T0, ugpr(src++));
219
        if (unlikely(src == 32))
220
            src = 0;
221
    }
222
    if (unlikely(T1 != 0)) {
223
        for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
224
            glue(stb, MEMSUFFIX)((uint32_t)T0, (ugpr(src) >> sh) & 0xFF);
225
    }
226
}
227

    
228
#if defined(TARGET_PPC64)
229
void glue(do_stsw_le_64, MEMSUFFIX) (int src)
230
{
231
    int sh;
232

    
233
    for (; T1 > 3; T1 -= 4, T0 += 4) {
234
        glue(st32r, MEMSUFFIX)((uint64_t)T0, ugpr(src++));
235
        if (unlikely(src == 32))
236
            src = 0;
237
    }
238
    if (unlikely(T1 != 0)) {
239
        for (sh = 0; T1 > 0; T1--, T0++, sh += 8)
240
            glue(stb, MEMSUFFIX)((uint64_t)T0, (ugpr(src) >> sh) & 0xFF);
241
    }
242
}
243
#endif
244

    
245
/* PPC 601 specific instructions (POWER bridge) */
246
// XXX: to be tested
247
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb)
248
{
249
    int i, c, d, reg;
250

    
251
    d = 24;
252
    reg = dest;
253
    for (i = 0; i < T1; i++) {
254
        c = glue(ldub, MEMSUFFIX)((uint32_t)T0++);
255
        /* ra (if not 0) and rb are never modified */
256
        if (likely(reg != rb && (ra == 0 || reg != ra))) {
257
            ugpr(reg) = (ugpr(reg) & ~(0xFF << d)) | (c << d);
258
        }
259
        if (unlikely(c == T2))
260
            break;
261
        if (likely(d != 0)) {
262
            d -= 8;
263
        } else {
264
            d = 24;
265
            reg++;
266
            reg = reg & 0x1F;
267
        }
268
    }
269
    T0 = i;
270
}
271

    
272
/* XXX: TAGs are not managed */
273
void glue(do_POWER2_lfq, MEMSUFFIX) (void)
274
{
275
    FT0 = glue(ldfq, MEMSUFFIX)((uint32_t)T0);
276
    FT1 = glue(ldfq, MEMSUFFIX)((uint32_t)(T0 + 4));
277
}
278

    
279
static inline double glue(ldfqr, MEMSUFFIX) (target_ulong EA)
280
{
281
    union {
282
        double d;
283
        uint64_t u;
284
    } u;
285

    
286
    u.d = glue(ldfq, MEMSUFFIX)(EA);
287
    u.u = ((u.u & 0xFF00000000000000ULL) >> 56) |
288
        ((u.u & 0x00FF000000000000ULL) >> 40) |
289
        ((u.u & 0x0000FF0000000000ULL) >> 24) |
290
        ((u.u & 0x000000FF00000000ULL) >> 8) |
291
        ((u.u & 0x00000000FF000000ULL) << 8) |
292
        ((u.u & 0x0000000000FF0000ULL) << 24) |
293
        ((u.u & 0x000000000000FF00ULL) << 40) |
294
        ((u.u & 0x00000000000000FFULL) << 56);
295

    
296
    return u.d;
297
}
298

    
299
void glue(do_POWER2_lfq_le, MEMSUFFIX) (void)
300
{
301
    FT0 = glue(ldfqr, MEMSUFFIX)((uint32_t)(T0 + 4));
302
    FT1 = glue(ldfqr, MEMSUFFIX)((uint32_t)T0);
303
}
304

    
305
void glue(do_POWER2_stfq, MEMSUFFIX) (void)
306
{
307
    glue(stfq, MEMSUFFIX)((uint32_t)T0, FT0);
308
    glue(stfq, MEMSUFFIX)((uint32_t)(T0 + 4), FT1);
309
}
310

    
311
static inline void glue(stfqr, MEMSUFFIX) (target_ulong EA, double d)
312
{
313
    union {
314
        double d;
315
        uint64_t u;
316
    } u;
317

    
318
    u.d = d;
319
    u.u = ((u.u & 0xFF00000000000000ULL) >> 56) |
320
        ((u.u & 0x00FF000000000000ULL) >> 40) |
321
        ((u.u & 0x0000FF0000000000ULL) >> 24) |
322
        ((u.u & 0x000000FF00000000ULL) >> 8) |
323
        ((u.u & 0x00000000FF000000ULL) << 8) |
324
        ((u.u & 0x0000000000FF0000ULL) << 24) |
325
        ((u.u & 0x000000000000FF00ULL) << 40) |
326
        ((u.u & 0x00000000000000FFULL) << 56);
327
    glue(stfq, MEMSUFFIX)(EA, u.d);
328
}
329

    
330
void glue(do_POWER2_stfq_le, MEMSUFFIX) (void)
331
{
332
    glue(stfqr, MEMSUFFIX)((uint32_t)(T0 + 4), FT0);
333
    glue(stfqr, MEMSUFFIX)((uint32_t)T0, FT1);
334
}
335

    
336
#undef MEMSUFFIX