Statistics
| Branch: | Revision:

root / target-cris / op.c @ 786c02f1

History | View | Annotate | Download (21.3 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_break_im(void)
155
{
156
        env->trap_vector = PARAM1;
157
        env->exception_index = EXCP_BREAK;
158
        cpu_loop_exit();
159
}
160

    
161
void OPPROTO op_debug(void)
162
{
163
        env->exception_index = EXCP_DEBUG;
164
        cpu_loop_exit();
165
}
166

    
167
void OPPROTO op_exec_insn(void)
168
{
169
        env->stats.exec_insns++;
170
        RETURN();
171
}
172
void OPPROTO op_exec_load(void)
173
{
174
        env->stats.exec_loads++;
175
        RETURN();
176
}
177
void OPPROTO op_exec_store(void)
178
{
179
        env->stats.exec_stores++;
180
        RETURN();
181
}
182

    
183
void OPPROTO op_ccs_lshift (void)
184
{
185
        uint32_t ccs;
186

    
187
        /* Apply the ccs shift.  */
188
        ccs = env->pregs[PR_CCS];
189
        ccs = (ccs & 0xc0000000) | ((ccs << 12) >> 2);
190
        env->pregs[PR_CCS] = ccs;
191
        RETURN();
192
}
193
void OPPROTO op_ccs_rshift (void)
194
{
195
        uint32_t ccs;
196

    
197
        /* Apply the ccs shift.  */
198
        ccs = env->pregs[PR_CCS];
199
        ccs = (ccs & 0xc0000000) | ((ccs & 0x0fffffff) >> 10);
200
        env->pregs[PR_CCS] = ccs;
201
        RETURN();
202
}
203

    
204
void OPPROTO op_setf (void)
205
{
206
        env->pregs[PR_CCS] |= PARAM1;
207
        RETURN();
208
}
209

    
210
void OPPROTO op_clrf (void)
211
{
212
        env->pregs[PR_CCS] &= ~PARAM1;
213
        RETURN();
214
}
215

    
216
void OPPROTO op_movl_debug1_T0 (void)
217
{
218
        env->debug1 = T0;
219
        RETURN();
220
}
221

    
222
void OPPROTO op_movl_debug2_T0 (void)
223
{
224
        env->debug2 = T0;
225
        RETURN();
226
}
227

    
228
void OPPROTO op_movl_debug3_T0 (void)
229
{
230
        env->debug3 = T0;
231
        RETURN();
232
}
233
void OPPROTO op_movl_debug1_T1 (void)
234
{
235
        env->debug1 = T1;
236
        RETURN();
237
}
238

    
239
void OPPROTO op_movl_debug2_T1 (void)
240
{
241
        env->debug2 = T1;
242
        RETURN();
243
}
244

    
245
void OPPROTO op_movl_debug3_T1 (void)
246
{
247
        env->debug3 = T1;
248
        RETURN();
249
}
250
void OPPROTO op_movl_debug3_im (void)
251
{
252
        env->debug3 = PARAM1;
253
        RETURN();
254
}
255
void OPPROTO op_movl_T0_flags (void)
256
{
257
        T0 = env->pregs[PR_CCS];
258
        RETURN();
259
}
260
void OPPROTO op_movl_flags_T0 (void)
261
{
262
        env->pregs[PR_CCS] = T0;
263
        RETURN();
264
}
265

    
266
void OPPROTO op_movl_sreg_T0 (void)
267
{
268
        env->sregs[env->pregs[PR_SRS]][PARAM1] = T0;
269
        RETURN();
270
}
271

    
272
void OPPROTO op_movl_tlb_hi_T0 (void)
273
{
274
        uint32_t srs;
275
        srs = env->pregs[PR_SRS];
276
        if (srs == 1 || srs == 2)
277
        {
278
                /* Writes to tlb-hi write to mm_cause as a side effect.  */
279
                env->sregs[SFR_RW_MM_TLB_HI] = T0;
280
                env->sregs[SFR_R_MM_CAUSE] = T0;
281
        }
282
        RETURN();
283
}
284

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

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

    
299
                idx &= 15;
300
                /* We've just made a write to tlb_lo.  */
301
                lo = env->sregs[SFR_RW_MM_TLB_LO];
302
                /* Writes are done via r_mm_cause.  */
303
                hi = env->sregs[SFR_R_MM_CAUSE];
304
                env->tlbsets[srs - 1][set][idx].lo = lo;
305
                env->tlbsets[srs - 1][set][idx].hi = hi;
306
        }
307
        RETURN();
308
}
309

    
310
void OPPROTO op_movl_T0_sreg (void)
311
{
312
        T0 = env->sregs[env->pregs[PR_SRS]][PARAM1];
313
        RETURN();
314
}
315

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

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

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

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

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

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

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

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

    
371
        /* Extended arithmetics, leave the z flag alone.  */
