001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.jikesrvm.util;
014
015import org.vmmagic.pragma.Inline;
016import org.vmmagic.unboxed.Address;
017import org.vmmagic.unboxed.Offset;
018import org.vmmagic.unboxed.Word;
019
020/**
021 * Utilities for manipulating values at the bit-level.
022 */
023public class Bits {
024
025  /**
026   * @param value the value to mask
027   * @return the lower 16 bits to
028   * be used in a PPC immediate field
029   */
030  public static int PPCMaskLower16(int value) {
031    return (value & 0xffff);
032  }
033
034  /**
035   * @param value the value to mask
036   * @return the lower 16 bits to
037   * be used in a PPC immediate field
038   */
039  public static int PPCMaskLower16(Offset value) {
040    return (value.toInt() & 0xffff);
041  }
042
043  /**
044   * @param value the value to mask
045   * @return the upper 16 bits to be used in a PPC
046   * immediate field
047   */
048  public static int PPCMaskUpper16(int value) {
049    short s = (short) (value & 0xffff);
050    return ((value - s) >> 16) & 0xffff;
051  }
052
053  /**
054   * @param value the value to mask
055   * @return the upper 16 bits to be used in a PPC
056   * immediate field, make sure fits in 32 bits
057   */
058  public static int PPCMaskUpper16(Offset value) {
059    return PPCMaskUpper16(value.toInt());
060  }
061
062  /**
063   * @param value the value to mask
064   * @return the lower 8 bits (as an int) of an int
065   */
066  public static int lower8(int value) {
067    return (value & 0xff);
068  }
069
070  /**
071   * @param value the value to mask
072   * @return the lower 16 bits (as an int) of  an int
073   */
074  public static int lower16(int value) {
075    return (value & 0xffff);
076  }
077
078  /**
079   * @param value the value to mask
080   * @return the upper 16 bits (as an int) of an int
081   */
082  public static int upper16(int value) {
083    return value >>> 16;
084  }
085
086  /**
087   * @param value the value to mask
088   * @return the upper 24 bits (as an int) of an int
089   */
090  public static int upper24(int value) {
091    return value >>> 8;
092  }
093
094  /**
095   * @param value the value to mask
096   * @return the lower 32 bits (as an int) of a long
097   */
098  public static int lower32(long value) {
099    return (int) value;
100  }
101
102  /**
103   * @param value the value to mask
104   * @return the upper 32 bits (as an int) of a long
105   */
106  public static int upper32(long value) {
107    return (int) (value >>> 32);
108  }
109
110  /**
111   * Finds out whether a given signed value can be represented in a
112   * given number of bits.
113   *
114   * @param val the value to be represented
115   * @param bits the number of bits to use.
116   * @return {@code true} if val can be encoded in bits.
117   */
118  @Inline
119  public static boolean fits(long val, int bits) {
120    val = val >> bits - 1;
121    return (val == 0L || val == -1L);
122  }
123
124  /**
125   * Finds out whether a given signed value can be represented in a
126   * given number of bits.
127   *
128   * @param val the value to be represented
129   * @param bits the number of bits to use.
130   * @return {@code true} if val can be encoded in bits.
131   */
132  @Inline
133  public static boolean fits(Offset val, int bits) {
134    return fits(val.toWord(), bits);
135  }
136
137  /**
138   * Find out whether a given signed value can be represented in a
139   * given number of bits.
140   *
141   * @param val the value to be represented
142   * @param bits the number of bits to use.
143   * @return {@code true} if val can be encoded in bits.
144   */
145  @Inline
146  public static boolean fits(Address val, int bits) {
147    return fits(val.toWord(), bits);
148  }
149
150  /**
151   * Finds out whether a given signed value can be represented in a
152   * given number of bits.
153   *
154   * @param val the value to be represented
155   * @param bits the number of bits to use.
156   * @return {@code true} if val can be encoded in bits.
157   */
158  public static boolean fits(int val, int bits) {
159    val = val >> bits - 1;
160    return (val == 0 || val == -1);
161  }
162
163  /**
164   * Finds out whether a given signed value can be represented in a
165   * given number of bits.
166   *
167   * @param val the value to be represented
168   * @param bits the number of bits to use.
169   * @return {@code true} if val can be encoded in bits.
170   */
171  @Inline
172  public static boolean fits(Word val, int bits) {
173    Word o = val.rsha(bits - 1);
174    return (o.isZero() || o.isMax());
175 }
176
177}