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