Revision fb0eaffc target-ppc/helper.c

b/target-ppc/helper.c
121 121
}
122 122

  
123 123
/* The 32 MSB of the target fpr are undefined. They'll be zero... */
124
uint32_t do_load_fpscr (void)
124
/* Floating point operations helpers */
125
void do_load_fpscr (void)
125 126
{
126
    return (fpscr_fx  << FPSCR_FX) |
127
        (fpscr_fex    << FPSCR_FEX) |
128
        (fpscr_vx     << FPSCR_VX) |
129
        (fpscr_ox     << FPSCR_OX) |
130
        (fpscr_ux     << FPSCR_UX) |
131
        (fpscr_zx     << FPSCR_ZX) |
132
        (fpscr_xx     << FPSCR_XX) |
133
        (fpscr_vsxnan << FPSCR_VXSNAN) |
134
        (fpscr_vxisi  << FPSCR_VXISI) |
135
        (fpscr_vxidi  << FPSCR_VXIDI) |
136
        (fpscr_vxzdz  << FPSCR_VXZDZ) |
137
        (fpscr_vximz  << FPSCR_VXIMZ) |
138
        (fpscr_fr     << FPSCR_FR) |
139
        (fpscr_fi     << FPSCR_FI) |
140
        (fpscr_fprf   << FPSCR_FPRF) |
141
        (fpscr_vxsoft << FPSCR_VXSOFT) |
142
        (fpscr_vxsqrt << FPSCR_VXSQRT) |
143
        (fpscr_oe     << FPSCR_OE) |
144
        (fpscr_ue     << FPSCR_UE) |
145
        (fpscr_ze     << FPSCR_ZE) |
146
        (fpscr_xe     << FPSCR_XE) |
147
        (fpscr_ni     << FPSCR_NI) |
148
        (fpscr_rn     << FPSCR_RN);
127
    /* The 32 MSB of the target fpr are undefined.
128
     * They'll be zero...
129
     */
130
    union {
131
        double d;
132
        struct {
133
            uint32_t u[2];
134
        } s;
135
    } u;
136
    int i;
137

  
138
    u.s.u[0] = 0;
139
    u.s.u[1] = 0;
140
    for (i = 0; i < 8; i++)
141
        u.s.u[1] |= env->fpscr[i] << (4 * i);
142
    FT0 = u.d;
149 143
}
150 144

  
151
/* We keep only 32 bits of input... */
152
/* For now, this is COMPLETELY BUGGY ! */
153
void do_store_fpscr (uint8_t mask, uint32_t fp)
145
void do_store_fpscr (uint32_t mask)
154 146
{
147
    /*
148
     * We use only the 32 LSB of the incoming fpr
149
     */
150
    union {
151
        double d;
152
        struct {
153
            uint32_t u[2];
154
        } s;
155
    } u;
155 156
    int i;
156 157

  
157
    for (i = 0; i < 7; i++) {
158
        if ((mask & (1 << i)) == 0)
159
            fp &= ~(0xf << (4 * i));
158
    u.d = FT0;
159
    if (mask & 0x80)
160
        env->fpscr[0] = (env->fpscr[0] & 0x9) | ((u.s.u[1] >> 28) & ~0x9);
161
    for (i = 1; i < 7; i++) {
162
        if (mask & (1 << (7 - i)))
163
            env->fpscr[i] = (u.s.u[1] >> (4 * (7 - i))) & 0xF;
164
    }
165
    /* TODO: update FEX & VX */
166
    /* Set rounding mode */
167
    switch (env->fpscr[0] & 0x3) {
168
    case 0:
169
        /* Best approximation (round to nearest) */
170
        fesetround(FE_TONEAREST);
171
        break;
172
    case 1:
173
        /* Smaller magnitude (round toward zero) */
174
        fesetround(FE_TOWARDZERO);
175
        break;
176
    case 2:
177
        /* Round toward +infinite */
178
        fesetround(FE_UPWARD);
179
        break;
180
    case 3:
181
        /* Round toward -infinite */
182
        fesetround(FE_DOWNWARD);
183
        break;
160 184
    }
161
    if ((mask & 80) != 0)
162
        fpscr_fx = (fp >> FPSCR_FX) & 0x01;
163
    fpscr_fex = (fp >> FPSCR_FEX) & 0x01;
164
    fpscr_vx = (fp >> FPSCR_VX) & 0x01;
165
    fpscr_ox = (fp >> FPSCR_OX) & 0x01;
166
    fpscr_ux = (fp >> FPSCR_UX) & 0x01;
167
    fpscr_zx = (fp >> FPSCR_ZX) & 0x01;
168
    fpscr_xx = (fp >> FPSCR_XX) & 0x01;
169
    fpscr_vsxnan = (fp >> FPSCR_VXSNAN) & 0x01;
170
    fpscr_vxisi = (fp >> FPSCR_VXISI) & 0x01;
171
    fpscr_vxidi = (fp >> FPSCR_VXIDI) & 0x01;
172
    fpscr_vxzdz = (fp >> FPSCR_VXZDZ) & 0x01;
173
    fpscr_vximz = (fp >> FPSCR_VXIMZ) & 0x01;
174
    fpscr_fr = (fp >> FPSCR_FR) & 0x01;
175
    fpscr_fi = (fp >> FPSCR_FI) & 0x01;
176
    fpscr_fprf = (fp >> FPSCR_FPRF) & 0x1F;
177
    fpscr_vxsoft = (fp >> FPSCR_VXSOFT) & 0x01;
178
    fpscr_vxsqrt = (fp >> FPSCR_VXSQRT) & 0x01;
179
    fpscr_oe = (fp >> FPSCR_OE) & 0x01;
180
    fpscr_ue = (fp >> FPSCR_UE) & 0x01;
181
    fpscr_ze = (fp >> FPSCR_ZE) & 0x01;
182
    fpscr_xe = (fp >> FPSCR_XE) & 0x01;
183
    fpscr_ni = (fp >> FPSCR_NI) & 0x01;
184
    fpscr_rn = (fp >> FPSCR_RN) & 0x03;
185 185
}
186 186

  
187 187
int32_t do_sraw(int32_t value, uint32_t shift)
......
220 220
    int sh;
221 221
    
222 222
    for (; count > 3; count -= 4, src += 4) {
223
        if (reg == 32)
224
            reg = 0;
225 223
        ugpr(reg++) = ld32(src);
224
        if (T2 == 32)
225
            T2 = 0;
226 226
    }
227 227
    if (count > 0) {
228
        for (sh = 24, tmp = 0; count > 0; count--, src++, sh -= 8) {
229
            if (reg == 32)
230
                reg = 0;
231
            tmp |= ld8(src) << sh;
232
            if (sh == 0) {
233
                sh = 32;
234
                ugpr(reg++) = tmp;
235 228
                tmp = 0;
236
            }
229
        for (sh = 24; count > 0; count--, src++, sh -= 8) {
230
            tmp |= ld8(src) << sh;
237 231
        }
238 232
        ugpr(reg) = tmp;
239 233
    }
......
244 238
    int sh;
245 239

  
246 240
    for (; count > 3; count -= 4, dest += 4) {
241
        st32(dest, ugpr(reg++));
247 242
        if (reg == 32)
248 243
            reg = 0;
249
        st32(dest, ugpr(reg++));
250 244
    }
251 245
    if (count > 0) {
252 246
        for (sh = 24; count > 0; count--, dest++, sh -= 8) {
253
            if (reg == 32)
254
                reg = 0;
255 247
            st8(dest, (ugpr(reg) >> sh) & 0xFF);
256
            if (sh == 0) {
257
                sh = 32;
258
                reg++;
259 248
            }
260 249
        }
250
}
251

  
252
void do_dcbz (void)
253
{
254
    int i;
255

  
256
    /* Assume cache line size is 32 */
257
    for (i = 0; i < 8; i++) {
258
        st32(T0, 0);
259
        T0 += 4;
261 260
    }
262 261
}
262
    
263
/* Instruction cache invalidation helper */
264
void do_icbi (void)
265
{
266
    tb_invalidate_page(T0);
267
}

Also available in: Unified diff