* @param lsb
* @param msb
*/
final void loadTo32(EmitterContext ec, X86Register.GPR lsb,
X86Register.GPR msb) {
final X86Assembler os = ec.getStream();
final X86RegisterPool pool = ec.getGPRPool();
final VirtualStack stack = ec.getVStack();
if (!os.isCode32()) {
throw new RuntimeException("Can only be used in 32-bit mode.");
}
// os.log("LongItem.log called "+Integer.toString(kind));
if (VmUtils.verifyAssertions()) {
VmUtils._assert(lsb != msb, "lsb != msb");
VmUtils._assert(lsb != null, "lsb != null");
VmUtils._assert(msb != null, "msb != null");
}
switch (getKind()) {
case Kind.GPR:
// invariant: (msb != lsb) && (this.msb != this.lsb)
if (msb != this.lsb) {
// generic case; avoid only if msb is lsb' (value overwriting)
// invariant: (msb != this.lsb) && (msb != lsb) && (this.msb !=
// this.lsb)
// msb <- msb'
// lsb <- lsb'
if (msb != this.msb) {
os.writeMOV(INTSIZE, msb, this.msb);
if (lsb != this.msb) {
pool.release(this.msb);
}
}
if (lsb != this.lsb) {
// invariant: (msb != this.lsb) && (lsb != this.lsb) && (msb
// != lsb) && (this.msb != this.lsb)
os.writeMOV(INTSIZE, lsb, this.lsb);
// if (msb != this.lsb) { <- enforced by first if()
pool.release(this.lsb);
// }
}
} else if (lsb != this.msb) {
// generic case, assignment sequence inverted; avoid only if lsb
// is msb' (overwriting)
// invariant: (msb == this.lsb) && (lsb != this.msb)
// lsb <- lsb'
// msb <- msb'
// if (lsb != this.lsb) { <- always true, because msb ==
// this.lsb
os.writeMOV(INTSIZE, lsb, this.lsb);
// if (msb != this.lsb) { <- always false, because of invariant
// pool.release(this.lsb);
// }
// }
// if (msb != this.msb) { <- always true, because of invariant
os.writeMOV(INTSIZE, msb, this.msb);
// if (lsb != this.msb) { <- always true, because of invariant
pool.release(this.msb);
// }
// }
} else {
// invariant: (msb == this.lsb) && (lsb == this.msb)
// swap registers
os.writeXCHG(this.lsb, this.msb);
}
break;
case Kind.LOCAL:
final int ofs = super.getOffsetToFP(ec);
os.writeMOV(INTSIZE, lsb, X86Register.EBP, ofs);
os.writeMOV(INTSIZE, msb, X86Register.EBP, ofs + 4);
break;
case Kind.CONSTANT:
loadToConstant32(ec, os, (GPR32) lsb, (GPR32) msb);
break;
case Kind.FPUSTACK:
// Make sure this item is on top of the FPU stack
stack.fpuStack.pop(this);
// Convert & move to new space on normal stack
os.writeLEA(X86Register.ESP, X86Register.ESP, -8);
popFromFPU(os, X86Register.ESP, 0);
os.writePOP(lsb);
os.writePOP(msb);
break;
case Kind.STACK:
if (VirtualStack.checkOperandStack) {
stack.operandStack.pop(this);
}
os.writePOP(lsb);
os.writePOP(msb);
break;
}
setKind(Kind.GPR);
this.lsb = (GPR32) lsb;