use of com.android.dx.rop.code.Rop in project J2ME-Loader by nikita36078.
the class LiteralOpUpgrader method run.
/**
* Run the literal op upgrader
*/
private void run() {
final TranslationAdvice advice = Optimizer.getAdvice();
ssaMeth.forEachInsn(new SsaInsn.Visitor() {
public void visitMoveInsn(NormalSsaInsn insn) {
// do nothing
}
public void visitPhiInsn(PhiInsn insn) {
// do nothing
}
public void visitNonMoveInsn(NormalSsaInsn insn) {
Insn originalRopInsn = insn.getOriginalRopInsn();
Rop opcode = originalRopInsn.getOpcode();
RegisterSpecList sources = insn.getSources();
// Replace insns with constant results with const insns
if (tryReplacingWithConstant(insn))
return;
if (sources.size() != 2) {
// We're only dealing with two-source insns here.
return;
}
if (opcode.getBranchingness() == Rop.BRANCH_IF) {
/*
* An if instruction can become an if-*z instruction.
*/
if (isConstIntZeroOrKnownNull(sources.get(0))) {
replacePlainInsn(insn, sources.withoutFirst(), RegOps.flippedIfOpcode(opcode.getOpcode()), null);
} else if (isConstIntZeroOrKnownNull(sources.get(1))) {
replacePlainInsn(insn, sources.withoutLast(), opcode.getOpcode(), null);
}
} else if (advice.hasConstantOperation(opcode, sources.get(0), sources.get(1))) {
insn.upgradeToLiteral();
} else if (opcode.isCommutative() && advice.hasConstantOperation(opcode, sources.get(1), sources.get(0))) {
/*
* An instruction can be commuted to a literal operation
*/
insn.setNewSources(RegisterSpecList.make(sources.get(1), sources.get(0)));
insn.upgradeToLiteral();
}
}
});
}
use of com.android.dx.rop.code.Rop in project J2ME-Loader by nikita36078.
the class RopTranslator method outputBlock.
/**
* Helper for {@link #outputInstructions}, which does the processing
* and output of one block.
*
* @param block {@code non-null;} the block to process and output
* @param nextLabel {@code >= -1;} the next block that will be processed, or
* {@code -1} if there is no next block
*/
private void outputBlock(BasicBlock block, int nextLabel) {
// Append the code address for this block.
CodeAddress startAddress = addresses.getStart(block);
output.add(startAddress);
// Append the local variable state for the block.
if (locals != null) {
RegisterSpecSet starts = locals.getStarts(block);
output.add(new LocalSnapshot(startAddress.getPosition(), starts));
}
/*
* Choose and append an output instruction for each original
* instruction.
*/
translationVisitor.setBlock(block, addresses.getLast(block));
block.getInsns().forEach(translationVisitor);
// Insert the block end code address.
output.add(addresses.getEnd(block));
// Set up for end-of-block activities.
int succ = block.getPrimarySuccessor();
Insn lastInsn = block.getLastInsn();
if ((succ >= 0) && (succ != nextLabel)) {
/*
* The block has a "primary successor" and that primary
* successor isn't the next block to be output.
*/
Rop lastRop = lastInsn.getOpcode();
if ((lastRop.getBranchingness() == Rop.BRANCH_IF) && (block.getSecondarySuccessor() == nextLabel)) {
/*
* The block ends with an "if" of some sort, and its
* secondary successor (the "then") is in fact the
* next block to output. So, reverse the sense of
* the test, so that we can just emit the next block
* without an interstitial goto.
*/
output.reverseBranch(1, addresses.getStart(succ));
} else {
/*
* Our only recourse is to add a goto here to get the
* flow to be correct.
*/
TargetInsn insn = new TargetInsn(Dops.GOTO, lastInsn.getPosition(), RegisterSpecList.EMPTY, addresses.getStart(succ));
output.add(insn);
}
}
}
use of com.android.dx.rop.code.Rop in project dexmaker by linkedin.
the class Code method compare.
// instructions: branches
/**
* Compare ints or references. If the comparison is true, execution jumps to
* {@code trueLabel}. If it is false, execution continues to the next
* instruction.
*/
public <T> void compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b) {
adopt(trueLabel);
Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType));
addInstruction(new PlainInsn(rop, sourcePosition, null, RegisterSpecList.make(a.spec(), b.spec())), trueLabel);
}
use of com.android.dx.rop.code.Rop in project dexmaker by linkedin.
the class Code method compareFloatingPoint.
/**
* Compare floats or doubles. This stores -1 in {@code target} if {@code
* a < b}, 0 in {@code target} if {@code a == b} and 1 in target if {@code
* a > b}. This stores {@code nanValue} in {@code target} if either value
* is {@code NaN}.
*/
public <T extends Number> void compareFloatingPoint(Local<Integer> target, Local<T> a, Local<T> b, int nanValue) {
Rop rop;
if (nanValue == 1) {
rop = Rops.opCmpg(a.type.ropType);
} else if (nanValue == -1) {
rop = Rops.opCmpl(a.type.ropType);
} else {
throw new IllegalArgumentException("expected 1 or -1 but was " + nanValue);
}
addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), RegisterSpecList.make(a.spec(), b.spec())));
}
use of com.android.dx.rop.code.Rop in project dexmaker by linkedin.
the class Code method moveResult.
private void moveResult(Local<?> target, boolean afterNonInvokeThrowingInsn) {
Rop rop = afterNonInvokeThrowingInsn ? Rops.opMoveResultPseudo(target.type.ropType) : Rops.opMoveResult(target.type.ropType);
addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), RegisterSpecList.EMPTY));
}
Aggregations