372
        env->debug3 = env->pregs[PR_CCS];
373

    
374
        if (env->cc_x_live)
375
                x = env->cc_x;
376
        else
377
                x = env->pregs[PR_CCS] & X_FLAG;
378

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

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

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

    
401
        src = env->cc_src;
402
        dst = env->cc_dest;
403
        res = env->cc_result;
404

    
405

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

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

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

    
434
        src = env->cc_src;
435
        dst = env->cc_dest;
436
        res = env->cc_result;
437

    
438

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

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

    
452
        evaluate_flags_writeback(flags);
453
        RETURN();
454
}
455

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

    
463
        src = env->cc_src;
464
        dst = env->cc_dest;
465
        res = env->cc_result;
466

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

    
493
        evaluate_flags_writeback(flags);
494
        RETURN();
495
}
496

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

    
504
        src = env->cc_src;
505
        dst = env->cc_dest;
506
        res = env->cc_result;
507

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

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

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

    
548
        src = env->cc_src;
549
        res = env->cc_result;
550

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

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

    
565
        src = env->cc_src;
566
        res = env->cc_result;
567

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

    
573
        evaluate_flags_writeback(flags);
574
        RETURN();
575
}
576

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

    
586
        src = env->cc_src;
587
        dst = env->cc_dest;
588
        res = env->cc_result;
