Statistics
| Branch: | Revision:

root / target-cris / op.c @ 9004627f

History | View | Annotate | Download (20.8 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->trapnr = 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 >> 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_lo_T0 (void)
273
{
274
        int srs;
275
        srs = env->pregs[PR_SRS];
276
        if (srs == 1 || srs == 2)
277
        {
278
                int set;
279
                int idx;
280
                uint32_t lo, hi;
281

    
282
                idx = set = env->sregs[SFR_RW_MM_TLB_SEL];
283
                set >>= 4;
284
                set &= 3;
285

    
286
                idx &= 31;
287
                /* We've just made a write to tlb_lo.  */
288
                lo = env->sregs[SFR_RW_MM_TLB_LO];
289
                hi = env->sregs[SFR_RW_MM_TLB_HI];
290
                env->tlbsets[srs - 1][set][idx].lo = lo;
291
                env->tlbsets[srs - 1][set][idx].hi = hi;
292
        }
293

    
294
        RETURN();
295
}
296

    
297
void OPPROTO op_movl_T0_sreg (void)
298
{
299
        T0 = env->sregs[env->pregs[PR_SRS]][PARAM1];
300
        RETURN();
301
}
302

    
303
void OPPROTO op_update_cc (void)
304
{
305
        env->cc_op = PARAM1;
306
        env->cc_dest = PARAM2;
307
        env->cc_src = PARAM3;
308
        RETURN();
309
}
310

    
311
void OPPROTO op_update_cc_op (void)
312
{
313
        env->cc_op = PARAM1;
314
        RETURN();
315
}
316

    
317
void OPPROTO op_update_cc_mask (void)
318
{
319
        env->cc_mask = PARAM1;
320
        RETURN();
321
}
322

    
323
void OPPROTO op_update_cc_dest_T0 (void)
324
{
325
        env->cc_dest = T0;
326
        RETURN();
327
}
328

    
329
void OPPROTO op_update_cc_result_T0 (void)
330
{
331
        env->cc_result = T0;
332
        RETURN();
333
}
334

    
335
void OPPROTO op_update_cc_size_im (void)
336
{
337
        env->cc_size = PARAM1;
338
        RETURN();
339
}
340

    
341
void OPPROTO op_update_cc_src_T1 (void)
342
{
343
        env->cc_src = T1;
344
        RETURN();
345
}
346
void OPPROTO op_update_cc_x (void)
347
{
348
        env->cc_x_live = PARAM1;
349
        env->cc_x = PARAM2;
350
        RETURN();
351
}
352

    
353
/* FIXME: is this allowed?  */
354
extern inline void evaluate_flags_writeback(uint32_t flags)
355
{
356
        int x;
357

    
358
        /* Extended arithmetics, leave the z flag alone.  */
359
        env->debug3 = env->pregs[PR_CCS];
360

    
361
        if (env->cc_x_live)
362
                x = env->cc_x;
363
        else
364
                x = env->pregs[PR_CCS] & X_FLAG;
365

    
366
        if ((x || env->cc_op == CC_OP_ADDC)
367
            && flags & Z_FLAG)
368
                env->cc_mask &= ~Z_FLAG;
369

    
370
        /* all insn clear the x-flag except setf or clrf.  */
371
        env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);
372
        flags &= env->cc_mask;
373
        env->pregs[PR_CCS] |= flags;
374
        RETURN();
375
}
376

    
377
void OPPROTO op_evaluate_flags_muls(void)
378
{
379
        uint32_t src;
380
        uint32_t dst;
381
        uint32_t res;
382
        uint32_t flags = 0;
383
        /* were gonna have to redo the muls.  */
384
        int64_t tmp, t0 ,t1;
385
        int32_t mof;
386
        int dneg;
387

    
388
        src = env->cc_src;
389
        dst = env->cc_dest;
390
        res = env->cc_result;
391

    
392

    
393
        /* cast into signed values to make GCC sign extend.  */
394
        t0 = (int32_t)src;
395
        t1 = (int32_t)dst;
396
        dneg = ((int32_t)res) < 0;
397

    
398
        tmp = t0 * t1;
399
        mof = tmp >> 32;
400
        if (tmp == 0)
401
                flags |= Z_FLAG;
402
        else if (tmp < 0)
403
                flags |= N_FLAG;
404
        if ((dneg && mof != -1)
405
            || (!dneg && mof != 0))
406
                flags |= V_FLAG;
407
        evaluate_flags_writeback(flags);
408
        RETURN();
409
}
410

    
411
void OPPROTO op_evaluate_flags_mulu(void)
412
{
413
        uint32_t src;
414
        uint32_t dst;
415
        uint32_t res;
416
        uint32_t flags = 0;
417
        /* were gonna have to redo the muls.  */
418
        uint64_t tmp, t0 ,t1;
419
        uint32_t mof;
420

    
421
        src = env->cc_src;
422
        dst = env->cc_dest;
423
        res = env->cc_result;
424

    
425

    
426
        /* cast into signed values to make GCC sign extend.  */
427
        t0 = src;
428
        t1 = dst;
429

    
430
        tmp = t0 * t1;
431
        mof = tmp >> 32;
432
        if (tmp == 0)
433
                flags |= Z_FLAG;
434
        else if (tmp >> 63)
435
                flags |= N_FLAG;
436
        if (mof)
437
                flags |= V_FLAG;
438

    
439
        evaluate_flags_writeback(flags);
440
        RETURN();
441
}
442

    
443
void OPPROTO op_evaluate_flags_mcp(void)
444
{
445
        uint32_t src;
446
        uint32_t dst;
447
        uint32_t res;
448
        uint32_t flags = 0;
449

    
450
        src = env->cc_src;
451
        dst = env->cc_dest;
452
        res = env->cc_result;
453

    
454
        if ((res & 0x80000000L) != 0L)
455
        {
456
                flags |= N_FLAG;
457
                if (((src & 0x80000000L) == 0L)
458
                    && ((dst & 0x80000000L) == 0L))
459
                {
460
                        flags |= V_FLAG;
461
                }
462
                else if (((src & 0x80000000L) != 0L) &&
463
                         ((dst & 0x80000000L) != 0L))
464
                {
465
                        flags |= R_FLAG;
466
                }
467
        }
468
        else
469
        {
470
                if (res == 0L)
471
                        flags |= Z_FLAG;
472
                if (((src & 0x80000000L) != 0L)
473
                    && ((dst & 0x80000000L) != 0L))
474
                        flags |= V_FLAG;
475
                if ((dst & 0x80000000L) != 0L
476
                    || (src & 0x80000000L) != 0L)
477
                        flags |= R_FLAG;
478
        }
479

    
480
        evaluate_flags_writeback(flags);
481
        RETURN();
482
}
483

    
484
void OPPROTO op_evaluate_flags_alu_4(void)
485
{
486
        uint32_t src;
487
        uint32_t dst;
488
        uint32_t res;
489
        uint32_t flags = 0;
490

    
491
        src = env->cc_src;
492
        dst = env->cc_dest;
493
        res = env->cc_result;
494

    
495
        if ((res & 0x80000000L) != 0L)
496
        {
497
                flags |= N_FLAG;
498
                if (((src & 0x80000000L) == 0L)
499
                    && ((dst & 0x80000000L) == 0L))
500
                {
501
                        flags |= V_FLAG;
502
                }
503
                else if (((src & 0x80000000L) != 0L) &&
504
                         ((dst & 0x80000000L) != 0L))
505
                {
506
                        flags |= C_FLAG;
507
                }
508
        }
509
        else
510
        {
511
                if (res == 0L)
512
                        flags |= Z_FLAG;
513
                if (((src & 0x80000000L) != 0L)
514
                    && ((dst & 0x80000000L) != 0L))
515
                        flags |= V_FLAG;
516
                if ((dst & 0x80000000L) != 0L
517
                    || (src & 0x80000000L) != 0L)
518
                        flags |= C_FLAG;
519
        }
520

    
521
        if (env->cc_op == CC_OP_SUB
522
            || env->cc_op == CC_OP_CMP) {
523
                flags ^= C_FLAG;
524
        }
525
        evaluate_flags_writeback(flags);
526
        RETURN();
527
}
528

    
529
void OPPROTO op_evaluate_flags_move_4 (void)
530
{
531
        uint32_t src;
532
        uint32_t res;
533
        uint32_t flags = 0;
534

    
535
        src = env->cc_src;
536
        res = env->cc_result;
537

    
538
        if ((int32_t)res < 0)
539
                flags |= N_FLAG;
540
        else if (res == 0L)
541
                flags |= Z_FLAG;
542

    
543
        evaluate_flags_writeback(flags);
544
        RETURN();
545
}
546
void OPPROTO op_evaluate_flags_move_2 (void)
547
{
548
        uint32_t src;
549
        uint32_t flags = 0;
550
        uint16_t res;
551

    
552
        src = env->cc_src;
553
        res = env->cc_result;
554

    
555
        if ((int16_t)res < 0L)
556
                flags |= N_FLAG;
557
        else if (res == 0)
558
                flags |= Z_FLAG;
559

    
560
        evaluate_flags_writeback(flags);
561
        RETURN();
562
}
563

    
564
/* TODO: This is expensive. We could split things up and only evaluate part of
565
   CCR on a need to know basis. For now, we simply re-evaluate everything.  */
