Statistics
| Branch: | Revision:

root / target-ppc / op.c @ 71be0fc3

History | View | Annotate | Download (19.5 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 a541f297 bellard
//#define DEBUG_OP
22 a541f297 bellard
23 79aceca5 bellard
#include "config.h"
24 79aceca5 bellard
#include "exec.h"
25 79aceca5 bellard
26 79aceca5 bellard
#define regs (env)
27 79aceca5 bellard
#define Ts0 (int32_t)T0
28 79aceca5 bellard
#define Ts1 (int32_t)T1
29 79aceca5 bellard
#define Ts2 (int32_t)T2
30 79aceca5 bellard
31 28b6751f bellard
#define FT0 (env->ft0)
32 fb0eaffc bellard
#define FT1 (env->ft1)
33 fb0eaffc bellard
#define FT2 (env->ft2)
34 fb0eaffc bellard
35 9a64fbe4 bellard
#define PPC_OP(name) void glue(op_, name)(void)
36 79aceca5 bellard
37 28b6751f bellard
#define REG 0
38 28b6751f bellard
#include "op_template.h"
39 28b6751f bellard
40 28b6751f bellard
#define REG 1
41 28b6751f bellard
#include "op_template.h"
42 28b6751f bellard
43 28b6751f bellard
#define REG 2
44 28b6751f bellard
#include "op_template.h"
45 28b6751f bellard
46 28b6751f bellard
#define REG 3
47 28b6751f bellard
#include "op_template.h"
48 28b6751f bellard
49 28b6751f bellard
#define REG 4
50 28b6751f bellard
#include "op_template.h"
51 28b6751f bellard
52 28b6751f bellard
#define REG 5
53 28b6751f bellard
#include "op_template.h"
54 28b6751f bellard
55 28b6751f bellard
#define REG 6
56 28b6751f bellard
#include "op_template.h"
57 28b6751f bellard
58 28b6751f bellard
#define REG 7
59 28b6751f bellard
#include "op_template.h"
60 28b6751f bellard
61 28b6751f bellard
#define REG 8
62 28b6751f bellard
#include "op_template.h"
63 28b6751f bellard
64 28b6751f bellard
#define REG 9
65 28b6751f bellard
#include "op_template.h"
66 28b6751f bellard
67 28b6751f bellard
#define REG 10
68 28b6751f bellard
#include "op_template.h"
69 28b6751f bellard
70 28b6751f bellard
#define REG 11
71 28b6751f bellard
#include "op_template.h"
72 28b6751f bellard
73 28b6751f bellard
#define REG 12
74 28b6751f bellard
#include "op_template.h"
75 28b6751f bellard
76 28b6751f bellard
#define REG 13
77 28b6751f bellard
#include "op_template.h"
78 28b6751f bellard
79 28b6751f bellard
#define REG 14
80 28b6751f bellard
#include "op_template.h"
81 28b6751f bellard
82 28b6751f bellard
#define REG 15
83 28b6751f bellard
#include "op_template.h"
84 28b6751f bellard
85 28b6751f bellard
#define REG 16
86 28b6751f bellard
#include "op_template.h"
87 28b6751f bellard
88 28b6751f bellard
#define REG 17
89 28b6751f bellard
#include "op_template.h"
90 28b6751f bellard
91 28b6751f bellard
#define REG 18
92 28b6751f bellard
#include "op_template.h"
93 28b6751f bellard
94 28b6751f bellard
#define REG 19
95 28b6751f bellard
#include "op_template.h"
96 28b6751f bellard
97 28b6751f bellard
#define REG 20
98 28b6751f bellard
#include "op_template.h"
99 28b6751f bellard
100 28b6751f bellard
#define REG 21
101 28b6751f bellard
#include "op_template.h"
102 28b6751f bellard
103 28b6751f bellard
#define REG 22
104 28b6751f bellard
#include "op_template.h"
105 28b6751f bellard
106 28b6751f bellard
#define REG 23
107 28b6751f bellard
#include "op_template.h"
108 28b6751f bellard
109 28b6751f bellard
#define REG 24
110 28b6751f bellard
#include "op_template.h"
111 28b6751f bellard
112 28b6751f bellard
#define REG 25
113 28b6751f bellard
#include "op_template.h"
114 28b6751f bellard
115 28b6751f bellard
#define REG 26
116 28b6751f bellard
#include "op_template.h"
117 28b6751f bellard
118 28b6751f bellard
#define REG 27
119 28b6751f bellard
#include "op_template.h"
120 28b6751f bellard
121 28b6751f bellard
#define REG 28
122 28b6751f bellard
#include "op_template.h"
123 28b6751f bellard
124 28b6751f bellard
#define REG 29
125 28b6751f bellard
#include "op_template.h"
126 28b6751f bellard
127 28b6751f bellard
#define REG 30
128 28b6751f bellard
#include "op_template.h"
129 28b6751f bellard
130 28b6751f bellard
#define REG 31
131 28b6751f bellard
#include "op_template.h"
132 28b6751f bellard
133 79aceca5 bellard
/* PPC state maintenance operations */
134 79aceca5 bellard
/* set_Rc0 */
135 79aceca5 bellard
PPC_OP(set_Rc0)
136 79aceca5 bellard
{
137 79aceca5 bellard
    uint32_t tmp;
138 79aceca5 bellard
139 79aceca5 bellard
    if (Ts0 < 0) {
140 79aceca5 bellard
        tmp = 0x08;
141 79aceca5 bellard
    } else if (Ts0 > 0) {
142 79aceca5 bellard
        tmp = 0x04;
143 79aceca5 bellard
    } else {
144 79aceca5 bellard
        tmp = 0x02;
145 79aceca5 bellard
    }
146 79aceca5 bellard
    tmp |= xer_ov;
147 9a64fbe4 bellard
    env->crf[0] = tmp;
148 79aceca5 bellard
    RETURN();
149 79aceca5 bellard
}
150 79aceca5 bellard
151 79aceca5 bellard
/* reset_Rc0 */
152 79aceca5 bellard
PPC_OP(reset_Rc0)
153 79aceca5 bellard
{
154 9a64fbe4 bellard
    env->crf[0] = 0x02 | xer_ov;
155 79aceca5 bellard
    RETURN();
156 79aceca5 bellard
}
157 79aceca5 bellard
158 79aceca5 bellard
/* set_Rc0_1 */
159 79aceca5 bellard
PPC_OP(set_Rc0_1)
160 79aceca5 bellard
{
161 9a64fbe4 bellard
    env->crf[0] = 0x04 | xer_ov;
162 79aceca5 bellard
    RETURN();
163 79aceca5 bellard
}
164 79aceca5 bellard
165 fb0eaffc bellard
/* Set Rc1 (for floating point arithmetic) */
166 fb0eaffc bellard
PPC_OP(set_Rc1)
167 fb0eaffc bellard
{
168 fb0eaffc bellard
    env->crf[1] = regs->fpscr[7];
169 fb0eaffc bellard
    RETURN();
170 fb0eaffc bellard
}
171 fb0eaffc bellard
172 9a64fbe4 bellard
/* Constants load */
173 79aceca5 bellard
PPC_OP(set_T0)
174 79aceca5 bellard
{
175 79aceca5 bellard
    T0 = PARAM(1);
176 79aceca5 bellard
    RETURN();
177 79aceca5 bellard
}
178 79aceca5 bellard
179 79aceca5 bellard
PPC_OP(set_T1)
180 79aceca5 bellard
{
181 79aceca5 bellard
    T1 = PARAM(1);
182 79aceca5 bellard
    RETURN();
183 79aceca5 bellard
}
184 79aceca5 bellard
185 79aceca5 bellard
PPC_OP(set_T2)
186 79aceca5 bellard
{
187 79aceca5 bellard
    T2 = PARAM(1);
188 79aceca5 bellard
    RETURN();
189 79aceca5 bellard
}
190 79aceca5 bellard
191 9a64fbe4 bellard
/* Generate exceptions */
192 9fddaa0c bellard
PPC_OP(raise_exception_err)
193 79aceca5 bellard
{
194 9fddaa0c bellard
    do_raise_exception_err(PARAM(1), PARAM(2));
195 9a64fbe4 bellard
}
196 9a64fbe4 bellard
197 9fddaa0c bellard
PPC_OP(raise_exception)
198 9a64fbe4 bellard
{
199 9fddaa0c bellard
    do_raise_exception(PARAM(1));
200 9a64fbe4 bellard
}
201 9a64fbe4 bellard
202 9fddaa0c bellard
PPC_OP(update_nip)
203 9a64fbe4 bellard
{
204 004bc62c bellard
    env->nip = PARAM(1);
205 9a64fbe4 bellard
}
206 9a64fbe4 bellard
207 a541f297 bellard
PPC_OP(debug)
208 a541f297 bellard
{
209 a541f297 bellard
    env->nip = PARAM(1);
210 a541f297 bellard
#if defined (DEBUG_OP)
211 a541f297 bellard
    dump_state();
212 a541f297 bellard
#endif
213 9fddaa0c bellard
    do_raise_exception(EXCP_DEBUG);
214 a541f297 bellard
    RETURN();
215 a541f297 bellard
}
216 a541f297 bellard
217 9a64fbe4 bellard
/* Segment registers load and store with immediate index */
218 9a64fbe4 bellard
PPC_OP(load_srin)
219 9a64fbe4 bellard
{
220 9a64fbe4 bellard
    T0 = regs->sr[T1 >> 28];
221 9a64fbe4 bellard
    RETURN();
222 9a64fbe4 bellard
}
223 9a64fbe4 bellard
224 9a64fbe4 bellard
PPC_OP(store_srin)
225 9a64fbe4 bellard
{
226 4b3686fa bellard
    do_store_sr(T1 >> 28);
227 9a64fbe4 bellard
    RETURN();
228 9a64fbe4 bellard
}
229 9a64fbe4 bellard
230 9a64fbe4 bellard
PPC_OP(load_sdr1)
231 9a64fbe4 bellard
{
232 9a64fbe4 bellard
    T0 = regs->sdr1;
233 79aceca5 bellard
    RETURN();
234 79aceca5 bellard
}
235 79aceca5 bellard
236 9a64fbe4 bellard
PPC_OP(store_sdr1)
237 79aceca5 bellard
{
238 9a64fbe4 bellard
    regs->sdr1 = T0;
239 79aceca5 bellard
    RETURN();
240 79aceca5 bellard
}
241 79aceca5 bellard
242 79aceca5 bellard
PPC_OP(exit_tb)
243 79aceca5 bellard
{
244 79aceca5 bellard
    EXIT_TB();
245 79aceca5 bellard
}
246 79aceca5 bellard
247 9a64fbe4 bellard
/* Load/store special registers */
248 79aceca5 bellard
PPC_OP(load_cr)
249 79aceca5 bellard
{
250 9a64fbe4 bellard
    do_load_cr();
251 79aceca5 bellard
    RETURN();
252 79aceca5 bellard
}
253 79aceca5 bellard
254 79aceca5 bellard
PPC_OP(store_cr)
255 79aceca5 bellard
{
256 9a64fbe4 bellard
    do_store_cr(PARAM(1));
257 79aceca5 bellard
    RETURN();
258 79aceca5 bellard
}
259 79aceca5 bellard
260 79aceca5 bellard
PPC_OP(load_xer_cr)
261 79aceca5 bellard
{
262 79aceca5 bellard
    T0 = (xer_so << 3) | (xer_ov << 2) | (xer_ca << 1);
263 79aceca5 bellard
    RETURN();
264 79aceca5 bellard
}
265 79aceca5 bellard
266 79aceca5 bellard
PPC_OP(clear_xer_cr)
267 79aceca5 bellard
{
268 79aceca5 bellard
    xer_so = 0;
269 79aceca5 bellard
    xer_ov = 0;
270 79aceca5 bellard
    xer_ca = 0;
271 79aceca5 bellard
    RETURN();
272 79aceca5 bellard
}
273 79aceca5 bellard
274 79aceca5 bellard
PPC_OP(load_xer_bc)
275 79aceca5 bellard
{
276 9a64fbe4 bellard
    T1 = xer_bc;
277 79aceca5 bellard
    RETURN();
278 79aceca5 bellard
}
279 79aceca5 bellard
280 79aceca5 bellard
PPC_OP(load_xer)
281 79aceca5 bellard
{
282 9a64fbe4 bellard
    do_load_xer();
283 79aceca5 bellard
    RETURN();
284 79aceca5 bellard
}
285 79aceca5 bellard
286 79aceca5 bellard
PPC_OP(store_xer)
287 79aceca5 bellard
{
288 9a64fbe4 bellard
    do_store_xer();
289 79aceca5 bellard
    RETURN();
290 79aceca5 bellard
}
291 79aceca5 bellard
292 79aceca5 bellard
PPC_OP(load_msr)
293 79aceca5 bellard
{
294 9a64fbe4 bellard
    do_load_msr();
295 79aceca5 bellard
    RETURN();
296 79aceca5 bellard
}
297 79aceca5 bellard
298 79aceca5 bellard
PPC_OP(store_msr)
299 79aceca5 bellard
{
300 9a64fbe4 bellard
    do_store_msr();
301 9a64fbe4 bellard
    RETURN();
302 9a64fbe4 bellard
}
303 9a64fbe4 bellard
304 9a64fbe4 bellard
/* SPR */
305 9a64fbe4 bellard
PPC_OP(load_spr)
306 9a64fbe4 bellard
{
307 9a64fbe4 bellard
    T0 = regs->spr[PARAM(1)];
308 9a64fbe4 bellard
    RETURN();
309 9a64fbe4 bellard
}
310 9a64fbe4 bellard
311 9a64fbe4 bellard
PPC_OP(store_spr)
312 9a64fbe4 bellard
{
313 9a64fbe4 bellard
    regs->spr[PARAM(1)] = T0;
314 79aceca5 bellard
    RETURN();
315 79aceca5 bellard
}
316 79aceca5 bellard
317 79aceca5 bellard
PPC_OP(load_lr)
318 79aceca5 bellard
{
319 9a64fbe4 bellard
    T0 = regs->lr;
320 9a64fbe4 bellard
    RETURN();
321 9a64fbe4 bellard
}
322 9a64fbe4 bellard
323 9a64fbe4 bellard
PPC_OP(store_lr)
324 9a64fbe4 bellard
{
325 9a64fbe4 bellard
    regs->lr = T0;
326 9a64fbe4 bellard
    RETURN();
327 9a64fbe4 bellard
}
328 9a64fbe4 bellard
329 9a64fbe4 bellard
PPC_OP(load_ctr)
330 9a64fbe4 bellard
{
331 9a64fbe4 bellard
    T0 = regs->ctr;
332 9a64fbe4 bellard
    RETURN();
333 9a64fbe4 bellard
}
334 9a64fbe4 bellard
335 9a64fbe4 bellard
PPC_OP(store_ctr)
336 9a64fbe4 bellard
{
337 9a64fbe4 bellard
    regs->ctr = T0;
338 9a64fbe4 bellard
    RETURN();
339 9a64fbe4 bellard
}
340 9a64fbe4 bellard
341 9fddaa0c bellard
PPC_OP(load_tbl)
342 9a64fbe4 bellard
{
343 9fddaa0c bellard
    T0 = cpu_ppc_load_tbl(regs);
344 9a64fbe4 bellard
    RETURN();
345 9a64fbe4 bellard
}
346 9a64fbe4 bellard
347 9fddaa0c bellard
PPC_OP(load_tbu)
348 9a64fbe4 bellard
{
349 9fddaa0c bellard
    T0 = cpu_ppc_load_tbu(regs);
350 9a64fbe4 bellard
    RETURN();
351 9a64fbe4 bellard
}
352 9a64fbe4 bellard
353 9fddaa0c bellard
PPC_OP(store_tbl)
354 9a64fbe4 bellard
{
355 9fddaa0c bellard
    cpu_ppc_store_tbl(regs, T0);
356 79aceca5 bellard
    RETURN();
357 79aceca5 bellard
}
358 79aceca5 bellard
359 9fddaa0c bellard
PPC_OP(store_tbu)
360 9a64fbe4 bellard
{
361 9fddaa0c bellard
    cpu_ppc_store_tbu(regs, T0);
362 9a64fbe4 bellard
    RETURN();
363 9a64fbe4 bellard
}
364 9a64fbe4 bellard
365 9fddaa0c bellard
PPC_OP(load_decr)
366 9a64fbe4 bellard
{
367 9fddaa0c bellard
    T0 = cpu_ppc_load_decr(regs);
368 9a64fbe4 bellard
    }
369 9fddaa0c bellard
370 9fddaa0c bellard
PPC_OP(store_decr)
371 9fddaa0c bellard
{
372 9fddaa0c bellard
    cpu_ppc_store_decr(regs, T0);
373 9a64fbe4 bellard
    RETURN();
374 9a64fbe4 bellard
}
375 9a64fbe4 bellard
376 9a64fbe4 bellard
PPC_OP(load_ibat)
377 9a64fbe4 bellard
{
378 9a64fbe4 bellard
    T0 = regs->IBAT[PARAM(1)][PARAM(2)];
379 9a64fbe4 bellard
}
380 9a64fbe4 bellard
381 9a64fbe4 bellard
PPC_OP(store_ibat)
382 9a64fbe4 bellard
{
383 4b3686fa bellard
    do_store_ibat(PARAM(1), PARAM(2));
384 9a64fbe4 bellard
}
385 9a64fbe4 bellard
386 9a64fbe4 bellard
PPC_OP(load_dbat)
387 9a64fbe4 bellard
{
388 9a64fbe4 bellard
    T0 = regs->DBAT[PARAM(1)][PARAM(2)];
389 9a64fbe4 bellard
}
390 9a64fbe4 bellard
391 9a64fbe4 bellard
PPC_OP(store_dbat)
392 9a64fbe4 bellard
{
393 4b3686fa bellard
    do_store_dbat(PARAM(1), PARAM(2));
394 9a64fbe4 bellard
}
395 9a64fbe4 bellard
396 fb0eaffc bellard
/* FPSCR */
397 fb0eaffc bellard
PPC_OP(load_fpscr)
398 fb0eaffc bellard
{
399 fb0eaffc bellard
    do_load_fpscr();
400 fb0eaffc bellard
    RETURN();
401 fb0eaffc bellard
}
402 fb0eaffc bellard
403 fb0eaffc bellard
PPC_OP(store_fpscr)
404 fb0eaffc bellard
{
405 fb0eaffc bellard
    do_store_fpscr(PARAM(1));
406 fb0eaffc bellard
    RETURN();
407 fb0eaffc bellard
}
408 fb0eaffc bellard
409 fb0eaffc bellard
PPC_OP(reset_scrfx)
410 fb0eaffc bellard
{
411 fb0eaffc bellard
    regs->fpscr[7] &= ~0x8;
412 fb0eaffc bellard
    RETURN();
413 fb0eaffc bellard
}
414 fb0eaffc bellard
415 79aceca5 bellard
/* crf operations */
416 79aceca5 bellard
PPC_OP(getbit_T0)
417 79aceca5 bellard
{
418 79aceca5 bellard
    T0 = (T0 >> PARAM(1)) & 1;
419 79aceca5 bellard
    RETURN();
420 79aceca5 bellard
}
421 79aceca5 bellard
422 79aceca5 bellard
PPC_OP(getbit_T1)
423 79aceca5 bellard
{
424 79aceca5 bellard
    T1 = (T1 >> PARAM(1)) & 1;
425 79aceca5 bellard
    RETURN();
426 79aceca5 bellard
}
427 79aceca5 bellard
428 79aceca5 bellard
PPC_OP(setcrfbit)
429 79aceca5 bellard
{
430 79aceca5 bellard
    T1 = (T1 & PARAM(1)) | (T0 << PARAM(2)); 
431 79aceca5 bellard
    RETURN();
432 79aceca5 bellard
}
433 79aceca5 bellard
434 79aceca5 bellard
/* Branch */
435 9a64fbe4 bellard
#define EIP regs->nip
436 9a64fbe4 bellard
437 e98a6e40 bellard
PPC_OP(setlr)
438 e98a6e40 bellard
{
439 e98a6e40 bellard
    regs->lr = PARAM1;
440 e98a6e40 bellard
}
441 e98a6e40 bellard
442 e98a6e40 bellard
PPC_OP(b)
443 e98a6e40 bellard
{
444 e98a6e40 bellard
    JUMP_TB(b1, PARAM1, 0, PARAM2);
445 e98a6e40 bellard
}
446 e98a6e40 bellard
447 e98a6e40 bellard
PPC_OP(b_T1)
448 e98a6e40 bellard
{
449 89934337 bellard
    regs->nip = T1 & ~3;
450 e98a6e40 bellard
}
451 e98a6e40 bellard
452 e98a6e40 bellard
PPC_OP(btest) 
453 e98a6e40 bellard
{
454 e98a6e40 bellard
    if (T0) {
455 e98a6e40 bellard
        JUMP_TB(btest, PARAM1, 0, PARAM2);
456 e98a6e40 bellard
    } else {
457 e98a6e40 bellard
        JUMP_TB(btest, PARAM1, 1, PARAM3);
458 e98a6e40 bellard
    }
459 e98a6e40 bellard
    RETURN();
460 e98a6e40 bellard
}
461 e98a6e40 bellard
462 e98a6e40 bellard
PPC_OP(btest_T1) 
463 e98a6e40 bellard
{
464 e98a6e40 bellard
    if (T0) {
465 e98a6e40 bellard
        regs->nip = T1 & ~3;
466 e98a6e40 bellard
    } else {
467 e98a6e40 bellard
        regs->nip = PARAM1;
468 e98a6e40 bellard
    }
469 e98a6e40 bellard
    RETURN();
470 e98a6e40 bellard
}
471 e98a6e40 bellard
472 e98a6e40 bellard
PPC_OP(movl_T1_ctr)
473 e98a6e40 bellard
{
474 e98a6e40 bellard
    T1 = regs->ctr;
475 e98a6e40 bellard
}
476 e98a6e40 bellard
477 e98a6e40 bellard
PPC_OP(movl_T1_lr)
478 e98a6e40 bellard
{
479 e98a6e40 bellard
    T1 = regs->lr;
480 e98a6e40 bellard
}
481 e98a6e40 bellard
482 e98a6e40 bellard
/* tests with result in T0 */
483 e98a6e40 bellard
484 e98a6e40 bellard
PPC_OP(test_ctr)
485 e98a6e40 bellard
{
486 b88e4a9a bellard
    T0 = regs->ctr;
487 e98a6e40 bellard
}
488 e98a6e40 bellard
489 e98a6e40 bellard
PPC_OP(test_ctr_true)
490 e98a6e40 bellard
{
491 e98a6e40 bellard
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
492 e98a6e40 bellard
}
493 e98a6e40 bellard
494 e98a6e40 bellard
PPC_OP(test_ctr_false)
495 e98a6e40 bellard
{
496 e98a6e40 bellard
    T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
497 e98a6e40 bellard
}
498 e98a6e40 bellard
499 e98a6e40 bellard
PPC_OP(test_ctrz)
500 e98a6e40 bellard
{
501 e98a6e40 bellard
    T0 = (regs->ctr == 0);
502 e98a6e40 bellard
}
503 e98a6e40 bellard
504 e98a6e40 bellard
PPC_OP(test_ctrz_true)
505 e98a6e40 bellard
{
506 e98a6e40 bellard
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
507 e98a6e40 bellard
}
508 e98a6e40 bellard
509 e98a6e40 bellard
PPC_OP(test_ctrz_false)
510 e98a6e40 bellard
{
511 e98a6e40 bellard
    T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
512 e98a6e40 bellard
}
513 e98a6e40 bellard
514 e98a6e40 bellard
PPC_OP(test_true)
515 e98a6e40 bellard
{
516 b88e4a9a bellard
    T0 = (T0 & PARAM(1));
517 e98a6e40 bellard
}
518 e98a6e40 bellard
519 e98a6e40 bellard
PPC_OP(test_false)
520 e98a6e40 bellard
{
521 e98a6e40 bellard
    T0 = ((T0 & PARAM(1)) == 0);
522 e98a6e40 bellard
}
523 79aceca5 bellard
524 79aceca5 bellard
/* CTR maintenance */
525 79aceca5 bellard
PPC_OP(dec_ctr)
526 79aceca5 bellard
{
527 9a64fbe4 bellard
    regs->ctr--;
528 79aceca5 bellard
    RETURN();
529 79aceca5 bellard
}
530 79aceca5 bellard
531 79aceca5 bellard
/***                           Integer arithmetic                          ***/
532 79aceca5 bellard
/* add */
533 79aceca5 bellard
PPC_OP(add)
534 79aceca5 bellard
{
535 79aceca5 bellard
    T0 += T1;
536 79aceca5 bellard
    RETURN();
537 79aceca5 bellard
}
538 79aceca5 bellard
539 79aceca5 bellard
PPC_OP(addo)
540 79aceca5 bellard
{
541 79aceca5 bellard
    T2 = T0;
542 79aceca5 bellard
    T0 += T1;
543 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
544 79aceca5 bellard
        xer_so = 1;
545 79aceca5 bellard
        xer_ov = 1;
546 79aceca5 bellard
    } else {
547 79aceca5 bellard
        xer_ov = 0;
548 79aceca5 bellard
    }
549 79aceca5 bellard
    RETURN();
550 79aceca5 bellard
}
551 79aceca5 bellard
552 79aceca5 bellard
/* add carrying */
553 79aceca5 bellard
PPC_OP(addc)
554 79aceca5 bellard
{
555 79aceca5 bellard
    T2 = T0;
556 79aceca5 bellard
    T0 += T1;
557 79aceca5 bellard
    if (T0 < T2) {
558 79aceca5 bellard
        xer_ca = 1;
559 79aceca5 bellard
    } else {
560 79aceca5 bellard
        xer_ca = 0;
561 79aceca5 bellard
    }
562 79aceca5 bellard
    RETURN();
563 79aceca5 bellard
}
564 79aceca5 bellard
565 79aceca5 bellard
PPC_OP(addco)
566 79aceca5 bellard
{
567 79aceca5 bellard
    T2 = T0;
568 79aceca5 bellard
    T0 += T1;
569 79aceca5 bellard
    if (T0 < T2) {
570 79aceca5 bellard
        xer_ca = 1;
571 79aceca5 bellard
    } else {
572 79aceca5 bellard
        xer_ca = 0;
573 79aceca5 bellard
    }
574 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
575 79aceca5 bellard
        xer_so = 1;
576 79aceca5 bellard
        xer_ov = 1;
577 79aceca5 bellard
    } else {
578 79aceca5 bellard
        xer_ov = 0;
579 79aceca5 bellard
    }
