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.ppc;
014
015import java.util.Enumeration;
016import org.jikesrvm.VM;
017import org.jikesrvm.compilers.opt.ir.IR;
018import org.jikesrvm.compilers.opt.ir.Register;
019
020/**
021 * This class provides utilities to record defs and uses of physical
022 * registers by IR operators.
023 */
024public final class PhysicalDefUse {
025
026  // constants used to encode defs/uses of physical registers
027  public static final int mask = 0x00;  // empty mask
028  public static final int maskC0 = 0x01;
029  public static final int maskXER = 0x02;
030  public static final int maskLR = 0x04;
031  public static final int maskJTOC = 0x08;
032  public static final int maskCTR = 0x10;
033  public static final int maskTR = 0x20;
034
035  // Meta mask for the enumeration.
036  private static final int maskHIGH = 0x20;
037  private static final int maskALL = 0x3F;
038
039  public static final int maskC0_XER = maskC0 | maskXER;
040  public static final int maskJTOC_LR = maskJTOC | maskLR;
041  public static final int maskJTOC_CTR = maskJTOC | maskCTR;
042  public static final int maskcallDefs = maskLR;
043  public static final int maskcallUses = maskJTOC;
044  public static final int maskIEEEMagicUses = maskJTOC;
045  public static final int maskTSPDefs = maskTR;
046  public static final int maskTSPUses = maskJTOC;
047
048  /** XER mask on 32bit otherwise no mask */
049  public static final int maskXER_32 = VM.BuildFor32Addr ? maskXER : mask;
050  /** C0 mask on 32bit otherwise no mask */
051  public static final int maskC0_32 = VM.BuildFor32Addr ? maskC0 : mask;
052
053  /**
054   * @param code register code
055   * @return a string representation of the physical registers encoded by
056   * an integer
057   */
058  public static String getString(int code) {
059    if (code == mask) return "";
060    // Not a common case, construct it...
061    String s = "";
062    if ((code & maskC0) != 0) s += " C0";
063    if ((code & maskXER) != 0) s += " XER";
064    if ((code & maskLR) != 0) s += " LR";
065    if ((code & maskJTOC) != 0) s += " JTOC";
066    if ((code & maskCTR) != 0) s += " CTR";
067    if ((code & maskTR) != 0) s += " TR";
068    return s;
069  }
070
071  /**
072   * @param code an integer that encodes a set of physical registers
073   * @param ir the governing IR
074   * @return an enumeration of the physical registers embodied by a code
075   */
076  public static PDUEnumeration enumerate(int code, IR ir) {
077    return new PDUEnumeration(code, ir);
078  }
079
080  /**
081   * @param ir the governing IR
082   * @return an enumeration of all physical registers that code be
083   *         implicitly defed/used
084   */
085  public static PDUEnumeration enumerateAllImplicitDefUses(IR ir) {
086    return new PDUEnumeration(maskALL, ir);
087  }
088
089  /**
090   * A class to enumerate physical registers based on a code.
091   */
092  public static final class PDUEnumeration implements Enumeration<Register> {
093    private int code;
094    private int curMask;
095    private final PhysicalRegisterSet phys;
096
097    PDUEnumeration(int c, IR ir) {
098      phys = (PhysicalRegisterSet)ir.regpool.getPhysicalRegisterSet();
099      code = c;
100      curMask = maskHIGH;
101    }
102
103    @Override
104    public boolean hasMoreElements() {
105      return code != 0;
106    }
107
108    @Override
109    public Register nextElement() {
110      while (true) {
111        int curBit = code & curMask;
112        code -= curBit;
113        curMask = curMask >> 1;
114        if (curBit != 0) return getReg(curBit, phys);
115      }
116    }
117
118    // artifically make static to enable scalar replacement of
119    // enumeration object without requiring this method to be inlined.
120    private static Register getReg(int m, PhysicalRegisterSet phys) {
121      switch (m) {
122        case maskC0:
123          return phys.getConditionRegister(0);
124        case maskXER:
125          return phys.getXER();
126        case maskLR:
127          return phys.getLR();
128        case maskJTOC:
129          return phys.getJTOC();
130        case maskCTR:
131          return phys.getCTR();
132        case maskTR:
133          return phys.getTR();
134      }
135      org.jikesrvm.compilers.opt.OptimizingCompilerException.UNREACHABLE();
136      return null;
137    }
138  }
139}