Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 07ad1b93

History | View | Annotate | Download (25.4 kB)

1 79aceca5 bellard
/*
2 79aceca5 bellard
 *  PPC emulation micro-operations for qemu.
3 79aceca5 bellard
 * 
4 79aceca5 bellard
 *  Copyright (c) 2003 Jocelyn Mayer
5 79aceca5 bellard
 *
6 79aceca5 bellard
 * This library is free software; you can redistribute it and/or
7 79aceca5 bellard
 * modify it under the terms of the GNU Lesser General Public
8 79aceca5 bellard
 * License as published by the Free Software Foundation; either
9 79aceca5 bellard
 * version 2 of the License, or (at your option) any later version.
10 79aceca5 bellard
 *
11 79aceca5 bellard
 * This library is distributed in the hope that it will be useful,
12 79aceca5 bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 79aceca5 bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 79aceca5 bellard
 * Lesser General Public License for more details.
15 79aceca5 bellard
 *
16 79aceca5 bellard
 * You should have received a copy of the GNU Lesser General Public
17 79aceca5 bellard
 * License along with this library; if not, write to the Free Software
18 79aceca5 bellard
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 79aceca5 bellard
 */
20 79aceca5 bellard
21 79aceca5 bellard
#include "config.h"
22 79aceca5 bellard
#include "exec.h"
23 79aceca5 bellard
24 79aceca5 bellard
#define regs (env)
25 79aceca5 bellard
#define Ts0 (int32_t)T0
26 79aceca5 bellard
#define Ts1 (int32_t)T1
27 79aceca5 bellard
#define Ts2 (int32_t)T2
28 79aceca5 bellard
29 28b6751f bellard
#define FT0 (env->ft0)
30 79aceca5 bellard
31 79aceca5 bellard
#define PPC_OP(name) void op_##name(void)
32 79aceca5 bellard
33 28b6751f bellard
#define REG 0
34 28b6751f bellard
#include "op_template.h"
35 28b6751f bellard
36 28b6751f bellard
#define REG 1
37 28b6751f bellard
#include "op_template.h"
38 28b6751f bellard
39 28b6751f bellard
#define REG 2
40 28b6751f bellard
#include "op_template.h"
41 28b6751f bellard
42 28b6751f bellard
#define REG 3
43 28b6751f bellard
#include "op_template.h"
44 28b6751f bellard
45 28b6751f bellard
#define REG 4
46 28b6751f bellard
#include "op_template.h"
47 28b6751f bellard
48 28b6751f bellard
#define REG 5
49 28b6751f bellard
#include "op_template.h"
50 28b6751f bellard
51 28b6751f bellard
#define REG 6
52 28b6751f bellard
#include "op_template.h"
53 28b6751f bellard
54 28b6751f bellard
#define REG 7
55 28b6751f bellard
#include "op_template.h"
56 28b6751f bellard
57 28b6751f bellard
#define REG 8
58 28b6751f bellard
#include "op_template.h"
59 28b6751f bellard
60 28b6751f bellard
#define REG 9
61 28b6751f bellard
#include "op_template.h"
62 28b6751f bellard
63 28b6751f bellard
#define REG 10
64 28b6751f bellard
#include "op_template.h"
65 28b6751f bellard
66 28b6751f bellard
#define REG 11
67 28b6751f bellard
#include "op_template.h"
68 28b6751f bellard
69 28b6751f bellard
#define REG 12
70 28b6751f bellard
#include "op_template.h"
71 28b6751f bellard
72 28b6751f bellard
#define REG 13
73 28b6751f bellard
#include "op_template.h"
74 28b6751f bellard
75 28b6751f bellard
#define REG 14
76 28b6751f bellard
#include "op_template.h"
77 28b6751f bellard
78 28b6751f bellard
#define REG 15
79 28b6751f bellard
#include "op_template.h"
80 28b6751f bellard
81 28b6751f bellard
#define REG 16
82 28b6751f bellard
#include "op_template.h"
83 28b6751f bellard
84 28b6751f bellard
#define REG 17
85 28b6751f bellard
#include "op_template.h"
86 28b6751f bellard
87 28b6751f bellard
#define REG 18
88 28b6751f bellard
#include "op_template.h"
89 28b6751f bellard
90 28b6751f bellard
#define REG 19
91 28b6751f bellard
#include "op_template.h"
92 28b6751f bellard
93 28b6751f bellard
#define REG 20
94 28b6751f bellard
#include "op_template.h"
95 28b6751f bellard
96 28b6751f bellard
#define REG 21
97 28b6751f bellard
#include "op_template.h"
98 28b6751f bellard
99 28b6751f bellard
#define REG 22
100 28b6751f bellard
#include "op_template.h"
101 28b6751f bellard
102 28b6751f bellard
#define REG 23
103 28b6751f bellard
#include "op_template.h"
104 28b6751f bellard
105 28b6751f bellard
#define REG 24
106 28b6751f bellard
#include "op_template.h"
107 28b6751f bellard
108 28b6751f bellard
#define REG 25
109 28b6751f bellard
#include "op_template.h"
110 28b6751f bellard
111 28b6751f bellard
#define REG 26
112 28b6751f bellard
#include "op_template.h"
113 28b6751f bellard
114 28b6751f bellard
#define REG 27
115 28b6751f bellard
#include "op_template.h"
116 28b6751f bellard
117 28b6751f bellard
#define REG 28
118 28b6751f bellard
#include "op_template.h"
119 28b6751f bellard
120 28b6751f bellard
#define REG 29
121 28b6751f bellard
#include "op_template.h"
122 28b6751f bellard
123 28b6751f bellard
#define REG 30
124 28b6751f bellard
#include "op_template.h"
125 28b6751f bellard
126 28b6751f bellard
#define REG 31
127 28b6751f bellard
#include "op_template.h"
128 28b6751f bellard
129 79aceca5 bellard
/* PPC state maintenance operations */
130 79aceca5 bellard
/* set_Rc0 */
131 79aceca5 bellard
PPC_OP(set_Rc0)
132 79aceca5 bellard
{
133 79aceca5 bellard
    uint32_t tmp;
134 79aceca5 bellard
135 79aceca5 bellard
    if (Ts0 < 0) {
136 79aceca5 bellard
        tmp = 0x08;
137 79aceca5 bellard
    } else if (Ts0 > 0) {
138 79aceca5 bellard
        tmp = 0x04;
139 79aceca5 bellard
    } else {
140 79aceca5 bellard
        tmp = 0x02;
141 79aceca5 bellard
    }
142 79aceca5 bellard
    set_CRn(0, tmp);
143 79aceca5 bellard
    RETURN();
144 79aceca5 bellard
}
145 79aceca5 bellard
146 79aceca5 bellard
PPC_OP(set_Rc0_ov)
147 79aceca5 bellard
{
148 79aceca5 bellard
    uint32_t tmp;
149 79aceca5 bellard
150 79aceca5 bellard
    if (Ts0 < 0) {
151 79aceca5 bellard
        tmp = 0x08;
152 79aceca5 bellard
    } else if (Ts0 > 0) {
153 79aceca5 bellard
        tmp = 0x04;
154 79aceca5 bellard
    } else {
155 79aceca5 bellard
        tmp = 0x02;
156 79aceca5 bellard
    }
157 79aceca5 bellard
    tmp |= xer_ov;
158 79aceca5 bellard
    set_CRn(0, tmp);
159 79aceca5 bellard
    RETURN();
160 79aceca5 bellard
}
161 79aceca5 bellard
162 79aceca5 bellard
/* reset_Rc0 */
163 79aceca5 bellard
PPC_OP(reset_Rc0)
164 79aceca5 bellard
{
165 79aceca5 bellard
    set_CRn(0, 0x02 | xer_ov);
166 79aceca5 bellard
    RETURN();
167 79aceca5 bellard
}
168 79aceca5 bellard
169 79aceca5 bellard
/* set_Rc0_1 */
170 79aceca5 bellard
PPC_OP(set_Rc0_1)
171 79aceca5 bellard
{
172 79aceca5 bellard
    set_CRn(0, 0x04 | xer_ov);
173 79aceca5 bellard
    RETURN();
174 79aceca5 bellard
}
175 79aceca5 bellard
176 79aceca5 bellard
PPC_OP(set_T0)
177 79aceca5 bellard
{
178 79aceca5 bellard
    T0 = PARAM(1);
179 79aceca5 bellard
    RETURN();
180 79aceca5 bellard
}
181 79aceca5 bellard
182 79aceca5 bellard
PPC_OP(set_T1)
183 79aceca5 bellard
{
184 79aceca5 bellard
    T1 = PARAM(1);
185 79aceca5 bellard
    RETURN();
186 79aceca5 bellard
}
187 79aceca5 bellard
188 79aceca5 bellard
PPC_OP(set_T2)
189 79aceca5 bellard
{
190 79aceca5 bellard
    T2 = PARAM(1);
191 79aceca5 bellard
    RETURN();
192 79aceca5 bellard
}
193 79aceca5 bellard
194 79aceca5 bellard
/* Update time base */
195 79aceca5 bellard
PPC_OP(update_tb)
196 79aceca5 bellard
{
197 79aceca5 bellard
    T0 = regs->spr[SPR_ENCODE(268)];
198 79aceca5 bellard
    T1 = T0;
199 79aceca5 bellard
    T0 += PARAM(1);
200 79aceca5 bellard
    if (T0 < T1) {
201 79aceca5 bellard
        T1 = regs->spr[SPR_ENCODE(269)] + 1;
202 79aceca5 bellard
        regs->spr[SPR_ENCODE(269)] = T1;
203 79aceca5 bellard
    }
204 79aceca5 bellard
    regs->spr[SPR_ENCODE(268)] = T0;
205 79aceca5 bellard
    RETURN();
206 79aceca5 bellard
}
207 79aceca5 bellard
208 79aceca5 bellard
PPC_OP(raise_exception)
209 79aceca5 bellard
{
210 79aceca5 bellard
    raise_exception(PARAM(1));
211 79aceca5 bellard
    RETURN();
212 79aceca5 bellard
}
213 79aceca5 bellard
214 79aceca5 bellard
PPC_OP(exit_tb)
215 79aceca5 bellard
{
216 79aceca5 bellard
    EXIT_TB();
217 79aceca5 bellard
}
218 79aceca5 bellard
219 79aceca5 bellard
PPC_OP(load_cr)
220 79aceca5 bellard
{
221 79aceca5 bellard
    T0 = do_load_cr();
222 79aceca5 bellard
    RETURN();
223 79aceca5 bellard
}
224 79aceca5 bellard
225 79aceca5 bellard
PPC_OP(store_cr)
226 79aceca5 bellard
{
227 79aceca5 bellard
    do_store_cr(PARAM(1), T0);
228 79aceca5 bellard
    RETURN();
229 79aceca5 bellard
}
230 79aceca5 bellard
231 79aceca5 bellard
PPC_OP(load_xer_cr)
232 79aceca5 bellard
{
233 79aceca5 bellard
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
234 79aceca5 bellard
    RETURN();
235 79aceca5 bellard
}
236 79aceca5 bellard
237 79aceca5 bellard
PPC_OP(clear_xer_cr)
238 79aceca5 bellard
{
239 79aceca5 bellard
    xer_so = 0;
240 79aceca5 bellard
    xer_ov = 0;
241 79aceca5 bellard
    xer_ca = 0;
242 79aceca5 bellard
    RETURN();
243 79aceca5 bellard
}
244 79aceca5 bellard
245 79aceca5 bellard
PPC_OP(load_xer_bc)
246 79aceca5 bellard
{
247 79aceca5 bellard
    T0 = xer_bc;
248 79aceca5 bellard
    RETURN();
249 79aceca5 bellard
}
250 79aceca5 bellard
251 79aceca5 bellard
PPC_OP(load_xer)
252 79aceca5 bellard
{
253 79aceca5 bellard
    T0 = do_load_xer();
254 79aceca5 bellard
    RETURN();
255 79aceca5 bellard
}
256 79aceca5 bellard
257 79aceca5 bellard
PPC_OP(store_xer)
258 79aceca5 bellard
{
259 79aceca5 bellard
    do_store_xer(T0);
260 79aceca5 bellard
    RETURN();
261 79aceca5 bellard
}
262 79aceca5 bellard
263 79aceca5 bellard
PPC_OP(load_msr)
264 79aceca5 bellard
{
265 79aceca5 bellard
    T0 = do_load_msr();
266 79aceca5 bellard
    RETURN();
267 79aceca5 bellard
}
268 79aceca5 bellard
269 79aceca5 bellard
PPC_OP(store_msr)
270 79aceca5 bellard
{
271 79aceca5 bellard
    do_store_msr(T0);
272 79aceca5 bellard
    RETURN();
273 79aceca5 bellard
}
274 79aceca5 bellard
275 79aceca5 bellard
PPC_OP(load_lr)
276 79aceca5 bellard
{
277 79aceca5 bellard
    regs->LR = PARAM(1);
278 79aceca5 bellard
    RETURN();
279 79aceca5 bellard
}
280 79aceca5 bellard
281 79aceca5 bellard
/* Set reservation */
282 79aceca5 bellard
PPC_OP(set_reservation)
283 79aceca5 bellard
{
284 79aceca5 bellard
    regs->reserve = T1 & ~0x03;
285 79aceca5 bellard
    RETURN();
286 79aceca5 bellard
}
287 79aceca5 bellard
288 79aceca5 bellard
/* Reset reservation */
289 79aceca5 bellard
PPC_OP(reset_reservation)
290 79aceca5 bellard
{
291 79aceca5 bellard
    regs->reserve = 0;
292 79aceca5 bellard
    RETURN();
293 79aceca5 bellard
}
294 79aceca5 bellard
295 79aceca5 bellard
/* crf operations */
296 79aceca5 bellard
PPC_OP(getbit_T0)
297 79aceca5 bellard
{
298 79aceca5 bellard
    T0 = (T0 >> PARAM(1)) & 1;
299 79aceca5 bellard
    RETURN();
300 79aceca5 bellard
}
301 79aceca5 bellard
302 79aceca5 bellard
PPC_OP(getbit_T1)
303 79aceca5 bellard
{
304 79aceca5 bellard
    T1 = (T1 >> PARAM(1)) & 1;
305 79aceca5 bellard
    RETURN();
306 79aceca5 bellard
}
307 79aceca5 bellard
308 79aceca5 bellard
PPC_OP(setcrfbit)
309 79aceca5 bellard
{
310 79aceca5 bellard
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2)); 
311 79aceca5 bellard
    RETURN();
