Revision 76a66253 target-ppc/op_mem.h

b/target-ppc/op_mem.h
1
/* External helpers */
2
void glue(do_lsw, MEMSUFFIX) (int dst);
3
void glue(do_stsw, MEMSUFFIX) (int src);
1
/*
2
 *  PowerPC emulation micro-operations 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
 */
4 20

  
5 21
static inline uint16_t glue(ld16r, MEMSUFFIX) (target_ulong EA)
6 22
{
......
11 27
static inline int32_t glue(ld16rs, MEMSUFFIX) (target_ulong EA)
12 28
{
13 29
    int16_t tmp = glue(lduw, MEMSUFFIX)(EA);
14
    return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8);
30
    return (int16_t)((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8);
15 31
}
16 32

  
17 33
static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA)
......
80 96
/***                    Integer load and store multiple                    ***/
81 97
PPC_OP(glue(lmw, MEMSUFFIX))
82 98
{
83
    int dst = PARAM(1);
84

  
85
    for (; dst < 32; dst++, T0 += 4) {
86
        ugpr(dst) = glue(ldl, MEMSUFFIX)(T0);
87
    }
99
    glue(do_lmw, MEMSUFFIX)(PARAM1);
88 100
    RETURN();
89 101
}
90 102

  
91
PPC_OP(glue(stmw, MEMSUFFIX))
103
PPC_OP(glue(lmw_le, MEMSUFFIX))
92 104
{
93
    int src = PARAM(1);
94

  
95
    for (; src < 32; src++, T0 += 4) {
96
        glue(stl, MEMSUFFIX)(T0, ugpr(src));
97
    }
105
    glue(do_lmw_le, MEMSUFFIX)(PARAM1);
98 106
    RETURN();
99 107
}
100 108

  
101
PPC_OP(glue(lmw_le, MEMSUFFIX))
109
PPC_OP(glue(stmw, MEMSUFFIX))
102 110
{
103
    int dst = PARAM(1);
104

  
105
    for (; dst < 32; dst++, T0 += 4) {
106
        ugpr(dst) = glue(ld32r, MEMSUFFIX)(T0);
107
    }
111
    glue(do_stmw, MEMSUFFIX)(PARAM1);
108 112
    RETURN();
109 113
}
110 114

  
111 115
PPC_OP(glue(stmw_le, MEMSUFFIX))
112 116
{
113
    int src = PARAM(1);
114

  
115
    for (; src < 32; src++, T0 += 4) {
116
        glue(st32r, MEMSUFFIX)(T0, ugpr(src));
117
    }
117
    glue(do_stmw_le, MEMSUFFIX)(PARAM1);
118 118
    RETURN();
119 119
}
120 120

  
......
125 125
    RETURN();
