Commit 05f778c8bdfa3f0499c3777f562db1feed338502

Authored by ths
1 parent 5592a750

Add sharable clz/clo inline functions and use them for the mips target.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3455 c046a42c-6fe2-441c-8c8c-71466251a162
host-utils.h 0 → 100644
  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 +}
target-mips/exec.h
@@ -70,6 +70,8 @@ void do_dsllv (void); @@ -70,6 +70,8 @@ void do_dsllv (void);
70 void do_dsrav (void); 70 void do_dsrav (void);
71 void do_dsrlv (void); 71 void do_dsrlv (void);
72 void do_drotrv (void); 72 void do_drotrv (void);
  73 +void do_dclo (void);
  74 +void do_dclz (void);
73 #endif 75 #endif
74 #endif 76 #endif
75 77
target-mips/op.c
@@ -22,6 +22,7 @@ @@ -22,6 +22,7 @@
22 22
23 #include "config.h" 23 #include "config.h"
24 #include "exec.h" 24 #include "exec.h"
  25 +#include "host-utils.h"
25 26
26 #ifndef CALL_FROM_TB0 27 #ifndef CALL_FROM_TB0
27 #define CALL_FROM_TB0(func) func() 28 #define CALL_FROM_TB0(func) func()
@@ -537,35 +538,13 @@ void op_rotrv (void) @@ -537,35 +538,13 @@ void op_rotrv (void)
537 538
538 void op_clo (void) 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 RETURN(); 542 RETURN();
553 } 543 }
554 544
555 void op_clz (void) 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 RETURN(); 548 RETURN();
570 } 549 }
571 550
@@ -645,6 +624,18 @@ void op_drotrv (void) @@ -645,6 +624,18 @@ void op_drotrv (void)
645 RETURN(); 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 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */ 639 #else /* TARGET_LONG_BITS > HOST_LONG_BITS */
649 640
650 void op_dsll (void) 641 void op_dsll (void)
@@ -735,41 +726,19 @@ void op_drotrv (void) @@ -735,41 +726,19 @@ void op_drotrv (void)
735 T0 = T1; 726 T0 = T1;
736 RETURN(); 727 RETURN();
737 } 728 }
738 -#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */  
739 729
740 void op_dclo (void) 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 RETURN(); 733 RETURN();
755 } 734 }
756 735
757 void op_dclz (void) 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 RETURN(); 739 RETURN();
772 } 740 }
  741 +#endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
773 #endif /* TARGET_MIPSN32 || TARGET_MIPS64 */ 742 #endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
774 743
775 /* 64 bits arithmetic */ 744 /* 64 bits arithmetic */
target-mips/op_helper.c
@@ -20,6 +20,8 @@ @@ -20,6 +20,8 @@
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include "exec.h" 21 #include "exec.h"
22 22
  23 +#include "host-utils.h"
  24 +
23 #define GETPC() (__builtin_return_address(0)) 25 #define GETPC() (__builtin_return_address(0))
24 26
25 /*****************************************************************************/ 27 /*****************************************************************************/
@@ -141,6 +143,17 @@ void do_drotrv (void) @@ -141,6 +143,17 @@ void do_drotrv (void)
141 } else 143 } else
142 T0 = T1; 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 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */ 157 #endif /* TARGET_LONG_BITS > HOST_LONG_BITS */
145 #endif /* TARGET_MIPSN32 || TARGET_MIPS64 */ 158 #endif /* TARGET_MIPSN32 || TARGET_MIPS64 */
146 159