312 79aceca5 bellard
}
313 79aceca5 bellard
314 79aceca5 bellard
/* Branch */
315 79aceca5 bellard
#define __PPC_OP_B(name, target)                                              \
316 79aceca5 bellard
PPC_OP(name)                                                                  \
317 79aceca5 bellard
{                                                                             \
318 79aceca5 bellard
    regs->nip = (target);                                                     \
319 79aceca5 bellard
    RETURN();                                                                 \
320 79aceca5 bellard
}
321 79aceca5 bellard
322 79aceca5 bellard
#define __PPC_OP_BL(name, target)                                             \
323 79aceca5 bellard
PPC_OP(name)                                                                  \
324 79aceca5 bellard
{                                                                             \
325 79aceca5 bellard
    regs->LR = PARAM(1);                                                      \
326 79aceca5 bellard
    regs->nip = (target);                                                     \
327 79aceca5 bellard
    RETURN();                                                                 \
328 79aceca5 bellard
}
329 79aceca5 bellard
330 79aceca5 bellard
#define PPC_OP_B(name, target)                                                \
331 79aceca5 bellard
__PPC_OP_B(name, target);                                                     \
332 79aceca5 bellard
__PPC_OP_BL(name##l, target)
333 79aceca5 bellard
334 79aceca5 bellard
#define __PPC_OP_BC(name, cond, target)                                       \
335 79aceca5 bellard
PPC_OP(name)                                                                  \
336 79aceca5 bellard
{                                                                             \
337 79aceca5 bellard
    if (cond) {                                                               \
338 79aceca5 bellard
        T0 = (target);                                                        \
339 79aceca5 bellard
    } else {                                                                  \
340 79aceca5 bellard
        T0 = PARAM(1);                                                        \
341 79aceca5 bellard
    }                                                                         \
342 79aceca5 bellard
    regs->nip = T0;                                                           \
343 79aceca5 bellard
    RETURN();                                                                 \
344 79aceca5 bellard
}
345 79aceca5 bellard
346 79aceca5 bellard
#define __PPC_OP_BCL(name, cond, target)                                      \
347 79aceca5 bellard
PPC_OP(name)                                                                  \
348 79aceca5 bellard
{                                                                             \
349 79aceca5 bellard
    if (cond) {                                                               \
350 79aceca5 bellard
        T0 = (target);                                                        \
351 79aceca5 bellard
        regs->LR = PARAM(1);                                                  \
352 79aceca5 bellard
    } else {                                                                  \
353 79aceca5 bellard
        T0 = PARAM(1);                                                        \
354 79aceca5 bellard
    }                                                                         \
355 79aceca5 bellard
    regs->nip = T0;                                                           \
356 79aceca5 bellard
    RETURN();                                                                 \
357 79aceca5 bellard
}
358 79aceca5 bellard
359 79aceca5 bellard
#define _PPC_OP_BC(name, namel, cond, target)                                 \
360 79aceca5 bellard
__PPC_OP_BC(name, cond, target);                                              \
361 79aceca5 bellard
__PPC_OP_BCL(namel, cond, target)
362 79aceca5 bellard
363 79aceca5 bellard
/* Branch to target */
364 79aceca5 bellard
#define PPC_OP_BC(name, cond)                                                 \
365 79aceca5 bellard
_PPC_OP_BC(b_##name, bl_##name, cond, PARAM(2))
366 79aceca5 bellard
367 79aceca5 bellard
PPC_OP_B(b, PARAM(1));
368 79aceca5 bellard
PPC_OP_BC(ctr,        (regs->CTR != 0));
369 79aceca5 bellard
PPC_OP_BC(ctr_true,   (regs->CTR != 0 && (T0 & PARAM(3)) != 0));
370 79aceca5 bellard
PPC_OP_BC(ctr_false,  (regs->CTR != 0 && (T0 & PARAM(3)) == 0));
371 79aceca5 bellard
PPC_OP_BC(ctrz,       (regs->CTR == 0));
372 79aceca5 bellard
PPC_OP_BC(ctrz_true,  (regs->CTR == 0 && (T0 & PARAM(3)) != 0));
373 79aceca5 bellard
PPC_OP_BC(ctrz_false, (regs->CTR == 0 && (T0 & PARAM(3)) == 0));
374 79aceca5 bellard
PPC_OP_BC(true,       ((T0 & PARAM(3)) != 0));
375 79aceca5 bellard
PPC_OP_BC(false,      ((T0 & PARAM(3)) == 0));
376 79aceca5 bellard
377 79aceca5 bellard
/* Branch to CTR */
378 79aceca5 bellard
#define PPC_OP_BCCTR(name, cond)                                              \
379 79aceca5 bellard
_PPC_OP_BC(bctr_##name, bctrl_##name, cond, regs->CTR & ~0x03)
380 79aceca5 bellard
381 79aceca5 bellard
PPC_OP_B(bctr, regs->CTR & ~0x03);
382 79aceca5 bellard
PPC_OP_BCCTR(ctr,        (regs->CTR != 0));
383 79aceca5 bellard
PPC_OP_BCCTR(ctr_true,   (regs->CTR != 0 && (T0 & PARAM(2)) != 0));
384 79aceca5 bellard
PPC_OP_BCCTR(ctr_false,  (regs->CTR != 0 && (T0 & PARAM(2)) == 0));
385 79aceca5 bellard
PPC_OP_BCCTR(ctrz,       (regs->CTR == 0));
386 79aceca5 bellard
PPC_OP_BCCTR(ctrz_true,  (regs->CTR == 0 && (T0 & PARAM(2)) != 0));
387 79aceca5 bellard
PPC_OP_BCCTR(ctrz_false, (regs->CTR == 0 && (T0 & PARAM(2)) == 0));
388 79aceca5 bellard
PPC_OP_BCCTR(true,       ((T0 & PARAM(2)) != 0));
389 79aceca5 bellard
PPC_OP_BCCTR(false,      ((T0 & PARAM(2)) == 0));
390 79aceca5 bellard
391 79aceca5 bellard
/* Branch to LR */
392 79aceca5 bellard
#define PPC_OP_BCLR(name, cond)                                               \
393 79aceca5 bellard
_PPC_OP_BC(blr_##name, blrl_##name, cond, regs->LR & ~0x03)
394 79aceca5 bellard
395 79aceca5 bellard
PPC_OP_B(blr, regs->LR & ~0x03);
396 79aceca5 bellard
PPC_OP_BCLR(ctr,        (regs->CTR != 0));
397 79aceca5 bellard
PPC_OP_BCLR(ctr_true,   (regs->CTR != 0 && (T0 & PARAM(2)) != 0));
398 79aceca5 bellard
PPC_OP_BCLR(ctr_false,  (regs->CTR != 0 && (T0 & PARAM(2)) == 0));
399 79aceca5 bellard
PPC_OP_BCLR(ctrz,       (regs->CTR == 0));
400 79aceca5 bellard
PPC_OP_BCLR(ctrz_true,  (regs->CTR == 0 && (T0 & PARAM(2)) != 0));
401 79aceca5 bellard
PPC_OP_BCLR(ctrz_false, (regs->CTR == 0 && (T0 & PARAM(2)) == 0));
402 79aceca5 bellard
PPC_OP_BCLR(true,       ((T0 & PARAM(2)) != 0));
403 79aceca5 bellard
PPC_OP_BCLR(false,      ((T0 & PARAM(2)) == 0));
404 79aceca5 bellard
405 79aceca5 bellard
/* CTR maintenance */
406 79aceca5 bellard
PPC_OP(dec_ctr)
407 79aceca5 bellard
{
408 79aceca5 bellard
    regs->CTR--;
409 79aceca5 bellard
    RETURN();
410 79aceca5 bellard
}
411 79aceca5 bellard
412 79aceca5 bellard
/***                           Integer arithmetic                          ***/
413 79aceca5 bellard
/* add */
414 79aceca5 bellard
PPC_OP(add)
415 79aceca5 bellard
{
416 79aceca5 bellard
    T0 += T1;
417 79aceca5 bellard
    RETURN();
418 79aceca5 bellard
}
419 79aceca5 bellard
420 79aceca5 bellard
PPC_OP(addo)
421 79aceca5 bellard
{
422 79aceca5 bellard
    T2 = T0;
423 79aceca5 bellard
    T0 += T1;
424 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
425 79aceca5 bellard
        xer_so = 1;
426 79aceca5 bellard
        xer_ov = 1;
427 79aceca5 bellard
    } else {
428 79aceca5 bellard
        xer_ov = 0;
429 79aceca5 bellard
    }
430 79aceca5 bellard
    RETURN();
431 79aceca5 bellard
}
432 79aceca5 bellard
433 79aceca5 bellard
/* add carrying */
434 79aceca5 bellard
PPC_OP(addc)
435 79aceca5 bellard
{
436 79aceca5 bellard
    T2 = T0;
437 79aceca5 bellard
    T0 += T1;
438 79aceca5 bellard
    if (T0 < T2) {
439 79aceca5 bellard
        xer_ca = 1;
440 79aceca5 bellard
    } else {
441 79aceca5 bellard
        xer_ca = 0;
442 79aceca5 bellard
    }
443 79aceca5 bellard
    RETURN();
444 79aceca5 bellard
}
445 79aceca5 bellard
446 79aceca5 bellard
PPC_OP(addco)
447 79aceca5 bellard
{
448 79aceca5 bellard
    T2 = T0;
449 79aceca5 bellard
    T0 += T1;
450 79aceca5 bellard
    if (T0 < T2) {
451 79aceca5 bellard
        xer_ca = 1;
452 79aceca5 bellard
    } else {
453 79aceca5 bellard
        xer_ca = 0;
454 79aceca5 bellard
    }
455 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
456 79aceca5 bellard
        xer_so = 1;
457 79aceca5 bellard
        xer_ov = 1;
458 79aceca5 bellard
    } else {
459 79aceca5 bellard
        xer_ov = 0;
460 79aceca5 bellard
    }
461 79aceca5 bellard
    RETURN();
462 79aceca5 bellard
}
463 79aceca5 bellard
464 79aceca5 bellard
/* add extended */
465 79aceca5 bellard
/* candidate for helper (too long) */
466 79aceca5 bellard
PPC_OP(adde)
467 79aceca5 bellard
{
468 79aceca5 bellard
    T2 = T0;
469 79aceca5 bellard
    T0 += T1 + xer_ca;
470 79aceca5 bellard
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
471 79aceca5 bellard
        xer_ca = 1;
472 79aceca5 bellard
    } else {
473 79aceca5 bellard
        xer_ca = 0;
474 79aceca5 bellard
    }
475 79aceca5 bellard
    RETURN();
476 79aceca5 bellard
}
477 79aceca5 bellard
478 79aceca5 bellard
PPC_OP(addeo)
479 79aceca5 bellard
{
480 79aceca5 bellard
    T2 = T0;
481 79aceca5 bellard
    T0 += T1 + xer_ca;
482 79aceca5 bellard
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
483 79aceca5 bellard
        xer_ca = 1;
484 79aceca5 bellard
    } else {
485 79aceca5 bellard
        xer_ca = 0;
486 79aceca5 bellard
    }
487 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
488 79aceca5 bellard
        xer_so = 1;
489 79aceca5 bellard
        xer_ov = 1;
490 79aceca5 bellard
    } else {
491 79aceca5 bellard
        xer_ov = 0;
492 79aceca5 bellard
    }