566
void OPPROTO op_evaluate_flags (void)
567
{
568
        uint32_t src;
569
        uint32_t dst;
570
        uint32_t res;
571
        uint32_t flags = 0;
572

    
573
        src = env->cc_src;
574
        dst = env->cc_dest;
575
        res = env->cc_result;
576

    
577

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

    
679
        if (env->cc_op == CC_OP_SUB
680
            || env->cc_op == CC_OP_CMP) {
681
                flags ^= C_FLAG;
682
        }
683
        evaluate_flags_writeback(flags);
684
        RETURN();
685
}
686

    
687
void OPPROTO op_extb_T0_T0 (void)
688
{
689
        T0 = ((int8_t)T0);
690
        RETURN();
691
}
692
void OPPROTO op_extb_T1_T0 (void)
693
{
694
        T1 = ((int8_t)T0);
695
        RETURN();
696
}
697
void OPPROTO op_extb_T1_T1 (void)
698
{
699
        T1 = ((int8_t)T1);
700
        RETURN();
701
}
702
void OPPROTO op_zextb_T0_T0 (void)
703
{
704
        T0 = ((uint8_t)T0);
705
        RETURN();
706
}
707
void OPPROTO op_zextb_T1_T0 (void)
708
{
709
        T1 = ((uint8_t)T0);
710
        RETURN();
711
}
712
void OPPROTO op_zextb_T1_T1 (void)
713
{
714
        T1 = ((uint8_t)T1);
715
        RETURN();
716
}
717
void OPPROTO op_extw_T0_T0 (void)
718
{
719
        T0 = ((int16_t)T0);
720
        RETURN();
721
}
722
void OPPROTO op_extw_T1_T0 (void)
723
{
724
        T1 = ((int16_t)T0);
725
        RETURN();
726
}
727
void OPPROTO op_extw_T1_T1 (void)
728
{
729
        T1 = ((int16_t)T1);
730
        RETURN();
731
}
732

    
733
void OPPROTO op_zextw_T0_T0 (void)
734
{
735
        T0 = ((uint16_t)T0);
736
        RETURN();
737
}
738
void OPPROTO op_zextw_T1_T0 (void)
739
{
740
        T1 = ((uint16_t)T0);
741
        RETURN();
742
}
743

    
744
void OPPROTO op_zextw_T1_T1 (void)
745
{
746
        T1 = ((uint16_t)T1);
747
        RETURN();
748
}
749

    
750
void OPPROTO op_movl_T0_im (void)
751
{
752
        T0 = PARAM1;
753
        RETURN();
754
}
755
void OPPROTO op_movl_T1_im (void)
756
{
757
        T1 = PARAM1;
758
        RETURN();
759
}
760

    
761
void OPPROTO op_addl_T0_im (void)
762
{
763
        T0 += PARAM1;
764
        RETURN();
765
}
766

    
767
void OPPROTO op_addl_T1_im (void)
768
{
769
        T1 += PARAM1;
770
        RETURN();
771

    
772
}
773
void OPPROTO op_subl_T0_im (void)
774
{
775
        T0 -= PARAM1;
776
        RETURN();
777
}
778

    
779
void OPPROTO op_addxl_T0_C (void)
780
{
781
        if (env->pregs[PR_CCS] & X_FLAG)
782
                T0 += !!(env->pregs[PR_CCS] & C_FLAG);
783
        RETURN();
784
}
785
void OPPROTO op_subxl_T0_C (void)
786
{
787
        if (env->pregs[PR_CCS] & X_FLAG)
788
                T0 -= !!(env->pregs[PR_CCS] & C_FLAG);
789
        RETURN();
790
}
791
void OPPROTO op_addl_T0_C (void)
792
{
793
        T0 += !!(env->pregs[PR_CCS] & C_FLAG);
794
        RETURN();
795
}
796
void OPPROTO op_addl_T0_R (void)
797
{
798
        T0 += !!(env->pregs[PR_CCS] & R_FLAG);
799
        RETURN();
800
}
801

    
802
void OPPROTO op_clr_R (void)
803
{
804
        env->pregs[PR_CCS] &= ~R_FLAG;
805
        RETURN();
806
}
807

    
808

    
809
void OPPROTO op_andl_T0_im (void)
810
{
811
        T0 &= PARAM1;
812
        RETURN();
813
}
814

    
815
void OPPROTO op_andl_T1_im (void)
816
{
817
        T1 &= PARAM1;
818
        RETURN();
819
}
820

    
821
void OPPROTO op_movl_T0_T1 (void)
822
{
823
        T0 = T1;
824
        RETURN();
825
}
826

    
827
void OPPROTO op_swp_T0_T1 (void)
828
{
829
        T0 ^= T1;
830
        T1 ^= T0;
831
        T0 ^= T1;
832
        RETURN();
833
}
834

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

    
841
void OPPROTO op_movl_pc_T0 (void)
842
{
843
        env->pc = T0;
844
        RETURN();
845
}
846

    
847
void OPPROTO op_movl_T0_0 (void)
848
{
849
        T0 = 0;
850
        RETURN();
851
}
852

    
853
void OPPROTO op_addl_T0_T1 (void)
854
{
855
        T0 += T1;
856
        RETURN();
857
}
858

    
859
void OPPROTO op_subl_T0_T1 (void)
860
{
861
        T0 -= T1;
862
        RETURN();
863
}
864

    
865
void OPPROTO op_absl_T1_T1 (void)
866
{
867
        int32_t st = T1;
868

    
869
        T1 = st < 0 ? -st : st;
870
        RETURN();
871
}
872

    
873
void OPPROTO op_muls_T0_T1 (void)
874
{
875
        int64_t tmp, t0 ,t1;
876

    
877
        /* cast into signed values to make GCC sign extend these babies.  */
878
        t0 = (int32_t)T0;
879
        t1 = (int32_t)T1;
880

    
881
        tmp = t0 * t1;
882
        T0 = tmp & 0xffffffff;
883
        env->pregs[PR_MOF] = tmp >> 32;
884
        RETURN();
885
}
886

    
887
void OPPROTO op_mulu_T0_T1 (void)
888
{
889
        uint64_t tmp, t0 ,t1;
890
        t0 = T0;
891
        t1 = T1;
892

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

    
899
void OPPROTO op_dstep_T0_T1 (void)
900
{
901
        T0 <<= 1;
902
        if (T0 >= T1)
903
                T0 -= T1;
904
        RETURN();
905
}
906

    
907
void OPPROTO op_orl_T0_T1 (void)
908
{
909
        T0 |= T1;
910
        RETURN();
911
}
912

    
913
void OPPROTO op_andl_T0_T1 (void)
914
{
915
        T0 &= T1;
916
        RETURN();
917
}
918

    
919
void OPPROTO op_xorl_T0_T1 (void)
920
{
921
        T0 ^= T1;
922
        RETURN();
923
}
924

    
925
void OPPROTO op_lsll_T0_T1 (void)
926
{
927
        int s = T1;
928
        if (s > 31)
929
                T0 = 0;
930
        else
931
                T0 <<= s;
932
        RETURN();
933
}
934

    
935
void OPPROTO op_lsll_T0_im (void)
936
{
937
        T0 <<= PARAM1;
938
        RETURN();
939
}
940

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

    
951
/* Rely on GCC emitting an arithmetic shift for signed right shifts.  */
952
void OPPROTO op_asrl_T0_T1 (void)
953
{
954
        int s = T1;
955
        if (s > 31)
956
                T0 = T0 & 0x80000000 ? -1 : 0;
957
        else
958
                T0 = (int32_t)T0 >> s;
959
        RETURN();
960
}
961

    
962
void OPPROTO op_btst_T0_T1 (void)
963
{
964
        /* FIXME: clean this up.  */
965

    
966
        /* des ref:
967
           The N flag is set according to the selected bit in the dest reg.
968
           The Z flag is set if the selected bit and all bits to the right are
969
           zero.
970
           The destination reg is not affected.*/
971
        unsigned int fz, sbit, bset, mask, masked_t0;
972

    
973
        sbit = T1 & 31;
974
        bset = !!(T0 & (1 << sbit));
975
        mask = sbit == 31 ? -1 : (1 << (sbit + 1)) - 1;
976
        masked_t0 = T0 & mask;
977
        fz = !(masked_t0 | bset);
978
        /* Set the N and Z flags accordingly.  */
979
        T0 = (bset << 3) | (fz << 2);
980
        RETURN();
981
}
982

    
983
void OPPROTO op_bound_T0_T1 (void)
984
{
985
        if (T0 > T1)
986
                T0 = T1;
987
        RETURN();
988
}
989

    
990
void OPPROTO op_lz_T0_T1 (void)
991
{
992
        T0 = clz32(T1);
993
        RETURN();
994
}
995

    
996
void OPPROTO op_negl_T0_T1 (void)
997
{
998
        T0 = -T1;
999
        RETURN();
1000
}
1001

    
1002
void OPPROTO op_negl_T1_T1 (void)
1003
{
1004
        T1 = -T1;
1005
        RETURN();
1006
}
1007

    
1008
void OPPROTO op_not_T0_T0 (void)
1009
{
1010
        T0 = ~(T0);
1011
        RETURN();
1012
}
1013
void OPPROTO op_not_T1_T1 (void)
1014
{
1015
        T1 = ~(T1);
1016
        RETURN();
1017
}
1018

    
1019
void OPPROTO op_swapw_T0_T0 (void)
1020
{
1021
        T0 = (T0 << 16) | ((T0 >> 16));
1022
        RETURN();
1023
}
1024

    
1025
void OPPROTO op_swapb_T0_T0 (void)
1026
{
1027
        T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff);
1028
        RETURN();
1029
}
1030

    
1031
void OPPROTO op_swapr_T0_T0 (void)
1032
{
1033
        T0 = (((T0 << 7) & 0x80808080) |
1034
              ((T0 << 5) & 0x40404040) |
1035
              ((T0 << 3) & 0x20202020) |
1036
              ((T0 << 1) & 0x10101010) |
1037
              ((T0 >> 1) & 0x08080808) |
1038
              ((T0 >> 3) & 0x04040404) |
1039
              ((T0 >> 5) & 0x02020202) |
1040
              ((T0 >> 7) & 0x01010101));
1041
        RETURN();
1042
}
1043

    
1044
void OPPROTO op_tst_cc_eq (void) {
1045
        uint32_t flags = env->pregs[PR_CCS];
1046
        int z_set;
1047

    
1048
        z_set = !!(flags & Z_FLAG);
1049
        T0 = z_set;
1050
        RETURN();
1051
}
1052

    
1053
void OPPROTO op_tst_cc_eq_fast (void) {
1054
        T0 = !(env->cc_result);
1055
        RETURN();
1056
}
1057

    
1058
void OPPROTO op_tst_cc_ne (void) {
1059
        uint32_t flags = env->pregs[PR_CCS];
1060
        int z_set;
1061

    
1062
        z_set = !!(flags & Z_FLAG);
1063
        T0 = !z_set;
1064
        RETURN();
1065
}
1066
void OPPROTO op_tst_cc_ne_fast (void) {
1067
        T0 = !!(env->cc_result);
1068
        RETURN();
1069
}
1070

    
1071
void OPPROTO op_tst_cc_cc (void) {
1072
        uint32_t flags = env->pregs[PR_CCS];
1073
        int c_set;
1074

    
1075
        c_set = !!(flags & C_FLAG);
1076
        T0 = !c_set;
1077
        RETURN();
1078
}
1079
void OPPROTO op_tst_cc_cs (void) {
1080
        uint32_t flags = env->pregs[PR_CCS];
1081
        int c_set;
1082

    
1083
        c_set = !!(flags & C_FLAG);
1084
        T0 = c_set;
1085
        RETURN();
1086
}
1087

    
1088
void OPPROTO op_tst_cc_vc (void) {
1089
        uint32_t flags = env->pregs[PR_CCS];
1090
        int v_set;
1091

    
1092
        v_set = !!(flags & V_FLAG);
1093
        T0 = !v_set;
1094
        RETURN();
1095
}
1096
void OPPROTO op_tst_cc_vs (void) {
1097
        uint32_t flags = env->pregs[PR_CCS];
1098
        int v_set;
1099

    
1100
        v_set = !!(flags & V_FLAG);
1101
        T0 = v_set;
1102
        RETURN();
1103
}
1104
void OPPROTO op_tst_cc_pl (void) {
1105
        uint32_t flags = env->pregs[PR_CCS];
1106
        int n_set;
1107

    
1108
        n_set = !!(flags & N_FLAG);
1109
        T0 = !n_set;
1110
        RETURN();
1111
}
1112
void OPPROTO op_tst_cc_pl_fast (void) {
1113
        T0 = ((int32_t)env->cc_result) >= 0;
1114
        RETURN();
1115
}
1116

    
1117
void OPPROTO op_tst_cc_mi (void) {
1118
        uint32_t flags = env->pregs[PR_CCS];
1119
        int n_set;
1120

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

    
1130
void OPPROTO op_tst_cc_ls (void) {
1131
        uint32_t flags = env->pregs[PR_CCS];
1132
        int c_set;
1133
        int z_set;
1134

    
1135
        c_set = !!(flags & C_FLAG);
1136
        z_set = !!(flags & Z_FLAG);
1137
        T0 = c_set || z_set;
1138
        RETURN();
1139
}
1140
void OPPROTO op_tst_cc_hi (void) {
1141
        uint32_t flags = env->pregs[PR_CCS];
1142
        int z_set;
1143
        int c_set;
1144

    
1145
        z_set = !!(flags & Z_FLAG);
1146
        c_set = !!(flags & C_FLAG);
1147
        T0 = !c_set && !z_set;
1148
        RETURN();
1149

    
1150
}
1151

    
1152
void OPPROTO op_tst_cc_ge (void) {
1153
        uint32_t flags = env->pregs[PR_CCS];
1154
        int n_set;
1155
        int v_set;
1156

    
1157
        n_set = !!(flags & N_FLAG);
1158
        v_set = !!(flags & V_FLAG);
1159
        T0 = (n_set && v_set) || (!n_set && !v_set);
1160
        RETURN();
1161
}
1162

    
1163
void OPPROTO op_tst_cc_ge_fast (void) {
1164
        T0 = ((int32_t)env->cc_src < (int32_t)env->cc_dest);
1165
        RETURN();
1166
}
1167

    
1168
void OPPROTO op_tst_cc_lt (void) {
1169
        uint32_t flags = env->pregs[PR_CCS];
1170
        int n_set;
1171
        int v_set;
1172

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

    
1179
void OPPROTO op_tst_cc_gt (void) {
1180
        uint32_t flags = env->pregs[PR_CCS];
1181
        int n_set;
1182
        int v_set;
1183
        int z_set;
1184

    
1185
        n_set = !!(flags & N_FLAG);
1186
        v_set = !!(flags & V_FLAG);
1187
        z_set = !!(flags & Z_FLAG);
1188
        T0 = (n_set && v_set && !z_set)
1189
                || (!n_set && !v_set && !z_set);
1190
        RETURN();
1191
}
1192

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

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

    
1206
void OPPROTO op_tst_cc_p (void) {
1207
        uint32_t flags = env->pregs[PR_CCS];
1208
        int p_set;
1209

    
1210
        p_set = !!(flags & P_FLAG);
1211
        T0 = p_set;
1212
        RETURN();
1213
}
1214

    
1215
/* Evaluate the if the branch should be taken or not. Needs to be done in
1216
   the original sequence. The acutal branch is rescheduled to right after the
1217
   delay-slot.  */
1218
void OPPROTO op_evaluate_bcc (void)
1219
{
1220
        env->btaken = T0;
1221
        RETURN();
1222
}
1223

    
1224
/* this one is used on every alu op, optimize it!.  */
1225
void OPPROTO op_goto_if_not_x (void)
1226
{
1227
        if (env->pregs[PR_CCS] & X_FLAG)
1228
                GOTO_LABEL_PARAM(1);
1229
        RETURN();
1230
}
1231

    
1232
void OPPROTO op_cc_jmp (void)
1233
{
1234
        if (env->btaken)
1235
                env->pc = PARAM1;
1236
        else
1237
                env->pc = PARAM2;
1238
        RETURN();
1239
}
1240

    
1241
void OPPROTO op_cc_ngoto (void)
1242
{
1243
        if (!env->btaken)
1244
                GOTO_LABEL_PARAM(1);
1245
        RETURN();
1246
}
1247

    
1248
void OPPROTO op_movl_btarget_T0 (void)
1249
{
1250
        env->btarget = T0;
1251
        RETURN();
1252
}
1253

    
1254
void OPPROTO op_jmp1 (void)
1255
{
1256
        env->pc = env->btarget;
1257
        RETURN();
1258
}
1259

    
1260
/* Load and store */
1261
#define MEMSUFFIX _raw
1262
#include "op_mem.c"
1263
#undef MEMSUFFIX
1264
#if !defined(CONFIG_USER_ONLY)
1265
#define MEMSUFFIX _user
1266
#include "op_mem.c"
1267
#undef MEMSUFFIX
1268

    
1269
#define MEMSUFFIX _kernel
1270
#include "op_mem.c"
1271
#undef MEMSUFFIX
1272
#endif