--- old/agent/src/share/classes/sun/jvm/hotspot/asm/x86/InstructionDecoder.java Thu Sep 17 16:10:30 2009 +++ /dev/null Thu Sep 17 16:10:30 2009 @@ -1,554 +0,0 @@ -/* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. - * - */ - -package sun.jvm.hotspot.asm.x86; - -import sun.jvm.hotspot.asm.*; - -// basic instruction decoder class -public class InstructionDecoder implements /* imports */ X86Opcodes , RTLDataTypes, RTLOperations { - - protected String name; - protected int addrMode1; - protected int operandType1; - protected int addrMode2; - protected int operandType2; - protected int addrMode3; - protected int operandType3; - - private int mod; - private int regOrOpcode; - private int rm; - protected int prefixes; - - protected int byteIndex; - protected int instrStartIndex; - - public InstructionDecoder(String name) { - this.name = name; - this.operandType1 = INVALID_OPERANDTYPE; - this.operandType2 = INVALID_OPERANDTYPE; - this.operandType3 = INVALID_OPERANDTYPE; - this.addrMode1 = INVALID_ADDRMODE; - this.addrMode2 = INVALID_ADDRMODE; - this.addrMode3 = INVALID_ADDRMODE; - } - public InstructionDecoder(String name, int addrMode1, int operandType1) { - this(name); - this.addrMode1 = addrMode1; - this.operandType1 = operandType1; - } - public InstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2) { - this(name, addrMode1, operandType1); - this.addrMode2 = addrMode2; - this.operandType2 = operandType2; - } - public InstructionDecoder(String name, int addrMode1, int operandType1, int addrMode2, int operandType2, - int addrMode3, int operandType3) { - this(name, addrMode1, operandType1, addrMode2, operandType2); - this.addrMode3 = addrMode3; - this.operandType3 = operandType3; - } - // "operand1" - protected Operand getOperand1(byte[] bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode1 != INVALID_ADDRMODE) && (operandType1 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode1, operandType1, operandSize, addrSize); - else - return null; - } - - // "operand2" - protected Operand getOperand2(byte[] bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode2 != INVALID_ADDRMODE) && (operandType2 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode2, operandType2, operandSize, addrSize); - else - return null; - } - - // "operand3" - protected Operand getOperand3(byte[] bytesArray, boolean operandSize, boolean addrSize) { - if( (addrMode3 != INVALID_ADDRMODE) && (operandType3 != INVALID_OPERANDTYPE) ) - return getOperand(bytesArray, addrMode3, operandType3, operandSize, addrSize); - else - return null; - } - - static int readInt32(byte[] bytesArray, int index) { - int ret = 0; - ret = readByte(bytesArray, index); - ret |= readByte(bytesArray, index+1) << 8; - ret |= readByte(bytesArray, index+2) << 16; - ret |= readByte(bytesArray, index+3) << 24; - return ret; - } - static int readInt16(byte[] bytesArray, int index) { - int ret = 0; - ret = readByte(bytesArray, index); - ret |= readByte(bytesArray, index+1) << 8; - return ret; - } - static int readByte(byte[] bytesArray, int index) { - int ret = 0; - if (index < bytesArray.length) { - ret = (int)bytesArray[index]; - ret = ret & 0xff; - } - return ret; - } - private boolean isModRMPresent(int addrMode) { - if( (addrMode == ADDR_E) || (addrMode == ADDR_G) || (addrMode == ADDR_FPREG) || (addrMode == ADDR_Q) || (addrMode == ADDR_W) ) - return true; - else - return false; - } - public int getCurrentIndex() { - return byteIndex; - } - - public Instruction decode(byte[] bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { - this.byteIndex = index; - this.instrStartIndex = instrStartIndex; - this.prefixes = prefixes; - boolean operandSize; //operand-size prefix - boolean addrSize; //address-size prefix - if ( ( (prefixes & PREFIX_DATA) ^ segmentOverride ) == 1) - operandSize = true; - else - operandSize = false; - if ( ((prefixes & PREFIX_ADR) ^ segmentOverride) == 1) - addrSize = true; - else - addrSize = false; - this.name = getCorrectOpcodeName(name, prefixes, operandSize, addrSize); - - //Fetch the mod/reg/rm byte only if it is present. - if( isModRMPresent(addrMode1) || isModRMPresent(addrMode2) || isModRMPresent(addrMode3) ) { - - int ModRM = readByte(bytesArray, byteIndex); - byteIndex++; - mod = (ModRM >> 6) & 3; - regOrOpcode = (ModRM >> 3) & 7; - rm = ModRM & 7; - } - return decodeInstruction(bytesArray, operandSize, addrSize, factory); - } - - protected Instruction decodeInstruction(byte[] bytesArray, boolean operandSize, boolean addrSize, X86InstructionFactory factory) { - Operand op1 = getOperand1(bytesArray, operandSize, addrSize); - Operand op2 = getOperand2(bytesArray, operandSize, addrSize); - Operand op3 = getOperand3(bytesArray, operandSize, addrSize); - int size = byteIndex - instrStartIndex; - return factory.newGeneralInstruction(name, op1, op2, op3, size, prefixes); - } - - // capital letters in template are macros - private String getCorrectOpcodeName(String oldName, int prefixes, boolean operandSize, boolean addrSize) { - StringBuffer newName = new StringBuffer(oldName); - int index = 0; - for(index=0; index> 6) & 3; - index = (sib >> 3) & 7; - base = sib & 7; - } - - switch (mod) { - case 0: - switch(rm) { - case 4: - if(base == 5) { - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - if (index != 4) { - op = new X86RegisterIndirectAddress(segReg, null, X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86RegisterIndirectAddress(segReg, null, null, disp, scale); - } - } - else { - if (index != 4) { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), 0, scale); - } else { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, 0, scale); - } - } - break; - case 5: - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - //Create an Address object only with displacement - op = new X86RegisterIndirectAddress(segReg, null, null, disp); - break; - default: - base = rm; - //Create an Address object only with base - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, 0); - break; - } - break; - case 1: - disp = (byte)readByte(bytesArray, byteIndex); - byteIndex++; - if (rm !=4) { - base = rm; - //Address with base and disp only - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, disp); - } else { - if (index != 4) { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, disp, scale); - } - } - break; - case 2: - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - if (rm !=4) { - base = rm; - //Address with base and disp - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, disp); - } else if (index != 4) { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), X86Registers.getRegister32(index), disp, scale); - } else { - op = new X86RegisterIndirectAddress(segReg, X86Registers.getRegister32(base), null, disp, scale); - } - break; - } - } - break; - - case ADDR_I: - switch (operandType) { - case b_mode: - op = new Immediate(new Integer(readByte(bytesArray, byteIndex))); - byteIndex++; - break; - case w_mode: - op = new Immediate(new Integer(readInt16(bytesArray, byteIndex))); - byteIndex += 2; - break; - case v_mode: - if (operandSize == true) { //Operand size prefix is present - op = new Immediate(new Integer(readInt32(bytesArray, byteIndex))); - byteIndex += 4; - } else { - op = new Immediate(new Integer(readInt16(bytesArray, byteIndex))); - byteIndex += 2; - } - break; - default: - break; - } - break; - case ADDR_REG: //registers - switch(operandType) { - case EAX: - case ECX: - case EDX: - case EBX: - case ESP: - case EBP: - case ESI: - case EDI: - if(operandSize == true) { - op = X86Registers.getRegister32(operandType - EAX); - } - else { - op = X86Registers.getRegister16(operandType - EAX); - } - break; - case AX: - case CX: - case DX: - case BX: - case SP: - case BP: - case SI: - case DI: - op = X86Registers.getRegister16(operandType - AX); - break; - case AL: - case CL: - case DL: - case BL: - case AH: - case CH: - case DH: - case BH: - op = X86Registers.getRegister8(operandType - AL); - break; - case ES: //ES, CS, SS, DS, FS, GS - case CS: - case SS: - case DS: - case FS: - case GS: - op = X86SegmentRegisters.getSegmentRegister(operandType - ES); - break; - } - break; - case ADDR_DIR: //segment and offset - long segment = 0; - long offset = 0; - switch (operandType) { - case p_mode: - if (addrSize == true) { - offset = readInt32(bytesArray, byteIndex); - byteIndex += 4; - segment = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } else { - offset = readInt16(bytesArray, byteIndex); - byteIndex += 2; - segment = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - op = new X86DirectAddress(segment, offset); //with offset - break; - case v_mode: - if (addrSize == true) { - offset = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } else { - offset = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - op = new X86DirectAddress(offset); //with offset - break; - default: - break; - } - break; - case ADDR_G: - switch (operandType) { - case b_mode: - op = X86Registers.getRegister8(regOrOpcode); - break; - case w_mode: - op = X86Registers.getRegister16(regOrOpcode); - break; - case d_mode: - op = X86Registers.getRegister32(regOrOpcode); - break; - case v_mode: - if (operandSize == true) - op = X86Registers.getRegister32(regOrOpcode); - else - op = X86Registers.getRegister16(regOrOpcode); - break; - default: - break; - } - break; - case ADDR_SEG: - op = X86SegmentRegisters.getSegmentRegister(regOrOpcode); - break; - case ADDR_OFF: - int off = 0; - if (addrSize == true) { - off = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } - else { - off = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - op = new X86DirectAddress((long)off); - break; - case ADDR_J: - long disp = 0; - //The effective address is Instruction pointer + relative offset - switch(operandType) { - case b_mode: - disp = (byte)readByte(bytesArray, byteIndex); - byteIndex++; - break; - case v_mode: - if (operandSize == true) { - disp = readInt32(bytesArray, byteIndex); - byteIndex += 4; - } - else { - disp = readInt16(bytesArray, byteIndex); - byteIndex += 2; - } - //disp = disp + (byteIndex-instrStartIndex); - break; - } - op = new X86PCRelativeAddress(disp); - break; - case ADDR_ESDI: - op = new X86SegmentRegisterAddress(X86SegmentRegisters.ES, X86Registers.DI); - break; - case ADDR_DSSI: - op = new X86SegmentRegisterAddress(X86SegmentRegisters.DS, X86Registers.SI); - break; - case ADDR_R: - switch (operandType) { - case b_mode: - op = X86Registers.getRegister8(mod); - break; - case w_mode: - op = X86Registers.getRegister16(mod); - break; - case d_mode: - op = X86Registers.getRegister32(mod); - break; - case v_mode: - if (operandSize == true) - op = X86Registers.getRegister32(mod); - else - op = X86Registers.getRegister16(mod); - break; - default: - break; - } - break; - case ADDR_FPREG: - switch (operandType) { - case 0: - op = X86FloatRegisters.getRegister(0); - break; - case 1: - op = X86FloatRegisters.getRegister(rm); - break; - } - break; - - //SSE: reg field of ModR/M byte selects a 128-bit XMM register - case ADDR_V: - op = X86XMMRegisters.getRegister(regOrOpcode); - break; - - //SSE: reg field of ModR/M byte selects a 64-bit MMX register - case ADDR_P: - op = X86MMXRegisters.getRegister(regOrOpcode); - break; - } - return op; - } - - private X86SegmentRegister getSegmentRegisterFromPrefix(int prefixes) { - X86SegmentRegister segRegister = null; - - if ( (prefixes & PREFIX_CS) != 0) - segRegister = X86SegmentRegisters.CS; - if ( (prefixes & PREFIX_DS) != 0) - segRegister = X86SegmentRegisters.DS; - if ( (prefixes & PREFIX_ES) != 0) - segRegister = X86SegmentRegisters.ES; - if ( (prefixes & PREFIX_FS) != 0) - segRegister = X86SegmentRegisters.FS; - if ( (prefixes & PREFIX_SS) != 0) - segRegister = X86SegmentRegisters.SS; - if ( (prefixes & PREFIX_GS) != 0) - segRegister = X86SegmentRegisters.GS; - - return segRegister; - } - -}