1/*
2 * Copyright (c) 2015, 2015, 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 */
23package org.graalvm.compiler.word;
24
25/**
26 * Utility methods on Pointers.
27 */
28public final class PointerUtils {
29
30    private PointerUtils() {
31        // This is a class of static methods, so no need for any instances.
32    }
33
34    /**
35     * The value of a null Pointer.
36     *
37     * @return A null Pointer value.
38     */
39    @SuppressWarnings("unchecked")
40    public static <T extends PointerBase> T nullPointer() {
41        return (T) Word.zero();
42    }
43
44    /**
45     * Predicate to check for the null Pointer value.
46     *
47     * @return Whether that Pointer is the null Pointer.
48     */
49    public static boolean isNull(ComparableWord that) {
50        return that.equal(nullPointer());
51    }
52
53    /**
54     * Predicate to check for a non-null Pointer value.
55     *
56     * @return Whether that Pointer is not the null Pointer.
57     */
58    public static boolean isNonNull(ComparableWord that) {
59        return that.notEqual(nullPointer());
60    }
61
62    /**
63     * Round a Pointer down to the nearest smaller multiple.
64     *
65     * @param that The Pointer to be rounded up.
66     * @param multiple The multiple to which that Pointer should be decreased.
67     * @return That Pointer, but rounded down.
68     */
69    public static Pointer roundDown(PointerBase that, Unsigned multiple) {
70        return (Pointer) UnsignedUtils.roundDown((Unsigned) that, multiple);
71    }
72
73    /**
74     * Round a Pointer up to the nearest larger multiple.
75     *
76     * @param that The Pointer to be rounded up.
77     * @param multiple The multiple to which that Pointer should be increased.
78     * @return That Pointer, but rounded up.
79     */
80    public static Pointer roundUp(PointerBase that, Unsigned multiple) {
81        return (Pointer) UnsignedUtils.roundUp((Unsigned) that, multiple);
82    }
83
84    /**
85     * Check that a Pointer is an even multiple.
86     *
87     * @param that The Pointer to be verified as a multiple.
88     * @param multiple The multiple against which the Pointer should be verified.
89     * @return true if that Pointer is a multiple, false otherwise.
90     */
91    public static boolean isAMultiple(PointerBase that, Unsigned multiple) {
92        return that.equal(PointerUtils.roundDown(that, multiple));
93    }
94
95    /**
96     * Return the distance between two Pointers.
97     *
98     * @param pointer1 A first Pointer.
99     * @param pointer2 A second Pointer.
100     * @return The distance in bytes between the two Pointers.
101     */
102    public static Unsigned absoluteDifference(PointerBase pointer1, PointerBase pointer2) {
103        Pointer p1 = (Pointer) pointer1;
104        Pointer p2 = (Pointer) pointer2;
105        final Unsigned result;
106        if (p1.aboveOrEqual(p2)) {
107            result = p1.subtract(p2);
108        } else {
109            result = p2.subtract(p1);
110        }
111        return result;
112    }
113
114    /**
115     * The minimum of two Pointers.
116     *
117     * @param x A Pointer.
118     * @param y Another Pointer.
119     * @return The whichever Pointer is smaller.
120     */
121    public static <T extends PointerBase> T min(T x, T y) {
122        return (((Pointer) x).belowOrEqual((Pointer) y)) ? x : y;
123    }
124
125    /**
126     * The maximum of two Pointers.
127     *
128     * @param x A Pointer.
129     * @param y Another Pointer.
130     * @return The whichever Pointer is larger.
131     */
132    public static <T extends PointerBase> T max(T x, T y) {
133        return (((Pointer) x).aboveOrEqual((Pointer) y)) ? x : y;
134    }
135}
136