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.lir2mir.ia32;
014
015 import java.util.Enumeration;
016
017 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
018 import org.jikesrvm.compilers.opt.Simplifier;
019 import org.jikesrvm.compilers.opt.driver.CompilerPhase;
020 import org.jikesrvm.compilers.opt.ir.CondMove;
021 import org.jikesrvm.compilers.opt.ir.IR;
022 import org.jikesrvm.compilers.opt.ir.Instruction;
023 import org.jikesrvm.compilers.opt.ir.InstructionEnumeration;
024 import org.jikesrvm.compilers.opt.ir.Operators;
025 import org.jikesrvm.ia32.ArchConstants;
026
027 /**
028 * Reduce the number of ALU operators considered by BURS
029 */
030 public class ConvertALUOperators extends CompilerPhase implements Operators, ArchConstants {
031
032 @Override
033 public final String getName() { return "ConvertALUOps"; }
034
035 /**
036 * Return this instance of this phase. This phase contains no
037 * per-compilation instance fields.
038 * @param ir not used
039 * @return this
040 */
041 @Override
042 public CompilerPhase newExecution(IR ir) {
043 return this;
044 }
045
046 @Override
047 public final void perform(IR ir) {
048 // Calling Simplifier.simplify ensures that the instruction is
049 // in normalized form. This reduces the number of cases we have to
050 // worry about (and does last minute constant folding on the off
051 // chance we've missed an opportunity...)
052 // BURS assumes that this has been done
053 for (InstructionEnumeration instrs = ir.forwardInstrEnumerator(); instrs.hasMoreElements();) {
054 Instruction s = instrs.next();
055 Simplifier.simplify(false, ir.regpool, ir.options, s);
056 }
057
058 // Pass over instructions
059 for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements();) {
060 Instruction s = e.nextElement();
061
062 switch (s.getOpcode()) {
063 case REF_ADD_opcode:
064 s.operator = INT_ADD;
065 break;
066 case REF_SUB_opcode:
067 s.operator = INT_SUB;
068 break;
069 case REF_NEG_opcode:
070 s.operator = INT_NEG;
071 break;
072 case REF_NOT_opcode:
073 s.operator = INT_NOT;
074 break;
075 case REF_AND_opcode:
076 s.operator = INT_AND;
077 break;
078 case REF_OR_opcode:
079 s.operator = INT_OR;
080 break;
081 case REF_XOR_opcode:
082 s.operator = INT_XOR;
083 break;
084 case REF_SHL_opcode:
085 s.operator = INT_SHL;
086 break;
087 case REF_SHR_opcode:
088 s.operator = INT_SHR;
089 break;
090 case REF_USHR_opcode:
091 s.operator = INT_USHR;
092 break;
093
094 // BURS doesn't really care, so consolidate to reduce rule space
095 case BOOLEAN_CMP_ADDR_opcode:
096 s.operator = BOOLEAN_CMP_INT;
097 break;
098
099 // BURS doesn't really care, so consolidate to reduce rule space
100 case FLOAT_ADD_opcode:
101 if (!SSE2_FULL)
102 s.operator = FP_ADD;
103 break;
104 case DOUBLE_ADD_opcode:
105 if (!SSE2_FULL)
106 s.operator = FP_ADD;
107 break;
108 case FLOAT_SUB_opcode:
109 if (!SSE2_FULL)
110 s.operator = FP_SUB;
111 break;
112 case DOUBLE_SUB_opcode:
113 if (!SSE2_FULL)
114 s.operator = FP_SUB;
115 break;
116 case FLOAT_MUL_opcode:
117 if (!SSE2_FULL)
118 s.operator = FP_MUL;
119 break;
120 case DOUBLE_MUL_opcode:
121 if (!SSE2_FULL)
122 s.operator = FP_MUL;
123 break;
124 case FLOAT_DIV_opcode:
125 if (!SSE2_FULL)
126 s.operator = FP_DIV;
127 break;
128 case DOUBLE_DIV_opcode:
129 if (!SSE2_FULL)
130 s.operator = FP_DIV;
131 break;
132 case FLOAT_REM_opcode:
133 if (!SSE2_FULL)
134 s.operator = FP_REM;
135 break;
136 case DOUBLE_REM_opcode:
137 if (!SSE2_FULL)
138 s.operator = FP_REM;
139 break;
140 case FLOAT_NEG_opcode:
141 if (!SSE2_FULL)
142 s.operator = FP_NEG;
143 break;
144 case DOUBLE_NEG_opcode:
145 if (!SSE2_FULL)
146 s.operator = FP_NEG;
147 break;
148
149 // BURS doesn't really care, so consolidate to reduce rule space
150 case INT_COND_MOVE_opcode:
151 case REF_COND_MOVE_opcode:
152 s.operator = CondMove.getCond(s).isFLOATINGPOINT() ? FCMP_CMOV : (CondMove.getVal1(s).isLong() ? LCMP_CMOV : CMP_CMOV);
153 break;
154 case FLOAT_COND_MOVE_opcode:
155 case DOUBLE_COND_MOVE_opcode:
156 s.operator = CondMove.getCond(s).isFLOATINGPOINT() ? FCMP_FCMOV : CMP_FCMOV;
157 break;
158
159 case GUARD_COND_MOVE_opcode:
160 case LONG_COND_MOVE_opcode:
161 OptimizingCompilerException.TODO("Unimplemented conversion" + s);
162 break;
163
164 // BURS doesn't really care, so consolidate to reduce rule space
165 case INT_2FLOAT_opcode:
166 if (!SSE2_FULL)
167 s.operator = INT_2FP;
168 break;
169 case INT_2DOUBLE_opcode:
170 if (!SSE2_FULL)
171 s.operator = INT_2FP;
172 break;
173 case LONG_2FLOAT_opcode:
174 if (!SSE2_FULL)
175 s.operator = LONG_2FP;
176 break;
177 case LONG_2DOUBLE_opcode:
178 if (!SSE2_FULL)
179 s.operator = LONG_2FP;
180 break;
181
182 // BURS doesn't really care, so consolidate to reduce rule space
183 case REF_LOAD_opcode:
184 s.operator = INT_LOAD;
185 break;
186 case REF_STORE_opcode:
187 s.operator = INT_STORE;
188 break;
189 case REF_ALOAD_opcode:
190 s.operator = INT_ALOAD;
191 break;
192 case REF_ASTORE_opcode:
193 s.operator = INT_ASTORE;
194 break;
195 case REF_MOVE_opcode:
196 s.operator = INT_MOVE;
197 break;
198 case REF_IFCMP_opcode:
199 s.operator = INT_IFCMP;
200 break;
201 case ATTEMPT_ADDR_opcode:
202 s.operator = ATTEMPT_INT;
203 break;
204 case PREPARE_ADDR_opcode:
205 s.operator = PREPARE_INT;
206 break;
207 case INT_2ADDRSigExt_opcode:
208 s.operator = INT_MOVE;
209 break;
210 case INT_2ADDRZerExt_opcode:
211 s.operator = INT_MOVE;
212 break;
213 case ADDR_2INT_opcode:
214 s.operator = INT_MOVE;
215 break;
216 case LONG_2ADDR_opcode:
217 s.operator = LONG_2INT;
218 break;
219 }
220 }
221 }
222 }