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.ir.ia32;
014
015 import java.util.Enumeration;
016 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
017 import org.jikesrvm.compilers.opt.ir.IR;
018 import org.jikesrvm.compilers.opt.ir.Operator;
019 import org.jikesrvm.compilers.opt.ir.Register;
020 import org.vmmagic.pragma.Pure;
021
022 /**
023 * This class provides utilities to record defs and uses of physical
024 * registers by IR operators.
025 */
026 public abstract class PhysicalDefUse {
027
028 // constants used to encode defs/uses of physical registers
029 /** Default empty mask */
030 public static final int mask = 0x0000;
031 /** AF in the eflags is used/defined */
032 public static final int maskAF = 0x0001;
033 /** CF in the eflags is used/defined */
034 public static final int maskCF = 0x0002;
035 /** OF in the eflags is used/defined */
036 public static final int maskOF = 0x0004;
037 /** PF in the eflags is used/defined */
038 public static final int maskPF = 0x0008;
039 /** SF in the eflags is used/defined */
040 public static final int maskSF = 0x0010;
041 /** ZF in the eflags is used/defined */
042 public static final int maskZF = 0x0020;
043 /** C0 in the x87 FPU is used/defined */
044 public static final int maskC0 = 0x0040;
045 /** C1 in the x87 FPU is used/defined */
046 public static final int maskC1 = 0x0080;
047 /** C2 in the x87 FPU is used/defined */
048 public static final int maskC2 = 0x0100;
049 /** C3 in the x87 FPU is used/defined */
050 public static final int maskC3 = 0x0200;
051 /** The processor register is used/defined */
052 public static final int maskTR = 0x0400;
053 /** The ESP register is used/defined */
054 public static final int maskESP= 0x0800;
055 /* Meta mask for the enumeration. */
056 /** First mask bit */
057 private static final int maskHIGH = 0x0800;
058 /** Mask for all bits */
059 private static final int maskALL = 0x0FFF;
060
061 public static final int maskCF_OF = maskCF | maskOF;
062 public static final int maskCF_PF_ZF = maskCF | maskPF | maskZF;
063 public static final int maskCF_OF_PF_SF_ZF = maskCF | maskOF | maskPF | maskSF | maskZF;
064 public static final int maskAF_OF_PF_SF_ZF = maskAF | maskOF | maskPF | maskSF | maskZF;
065 public static final int maskAF_CF_OF_PF_SF_ZF = maskAF | maskCF | maskOF | maskPF | maskSF | maskZF;
066 public static final int maskC0_C1_C2_C3 = maskC0 | maskC1 | maskC2 | maskC3;
067 public static final int maskcallDefs = maskAF_CF_OF_PF_SF_ZF | maskESP;
068 public static final int maskcallUses = maskESP;
069 public static final int maskIEEEMagicUses = mask;
070 /** Uses mask used by dependence graph to show a yield point */
071 public static final int maskTSPUses = maskESP;
072 /** Definitions mask used by dependence graph to show a yield point */
073 public static final int maskTSPDefs = maskAF_CF_OF_PF_SF_ZF | maskTR | maskESP;
074
075 /**
076 * @return whether or not an Operator uses the EFLAGS
077 */
078 public static boolean usesEFLAGS(Operator op) {
079 return (op.implicitUses & maskAF_CF_OF_PF_SF_ZF) != 0;
080 }
081
082 /**
083 * @return whether or not an Operator uses the EFLAGS
084 */
085 public static boolean definesEFLAGS(Operator op) {
086 return (op.implicitDefs & maskAF_CF_OF_PF_SF_ZF) != 0;
087 }
088
089 /**
090 * @return whether or not an Operator implicitly uses or defines ESP
091 */
092 public static boolean usesOrDefinesESP(Operator op) {
093 return ((op.implicitUses & maskESP) != 0) || ((op.implicitDefs & maskESP) != 0);
094 }
095 /**
096 * @return a string representation of the physical registers encoded by
097 * an integer
098 */
099 @Pure
100 public static String getString(int code) {
101 if (code == mask) return "";
102 if (code == maskAF_CF_OF_PF_SF_ZF) return " AF CF OF PF SF ZF";
103 // Not a common case, construct it...
104 String s = "";
105 if ((code & maskAF) != 0) s += " AF";
106 if ((code & maskCF) != 0) s += " CF";
107 if ((code & maskOF) != 0) s += " OF";
108 if ((code & maskPF) != 0) s += " PF";
109 if ((code & maskZF) != 0) s += " ZF";
110 if ((code & maskC0) != 0) s += " CO";
111 if ((code & maskC1) != 0) s += " C1";
112 if ((code & maskC2) != 0) s += " C2";
113 if ((code & maskC3) != 0) s += " C3";
114 if ((code & maskTR) != 0) s += " TR";
115 if ((code & maskESP) != 0) s += " ESP";
116 return s;
117 }
118
119 /**
120 * @param code an integer that encodes a set of physical registers
121 * @param ir the governing IR
122 * @return an enumeration of the physical registers embodied by a code
123 */
124 public static PDUEnumeration enumerate(int code, IR ir) {
125 return new PDUEnumeration(code, ir);
126 }
127
128 /**
129 * @param ir the governing IR
130 * @return an enumeration of all physical registers that code be
131 * implicitly defed/used
132 */
133 public static PDUEnumeration enumerateAllImplicitDefUses(IR ir) {
134 return new PDUEnumeration(maskALL, ir);
135 }
136
137 /**
138 * A class to enumerate physical registers based on a code.
139 */
140 public static final class PDUEnumeration implements Enumeration<Register> {
141 private int code;
142 private int curMask;
143 private PhysicalRegisterSet phys;
144
145 PDUEnumeration(int c, IR ir) {
146 phys = ir.regpool.getPhysicalRegisterSet();
147 code = c;
148 curMask = maskHIGH;
149 }
150
151 public boolean hasMoreElements() {
152 return code != 0;
153 }
154
155 public Register nextElement() {
156 while (true) {
157 int curBit = code & curMask;
158 code -= curBit;
159 curMask = curMask >> 1;
160 if (curBit != 0) return getReg(curBit, phys);
161 }
162 }
163
164 // artifically make static to enable scalar replacement of
165 // enumeration object without requiring this method to be inlined.
166 private static Register getReg(int m, PhysicalRegisterSet phys) {
167 switch (m) {
168 case maskAF:
169 return phys.getAF();
170 case maskCF:
171 return phys.getCF();
172 case maskOF:
173 return phys.getOF();
174 case maskPF:
175 return phys.getPF();
176 case maskSF:
177 return phys.getSF();
178 case maskZF:
179 return phys.getZF();
180 case maskC0:
181 return phys.getC0();
182 case maskC1:
183 return phys.getC1();
184 case maskC2:
185 return phys.getC2();
186 case maskC3:
187 return phys.getC3();
188 case maskTR:
189 return phys.getTR();
190 case maskESP:
191 return phys.getESP();
192 }
193 OptimizingCompilerException.UNREACHABLE();
194 return null; // placate jikes.
195 }
196 }
197 }