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    }