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.compilers.opt.ir;
014
015import java.util.Enumeration;
016import org.jikesrvm.compilers.opt.ir.operand.Operand;
017import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand;
018
019/**
020 * This abstract class provides a set of useful architecture-independent
021 * methods for manipulating physical registers for an IR.
022 */
023public abstract class GenericPhysicalRegisterTools extends IRTools {
024
025  public abstract IR getIR();
026
027  /**
028   * Create an address register operand for a given physical GPR.
029   * To be used in passthrough expressions like
030   * <pre>
031   *    ... Load.create(INT_LOAD, I(2), A(1), IC(4)) ...
032   * </pre>
033   *
034   * @param regnum the given GPR register number
035   * @return integer register operand
036   */
037  protected final RegisterOperand A(int regnum) {
038    GenericPhysicalRegisterSet phys = getIR().regpool.getPhysicalRegisterSet();
039    return A(phys.getGPR(regnum));
040  }
041
042  /**
043   * Create an integer register operand for a given physical GPR.
044   * To be used in passthrough expressions like
045   * <pre>
046   *    ... Load.create(INT_LOAD, I(2), A(1), IC(4)) ...
047   * </pre>
048   *
049   * @param regnum the given GPR register number
050   * @return integer register operand
051   */
052  protected final RegisterOperand I(int regnum) {
053    GenericPhysicalRegisterSet phys = getIR().regpool.getPhysicalRegisterSet();
054    return I(phys.getGPR(regnum));
055  }
056
057  /**
058   * Create a float register operand for a given physical FPR.
059   * To be used in passthrough expressions like
060   * <pre>
061   *    ... Load.create(FLOAT_LOAD, F(2), A(1), IC(4)) ...
062   * </pre>
063   *
064   * @param regnum the given DOUBLE register number
065   * @return float register operand
066   */
067  final RegisterOperand F(int regnum) {
068    GenericPhysicalRegisterSet phys = getIR().regpool.getPhysicalRegisterSet();
069    return F(phys.getFPR(regnum));
070  }
071
072  /**
073   * Create a double register operand for a given physical FPR.
074   * To be used in passthrough expressions like
075   * <pre>
076   *    ... Load.create(DOUBLE_LOAD, D(2), A(1), IC(4)) ...
077   * </pre>
078   *
079   * @param regnum the given double register number
080   * @return double register operand
081   */
082  final RegisterOperand D(int regnum) {
083    GenericPhysicalRegisterSet phys = getIR().regpool.getPhysicalRegisterSet();
084    return D(phys.getFPR(regnum));
085  }
086
087  /**
088   * Create a long register operand for a given GPR number.
089   * To be used in passthrough expressions like
090   * <pre>
091   *    ... Load.create(LONG_LOAD, L(2), A(1), IC(4)) ...
092   * </pre>
093   *
094   * @param regnum the given GPR register number
095   * @return long register operand
096   */
097  final RegisterOperand L(int regnum) {
098    GenericPhysicalRegisterSet phys = getIR().regpool.getPhysicalRegisterSet();
099    return L(phys.getGPR(regnum));
100  }
101
102  /**
103   * @param s the instruction to check
104   * @return {@code true} if the instruction  has an operand that contains a physical register
105   */
106  static boolean hasPhysicalOperand(Instruction s) {
107    for (Enumeration<Operand> e = s.getOperands(); e.hasMoreElements();) {
108      Operand op = e.nextElement();
109      if (op == null) continue;
110      if (op.isRegister()) {
111        if (op.asRegister().getRegister().isPhysical()) {
112          return true;
113        }
114      }
115    }
116    return false;
117  }
118}