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.ia32; 014 015import java.util.Enumeration; 016import org.jikesrvm.compilers.opt.OptimizingCompilerException; 017import org.jikesrvm.compilers.opt.ir.IR; 018import org.jikesrvm.compilers.opt.ir.Operator; 019import org.jikesrvm.compilers.opt.ir.Register; 020import org.vmmagic.pragma.Pure; 021 022/** 023 * This class provides utilities to record defs and uses of physical 024 * registers by IR operators. 025 */ 026public 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 public static boolean usesEFLAGS(Operator op) { 076 return (op.implicitUses & maskAF_CF_OF_PF_SF_ZF) != 0; 077 } 078 079 public static boolean definesEFLAGS(Operator op) { 080 return (op.implicitDefs & maskAF_CF_OF_PF_SF_ZF) != 0; 081 } 082 083 public static boolean usesOrDefinesESP(Operator op) { 084 return ((op.implicitUses & maskESP) != 0) || ((op.implicitDefs & maskESP) != 0); 085 } 086 087 /** 088 * @param code the encoding of physical registers 089 * @return a string representation of the physical registers encoded by 090 * an integer 091 */ 092 @Pure 093 public static String getString(int code) { 094 if (code == mask) return ""; 095 if (code == maskAF_CF_OF_PF_SF_ZF) return " AF CF OF PF SF ZF"; 096 // Not a common case, construct it... 097 String s = ""; 098 if ((code & maskAF) != 0) s += " AF"; 099 if ((code & maskCF) != 0) s += " CF"; 100 if ((code & maskOF) != 0) s += " OF"; 101 if ((code & maskPF) != 0) s += " PF"; 102 if ((code & maskZF) != 0) s += " ZF"; 103 if ((code & maskC0) != 0) s += " CO"; 104 if ((code & maskC1) != 0) s += " C1"; 105 if ((code & maskC2) != 0) s += " C2"; 106 if ((code & maskC3) != 0) s += " C3"; 107 if ((code & maskTR) != 0) s += " TR"; 108 if ((code & maskESP) != 0) s += " ESP"; 109 return s; 110 } 111 112 /** 113 * @param code an integer that encodes a set of physical registers 114 * @param ir the governing IR 115 * @return an enumeration of the physical registers embodied by a code 116 */ 117 public static PDUEnumeration enumerate(int code, IR ir) { 118 return new PDUEnumeration(code, ir); 119 } 120 121 /** 122 * @param ir the governing IR 123 * @return an enumeration of all physical registers that code be 124 * implicitly defed/used 125 */ 126 public static PDUEnumeration enumerateAllImplicitDefUses(IR ir) { 127 return new PDUEnumeration(maskALL, ir); 128 } 129 130 /** 131 * A class to enumerate physical registers based on a code. 132 */ 133 public static final class PDUEnumeration implements Enumeration<Register> { 134 private int code; 135 private int curMask; 136 private final PhysicalRegisterSet phys; 137 138 PDUEnumeration(int c, IR ir) { 139 phys = (PhysicalRegisterSet)ir.regpool.getPhysicalRegisterSet(); 140 code = c; 141 curMask = maskHIGH; 142 } 143 144 @Override 145 public boolean hasMoreElements() { 146 return code != 0; 147 } 148 149 @Override 150 public Register nextElement() { 151 while (true) { 152 int curBit = code & curMask; 153 code -= curBit; 154 curMask = curMask >> 1; 155 if (curBit != 0) return getReg(curBit, phys); 156 } 157 } 158 159 // Artificially make static to enable scalar replacement of 160 // enumeration object without requiring this method to be inlined. 161 private static Register getReg(int m, PhysicalRegisterSet phys) { 162 switch (m) { 163 case maskAF: 164 return phys.getAF(); 165 case maskCF: 166 return phys.getCF(); 167 case maskOF: 168 return phys.getOF(); 169 case maskPF: 170 return phys.getPF(); 171 case maskSF: 172 return phys.getSF(); 173 case maskZF: 174 return phys.getZF(); 175 case maskC0: 176 return phys.getC0(); 177 case maskC1: 178 return phys.getC1(); 179 case maskC2: 180 return phys.getC2(); 181 case maskC3: 182 return phys.getC3(); 183 case maskTR: 184 return phys.getTR(); 185 case maskESP: 186 return phys.getESP(); 187 } 188 OptimizingCompilerException.UNREACHABLE(); 189 return null; 190 } 191 } 192}