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     */
013    package org.jikesrvm.compilers.opt.util;
014    
015    import org.jikesrvm.VM;
016    import org.vmmagic.unboxed.Address;
017    import org.vmmagic.unboxed.Offset;
018    
019    /**
020     * Bits.java
021     *
022     * utilities for manipulating values at the bit-level.
023     */
024    public class Bits {
025    
026      /**
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       * Return the lower 16 bits to
036       * be used in a PPC immediate field
037       */
038      public static int PPCMaskLower16(Offset value) {
039        return (value.toInt() & 0xffff);
040      }
041    
042      /**
043       * Return the upper 16 bits to be used in a PPC
044       * immediate field
045       */
046      public static int PPCMaskUpper16(int value) {
047        short s = (short) (value & 0xffff);
048        return ((value - (int) s) >> 16) & 0xffff;
049      }
050    
051      /**
052       * Return the upper 16 bits to be used in a PPC
053       * immediate field, make sure fits in 32 bits
054       */
055      public static int PPCMaskUpper16(Offset value) {
056        return PPCMaskUpper16(value.toInt());
057      }
058    
059      /**
060       * Return the lower 8 bits (as an int) of an int
061       */
062      public static int lower8(int value) {
063        return (value & 0xff);
064      }
065    
066      /**
067       * Return the lower 16 bits (as an int) of  an int
068       */
069      public static int lower16(int value) {
070        return (value & 0xffff);
071      }
072    
073      /**
074       * Return the upper 16 bits (as an int) of an int
075       */
076      public static int upper16(int value) {
077        return value >>> 16;
078      }
079    
080      /**
081       * Return the upper 24 bits (as an int) of an int
082       */
083      public static int upper24(int value) {
084        return value >>> 8;
085      }
086    
087      /**
088       * Return the lower 32 bits (as an int) of a long
089       */
090      public static int lower32(long value) {
091        return (int) value;
092      }
093    
094      /**
095       * Return the upper 32 bits (as an int) of a long
096       */
097      public static int upper32(long value) {
098        return (int) (value >>> 32);
099      }
100    
101      /**
102       * Does a long literal val fit in bits bits?
103       */
104      public static boolean fits(long val, int bits) {
105        val = val >> bits - 1;
106        return (val == 0L || val == -1L);
107      }
108    
109      /**
110       * Does an offset literal val fit in bits bits?
111       */
112      public static boolean fits(Offset val, int bits) {
113        return (VM.BuildFor32Addr) ? fits(val.toInt(), bits) : fits(val.toLong(), bits);
114      }
115    
116      /**
117       * Does an address literal val fit in bits bits?
118       */
119      public static boolean fits(Address val, int bits) {
120        return (VM.BuildFor32Addr) ? fits(val.toInt(), bits) : fits(val.toLong(), bits);
121      }
122    
123      /**
124       * Does an int literal val fit in bits bits?
125       */
126      public static boolean fits(int val, int bits) {
127        val = val >> bits - 1;
128        return (val == 0 || val == -1);
129      }
130    }