580 79aceca5 bellard
    RETURN();
581 79aceca5 bellard
}
582 79aceca5 bellard
583 79aceca5 bellard
/* add extended */
584 79aceca5 bellard
/* candidate for helper (too long) */
585 79aceca5 bellard
PPC_OP(adde)
586 79aceca5 bellard
{
587 79aceca5 bellard
    T2 = T0;
588 79aceca5 bellard
    T0 += T1 + xer_ca;
589 79aceca5 bellard
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
590 79aceca5 bellard
        xer_ca = 1;
591 79aceca5 bellard
    } else {
592 79aceca5 bellard
        xer_ca = 0;
593 79aceca5 bellard
    }
594 79aceca5 bellard
    RETURN();
595 79aceca5 bellard
}
596 79aceca5 bellard
597 79aceca5 bellard
PPC_OP(addeo)
598 79aceca5 bellard
{
599 79aceca5 bellard
    T2 = T0;
600 79aceca5 bellard
    T0 += T1 + xer_ca;
601 79aceca5 bellard
    if (T0 < T2 || (xer_ca == 1 && T0 == T2)) {
602 79aceca5 bellard
        xer_ca = 1;
603 79aceca5 bellard
    } else {
604 79aceca5 bellard
        xer_ca = 0;
605 79aceca5 bellard
    }
606 79aceca5 bellard
    if ((T2 ^ T1 ^ (-1)) & (T2 ^ T0) & (1 << 31)) {
607 79aceca5 bellard
        xer_so = 1;
608 79aceca5 bellard
        xer_ov = 1;
609 79aceca5 bellard
    } else {
610 79aceca5 bellard
        xer_ov = 0;
611 79aceca5 bellard
    }
612 79aceca5 bellard
    RETURN();
613 79aceca5 bellard
}
614 79aceca5 bellard
615 79aceca5 bellard
/* add immediate */
616 79aceca5 bellard
PPC_OP(addi)
617 79aceca5 bellard
{
618 79aceca5 bellard
    T0 += PARAM(1);
619 79aceca5 bellard
    RETURN();
620 79aceca5 bellard
}
621 79aceca5 bellard
622 79aceca5 bellard
/* add immediate carrying */
623 79aceca5 bellard
PPC_OP(addic)
624 79aceca5 bellard
{
625 79aceca5 bellard
    T1 = T0;
626 79aceca5 bellard
    T0 += PARAM(1);
627 79aceca5 bellard
    if (T0 < T1) {
628 79aceca5 bellard
        xer_ca = 1;
629 79aceca5 bellard
    } else {
630 79aceca5 bellard
        xer_ca = 0;
631 79aceca5 bellard
    }
632 79aceca5 bellard
    RETURN();
633 79aceca5 bellard
}
634 79aceca5 bellard
635 79aceca5 bellard
/* add to minus one extended */
636 79aceca5 bellard
PPC_OP(addme)
637 79aceca5 bellard
{
638 79aceca5 bellard
    T1 = T0;
639 79aceca5 bellard
    T0 += xer_ca + (-1);
640 79aceca5 bellard
    if (T1 != 0)
641 79aceca5 bellard
        xer_ca = 1;
642 79aceca5 bellard
    RETURN();
643 79aceca5 bellard
}
644 79aceca5 bellard
645 79aceca5 bellard
PPC_OP(addmeo)
646 79aceca5 bellard
{
647 79aceca5 bellard
    T1 = T0;
648 79aceca5 bellard
    T0 += xer_ca + (-1);
649 79aceca5 bellard
    if (T1 & (T1 ^ T0) & (1 << 31)) {
650 79aceca5 bellard
        xer_so = 1;
651 79aceca5 bellard
        xer_ov = 1;
652 79aceca5 bellard
    } else {
653 79aceca5 bellard
        xer_ov = 0;
654 79aceca5 bellard
    }
655 79aceca5 bellard
    if (T1 != 0)
656 79aceca5 bellard
        xer_ca = 1;
657 79aceca5 bellard
    RETURN();
658 79aceca5 bellard
}
659 79aceca5 bellard
660 79aceca5 bellard
/* add to zero extended */
661 79aceca5 bellard
PPC_OP(addze)
662 79aceca5 bellard
{
663 79aceca5 bellard
    T1 = T0;
664 79aceca5 bellard
    T0 += xer_ca;
665 79aceca5 bellard
    if (T0 < T1) {
666 79aceca5 bellard
        xer_ca = 1;
667 79aceca5 bellard
    } else {
668 79aceca5 bellard
        xer_ca = 0;
669 79aceca5 bellard
    }
670 79aceca5 bellard
    RETURN();
671 79aceca5 bellard
}
672 79aceca5 bellard
673 79aceca5 bellard
PPC_OP(addzeo)
674 79aceca5 bellard
{
675 79aceca5 bellard
    T1 = T0;
676 79aceca5 bellard
    T0 += xer_ca;
677 79aceca5 bellard
    if ((T1 ^ (-1)) & (T1 ^ T0) & (1 << 31)) {
678 79aceca5 bellard
        xer_so = 1;
679 79aceca5 bellard
        xer_ov = 1;
680 79aceca5 bellard
    } else {
681 79aceca5 bellard
        xer_ov = 0;
682 79aceca5 bellard
    }
683 79aceca5 bellard
    if (T0 < T1) {
684 79aceca5 bellard
        xer_ca = 1;
685 79aceca5 bellard
    } else {
686 79aceca5 bellard
        xer_ca = 0;
687 79aceca5 bellard
    }
688 79aceca5 bellard
    RETURN();
689 79aceca5 bellard
}
690 79aceca5 bellard
691 79aceca5 bellard
/* divide word */
692 79aceca5 bellard
/* candidate for helper (too long) */
693 79aceca5 bellard
PPC_OP(divw)
694 79aceca5 bellard
{
695 79aceca5 bellard
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
696 3cc62370 bellard
        T0 = (int32_t)((-1) * (T0 >> 31));
697 79aceca5 bellard
    } else {
698 3cc62370 bellard
        T0 = (Ts0 / Ts1);
699 79aceca5 bellard
    }
