001: /*
002: * DcmplCommand.java Copyright (c) 2006,07 Swaroop Belur
003: *
004: * This program is free software; you can redistribute it and/itor
005: * modify it under the terms of the GNU General Public License
006: * as published by the Free Software Foundation; either version 2
007: * of the License, or (at your option) any later version.
008:
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013:
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
017: *
018: */
019: package net.sf.jdec.jvminstructions.commands;
020:
021: import net.sf.jdec.blockhelpers.IFHelper;
022: import net.sf.jdec.core.JvmOpCodes;
023: import net.sf.jdec.core.Operand;
024: import net.sf.jdec.core.OperandStack;
025: import net.sf.jdec.core.ShortcutAnalyser;
026: import net.sf.jdec.reflection.Behaviour;
027: import net.sf.jdec.util.Constants;
028:
029: public class DcmplCommand extends AbstractInstructionCommand {
030:
031: public DcmplCommand(Behaviour context) {
032: super (context);
033:
034: }
035:
036: public int getSkipBytes() {
037: return 0;
038: }
039:
040: public void execute() {
041:
042: int currentForIndex = getCurrentInstPosInCode();
043: OperandStack stack = getStack();
044: byte[] info = getCode();
045: int i = currentForIndex;
046: Operand op = (Operand) stack.pop();
047: Operand op1 = (Operand) stack.pop();
048: Operand op2 = new Operand();
049: ShortcutAnalyser sanalyser = getContext().getShortCutAnalyser();
050: op2.setOperandType(Constants.IS_CONSTANT_INT);
051: int j = i + 1;
052: int nextInstruction = info[j];
053: boolean sh = getBranchFinder().isIFShortcutORComp(j);
054: boolean invert = sanalyser.isLastIfInChain(j);
055: if (!invert) {
056: java.lang.String connector = sanalyser.getConnector(j);
057: if (connector != null
058: && connector.trim().equals(ShortcutAnalyser.AND)) {
059: invert = true;
060: }
061: }
062: if (!sh) {
063: if (getGenericFinder().isThisInstrStart(
064: (currentForIndex + 1))) {
065: if (getBranchFinder().isInstructionIF(
066: (currentForIndex + 1))) {
067: int ifclose = IFHelper.getIfCloseNumberForThisIF(
068: info, (currentForIndex + 1));
069: ifclose = ifclose - 3;
070: if (getGenericFinder().isThisInstrStart(ifclose)) {
071: if (getBranchFinder().isInstructionIF(ifclose)
072: && ifclose != j) {
073: sh = true;
074: }
075: }
076: }
077: }
078:
079: }
080: switch (nextInstruction) {
081: case JvmOpCodes.IFEQ:
082: if (!sh)
083: op2.setOperandValue(op1.getOperandValue() + "!="
084: + op.getOperandValue());
085: else {
086: if (!invert)
087: op2.setOperandValue(op1.getOperandValue() + "=="
088: + op.getOperandValue());
089: else
090: op2.setOperandValue(op1.getOperandValue() + "!="
091: + op.getOperandValue());
092: }
093:
094: break;
095: case JvmOpCodes.IFNE:
096: if (!sh)
097: op2.setOperandValue(op1.getOperandValue() + "=="
098: + op.getOperandValue());
099: else {
100: if (!invert)
101: op2.setOperandValue(op1.getOperandValue() + "!="
102: + op.getOperandValue());
103: else
104: op2.setOperandValue(op1.getOperandValue() + "=="
105: + op.getOperandValue());
106: }
107: break;
108: case JvmOpCodes.IFLT:
109: if (!sh)
110: op2.setOperandValue(op1.getOperandValue() + ">="
111: + op.getOperandValue());
112: else {
113: if (invert)
114: op2.setOperandValue(op1.getOperandValue() + "<"
115: + op.getOperandValue());
116: else
117: op2.setOperandValue(op1.getOperandValue() + ">="
118: + op.getOperandValue());
119: }
120: break;
121: case JvmOpCodes.IFGE:
122: if (!sh)
123: op2.setOperandValue(op1.getOperandValue() + "<"
124: + op.getOperandValue());
125: else {
126: if (invert)
127: op2.setOperandValue(op1.getOperandValue() + ">="
128: + op.getOperandValue());
129: else
130: op2.setOperandValue(op1.getOperandValue() + "<"
131: + op.getOperandValue());
132: }
133: break;
134: case JvmOpCodes.IFGT:
135: if (!sh)
136: op2.setOperandValue(op1.getOperandValue() + "<="
137: + op.getOperandValue());
138: else {
139: if (invert)
140: op2.setOperandValue(op1.getOperandValue() + ">"
141: + op.getOperandValue());
142: else
143: op2.setOperandValue(op1.getOperandValue() + "<="
144: + op.getOperandValue());
145: }
146: break;
147:
148: case JvmOpCodes.IFLE:
149: if (!sh)
150: op2.setOperandValue(op1.getOperandValue() + ">"
151: + op.getOperandValue());
152: else {
153: if (invert)
154: op2.setOperandValue(op1.getOperandValue() + "<="
155: + op.getOperandValue());
156: else
157: op2.setOperandValue(op1.getOperandValue() + ">"
158: + op.getOperandValue());
159: }
160: break;
161: }
162: stack.push(op2);
163: }
164:
165: }
|