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 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  
... ...
target-mips/op.c
... ... @@ -22,6 +22,7 @@
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,35 +538,13 @@ void op_rotrv (void)
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,6 +624,18 @@ void op_drotrv (void)
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,41 +726,19 @@ void op_drotrv (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 */
... ...
target-mips/op_helper.c
... ... @@ -20,6 +20,8 @@
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,6 +143,17 @@ void do_drotrv (void)
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  
... ...