493 79aceca5 bellard
    RETURN();
494 79aceca5 bellard
}
495 79aceca5 bellard
496 79aceca5 bellard
/* add immediate */
497 79aceca5 bellard
PPC_OP(addi)
498 79aceca5 bellard
{
499 79aceca5 bellard
    T0 += PARAM(1);
500 79aceca5 bellard
    RETURN();
501 79aceca5 bellard
}
502 79aceca5 bellard
503 79aceca5 bellard
/* add immediate carrying */
504 79aceca5 bellard
PPC_OP(addic)
505 79aceca5 bellard
{
506 79aceca5 bellard
    T1 = T0;
507 79aceca5 bellard
    T0 += PARAM(1);
508 79aceca5 bellard
    if (T0 < T1) {
509 79aceca5 bellard
        xer_ca = 1;
510 79aceca5 bellard
    } else {
511 79aceca5 bellard
        xer_ca = 0;
512 79aceca5 bellard
    }
513 79aceca5 bellard
    RETURN();
514 79aceca5 bellard
}
515 79aceca5 bellard
516 79aceca5 bellard
/* add to minus one extended */
517 79aceca5 bellard
PPC_OP(addme)
518 79aceca5 bellard
{
519 79aceca5 bellard
    T1 = T0;
520 79aceca5 bellard
    T0 += xer_ca + (-1);
521 79aceca5 bellard
    if (T1 != 0)
522 79aceca5 bellard
        xer_ca = 1;
523 79aceca5 bellard
    RETURN();
524 79aceca5 bellard
}
525 79aceca5 bellard
526 79aceca5 bellard
PPC_OP(addmeo)
527 79aceca5 bellard
{
528 79aceca5 bellard
    T1 = T0;
529 79aceca5 bellard
    T0 += xer_ca + (-1);
530 79aceca5 bellard
    if (T1 & (T1 ^ T0) & (1 << 31)) {
531 79aceca5 bellard
        xer_so = 1;
532 79aceca5 bellard
        xer_ov = 1;
533 79aceca5 bellard
    } else {
534 79aceca5 bellard
        xer_ov = 0;
535 79aceca5 bellard
    }
536 79aceca5 bellard
    if (T1 != 0)
537 79aceca5 bellard
        xer_ca = 1;
538 79aceca5 bellard
    RETURN();
539 79aceca5 bellard
}
540 79aceca5 bellard
541 79aceca5 bellard
/* add to zero extended */
542 79aceca5 bellard
PPC_OP(addze)
543 79aceca5 bellard
{
544 79aceca5 bellard
    T1 = T0;
545 79aceca5 bellard
    T0 += xer_ca;
546 79aceca5 bellard
    if (T0 < T1) {
547 79aceca5 bellard
        xer_ca = 1;
548 79aceca5 bellard
    } else {
549 79aceca5 bellard
        xer_ca = 0;
550 79aceca5 bellard
    }
551 79aceca5 bellard
    RETURN();
552 79aceca5 bellard
}
553 79aceca5 bellard
554 79aceca5 bellard
PPC_OP(addzeo)
555 79aceca5 bellard
{
556 79aceca5 bellard
    T1 = T0;
557 79aceca5 bellard
    T0 += xer_ca;
558 79aceca5 bellard
    if ((T1 ^ (-1)) & (T1 ^ T0) & (1 << 31)) {
559 79aceca5 bellard
        xer_so = 1;
560 79aceca5 bellard
        xer_ov = 1;
561 79aceca5 bellard
    } else {
562 79aceca5 bellard
        xer_ov = 0;
563 79aceca5 bellard
    }
564 79aceca5 bellard
    if (T0 < T1) {
565 79aceca5 bellard
        xer_ca = 1;
566 79aceca5 bellard
    } else {
567 79aceca5 bellard
        xer_ca = 0;
568 79aceca5 bellard
    }
569 79aceca5 bellard
    RETURN();
570 79aceca5 bellard
}
571 79aceca5 bellard
572 79aceca5 bellard
/* divide word */
573 79aceca5 bellard
/* candidate for helper (too long) */
574 79aceca5 bellard
PPC_OP(divw)
575 79aceca5 bellard
{
576 79aceca5 bellard
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
577 79aceca5 bellard
        Ts0 = (-1) * (T0 >> 31);
578 79aceca5 bellard
    } else {
579 79aceca5 bellard
        Ts0 /= Ts1;
580 79aceca5 bellard
    }
