mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-06-03 07:29:37 +00:00
88 lines
3.8 KiB
Java
88 lines
3.8 KiB
Java
package dk.camelot64.kickc.passes;
|
|
|
|
import dk.camelot64.kickc.model.CompileError;
|
|
import dk.camelot64.kickc.model.ControlFlowBlock;
|
|
import dk.camelot64.kickc.model.Graph;
|
|
import dk.camelot64.kickc.model.Program;
|
|
import dk.camelot64.kickc.model.operators.OperatorUnary;
|
|
import dk.camelot64.kickc.model.operators.Operators;
|
|
import dk.camelot64.kickc.model.statements.Statement;
|
|
import dk.camelot64.kickc.model.statements.StatementAssignment;
|
|
import dk.camelot64.kickc.model.statements.StatementCall;
|
|
import dk.camelot64.kickc.model.values.RValue;
|
|
|
|
import java.util.List;
|
|
import java.util.ListIterator;
|
|
|
|
/**
|
|
* Rewrite BYTE0() / BYTE1() / BYTE2() / BYTE3() calls to special unary operators.
|
|
*/
|
|
public class Pass1ByteXIntrinsicRewrite extends Pass2SsaOptimization {
|
|
|
|
/** The byte0 procedure name. */
|
|
public static final String INTRINSIC_BYTE0_NAME = "BYTE0";
|
|
/** The byte1 procedure name. */
|
|
public static final String INTRINSIC_BYTE1_NAME = "BYTE1";
|
|
/** The byte2 procedure name. */
|
|
public static final String INTRINSIC_BYTE2_NAME = "BYTE2";
|
|
/** The byte3 procedure name. */
|
|
public static final String INTRINSIC_BYTE3_NAME = "BYTE3";
|
|
/** The word0 procedure name. */
|
|
public static final String INTRINSIC_WORD0_NAME = "WORD0";
|
|
/** The word1 procedure name. */
|
|
public static final String INTRINSIC_WORD1_NAME = "WORD1";
|
|
/** The makeword procedure name. */
|
|
public static final String INTRINSIC_MAKEWORD = "MAKEWORD";
|
|
/** The makelong procedure name. */
|
|
public static final String INTRINSIC_MAKELONG = "MAKELONG";
|
|
/** The makelong4 procedure name. */
|
|
public static final String INTRINSIC_MAKELONG4 = "MAKELONG4";
|
|
|
|
public Pass1ByteXIntrinsicRewrite(Program program) {
|
|
super(program);
|
|
}
|
|
|
|
@Override
|
|
public boolean step() {
|
|
for(var block : getGraph().getAllBlocks()) {
|
|
final ListIterator<Statement> stmtIt = block.getStatements().listIterator();
|
|
while(stmtIt.hasNext()) {
|
|
Statement statement = stmtIt.next();
|
|
if(statement instanceof StatementCall) {
|
|
StatementCall call = (StatementCall) statement;
|
|
final List<RValue> parameters = call.getParameters();
|
|
if(INTRINSIC_BYTE0_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.BYTE0);
|
|
} else if(INTRINSIC_BYTE1_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.BYTE1);
|
|
} else if(INTRINSIC_BYTE2_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.BYTE2);
|
|
} else if(INTRINSIC_BYTE3_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.BYTE3);
|
|
} else if(INTRINSIC_WORD0_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.WORD0);
|
|
} else if(INTRINSIC_WORD1_NAME.equals(call.getProcedureName())) {
|
|
generateUnaryOperator(stmtIt, call, parameters, Operators.WORD1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Generate an unary operator expression for the BYTEX()/WORDX()
|
|
*/
|
|
private void generateUnaryOperator(ListIterator<Statement> stmtIt, StatementCall call, List<RValue> parameters, OperatorUnary operator) {
|
|
if(parameters.size()!=1) {
|
|
throw new CompileError("Wrong number of parameters in call " + call.toString(getProgram(), false) + " expected " + 1, call);
|
|
}
|
|
// Remove the call
|
|
stmtIt.remove();
|
|
// Add the unary operator
|
|
stmtIt.add(new StatementAssignment(call.getlValue(), operator, parameters.get(0), call.isInitialAssignment(), call.getSource(), call.getComments()));
|
|
}
|
|
|
|
|
|
}
|