예제 #1
0
 /**
  * Load this item to a general purpose register.
  *
  * @param ec
  */
 final void loadToGPR(EmitterContext ec) {
   if (!isGPR()) {
     X86Register r = ec.getGPRPool().request(JvmType.INT);
     if (r == null) {
       ec.getVStack().push(ec);
       r = ec.getGPRPool().request(JvmType.INT);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
 }
예제 #2
0
 /**
  * Load this item into a register that is suitable for BITS8 mode.
  *
  * @param ec
  */
 final void loadToBITS8GPR(EmitterContext ec) {
   if (!isGPR() || !gpr.isSuitableForBits8()) {
     final X86RegisterPool pool = ec.getGPRPool();
     X86Register r = pool.request(JvmType.INT, this, true);
     if (r == null) {
       ec.getVStack().push(ec);
       r = ec.getGPRPool().request(JvmType.INT, this, true);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
 }
예제 #3
0
  /** @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);
    }
  }
예제 #4
0
  /**
   * @param ec
   * @see org.jnode.vm.x86.compiler.l1a.Item#release(EmitterContext)
   */
  private void cleanup(EmitterContext ec) {
    // assertCondition(!ec.getVStack().contains(this), "Cannot release while
    // on vstack");
    final X86RegisterPool pool = ec.getGPRPool();

    switch (getKind()) {
      case Kind.GPR:
        pool.release(gpr);
        if (VmUtils.verifyAssertions()) VmUtils._assert(pool.isFree(gpr), "reg is free");
        break;

      case Kind.LOCAL:
        // nothing to do
        break;

      case Kind.CONSTANT:
        // nothing to do
        break;

      case Kind.FPUSTACK:
        // nothing to do
        break;

      case Kind.STACK:
        // nothing to do
        break;

      default:
        throw new IllegalArgumentException("Invalid item kind");
    }

    this.gpr = null;
    setKind((byte) 0);
  }
예제 #5
0
 /** @see org.jnode.vm.x86.compiler.l1a.Item#load(EmitterContext) */
 final void load(EmitterContext ec) {
   if (!isGPR()) {
     final X86RegisterPool pool = ec.getGPRPool();
     X86Register r = pool.request(getType(), this);
     if (r == null) {
       final VirtualStack vstack = ec.getVStack();
       vstack.push(ec);
       r = pool.request(getType(), this);
     }
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
     loadTo(ec, (X86Register.GPR) r);
   }
   if (VmUtils.verifyAssertions()) {
     verifyState(ec);
   }
 }
예제 #6
0
  /** @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);
  }
예제 #7
0
  /** @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;
  }
예제 #8
0
 /**
  * @see org.jnode.vm.x86.compiler.l1a.Item#spill(EmitterContext,
  *     org.jnode.assembler.x86.X86Register)
  */
 final void spill(EmitterContext ec, X86Register reg) {
   if (VmUtils.verifyAssertions()) {
     VmUtils._assert(
         isGPR() && (this.gpr.getNr() == reg.getNr()), "spill1 gpr=" + gpr + ", reg=" + reg);
   }
   final X86RegisterPool pool = ec.getGPRPool();
   X86Register r = pool.request(getType());
   if (r == null) {
     ec.getVStack().push(ec);
     if (getKind() == Kind.STACK) {
       return;
     }
     r = pool.request(getType());
     if (VmUtils.verifyAssertions()) VmUtils._assert(r != null, "r != null");
   }
   loadTo(ec, (X86Register.GPR) r);
   pool.transferOwnerTo(r, this);
   if (VmUtils.verifyAssertions()) {
     verifyState(ec);
   }
 }
예제 #9
0
 /**
  * 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;
   }
 }
예제 #10
0
 /** @see org.jnode.vm.x86.compiler.l1a.Item#release(EmitterContext) */
 final void release(EmitterContext ec) {
   cleanup(ec);
   ec.getItemFactory().release(this);
 }
예제 #11
0
  /**
   * 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;
  }