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