Statistics
| Branch: | Revision:

root / target-cris / op.c @ 94cff60a

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
86

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
151
/* Microcode.  */
152

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
308
        RETURN();
309
}
310

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
406

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

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

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

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

    
439

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
591

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

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

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

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

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

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

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

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

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

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

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

    
822

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1004
void OPPROTO op_lz_T0_T1 (void)
1005
{
1006
        if (T1 == 0)
1007
                T0 = 32;
1008
        else
1009
                T0 = __builtin_clz(T1);
1010
        RETURN();
1011
}
1012

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1167
}
1168

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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