// larger tables.
counters.getCounter("tableswitch-opt").inc();
final GPR tmp = (GPR) L1AHelper.requestRegister(eContext, JvmType.REFERENCE, false);
if (os.isCode64()) {
GPR64 valr64 = L1AHelper.get64BitReg(eContext, valr);
os.writeMOVSXD(valr64, (GPR32) valr);
valr = valr64;
}
if (lowValue != 0) {
os.writeSUB(valr, lowValue);
}
// If outsite low-high range, jump to default
os.writeCMP_Const(valr, n);
os.writeJCC(helper.getInstrLabel(defAddress), X86Constants.JAE);
final Label curInstrLabel = getCurInstrLabel();
final Label l1 = new Label(curInstrLabel + "$$l1");
final Label l2 = new Label(curInstrLabel + "$$l2");
final int l12distance = os.isCode32() ? 12 : 23;
// Get absolute address of l1 into S0. (do not use
// stackMgr.writePOP!)
os.writeCALL(l1);
os.setObjectRef(l1);
final int l1Ofs = os.getLength();
os.writePOP(tmp);
// Calculate absolute address of jumptable entry into S1
os.writeLEA(tmp, tmp, valr, helper.ADDRSIZE, l12distance);
// Calculate absolute address of jump target
if (os.isCode32()) {
os.writeADD(tmp, tmp, 0);
} else {
final GPR32 tmp2 = (GPR32) L1AHelper.requestRegister(eContext, JvmType.INT, false);
os.writeMOV(BITS32, tmp2, tmp, 0);
final GPR64 tmp2_64 = L1AHelper.get64BitReg(eContext, tmp2);
os.writeMOVSXD(tmp2_64, tmp2);
os.writeADD(tmp, tmp2_64);
L1AHelper.releaseRegister(eContext, tmp2);
}
os.writeLEA(tmp, tmp, 4); // Compensate for writeRelativeObject