import org.apache.bcel.generic.*;
+// FEATURE: Use IINC where possible
// FEATURE: Use BCEL to do peephole optimization
// FEATURE: Special mode to support single-precision only - regs are floats not ints
a(fac.createCheckCast(new ObjectType("java.lang.Integer")));
a(fac.createInvoke("java.lang.Integer","intValue",Type.INT,Type.NO_ARGS,INVOKEVIRTUAL));
a(InstructionConstants.IRETURN);
- bh.setTarget(a(InstructionConstants.ICONST_M1));
- a(InstructionConstants.IRETURN);
+ bh.setTarget(a(InstructionConstants.POP));
+ a(InstructionConstants.ICONST_M1);
+ a(InstructionConstants.IRETURN);
lookupSymbol.setMaxLocals();
lookupSymbol.setMaxStack();
cl.addMethod(lookupSymbol.getMethod());
private InstructionHandle realStart;
private MethodGen curMethod;
- private boolean jumpable(int addr) { return jumpableAddresses.contains(new Integer(addr)); }
+ private boolean jumpable(int addr) { return jumpableAddresses.get(new Integer(addr)) != null; }
private void emitText(int addr, DataInputStream dis, int size) throws Exn,IOException {
if(textDone) throw new Exn("Multiple text segments");
pushConst(firstAddrOfNext);
setPC();
// mark the start of the next method as jumpable
- jumpableAddresses.add(new Integer(firstAddrOfNext));
+ jumpableAddresses.put(new Integer(firstAddrOfNext),Boolean.TRUE);
}
insnList.move(returnHandle,insnList.getEnd());
//System.err.println("Delay slot is jumpable - This code is untested + " + toHex(nextInsn));
if(pc+4==endOfMethod) {
// the delay slot is at the start of the next method
- jumpableAddresses.add(new Integer(pc+8)); // make the 2nd insn of the next method jumpable
+ jumpableAddresses.put(new Integer(pc+8),Boolean.TRUE); // make the 2nd insn of the next method jumpable
branch(pc,pc+8); // jump over it
//System.err.println("delay slot: " + toHex(pc+8));
unreachable = true;
pushRegZ(R+A1);
pushRegZ(R+A2);
pushRegZ(R+A3);
- a(fac.createInvoke(fullClassName,"syscall",Type.INT,new Type[]{Type.INT,Type.INT,Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
+ pushRegZ(R+T0);
+ pushRegZ(R+T1);
+ a(fac.createInvoke(fullClassName,"syscall",Type.INT,new Type[]{Type.INT,Type.INT,Type.INT,Type.INT,Type.INT,Type.INT,Type.INT},INVOKEVIRTUAL));
setReg();
a(InstructionConstants.ALOAD_0);
break;
case 1: // SUB.X
preSetDouble(F+fd,d);
- pushDouble(F+ft,d);
pushDouble(F+fs,d);
+ pushDouble(F+ft,d);
a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB);
- setDouble(d);
+ setDouble(d);
break;
case 2: // MUL.X
preSetDouble(F+fd,d);
b1 = a(InstructionFactory.createBranchInstruction(IFGT,null));
a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0);
- if(d) {
- a(InstructionConstants.DUP2_X2);
- a(InstructionConstants.POP2);
- } else {
- a(InstructionConstants.POP);
- }
- a(InstructionConstants.DSUB);
+ a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB);
b1.setTarget(setDouble(d));
pushReg(F+fs);
setReg();
- preSetReg(F+fd+1);
- pushReg(F+fs+1);
- setReg();
+ if(d) {
+ preSetReg(F+fd+1);
+ pushReg(F+fs+1);
+ setReg();
+ }
break;
case 7: // NEG.X
preSetDouble(F+fd,d);
pushDouble(F+fs,d);
a(d ? InstructionConstants.DNEG : InstructionConstants.FNEG);
- setDouble(d);
+ setDouble(d);
break;
case 32: // CVT.S.X
preSetFloat(F+fd);
- pushDouble(F+fd,d);
+ pushDouble(F+fs,d);
if(d) a(InstructionConstants.D2F);
setFloat();
break;
case 33: // CVT.D.X
preSetDouble(F+fd);
- pushDouble(F+fd,d);
+ pushDouble(F+fs,d);
if(!d) a(InstructionConstants.F2D);
setDouble();
break;
case 62: b1 = a(InstructionFactory.createBranchInstruction(IFLE,null)); break;
default: b1 = null;
}
-
+ // FIXME: We probably don't need to pushConst(0x00000)
pushConst(0x000000);
b2 = a(InstructionFactory.createBranchInstruction(GOTO,null));
b1.setTarget(pushConst(0x800000));