700 79aceca5 bellard
    RETURN();
701 79aceca5 bellard
}
702 79aceca5 bellard
703 79aceca5 bellard
PPC_OP(divwo)
704 79aceca5 bellard
{
705 79aceca5 bellard
    if ((Ts0 == INT32_MIN && Ts1 == -1) || Ts1 == 0) {
706 79aceca5 bellard
        xer_so = 1;
707 79aceca5 bellard
        xer_ov = 1;
708 79aceca5 bellard
        T0 = (-1) * (T0 >> 31);
709 79aceca5 bellard
    } else {
710 79aceca5 bellard
        xer_ov = 0;
711 3cc62370 bellard
        T0 = (Ts0 / Ts1);
712 79aceca5 bellard
    }
713 79aceca5 bellard
    RETURN();
714 79aceca5 bellard
}
715 79aceca5 bellard
716 79aceca5 bellard
/* divide word unsigned */
717 79aceca5 bellard
PPC_OP(divwu)
718 79aceca5 bellard
{
719 79aceca5 bellard
    if (T1 == 0) {
720 79aceca5 bellard
        T0 = 0;
721 79aceca5 bellard
    } else {
722 79aceca5 bellard
        T0 /= T1;
723 79aceca5 bellard
    }
724 79aceca5 bellard
    RETURN();
725 79aceca5 bellard
}
726 79aceca5 bellard
727 79aceca5 bellard
PPC_OP(divwuo)
728 79aceca5 bellard
{
729 79aceca5 bellard
    if (T1 == 0) {
730 79aceca5 bellard
        xer_so = 1;
731 79aceca5 bellard
        xer_ov = 1;
732 79aceca5 bellard
        T0 = 0;
733 79aceca5 bellard
    } else {
734 79aceca5 bellard
        xer_ov = 0;
735 79aceca5 bellard
        T0 /= T1;
736 79aceca5 bellard
    }
737 79aceca5 bellard
    RETURN();
738 79aceca5 bellard
}
739 79aceca5 bellard
740 79aceca5 bellard
/* multiply high word */
741 79aceca5 bellard
PPC_OP(mulhw)
742 79aceca5 bellard
{
743 3cc62370 bellard
    T0 = ((int64_t)Ts0 * (int64_t)Ts1) >> 32;
744 79aceca5 bellard
    RETURN();
745 79aceca5 bellard
}
746 79aceca5 bellard
747 79aceca5 bellard
/* multiply high word unsigned */
748 79aceca5 bellard
PPC_OP(mulhwu)
749 79aceca5 bellard
{
750 79aceca5 bellard
    T0 = ((uint64_t)T0 * (uint64_t)T1) >> 32;
751 79aceca5 bellard
    RETURN();
752 79aceca5 bellard
}
753 79aceca5 bellard
754 79aceca5 bellard
/* multiply low immediate */
755 79aceca5 bellard
PPC_OP(mulli)
756 79aceca5 bellard
{
757 3cc62370 bellard
    T0 = (Ts0 * SPARAM(1));
758 79aceca5 bellard
    RETURN();
759 79aceca5 bellard
}
760 79aceca5 bellard
761 79aceca5 bellard
/* multiply low word */
762 79aceca5 bellard
PPC_OP(mullw)
763 79aceca5 bellard
{
764 79aceca5 bellard
    T0 *= T1;
765 79aceca5 bellard
    RETURN();
766 79aceca5 bellard
}
767 79aceca5 bellard
768 79aceca5 bellard
PPC_OP(mullwo)
769 79aceca5 bellard
{
770 79aceca5 bellard
    int64_t res = (int64_t)Ts0 * (int64_t)Ts1;
771 79aceca5 bellard
772 79aceca5 bellard
    if ((int32_t)res != res) {
773 79aceca5 bellard
        xer_ov = 1;
774 79aceca5 bellard
        xer_so = 1;
775 79aceca5 bellard
    } else {
776 79aceca5 bellard
        xer_ov = 0;
777 79aceca5 bellard
    }
778 3cc62370 bellard
    T0 = (int32_t)res;
779 79aceca5 bellard
    RETURN();
780 79aceca5 bellard
}
781 79aceca5 bellard
782 79aceca5 bellard
/* negate */
783 79aceca5 bellard
PPC_OP(neg)
784 79aceca5 bellard
{
785 79aceca5 bellard
    if (T0 != 0x80000000) {
786 3cc62370 bellard
        T0 = -Ts0;
787 79aceca5 bellard
    }
788 79aceca5 bellard
    RETURN();
789 79aceca5 bellard
}
790 79aceca5 bellard
791 79aceca5 bellard
PPC_OP(nego)
792 79aceca5 bellard
{
793 79aceca5 bellard
    if (T0 == 0x80000000) {
794 79aceca5 bellard
        xer_ov = 1;
795 79aceca5 bellard
        xer_so = 1;
796 79aceca5 bellard
    } else {
797 79aceca5 bellard
        xer_ov = 0;
798 3cc62370 bellard
        T0 = -Ts0;
799 79aceca5 bellard
    }
800 79aceca5 bellard
    RETURN();
801 79aceca5 bellard
}
802 79aceca5 bellard
803 79aceca5 bellard
/* substract from */
804 79aceca5 bellard
PPC_OP(subf)
805 79aceca5 bellard
{
806 79aceca5 bellard
    T0 = T1 - T0;
807 79aceca5 bellard
    RETURN();
808 79aceca5 bellard
}
809 79aceca5 bellard
810 79aceca5 bellard
PPC_OP(subfo)
811 79aceca5 bellard
{
812 79aceca5 bellard
    T2 = T0;
813 79aceca5 bellard
    T0 = T1 - T0;
814 79aceca5 bellard
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
815 79aceca5 bellard
        xer_so = 1;
816 79aceca5 bellard
        xer_ov = 1;
817 79aceca5 bellard
    } else {
818 79aceca5 bellard
        xer_ov = 0;
819 79aceca5 bellard
    }
