Statistics
| Branch: | Revision:

root / target-cris / op.c @ 941db528

History | View | Annotate | Download (21 kB)

1
/*
2
 *  CRIS emulation micro-operations for qemu.
3
 *
4
 *  Copyright (c) 2007 Edgar E. Iglesias, Axis Communications AB.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include "exec.h"
21
#include "host-utils.h"
22

    
23
#define REGNAME r0
24
#define REG (env->regs[0])
25
#include "op_template.h"
26

    
27
#define REGNAME r1
28
#define REG (env->regs[1])
29
#include "op_template.h"
30

    
31
#define REGNAME r2
32
#define REG (env->regs[2])
33
#include "op_template.h"
34

    
35
#define REGNAME r3
36
#define REG (env->regs[3])
37
#include "op_template.h"
38

    
39
#define REGNAME r4
40
#define REG (env->regs[4])
41
#include "op_template.h"
42

    
43
#define REGNAME r5
44
#define REG (env->regs[5])
45
#include "op_template.h"
46

    
47
#define REGNAME r6
48
#define REG (env->regs[6])
49
#include "op_template.h"
50

    
51
#define REGNAME r7
52
#define REG (env->regs[7])
53
#include "op_template.h"
54

    
55
#define REGNAME r8
56
#define REG (env->regs[8])
57
#include "op_template.h"
58

    
59
#define REGNAME r9
60
#define REG (env->regs[9])
61
#include "op_template.h"
62

    
63
#define REGNAME r10
64
#define REG (env->regs[10])
65
#include "op_template.h"
66

    
67
#define REGNAME r11
68
#define REG (env->regs[11])
69
#include "op_template.h"
70

    
71
#define REGNAME r12
72
#define REG (env->regs[12])
73
#include "op_template.h"
74

    
75
#define REGNAME r13
76
#define REG (env->regs[13])
77
#include "op_template.h"
78

    
79
#define REGNAME r14
80
#define REG (env->regs[14])
81
#include "op_template.h"
82

    
83
#define REGNAME r15
84
#define REG (env->regs[15])
85
#include "op_template.h"
86

    
87

    
88
#define REGNAME p0
89
#define REG (env->pregs[0])
90
#include "op_template.h"
91

    
92
#define REGNAME p1
93
#define REG (env->pregs[1])
94
#include "op_template.h"
95

    
96
#define REGNAME p2
97
#define REG (env->pregs[2])
98
#include "op_template.h"
99

    
100
#define REGNAME p3
101
#define REG (env->pregs[3])
102
#include "op_template.h"
103

    
104
#define REGNAME p4
105
#define REG (env->pregs[4])
106
#include "op_template.h"
107

    
108
#define REGNAME p5
109
#define REG (env->pregs[5])
110
#include "op_template.h"
111

    
112
#define REGNAME p6
113
#define REG (env->pregs[6])
114
#include "op_template.h"
115

    
116
#define REGNAME p7
117
#define REG (env->pregs[7])
118
#include "op_template.h"
119

    
120
#define REGNAME p8
121
#define REG (env->pregs[8])
122
#include "op_template.h"
123

    
124
#define REGNAME p9
125
#define REG (env->pregs[9])
126
#include "op_template.h"
127

    
128
#define REGNAME p10
129
#define REG (env->pregs[10])
130
#include "op_template.h"
131

    
132
#define REGNAME p11
133
#define REG (env->pregs[11])
134
#include "op_template.h"
135

    
136
#define REGNAME p12
137
#define REG (env->pregs[12])
138
#include "op_template.h"
139

    
140
#define REGNAME p13
141
#define REG (env->pregs[13])
142
#include "op_template.h"
143

    
144
#define REGNAME p14
145
#define REG (env->pregs[14])
146
#include "op_template.h"
147

    
148
#define REGNAME p15
149
#define REG (env->pregs[15])
150
#include "op_template.h"
151

    
152
/* Microcode.  */
153

    
154
void OPPROTO op_exit_tb (void)
155
{
156
        EXIT_TB();
157
}
158

    
159
void OPPROTO op_goto_tb0 (void)
160
{
161
        GOTO_TB(op_goto_tb0, PARAM1, 0);
162
        RETURN();
163
}
164

    
165
void OPPROTO op_goto_tb1 (void)
166
{
167
        GOTO_TB(op_goto_tb1, PARAM1, 1);
168
        RETURN();
169
}
170

    
171
void OPPROTO op_break_im(void)
172
{
173
        env->trapnr = PARAM1;
174
        env->exception_index = EXCP_BREAK;
175
        cpu_loop_exit();
176
}
177

    
178
void OPPROTO op_debug(void)
179
{
180
        env->exception_index = EXCP_DEBUG;
181
        cpu_loop_exit();
182
}
183

    
184
void OPPROTO op_exec_insn(void)
185
{
186
        env->stats.exec_insns++;
187
        RETURN();
188
}
189
void OPPROTO op_exec_load(void)
190
{
191
        env->stats.exec_loads++;
192
        RETURN();
193
}
194
void OPPROTO op_exec_store(void)
195
{
196
        env->stats.exec_stores++;
197
        RETURN();
198
}
199

    
200
void OPPROTO op_ccs_lshift (void)
201
{
202
        uint32_t ccs;
203

    
204
        /* Apply the ccs shift.  */
205
        ccs = env->pregs[SR_CCS];
206
        ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
207
        env->pregs[SR_CCS] = ccs;
208
}
209
void OPPROTO op_ccs_rshift (void)
210
{
211
        uint32_t ccs;
212

    
213
        /* Apply the ccs shift.  */
214
        ccs = env->pregs[SR_CCS];
215
        ccs = (ccs & 0xc0000000) | (ccs >> 10);
216
        env->pregs[SR_CCS] = ccs;
217
}
218

    
219
void OPPROTO op_setf (void)
220
{
221
        env->pregs[SR_CCS] |= PARAM1;
222
        RETURN();
223
}
224

    
225
void OPPROTO op_clrf (void)
226
{
227
        env->pregs[SR_CCS] &= ~PARAM1;
228
        RETURN();
229
}
230

    
231
void OPPROTO op_movl_debug1_T0 (void)
232
{
233
        env->debug1 = T0;
234
        RETURN();
235
}
236

    
237
void OPPROTO op_movl_debug2_T0 (void)
238
{
239
        env->debug2 = T0;
240
        RETURN();
241
}
242

    
243
void OPPROTO op_movl_debug3_T0 (void)
244
{
245
        env->debug3 = T0;
246
        RETURN();
247
}
248
void OPPROTO op_movl_debug1_T1 (void)
249
{
250
        env->debug1 = T1;
251
        RETURN();
252
}
253

    
254
void OPPROTO op_movl_debug2_T1 (void)
255
{
256
        env->debug2 = T1;
257
        RETURN();
258
}
259

    
260
void OPPROTO op_movl_debug3_T1 (void)
261
{
262
        env->debug3 = T1;
263
        RETURN();
264
}
265
void OPPROTO op_movl_debug3_im (void)
266
{
267
        env->debug3 = PARAM1;
268
        RETURN();
269
}
270
void OPPROTO op_movl_T0_flags (void)
271
{
272
        T0 = env->pregs[SR_CCS];
273
        RETURN();
274
}
275
void OPPROTO op_movl_flags_T0 (void)
276
{
277
        env->pregs[SR_CCS] = T0;
278
        RETURN();
279
}
280

    
281
void OPPROTO op_movl_sreg_T0 (void)
282
{
283
        env->sregs[env->pregs[SR_SRS]][PARAM1] = T0;
284
        RETURN();
285
}
286

    
287
void OPPROTO op_movl_tlb_lo_T0 (void)
288
{
289
        int srs;
290
        srs = env->pregs[SR_SRS];
291
        if (srs == 1 || srs == 2)
292
        {
293
                int set;
294
                int idx;
295
                uint32_t lo, hi;
296

    
297
                idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
298
                set >>= 4;
299
                set &= 3;
300

    
301
                idx &= 31;
302
                /* We've just made a write to tlb_lo.  */
303
                lo = env->sregs[SFR_RW_MM_TLB_LO];
304
                hi = env->sregs[SFR_RW_MM_TLB_HI];
305
                env->tlbsets[srs - 1][set][idx].lo = lo;
306
                env->tlbsets[srs - 1][set][idx].hi = hi;
307
        }
308

    
309
        RETURN();
310
}
311

    
312
void OPPROTO op_movl_T0_sreg (void)
313
{
314
        T0 = env->sregs[env->pregs[SR_SRS]][PARAM1];
315
        RETURN();
316
}
317

    
318
void OPPROTO op_update_cc (void)
319
{
320
        env->cc_op = PARAM1;
321
        env->cc_dest = PARAM2;
322
        env->cc_src = PARAM3;
323
        RETURN();
324
}
325

    
326
void OPPROTO op_update_cc_op (void)
327
{
328
        env->cc_op = PARAM1;
329
        RETURN();
330
}
331

    
332
void OPPROTO op_update_cc_mask (void)
333
{
334
        env->cc_mask = PARAM1;
335
        RETURN();
336
}
337

    
338
void OPPROTO op_update_cc_dest_T0 (void)
339
{
340
        env->cc_dest = T0;
341
        RETURN();
342
}
343

    
344
void OPPROTO op_update_cc_result_T0 (void)
345
{
346
        env->cc_result = T0;
347
        RETURN();
348
}
349

    
350
void OPPROTO op_update_cc_size_im (void)
351
{
352
        env->cc_size = PARAM1;
353
        RETURN();
354
}
355

    
356
void OPPROTO op_update_cc_src_T1 (void)
357
{
358
        env->cc_src = T1;
359
        RETURN();
360
}
361
void OPPROTO op_update_cc_x (void)
362
{
363
        env->cc_x_live = PARAM1;
364
        env->cc_x = PARAM2;
365
        RETURN();
366
}
367

    
368
/* FIXME: is this allowed?  */
369
extern inline void evaluate_flags_writeback(uint32_t flags)
370
{
371
        int x;
372

    
373
        /* Extended arithmetics, leave the z flag alone.  */
374
        env->debug3 = env->pregs[SR_CCS];
375

    
376
        if (env->cc_x_live)
377
                x = env->cc_x;
378
        else
379
                x = env->pregs[SR_CCS] & X_FLAG;
380

    
381
        if ((x || env->cc_op == CC_OP_ADDC)
382
            && flags & Z_FLAG)
383
                env->cc_mask &= ~Z_FLAG;
384

    
385
        /* all insn clear the x-flag except setf or clrf.  */
386
        env->pregs[SR_CCS] &= ~(env->cc_mask | X_FLAG);
387
        flags &= env->cc_mask;
388
        env->pregs[SR_CCS] |= flags;
389
        RETURN();
390
}
391

    
392
void OPPROTO op_evaluate_flags_muls(void)
393
{
394
        uint32_t src;
395
        uint32_t dst;
396
        uint32_t res;
397
        uint32_t flags = 0;
398
        /* were gonna have to redo the muls.  */
399
        int64_t tmp, t0 ,t1;
400
        int32_t mof;
401
        int dneg;
402

    
403
        src = env->cc_src;
404
        dst = env->cc_dest;
405
        res = env->cc_result;
406

    
407

    
408
        /* cast into signed values to make GCC sign extend.  */
409
        t0 = (int32_t)src;
410
        t1 = (int32_t)dst;
411
        dneg = ((int32_t)res) < 0;
412

    
413
        tmp = t0 * t1;
414
        mof = tmp >> 32;
415
        if (tmp == 0)
416
                flags |= Z_FLAG;
417
        else if (tmp < 0)
418
                flags |= N_FLAG;
419
        if ((dneg && mof != -1)
420
            || (!dneg && mof != 0))
421
                flags |= V_FLAG;
422
        evaluate_flags_writeback(flags);
423
        RETURN();
424
}
425

    
426
void OPPROTO op_evaluate_flags_mulu(void)
427
{
428
        uint32_t src;
429
        uint32_t dst;
430
        uint32_t res;
431
        uint32_t flags = 0;
432
        /* were gonna have to redo the muls.  */
433
        uint64_t tmp, t0 ,t1;
434
        uint32_t mof;
435

    
436
        src = env->cc_src;
437
        dst = env->cc_dest;
438
        res = env->cc_result;
439

    
440

    
441
        /* cast into signed values to make GCC sign extend.  */
442
        t0 = src;
443
        t1 = dst;
444

    
445
        tmp = t0 * t1;
446
        mof = tmp >> 32;
447
        if (tmp == 0)
448
                flags |= Z_FLAG;
449
        else if (tmp >> 63)
450
                flags |= N_FLAG;
451
        if (mof)
452
                flags |= V_FLAG;
453

    
454
        evaluate_flags_writeback(flags);
455
        RETURN();
456
}
457

    
458
void OPPROTO op_evaluate_flags_mcp(void)
459
{
460
        uint32_t src;
461
        uint32_t dst;
462
        uint32_t res;
463
        uint32_t flags = 0;
464

    
465
        src = env->cc_src;
466
        dst = env->cc_dest;
467
        res = env->cc_result;
468

    
469
        if ((res & 0x80000000L) != 0L)
470
        {
471
                flags |= N_FLAG;
472
                if (((src & 0x80000000L) == 0L)
473
                    && ((dst & 0x80000000L) == 0L))
474
                {
475
                        flags |= V_FLAG;
476
                }
477
                else if (((src & 0x80000000L) != 0L) &&
478
                         ((dst & 0x80000000L) != 0L))
479
                {
480
                        flags |= R_FLAG;
481
                }
482
        }
483
        else
484
        {
485
                if (res == 0L)
486
                        flags |= Z_FLAG;
487
                if (((src & 0x80000000L) != 0L)
488
                    && ((dst & 0x80000000L) != 0L))
489
                        flags |= V_FLAG;
490
                if ((dst & 0x80000000L) != 0L
491
                    || (src & 0x80000000L) != 0L)
492
                        flags |= R_FLAG;
493
        }
494

    
495
        evaluate_flags_writeback(flags);
496
        RETURN();
497
}
498

    
499
void OPPROTO op_evaluate_flags_alu_4(void)
500
{
501
        uint32_t src;
502
        uint32_t dst;
503
        uint32_t res;
504
        uint32_t flags = 0;
505

    
506
        src = env->cc_src;
507
        dst = env->cc_dest;
508
        res = env->cc_result;
509

    
510
        if ((res & 0x80000000L) != 0L)
511
        {
512
                flags |= N_FLAG;
513
                if (((src & 0x80000000L) == 0L)
514
                    && ((dst & 0x80000000L) == 0L))
515
                {
516
                        flags |= V_FLAG;
517
                }
518
                else if (((src & 0x80000000L) != 0L) &&
519
                         ((dst & 0x80000000L) != 0L))
520
                {
521
                        flags |= C_FLAG;
522
                }
523
        }
524
        else
525
        {
526
                if (res == 0L)
527
                        flags |= Z_FLAG;
528
                if (((src & 0x80000000L) != 0L)
529
                    && ((dst & 0x80000000L) != 0L))
530
                        flags |= V_FLAG;
531
                if ((dst & 0x80000000L) != 0L
532
                    || (src & 0x80000000L) != 0L)
533
                        flags |= C_FLAG;
534
        }
535

    
536
        if (env->cc_op == CC_OP_SUB
537
            || env->cc_op == CC_OP_CMP) {
538
                flags ^= C_FLAG;
539
        }
540
        evaluate_flags_writeback(flags);
541
        RETURN();
542
}
543

    
544
void OPPROTO op_evaluate_flags_move_4 (void)
545
{
546
        uint32_t src;
547
        uint32_t res;
548
        uint32_t flags = 0;
549

    
550
        src = env->cc_src;
551
        res = env->cc_result;
552

    
553
        if ((int32_t)res < 0)
554
                flags |= N_FLAG;
555
        else if (res == 0L)
556
                flags |= Z_FLAG;
557

    
558
        evaluate_flags_writeback(flags);
559
        RETURN();
560
}
561
void OPPROTO op_evaluate_flags_move_2 (void)
562
{
563
        uint32_t src;
564
        uint32_t flags = 0;
565
        uint16_t res;
566

    
567
        src = env->cc_src;
568
        res = env->cc_result;
569

    
570
        if ((int16_t)res < 0L)
571
                flags |= N_FLAG;
572
        else if (res == 0)
573
                flags |= Z_FLAG;
574

    
575
        evaluate_flags_writeback(flags);
576
        RETURN();
577
}
578

    
579
/* TODO: This is expensive. We could split things up and only evaluate part of
580
   CCR on a need to know basis. For now, we simply re-evaluate everything.  */
