/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.jikesrvm.compilers.opt.lir2mir.ia32;
import java.util.Enumeration;
import org.jikesrvm.compilers.opt.OptimizingCompilerException;
import org.jikesrvm.compilers.opt.Simplifier;
import org.jikesrvm.compilers.opt.driver.CompilerPhase;
import org.jikesrvm.compilers.opt.ir.CondMove;
import org.jikesrvm.compilers.opt.ir.IR;
import org.jikesrvm.compilers.opt.ir.Instruction;
import org.jikesrvm.compilers.opt.ir.InstructionEnumeration;
import org.jikesrvm.compilers.opt.ir.Operators;
import org.jikesrvm.ia32.ArchConstants;
/**
* Reduce the number of ALU operators considered by BURS
*/
public class ConvertALUOperators extends CompilerPhase implements Operators, ArchConstants {
@Override
public final String getName() { return "ConvertALUOps"; }
/**
* Return this instance of this phase. This phase contains no
* per-compilation instance fields.
* @param ir not used
* @return this
*/
@Override
public CompilerPhase newExecution(IR ir) {
return this;
}
@Override
public final void perform(IR ir) {
// Calling Simplifier.simplify ensures that the instruction is
// in normalized form. This reduces the number of cases we have to
// worry about (and does last minute constant folding on the off
// chance we've missed an opportunity...)
// BURS assumes that this has been done
for (InstructionEnumeration instrs = ir.forwardInstrEnumerator(); instrs.hasMoreElements();) {
Instruction s = instrs.next();
Simplifier.simplify(false, ir.regpool, ir.options, s);
}
// Pass over instructions
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements();) {
Instruction s = e.nextElement();
switch (s.getOpcode()) {
case REF_ADD_opcode:
s.operator = INT_ADD;
break;
case REF_SUB_opcode:
s.operator = INT_SUB;
break;
case REF_NEG_opcode:
s.operator = INT_NEG;
break;
case REF_NOT_opcode:
s.operator = INT_NOT;
break;
case REF_AND_opcode:
s.operator = INT_AND;
break;
case REF_OR_opcode:
s.operator = INT_OR;
break;
case REF_XOR_opcode:
s.operator = INT_XOR;
break;
case REF_SHL_opcode:
s.operator = INT_SHL;
break;
case REF_SHR_opcode:
s.operator = INT_SHR;
break;
case REF_USHR_opcode:
s.operator = INT_USHR;
break;
// BURS doesn't really care, so consolidate to reduce rule space
case BOOLEAN_CMP_ADDR_opcode:
s.operator = BOOLEAN_CMP_INT;
break;
// BURS doesn't really care, so consolidate to reduce rule space
case FLOAT_ADD_opcode:
if (!SSE2_FULL)
s.operator = FP_ADD;
break;
case DOUBLE_ADD_opcode:
if (!SSE2_FULL)
s.operator = FP_ADD;
break;
case FLOAT_SUB_opcode:
if (!SSE2_FULL)
s.operator = FP_SUB;
break;
case DOUBLE_SUB_opcode:
if (!SSE2_FULL)
s.operator = FP_SUB;
break;
case FLOAT_MUL_opcode:
if (!SSE2_FULL)
s.operator = FP_MUL;
break;
case DOUBLE_MUL_opcode:
if (!SSE2_FULL)
s.operator = FP_MUL;
break;
case FLOAT_DIV_opcode:
if (!SSE2_FULL)
s.operator = FP_DIV;
break;
case DOUBLE_DIV_opcode:
if (!SSE2_FULL)
s.operator = FP_DIV;
break;
case FLOAT_REM_opcode:
if (!SSE2_FULL)
s.operator = FP_REM;
break;
case DOUBLE_REM_opcode:
if (!SSE2_FULL)
s.operator = FP_REM;
break;
case FLOAT_NEG_opcode:
if (!SSE2_FULL)
s.operator = FP_NEG;
break;
case DOUBLE_NEG_opcode:
if (!SSE2_FULL)
s.operator = FP_NEG;
break;
// BURS doesn't really care, so consolidate to reduce rule space
case INT_COND_MOVE_opcode:
case REF_COND_MOVE_opcode:
s.operator = CondMove.getCond(s).isFLOATINGPOINT() ? FCMP_CMOV : (CondMove.getVal1(s).isLong() ? LCMP_CMOV : CMP_CMOV);
break;
case FLOAT_COND_MOVE_opcode:
case DOUBLE_COND_MOVE_opcode:
s.operator = CondMove.getCond(s).isFLOATINGPOINT() ? FCMP_FCMOV : CMP_FCMOV;
break;
case GUARD_COND_MOVE_opcode:
case LONG_COND_MOVE_opcode:
OptimizingCompilerException.TODO("Unimplemented conversion" + s);
break;
// BURS doesn't really care, so consolidate to reduce rule space
case INT_2FLOAT_opcode:
if (!SSE2_FULL)
s.operator = INT_2FP;
break;
case INT_2DOUBLE_opcode:
if (!SSE2_FULL)
s.operator = INT_2FP;
break;
case LONG_2FLOAT_opcode:
if (!SSE2_FULL)
s.operator = LONG_2FP;
break;
case LONG_2DOUBLE_opcode:
if (!SSE2_FULL)
s.operator = LONG_2FP;
break;
// BURS doesn't really care, so consolidate to reduce rule space
case REF_LOAD_opcode:
s.operator = INT_LOAD;
break;
case REF_STORE_opcode:
s.operator = INT_STORE;
break;
case REF_ALOAD_opcode:
s.operator = INT_ALOAD;
break;
case REF_ASTORE_opcode:
s.operator = INT_ASTORE;
break;
case REF_MOVE_opcode:
s.operator = INT_MOVE;
break;
case REF_IFCMP_opcode:
s.operator = INT_IFCMP;
break;
case ATTEMPT_ADDR_opcode:
s.operator = ATTEMPT_INT;
break;
case PREPARE_ADDR_opcode:
s.operator = PREPARE_INT;
break;
case INT_2ADDRSigExt_opcode:
s.operator = INT_MOVE;
break;
case INT_2ADDRZerExt_opcode:
s.operator = INT_MOVE;
break;
case ADDR_2INT_opcode:
s.operator = INT_MOVE;
break;
case LONG_2ADDR_opcode:
s.operator = LONG_2INT;
break;
}
}
}
}