589

    
590

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

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

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

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

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

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

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

    
780
void OPPROTO op_addl_T1_im (void)
781
{
782
        T1 += PARAM1;
783
        RETURN();
784

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

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

    
815
void OPPROTO op_clr_R (void)
816
{
817
        env->pregs[PR_CCS] &= ~R_FLAG;
818
        RETURN();
819
}
820

    
821

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

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

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

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

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

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

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

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

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

    
878
void OPPROTO op_absl_T1_T1 (void)
879
{
880
        int32_t st = T1;
881

    
882
        T1 = st < 0 ? -st : st;
883
        RETURN();
884
}
885

    
886
void OPPROTO op_muls_T0_T1 (void)
887
{
888
        int64_t tmp, t0 ,t1;
889

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

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

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

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

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

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

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

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

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

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

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

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

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

    
979
        /* des ref:
980
           The N flag is set according to the selected bit in the dest reg.
981
           The Z flag is set if the selected bit and all bits to the right are
982
           zero.
983
           The X flag is cleared.
984
           Other flags are left untouched.
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

    
994
        /* Clear the X, N and Z flags.  */
995
        T0 = env->pregs[PR_CCS] & ~(X_FLAG | N_FLAG | Z_FLAG);
996
        /* Set the N and Z flags accordingly.  */
997
        T0 |= (bset << 3) | (fz << 2);
998
        RETURN();
999
}
1000

    
1001
void OPPROTO op_bound_T0_T1 (void)
1002
{
1003
        if (T0 > T1)
1004
                T0 = T1;
1005
        RETURN();
1006
}
1007

    
1008
void OPPROTO op_lz_T0_T1 (void)
1009
{
1010
        T0 = clz32(T1);
1011
        RETURN();
1012
}
1013

    
1014
void OPPROTO op_negl_T0_T1 (void)
1015
{
1016
        T0 = -T1;
1017
        RETURN();
1018
}
1019

    
1020
void OPPROTO op_negl_T1_T1 (void)
1021
{
1022
        T1 = -T1;
1023
        RETURN();
1024
}
1025

    
1026
void OPPROTO op_not_T0_T0 (void)
1027
{
1028
        T0 = ~(T0);
1029
        RETURN();
1030
}
1031
void OPPROTO op_not_T1_T1 (void)
1032
{
1033
        T1 = ~(T1);
1034
        RETURN();
1035
}
1036

    
1037
void OPPROTO op_swapw_T0_T0 (void)
1038
{
1039
        T0 = (T0 << 16) | ((T0 >> 16));
1040
        RETURN();
1041
}
1042

    
1043
void OPPROTO op_swapb_T0_T0 (void)
1044
{
1045
        T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
1046
        RETURN();
1047
}
1048

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

    
1062
void OPPROTO op_tst_cc_eq (void) {
1063
        uint32_t flags = env->pregs[PR_CCS];
1064
        int z_set;
1065

    
1066
        z_set = !!(flags & Z_FLAG);
1067
        T0 = z_set;
1068
        RETURN();
1069
}
1070

    
1071
void OPPROTO op_tst_cc_eq_fast (void) {
1072
        T0 = !(env->cc_result);
1073
        RETURN();
1074
}
1075

    
1076
void OPPROTO op_tst_cc_ne (void) {
1077
        uint32_t flags = env->pregs[PR_CCS];
1078
        int z_set;
1079

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

    
1089
void OPPROTO op_tst_cc_cc (void) {
1090
        uint32_t flags = env->pregs[PR_CCS];
1091
        int c_set;
1092

    
1093
        c_set = !!(flags & C_FLAG);
1094
        T0 = !c_set;
1095
        RETURN();
1096
}
1097
void OPPROTO op_tst_cc_cs (void) {
1098
        uint32_t flags = env->pregs[PR_CCS];
1099
        int c_set;
1100

    
1101
        c_set = !!(flags & C_FLAG);
1102
        T0 = c_set;
1103
        RETURN();
1104
}
1105

    
1106
void OPPROTO op_tst_cc_vc (void) {
1107
        uint32_t flags = env->pregs[PR_CCS];
1108
        int v_set;
1109

    
1110
        v_set = !!(flags & V_FLAG);
1111
        T0 = !v_set;
1112
        RETURN();
1113
}
1114
void OPPROTO op_tst_cc_vs (void) {
1115
        uint32_t flags = env->pregs[PR_CCS];
1116
        int v_set;
1117

    
1118
        v_set = !!(flags & V_FLAG);
1119
        T0 = v_set;
1120
        RETURN();
1121
}
1122
void OPPROTO op_tst_cc_pl (void) {
1123
        uint32_t flags = env->pregs[PR_CCS];
1124
        int n_set;
1125

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

    
1135
void OPPROTO op_tst_cc_mi (void) {
1136
        uint32_t flags = env->pregs[PR_CCS];
1137
        int n_set;
1138

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

    
1148
void OPPROTO op_tst_cc_ls (void) {
1149
        uint32_t flags = env->pregs[PR_CCS];
1150
        int c_set;
1151
        int z_set;
1152

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

    
1163
        z_set = !!(flags & Z_FLAG);
1164
        c_set = !!(flags & C_FLAG);
1165
        T0 = !c_set && !z_set;
1166
        RETURN();
1167

    
1168
}
1169

    
1170
void OPPROTO op_tst_cc_ge (void) {
1171
        uint32_t flags = env->pregs[PR_CCS];
1172
        int n_set;
1173
        int v_set;
1174

    
1175
        n_set = !!(flags & N_FLAG);
1176
        v_set = !!(flags & V_FLAG);
1177
        T0 = (n_set && v_set) || (!n_set && !v_set);
1178
        RETURN();
1179
}
1180

    
1181
void OPPROTO op_tst_cc_ge_fast (void) {
1182
        T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
1183
        RETURN();
1184
}
1185

    
1186
void OPPROTO op_tst_cc_lt (void) {
1187
        uint32_t flags = env->pregs[PR_CCS];
1188
        int n_set;
1189
        int v_set;
1190

    
1191
        n_set = !!(flags & N_FLAG);
1192
        v_set = !!(flags & V_FLAG);
1193
        T0 = (n_set && !v_set) || (!n_set && v_set);
1194
        RETURN();
1195
}
1196

    
1197
void OPPROTO op_tst_cc_gt (void) {
1198
        uint32_t flags = env->pregs[PR_CCS];
1199
        int n_set;
1200
        int v_set;
1201
        int z_set;
1202

    
1203
        n_set = !!(flags & N_FLAG);
1204
        v_set = !!(flags & V_FLAG);
1205
        z_set = !!(flags & Z_FLAG);
1206
        T0 = (n_set && v_set && !z_set)
1207
                || (!n_set && !v_set && !z_set);
1208
        RETURN();
1209
}
1210

    
1211
void OPPROTO op_tst_cc_le (void) {
1212
        uint32_t flags = env->pregs[PR_CCS];
1213
        int n_set;
1214
        int v_set;
1215
        int z_set;
1216

    
1217
        n_set = !!(flags & N_FLAG);
1218
        v_set = !!(flags & V_FLAG);
1219
        z_set = !!(flags & Z_FLAG);
1220
        T0 = z_set || (n_set && !v_set) || (!n_set && v_set);
1221
        RETURN();
1222
}
1223

    
1224
void OPPROTO op_tst_cc_p (void) {
1225
        uint32_t flags = env->pregs[PR_CCS];
1226
        int p_set;
1227

    
1228
        p_set = !!(flags & P_FLAG);
1229
        T0 = p_set;
1230
        RETURN();
1231
}
1232

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

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

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

    
1259
void OPPROTO op_cc_ngoto (void)
1260
{
1261
        if (!env->btaken)
1262
                GOTO_LABEL_PARAM(1);
1263
        RETURN();
1264
}
1265

    
1266
void OPPROTO op_movl_btarget_T0 (void)
1267
{
1268
        env->btarget = T0;
1269
        RETURN();
1270
}
1271

    
1272
void OPPROTO op_jmp1 (void)
1273
{
1274
        env->pc = env->btarget;
1275
        RETURN();
1276
}
1277

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

    
1287
#define MEMSUFFIX _kernel
1288
#include "op_mem.c"
1289
#undef MEMSUFFIX
1290
#endif