581 79aceca5 bellard
    RETURN();
582 79aceca5 bellard
}
583 79aceca5 bellard
584 79aceca5 bellard
PPC_OP(divwo)
585 79aceca5 bellard
{
586 79aceca5 bellard
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
587 79aceca5 bellard
        xer_so = 1;
588 79aceca5 bellard
        xer_ov = 1;
589 79aceca5 bellard
        T0 = (-1) * (T0 >> 31);
590 79aceca5 bellard
    } else {
591 79aceca5 bellard
        xer_ov = 0;
592 79aceca5 bellard
        Ts0 /= Ts1;
593 79aceca5 bellard
    }
594 79aceca5 bellard
    RETURN();
595 79aceca5 bellard
}
596 79aceca5 bellard
597 79aceca5 bellard
/* divide word unsigned */
598 79aceca5 bellard
PPC_OP(divwu)
599 79aceca5 bellard
{
600 79aceca5 bellard
    if (T1 == 0) {
601 79aceca5 bellard
        T0 = 0;
602 79aceca5 bellard
    } else {
603 79aceca5 bellard
        T0 /= T1;
604 79aceca5 bellard
    }
605 79aceca5 bellard
    RETURN();
606 79aceca5 bellard
}
607 79aceca5 bellard
608 79aceca5 bellard
PPC_OP(divwuo)
609 79aceca5 bellard
{
610 79aceca5 bellard
    if (T1 == 0) {
611 79aceca5 bellard
        xer_so = 1;
612 79aceca5 bellard
        xer_ov = 1;
613 79aceca5 bellard
        T0 = 0;
614 79aceca5 bellard
    } else {
615 79aceca5 bellard
        xer_ov = 0;
616 79aceca5 bellard
        T0 /= T1;
617 79aceca5 bellard
    }
618 79aceca5 bellard
    RETURN();
619 79aceca5 bellard
}
620 79aceca5 bellard
621 79aceca5 bellard
/* multiply high word */
622 79aceca5 bellard
PPC_OP(mulhw)
623 79aceca5 bellard
{
624 79aceca5 bellard
    Ts0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32;
625 79aceca5 bellard
    RETURN();
626 79aceca5 bellard
}
627 79aceca5 bellard
628 79aceca5 bellard
/* multiply high word unsigned */
629 79aceca5 bellard
PPC_OP(mulhwu)
630 79aceca5 bellard
{
631 79aceca5 bellard
    T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32;
632 79aceca5 bellard
    RETURN();
633 79aceca5 bellard
}
634 79aceca5 bellard
635 79aceca5 bellard
/* multiply low immediate */
636 79aceca5 bellard
PPC_OP(mulli)
637 79aceca5 bellard
{
638 79aceca5 bellard
    Ts0 *= SPARAM(1);
639 79aceca5 bellard
    RETURN();
640 79aceca5 bellard
}
641 79aceca5 bellard
642 79aceca5 bellard
/* multiply low word */
643 79aceca5 bellard
PPC_OP(mullw)
644 79aceca5 bellard
{
645 79aceca5 bellard
    T0 *= T1;
646 79aceca5 bellard
    RETURN();
647 79aceca5 bellard
}
648 79aceca5 bellard
649 79aceca5 bellard
PPC_OP(mullwo)
650 79aceca5 bellard
{
651 79aceca5 bellard
    int64_t res = (int64_t)Ts0 * (int64_t)Ts1;
652 79aceca5 bellard
653 79aceca5 bellard
    if ((int32_t)res != res) {
654 79aceca5 bellard
        xer_ov = 1;
655 79aceca5 bellard
        xer_so = 1;
656 79aceca5 bellard
    } else {
657 79aceca5 bellard
        xer_ov = 0;
658 79aceca5 bellard
    }
659 79aceca5 bellard
    Ts0 = res;
660 79aceca5 bellard
    RETURN();
661 79aceca5 bellard
}
662 79aceca5 bellard
663 79aceca5 bellard
/* negate */
664 79aceca5 bellard
PPC_OP(neg)
665 79aceca5 bellard
{
666 79aceca5 bellard
    if (T0 != 0x80000000) {
667 79aceca5 bellard
        Ts0 = -Ts0;
668 79aceca5 bellard
    }
669 79aceca5 bellard
    RETURN();
670 79aceca5 bellard
}
671 79aceca5 bellard
672 79aceca5 bellard
PPC_OP(nego)
673 79aceca5 bellard
{
674 79aceca5 bellard
    if (T0 == 0x80000000) {
675 79aceca5 bellard
        xer_ov = 1;
676 79aceca5 bellard
        xer_so = 1;
677 79aceca5 bellard
    } else {
678 79aceca5 bellard
        xer_ov = 0;
679 79aceca5 bellard
        Ts0 = -Ts0;
680 79aceca5 bellard
    }
681 79aceca5 bellard
    RETURN();
682 79aceca5 bellard
}
683 79aceca5 bellard
684 79aceca5 bellard
/* substract from */
685 79aceca5 bellard
PPC_OP(subf)
686 79aceca5 bellard
{
687 79aceca5 bellard
    T0 = T1 - T0;
688 79aceca5 bellard
    RETURN();
689 79aceca5 bellard
}
690 79aceca5 bellard
691 79aceca5 bellard
PPC_OP(subfo)
692 79aceca5 bellard
{
693 79aceca5 bellard
    T2 = T0;
694 79aceca5 bellard
    T0 = T1 - T0;
695 79aceca5 bellard
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
696 79aceca5 bellard
        xer_so = 1;
697 79aceca5 bellard
        xer_ov = 1;
698 79aceca5 bellard
    } else {
699 79aceca5 bellard
        xer_ov = 0;
700 79aceca5 bellard
    }
