1/*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "opto/countbitsnode.hpp"
27#include "opto/opcodes.hpp"
28#include "opto/phaseX.hpp"
29#include "opto/type.hpp"
30
31//------------------------------Value------------------------------------------
32const Type* CountLeadingZerosINode::Value(PhaseGVN* phase) const {
33 const Type* t = phase->type(in(1));
34 if (t == Type::TOP) return Type::TOP;
35 const TypeInt* ti = t->isa_int();
36 if (ti && ti->is_con()) {
37 jint i = ti->get_con();
38 // HD, Figure 5-6
39 if (i == 0)
40 return TypeInt::make(BitsPerInt);
41 int n = 1;
42 unsigned int x = i;
43 if (x >> 16 == 0) { n += 16; x <<= 16; }
44 if (x >> 24 == 0) { n += 8; x <<= 8; }
45 if (x >> 28 == 0) { n += 4; x <<= 4; }
46 if (x >> 30 == 0) { n += 2; x <<= 2; }
47 n -= x >> 31;
48 return TypeInt::make(n);
49 }
50 return TypeInt::INT;
51}
52
53//------------------------------Value------------------------------------------
54const Type* CountLeadingZerosLNode::Value(PhaseGVN* phase) const {
55 const Type* t = phase->type(in(1));
56 if (t == Type::TOP) return Type::TOP;
57 const TypeLong* tl = t->isa_long();
58 if (tl && tl->is_con()) {
59 jlong l = tl->get_con();
60 // HD, Figure 5-6
61 if (l == 0)
62 return TypeInt::make(BitsPerLong);
63 int n = 1;
64 unsigned int x = (((julong) l) >> 32);
65 if (x == 0) { n += 32; x = (int) l; }
66 if (x >> 16 == 0) { n += 16; x <<= 16; }
67 if (x >> 24 == 0) { n += 8; x <<= 8; }
68 if (x >> 28 == 0) { n += 4; x <<= 4; }
69 if (x >> 30 == 0) { n += 2; x <<= 2; }
70 n -= x >> 31;
71 return TypeInt::make(n);
72 }
73 return TypeInt::INT;
74}
75
76//------------------------------Value------------------------------------------
77const Type* CountTrailingZerosINode::Value(PhaseGVN* phase) const {
78 const Type* t = phase->type(in(1));
79 if (t == Type::TOP) return Type::TOP;
80 const TypeInt* ti = t->isa_int();
81 if (ti && ti->is_con()) {
82 jint i = ti->get_con();
83 // HD, Figure 5-14
84 int y;
85 if (i == 0)
86 return TypeInt::make(BitsPerInt);
87 int n = 31;
88 y = i << 16; if (y != 0) { n = n - 16; i = y; }
89 y = i << 8; if (y != 0) { n = n - 8; i = y; }
90 y = i << 4; if (y != 0) { n = n - 4; i = y; }
91 y = i << 2; if (y != 0) { n = n - 2; i = y; }
92 y = i << 1; if (y != 0) { n = n - 1; }
93 return TypeInt::make(n);
94 }
95 return TypeInt::INT;
96}
97
98//------------------------------Value------------------------------------------
99const Type* CountTrailingZerosLNode::Value(PhaseGVN* phase) const {
100 const Type* t = phase->type(in(1));
101 if (t == Type::TOP) return Type::TOP;
102 const TypeLong* tl = t->isa_long();
103 if (tl && tl->is_con()) {
104 jlong l = tl->get_con();
105 // HD, Figure 5-14
106 int x, y;
107 if (l == 0)
108 return TypeInt::make(BitsPerLong);
109 int n = 63;
110 y = (int) l; if (y != 0) { n = n - 32; x = y; } else x = (((julong) l) >> 32);
111 y = x << 16; if (y != 0) { n = n - 16; x = y; }
112 y = x << 8; if (y != 0) { n = n - 8; x = y; }
113 y = x << 4; if (y != 0) { n = n - 4; x = y; }
114 y = x << 2; if (y != 0) { n = n - 2; x = y; }
115 y = x << 1; if (y != 0) { n = n - 1; }
116 return TypeInt::make(n);
117 }
118 return TypeInt::INT;
119}
120