x86stackmanager.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 209 行
JAVA
209 行
/*
* $Id: X86StackManager.java,v 1.9 2004/02/15 11:07:18 epr Exp $
*/
package org.jnode.vm.x86.compiler;
import org.jnode.assembler.x86.AbstractX86Stream;
import org.jnode.assembler.x86.Register;
import org.jnode.assembler.x86.X86Constants;
/**
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public class X86StackManager {
/** PUSH reg */
private static final int MODE_REG = 1;
/** PUSH imm32 */
private static final int MODE_IMM32 = 2;
/** PUSH msbReg ; PUSH lsbReg */
private static final int MODE_REG64 = 3;
private static int pushCount;
private static int popCount;
private static int pushTrimCount;
private static int popWarnCount;
protected final AbstractX86Stream os;
private Register lastPushReg = null;
private Register lastPushRegMSB = null;
private int lastPushStart = -1;
private int lastPushEnd = -1;
private int lastPushMode;
private int lastPushImm32;
/** Set to 0 to enable the push-pop removal, set to >0 to disable */
private final int DISABLED = 0;
/**
* Initialize this instance
*
* @param os
*/
public X86StackManager(AbstractX86Stream os) {
this.os = os;
}
/**
* Write code to push the imm32 value on the stack
*
* @param imm32
*/
public void writePUSH(int imm32) {
lastPushStart = os.writePUSH(imm32);
lastPushEnd = os.getLength();
lastPushReg = null;
lastPushImm32 = imm32;
lastPushMode = MODE_IMM32;
pushCount++;
}
/**
* Write code to push the contents of the given register on the stack
*
* @param reg
*/
public void writePUSH(Register reg) {
lastPushStart = os.writePUSH(reg);
lastPushEnd = os.getLength();
lastPushReg = reg;
lastPushMode = MODE_REG;
pushCount++;
}
/**
* Write code to push a 64-bit word on the stack
*
* @param lsbReg
* @param msbReg
*/
public void writePUSH64(Register lsbReg, Register msbReg) {
lastPushStart = os.writePUSH(msbReg);
os.writePUSH(lsbReg);
lastPushEnd = os.getLength();
lastPushReg = lsbReg;
lastPushRegMSB = msbReg;
lastPushMode = MODE_REG64;
pushCount++;
}
/**
* Write code to pop the contents of the top of the stack into the given register. If the last instruction was a push, this push is removed.
*
* @param reg
*/
public void writePOP(Register reg) {
popCount++;
//final int len = os.getLength()+1; // +1 -> Force an !=
final int len = os.getLength() + DISABLED;
if ((len == lastPushEnd) && (lastPushMode != MODE_REG64)) {
// We can undo the last push
pushTrimCount++;
os.trim(lastPushEnd - lastPushStart);
/*
* if (os.isLogEnabled()) { os.log("rewrite pop " + reg);
*/
switch (lastPushMode) {
case MODE_REG :
if (reg != lastPushReg) {
os.writeMOV(X86Constants.BITS32, reg, lastPushReg);
}
break;
case MODE_IMM32 :
os.writeMOV_Const(reg, lastPushImm32);
break;
default :
throw new IllegalArgumentException("Unknown lastPushMode");
}
lastPushEnd = -1;
} else {
os.writePOP(reg);
}
}
/**
* Write code to pop the contents of the top of the stack into [reg+disp]. If the last instruction was a push, this push is removed.
*
* @param reg
* @param disp
*/
public void writePOP(Register reg, int disp) {
popCount++;
//final int len = os.getLength();
final int len = os.getLength() + DISABLED;
if ((len == lastPushEnd) && (lastPushMode != MODE_REG64)) {
// We can undo the last push
pushTrimCount++;
os.trim(lastPushEnd - lastPushStart);
if (os.isLogEnabled()) {
os.log("rewrite pop [" + reg + "+" + disp + "]");
}
switch (lastPushMode) {
case MODE_REG :
os.writeMOV(X86Constants.BITS32, reg, disp, lastPushReg);
break;
case MODE_IMM32 :
os.writeMOV_Const(reg, disp, lastPushImm32);
break;
default :
throw new IllegalArgumentException("Unknown lastPushMode");
}
lastPushEnd = -1;
} else {
os.writePOP(reg, disp);
}
}
/**
* Write code to pop a 64-bit word from the stack
*
* @param lsbReg
* @param msbReg
*/
public void writePOP64(Register lsbReg, Register msbReg) {
popCount++;
//final int len = os.getLength();
final int len = os.getLength() + DISABLED;
if ((len == lastPushEnd) && (lastPushMode == MODE_REG64)) {
if (lsbReg != lastPushRegMSB) {
// We can undo the last push
pushTrimCount++;
os.trim(lastPushEnd - lastPushStart);
/*
* if (os.isLogEnabled()) { os.log("rewrite pop64 [" + lsbReg + "+" + msbReg + "]");
*/
if (lsbReg != lastPushReg) {
os.writeMOV(X86Constants.BITS32, lsbReg, lastPushReg);
}
if (msbReg != lastPushRegMSB) {
os.writeMOV(X86Constants.BITS32, msbReg, lastPushRegMSB);
}
lastPushEnd = -1;
} else {
//BootLog.debug("lsbReg == lastPushRegMSB (" + lsbReg + ")", new Exception("Stacktrace"));
popWarnCount++;
os.writePOP(lsbReg);
os.writePOP(msbReg);
}
} else {
os.writePOP(lsbReg);
os.writePOP(msbReg);
}
}
/**
* Reset the contents of this object to its default state.
*/
public void reset() {
lastPushReg = null;
lastPushStart = -1;
lastPushEnd = -1;
lastPushMode = -1;
}
public static void dumpStatistics() {
final int p = pushTrimCount * 100 / popCount;
System.out.println("Removed " + pushTrimCount + " push-pop's which is " + p + "% of all pop's; #warnings " + popWarnCount);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?