Statistics
| Branch: | Revision:

root / target-ppc / op_mem.h @ 9a64fbe4

History | View | Annotate | Download (5.9 kB)

1
/* External helpers */
2
void glue(do_lsw, MEMSUFFIX) (int dst);
3
void glue(do_stsw, MEMSUFFIX) (int src);
4

    
5
/* Internal helpers for sign extension and byte-reverse */
6
static inline uint32_t glue(_ld16x, MEMSUFFIX) (void *EA, int type)
7
{
8
    return s_ext16(glue(_lduw, MEMSUFFIX)(EA, type));
9
}
10

    
11
static inline uint16_t glue(_ld16r, MEMSUFFIX) (void *EA, int type)
12
{
13
    uint16_t tmp = glue(_lduw, MEMSUFFIX)(EA, type);
14
    return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8);
15
}
16

    
17
static inline uint32_t glue(_ld32r, MEMSUFFIX) (void *EA, int type)
18
{
19
    uint32_t tmp = glue(_ldl, MEMSUFFIX)(EA, type);
20
    return ((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) |
21
        ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
22
}
23

    
24
static inline void glue(_st16r, MEMSUFFIX) (void *EA, uint16_t data, int type)
25
{
26
    uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8);
27
    glue(_stw, MEMSUFFIX)(EA, tmp, type);
28
}
29

    
30
static inline void glue(_st32r, MEMSUFFIX) (void *EA, uint32_t data, int type)
31
{
32
    uint32_t tmp = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) |
33
        ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24);
34
    glue(_stl, MEMSUFFIX)(EA, tmp, type);
35
}
36

    
37
/***                             Integer load                              ***/
38
#define PPC_LD_OP(name, op)                                                   \
39
PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \
40
{                                                                             \
41
    T1 = glue(op, MEMSUFFIX)((void *)T0, ACCESS_INT);                         \
42
    RETURN();                                                                 \
43
}
44

    
45
#define PPC_ST_OP(name, op)                                                   \
46
PPC_OP(glue(glue(st, name), MEMSUFFIX))                                       \
47
{                                                                             \
48
    glue(op, MEMSUFFIX)((void *)T0, T1, ACCESS_INT);                          \
49
    RETURN();                                                                 \
50
}
51

    
52
PPC_LD_OP(bz, _ldub);
53
PPC_LD_OP(ha, _ld16x);
54
PPC_LD_OP(hz, _lduw);
55
PPC_LD_OP(wz, _ldl);
56

    
57
/***                              Integer store                            ***/
58
PPC_ST_OP(b, _stb);
59
PPC_ST_OP(h, _stw);
60
PPC_ST_OP(w, _stl);
61

    
62
/***                Integer load and store with byte reverse               ***/
63
PPC_LD_OP(hbr, _ld16r);
64
PPC_LD_OP(wbr, _ld32r);
65
PPC_ST_OP(hbr, _st16r);
66
PPC_ST_OP(wbr, _st32r);
67

    
68
/***                    Integer load and store multiple                    ***/
69
PPC_OP(glue(lmw, MEMSUFFIX))
70
{
71
    int dst = PARAM(1);
72

    
73
    for (; dst < 32; dst++, T0 += 4) {
74
        ugpr(dst) = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_INT);
75
    }
76
    RETURN();
77
}
78

    
79
PPC_OP(glue(stmw, MEMSUFFIX))
80
{
81
    int src = PARAM(1);
82

    
83
    for (; src < 32; src++, T0 += 4) {
84
        glue(_stl, MEMSUFFIX)((void *)T0, ugpr(src), ACCESS_INT);
85
    }
86
    RETURN();
87
}
88

    
89
/***                    Integer load and store strings                     ***/
90
PPC_OP(glue(lswi, MEMSUFFIX))
91
{
92
    glue(do_lsw, MEMSUFFIX)(PARAM(1));
93
    RETURN();
94
}
95

    
96
/* PPC32 specification says we must generate an exception if
97
 * rA is in the range of registers to be loaded.
98
 * In an other hand, IBM says this is valid, but rA won't be loaded.
99
 * For now, I'll follow the spec...
100
 */
101
PPC_OP(glue(lswx, MEMSUFFIX))
102
{
103
    if (T1 > 0) {
104
        if ((PARAM(1) < PARAM(2) && (PARAM(1) + T1) > PARAM(2)) ||
105
            (PARAM(1) < PARAM(3) && (PARAM(1) + T1) > PARAM(3))) {
106
            do_queue_exception_err(EXCP_PROGRAM, EXCP_INVAL | EXCP_INVAL_LSWX);
107
            do_process_exceptions();
108
        } else {
109
            glue(do_lsw, MEMSUFFIX)(PARAM(1));
110
        }
111
    }
112
    RETURN();
113
}
114

    
115
PPC_OP(glue(stsw, MEMSUFFIX))
116
{
117
    glue(do_stsw, MEMSUFFIX)(PARAM(1));
118
    RETURN();
119
}
120

    
121
/***                         Floating-point store                          ***/
122
#define PPC_STF_OP(name, op)                                                  \
123
PPC_OP(glue(glue(st, name), MEMSUFFIX))                                       \
124
{                                                                             \
125
    glue(op, MEMSUFFIX)((void *)T0, FT1);                                     \
126
    RETURN();                                                                 \
127
}
128

    
129
PPC_STF_OP(fd, stfq);
130
PPC_STF_OP(fs, stfl);
131

    
132
/***                         Floating-point load                           ***/
133
#define PPC_LDF_OP(name, op)                                                  \
134
PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \
135
{                                                                             \
136
    FT1 = glue(op, MEMSUFFIX)((void *)T0);                                    \
137
    RETURN();                                                                 \
138
}
139

    
140
PPC_LDF_OP(fd, ldfq);
141
PPC_LDF_OP(fs, ldfl);
142

    
143
/* Store with reservation */
144
PPC_OP(glue(stwcx, MEMSUFFIX))
145
{
146
    if (T0 & 0x03) {
147
        do_queue_exception(EXCP_ALIGN);
148
        do_process_exceptions();
149
    } else {
150
        if (regs->reserve != T0) {
151
            env->crf[0] = xer_ov;
152
        } else {
153
            glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_RES);
154
            env->crf[0] = xer_ov | 0x02;
155
        }
156
    }
157
    regs->reserve = 0;
158
    RETURN();
159
}
160

    
161
PPC_OP(glue(dcbz, MEMSUFFIX))
162
{
163
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x00), 0, ACCESS_INT);
164
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x04), 0, ACCESS_INT);
165
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x08), 0, ACCESS_INT);
166
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x0C), 0, ACCESS_INT);
167
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x10), 0, ACCESS_INT);
168
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x14), 0, ACCESS_INT);
169
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x18), 0, ACCESS_INT);
170
    glue(_stl, MEMSUFFIX)((void *)(T0 + 0x1C), 0, ACCESS_INT);
171
    RETURN();
172
}
173

    
174
/* External access */
175
PPC_OP(glue(eciwx, MEMSUFFIX))
176
{
177
    T1 = glue(_ldl, MEMSUFFIX)((void *)T0, ACCESS_EXT);
178
    RETURN();
179
}
180

    
181
PPC_OP(glue(ecowx, MEMSUFFIX))
182
{
183
    glue(_stl, MEMSUFFIX)((void *)T0, T1, ACCESS_EXT);
184
    RETURN();
185
}
186

    
187
#undef MEMSUFFIX