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