/** @see org.jnode.vm.x86.compiler.l1a.Item#push(EmitterContext) */ final void push(EmitterContext ec) { final X86Assembler os = ec.getStream(); final VirtualStack stack = ec.getVStack(); final X86CompilerHelper helper = ec.getHelper(); switch (getKind()) { case Kind.GPR: os.writePUSH(gpr); break; case Kind.LOCAL: os.writePUSH(helper.BP, getOffsetToFP(ec)); break; case Kind.CONSTANT: pushConstant(ec, os); break; case Kind.FPUSTACK: // Make sure this item is on top of the FPU stack final FPUStack fpuStack = stack.fpuStack; FPUHelper.fxch(os, fpuStack, this); stack.fpuStack.pop(this); // Convert & move to new space on normal stack os.writeLEA(helper.SP, helper.SP, -helper.SLOTSIZE); popFromFPU(os, helper.SP, 0); break; case Kind.STACK: // nothing to do if (VirtualStack.checkOperandStack) { // the item is not really pushed and popped // but this checks that it is really the top // element stack.operandStack.pop(this); } break; default: throw new IllegalArgumentException("Invalid item kind"); } cleanup(ec); setKind(Kind.STACK); if (VirtualStack.checkOperandStack) { stack.operandStack.push(this); } }
/** @see org.jnode.vm.x86.compiler.l1a.Item#pushToFPU(EmitterContext) */ final void pushToFPU(EmitterContext ec) { final X86Assembler os = ec.getStream(); final VirtualStack stack = ec.getVStack(); final X86CompilerHelper helper = ec.getHelper(); switch (getKind()) { case Kind.GPR: os.writePUSH(gpr); pushToFPU(os, helper.SP, 0); os.writeLEA(helper.SP, helper.SP, helper.SLOTSIZE); break; case Kind.LOCAL: pushToFPU(os, helper.BP, getOffsetToFP(ec)); break; case Kind.CONSTANT: pushConstant(ec, os); pushToFPU(os, helper.SP, 0); os.writeLEA(helper.SP, helper.SP, helper.SLOTSIZE); break; case Kind.FPUSTACK: // Assert this item is at the top of the stack stack.fpuStack.pop(this); stack.fpuStack.push(this); return; // break; case Kind.STACK: if (VirtualStack.checkOperandStack) { stack.operandStack.pop(this); } pushToFPU(os, helper.SP, 0); os.writeLEA(helper.SP, helper.SP, helper.SLOTSIZE); break; default: throw new IllegalArgumentException("Invalid item kind"); } cleanup(ec); setKind(Kind.FPUSTACK); stack.fpuStack.push(this); }
/** @see org.jnode.vm.x86.compiler.l1a.Item#clone() */ protected Item clone(EmitterContext ec) { final WordItem res; final X86Assembler os = ec.getStream(); switch (getKind()) { case Kind.GPR: res = L1AHelper.requestWordRegister(ec, getType(), false); final GPR r = res.getRegister(); os.writeMOV(gpr.getSize(), r, gpr); break; case Kind.LOCAL: res = (WordItem) factory.createLocal(getType(), getOffsetToFP(ec)); break; case Kind.CONSTANT: res = cloneConstant(ec); break; case Kind.FPUSTACK: // TODO notImplemented(); res = null; break; case Kind.STACK: os.writePUSH(X86Register.ESP, 0); res = (WordItem) factory.createStack(getType()); if (VirtualStack.checkOperandStack) { final ItemStack operandStack = ec.getVStack().operandStack; operandStack.pop(this); operandStack.push(this); operandStack.push(res); } break; default: throw new IllegalArgumentException("Invalid item kind"); } return res; }
/** * Verify the consistency of the state of this item. Throw an exception is the state is * inconsistent. */ protected void verifyState(EmitterContext ec) { switch (getKind()) { case Kind.GPR: if (gpr == null) { throw new IllegalStateException("gpr cannot not be null"); } if (ec.getStream().isCode32()) { if (!(gpr instanceof GPR32)) { throw new IllegalStateException("gpr must be GPR32"); } } else { if (getType() == JvmType.REFERENCE) { if (!(gpr instanceof GPR64)) { throw new IllegalStateException("gpr must be GPR64"); } } else { if (!(gpr instanceof GPR32)) { throw new IllegalStateException("gpr must be GPR32"); } } } break; } }
/** * load item with register reg. Assumes that reg is properly allocated * * @param ec current emitter context * @param reg register to load the item to */ final void loadTo(EmitterContext ec, X86Register.GPR reg) { if (VmUtils.verifyAssertions()) VmUtils._assert(reg != null, "Reg != null"); final X86Assembler os = ec.getStream(); final X86RegisterPool pool = ec.getGPRPool(); final VirtualStack stack = ec.getVStack(); final X86CompilerHelper helper = ec.getHelper(); if (VmUtils.verifyAssertions()) { VmUtils._assert(!pool.isFree(reg), "reg not free"); } switch (getKind()) { case Kind.GPR: if (this.gpr != reg) { os.writeMOV(reg.getSize(), reg, this.gpr); cleanup(ec); } break; case Kind.LOCAL: os.writeMOV(reg.getSize(), reg, helper.BP, getOffsetToFP(ec)); break; case Kind.CONSTANT: loadToConstant(ec, os, reg); break; case Kind.FPUSTACK: // Make sure this item is on top of the FPU stack FPUHelper.fxch(os, stack.fpuStack, this); stack.fpuStack.pop(this); // Convert & move to new space on normal stack os.writeLEA(helper.SP, helper.SP, -helper.SLOTSIZE); popFromFPU(os, helper.SP, 0); os.writePOP(reg); break; case Kind.STACK: // TODO: make sure 'this' is on top of stack // TODO: implemen it for 64 bits if (!stack.operandStack.isTos(this)) { int stack_loc = stack.operandStack.stackLocation(this); if (stack_loc < 0) throw new StackException("Item not found on stack"); stack.operandStack.makeTop(stack_loc); // todo test it os.writeMOV( org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32, reg, helper.SP, helper.SLOTSIZE); os.writeXCHG( helper.SP, org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32 * stack_loc, reg); os.writeMOV( org.jnode.vm.x86.compiler.X86CompilerConstants.BITS32, helper.SP, helper.SLOTSIZE, reg); } if (VirtualStack.checkOperandStack) { stack.operandStack.pop(this); } os.writePOP(reg); break; default: throw new IllegalArgumentException("Invalid item kind"); } setKind(Kind.GPR); this.gpr = reg; }