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