581
void OPPROTO op_evaluate_flags (void)
582
{
583
        uint32_t src;
584
        uint32_t dst;
585
        uint32_t res;
586
        uint32_t flags = 0;
587

    
588
        src = env->cc_src;
589
        dst = env->cc_dest;
590
        res = env->cc_result;
591

    
592

    
593
        /* Now, evaluate the flags. This stuff is based on
594
           Per Zander's CRISv10 simulator.  */
595
        switch (env->cc_size)
596
        {
597
                case 1:
598
                        if ((res & 0x80L) != 0L)
599
                        {
600
                                flags |= N_FLAG;
601
                                if (((src & 0x80L) == 0L)
602
                                    && ((dst & 0x80L) == 0L))
603
                                {
604
                                        flags |= V_FLAG;
605
                                }
606
                                else if (((src & 0x80L) != 0L)
607
                                         && ((dst & 0x80L) != 0L))
608
                                {
609
                                        flags |= C_FLAG;
610
                                }
611
                        }
612
                        else
613
                        {
614
                                if ((res & 0xFFL) == 0L)
615
                                {
616
                                        flags |= Z_FLAG;
617
                                }
618
                                if (((src & 0x80L) != 0L)
619
                                    && ((dst & 0x80L) != 0L))
620
                                {
621
                                        flags |= V_FLAG;
622
                                }
623
                                if ((dst & 0x80L) != 0L
624
                                    || (src & 0x80L) != 0L)
625
                                {
626
                                        flags |= C_FLAG;
627
                                }
628
                        }
629
                        break;
630
                case 2:
631
                        if ((res & 0x8000L) != 0L)
632
                        {
633
                                flags |= N_FLAG;
634
                                if (((src & 0x8000L) == 0L)
635
                                    && ((dst & 0x8000L) == 0L))
636
                                {
637
                                        flags |= V_FLAG;
638
                                }
639
                                else if (((src & 0x8000L) != 0L)
640
                                         && ((dst & 0x8000L) != 0L))
641
                                {
642
                                        flags |= C_FLAG;
643
                                }
644
                        }
645
                        else
646
                        {
647
                                if ((res & 0xFFFFL) == 0L)
648
                                {
649
                                        flags |= Z_FLAG;
650
                                }
651
                                if (((src & 0x8000L) != 0L)
652
                                    && ((dst & 0x8000L) != 0L))
653
                                {
654
                                        flags |= V_FLAG;
655
                                }
656
                                if ((dst & 0x8000L) != 0L
657
                                    || (src & 0x8000L) != 0L)
658
                                {
659
                                        flags |= C_FLAG;
660
                                }
661
                        }
662
                        break;
663
                case 4:
664
                        if ((res & 0x80000000L) != 0L)
665
                        {
666
                                flags |= N_FLAG;
667
                                if (((src & 0x80000000L) == 0L)
668
                                    && ((dst & 0x80000000L) == 0L))
669
                                {
670
                                        flags |= V_FLAG;
671
                                }
672
                                else if (((src & 0x80000000L) != 0L) &&
673
                                         ((dst & 0x80000000L) != 0L))
674
                                {
675
                                        flags |= C_FLAG;
676
                                }
677
                        }
678
                        else
679
                        {
680
                                if (res == 0L)
681
                                        flags |= Z_FLAG;
682
                                if (((src & 0x80000000L) != 0L)
683
                                    && ((dst & 0x80000000L) != 0L))
684
                                        flags |= V_FLAG;
685
                                if ((dst & 0x80000000L) != 0L
686
                                    || (src & 0x80000000L) != 0L)
687
                                        flags |= C_FLAG;
688
                        }
689
                        break;
690
                default:
691
                        break;
692
        }
693

    
694
        if (env->cc_op == CC_OP_SUB
695
            || env->cc_op == CC_OP_CMP) {
696
                flags ^= C_FLAG;
697
        }
698
        evaluate_flags_writeback(flags);
699
        RETURN();
700
}
701

    
702
void OPPROTO op_extb_T0_T0 (void)
703
{
704
        T0 = ((int8_t)T0);
705
        RETURN();
706
}
707
void OPPROTO op_extb_T1_T0 (void)
708
{
709
        T1 = ((int8_t)T0);
710
        RETURN();
711
}
712
void OPPROTO op_extb_T1_T1 (void)
713
{
714
        T1 = ((int8_t)T1);
715
        RETURN();
716
}
717
void OPPROTO op_zextb_T0_T0 (void)
718
{
719
        T0 = ((uint8_t)T0);
720
        RETURN();
721
}
722
void OPPROTO op_zextb_T1_T0 (void)
723
{
724
        T1 = ((uint8_t)T0);
725
        RETURN();
726
}
727
void OPPROTO op_zextb_T1_T1 (void)
728
{
729
        T1 = ((uint8_t)T1);
730
        RETURN();
731
}
732
void OPPROTO op_extw_T0_T0 (void)
733
{
734
        T0 = ((int16_t)T0);
735
        RETURN();
736
}
737
void OPPROTO op_extw_T1_T0 (void)
738
{
739
        T1 = ((int16_t)T0);
740
        RETURN();
741
}
742
void OPPROTO op_extw_T1_T1 (void)
743
{
744
        T1 = ((int16_t)T1);
745
        RETURN();
746
}
747

    
748
void OPPROTO op_zextw_T0_T0 (void)
749
{
750
        T0 = ((uint16_t)T0);
751
        RETURN();
752
}
753
void OPPROTO op_zextw_T1_T0 (void)
754
{
755
        T1 = ((uint16_t)T0);
756
        RETURN();
757
}
758

    
759
void OPPROTO op_zextw_T1_T1 (void)
760
{
761
        T1 = ((uint16_t)T1);
762
        RETURN();
763
}
764

    
765
void OPPROTO op_movl_T0_im (void)
766
{
767
        T0 = PARAM1;
768
        RETURN();
769
}
770
void OPPROTO op_movl_T1_im (void)
771
{
772
        T1 = PARAM1;
773
        RETURN();
774
}
775

    
776
void OPPROTO op_addl_T0_im (void)
777
{
778
        T0 += PARAM1;
779
        RETURN();
780
}
781

    
782
void OPPROTO op_addl_T1_im (void)
783
{
784
        T1 += PARAM1;
785
        RETURN();
786

    
787
}
788
void OPPROTO op_subl_T0_im (void)
789
{
790
        T0 -= PARAM1;
791
        RETURN();
792
}
793

    
794
void OPPROTO op_addxl_T0_C (void)
795
{
796
        if (env->pregs[SR_CCS] & X_FLAG)
797
                T0 += !!(env->pregs[SR_CCS] & C_FLAG);
798
        RETURN();
799
}
800
void OPPROTO op_subxl_T0_C (void)
801
{
802
        if (env->pregs[SR_CCS] & X_FLAG)
803
                T0 -= !!(env->pregs[SR_CCS] & C_FLAG);
804
        RETURN();
805
}
806
void OPPROTO op_addl_T0_C (void)
807
{
808
        T0 += !!(env->pregs[SR_CCS] & C_FLAG);
809
        RETURN();
810
}
811
void OPPROTO op_addl_T0_R (void)
812
{
813
        T0 += !!(env->pregs[SR_CCS] & R_FLAG);
814
        RETURN();
815
}
816

    
817
void OPPROTO op_clr_R (void)
818
{
819
        env->pregs[SR_CCS] &= ~R_FLAG;
820
        RETURN();
821
}
822

    
823

    
824
void OPPROTO op_andl_T0_im (void)
825
{
826
        T0 &= PARAM1;
827
        RETURN();
828
}
829

    
830
void OPPROTO op_andl_T1_im (void)
831
{
832
        T1 &= PARAM1;
833
        RETURN();
834
}
835

    
836
void OPPROTO op_movl_T0_T1 (void)
837
{
838
        T0 = T1;
839
        RETURN();
840
}
841

    
842
void OPPROTO op_swp_T0_T1 (void)
843
{
844
        T0 ^= T1;
845
        T1 ^= T0;
846
        T0 ^= T1;
847
        RETURN();
848
}
849

    
850
void OPPROTO op_movl_T1_T0 (void)
851
{
852
        T1 = T0;
853
        RETURN();
854
}
855

    
856
void OPPROTO op_movl_pc_T0 (void)
857
{
858
        env->pc = T0;
859
        RETURN();
860
}
861

    
862
void OPPROTO op_movl_T0_0 (void)
863
{
864
        T0 = 0;
865
        RETURN();
866
}
867

    
868
void OPPROTO op_addl_T0_T1 (void)
869
{
870
        T0 += T1;
871
        RETURN();
872
}
873

    
874
void OPPROTO op_subl_T0_T1 (void)
875
{
876
        T0 -= T1;
877
        RETURN();
878
}
879

    
880
void OPPROTO op_absl_T1_T1 (void)
881
{
882
        int32_t st = T1;
883

    
884
        T1 = st < 0 ? -st : st;
885
        RETURN();
886
}
887

    
888
void OPPROTO op_muls_T0_T1 (void)
889
{
890
        int64_t tmp, t0 ,t1;
891

    
892
        /* cast into signed values to make GCC sign extend these babies.  */
893
        t0 = (int32_t)T0;
894
        t1 = (int32_t)T1;
895

    
896
        tmp = t0 * t1;
897
        T0 = tmp & 0xffffffff;
898
        env->pregs[REG_MOF] = tmp >> 32;
899
        RETURN();
900
}
901

    
902
void OPPROTO op_mulu_T0_T1 (void)
903
{
904
        uint64_t tmp, t0 ,t1;
905
        t0 = T0;
906
        t1 = T1;
907

    
908
        tmp = t0 * t1;
909
        T0 = tmp & 0xffffffff;
910
        env->pregs[REG_MOF] = tmp >> 32;
911
        RETURN();
912
}
913

    
914
void OPPROTO op_dstep_T0_T1 (void)
915
{
916
        T0 <<= 1;
917
        if (T0 >= T1)
918
                T0 -= T1;
919
        RETURN();
920
}
921

    
922
void OPPROTO op_orl_T0_T1 (void)
923
{
924
        T0 |= T1;
925
        RETURN();
926
}
927

    
928
void OPPROTO op_andl_T0_T1 (void)
929
{
930
        T0 &= T1;
931
        RETURN();
932
}
933

    
934
void OPPROTO op_xorl_T0_T1 (void)
935
{
936
        T0 ^= T1;
937
        RETURN();
938
}
939

    
940
void OPPROTO op_lsll_T0_T1 (void)
941
{
942
        int s = T1;
943
        if (s > 31)
944
                T0 = 0;
945
        else
946
                T0 <<= s;
947
        RETURN();
948
}
949

    
950
void OPPROTO op_lsll_T0_im (void)
951
{
952
        T0 <<= PARAM1;
953
        RETURN();
954
}
955

    
956
void OPPROTO op_lsrl_T0_T1 (void)
957
{
958
        int s = T1;
959
        if (s > 31)
960
                T0 = 0;
961
        else
962
                T0 >>= s;
963
        RETURN();
964
}
965

    
966
/* Rely on GCC emitting an arithmetic shift for signed right shifts.  */
967
void OPPROTO op_asrl_T0_T1 (void)
968
{
969
        int s = T1;
970
        if (s > 31)
971
                T0 = T0 & 0x80000000 ? -1 : 0;
972
        else
973
                T0 = (int32_t)T0 >> s;
974
        RETURN();
975
}
976

    
977
void OPPROTO op_btst_T0_T1 (void)
978
{
979
        /* FIXME: clean this up.  */
980

    
981
        /* des ref:
982
           The N flag is set according to the selected bit in the dest reg.
983
           The Z flag is set if the selected bit and all bits to the right are
984
           zero.
985
           The destination reg is not affected.*/
986
        unsigned int fz, sbit, bset, mask, masked_t0;
987

    
988
        sbit = T1 & 31;
989
        bset = !!(T0 & (1 << sbit));
990
        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
991
        masked_t0 = T0 & mask;
992
        fz = !(masked_t0 | bset);
993
        /* Set the N and Z flags accordingly.  */
994
        T0 = (bset << 3) | (fz << 2);
995
        RETURN();
996
}
997

    
998
void OPPROTO op_bound_T0_T1 (void)
999
{
1000
        if (T0 > T1)
1001
                T0 = T1;
1002
        RETURN();
1003
}
1004

    
1005
void OPPROTO op_lz_T0_T1 (void)
1006
{
1007
        T0 = clz32(T1);
1008
        RETURN();
1009
}
1010

    
1011
void OPPROTO op_negl_T0_T1 (void)
1012
{
1013
        T0 = -T1;
1014
        RETURN();
1015
}
1016

    
1017
void OPPROTO op_negl_T1_T1 (void)
1018
{
1019
        T1 = -T1;
1020
        RETURN();
1021
}
1022

    
1023
void OPPROTO op_not_T0_T0 (void)
1024
{
1025
        T0 = ~(T0);
1026
        RETURN();
1027
}
1028
void OPPROTO op_not_T1_T1 (void)
1029
{
1030
        T1 = ~(T1);
1031
        RETURN();
1032
}
1033

    
1034
void OPPROTO op_swapw_T0_T0 (void)
1035
{
1036
        T0 = (T0 << 16) | ((T0 >> 16));
1037
        RETURN();
1038
}
1039

    
1040
void OPPROTO op_swapb_T0_T0 (void)
1041
{
1042
        T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
1043
        RETURN();
1044
}
1045

    
1046
void OPPROTO op_swapr_T0_T0 (void)
1047
{
1048
        T0 = (((T0 << 7) & 0x80808080) |
1049
              ((T0 << 5) & 0x40404040) |
1050
              ((T0 << 3) & 0x20202020) |
1051
              ((T0 << 1) & 0x10101010) |
1052
              ((T0 >> 1) & 0x08080808) |
1053
              ((T0 >> 3) & 0x04040404) |
1054
              ((T0 >> 5) & 0x02020202) |
1055
              ((T0 >> 7) & 0x01010101));
1056
        RETURN();
1057
}
1058

    
1059
void OPPROTO op_tst_cc_eq (void) {
1060
        uint32_t flags = env->pregs[SR_CCS];
1061
        int z_set;
1062

    
1063
        z_set = !!(flags & Z_FLAG);
1064
        T0 = z_set;
1065
        RETURN();
1066
}
1067

    
1068
void OPPROTO op_tst_cc_eq_fast (void) {
1069
        T0 = !(env->cc_result);
1070
        RETURN();
1071
}
1072

    
1073
void OPPROTO op_tst_cc_ne (void) {
1074
        uint32_t flags = env->pregs[SR_CCS];
1075
        int z_set;
1076

    
1077
        z_set = !!(flags & Z_FLAG);
1078
        T0 = !z_set;
1079
        RETURN();
1080
}
1081
void OPPROTO op_tst_cc_ne_fast (void) {
1082
        T0 = !!(env->cc_result);
1083
        RETURN();
1084
}
1085

    
1086
void OPPROTO op_tst_cc_cc (void) {
1087
        uint32_t flags = env->pregs[SR_CCS];
1088
        int c_set;
1089

    
1090
        c_set = !!(flags & C_FLAG);
1091
        T0 = !c_set;
1092
        RETURN();
1093
}
1094
void OPPROTO op_tst_cc_cs (void) {
1095
        uint32_t flags = env->pregs[SR_CCS];
1096
        int c_set;
1097

    
1098
        c_set = !!(flags & C_FLAG);
1099
        T0 = c_set;
1100
        RETURN();
1101
}
1102

    
1103
void OPPROTO op_tst_cc_vc (void) {
1104
        uint32_t flags = env->pregs[SR_CCS];
1105
        int v_set;
1106

    
1107
        v_set = !!(flags & V_FLAG);
1108
        T0 = !v_set;
1109
        RETURN();
1110
}
1111
void OPPROTO op_tst_cc_vs (void) {
1112
        uint32_t flags = env->pregs[SR_CCS];
1113
        int v_set;
1114

    
1115
        v_set = !!(flags & V_FLAG);
1116
        T0 = v_set;
1117
        RETURN();
1118
}
1119
void OPPROTO op_tst_cc_pl (void) {
1120
        uint32_t flags = env->pregs[SR_CCS];
1121
        int n_set;
1122

    
1123
        n_set = !!(flags & N_FLAG);
1124
        T0 = !n_set;
1125
        RETURN();
1126
}
1127
void OPPROTO op_tst_cc_pl_fast (void) {
1128
        T0 = ((int32_t)env->cc_result) >= 0;
1129
        RETURN();
1130
}
1131

    
1132
void OPPROTO op_tst_cc_mi (void) {
1133
        uint32_t flags = env->pregs[SR_CCS];
1134
        int n_set;
1135

    
1136
        n_set = !!(flags & N_FLAG);
1137
        T0 = n_set;
1138
        RETURN();
1139
}
1140
void OPPROTO op_tst_cc_mi_fast (void) {
1141
        T0 = ((int32_t)env->cc_result) < 0;
1142
        RETURN();
1143
}
1144

    
1145
void OPPROTO op_tst_cc_ls (void) {
1146
        uint32_t flags = env->pregs[SR_CCS];
1147
        int c_set;
1148
        int z_set;
1149

    
1150
        c_set = !!(flags & C_FLAG);
1151
        z_set = !!(flags & Z_FLAG);
1152
        T0 = c_set || z_set;
1153
        RETURN();
1154
}
1155
void OPPROTO op_tst_cc_hi (void) {
1156
        uint32_t flags = env->pregs[SR_CCS];
1157
        int z_set;
1158
        int c_set;
1159

    
1160
        z_set = !!(flags & Z_FLAG);
1161
        c_set = !!(flags & C_FLAG);
1162
        T0 = !c_set && !z_set;
1163
        RETURN();
1164

    
1165
}
1166

    
1167
void OPPROTO op_tst_cc_ge (void) {
1168
        uint32_t flags = env->pregs[SR_CCS];
1169
        int n_set;
1170
        int v_set;
1171

    
1172
        n_set = !!(flags & N_FLAG);
1173
        v_set = !!(flags & V_FLAG);
1174
        T0 = (n_set && v_set) || (!n_set && !v_set);
1175
        RETURN();
1176
}
1177

    
1178
void OPPROTO op_tst_cc_ge_fast (void) {
1179
        T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
1180
        RETURN();
1181
}
1182

    
1183
void OPPROTO op_tst_cc_lt (void) {
1184
        uint32_t flags = env->pregs[SR_CCS];
1185
        int n_set;
1186
        int v_set;
1187

    
1188
        n_set = !!(flags & N_FLAG);
1189
        v_set = !!(flags & V_FLAG);
1190
        T0 = (n_set && !v_set) || (!n_set && v_set);
1191
        RETURN();
1192
}
1193

    
1194
void OPPROTO op_tst_cc_gt (void) {
1195
        uint32_t flags = env->pregs[SR_CCS];
1196
        int n_set;
1197
        int v_set;
1198
        int z_set;
1199

    
1200
        n_set = !!(flags & N_FLAG);
1201
        v_set = !!(flags & V_FLAG);
1202
        z_set = !!(flags & Z_FLAG);
1203
        T0 = (n_set && v_set && !z_set)
1204
                || (!n_set && !v_set && !z_set);
1205
        RETURN();
1206
}
1207

    
1208
void OPPROTO op_tst_cc_le (void) {
1209
        uint32_t flags = env->pregs[SR_CCS];
1210
        int n_set;
1211
        int v_set;
1212
        int z_set;
1213

    
1214
        n_set = !!(flags & N_FLAG);
1215
        v_set = !!(flags & V_FLAG);
1216
        z_set = !!(flags & Z_FLAG);
1217
        T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
1218
        RETURN();
1219
}
1220

    
1221
void OPPROTO op_tst_cc_p (void) {
1222
        uint32_t flags = env->pregs[SR_CCS];
1223
        int p_set;
1224

    
1225
        p_set = !!(flags & P_FLAG);
1226
        T0 = p_set;
1227
        RETURN();
1228
}
1229

    
1230
/* Evaluate the if the branch should be taken or not. Needs to be done in
1231
   the original sequence. The acutal branch is rescheduled to right after the
1232
   delay-slot.  */