701 79aceca5 bellard
    RETURN();
702 79aceca5 bellard
}
703 79aceca5 bellard
704 79aceca5 bellard
/* substract from carrying */
705 79aceca5 bellard
PPC_OP(subfc)
706 79aceca5 bellard
{
707 79aceca5 bellard
    T0 = T1 - T0;
708 79aceca5 bellard
    if (T0 <= T1) {
709 79aceca5 bellard
        xer_ca = 1;
710 79aceca5 bellard
    } else {
711 79aceca5 bellard
        xer_ca = 0;
712 79aceca5 bellard
    }
713 79aceca5 bellard
    RETURN();
714 79aceca5 bellard
}
715 79aceca5 bellard
716 79aceca5 bellard
PPC_OP(subfco)
717 79aceca5 bellard
{
718 79aceca5 bellard
    T2 = T0;
719 79aceca5 bellard
    T0 = T1 - T0;
720 79aceca5 bellard
    if (T0 <= T1) {
721 79aceca5 bellard
        xer_ca = 1;
722 79aceca5 bellard
    } else {
723 79aceca5 bellard
        xer_ca = 0;
724 79aceca5 bellard
    }
725 79aceca5 bellard
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
726 79aceca5 bellard
        xer_so = 1;
727 79aceca5 bellard
        xer_ov = 1;
728 79aceca5 bellard
    } else {
729 79aceca5 bellard
        xer_ov = 0;
730 79aceca5 bellard
    }
731 79aceca5 bellard
    RETURN();
732 79aceca5 bellard
}
733 79aceca5 bellard
734 79aceca5 bellard
/* substract from extended */
735 79aceca5 bellard
/* candidate for helper (too long) */
736 79aceca5 bellard
PPC_OP(subfe)
737 79aceca5 bellard
{
738 79aceca5 bellard
    T0 = T1 + ~T0 + xer_ca;
739 79aceca5 bellard
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
740 79aceca5 bellard
        xer_ca = 1;
741 79aceca5 bellard
    } else {
742 79aceca5 bellard
        xer_ca = 0;
743 79aceca5 bellard
    }
744 79aceca5 bellard
    RETURN();
745 79aceca5 bellard
}
746 79aceca5 bellard
747 79aceca5 bellard
PPC_OP(subfeo)
748 79aceca5 bellard
{
749 79aceca5 bellard
    T2 = T0;
750 79aceca5 bellard
    T0 = T1 + ~T0 + xer_ca;
751 79aceca5 bellard
    if ((~T2 ^ T1 ^ (-1)) & (~T2 ^ T0) & (1 << 31)) {
752 79aceca5 bellard
        xer_so = 1;
753 79aceca5 bellard
        xer_ov = 1;
754 79aceca5 bellard
    } else {
755 79aceca5 bellard
        xer_ov = 0;
756 79aceca5 bellard
    }
757 79aceca5 bellard
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
758 79aceca5 bellard
        xer_ca = 1;
759 79aceca5 bellard
    } else {
760 79aceca5 bellard
        xer_ca = 0;
761 79aceca5 bellard
    }
762 79aceca5 bellard
    RETURN();
