addr.load(ec);
GPR ofsr = ofs.getRegister();
final GPR addrr = addr.getRegister();
if (ofsr.getSize() != addrr.getSize()) {
// Sign-extend offset
final GPR64 ofsr64 = (GPR64) pool.getRegisterInSameGroup(ofsr, JvmType.REFERENCE);
os.writeMOVSXD(ofsr64, (GPR32) ofsr);
ofsr = ofsr64;
}
os.writeADD(addrr, ofsr);
ofs.release(ec);
vstack.push(addr);
break;
}
case AND: {
// addr & ofs
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem ofs = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
GPR ofsr = ofs.getRegister();
final GPR addrr = addr.getRegister();
if (ofsr.getSize() != addrr.getSize()) {
// Sign-extend offset
final GPR64 ofsr64 = (GPR64) pool.getRegisterInSameGroup(ofsr, JvmType.REFERENCE);
os.writeMOVSXD(ofsr64, (GPR32) ofsr);
ofsr = ofsr64;
}
os.writeAND(addrr, ofsr);
ofs.release(ec);
vstack.push(addr);
break;
}
case OR: {
// addr | ofs
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem ofs = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
GPR ofsr = ofs.getRegister();
final GPR addrr = addr.getRegister();
if (ofsr.getSize() != addrr.getSize()) {
// Sign-extend offset
final GPR64 ofsr64 = (GPR64) pool.getRegisterInSameGroup(ofsr, JvmType.REFERENCE);
os.writeMOVSXD(ofsr64, (GPR32) ofsr);
ofsr = ofsr64;
}
os.writeOR(addrr, ofsr);
ofs.release(ec);
vstack.push(addr);
break;
}
case SUB:
case DIFF: {
// addr - ofs
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem ofs = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
GPR ofsr = ofs.getRegister();
final GPR addrr = addr.getRegister();
if (ofsr.getSize() != addrr.getSize()) {
// Sign-extend offset
final GPR64 ofsr64 = (GPR64) pool.getRegisterInSameGroup(ofsr, JvmType.REFERENCE);
os.writeMOVSXD(ofsr64, (GPR32) ofsr);
ofsr = ofsr64;
}
os.writeSUB(addrr, ofsr);
ofs.release(ec);
vstack.push(addr);
break;
}
case XOR: {
// addr ^ ofs
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem ofs = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
GPR ofsr = ofs.getRegister();
final GPR addrr = addr.getRegister();
if (ofsr.getSize() != addrr.getSize()) {
// Sign-extend offset
final GPR64 ofsr64 = (GPR64) pool.getRegisterInSameGroup(ofsr, JvmType.REFERENCE);
os.writeMOVSXD(ofsr64, (GPR32) ofsr);
ofsr = ofsr64;
}
os.writeXOR(addrr, ofsr);
ofs.release(ec);
vstack.push(addr);
break;
}
case NOT: {
// !addr
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem addr = vstack.popRef();
addr.load(ec);
os.writeNOT(addr.getRegister());
vstack.push(addr);
break;
}
case TOINT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem addr = vstack.popRef();
addr.load(ec);
X86Register r = addr.getRegister();
if (os.isCode64()) {
r = pool.getRegisterInSameGroup(r, JvmType.INT);
// We just take the lower 32-bit, so no actual mov's needed.
}
addr.release(ec);
L1AHelper.requestRegister(ec, r);
final IntItem result = (IntItem) ifac.createReg(ec, JvmType.INT, r);
pool.transferOwnerTo(r, result);
vstack.push(result);
break;
}
case TOWORD:
case TOADDRESS:
case TOOFFSET:
case TOOBJECT:
case TOOBJECTREFERENCE:
case TOEXTENT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem addr = vstack.popRef();
vstack.push(addr);
break;
}
case TOLONG: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem addr = vstack.popRef();
addr.load(ec);
final X86Register.GPR r = addr.getRegister();
addr.release(ec);
L1AHelper.requestRegister(ec, r);
final LongItem result;
if (os.isCode32()) {
final X86Register.GPR msb = (X86Register.GPR) L1AHelper.requestRegister(ec, JvmType.INT,
false);
result = (LongItem) ifac.createReg(ec, JvmType.LONG, r,
msb);
os.writeXOR(msb, msb);
pool.transferOwnerTo(msb, result);
} else {
result = (LongItem) ifac.createReg(ec, JvmType.LONG, (GPR64) r);
}
pool.transferOwnerTo(r, result);
vstack.push(result);
break;
}
case MAX: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem result = (RefItem) L1AHelper.requestWordRegister(ec,
JvmType.REFERENCE, false);
final GPR r = result.getRegister();
os.writeMOV_Const(r, -1);
vstack.push(result);
break;
}
case ONE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem result = (RefItem) L1AHelper.requestWordRegister(ec,
JvmType.REFERENCE, false);
final GPR r = result.getRegister();
os.writeMOV_Const(r, 1);
vstack.push(result);
break;
}
case ZERO:
case NULLREFERENCE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem result = ifac.createAConst(ec, null);
vstack.push(result);
break;
}
case SIZE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final IntItem result = ifac.createIConst(ec, slotSize);
vstack.push(result);
break;
}
case ISMAX: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem addr = vstack.popRef();
addr.load(ec);
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, true);
final GPR addrr = addr.getRegister();
final GPR resultr = result.getRegister();
os.writeXOR(resultr, resultr);
os.writeCMP_Const(addrr, -1);
os.writeSETCC(resultr, X86Constants.JE);
addr.release(ec);
vstack.push(result);
break;
}
case ISZERO:
case ISNULL: {
// Just convert to int
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem addr = vstack.popRef();
addr.load(ec);
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, true);
final GPR addrr = addr.getRegister();
final GPR resultr = result.getRegister();
os.writeXOR(resultr, resultr);
os.writeTEST(addrr, addrr);
os.writeSETCC(resultr, X86Constants.JZ);
addr.release(ec);
vstack.push(result);
break;
}
case EQUALS:
case EQ:
case NE:
case LT:
case LE:
case GE:
case GT:
case SLT:
case SLE:
case SGE:
case SGT: {
// addr .. other
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem other = vstack.popRef();
final RefItem addr = vstack.popRef();
other.load(ec);
addr.load(ec);
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, true);
final GPR resultr = result.getRegister();
os.writeXOR(resultr, resultr);
os.writeCMP(addr.getRegister(), other.getRegister());
os.writeSETCC(resultr, methodToCC(mcode));
other.release(ec);
addr.release(ec);
vstack.push(result);
break;
}
case FROMINT:
case FROMINTSIGNEXTEND:
case FROMINTZEROEXTEND: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final WordItem addr = vstack.popInt();
addr.load(ec);
GPR r = addr.getRegister();
if (os.isCode64()) {
final GPR64 newR = (GPR64) pool.getRegisterInSameGroup(r, JvmType.REFERENCE);
if (mcode == FROMINTZEROEXTEND) {
// Moving the register to itself in 32-bit mode, will
// zero extend the top 32-bits.
os.writeMOV(BITS32, r, r);
} else {
// Sign extend
os.writeMOVSXD(newR, (GPR32) r);
}
r = newR;
}
addr.release(ec);
vstack.push(L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, r));
break;
}
case FROMADDRESS:
case FROMOBJECT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
// Do nothing
vstack.push(obj);
break;
}
case FROMLONG: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final LongItem addr = vstack.popLong();
addr.load(ec);
final X86Register r;
if (os.isCode32()) {
r = addr.getLsbRegister(ec);
} else {
r = addr.getRegister(ec);
}
addr.release(ec);
vstack.push(L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, r));
break;
}
case LSH:
case RSHA:
case RSHL: {
// addr shift cnt
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final GPR ECX = X86Register.ECX;
final IntItem cnt = vstack.popInt();
final RefItem addr = vstack.popRef();
if (!cnt.isConstant() && !cnt.uses(ECX)) {
addr.spillIfUsing(ec, ECX);
L1AHelper.requestRegister(ec, ECX);
cnt.loadTo(ec, ECX);
}
addr.load(ec);
final int shift = methodToShift(mcode);
if (cnt.isConstant()) {
os.writeShift(shift, addr.getRegister(), cnt.getValue());
} else {
os.writeShift_CL(shift, addr.getRegister());
}
cnt.release(ec);
vstack.push(addr);
break;
}
case LOADBYTE:
case LOADCHAR:
case LOADSHORT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem addr = vstack.popRef();
addr.loadToBITS8GPR(ec);
final GPR r = addr.getRegister();
final WordItem result = L1AHelper.requestWordRegister(ec, methodToType(mcode), true);
final GPR resultr = result.getRegister();
if (mcode == LOADCHAR) {
os.writeMOVZX(resultr, r, 0, methodToSize(mcode));
} else {
os.writeMOVSX(resultr, r, 0, methodToSize(mcode));
}
addr.release(ec);
vstack.push(result);
break;
}
case LOADINT:
case LOADFLOAT:
case LOADADDRESS:
case LOADOBJECTREFERENCE:
case LOADWORD:
case PREPAREINT:
case PREPAREADDRESS:
case PREPAREOBJECTREFERENCE:
case PREPAREWORD: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem addr = vstack.popRef();
addr.load(ec);
final GPR r = addr.getRegister();
final WordItem result = L1AHelper.requestWordRegister(ec, methodToType(mcode), false);
final GPR resultr = result.getRegister();
os.writeMOV(resultr.getSize(), resultr, r, 0);
addr.release(ec);
vstack.push(result);
break;
}
case LOADLONG:
case LOADDOUBLE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem addr = vstack.popRef();
addr.load(ec);
final X86Register.GPR r = addr.getRegister();
if (os.isCode32()) {
final X86Register.GPR msb = (X86Register.GPR) L1AHelper.requestRegister(ec, JvmType.INT, false);
addr.release(ec);
L1AHelper.releaseRegister(ec, msb);
os.writeMOV(X86CompilerConstants.INTSIZE, msb, r, X86CompilerConstants.MSB);
os.writeMOV(X86CompilerConstants.INTSIZE, r, r, X86CompilerConstants.LSB);
vstack.push(L1AHelper.requestDoubleWordRegisters(ec, methodToType(mcode), r, msb));
} else {
final DoubleWordItem result = L1AHelper.requestDoubleWordRegisters(ec, methodToType(mcode));
os.writeMOV(BITS64, result.getRegister(ec), r, 0);
addr.release(ec);
vstack.push(result);
}
break;
}
case LOADBYTE_OFS:
case LOADCHAR_OFS:
case LOADSHORT_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
final GPR ofsr = ofs.getRegister();
final GPR r = addr.getRegister();
os.writeLEA(r, r, ofsr, 1, 0);
final WordItem result = L1AHelper.requestWordRegister(ec, methodToType(mcode), true);
final GPR resultr = result.getRegister();
if (mcode == LOADCHAR_OFS) {
os.writeMOVZX(resultr, r, 0, methodToSize(mcode));
} else {
os.writeMOVSX(resultr, r, 0, methodToSize(mcode));
}
ofs.release(ec);
addr.release(ec);
vstack.push(result);
break;
}
case LOADINT_OFS:
case LOADFLOAT_OFS:
case LOADADDRESS_OFS:
case LOADOBJECTREFERENCE_OFS:
case LOADWORD_OFS:
case PREPAREINT_OFS:
case PREPAREADDRESS_OFS:
case PREPAREOBJECTREFERENCE_OFS:
case PREPAREWORD_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
final GPR ofsr = ofs.getRegister();
final GPR r = addr.getRegister();
final WordItem result = L1AHelper.requestWordRegister(ec, methodToType(mcode), false);
final GPR resultr = result.getRegister();
os.writeMOV(resultr.getSize(), resultr, r, ofsr, 1, 0);
ofs.release(ec);
addr.release(ec);
vstack.push(result);
break;
}
case LOADLONG_OFS:
case LOADDOUBLE_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final RefItem addr = vstack.popRef();
ofs.load(ec);
addr.load(ec);
final GPR ofsr = ofs.getRegister();
final GPR r = addr.getRegister();
if (os.isCode32()) {
final GPR msb = (GPR) L1AHelper.requestRegister(ec, JvmType.INT, false);
os.writeMOV(X86CompilerConstants.INTSIZE, msb, r, ofsr, 1, X86CompilerConstants.MSB);
os.writeMOV(X86CompilerConstants.INTSIZE, r, r, ofsr, 1, X86CompilerConstants.LSB);
ofs.release(ec);
addr.release(ec);
L1AHelper.releaseRegister(ec, msb);
vstack.push(L1AHelper.requestDoubleWordRegisters(ec, methodToType(mcode), r, msb));
} else {
final DoubleWordItem result = L1AHelper.requestDoubleWordRegisters(ec, methodToType(mcode));
os.writeMOV(BITS64, result.getRegister(ec), r, ofsr, 1, 0);
addr.release(ec);
ofs.release(ec);
vstack.push(result);
}
break;
}
case STOREBYTE:
case STORECHAR:
case STORESHORT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final IntItem val = vstack.popInt();
final RefItem addr = vstack.popRef();
val.loadToBITS8GPR(ec);
addr.load(ec);
final GPR r = addr.getRegister();
final GPR valr = val.getRegister();
os.writeMOV(methodToSize(mcode), r, 0, valr);
val.release(ec);
addr.release(ec);
break;
}
case STOREINT:
case STOREFLOAT:
case STOREADDRESS:
case STOREOBJECTREFERENCE:
case STOREWORD: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem val = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
val.load(ec);
addr.load(ec);
final GPR r = addr.getRegister();
final GPR valr = val.getRegister();
os.writeMOV(valr.getSize(), r, 0, valr);
val.release(ec);
addr.release(ec);
break;
}
case STORELONG:
case STOREDOUBLE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final DoubleWordItem val = (DoubleWordItem) vstack.pop();
final RefItem addr = vstack.popRef();
val.load(ec);
addr.load(ec);
final GPR r = addr.getRegister();
if (os.isCode32()) {
final GPR lsb = val.getLsbRegister(ec);
final GPR msb = val.getMsbRegister(ec);
os.writeMOV(X86CompilerConstants.INTSIZE, r, X86CompilerConstants.LSB, lsb);
os.writeMOV(X86CompilerConstants.INTSIZE, r, X86CompilerConstants.MSB, msb);
} else {
final GPR64 valr = val.getRegister(ec);
os.writeMOV(BITS64, r, 0, valr);
}
val.release(ec);
addr.release(ec);
break;
}
case STOREBYTE_OFS:
case STORECHAR_OFS:
case STORESHORT_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final IntItem val = vstack.popInt();
final RefItem addr = vstack.popRef();
ofs.load(ec);
val.loadToBITS8GPR(ec);
addr.load(ec);
final GPR r = addr.getRegister();
final GPR ofsr = ofs.getRegister();
final GPR valr = val.getRegister();
os.writeMOV(methodToSize(mcode), r, ofsr, 1, 0, valr);
ofs.release(ec);
val.release(ec);
addr.release(ec);
break;
}
case STOREINT_OFS:
case STOREFLOAT_OFS:
case STOREADDRESS_OFS:
case STOREOBJECTREFERENCE_OFS:
case STOREWORD_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final WordItem val = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
val.load(ec);
addr.load(ec);
final GPR r = addr.getRegister();
final GPR ofsr = ofs.getRegister();
final GPR valr = val.getRegister();
os.writeMOV(valr.getSize(), r, ofsr, 1, 0, valr);
ofs.release(ec);
val.release(ec);
addr.release(ec);
break;
}
case STORELONG_OFS:
case STOREDOUBLE_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final DoubleWordItem val = (DoubleWordItem) vstack.pop();
final RefItem addr = vstack.popRef();
ofs.load(ec);
val.load(ec);
addr.load(ec);
final GPR r = addr.getRegister();
final GPR ofsr = ofs.getRegister();
if (os.isCode32()) {
final GPR lsb = val.getLsbRegister(ec);
final GPR msb = val.getMsbRegister(ec);
os.writeMOV(X86CompilerConstants.INTSIZE, r, ofsr, 1, X86CompilerConstants.LSB, lsb);
os.writeMOV(X86CompilerConstants.INTSIZE, r, ofsr, 1, X86CompilerConstants.MSB, msb);
} else {
final GPR64 valr = val.getRegister(ec);
os.writeMOV(BITS64, r, ofsr, 1, 0, valr);
}
ofs.release(ec);
val.release(ec);
addr.release(ec);
break;
}
case ATTEMPTINT:
case ATTEMPTADDRESS:
case ATTEMPTOBJECTREFERENCE:
case ATTEMPTWORD: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final WordItem val = (WordItem) vstack.pop();
final WordItem old = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
final X86Register.GPR aax;
if ((mcode == ATTEMPTINT) || os.isCode32()) {
aax = X86Register.EAX;
} else {
aax = X86Register.RAX;
}
if (!old.uses(aax)) {
L1AHelper.requestRegister(ec, aax, old);
val.load(ec);
old.loadTo(ec, aax);
} else {
val.load(ec);
}
addr.load(ec);
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, true);
final GPR resultr = result.getRegister();
final GPR r = addr.getRegister();
final GPR valr = val.getRegister();
os.writeCMPXCHG_EAX(r, 0, valr, true);
os.writeSETCC(resultr, X86Constants.JZ);
os.writeAND(resultr, 0xFF);
val.release(ec);
old.release(ec);
addr.release(ec);
vstack.push(result);
break;
}
case ATTEMPTINT_OFS:
case ATTEMPTADDRESS_OFS:
case ATTEMPTOBJECTREFERENCE_OFS:
case ATTEMPTWORD_OFS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem ofs = vstack.popRef();
final WordItem val = (WordItem) vstack.pop();
final WordItem old = (WordItem) vstack.pop();
final RefItem addr = vstack.popRef();
final X86Register.GPR aax;
if ((mcode == ATTEMPTINT) || os.isCode32()) {
aax = X86Register.EAX;
} else {
aax = X86Register.RAX;
}
if (!old.uses(aax)) {
L1AHelper.requestRegister(ec, aax, old);
ofs.load(ec);
val.load(ec);
old.loadTo(ec, aax);
} else {
ofs.load(ec);
val.load(ec);
}
addr.load(ec);
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, true);
final GPR resultr = result.getRegister();
final GPR r = addr.getRegister();
final GPR valr = val.getRegister();
final GPR ofsr = ofs.getRegister();
os.writeLEA(r, r, ofsr, 1, 0);
os.writeCMPXCHG_EAX(r, 0, valr, true);
os.writeSETCC(resultr, X86Constants.JZ);
os.writeAND(resultr, 0xFF);
ofs.release(ec);
val.release(ec);
old.release(ec);
addr.release(ec);
vstack.push(L1AHelper.requestWordRegister(ec, JvmType.INT, resultr));
break;
}
case GETOBJECTTYPE: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
final RefItem result = (RefItem) L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, false);
final GPR resultr = result.getRegister();
// Get TIB
os.writeMOV(helper.ADDRSIZE, r, r, ObjectLayout.TIB_SLOT * slotSize);
// Get VmType
os.writeMOV(helper.ADDRSIZE, resultr, r, (TIBLayout.VMTYPE_INDEX + VmArray.DATA_OFFSET) * slotSize);
obj.release(ec);
vstack.push(result);
break;
}
case GETTIB: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
// Get TIB
os.writeMOV(helper.ADDRSIZE, r, r, ObjectLayout.TIB_SLOT * slotSize);
vstack.push(obj);
break;
}
case GETOBJECTFLAGS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
// Get flags
os.writeMOV(helper.ADDRSIZE, r, r, ObjectLayout.FLAGS_SLOT * slotSize);
obj.release(ec);
vstack.push(L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, r));
break;
}
case SETOBJECTFLAGS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem flags = vstack.popRef();
final RefItem obj = vstack.popRef();
flags.load(ec);
obj.load(ec);
final GPR flagsr = flags.getRegister();
final GPR r = obj.getRegister();
// Set flags
os.writeMOV(helper.ADDRSIZE, r, ObjectLayout.FLAGS_SLOT * slotSize, flagsr);
flags.release(ec);
obj.release(ec);
break;
}
case GETARRAYDATA: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
os.writeADD(r, VmArray.DATA_OFFSET * slotSize);
vstack.push(obj);
break;
}
case GETOBJECTCOLOR: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, false);
final GPR resultr = result.getRegister();
// Get flags
os.writeMOV(BITS32, resultr, r, ObjectLayout.FLAGS_SLOT * slotSize);
os.writeAND(resultr, ObjectFlags.GC_COLOUR_MASK);
obj.release(ec);
vstack.push(result);
break;
}
case ISFINALIZED: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem obj = vstack.popRef();
obj.load(ec);
final GPR r = obj.getRegister();
final IntItem result = (IntItem) L1AHelper.requestWordRegister(ec, JvmType.INT, false);
final GPR resultr = result.getRegister();
// Get flags
os.writeMOV(BITS32, resultr, r, ObjectLayout.FLAGS_SLOT * slotSize);
os.writeAND(resultr, ObjectFlags.STATUS_FINALIZED);
obj.release(ec);
vstack.push(result);
break;
}
case ATOMICADD:
case ATOMICAND:
case ATOMICOR:
case ATOMICSUB: {
if (VmUtils.verifyAssertions()) VmUtils._assert(!isstatic);
final RefItem value = vstack.popRef();
final RefItem addr = vstack.popRef();
value.load(ec);
addr.load(ec);
final X86Register.GPR valuer = (X86Register.GPR) value.getRegister();
final X86Register.GPR r = (X86Register.GPR) addr.getRegister();
os.writePrefix(X86Constants.LOCK_PREFIX);
os.writeArithOp(methodCodeToOperation(mcode), r, 0, valuer);
value.release(ec);
addr.release(ec);
break;
}
case GETCURRENTFRAME: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final WordItem result = L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, false);
final GPR r = result.getRegister();
os.writeMOV(helper.ADDRSIZE, r, helper.BP);
vstack.push(result);
break;
}
case GETTIMESTAMP: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
if (os.isCode32()) {
final DoubleWordItem result =
L1AHelper.requestDoubleWordRegisters(ec, JvmType.LONG, X86Register.EAX, X86Register.EDX);
os.writeRDTSC();
vstack.push(result);
} else {
final DoubleWordItem result =
L1AHelper.requestDoubleWordRegister(ec, JvmType.LONG, X86Register.RAX);
L1AHelper.requestRegister(ec, X86Register.RDX);
os.writeRDTSC();
// Move MSB to upper 32-bit of RDX
os.writeSHL(X86Register.RDX, 32);
// RAX is zero extended by RDTSC, so an OR of RAX,RDX will combine
// the upper 32-bits of RDX and the lower 32-bits of RAX.
os.writeOR(X86Register.RAX, X86Register.RDX);
// Now free RDX
L1AHelper.releaseRegister(ec, X86Register.RDX);
vstack.push(result);
}
break;
}
case INTBITSTOFLOAT:
case FLOATTORAWINTBITS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final WordItem v = (WordItem) vstack.pop();
v.load(ec);
final X86Register.GPR r = v.getRegister();
v.release(ec);
final int resultType = (mcode == INTBITSTOFLOAT) ? JvmType.FLOAT : JvmType.INT;
vstack.push(L1AHelper.requestWordRegister(ec, resultType, r));
break;
}
case LONGBITSTODOUBLE:
case DOUBLETORAWLONGBITS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final DoubleWordItem v = (DoubleWordItem) vstack.pop();
v.load(ec);
final int resultType = (mcode == LONGBITSTODOUBLE) ? JvmType.DOUBLE : JvmType.LONG;
if (os.isCode32()) {
final X86Register.GPR lsb = v.getLsbRegister(ec);
final X86Register.GPR msb = v.getMsbRegister(ec);
v.release(ec);
vstack.push(L1AHelper.requestDoubleWordRegisters(ec, resultType, lsb, msb));
} else {
final GPR64 vreg = v.getRegister(ec);
v.release(ec);
vstack.push(L1AHelper.requestDoubleWordRegister(ec, resultType, vreg));
}
break;
}
case BREAKPOINT: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
os.writeINT(3);
break;
}
case CURRENTPROCESSOR: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final RefItem item = (RefItem) L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, false);
final int offset = ec.getContext().getVmProcessorMeField().getOffset();
if (os.isCode32()) {
os.writePrefix(X86Constants.FS_PREFIX);
os.writeMOV(item.getRegister(), offset);
} else {
os.writeMOV(BITS64, item.getRegister(), X86Register.R12, offset);
}
vstack.push(item);
break;
}
case GETSHAREDSTATICSFIELDADDRESS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final IntItem index = (IntItem) vstack.pop();
index.load(ec);
final RefItem item = (RefItem) L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, false);
final GPR itemReg = item.getRegister();
final int offset = ec.getContext().getVmProcessorSharedStaticsTable().getOffset();
// Load table
if (os.isCode32()) {
os.writePrefix(X86Constants.FS_PREFIX);
os.writeMOV(itemReg, offset);
} else {
os.writeMOV(BITS64, itemReg, X86CompilerConstants.PROCESSOR64, offset);
}
GPR indexReg = index.getRegister();
if (os.isCode64()) {
GPR64 indexReg64 = L1AHelper.get64BitReg(ec, indexReg);
os.writeMOVSXD(indexReg64, (GPR32) indexReg);
indexReg = indexReg64;
}
os.writeLEA(itemReg, itemReg, indexReg, os.getWordSize(), VmArray.DATA_OFFSET * os.getWordSize());
index.release(ec);
vstack.push(item);
break;
}
case GETISOLATEDSTATICSFIELDADDRESS: {
if (VmUtils.verifyAssertions()) VmUtils._assert(isstatic);
final IntItem index = (IntItem) vstack.pop();
index.load(ec);
final RefItem item = (RefItem) L1AHelper.requestWordRegister(ec, JvmType.REFERENCE, false);
final GPR itemReg = item.getRegister();
final int offset = ec.getContext().getVmProcessorIsolatedStaticsTable().getOffset();
// Load table
if (os.isCode32()) {
os.writePrefix(X86Constants.FS_PREFIX);
os.writeMOV(itemReg, offset);
} else {
os.writeMOV(BITS64, itemReg, X86CompilerConstants.PROCESSOR64, offset);
}
GPR indexReg = index.getRegister();
if (os.isCode64()) {
GPR64 indexReg64 = L1AHelper.get64BitReg(ec, indexReg);
os.writeMOVSXD(indexReg64, (GPR32) indexReg);
indexReg = indexReg64;
}
os.writeLEA(itemReg, itemReg, indexReg, os.getWordSize(), VmArray.DATA_OFFSET * os.getWordSize());
index.release(ec);