1233
void OPPROTO op_evaluate_bcc (void)
1234
{
1235
        env->btaken = T0;
1236
        RETURN();
1237
}
1238

    
1239
/* this one is used on every alu op, optimize it!.  */
1240
void OPPROTO op_goto_if_not_x (void)
1241
{
1242
        if (env->pregs[SR_CCS] & X_FLAG)
1243
                GOTO_LABEL_PARAM(1);
1244
        RETURN();
1245
}
1246

    
1247
void OPPROTO op_cc_jmp (void)
1248
{
1249
        if (env->btaken)
1250
                env->pc = PARAM1;
1251
        else
1252
                env->pc = PARAM2;
1253
        RETURN();
1254
}
1255

    
1256
void OPPROTO op_cc_ngoto (void)
1257
{
1258
        if (!env->btaken)
1259
                GOTO_LABEL_PARAM(1);
1260
        RETURN();
1261
}
1262

    
1263
void OPPROTO op_movl_btarget_T0 (void)
1264
{
1265
        env->btarget = T0;
1266
        RETURN();
1267
}
1268

    
1269
void OPPROTO op_jmp (void)
1270
{
1271
        env->pc = env->btarget;
1272
        RETURN();
1273
}
1274

    
1275
/* Load and store */
1276
#define MEMSUFFIX _raw
1277
#include "op_mem.c"
1278
#undef MEMSUFFIX
1279
#if !defined(CONFIG_USER_ONLY)
1280
#define MEMSUFFIX _user
1281
#include "op_mem.c"
1282
#undef MEMSUFFIX
1283

    
1284
#define MEMSUFFIX _kernel
1285
#include "op_mem.c"
1286
#undef MEMSUFFIX
1287
#endif