763 79aceca5 bellard
}
764 79aceca5 bellard
765 79aceca5 bellard
/* substract from immediate carrying */
766 79aceca5 bellard
PPC_OP(subfic)
767 79aceca5 bellard
{
768 79aceca5 bellard
    T0 = PARAM(1) + ~T0 + 1;
769 79aceca5 bellard
    if (T0 <= PARAM(1)) {
770 79aceca5 bellard
        xer_ca = 1;
771 79aceca5 bellard
    } else {
772 79aceca5 bellard
        xer_ca = 0;
773 79aceca5 bellard
    }
774 79aceca5 bellard
    RETURN();
775 79aceca5 bellard
}
776 79aceca5 bellard
777 79aceca5 bellard
/* substract from minus one extended */
778 79aceca5 bellard
PPC_OP(subfme)
779 79aceca5 bellard
{
780 79aceca5 bellard
    T0 = ~T0 + xer_ca - 1;
781 79aceca5 bellard
782 79aceca5 bellard
    if (T0 != -1)
783 79aceca5 bellard
        xer_ca = 1;
784 79aceca5 bellard
    RETURN();
785 79aceca5 bellard
}
786 79aceca5 bellard
787 79aceca5 bellard
PPC_OP(subfmeo)
788 79aceca5 bellard
{
789 79aceca5 bellard
    T1 = T0;
790 79aceca5 bellard
    T0 = ~T0 + xer_ca - 1;
791 79aceca5 bellard
    if (~T1 & (~T1 ^ T0) & (1 << 31)) {
792 79aceca5 bellard
        xer_so = 1;
793 79aceca5 bellard
        xer_ov = 1;
794 79aceca5 bellard
    } else {
795 79aceca5 bellard
        xer_ov = 0;
796 79aceca5 bellard
    }
797 79aceca5 bellard
    if (T1 != -1)
798 79aceca5 bellard
        xer_ca = 1;
799 79aceca5 bellard
    RETURN();
800 79aceca5 bellard
}
801 79aceca5 bellard
802 79aceca5 bellard
/* substract from zero extended */
803 79aceca5 bellard
PPC_OP(subfze)
804 79aceca5 bellard
{
805 79aceca5 bellard
    T1 = ~T0;
806 79aceca5 bellard
    T0 = T1 + xer_ca;
807 79aceca5 bellard
    if (T0 < T1) {
808 79aceca5 bellard
        xer_ca = 1;
809 79aceca5 bellard
    } else {
810 79aceca5 bellard
        xer_ca = 0;
811 79aceca5 bellard
    }
812 79aceca5 bellard
    RETURN();
813 79aceca5 bellard
}
814 79aceca5 bellard
815 79aceca5 bellard
PPC_OP(subfzeo)
816 79aceca5 bellard
{
817 79aceca5 bellard
    T1 = T0;
818 79aceca5 bellard
    T0 = ~T0 + xer_ca;
819 79aceca5 bellard
    if ((~T1 ^ (-1)) & ((~T1) ^ T0) & (1 << 31)) {
820 79aceca5 bellard
        xer_ov = 1;
821 79aceca5 bellard
        xer_so = 1;
822 79aceca5 bellard
    } else {
823 79aceca5 bellard
        xer_ov = 0;
824 79aceca5 bellard
    }
825 79aceca5 bellard
    if (T0 < ~T1) {
826 79aceca5 bellard
        xer_ca = 1;
827 79aceca5 bellard
    } else {
828 79aceca5 bellard
        xer_ca = 0;
829 79aceca5 bellard
    }
830 79aceca5 bellard
    RETURN();
831 79aceca5 bellard
}
832 79aceca5 bellard
833 79aceca5 bellard
/***                           Integer comparison                          ***/
834 79aceca5 bellard
/* compare */
835 79aceca5 bellard
PPC_OP(cmp)
836 79aceca5 bellard
{
837 79aceca5 bellard
    if (Ts0 < Ts1) {
838 79aceca5 bellard
        T0 = 0x08;
839 79aceca5 bellard
    } else if (Ts0 > Ts1) {
840 79aceca5 bellard
        T0 = 0x04;
841 79aceca5 bellard
    } else {
842 79aceca5 bellard
        T0 = 0x02;
843 79aceca5 bellard
    }
844 79aceca5 bellard
    RETURN();
845 79aceca5 bellard
}
846 79aceca5 bellard
847 79aceca5 bellard
/* compare immediate */
848 79aceca5 bellard
PPC_OP(cmpi)
849 79aceca5 bellard
{
850 79aceca5 bellard
    if (Ts0 < SPARAM(1)) {
851 79aceca5 bellard
        T0 = 0x08;
852 79aceca5 bellard
    } else if (Ts0 > SPARAM(1)) {
853 79aceca5 bellard
        T0 = 0x04;
854 79aceca5 bellard
    } else {
855 79aceca5 bellard
        T0 = 0x02;
856 79aceca5 bellard
    }
857 79aceca5 bellard
    RETURN();
858 79aceca5 bellard
}
859 79aceca5 bellard
860 79aceca5 bellard
/* compare logical */
861 79aceca5 bellard
PPC_OP(cmpl)
862 79aceca5 bellard
{
863 79aceca5 bellard
    if (T0 < T1) {
864 79aceca5 bellard
        T0 = 0x08;
865 79aceca5 bellard
    } else if (T0 > T1) {
866 79aceca5 bellard
        T0 = 0x04;
867 79aceca5 bellard
    } else {
868 79aceca5 bellard
        T0 = 0x02;
869 79aceca5 bellard
    }
870 79aceca5 bellard
    RETURN();
871 79aceca5 bellard
}
872 79aceca5 bellard
873 79aceca5 bellard
/* compare logical immediate */
874 79aceca5 bellard
PPC_OP(cmpli)
875 79aceca5 bellard
{
876 79aceca5 bellard
    if (T0 < PARAM(1)) {
877 79aceca5 bellard
        T0 = 0x08;
878 79aceca5 bellard
    } else if (T0 > PARAM(1)) {
879 79aceca5 bellard
        T0 = 0x04;
880 79aceca5 bellard
    } else {
881 79aceca5 bellard
        T0 = 0x02;
882 79aceca5 bellard
    }
883 79aceca5 bellard
    RETURN();
884 79aceca5 bellard
}
885 79aceca5 bellard
886 79aceca5 bellard
/***                            Integer logical                            ***/
887 79aceca5 bellard
/* and */
888 79aceca5 bellard
PPC_OP(and)
889 79aceca5 bellard
{
890 79aceca5 bellard
    T0 &= T1;
891 79aceca5 bellard
    RETURN();
892 79aceca5 bellard
}
893 79aceca5 bellard
894 79aceca5 bellard
/* andc */
895 79aceca5 bellard
PPC_OP(andc)
896 79aceca5 bellard
{
897 79aceca5 bellard
    T0 &= ~T1;
898 79aceca5 bellard
    RETURN();
899 79aceca5 bellard
}
900 79aceca5 bellard
901 79aceca5 bellard
/* andi. */
902 79aceca5 bellard
PPC_OP(andi_)
903 79aceca5 bellard
{
904 79aceca5 bellard
    T0 &= PARAM(1);
905 79aceca5 bellard
    RETURN();
906 79aceca5 bellard
}
907 79aceca5 bellard
908 79aceca5 bellard
/* count leading zero */
909 79aceca5 bellard
PPC_OP(cntlzw)
910 79aceca5 bellard
{
911 79aceca5 bellard
    T1 = T0;
912 79aceca5 bellard
    for (T0 = 32; T1 > 0; T0--)
913 79aceca5 bellard
        T1 = T1 >> 1;
914 79aceca5 bellard
    RETURN();
915 79aceca5 bellard
}
916 79aceca5 bellard
917 79aceca5 bellard
/* eqv */
918 79aceca5 bellard
PPC_OP(eqv)
919 79aceca5 bellard
{
920 79aceca5 bellard
    T0 = ~(T0 ^ T1);
921 79aceca5 bellard
    RETURN();
922 79aceca5 bellard
}
923 79aceca5 bellard
924 79aceca5 bellard
/* extend sign byte */
925 79aceca5 bellard
PPC_OP(extsb)
926 79aceca5 bellard
{
927 79aceca5 bellard
    Ts0 = s_ext8(Ts0);
928 79aceca5 bellard
    RETURN();
929 79aceca5 bellard
}
930 79aceca5 bellard
931 79aceca5 bellard
/* extend sign half word */
932 79aceca5 bellard
PPC_OP(extsh)
933 79aceca5 bellard
{
934 79aceca5 bellard
    Ts0 = s_ext16(Ts0);
935 79aceca5 bellard
    RETURN();
936 79aceca5 bellard
}
937 79aceca5 bellard
938 79aceca5 bellard
/* nand */
939 79aceca5 bellard
PPC_OP(nand)
940 79aceca5 bellard
{
941 79aceca5 bellard
    T0 = ~(T0 & T1);
942 79aceca5 bellard
    RETURN();
943 79aceca5 bellard
}
944 79aceca5 bellard
945 79aceca5 bellard
/* nor */
946 79aceca5 bellard
PPC_OP(nor)
947 79aceca5 bellard
{
948 79aceca5 bellard
    T0 = ~(T0 | T1);
949 79aceca5 bellard
    RETURN();
950 79aceca5 bellard
}
951 79aceca5 bellard
952 79aceca5 bellard
/* or */
953 79aceca5 bellard
PPC_OP(or)
954 79aceca5 bellard
{
955 79aceca5 bellard
    T0 |= T1;
956 79aceca5 bellard
    RETURN();
957 79aceca5 bellard
}
958 79aceca5 bellard
959 79aceca5 bellard
/* orc */
960 79aceca5 bellard
PPC_OP(orc)
961 79aceca5 bellard
{
962 79aceca5 bellard
    T0 |= ~T1;
963 79aceca5 bellard
    RETURN();
964 79aceca5 bellard
}
965 79aceca5 bellard
966 79aceca5 bellard
/* ori */
967 79aceca5 bellard
PPC_OP(ori)
968 79aceca5 bellard
{
969 79aceca5 bellard
    T0 |= PARAM(1);
970 79aceca5 bellard
    RETURN();
971 79aceca5 bellard
}
972 79aceca5 bellard
973 79aceca5 bellard
/* xor */
974 79aceca5 bellard
PPC_OP(xor)
975 79aceca5 bellard
{
976 79aceca5 bellard
    T0 ^= T1;
977 79aceca5 bellard
    RETURN();
978 79aceca5 bellard
}
979 79aceca5 bellard
980 79aceca5 bellard
/* xori */
981 79aceca5 bellard
PPC_OP(xori)
982 79aceca5 bellard
{
983 79aceca5 bellard
    T0 ^= PARAM(1);
984 79aceca5 bellard
    RETURN();
985 79aceca5 bellard
}
986 79aceca5 bellard
987 79aceca5 bellard
/***                             Integer rotate                            ***/
988 79aceca5 bellard
/* rotate left word immediate then mask insert */
989 79aceca5 bellard
PPC_OP(rlwimi)
990 79aceca5 bellard
{
991 79aceca5 bellard
    T0 = rotl(T0, PARAM(1) & PARAM(2)) | (T0 & PARAM(3));
992 79aceca5 bellard
    RETURN();
993 79aceca5 bellard
}
994 79aceca5 bellard
995 79aceca5 bellard
/* rotate left immediate then and with mask insert */
996 79aceca5 bellard
PPC_OP(rotlwi)
997 79aceca5 bellard
{
998 79aceca5 bellard
    T0 = rotl(T0, PARAM(1));
999 79aceca5 bellard
    RETURN();
1000 79aceca5 bellard
}
1001 79aceca5 bellard
1002 79aceca5 bellard
PPC_OP(slwi)
1003 79aceca5 bellard
{
1004 79aceca5 bellard
    T0 = T0 << PARAM(1);
1005 79aceca5 bellard
    RETURN();
1006 79aceca5 bellard
}
1007 79aceca5 bellard
1008 79aceca5 bellard
PPC_OP(srwi)
1009 79aceca5 bellard
{
1010 79aceca5 bellard
    T0 = T0 >> PARAM(1);
1011 79aceca5 bellard
    RETURN();
1012 79aceca5 bellard
}
1013 79aceca5 bellard
1014 79aceca5 bellard
/* rotate left word then and with mask insert */
1015 79aceca5 bellard
PPC_OP(rlwinm)
1016 79aceca5 bellard
{
1017 79aceca5 bellard
    T0 = rotl(T0, PARAM(1)) & PARAM(2);
1018 79aceca5 bellard
    RETURN();
1019 79aceca5 bellard
}
1020 79aceca5 bellard
1021 79aceca5 bellard
PPC_OP(rotl)
1022 79aceca5 bellard
{
1023 79aceca5 bellard
    T0 = rotl(T0, T1);
1024 79aceca5 bellard
    RETURN();
1025 79aceca5 bellard
}
1026 79aceca5 bellard
1027 79aceca5 bellard
PPC_OP(rlwnm)
1028 79aceca5 bellard
{
1029 79aceca5 bellard
    T0 = rotl(T0, T1) & PARAM(1);
1030 79aceca5 bellard
    RETURN();
1031 79aceca5 bellard
}
1032 79aceca5 bellard
1033 79aceca5 bellard
/***                             Integer shift                             ***/
1034 79aceca5 bellard
/* shift left word */
1035 79aceca5 bellard
PPC_OP(slw)
1036 79aceca5 bellard
{
1037 79aceca5 bellard
    if (T1 & 0x20) {
1038 79aceca5 bellard
        T0 = 0;
1039 79aceca5 bellard
    } else {
1040 79aceca5 bellard
        T0 = T0 << T1;
1041 79aceca5 bellard
    }
1042 79aceca5 bellard
    RETURN();
1043 79aceca5 bellard
}
1044 79aceca5 bellard
1045 79aceca5 bellard
/* shift right algebraic word */
1046 79aceca5 bellard
PPC_OP(sraw)
1047 79aceca5 bellard
{
1048 79aceca5 bellard
    Ts0 = do_sraw(Ts0, T1);
1049 79aceca5 bellard
    RETURN();
1050 79aceca5 bellard
}
1051 79aceca5 bellard
1052 79aceca5 bellard
/* shift right algebraic word immediate */
1053 79aceca5 bellard
PPC_OP(srawi)
1054 79aceca5 bellard
{
1055 79aceca5 bellard
    Ts1 = Ts0;
1056 79aceca5 bellard
    Ts0 = Ts0 >> PARAM(1);
1057 79aceca5 bellard
    if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
1058 79aceca5 bellard
        xer_ca = 1;
1059 79aceca5 bellard
    } else {
1060 79aceca5 bellard
        xer_ca = 0;
1061 79aceca5 bellard
    }
