|
|
@ -31,129 +31,131 @@ public class CreatePrePostIncExpression { |
|
|
|
|
|
|
|
|
|
|
|
public static boolean createLocalPrePostInc(InstructionContainer ic, |
|
|
|
public static boolean createLocalPrePostInc(InstructionContainer ic, |
|
|
|
StructuredBlock last) { |
|
|
|
StructuredBlock last) { |
|
|
|
|
|
|
|
/* Situations: |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* PUSH local_x -> PUSH local_x++ |
|
|
|
|
|
|
|
* IINC local_x, +/-1 |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* IINC local_x, +/-1 |
|
|
|
|
|
|
|
* PUSH local_x -> PUSH ++local_x |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (last.outer instanceof SequentialBlock |
|
|
|
if (!(last.outer instanceof SequentialBlock) |
|
|
|
&& last.outer.getSubBlocks()[0] instanceof InstructionBlock) { |
|
|
|
|| !(last.outer.getSubBlocks()[0] instanceof InstructionBlock)) |
|
|
|
|
|
|
|
return false; |
|
|
|
Expression instr1 = ((InstructionBlock) |
|
|
|
|
|
|
|
last.outer.getSubBlocks()[0]) |
|
|
|
Expression instr1 = ((InstructionBlock) |
|
|
|
.getInstruction(); |
|
|
|
last.outer.getSubBlocks()[0]).getInstruction(); |
|
|
|
Expression instr2 = ic.getInstruction(); |
|
|
|
Expression instr2 = ic.getInstruction(); |
|
|
|
|
|
|
|
|
|
|
|
IIncOperator iinc; |
|
|
|
IIncOperator iinc; |
|
|
|
LocalLoadOperator load; |
|
|
|
LocalLoadOperator load; |
|
|
|
boolean isPost; |
|
|
|
boolean isPost; |
|
|
|
if (instr1 instanceof IIncOperator |
|
|
|
if (instr1 instanceof IIncOperator |
|
|
|
&& instr2 instanceof LocalLoadOperator) { |
|
|
|
&& instr2 instanceof LocalLoadOperator) { |
|
|
|
iinc = (IIncOperator) instr1; |
|
|
|
iinc = (IIncOperator) instr1; |
|
|
|
load = (LocalLoadOperator) instr2; |
|
|
|
load = (LocalLoadOperator) instr2; |
|
|
|
isPost = false; |
|
|
|
isPost = false; |
|
|
|
} else if (instr1 instanceof LocalLoadOperator |
|
|
|
} else if (instr1 instanceof LocalLoadOperator |
|
|
|
&& instr2 instanceof IIncOperator) { |
|
|
|
&& instr2 instanceof IIncOperator) { |
|
|
|
load = (LocalLoadOperator) instr1; |
|
|
|
load = (LocalLoadOperator) instr1; |
|
|
|
iinc = (IIncOperator) instr2; |
|
|
|
iinc = (IIncOperator) instr2; |
|
|
|
isPost = true; |
|
|
|
isPost = true; |
|
|
|
} else |
|
|
|
} else |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
int op; |
|
|
|
int op; |
|
|
|
if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP) |
|
|
|
if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP) |
|
|
|
op = Operator.INC_OP; |
|
|
|
op = Operator.INC_OP; |
|
|
|
else if (iinc.getOperatorIndex() == iinc.NEG_OP + iinc.OPASSIGN_OP) |
|
|
|
else if (iinc.getOperatorIndex() == iinc.NEG_OP + iinc.OPASSIGN_OP) |
|
|
|
op = Operator.DEC_OP; |
|
|
|
op = Operator.DEC_OP; |
|
|
|
else |
|
|
|
else |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (iinc.getValue().equals("-1")) |
|
|
|
if (iinc.getValue().equals("-1")) |
|
|
|
op ^= 1; |
|
|
|
op ^= 1; |
|
|
|
else if (!iinc.getValue().equals("1")) |
|
|
|
else if (!iinc.getValue().equals("1")) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (!iinc.matches(load)) |
|
|
|
if (!iinc.matches(load)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
Type type = load.getType().intersection(Type.tUInt); |
|
|
|
Type type = load.getType().intersection(Type.tUInt); |
|
|
|
Operator ppop = |
|
|
|
Operator ppop = |
|
|
|
new LocalPrePostFixOperator(type, op, iinc, isPost); |
|
|
|
new LocalPrePostFixOperator(type, op, iinc, isPost); |
|
|
|
|
|
|
|
|
|
|
|
ic.setInstruction(ppop); |
|
|
|
ic.setInstruction(ppop); |
|
|
|
ic.moveDefinitions(last.outer, last); |
|
|
|
ic.moveDefinitions(last.outer, last); |
|
|
|
last.replace(last.outer); |
|
|
|
last.replace(last.outer); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static boolean createPostInc(InstructionContainer ic, |
|
|
|
public static boolean createPostInc(InstructionContainer ic, |
|
|
|
StructuredBlock last) { |
|
|
|
StructuredBlock last) { |
|
|
|
|
|
|
|
|
|
|
|
/* Situation: |
|
|
|
/* Situation: |
|
|
|
* |
|
|
|
* |
|
|
|
* PUSH load/storeOps PUSH load/storeOps |
|
|
|
* PUSH load/storeOps (optional/ |
|
|
|
* DUP load/storeOps PUSH store++/-- |
|
|
|
* not checked) PUSH load/storeOps |
|
|
|
* load (unresolved) |
|
|
|
* DUP load/storeOps (optional) PUSH store++/-- |
|
|
|
* DUP -> |
|
|
|
* PUSH load(stack) |
|
|
|
* PUSH +/-1 |
|
|
|
* DUP_X(storeOps count) -> |
|
|
|
* IADD/SUB |
|
|
|
* store(stack) = stack_0 +/- 1 |
|
|
|
* store (unresolved) |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* load (no params) -> PUSH store++/-- |
|
|
|
|
|
|
|
* DUP |
|
|
|
|
|
|
|
* PUSH +/-1 |
|
|
|
|
|
|
|
* store IADD/SUB |
|
|
|
|
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
if (!(ic.getInstruction().getOperator() instanceof StoreInstruction) |
|
|
|
if (!(ic.getInstruction() instanceof ComplexExpression) |
|
|
|
|
|
|
|
|| !(ic.getInstruction().getOperator() instanceof StoreInstruction) |
|
|
|
|| !(ic.getInstruction().isVoid())) |
|
|
|
|| !(ic.getInstruction().isVoid())) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ComplexExpression storeExpr = (ComplexExpression) ic.getInstruction(); |
|
|
|
StoreInstruction store = |
|
|
|
StoreInstruction store = |
|
|
|
(StoreInstruction) ic.getInstruction().getOperator(); |
|
|
|
(StoreInstruction) ic.getInstruction().getOperator(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Make sure that the lvalue part of the store is |
|
|
|
if (!(last.outer instanceof SequentialBlock)) |
|
|
|
* not yet resolved (and not that the rvalue part |
|
|
|
|
|
|
|
* should also have 1 remaining operand) |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
int storeParams = store.getLValueOperandCount(); |
|
|
|
|
|
|
|
if (storeExpr.getOperandCount() != storeParams + 1 |
|
|
|
|
|
|
|
|| !(storeExpr.getSubExpressions()[storeParams] |
|
|
|
|
|
|
|
instanceof ComplexExpression)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
if (storeParams > 0) { |
|
|
|
|
|
|
|
for (int i=0; i< storeParams; i++) { |
|
|
|
|
|
|
|
if (!(storeExpr.getSubExpressions()[i] instanceof NopOperator)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ComplexExpression binExpr = (ComplexExpression) |
|
|
|
|
|
|
|
storeExpr.getSubExpressions()[storeParams]; |
|
|
|
|
|
|
|
if (!(binExpr instanceof ComplexExpression) |
|
|
|
|
|
|
|
|| !(binExpr.getOperator() instanceof BinaryOperator) |
|
|
|
|
|
|
|
|| !(binExpr.getSubExpressions()[0] instanceof NopOperator) |
|
|
|
|
|
|
|
|| !(binExpr.getSubExpressions()[1] instanceof ConstOperator)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
SequentialBlock sb = (SequentialBlock)last.outer; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Expression binOp; |
|
|
|
BinaryOperator binOp = (BinaryOperator) binExpr.getOperator(); |
|
|
|
if (store.getLValueOperandCount() == 0) { |
|
|
|
ConstOperator constOp = (ConstOperator) binExpr.getSubExpressions()[1]; |
|
|
|
if (!(ic.getInstruction() instanceof ComplexExpression)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
binOp = ((ComplexExpression) ic.getInstruction()) |
|
|
|
|
|
|
|
.getSubExpressions()[0]; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (!(sb.subBlocks[0] instanceof InstructionBlock) |
|
|
|
|
|
|
|
|| !(sb.outer instanceof SequentialBlock)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
binOp = ((InstructionBlock) sb.subBlocks[0]) |
|
|
|
|
|
|
|
.getInstruction(); |
|
|
|
|
|
|
|
sb = (SequentialBlock) sb.outer; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (!(binOp instanceof BinaryOperator)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int op; |
|
|
|
int op; |
|
|
|
if (binOp.getOperator().getOperatorIndex() == store.ADD_OP) |
|
|
|
if (binOp.getOperatorIndex() == store.ADD_OP) |
|
|
|
op = Operator.INC_OP; |
|
|
|
op = Operator.INC_OP; |
|
|
|
else if (binOp.getOperator().getOperatorIndex() == store.NEG_OP) |
|
|
|
else if (binOp.getOperatorIndex() == store.NEG_OP) |
|
|
|
op = Operator.DEC_OP; |
|
|
|
op = Operator.DEC_OP; |
|
|
|
else |
|
|
|
else |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (!(sb.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
if (constOp.getValue().equals("-1") |
|
|
|
return false; |
|
|
|
|| constOp.getValue().equals("-1.0")) |
|
|
|
InstructionBlock ib = (InstructionBlock) sb.subBlocks[0]; |
|
|
|
|
|
|
|
if (!(ib.getInstruction() instanceof ConstOperator)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
ConstOperator constOp = (ConstOperator) ib.getInstruction(); |
|
|
|
|
|
|
|
if (constOp.getValue().equals("-1")) |
|
|
|
|
|
|
|
op ^= 1; |
|
|
|
op ^= 1; |
|
|
|
else if (!constOp.getValue().equals("1")) |
|
|
|
else if (!constOp.getValue().equals("1") |
|
|
|
|
|
|
|
&& !constOp.getValue().equals("-1.0")) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
if (!(sb.outer instanceof SequentialBlock)) |
|
|
|
if (!(last.outer instanceof SequentialBlock)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
sb = (SequentialBlock) sb.outer; |
|
|
|
SequentialBlock sb = (SequentialBlock)last.outer; |
|
|
|
if (!(sb.subBlocks[0] instanceof SpecialBlock)) |
|
|
|
if (!(sb.subBlocks[0] instanceof SpecialBlock)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
@ -168,7 +170,7 @@ public class CreatePrePostIncExpression { |
|
|
|
sb = (SequentialBlock) sb.outer; |
|
|
|
sb = (SequentialBlock) sb.outer; |
|
|
|
if (!(sb.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
if (!(sb.subBlocks[0] instanceof InstructionBlock)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
ib = (InstructionBlock) sb.subBlocks[0]; |
|
|
|
InstructionBlock ib = (InstructionBlock) sb.subBlocks[0]; |
|
|
|
|
|
|
|
|
|
|
|
if (!(ib.getInstruction() instanceof Operator) |
|
|
|
if (!(ib.getInstruction() instanceof Operator) |
|
|
|
|| !store.matches((Operator) ib.getInstruction())) |
|
|
|
|| !store.matches((Operator) ib.getInstruction())) |
|
|
|