Statistics
| Branch: | Revision:

root / target-ppc / op_mem.h @ 985a19d6

History | View | Annotate | Download (5.8 kB)

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

    
5
static inline uint16_t glue(ld16r, MEMSUFFIX) (void *EA)
6
{
7
    uint16_t tmp = glue(lduw, MEMSUFFIX)(EA);
8
    return ((tmp & 0xFF00) >> 8) | ((tmp & 0x00FF) << 8);
9
}
10

    
11
static inline uint32_t glue(ld32r, MEMSUFFIX) (void *EA)
12
{
13
    uint32_t tmp = glue(ldl, MEMSUFFIX)(EA);
14
    return ((tmp & 0xFF000000) >> 24) | ((tmp & 0x00FF0000) >> 8) |
15
        ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
16
}
17

    
18
static inline void glue(st16r, MEMSUFFIX) (void *EA, uint16_t data)
19
{
20
    uint16_t tmp = ((data & 0xFF00) >> 8) | ((data & 0x00FF) << 8);
21
    glue(stw, MEMSUFFIX)(EA, tmp);
22
}
23

    
24
static inline void glue(st32r, MEMSUFFIX) (void *EA, uint32_t data)
25
{
26
    uint32_t tmp = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) |
27
        ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24);
28
    glue(stl, MEMSUFFIX)(EA, tmp);
29
}
30

    
31
/***                             Integer load                              ***/
32
#define PPC_LD_OP(name, op)                                                   \
33
PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \
34
{                                                                             \
35
    T1 = glue(op, MEMSUFFIX)((void *)T0);                                     \
36
    RETURN();                                                                 \
37
}
38

    
39
#define PPC_ST_OP(name, op)                                                   \
40
PPC_OP(glue(glue(st, name), MEMSUFFIX))                                       \
41
{                                                                             \
42
    glue(op, MEMSUFFIX)((void *)T0, T1);                                      \
43
    RETURN();                                                                 \
44
}
45

    
46
PPC_LD_OP(bz, ldub);
47
PPC_LD_OP(ha, ldsw);
48
PPC_LD_OP(hz, lduw);
49
PPC_LD_OP(wz, ldl);
50

    
51
/***                              Integer store                            ***/
52
PPC_ST_OP(b, stb);
53
PPC_ST_OP(h, stw);
54
PPC_ST_OP(w, stl);
55

    
56
/***                Integer load and store with byte reverse               ***/
57
PPC_LD_OP(hbr, ld16r);
58
PPC_LD_OP(wbr, ld32r);
59
PPC_ST_OP(hbr, st16r);
60
PPC_ST_OP(wbr, st32r);
61

    
62
/***                    Integer load and store multiple                    ***/
63
PPC_OP(glue(lmw, MEMSUFFIX))
64
{
65
    int dst = PARAM(1);
66

    
67
    for (; dst < 32; dst++, T0 += 4) {
68
        ugpr(dst) = glue(ldl, MEMSUFFIX)((void *)T0);
69
    }
70
    RETURN();
71
}
72

    
73
PPC_OP(glue(stmw, MEMSUFFIX))
74
{
75
    int src = PARAM(1);
76

    
77
    for (; src < 32; src++, T0 += 4) {
78
        glue(stl, MEMSUFFIX)((void *)T0, ugpr(src));
79
    }
80
    RETURN();
81
}
82

    
83
/***                    Integer load and store strings                     ***/
84
PPC_OP(glue(lswi, MEMSUFFIX))
85
{
86
    glue(do_lsw, MEMSUFFIX)(PARAM(1));
87
    RETURN();
88
}
89

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

    
109
PPC_OP(glue(stsw, MEMSUFFIX))
110
{
111
    glue(do_stsw, MEMSUFFIX)(PARAM(1));
112
    RETURN();
113
}
114

    
115
/***                         Floating-point store                          ***/
116
#define PPC_STF_OP(name, op)                                                  \
117
PPC_OP(glue(glue(st, name), MEMSUFFIX))                                       \
118
{                                                                             \
119
    glue(op, MEMSUFFIX)((void *)T0, FT1);                                     \
120
    RETURN();                                                                 \
121
}
122

    
123
PPC_STF_OP(fd, stfq);
124
PPC_STF_OP(fs, stfl);
125

    
126
/***                         Floating-point load                           ***/
127
#define PPC_LDF_OP(name, op)                                                  \
128
PPC_OP(glue(glue(l, name), MEMSUFFIX))                                        \
129
{                                                                             \
130
    FT1 = glue(op, MEMSUFFIX)((void *)T0);                                    \
131
    RETURN();                                                                 \
132
}
133

    
134
PPC_LDF_OP(fd, ldfq);
135
PPC_LDF_OP(fs, ldfl);
136

    
137
/* Load and set reservation */
138
PPC_OP(glue(lwarx, MEMSUFFIX))
139
{
140
    if (T0 & 0x03) {
141
        do_queue_exception(EXCP_ALIGN);
142
        do_process_exceptions();
143
    } else {
144
        glue(ldl, MEMSUFFIX)((void *)T0);
145
        regs->reserve = T0 & ~0x03;
146
    }
147
    RETURN();
148
}
149

    
150
/* Store with reservation */
151
PPC_OP(glue(stwcx, MEMSUFFIX))
152
{
153
    if (T0 & 0x03) {
154
        do_queue_exception(EXCP_ALIGN);
155
        do_process_exceptions();
156
    } else {
157
        if (regs->reserve != T0) {
158
            env->crf[0] = xer_ov;
159
        } else {
160
            glue(stl, MEMSUFFIX)((void *)T0, T1);
161
            env->crf[0] = xer_ov | 0x02;
162
        }
163
    }
164
    regs->reserve = 0;
165
    RETURN();
166
}
167

    
168
PPC_OP(glue(dcbz, MEMSUFFIX))
169
{
170
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x00), 0);
171
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x04), 0);
172
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x08), 0);
173
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x0C), 0);
174
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x10), 0);
175
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x14), 0);
176
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x18), 0);
177
    glue(stl, MEMSUFFIX)((void *)(T0 + 0x1C), 0);
178
    RETURN();
179
}
180

    
181
/* External access */
182
PPC_OP(glue(eciwx, MEMSUFFIX))
183
{
184
    T1 = glue(ldl, MEMSUFFIX)((void *)T0);
185
    RETURN();
186
}
187

    
188
PPC_OP(glue(ecowx, MEMSUFFIX))
189
{
190
    glue(stl, MEMSUFFIX)((void *)T0, T1);
191
    RETURN();
192
}
193

    
194
#undef MEMSUFFIX