820 79aceca5 bellard
    RETURN();
821 79aceca5 bellard
}
822 79aceca5 bellard
823 79aceca5 bellard
/* substract from carrying */
824 79aceca5 bellard
PPC_OP(subfc)
825 79aceca5 bellard
{
826 79aceca5 bellard
    T0 = T1 - T0;
827 79aceca5 bellard
    if (T0 <= T1) {
828 79aceca5 bellard
        xer_ca = 1;
829 79aceca5 bellard
    } else {
830 79aceca5 bellard
        xer_ca = 0;
831 79aceca5 bellard
    }
832 79aceca5 bellard
    RETURN();
833 79aceca5 bellard
}
834 79aceca5 bellard
835 79aceca5 bellard
PPC_OP(subfco)
836 79aceca5 bellard
{
837 79aceca5 bellard
    T2 = T0;
838 79aceca5 bellard
    T0 = T1 - T0;
839 79aceca5 bellard
    if (T0 <= T1) {
840 79aceca5 bellard
        xer_ca = 1;
841 79aceca5 bellard
    } else {
842 79aceca5 bellard
        xer_ca = 0;
843 79aceca5 bellard
    }
844 79aceca5 bellard
    if (((~T2) ^ T1 ^ (-1)) & ((~T2) ^ T0) & (1 << 31)) {
845 79aceca5 bellard
        xer_so = 1;
846 79aceca5 bellard
        xer_ov = 1;
847 79aceca5 bellard
    } else {
848 79aceca5 bellard
        xer_ov = 0;
849 79aceca5 bellard
    }
850 79aceca5 bellard
    RETURN();
851 79aceca5 bellard
}
852 79aceca5 bellard
853 79aceca5 bellard
/* substract from extended */
854 79aceca5 bellard
/* candidate for helper (too long) */
855 79aceca5 bellard
PPC_OP(subfe)
856 79aceca5 bellard
{
857 79aceca5 bellard
    T0 = T1 + ~T0 + xer_ca;
858 79aceca5 bellard
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
859 79aceca5 bellard
        xer_ca = 1;
860 79aceca5 bellard
    } else {
861 79aceca5 bellard
        xer_ca = 0;
862 79aceca5 bellard
    }
