Revision 05f778c8

b/host-utils.h
1
/*
2
 * Utility compute operations used by translated code.
3
 *
4
 * Copyright (c) 2007 Thiemo Seufer
5
 * Copyright (c) 2007 Jocelyn Mayer
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25

  
26
/* Note that some of those functions may end up calling libgcc functions,
27
   depending on the host machine. It is up to the target emulation to
28
   cope with that. */
29

  
30
/* Binary search for leading zeros.  */
31

  
32
static always_inline int clz32(uint32_t val)
33
{
34
    int cnt = 0;
35

  
36
    if (!(val & 0xFFFF0000U)) {
37
        cnt += 16;
38
        val <<= 16;
39
    }
40
    if (!(val & 0xFF000000U)) {
41
        cnt += 8;
42
        val <<= 8;
43
    }
44
    if (!(val & 0xF0000000U)) {
45
        cnt += 4;
46
        val <<= 4;
47
    }
48
    if (!(val & 0xC0000000U)) {
49
        cnt += 2;
50
        val <<= 2;
51
    }
52
    if (!(val & 0x80000000U)) {
53
        cnt++;
54
        val <<= 1;
55
    }
56
    if (!(val & 0x80000000U)) {
57
        cnt++;
58
    }
59
    return cnt;
60
}
61

  
62
static always_inline int clo32(uint32_t val)
63
{
64
    return clz32(~val);
65
}
66

  
67
static always_inline int clz64(uint64_t val)
68
{
69
    int cnt = 0;
70

  
71
    if (!(val & 0xFFFFFFFF00000000ULL)) {
72
        cnt += 32;
73
        val <<= 32;
74
    }
75
    if (!(val & 0xFFFF000000000000ULL)) {
76
        cnt += 16;
77
        val <<= 16;
78
    }
79
    if (!(val & 0xFF00000000000000ULL)) {
80
        cnt += 8;
81
        val <<= 8;
82
    }
83
    if (!(val & 0xF000000000000000ULL)) {
84
        cnt += 4;
85
        val <<= 4;
86
    }
87
    if (!(val & 0xC000000000000000ULL)) {
88
        cnt += 2;
89
        val <<= 2;
90
    }
91
    if (!(val & 0x8000000000000000ULL)) {
92
        cnt++;
93
        val <<= 1;
94
    }
95
    if (!(val & 0x8000000000000000ULL)) {
96
        cnt++;
97
    }
98
    return cnt;
99
}
100

  
101
static always_inline int clo64(uint64_t val)
102
{
103
    return clz64(~val);
104
}
b/target-mips/exec.h
70 70
void do_dsrav (void);
71 71
void do_dsrlv (void);
72 72
void do_drotrv (void);
73
void do_dclo (void);
74
void do_dclz (void);
73 75
#endif
74 76
#endif
75 77

  
b/target-mips/op.c
22 22

  
23 23
#include "config.h"
24 24
#include "exec.h"
25
#include "host-utils.h"
25 26

  
26 27
#ifndef CALL_FROM_TB0
27 28
#define CALL_FROM_TB0(func) func()
......
537 538

  
538 539
void op_clo (void)
539 540
{
540
    int n;
541

  
542
    if (T0 == ~((target_ulong)0)) {
543
        T0 = 32;
544
    } else {
545
        for (n = 0; n < 32; n++) {
546
            if (!(((int32_t)T0) & (1 << 31)))
547
                break;
548
            T0 <<= 1;
549
        }
550
        T0 = n;
551
    }
541
    T0 = clo32(T0);
552 542
    RETURN();
553 543
}
554 544

  
555 545
void op_clz (void)
556 546
{
557
    int n;
558

  
559
    if (T0 == 0) {
560
        T0 = 32;
561
    } else {
562
        for (n = 0; n < 32; n++) {
563
            if (T0 & (1 << 31))
564
                break;
565
            T0 <<= 1;
566
        }
567
        T0 = n;
568
    }
547
    T0 = clz32(T0);
569 548
    RETURN();
570 549
}
571 550

  
......
645 624
    RETURN();
646 625
}
647 626

  
627
void op_dclo (void)
628
{
629
    CALL_FROM_TB0(do_dclo);
630
    RETURN();
631
}
632

  
633
void op_dclz (void)
634
{
635
    CALL_FROM_TB0(do_dclz);
636
    RETURN();
637
}
638

  
648 639
#else /* TARGET_LONG_BITS > HOST_LONG_BITS */
649 640

  
650 641
void op_dsll (void)
......
735 726
       T0 = T1;
736 727
    RETURN();
737 728
}
738
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
739 729

  
740 730
void op_dclo (void)
741 731
{
742
    int n;
743

  
744
    if (T0 == ~((target_ulong)0)) {
745
        T0 = 64;
746
    } else {
747
        for (n = 0; n < 64; n++) {
748
            if (!(T0 & (1ULL << 63)))
749
                break;
750
            T0 <<= 1;
751
        }
752
        T0 = n;
753
    }
732
    T0 = clo64(T0);
754 733
    RETURN();
755 734
}
756 735

  
757 736
void op_dclz (void)
758 737
{
759
    int n;
760

  
761
    if (T0 == 0) {
762
        T0 = 64;
763
    } else {
764
        for (n = 0; n < 64; n++) {
765
            if (T0 & (1ULL << 63))
766
                break;
767
            T0 <<= 1;
768
        }
769
        T0 = n;
770
    }
738
    T0 = clz64(T0);
771 739
    RETURN();
772 740
}
741
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
773 742
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
774 743

  
775 744
/* 64 bits arithmetic */
b/target-mips/op_helper.c
20 20
#include <stdlib.h>
21 21
#include "exec.h"
22 22

  
23
#include "host-utils.h"
24

  
23 25
#define GETPC() (__builtin_return_address(0))
24 26

  
25 27
/*****************************************************************************/
......
141 143
    } else
142 144
       T0 = T1;
143 145
}
146

  
147
void do_dclo (void)
148
{
149
    T0 = clo64(T0);
150
}
151

  
152
void do_dclz (void)
153
{
154
    T0 = clz64(T0);
155
}
156

  
144 157
#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
145 158
#endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
146 159

  

Also available in: Unified diff