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