863 79aceca5 bellard
    RETURN();
864 79aceca5 bellard
}
865 79aceca5 bellard
866 79aceca5 bellard
PPC_OP(subfeo)
867 79aceca5 bellard
{
868 79aceca5 bellard
    T2 = T0;
869 79aceca5 bellard
    T0 = T1 + ~T0 + xer_ca;
870 79aceca5 bellard
    if ((~T2 ^ T1 ^ (-1)) & (~T2 ^ T0) & (1 << 31)) {
871 79aceca5 bellard
        xer_so = 1;
872 79aceca5 bellard
        xer_ov = 1;
873 79aceca5 bellard
    } else {
874 79aceca5 bellard
        xer_ov = 0;
875 79aceca5 bellard
    }
876 79aceca5 bellard
    if (T0 < T1 || (xer_ca == 1 && T0 == T1)) {
877 79aceca5 bellard
        xer_ca = 1;
878 79aceca5 bellard
    } else {
879 79aceca5 bellard
        xer_ca = 0;
880 79aceca5 bellard
    }
881 79aceca5 bellard
    RETURN();
882 79aceca5 bellard
}
883 79aceca5 bellard
884 79aceca5 bellard
/* substract from immediate carrying */
885 79aceca5 bellard
PPC_OP(subfic)
886 79aceca5 bellard
{
887 79aceca5 bellard
    T0 = PARAM(1) + ~T0 + 1;
888 79aceca5 bellard
    if (T0 <= PARAM(1)) {
889 79aceca5 bellard
        xer_ca = 1;
890 79aceca5 bellard
    } else {
891 79aceca5 bellard
        xer_ca = 0;
892 79aceca5 bellard
    }
893 79aceca5 bellard
    RETURN();
894 79aceca5 bellard
}
895 79aceca5 bellard
896 79aceca5 bellard
/* substract from minus one extended */
897 79aceca5 bellard
PPC_OP(subfme)
898 79aceca5 bellard
{
899 79aceca5 bellard
    T0 = ~T0 + xer_ca - 1;
900 79aceca5 bellard
901 79aceca5 bellard
    if (T0 != -1)
902 79aceca5 bellard
        xer_ca = 1;
903 79aceca5 bellard
    RETURN();
904 79aceca5 bellard
}
905 79aceca5 bellard
906 79aceca5 bellard
PPC_OP(subfmeo)
907 79aceca5 bellard
{
908 79aceca5 bellard
    T1 = T0;
909 79aceca5 bellard
    T0 = ~T0 + xer_ca - 1;
910 79aceca5 bellard
    if (~T1 & (~T1 ^ T0) & (1 << 31)) {
911 79aceca5 bellard
        xer_so = 1;
912 79aceca5 bellard
        xer_ov = 1;
913 79aceca5 bellard
    } else {
914 79aceca5 bellard
        xer_ov = 0;
915 79aceca5 bellard
    }
916 79aceca5 bellard
    if (T1 != -1)
917 79aceca5 bellard
        xer_ca = 1;
918 79aceca5 bellard
    RETURN();
919 79aceca5 bellard
}
920 79aceca5 bellard
921 79aceca5 bellard
/* substract from zero extended */
922 79aceca5 bellard
PPC_OP(subfze)
923 79aceca5 bellard
{
924 79aceca5 bellard
    T1 = ~T0;
925 79aceca5 bellard
    T0 = T1 + xer_ca;
926 79aceca5 bellard
    if (T0 < T1) {
927 79aceca5 bellard
        xer_ca = 1;
928 79aceca5 bellard
    } else {
929 79aceca5 bellard
        xer_ca = 0;
930 79aceca5 bellard
    }
931 79aceca5 bellard
    RETURN();
932 79aceca5 bellard
}
933 79aceca5 bellard
934 79aceca5 bellard
PPC_OP(subfzeo)
935 79aceca5 bellard
{
936 79aceca5 bellard
    T1 = T0;
937 79aceca5 bellard
    T0 = ~T0 + xer_ca;
938 79aceca5 bellard
    if ((~T1 ^ (-1)) & ((~T1) ^ T0) & (1 << 31)) {
939 79aceca5 bellard
        xer_ov = 1;
940 79aceca5 bellard
        xer_so = 1;
941 79aceca5 bellard
    } else {
942 79aceca5 bellard
        xer_ov = 0;
943 79aceca5 bellard
    }
944 79aceca5 bellard
    if (T0 < ~T1) {
945 79aceca5 bellard
        xer_ca = 1;
946 79aceca5 bellard
    } else {
947 79aceca5 bellard
        xer_ca = 0;
948 79aceca5 bellard
    }
949 79aceca5 bellard
    RETURN();
950 79aceca5 bellard
}
951 79aceca5 bellard
952 79aceca5 bellard
/***                           Integer comparison                          ***/
953 79aceca5 bellard
/* compare */
954 79aceca5 bellard
PPC_OP(cmp)
955 79aceca5 bellard
{
956 79aceca5 bellard
    if (Ts0 < Ts1) {
957 79aceca5 bellard
        T0 = 0x08;
958 79aceca5 bellard
    } else if (Ts0 > Ts1) {
959 79aceca5 bellard
        T0 = 0x04;
960 79aceca5 bellard
    } else {
961 79aceca5 bellard
        T0 = 0x02;
962 79aceca5 bellard
    }
963 79aceca5 bellard
    RETURN();
964 79aceca5 bellard
}
965 79aceca5 bellard
966 79aceca5 bellard
/* compare immediate */
967 79aceca5 bellard
PPC_OP(cmpi)
968 79aceca5 bellard
{
969 79aceca5 bellard
    if (Ts0 < SPARAM(1)) {
970 79aceca5 bellard
        T0 = 0x08;
971 79aceca5 bellard
    } else if (Ts0 > SPARAM(1)) {
972 79aceca5 bellard
        T0 = 0x04;
973 79aceca5 bellard
    } else {
974 79aceca5 bellard
        T0 = 0x02;
975 79aceca5 bellard
    }
976 79aceca5 bellard
    RETURN();
977 79aceca5 bellard
}
978 79aceca5 bellard
979 79aceca5 bellard
/* compare logical */
980 79aceca5 bellard
PPC_OP(cmpl)
981 79aceca5 bellard
{
982 79aceca5 bellard
    if (T0 < T1) {
983 79aceca5 bellard
        T0 = 0x08;
984 79aceca5 bellard
    } else if (T0 > T1) {
985 79aceca5 bellard
        T0 = 0x04;
986 79aceca5 bellard
    } else {
987 79aceca5 bellard
        T0 = 0x02;
988 79aceca5 bellard
    }
989 79aceca5 bellard
    RETURN();
990 79aceca5 bellard
}
991 79aceca5 bellard
992 79aceca5 bellard
/* compare logical immediate */
993 79aceca5 bellard
PPC_OP(cmpli)
994 79aceca5 bellard
{
995 79aceca5 bellard
    if (T0 < PARAM(1)) {
996 79aceca5 bellard
        T0 = 0x08;
997 79aceca5 bellard
    } else if (T0 > PARAM(1)) {
998 79aceca5 bellard
        T0 = 0x04;
999 79aceca5 bellard
    } else {
1000 79aceca5 bellard
        T0 = 0x02;
1001 79aceca5 bellard
    }
1002 79aceca5 bellard
    RETURN();
1003 79aceca5 bellard
}
1004 79aceca5 bellard
1005 79aceca5 bellard
/***                            Integer logical                            ***/
1006 79aceca5 bellard
/* and */
1007 79aceca5 bellard
PPC_OP(and)
1008 79aceca5 bellard
{
1009 79aceca5 bellard
    T0 &= T1;
1010 79aceca5 bellard
    RETURN();
1011 79aceca5 bellard
}
1012 79aceca5 bellard
1013 79aceca5 bellard
/* andc */
1014 79aceca5 bellard
PPC_OP(andc)
1015 79aceca5 bellard
{
1016 79aceca5 bellard
    T0 &= ~T1;
1017 79aceca5 bellard
    RETURN();
1018 79aceca5 bellard
}
1019 79aceca5 bellard
1020 79aceca5 bellard
/* andi. */
1021 79aceca5 bellard
PPC_OP(andi_)
1022 79aceca5 bellard
{
1023 79aceca5 bellard
    T0 &= PARAM(1);
1024 79aceca5 bellard
    RETURN();
1025 79aceca5 bellard
}
1026 79aceca5 bellard
1027 79aceca5 bellard
/* count leading zero */
1028 79aceca5 bellard
PPC_OP(cntlzw)
1029 79aceca5 bellard
{
1030 79aceca5 bellard
    T1 = T0;
1031 79aceca5 bellard
    for (T0 = 32; T1 > 0; T0--)
1032 79aceca5 bellard
        T1 = T1 >> 1;
1033 79aceca5 bellard
    RETURN();
1034 79aceca5 bellard
}
1035 79aceca5 bellard
1036 79aceca5 bellard
/* eqv */
1037 79aceca5 bellard
PPC_OP(eqv)
1038 79aceca5 bellard
{
1039 79aceca5 bellard
    T0 = ~(T0 ^ T1);
1040 79aceca5 bellard
    RETURN();
1041 79aceca5 bellard
}
1042 79aceca5 bellard
1043 79aceca5 bellard
/* extend sign byte */
1044 79aceca5 bellard
PPC_OP(extsb)
1045 79aceca5 bellard
{
1046 3cc62370 bellard
    T0 = (int32_t)((int8_t)(Ts0));
1047 79aceca5 bellard
    RETURN();
1048 79aceca5 bellard
}
1049 79aceca5 bellard
1050 79aceca5 bellard
/* extend sign half word */
1051 79aceca5 bellard
PPC_OP(extsh)
1052 79aceca5 bellard
{
1053 3cc62370 bellard
    T0 = (int32_t)((int16_t)(Ts0));
1054 79aceca5 bellard
    RETURN();
1055 79aceca5 bellard
}
1056 79aceca5 bellard
1057 79aceca5 bellard
/* nand */
1058 79aceca5 bellard
PPC_OP(nand)
1059 79aceca5 bellard
{
1060 79aceca5 bellard
    T0 = ~(T0 & T1);
1061 79aceca5 bellard
    RETURN();
1062 79aceca5 bellard
}
1063 79aceca5 bellard
1064 79aceca5 bellard
/* nor */
1065 79aceca5 bellard
PPC_OP(nor)
1066 79aceca5 bellard
{
1067 79aceca5 bellard
    T0 = ~(T0 | T1);
1068 79aceca5 bellard
    RETURN();
1069 79aceca5 bellard
}
1070 79aceca5 bellard
1071 79aceca5 bellard
/* or */
1072 79aceca5 bellard
PPC_OP(or)
1073 79aceca5 bellard
{
1074 79aceca5 bellard
    T0 |= T1;
1075 79aceca5 bellard
    RETURN();
1076 79aceca5 bellard
}
1077 79aceca5 bellard
1078 79aceca5 bellard
/* orc */
1079 79aceca5 bellard
PPC_OP(orc)
1080 79aceca5 bellard
{
1081 79aceca5 bellard
    T0 |= ~T1;
1082 79aceca5 bellard
    RETURN();
1083 79aceca5 bellard
}
1084 79aceca5 bellard
1085 79aceca5 bellard
/* ori */
1086 79aceca5 bellard
PPC_OP(ori)
1087 79aceca5 bellard
{
1088 79aceca5 bellard
    T0 |= PARAM(1);
1089 79aceca5 bellard
    RETURN();
1090 79aceca5 bellard
}
1091 79aceca5 bellard
1092 79aceca5 bellard
/* xor */
1093 79aceca5 bellard
PPC_OP(xor)
1094 79aceca5 bellard
{
1095 79aceca5 bellard
    T0 ^= T1;
1096 79aceca5 bellard
    RETURN();
1097 79aceca5 bellard
}
1098 79aceca5 bellard
1099 79aceca5 bellard
/* xori */
1100 79aceca5 bellard
PPC_OP(xori)
1101 79aceca5 bellard
{
1102 79aceca5 bellard
    T0 ^= PARAM(1);
1103 79aceca5 bellard
    RETURN();
1104 79aceca5 bellard
}
1105 79aceca5 bellard
1106 79aceca5 bellard
/***                             Integer rotate                            ***/
1107 79aceca5 bellard
/* rotate left word immediate then mask insert */
1108 79aceca5 bellard
PPC_OP(rlwimi)
1109 79aceca5 bellard
{
1110 fb0eaffc bellard
    T0 = (rotl(T0, PARAM(1)) & PARAM(2)) | (T1 & PARAM(3));
1111 79aceca5 bellard
    RETURN();
1112 79aceca5 bellard
}
1113 79aceca5 bellard
1114 79aceca5 bellard
/* rotate left immediate then and with mask insert */
1115 79aceca5 bellard
PPC_OP(rotlwi)
1116 79aceca5 bellard
{
1117 79aceca5 bellard
    T0 = rotl(T0, PARAM(1));
1118 79aceca5 bellard
    RETURN();
1119 79aceca5 bellard
}
1120 79aceca5 bellard
1121 79aceca5 bellard
PPC_OP(slwi)
1122 79aceca5 bellard
{
1123 79aceca5 bellard
    T0 = T0 << PARAM(1);
1124 79aceca5 bellard
    RETURN();
1125 79aceca5 bellard
}
1126 79aceca5 bellard
1127 79aceca5 bellard
PPC_OP(srwi)
1128 79aceca5 bellard
{
1129 79aceca5 bellard
    T0 = T0 >> PARAM(1);
1130 79aceca5 bellard
    RETURN();
1131 79aceca5 bellard
}
1132 79aceca5 bellard
1133 79aceca5 bellard
/* rotate left word then and with mask insert */
1134 79aceca5 bellard
PPC_OP(rlwinm)
1135 79aceca5 bellard
{
1136 79aceca5 bellard
    T0 = rotl(T0, PARAM(1)) & PARAM(2);
1137 79aceca5 bellard
    RETURN();
1138 79aceca5 bellard
}
1139 79aceca5 bellard
1140 79aceca5 bellard
PPC_OP(rotl)
1141 79aceca5 bellard
{
1142 79aceca5 bellard
    T0 = rotl(T0, T1);
1143 79aceca5 bellard
    RETURN();
1144 79aceca5 bellard
}
1145 79aceca5 bellard
1146 79aceca5 bellard
PPC_OP(rlwnm)
1147 79aceca5 bellard
{
1148 79aceca5 bellard
    T0 = rotl(T0, T1) & PARAM(1);
1149 79aceca5 bellard
    RETURN();
1150 79aceca5 bellard
}
1151 79aceca5 bellard
1152 79aceca5 bellard
/***                             Integer shift                             ***/
1153 79aceca5 bellard
/* shift left word */
1154 79aceca5 bellard
PPC_OP(slw)
1155 79aceca5 bellard
{
1156 79aceca5 bellard
    if (T1 & 0x20) {
1157 79aceca5 bellard
        T0 = 0;
1158 79aceca5 bellard
    } else {
1159 79aceca5 bellard
        T0 = T0 << T1;
1160 79aceca5 bellard
    }
1161 79aceca5 bellard
    RETURN();
1162 79aceca5 bellard
}
1163 79aceca5 bellard
1164 79aceca5 bellard
/* shift right algebraic word */
1165 79aceca5 bellard
PPC_OP(sraw)
1166 79aceca5 bellard
{
1167 9a64fbe4 bellard
    do_sraw();
1168 79aceca5 bellard
    RETURN();
1169 79aceca5 bellard
}
1170 79aceca5 bellard
1171 79aceca5 bellard
/* shift right algebraic word immediate */
1172 79aceca5 bellard
PPC_OP(srawi)
1173 79aceca5 bellard
{
1174 3cc62370 bellard
    T1 = T0;
1175 3cc62370 bellard
    T0 = (Ts0 >> PARAM(1));
1176 79aceca5 bellard
    if (Ts1 < 0 && (Ts1 & PARAM(2)) != 0) {
1177 79aceca5 bellard
        xer_ca = 1;
1178 79aceca5 bellard
    } else {
1179 79aceca5 bellard
        xer_ca = 0;
1180 79aceca5 bellard
    }
1181 79aceca5 bellard
    RETURN();
1182 79aceca5 bellard
}
1183 79aceca5 bellard
1184 79aceca5 bellard
/* shift right word */
1185 79aceca5 bellard
PPC_OP(srw)
1186 79aceca5 bellard
{
1187 79aceca5 bellard
    if (T1 & 0x20) {
1188 79aceca5 bellard
        T0 = 0;
1189 79aceca5 bellard
    } else {
1190 79aceca5 bellard
        T0 = T0 >> T1;
1191 79aceca5 bellard
    }
1192 79aceca5 bellard
    RETURN();
1193 79aceca5 bellard
}
1194 79aceca5 bellard
1195 79aceca5 bellard
/***                       Floating-Point arithmetic                       ***/
1196 9a64fbe4 bellard
/* fadd - fadd. */
1197 9a64fbe4 bellard
PPC_OP(fadd)
1198 79aceca5 bellard
{
1199 9a64fbe4 bellard
    FT0 += FT1;
1200 79aceca5 bellard
    RETURN();
1201 79aceca5 bellard
}
1202 79aceca5 bellard
1203 9a64fbe4 bellard
/* fsub - fsub. */
1204 9a64fbe4 bellard
PPC_OP(fsub)
1205 79aceca5 bellard
{
1206 9a64fbe4 bellard
    FT0 -= FT1;
1207 79aceca5 bellard
    RETURN();
1208 79aceca5 bellard
}
1209 79aceca5 bellard
1210 9a64fbe4 bellard
/* fmul - fmul. */
1211 9a64fbe4 bellard
PPC_OP(fmul)
1212 79aceca5 bellard
{
1213 9a64fbe4 bellard
    FT0 *= FT1;
1214 79aceca5 bellard
    RETURN();
1215 79aceca5 bellard
}
1216 79aceca5 bellard
1217 9a64fbe4 bellard
/* fdiv - fdiv. */
1218 4ecc3190 bellard
void do_fdiv (void);
1219 9a64fbe4 bellard
PPC_OP(fdiv)
1220 79aceca5 bellard
{
1221 4ecc3190 bellard
    do_fdiv();
1222 79aceca5 bellard
    RETURN();
1223 79aceca5 bellard
}
1224 28b6751f bellard
1225 9a64fbe4 bellard
/* fsqrt - fsqrt. */
1226 9a64fbe4 bellard
PPC_OP(fsqrt)
1227 28b6751f bellard
{
1228 9a64fbe4 bellard
    do_fsqrt();
1229 9a64fbe4 bellard
    RETURN();
1230 28b6751f bellard
}
1231 28b6751f bellard
1232 9a64fbe4 bellard
/* fres - fres. */
1233 9a64fbe4 bellard
PPC_OP(fres)
1234 28b6751f bellard
{
1235 9a64fbe4 bellard
    do_fres();
1236 9a64fbe4 bellard
    RETURN();
1237 28b6751f bellard
}
1238 28b6751f bellard
1239 9a64fbe4 bellard
/* frsqrte  - frsqrte. */
1240 9a64fbe4 bellard
PPC_OP(frsqrte)
1241 28b6751f bellard
{
1242 4ecc3190 bellard
    do_frsqrte();
1243 9a64fbe4 bellard
    RETURN();
1244 28b6751f bellard
}
1245 28b6751f bellard
1246 9a64fbe4 bellard
/* fsel - fsel. */
1247 9a64fbe4 bellard
PPC_OP(fsel)
1248 28b6751f bellard
{
1249 9a64fbe4 bellard
    do_fsel();
1250 9a64fbe4 bellard
    RETURN();
1251 28b6751f bellard
}
1252 28b6751f bellard
1253 9a64fbe4 bellard
/***                     Floating-Point multiply-and-add                   ***/
1254 9a64fbe4 bellard
/* fmadd - fmadd. */
1255 9a64fbe4 bellard
PPC_OP(fmadd)
1256 28b6751f bellard
{
1257 9a64fbe4 bellard
    FT0 = (FT0 * FT1) + FT2;
1258 9a64fbe4 bellard
    RETURN();
1259 28b6751f bellard
}
1260 28b6751f bellard
1261 9a64fbe4 bellard
/* fmsub - fmsub. */
1262 9a64fbe4 bellard
PPC_OP(fmsub)
1263 28b6751f bellard
{
1264 9a64fbe4 bellard
    FT0 = (FT0 * FT1) - FT2;
1265 9a64fbe4 bellard
    RETURN();
1266 28b6751f bellard
}
1267 28b6751f bellard
1268 9a64fbe4 bellard
/* fnmadd - fnmadd. - fnmadds - fnmadds. */
1269 9a64fbe4 bellard
PPC_OP(fnmadd)
1270 28b6751f bellard
{
1271 4b3686fa bellard
    do_fnmadd();
1272 9a64fbe4 bellard
    RETURN();
1273 28b6751f bellard
}
1274 28b6751f bellard
1275 9a64fbe4 bellard
/* fnmsub - fnmsub. */
1276 9a64fbe4 bellard
PPC_OP(fnmsub)
1277 28b6751f bellard
{
1278 4b3686fa bellard
    do_fnmsub();
1279 9a64fbe4 bellard
    RETURN();
1280 28b6751f bellard
}
1281 28b6751f bellard
1282 9a64fbe4 bellard
/***                     Floating-Point round & convert                    ***/
1283 9a64fbe4 bellard
/* frsp - frsp. */
1284 9a64fbe4 bellard
PPC_OP(frsp)
1285 28b6751f bellard
{
1286 3cc62370 bellard
    FT0 = (float)FT0;
1287 9a64fbe4 bellard
    RETURN();
1288 28b6751f bellard
}
1289 28b6751f bellard
1290 9a64fbe4 bellard
/* fctiw - fctiw. */
1291 9a64fbe4 bellard
PPC_OP(fctiw)
1292 28b6751f bellard
{
1293 9a64fbe4 bellard
    do_fctiw();
1294 9a64fbe4 bellard
    RETURN();
1295 28b6751f bellard
}
1296 28b6751f bellard
1297 9a64fbe4 bellard
/* fctiwz - fctiwz. */
1298 9a64fbe4 bellard
PPC_OP(fctiwz)
1299 28b6751f bellard
{
1300 9a64fbe4 bellard
    do_fctiwz();
1301 9a64fbe4 bellard
    RETURN();
1302 28b6751f bellard
}
1303 28b6751f bellard
1304 9a64fbe4 bellard
1305 9a64fbe4 bellard
/***                         Floating-Point compare                        ***/
1306 9a64fbe4 bellard
/* fcmpu */
1307 9a64fbe4 bellard
PPC_OP(fcmpu)
1308 28b6751f bellard
{
1309 9a64fbe4 bellard
    do_fcmpu();
1310 9a64fbe4 bellard
    RETURN();
1311 28b6751f bellard
}
1312 28b6751f bellard
1313 9a64fbe4 bellard
/* fcmpo */
1314 9a64fbe4 bellard
PPC_OP(fcmpo)
1315 28b6751f bellard
{
1316 9a64fbe4 bellard
    do_fcmpo();
1317 9a64fbe4 bellard
    RETURN();
1318 fb0eaffc bellard
}
1319 fb0eaffc bellard
1320 9a64fbe4 bellard
/***                         Floating-point move                           ***/
1321 9a64fbe4 bellard
/* fabs */
1322 4ecc3190 bellard
void do_fabs (void);
1323 9a64fbe4 bellard
PPC_OP(fabs)
1324 fb0eaffc bellard
{
1325 9a64fbe4 bellard
    do_fabs();
1326 fb0eaffc bellard
    RETURN();
1327 fb0eaffc bellard
}
1328 fb0eaffc bellard
1329 9a64fbe4 bellard
/* fnabs */
1330 4ecc3190 bellard
void do_fnabs (void);
1331 9a64fbe4 bellard
PPC_OP(fnabs)
1332 fb0eaffc bellard
{
1333 9a64fbe4 bellard
    do_fnabs();
1334 fb0eaffc bellard
    RETURN();
1335 fb0eaffc bellard
}
1336 fb0eaffc bellard
1337 9a64fbe4 bellard
/* fneg */
1338 9a64fbe4 bellard
PPC_OP(fneg)
1339 fb0eaffc bellard
{
1340 9a64fbe4 bellard
    FT0 = -FT0;
1341 fb0eaffc bellard
    RETURN();
1342 fb0eaffc bellard
}
1343 fb0eaffc bellard
1344 9a64fbe4 bellard
/* Load and store */
1345 9a64fbe4 bellard
#define MEMSUFFIX _raw
1346 9a64fbe4 bellard
#include "op_mem.h"
1347 a541f297 bellard
#if !defined(CONFIG_USER_ONLY)
1348 9a64fbe4 bellard
#define MEMSUFFIX _user
1349 9a64fbe4 bellard
#include "op_mem.h"
1350 9a64fbe4 bellard
1351 9a64fbe4 bellard
#define MEMSUFFIX _kernel
1352 9a64fbe4 bellard
#include "op_mem.h"
1353 9a64fbe4 bellard
#endif
1354 9a64fbe4 bellard
1355 4b3686fa bellard
/* Special op to check and maybe clear reservation */
1356 4b3686fa bellard
PPC_OP(check_reservation)
1357 4b3686fa bellard
{
1358 4b3686fa bellard
    do_check_reservation();
1359 4b3686fa bellard
    RETURN();
1360 4b3686fa bellard
}
1361 4b3686fa bellard
1362 9a64fbe4 bellard
/* Return from interrupt */
1363 9a64fbe4 bellard
PPC_OP(rfi)
1364 fb0eaffc bellard
{
1365 9fddaa0c bellard
    regs->nip = regs->spr[SRR0] & ~0x00000003;
1366 4b3686fa bellard
#if 1 // TRY
1367 4b3686fa bellard
    T0 = regs->spr[SRR1] & ~0xFFF00000;
1368 4b3686fa bellard
#else
1369 9a64fbe4 bellard
    T0 = regs->spr[SRR1] & ~0xFFFF0000;
1370 4b3686fa bellard
#endif
1371 9a64fbe4 bellard
    do_store_msr();
1372 a541f297 bellard
#if defined (DEBUG_OP)
1373 9a64fbe4 bellard
    dump_rfi();
1374 a541f297 bellard
#endif
1375 9fddaa0c bellard
    //    do_tlbia();
1376 9fddaa0c bellard
    do_raise_exception(EXCP_RFI);
1377 fb0eaffc bellard
    RETURN();
1378 fb0eaffc bellard
}
1379 fb0eaffc bellard
1380 9a64fbe4 bellard
/* Trap word */
1381 9a64fbe4 bellard
PPC_OP(tw)
1382 fb0eaffc bellard
{
1383 9a64fbe4 bellard
    if ((Ts0 < Ts1 && (PARAM(1) & 0x10)) ||
1384 9a64fbe4 bellard
        (Ts0 > Ts1 && (PARAM(1) & 0x08)) ||
1385 9a64fbe4 bellard
        (Ts0 == Ts1 && (PARAM(1) & 0x04)) ||
1386 9a64fbe4 bellard
        (T0 < T1 && (PARAM(1) & 0x02)) ||
1387 9a64fbe4 bellard
        (T0 > T1 && (PARAM(1) & 0x01)))
1388 9fddaa0c bellard
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1389 fb0eaffc bellard
    RETURN();
1390 fb0eaffc bellard
}
1391 fb0eaffc bellard
1392 9a64fbe4 bellard
PPC_OP(twi)
1393 fb0eaffc bellard
{
1394 9a64fbe4 bellard
    if ((Ts0 < SPARAM(1) && (PARAM(2) & 0x10)) ||
1395 9a64fbe4 bellard
        (Ts0 > SPARAM(1) && (PARAM(2) & 0x08)) ||
1396 9a64fbe4 bellard
        (Ts0 == SPARAM(1) && (PARAM(2) & 0x04)) ||
1397 9a64fbe4 bellard
        (T0 < (uint32_t)SPARAM(1) && (PARAM(2) & 0x02)) ||
1398 9a64fbe4 bellard
        (T0 > (uint32_t)SPARAM(1) && (PARAM(2) & 0x01)))
1399 9fddaa0c bellard
        do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP);
1400 fb0eaffc bellard
    RETURN();
1401 fb0eaffc bellard
}
1402 fb0eaffc bellard
1403 fb0eaffc bellard
/* Instruction cache block invalidate */
1404 9a64fbe4 bellard
PPC_OP(icbi)
1405 fb0eaffc bellard
{
1406 fb0eaffc bellard
    do_icbi();
1407 fb0eaffc bellard
    RETURN();
1408 fb0eaffc bellard
}
1409 fb0eaffc bellard
1410 9a64fbe4 bellard
/* tlbia */
1411 9a64fbe4 bellard
PPC_OP(tlbia)
1412 fb0eaffc bellard
{
1413 9a64fbe4 bellard
    do_tlbia();
1414 9a64fbe4 bellard
    RETURN();
1415 9a64fbe4 bellard
}
1416 9a64fbe4 bellard
1417 9a64fbe4 bellard
/* tlbie */
1418 9a64fbe4 bellard
PPC_OP(tlbie)
1419 9a64fbe4 bellard
{
1420 9a64fbe4 bellard
    do_tlbie();
1421 fb0eaffc bellard
    RETURN();
1422 28b6751f bellard
}