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.operand.ia32; 014 015 import org.jikesrvm.compilers.common.assembler.ia32.AssemblerConstants; 016 import org.jikesrvm.compilers.opt.OptimizingCompilerException; 017 import org.jikesrvm.compilers.opt.ir.operand.ConditionOperand; 018 import org.jikesrvm.compilers.opt.ir.operand.Operand; 019 020 /** 021 * An IA32 condition operand 022 */ 023 public final class IA32ConditionOperand extends Operand implements AssemblerConstants { 024 025 /** 026 * Value of this operand (one of the ConditionCode constants operands 027 * defined in AssemblerConstants) 028 */ 029 public byte value; 030 031 @Override 032 public Operand copy() { 033 return new IA32ConditionOperand(value); 034 } 035 036 @Override 037 public boolean similar(Operand op) { 038 return (op instanceof IA32ConditionOperand) && ((IA32ConditionOperand) op).value == value; 039 } 040 041 /** 042 * flip the direction of the condition (return this, mutated to flip value) 043 */ 044 public IA32ConditionOperand flipCode() { 045 switch (value) { 046 case O: 047 value = NO; 048 break; 049 case NO: 050 value = O; 051 break; 052 case LLT: 053 value = LGE; 054 break; 055 case LGE: 056 value = LLT; 057 break; 058 case EQ: 059 value = NE; 060 break; 061 case NE: 062 value = EQ; 063 break; 064 case LLE: 065 value = LGT; 066 break; 067 case LGT: 068 value = LLE; 069 break; 070 case S: 071 value = NS; 072 break; 073 case NS: 074 value = S; 075 break; 076 case PE: 077 value = PO; 078 break; 079 case PO: 080 value = PE; 081 break; 082 case LT: 083 value = GE; 084 break; 085 case GE: 086 value = LT; 087 break; 088 case LE: 089 value = GT; 090 break; 091 case GT: 092 value = LE; 093 break; 094 default: 095 OptimizingCompilerException.UNREACHABLE(); 096 } 097 return this; 098 } 099 100 /** 101 * change the condition when operands are flipped 102 * (return this mutated to change value) 103 */ 104 public IA32ConditionOperand flipOperands() { 105 switch (value) { 106 case LLT: 107 value = LGT; 108 break; 109 case LGE: 110 value = LLE; 111 break; 112 case LLE: 113 value = LGE; 114 break; 115 case LGT: 116 value = LLT; 117 break; 118 case LT: 119 value = GT; 120 break; 121 case GE: 122 value = LE; 123 break; 124 case LE: 125 value = GE; 126 break; 127 case GT: 128 value = LT; 129 break; 130 default: 131 OptimizingCompilerException.TODO(); 132 } 133 return this; 134 } 135 136 /** 137 * Construct the IA32 Condition Operand that corresponds to the 138 * argument ConditionOperand 139 */ 140 public IA32ConditionOperand(ConditionOperand c) { 141 translate(c); 142 } 143 144 public static IA32ConditionOperand EQ() { 145 return new IA32ConditionOperand(EQ); 146 } 147 148 public static IA32ConditionOperand NE() { 149 return new IA32ConditionOperand(NE); 150 } 151 152 public static IA32ConditionOperand LT() { 153 return new IA32ConditionOperand(LT); 154 } 155 156 public static IA32ConditionOperand LE() { 157 return new IA32ConditionOperand(LE); 158 } 159 160 public static IA32ConditionOperand GT() { 161 return new IA32ConditionOperand(GT); 162 } 163 164 public static IA32ConditionOperand GE() { 165 return new IA32ConditionOperand(GE); 166 } 167 168 public static IA32ConditionOperand O() { 169 return new IA32ConditionOperand(O); 170 } 171 172 public static IA32ConditionOperand NO() { 173 return new IA32ConditionOperand(NO); 174 } 175 176 public static IA32ConditionOperand LGT() { 177 return new IA32ConditionOperand(LGT); 178 } 179 180 public static IA32ConditionOperand LLT() { 181 return new IA32ConditionOperand(LLT); 182 } 183 184 public static IA32ConditionOperand LGE() { 185 return new IA32ConditionOperand(LGE); 186 } 187 188 public static IA32ConditionOperand LLE() { 189 return new IA32ConditionOperand(LLE); 190 } 191 192 public static IA32ConditionOperand PE() { 193 return new IA32ConditionOperand(PE); 194 } 195 196 public static IA32ConditionOperand PO() { 197 return new IA32ConditionOperand(PO); 198 } 199 200 private IA32ConditionOperand(byte c) { 201 value = c; 202 } 203 204 // translate from ConditionOperand: used during LIR => MIR translation 205 private void translate(ConditionOperand c) { 206 switch (c.value) { 207 case ConditionOperand.EQUAL: 208 value = EQ; 209 break; 210 case ConditionOperand.NOT_EQUAL: 211 value = NE; 212 break; 213 case ConditionOperand.LESS: 214 value = LT; 215 break; 216 case ConditionOperand.LESS_EQUAL: 217 value = LE; 218 break; 219 case ConditionOperand.GREATER: 220 value = GT; 221 break; 222 case ConditionOperand.GREATER_EQUAL: 223 value = GE; 224 break; 225 case ConditionOperand.HIGHER: 226 value = LGT; 227 break; 228 case ConditionOperand.LOWER: 229 value = LLT; 230 break; 231 case ConditionOperand.HIGHER_EQUAL: 232 value = LGE; 233 break; 234 case ConditionOperand.LOWER_EQUAL: 235 value = LLE; 236 break; 237 case ConditionOperand.CMPL_EQUAL: 238 case ConditionOperand.CMPL_GREATER: 239 case ConditionOperand.CMPG_LESS: 240 case ConditionOperand.CMPL_GREATER_EQUAL: 241 case ConditionOperand.CMPG_LESS_EQUAL: 242 case ConditionOperand.CMPL_NOT_EQUAL: 243 case ConditionOperand.CMPL_LESS: 244 case ConditionOperand.CMPG_GREATER_EQUAL: 245 case ConditionOperand.CMPG_GREATER: 246 case ConditionOperand.CMPL_LESS_EQUAL: 247 throw new Error("IA32ConditionOperand.translate: Complex operand can't be directly translated " + c); 248 default: 249 OptimizingCompilerException.UNREACHABLE(); 250 } 251 } 252 253 // Returns the string representation of this operand. 254 @Override 255 public String toString() { 256 return CONDITION[value]; 257 } 258 259 }