1062 79aceca5 bellard
    RETURN();
1063 79aceca5 bellard
}
1064 79aceca5 bellard
1065 79aceca5 bellard
/* shift right word */
1066 79aceca5 bellard
PPC_OP(srw)
1067 79aceca5 bellard
{
1068 79aceca5 bellard
    if (T1 & 0x20) {
1069 79aceca5 bellard
        T0 = 0;
1070 79aceca5 bellard
    } else {
1071 79aceca5 bellard
        T0 = T0 >> T1;
1072 79aceca5 bellard
    }
1073 79aceca5 bellard
    RETURN();
1074 79aceca5 bellard
}
1075 79aceca5 bellard
1076 79aceca5 bellard
/***                       Floating-Point arithmetic                       ***/
1077 79aceca5 bellard
1078 79aceca5 bellard
/***                     Floating-Point multiply-and-add                   ***/
1079 79aceca5 bellard
1080 79aceca5 bellard
/***                     Floating-Point round & convert                    ***/
1081 79aceca5 bellard
1082 79aceca5 bellard
/***                         Floating-Point compare                        ***/
1083 79aceca5 bellard
1084 79aceca5 bellard
/***                  Floating-Point status & ctrl register                ***/
1085 79aceca5 bellard
1086 79aceca5 bellard
/***                             Integer load                              ***/
1087 79aceca5 bellard
#define ld16x(x) s_ext16(ld16(x))
1088 79aceca5 bellard
#define PPC_ILD_OPX(name, op)                                                 \
1089 79aceca5 bellard
PPC_OP(l##name##x_z)                                                          \
1090 79aceca5 bellard
{                                                                             \
1091 79aceca5 bellard
    T1 = op(T0);                                                              \
1092 79aceca5 bellard
    RETURN();                                                                 \
1093 79aceca5 bellard
}                                                                             \
1094 79aceca5 bellard
PPC_OP(l##name##x)                                                            \
1095 79aceca5 bellard
{                                                                             \
1096 79aceca5 bellard
    T0 += T1;                                                                 \
1097 79aceca5 bellard
    T1 = op(T0);                                                              \
1098 79aceca5 bellard
    RETURN();                                                                 \
1099 79aceca5 bellard
}
1100 79aceca5 bellard
1101 79aceca5 bellard
#define PPC_ILD_OP(name, op)                                                  \
1102 79aceca5 bellard
PPC_OP(l##name##_z)                                                           \
1103 79aceca5 bellard
{                                                                             \
1104 79aceca5 bellard
    T1 = op(SPARAM(1));                                                       \
1105 79aceca5 bellard
    RETURN();                                                                 \
1106 79aceca5 bellard
}                                                                             \
1107 79aceca5 bellard
PPC_OP(l##name)                                                               \
1108 79aceca5 bellard
{                                                                             \
1109 79aceca5 bellard
    T0 += SPARAM(1);                                                          \
1110 79aceca5 bellard
    T1 = op(T0);                                                              \
1111 79aceca5 bellard
    RETURN();                                                                 \
1112 79aceca5 bellard
}                                                                             \
1113 79aceca5 bellard
PPC_ILD_OPX(name, op)
1114 79aceca5 bellard
1115 79aceca5 bellard
PPC_ILD_OP(bz, ld8);
1116 79aceca5 bellard
PPC_ILD_OP(ha, ld16x);
1117 79aceca5 bellard
PPC_ILD_OP(hz, ld16);
1118 79aceca5 bellard
PPC_ILD_OP(wz, ld32);
1119 79aceca5 bellard
1120 79aceca5 bellard
/***                              Integer store                            ***/
1121 79aceca5 bellard
#define PPC_IST_OPX(name, op)                                                 \
1122 79aceca5 bellard
PPC_OP(st##name##x_z)                                                         \
1123 79aceca5 bellard
{                                                                             \
1124 79aceca5 bellard
    op(T0, T1);                                                               \
1125 79aceca5 bellard
    RETURN();                                                                 \
1126 79aceca5 bellard
}                                                                             \
1127 79aceca5 bellard
PPC_OP(st##name##x)                                                           \
1128 79aceca5 bellard
{                                                                             \
1129 79aceca5 bellard
    T0 += T1;                                                                 \
1130 79aceca5 bellard
    op(T0, T2);                                                               \
1131 79aceca5 bellard
    RETURN();                                                                 \
1132 79aceca5 bellard
}
1133 79aceca5 bellard
1134 79aceca5 bellard
#define PPC_IST_OP(name, op)                                                  \
1135 79aceca5 bellard
PPC_OP(st##name##_z)                                                          \
1136 79aceca5 bellard
{                                                                             \
1137 79aceca5 bellard
    op(SPARAM(1), T0);                                                        \
1138 79aceca5 bellard
    RETURN();                                                                 \
1139 79aceca5 bellard
}                                                                             \
1140 79aceca5 bellard
PPC_OP(st##name)                                                              \
1141 79aceca5 bellard
{                                                                             \
1142 79aceca5 bellard
    T0 += SPARAM(1);                                                          \
1143 79aceca5 bellard
    op(T0, T1);                                                               \
1144 79aceca5 bellard
    RETURN();                                                                 \
1145 79aceca5 bellard
}                                                                             \
1146 79aceca5 bellard
PPC_IST_OPX(name, op);
1147 79aceca5 bellard
1148 79aceca5 bellard
PPC_IST_OP(b, st8);
1149 79aceca5 bellard
PPC_IST_OP(h, st16);
1150 79aceca5 bellard
PPC_IST_OP(w, st32);
1151 79aceca5 bellard
1152 79aceca5 bellard
/***                Integer load and store with byte reverse               ***/
1153 79aceca5 bellard
PPC_ILD_OPX(hbr, ld16r);
1154 79aceca5 bellard
PPC_ILD_OPX(wbr, ld32r);
1155 79aceca5 bellard
PPC_IST_OPX(hbr, st16r);
1156 79aceca5 bellard
PPC_IST_OPX(wbr, st32r);
1157 79aceca5 bellard
1158 79aceca5 bellard
/***                    Integer load and store multiple                    ***/
1159 79aceca5 bellard
PPC_OP(lmw)
1160 79aceca5 bellard
{
1161 79aceca5 bellard
    do_lmw(PARAM(1), SPARAM(2) + T0);
1162 79aceca5 bellard
    RETURN();
1163 79aceca5 bellard
}
1164 79aceca5 bellard
1165 79aceca5 bellard
PPC_OP(stmw)
1166 79aceca5 bellard
{
1167 79aceca5 bellard
    do_stmw(PARAM(1), SPARAM(2) + T0);
1168 79aceca5 bellard
    RETURN();
1169 79aceca5 bellard
}
1170 79aceca5 bellard
1171 79aceca5 bellard
/***                    Integer load and store strings                     ***/
1172 79aceca5 bellard
PPC_OP(lswi)
1173 79aceca5 bellard
{
1174 79aceca5 bellard
    do_lsw(PARAM(1), PARAM(2), T0);
1175 79aceca5 bellard
    RETURN();
1176 79aceca5 bellard
}
1177 79aceca5 bellard
1178 79aceca5 bellard
PPC_OP(lswx)
1179 79aceca5 bellard
{
1180 79aceca5 bellard
    do_lsw(PARAM(1), T0, T1 + T2);
1181 79aceca5 bellard
    RETURN();
1182 79aceca5 bellard
}
1183 79aceca5 bellard
1184 79aceca5 bellard
PPC_OP(stswi_z)
1185 79aceca5 bellard
{
1186 79aceca5 bellard
    do_stsw(PARAM(1), PARAM(2), 0);
1187 79aceca5 bellard
    RETURN();
1188 79aceca5 bellard
}
1189 79aceca5 bellard
1190 79aceca5 bellard
PPC_OP(stswi)
1191 79aceca5 bellard
{
1192 79aceca5 bellard
    do_stsw(PARAM(1), PARAM(2), T0);
1193 79aceca5 bellard
    RETURN();
1194 79aceca5 bellard
}
1195 79aceca5 bellard
1196 79aceca5 bellard
PPC_OP(stswx_z)
1197 79aceca5 bellard
{
1198 79aceca5 bellard
    do_stsw(PARAM(1), T0, T1);
1199 79aceca5 bellard
    RETURN();
1200 79aceca5 bellard
}
1201 79aceca5 bellard
1202 79aceca5 bellard
PPC_OP(stswx)
1203 79aceca5 bellard
{
1204 79aceca5 bellard
    do_stsw(PARAM(1), T0, T1 + T2);
1205 79aceca5 bellard
    RETURN();
1206 79aceca5 bellard
}
1207 28b6751f bellard
1208 28b6751f bellard
/* SPR */
1209 28b6751f bellard
PPC_OP(load_spr)
1210 28b6751f bellard
{
1211 28b6751f bellard
    T0 = regs->spr[PARAM(1)];
1212 28b6751f bellard
}
1213 28b6751f bellard
1214 28b6751f bellard
PPC_OP(store_spr)
1215 28b6751f bellard
{
1216 28b6751f bellard
    regs->spr[PARAM(1)] = T0;
1217 28b6751f bellard
}
1218 28b6751f bellard
1219 28b6751f bellard
/* FPSCR */
1220 28b6751f bellard
PPC_OP(load_fpscr)
1221 28b6751f bellard
{
1222 28b6751f bellard
    T0 = do_load_fpscr();
1223 28b6751f bellard
}
1224 28b6751f bellard
1225 28b6751f bellard
PPC_OP(store_fpscr)
1226 28b6751f bellard
{
1227 28b6751f bellard
    do_store_fpscr(PARAM(1), T0);
1228 28b6751f bellard
}
1229 28b6751f bellard
1230 28b6751f bellard
/***                         Floating-point store                          ***/
1231 28b6751f bellard
1232 28b6751f bellard
static inline uint32_t dtos(uint64_t f)
1233 28b6751f bellard
{
1234 28b6751f bellard
    unsigned int e, m, s;
1235 28b6751f bellard
    e = (((f >> 52) & 0x7ff) - 1022) + 126;
1236 28b6751f bellard
    s = (f >> 63);
1237 28b6751f bellard
    m = (f >> 29);
1238 28b6751f bellard
    return (s << 31) | (e << 23) | m;
1239 28b6751f bellard
}
1240 28b6751f bellard
1241 28b6751f bellard
static inline uint64_t stod(uint32_t f)
1242 28b6751f bellard
{
1243 28b6751f bellard
    unsigned int e, m, s;
1244 28b6751f bellard
    e = ((f >> 23) & 0xff) - 126 + 1022;
1245 28b6751f bellard
    s = f >> 31;
1246 28b6751f bellard
    m = f & ((1 << 23) - 1);
1247 28b6751f bellard
    return ((uint64_t)s << 63) | ((uint64_t)e << 52) | ((uint64_t)m << 29);
1248 28b6751f bellard
}
1249 28b6751f bellard
1250 28b6751f bellard
PPC_OP(stfd_z_FT0)
1251 28b6751f bellard
{
1252 28b6751f bellard
    st64(SPARAM(1), FT0);
1253 28b6751f bellard
}
1254 28b6751f bellard
1255 28b6751f bellard
PPC_OP(stfd_FT0)
1256 28b6751f bellard
{
1257 28b6751f bellard
    T0 += SPARAM(1);
1258 28b6751f bellard
    st64(T0, FT0);
1259 28b6751f bellard
}
1260 28b6751f bellard
1261 28b6751f bellard
PPC_OP(stfdx_z_FT0)
1262 28b6751f bellard
{
1263 28b6751f bellard
    st64(T0, FT0);
1264 28b6751f bellard
}
1265 28b6751f bellard
1266 28b6751f bellard
PPC_OP(stfdx_FT0)
1267 28b6751f bellard
{
1268 28b6751f bellard
    T0 += T1;
1269 28b6751f bellard
    st64(T0, FT0);
1270 28b6751f bellard
}
1271 28b6751f bellard
1272 28b6751f bellard
1273 28b6751f bellard
PPC_OP(stfs_z_FT0)
1274 28b6751f bellard
{
1275 28b6751f bellard
    st32(SPARAM(1), dtos(FT0));
1276 28b6751f bellard
}
1277 28b6751f bellard
1278 28b6751f bellard
PPC_OP(stfs_FT0)
1279 28b6751f bellard
{
1280 28b6751f bellard
    T0 += SPARAM(1);
1281 28b6751f bellard
    st32(T0, dtos(FT0));
1282 28b6751f bellard
}
1283 28b6751f bellard
1284 28b6751f bellard
PPC_OP(stfsx_z_FT0)
1285 28b6751f bellard
{
1286 28b6751f bellard
    st32(T0, dtos(FT0));
1287 28b6751f bellard
}
1288 28b6751f bellard
1289 28b6751f bellard
PPC_OP(stfsx_FT0)
1290 28b6751f bellard
{
1291 28b6751f bellard
    T0 += T1;
1292 28b6751f bellard
    st32(T0, dtos(FT0));
1293 28b6751f bellard
}
1294 28b6751f bellard
1295 28b6751f bellard
/***                         Floating-point load                          ***/
1296 28b6751f bellard
PPC_OP(lfd_z_FT0)
1297 28b6751f bellard
{
1298 28b6751f bellard
    FT0 = ld64(SPARAM(1));
1299 28b6751f bellard
}
1300 28b6751f bellard
1301 28b6751f bellard
PPC_OP(lfd_FT0)
1302 28b6751f bellard
{
1303 28b6751f bellard
    T0 += SPARAM(1);
1304 28b6751f bellard
    FT0 = ld64(T0);
1305 28b6751f bellard
}
1306 28b6751f bellard
1307 28b6751f bellard
PPC_OP(lfdx_z_FT0)
1308 28b6751f bellard
{
1309 28b6751f bellard
    FT0 = ld64(T0);
1310 28b6751f bellard
}
1311 28b6751f bellard
1312 28b6751f bellard
PPC_OP(lfdx_FT0)
1313 28b6751f bellard
{
1314 28b6751f bellard
    T0 += T1;
1315 28b6751f bellard
    FT0 = ld64(T0);
1316 28b6751f bellard
}
1317 28b6751f bellard
1318 28b6751f bellard
PPC_OP(lfs_z_FT0)
1319 28b6751f bellard
{
1320 28b6751f bellard
    FT0 = stod(ld32(SPARAM(1)));
1321 28b6751f bellard
}
1322 28b6751f bellard
1323 28b6751f bellard
PPC_OP(lfs_FT0)
1324 28b6751f bellard
{
1325 28b6751f bellard
    T0 += SPARAM(1);
1326 28b6751f bellard
    FT0 = stod(ld32(T0));
1327 28b6751f bellard
}
1328 28b6751f bellard
1329 28b6751f bellard
PPC_OP(lfsx_z_FT0)
1330 28b6751f bellard
{
1331 28b6751f bellard
    FT0 = stod(ld32(T0));
1332 28b6751f bellard
}
1333 28b6751f bellard
1334 28b6751f bellard
PPC_OP(lfsx_FT0)
1335 28b6751f bellard
{
1336 28b6751f bellard
    T0 += T1;
1337 28b6751f bellard
    FT0 = stod(ld32(T0));
1338 28b6751f bellard
}