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 @Override 152 public boolean hasMoreElements() { 153 return code != 0; 154 } 155 156 @Override 157 public Register nextElement() { 158 while (true) { 159 int curBit = code & curMask; 160 code -= curBit; 161 curMask = curMask >> 1; 162 if (curBit != 0) return getReg(curBit, phys); 163 } 164 } 165 166 // Artificially make static to enable scalar replacement of 167 // enumeration object without requiring this method to be inlined. 168 private static Register getReg(int m, PhysicalRegisterSet phys) { 169 switch (m) { 170 case maskAF: 171 return phys.getAF(); 172 case maskCF: 173 return phys.getCF(); 174 case maskOF: 175 return phys.getOF(); 176 case maskPF: 177 return phys.getPF(); 178 case maskSF: 179 return phys.getSF(); 180 case maskZF: 181 return phys.getZF(); 182 case maskC0: 183 return phys.getC0(); 184 case maskC1: 185 return phys.getC1(); 186 case maskC2: 187 return phys.getC2(); 188 case maskC3: 189 return phys.getC3(); 190 case maskTR: 191 return phys.getTR(); 192 case maskESP: 193 return phys.getESP(); 194 } 195 OptimizingCompilerException.UNREACHABLE(); 196 return null; 197 } 198 } 199 }