126 126
}
127 127

  
128
void glue(do_lsw_le, MEMSUFFIX) (int dst);
129 128
PPC_OP(glue(lswi_le, MEMSUFFIX))
130 129
{
131 130
    glue(do_lsw_le, MEMSUFFIX)(PARAM(1));
......
139 138
 */
140 139
PPC_OP(glue(lswx, MEMSUFFIX))
141 140
{
142
    if (T1 > 0) {
143
        if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) ||
144
            (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) {
141
    if (unlikely(T1 > 0)) {
142
        if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
143
                     (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
145 144
            do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
146 145
        } else {
147 146
            glue(do_lsw, MEMSUFFIX)(PARAM(1));
......
152 151

  
153 152
PPC_OP(glue(lswx_le, MEMSUFFIX))
154 153
{
155
    if (T1 > 0) {
156
        if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) ||
157
            (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) {
154
    if (unlikely(T1 > 0)) {
155
        if (unlikely((PARAM1 < PARAM2 && (PARAM1 + T1) > PARAM2) ||
156
                     (PARAM1 < PARAM3 && (PARAM1 + T1) > PARAM3))) {
158 157
            do_raise_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
159 158
        } else {
160 159
            glue(do_lsw_le, MEMSUFFIX)(PARAM(1));
......
169 168
    RETURN();
170 169
}
171 170

  
172
void glue(do_stsw_le, MEMSUFFIX) (int src);
173 171
PPC_OP(glue(stsw_le, MEMSUFFIX))
174 172
{
175 173
    glue(do_stsw_le, MEMSUFFIX)(PARAM(1));
......
180 178
#define PPC_STF_OP(name, op)                                                  \
181 179
PPC_OP(glue(glue(st, name), MEMSUFFIX))                                       \
182 180
{                                                                             \
183
    glue(op, MEMSUFFIX)(T0, FT1);                                     \
181
    glue(op, MEMSUFFIX)(T0, FT0);                                             \
184 182
    RETURN();                                                                 \
185 183
}
186 184

  
......
228 226
#define PPC_LDF_OP(name, op)                                                  \
229 227
PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \
230 228
{                                                                             \
231
    FT1 = glue(op, MEMSUFFIX)(T0);                                    \
229
    FT0 = glue(op, MEMSUFFIX)(T0);                                            \
232 230
    RETURN();                                                                 \
233 231
}
234 232

  
......
277 275
/* Load and set reservation */
278 276
PPC_OP(glue(lwarx, MEMSUFFIX))
279 277
{
280
    if (T0 & 0x03) {
278
    if (unlikely(T0 & 0x03)) {
281 279
        do_raise_exception(EXCP_ALIGN);
282 280
    } else {
283
       T1 = glue(ldl, MEMSUFFIX)(T0);
284
       regs->reserve = T0;
281
        T1 = glue(ldl, MEMSUFFIX)(T0);
282
        regs->reserve = T0;
285 283
    }
286 284
    RETURN();
287 285
}
288 286

  
289 287
PPC_OP(glue(lwarx_le, MEMSUFFIX))
290 288
{
291
    if (T0 & 0x03) {
289
    if (unlikely(T0 & 0x03)) {
292 290
        do_raise_exception(EXCP_ALIGN);
293 291
    } else {
294
       T1 = glue(ld32r, MEMSUFFIX)(T0);
295
       regs->reserve = T0;
292
        T1 = glue(ld32r, MEMSUFFIX)(T0);
293
        regs->reserve = T0;
296 294
    }
297 295
    RETURN();
298 296
}
......
300 298
/* Store with reservation */
301 299
PPC_OP(glue(stwcx, MEMSUFFIX))
302 300
{
303
    if (T0 & 0x03) {
301
    if (unlikely(T0 & 0x03)) {
304 302
        do_raise_exception(EXCP_ALIGN);
305 303
    } else {
306
        if (regs->reserve != T0) {
304
        if (unlikely(regs->reserve != T0)) {
307 305
            env->crf[0] = xer_ov;
308 306
        } else {
309 307
            glue(stl, MEMSUFFIX)(T0, T1);
310 308
            env->crf[0] = xer_ov | 0x02;
311 309
        }
312 310
    }
313
    regs->reserve = 0;
311
    regs->reserve = -1;
314 312
    RETURN();
315 313
}
316 314

  
317 315
PPC_OP(glue(stwcx_le, MEMSUFFIX))
318 316
{
319
    if (T0 & 0x03) {
317
    if (unlikely(T0 & 0x03)) {
320 318
        do_raise_exception(EXCP_ALIGN);
321 319
    } else {
322
        if (regs->reserve != T0) {
320
        if (unlikely(regs->reserve != T0)) {
323 321
            env->crf[0] = xer_ov;
324 322
        } else {
325 323
            glue(st32r, MEMSUFFIX)(T0, T1);
326 324
            env->crf[0] = xer_ov | 0x02;
327 325
        }
328 326
    }
329
    regs->reserve = 0;
327
    regs->reserve = -1;
330 328
    RETURN();
331 329
}
332 330

  
......
340 338
    glue(stl, MEMSUFFIX)(T0 + 0x14, 0);
341 339
    glue(stl, MEMSUFFIX)(T0 + 0x18, 0);
342 340
    glue(stl, MEMSUFFIX)(T0 + 0x1C, 0);
341
#if DCACHE_LINE_SIZE == 64
342
    /* XXX: cache line size should be 64 for POWER & PowerPC 601 */
343
    glue(stl, MEMSUFFIX)(T0 + 0x20UL, 0);
344
    glue(stl, MEMSUFFIX)(T0 + 0x24UL, 0);
345
    glue(stl, MEMSUFFIX)(T0 + 0x28UL, 0);
346
    glue(stl, MEMSUFFIX)(T0 + 0x2CUL, 0);
347
    glue(stl, MEMSUFFIX)(T0 + 0x30UL, 0);
348
    glue(stl, MEMSUFFIX)(T0 + 0x34UL, 0);
349
    glue(stl, MEMSUFFIX)(T0 + 0x38UL, 0);
350
    glue(stl, MEMSUFFIX)(T0 + 0x3CUL, 0);
351
#endif
343 352
    RETURN();
344 353
}
345 354

  
......
368 377
    RETURN();
369 378
}
370 379

  
380
/* XXX: those micro-ops need tests ! */
381
/* PowerPC 601 specific instructions (POWER bridge) */
382
void OPPROTO glue(op_POWER_lscbx, MEMSUFFIX) (void)
383
{
384
    /* When byte count is 0, do nothing */
385
    if (likely(T1 > 0)) {
386
        glue(do_POWER_lscbx, MEMSUFFIX)(PARAM1, PARAM2, PARAM3);
387
    }
388
    RETURN();
389
}
390

  
391
/* POWER2 quad load and store */
392
/* XXX: TAGs are not managed */
393
void OPPROTO glue(op_POWER2_lfq, MEMSUFFIX) (void)
394
{
395
    glue(do_POWER2_lfq, MEMSUFFIX)();
396
    RETURN();
397
}
398

  
399
void glue(op_POWER2_lfq_le, MEMSUFFIX) (void)
400
{
401
    glue(do_POWER2_lfq_le, MEMSUFFIX)();
402
    RETURN();
403
}
404

  
405
void OPPROTO glue(op_POWER2_stfq, MEMSUFFIX) (void)
406
{
407
    glue(do_POWER2_stfq, MEMSUFFIX)();
408
    RETURN();
409
}
410

  
411
void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void)
412
{
413
    glue(do_POWER2_stfq_le, MEMSUFFIX)();
414
    RETURN();
415
}
416

  
371 417
#undef MEMSUFFIX

Also available in: Unified diff