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.architecture.MachineRegister;
017import org.jikesrvm.VM;
018import org.jikesrvm.compilers.opt.util.BitSetMapping;
019import org.jikesrvm.compilers.opt.util.ReverseEnumerator;
020
021/**
022 * This class represents a set of Registers corresponding to the
023 * physical register set. This class holds the architecture-independent
024 * functionality
025 *
026 * <P> Implementation Note: Each register has an integer field
027 * Register.number.  This class must number the physical registers so
028 * that get(n) returns an Register r with r.number = n!
029 */
030public abstract class GenericPhysicalRegisterSet implements BitSetMapping {
031  /**
032   * @return the total number of physical registers
033   */
034  public static int getSize() {
035    if (VM.BuildForIA32) {
036      return org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet.getSize();
037    } else {
038      if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC);
039      return org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet.getSize();
040    }
041  }
042
043  /**
044   * @param regnum the number of the register in question
045   * @return the register name for a register with a particular number in the
046   * pool
047   */
048  public static String getName(int regnum) {
049    if (VM.BuildForIA32) {
050      return org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet.getName(regnum);
051    } else {
052      if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC);
053      return org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet.getName(regnum);
054    }
055  }
056
057  public static int getPhysicalRegisterType(Register symbReg) {
058    if (VM.BuildForIA32) {
059      return org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet.getPhysicalRegisterType(symbReg);
060    } else {
061      if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC);
062      return org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet.getPhysicalRegisterType(symbReg);
063    }
064  }
065
066  public static int getSpillSize(int type) {
067    if (VM.BuildForIA32) {
068      return org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet.getSpillSize(type);
069    } else {
070      if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC);
071      return org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet.getSpillSize(type);
072    }
073  }
074
075  public org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet asIA32() {
076    return (org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)this;
077  }
078
079  public org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet asPPC() {
080    return (org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet)this;
081  }
082
083  /**
084   * @param p the register in question
085   * @return whether the register is subject to allocation
086   */
087  public abstract boolean isAllocatable(Register p);
088
089  /**
090   * @return the total number of physical registers.
091   */
092  public abstract int getNumberOfPhysicalRegisters();
093
094  /**
095   * @return the FP register
096   */
097  public abstract Register getFP();
098
099  /**
100   * @return the thread register
101   */
102  public abstract Register getTR();
103
104  public abstract Register getGPR(int n);
105
106  /**
107   * @param n a register
108   * @return the physical GPR corresponding to n
109   */
110  public abstract Register getGPR(MachineRegister n);
111
112  /**
113   * @return the first GPR return
114   */
115  public abstract Register getFirstReturnGPR();
116
117  public abstract Register getFPR(int n);
118
119  /**
120   * @param n register number
121   * @return the nth physical register in the pool.
122   */
123  public abstract Register get(int n);
124
125  public abstract Enumeration<Register> enumerateAll();
126
127  public abstract Enumeration<Register> enumerateGPRs();
128
129  public abstract Enumeration<Register> enumerateVolatileGPRs();
130
131  public abstract Enumeration<Register> enumerateNonvolatileGPRs();
132
133  public abstract Enumeration<Register> enumerateVolatileFPRs();
134
135  public abstract Enumeration<Register> enumerateNonvolatileFPRs();
136
137  public abstract Enumeration<Register> enumerateVolatiles();
138
139  public abstract Enumeration<Register> enumerateVolatiles(int type);
140
141  public abstract Enumeration<Register> enumerateNonvolatilesBackwards(int type);
142
143  public Enumeration<Register> enumerateNonvolatileGPRsBackwards() {
144    return new ReverseEnumerator<Register>(enumerateNonvolatileGPRs());
145  }
146
147  public Enumeration<Register> enumerateNonvolatileFPRsBackwards() {
148    return new ReverseEnumerator<Register>(enumerateNonvolatileFPRs());
149  }
150
151  @Override
152  public final Object getMappedObject(int n) {
153    return get(n);
154  }
155
156  @Override
157  public final int getMappedIndex(Object o) {
158    Register r = (Register) o;
159    return r.number;
160  }
161
162  @Override
163  public final int getMappingSize() {
164    return getNumberOfPhysicalRegisters();
165  }
166}