Statistics
| Branch: | Revision:

root / target-ppc / op.c @ ac9eb073

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