x86bytecodevisitor.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 2,035 行 · 第 1/5 页
JAVA
2,035 行
os.writeADD(Register.ECX, Register.EAX); // hi2*lo1 + hi1*lo2
os.writeMOV(INTSIZE, Register.EAX, Register.ESI); // lo2
os.writeMUL_EAX(Register.EBX); // lo1*lo2
os.writeADD(Register.EDX, Register.ECX); // hi2*lo1 + hi1*lo2 +
// hi(lo1*lo2)
os.setObjectRef(tmp2);
// Reload the statics table, since it was destroyed here
helper.writeLoadSTATICS(curInstrLabel, "lmul", false);
helper.writePUSH64(Register.EAX, Register.EDX);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lneg()
*/
public final void visit_lneg() {
helper.writePOP64(T0, T1);
os.writeNEG(T1); // msb := -msb
os.writeNEG(T0); // lsb := -lsb
os.writeSBB(T1, 0); // high += borrow
helper.writePUSH64(T0, T1);
/*
* os.writeNEG(SP, 0); os.writeNEG(SP, 4);
*/
}
/**
* @param defAddress
* @param matchValues
* @param addresses
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lookupswitch(int,
* int[], int[])
*/
public final void visit_lookupswitch(int defAddress, int[] matchValues,
int[] addresses) {
final int n = matchValues.length;
//BootLog.debug("lookupswitch length=" + n);
helper.writePOP(Register.EAX); // Key
for (int i = 0; i < n; i++) {
os.writeCMP_EAX(matchValues[ i]);
os.writeJCC(helper.getInstrLabel(addresses[ i]), X86Constants.JE); // JE
}
os.writeJMP(helper.getInstrLabel(defAddress));
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lor()
*/
public final void visit_lor() {
helper.writePOP64(T0, T1); // Value 2
helper.writePOP64(S0, S1); // Value 1
os.writeOR(S0, T0);
os.writeOR(S1, T1);
helper.writePUSH64(S0, S1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lrem()
*/
public final void visit_lrem() {
helper.invokeJavaMethod(context.getLremMethod());
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lreturn()
*/
public final void visit_lreturn() {
helper.writePOP64(T0, T1);
visit_return();
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lshl()
*/
public final void visit_lshl() {
helper.writePOP(Register.ECX); // Value 2
helper.writePOP64(Register.EAX, Register.EDX); // Value 1
os.writeAND(Register.ECX, 63);
os.writeCMP(Register.ECX, 32);
Label gt32Label = new Label(curInstrLabel + "gt32");
Label endLabel = new Label(curInstrLabel + "end");
os.writeJCC(gt32Label, X86Constants.JAE); // JAE
/** ECX < 32 */
os.writeSHLD_CL(Register.EDX, Register.EAX);
os.writeSHL_CL(Register.EAX);
os.writeJMP(endLabel);
/** ECX >= 32 */
os.setObjectRef(gt32Label);
os.writeMOV(INTSIZE, Register.EDX, Register.EAX);
os.writeXOR(Register.EAX, Register.EAX);
os.writeSHL_CL(Register.EDX);
os.setObjectRef(endLabel);
helper.writePUSH64(Register.EAX, Register.EDX);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lshr()
*/
public final void visit_lshr() {
helper.writePOP(Register.ECX); // Value 2
helper.writePOP64(Register.EAX, Register.EDX); // Value 1
os.writeAND(Register.ECX, 63);
os.writeCMP(Register.ECX, 32);
Label gt32Label = new Label(curInstrLabel + "gt32");
Label endLabel = new Label(curInstrLabel + "end");
os.writeJCC(gt32Label, X86Constants.JAE); // JAE
/** ECX < 32 */
os.writeSHRD_CL(Register.EAX, Register.EDX);
os.writeSAR_CL(Register.EDX);
os.writeJMP(endLabel);
/** ECX >= 32 */
os.setObjectRef(gt32Label);
os.writeMOV(INTSIZE, Register.EAX, Register.EDX);
os.writeSAR(Register.EDX, 31);
os.writeSAR_CL(Register.EAX);
os.setObjectRef(endLabel);
helper.writePUSH64(Register.EAX, Register.EDX);
}
/**
* @param index
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lstore(int)
*/
public final void visit_lstore(int index) {
int ebpOfs = stackFrame.getWideEbpOffset(index);
helper.writePOP64(T0, T1);
os.writeMOV(INTSIZE, FP, ebpOfs, T0);
os.writeMOV(INTSIZE, FP, ebpOfs + 4, T1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lsub()
*/
public final void visit_lsub() {
helper.writePOP64(T0, T1); // Value 2
helper.writePOP64(S0, S1); // Value 1
os.writeSUB(S0, T0);
os.writeSBB(S1, T1);
helper.writePUSH64(S0, S1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lushr()
*/
public final void visit_lushr() {
helper.writePOP(Register.ECX); // Value 2
helper.writePOP64(Register.EAX, Register.EDX); // Value 1
os.writeAND(Register.ECX, 63);
os.writeCMP(Register.ECX, 32);
Label gt32Label = new Label(curInstrLabel + "gt32");
Label endLabel = new Label(curInstrLabel + "end");
os.writeJCC(gt32Label, X86Constants.JAE); // JAE
/** ECX < 32 */
os.writeSHRD_CL(Register.EAX, Register.EDX);
os.writeSHR_CL(Register.EDX);
os.writeJMP(endLabel);
/** ECX >= 32 */
os.setObjectRef(gt32Label);
os.writeMOV(INTSIZE, Register.EAX, Register.EDX);
os.writeXOR(Register.EDX, Register.EDX);
os.writeSHR_CL(Register.EAX);
os.setObjectRef(endLabel);
helper.writePUSH64(Register.EAX, Register.EDX);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_lxor()
*/
public final void visit_lxor() {
helper.writePOP64(T0, T1); // Value 2
helper.writePOP64(S0, S1); // Value 1
os.writeXOR(S0, T0);
os.writeXOR(S1, T1);
helper.writePUSH64(S0, S1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_monitorenter()
*/
public final void visit_monitorenter() {
// Objectref is already on the stack
helper.invokeJavaMethod(context.getMonitorEnterMethod());
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_monitorexit()
*/
public final void visit_monitorexit() {
// Objectref is already on the stack
helper.invokeJavaMethod(context.getMonitorExitMethod());
}
/**
* @param clazz
* @param dimensions
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_multianewarray(VmConstClass,
* int)
*/
public final void visit_multianewarray(VmConstClass clazz, int dimensions) {
System.out.println("multianewarray not implemented yet in "
+ helper.getMethod());
// Dummy to maintain the stack structure, but cause a
// NullPointerException
for (int i = 0; i < dimensions; i++) {
helper.writePOP(Register.EAX);
}
helper.writePUSH(0);
}
/**
* @param classRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_new(org.jnode.vm.classmgr.VmConstClass)
*/
public final void visit_new(VmConstClass classRef) {
writeResolveAndLoadClassToEAX(classRef, S0);
/* Setup a call to SoftByteCodes.allocObject */
helper.writePUSH(Register.EAX); /* vmClass */
helper.writePUSH(-1); /* Size */
helper.invokeJavaMethod(context.getAllocObjectMethod());
/* Result is already on the stack */
}
/**
* @param type
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_newarray(int)
*/
public final void visit_newarray(int type) {
helper.writePOP(S0); /* Elements */
/* Setup a call to SoftByteCodes.allocArray */
helper.writePUSH(type); /* type */
helper.writePUSH(S0); /* elements */
helper.invokeJavaMethod(context.getAllocPrimitiveArrayMethod());
/* Result is already on the stack */
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_nop()
*/
public final void visit_nop() {
os.writeNOP();
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_pop()
*/
public final void visit_pop() {
os.writeLEA(SP, SP, 4);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_pop2()
*/
public final void visit_pop2() {
os.writeLEA(SP, SP, 8);
}
/**
* @param fieldRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_putfield(org.jnode.vm.classmgr.VmConstFieldRef)
*/
public final void visit_putfield(VmConstFieldRef fieldRef) {
fieldRef.resolve(loader);
final VmField field = fieldRef.getResolvedVmField();
if (field.isStatic()) { throw new IncompatibleClassChangeError(
"getfield called on static field " + fieldRef.getName()); }
final VmInstanceField inf = (VmInstanceField) field;
final int offset = inf.getOffset();
if (!fieldRef.isWide()) {
/* Value -> T0 */
helper.writePOP(T0);
} else {
/* Value LSB -> T0 */
helper.writePOP(T0);
/* Value MSB -> T1 */
helper.writePOP(T1);
}
/* Objectref -> S0 */
helper.writePOP(S0); // Objectref
/* Get the data */
if (!fieldRef.isWide()) {
os.writeMOV(INTSIZE, S0, offset, T0);
helper.writePutfieldWriteBarrier(inf, S0, T0, S1);
} else {
/** Msb */
os.writeMOV(INTSIZE, S0, offset + 4, T1);
/** Lsb */
os.writeMOV(INTSIZE, S0, offset, T0);
}
}
/**
* @param fieldRef
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_putstatic(org.jnode.vm.classmgr.VmConstFieldRef)
*/
public final void visit_putstatic(VmConstFieldRef fieldRef) {
fieldRef.resolve(loader);
final VmStaticField sf = (VmStaticField) fieldRef.getResolvedVmField();
if (!sf.getDeclaringClass().isInitialized()) {
writeInitializeClass(fieldRef, S0);
}
// Put static field
if (!fieldRef.isWide()) {
helper.writePOP(T0);
helper.writePutStaticsEntry(curInstrLabel, T0, sf);
helper.writePutstaticWriteBarrier(sf, T0, S1);
} else {
helper.writePOP64(T0, T1);
helper.writePutStaticsEntry64(curInstrLabel, T0, T1, sf);
}
}
/**
* @param index
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_ret(int)
*/
public final void visit_ret(int index) {
final int ebpOfs = stackFrame.getEbpOffset(index);
os.writeMOV(INTSIZE, T0, FP, ebpOfs);
os.writeJMP(T0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_return()
*/
public final void visit_return() {
stackFrame.emitReturn();
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_saload()
*/
public final void visit_saload() {
helper.writePOP(T0); // Index
helper.writePOP(S0); // Arrayref
checkBounds(S0, T0);
os.writeMOV(WORDSIZE, T0, S0, T0, 2, VmArray.DATA_OFFSET * 4);
os.writeMOVSX(T0, T0, WORDSIZE);
helper.writePUSH(T0);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_sastore()
*/
public final void visit_sastore() {
helper.writePOP(T1); // Value
helper.writePOP(T0); // Index
helper.writePOP(S0); // Arrayref
checkBounds(S0, T0);
os.writeMOV(WORDSIZE, S0, T0, 2, VmArray.DATA_OFFSET * 4, T1);
}
/**
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_swap()
*/
public final void visit_swap() {
helper.writePOP(T0); // Value1
helper.writePOP(S0); // Value2
helper.writePUSH(T0); // Value1
helper.writePUSH(S0); // Value2
}
/**
* @param defAddress
* @param lowValue
* @param highValue
* @param addresses
* @see org.jnode.vm.bytecode.BytecodeVisitor#visit_tableswitch(int, int,
* int, int[])
*/
public final void visit_tableswitch(int defAddress, int lowValue,
int highValue, int[] addresses) {
final int n = addresses.length;
helper.writePOP(Register.EAX);
if (n > 8) {
// Optimized jumptable.
// This has some overhead to call, so only worth while for large
// tableswitches.
if (lowValue != 0) {
os.writeSUB(EAX, lowValue);
}
// If outsite low-high range, jump to default
os.writeCMP(EAX, n);
os.writeJCC(helper.getInstrLabel(defAddress), X86Constants.JAE);
final Label l1 = new Label(curInstrLabel + "$$l1");
final Label l2 = new Label(curInstrLabel + "$$l2");
final int l1Ofs;
final int l2Ofs;
final int l12distance = 12;
// Get absolute address of l1 into S0. (do not use
// helper.writePOP!)
os.writeCALL(l1);
os.setObjectRef(l1);
l1Ofs = os.getLength();
os.writePOP(S0);
// Calculate absolute address of jumptable entry into S1
os.writeLEA(S1, S0, EAX, 4, l12distance);
// Calculate absolute address of jump target
os.writeADD(S1, S1, 0);
os.writeLEA(S1, S1, 4); // Compensate for writ
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?