hotspot/agent/src/share/classes/sun/jvm/hotspot/asm/x86/InstructionDecoder.java
changeset 13909 9b94bf4dcc0c
parent 13908 6fa036b39eb9
parent 13907 52873e4bbeaa
child 13911 e59cfb5f223b
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/asm/x86/InstructionDecoder.java	Thu Sep 27 11:25:01 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,554 +0,0 @@
-/*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.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<oldName.length(); index++) {
-         switch (oldName.charAt(index)) {
-            case 'C':           /* For jcxz/jecxz */
-               if (addrSize)
-                  newName.setCharAt(index, 'e');
-               index++;
-               break;
-            case 'N':
-               if ((prefixes & PREFIX_FWAIT) == 0)
-                  newName.setCharAt(index, 'n');
-               index++;
-               break;
-            case 'S':
-            /* operand size flag */
-               if (operandSize == true)
-                  newName.setCharAt(index, 'l');
-               else
-                  newName.setCharAt(index, 'w');
-               index++;
-               break;
-            default:
-               break;
-         }
-      }
-      return newName.toString();
-   }
-
-   //IA-32 Intel Architecture Software Developer's Manual Volume 2
-   //Refer to Chapter 2 - Instruction Format
-
-   //Get the Operand object from the address type and the operand type
-   private Operand getOperand(byte[] bytesArray, int addrMode, int operandType, boolean operandSize, boolean addrSize) {
-      Operand op = null;
-      switch(addrMode) {
-         case ADDR_E:
-         case ADDR_W:   //SSE: ModR/M byte specifies either 128 bit XMM register or memory
-         case ADDR_Q:   //SSE: ModR/M byte specifies either 128 bit MMX register or memory
-            X86SegmentRegister segReg = getSegmentRegisterFromPrefix(prefixes);
-
-            if (mod == 3) {    //Register operand, no SIB follows
-               if (addrMode == ADDR_E) {
-                  switch (operandType) {
-                     case b_mode:
-                        op = X86Registers.getRegister8(rm);
-                        break;
-                     case w_mode:
-                        op = X86Registers.getRegister16(rm);
-                        break;
-                     case v_mode:
-                        if (operandSize == true) //Operand size prefix is present
-                           op = X86Registers.getRegister32(rm);
-                        else
-                           op = X86Registers.getRegister16(rm);
-                        break;
-                     case p_mode:
-                        X86Register reg;
-                        if (operandSize == true) //Operand size prefix is present
-                           reg = X86Registers.getRegister32(rm);
-                        else
-                           reg = X86Registers.getRegister16(rm);
-
-                        op = new X86RegisterIndirectAddress(segReg, reg, null, 0);
-                        break;
-                     default:
-                        break;
-                  }
-               } else if (addrMode == ADDR_W) {
-                  op = X86XMMRegisters.getRegister(rm);
-               } else if (addrMode == ADDR_Q) {
-                  op = X86MMXRegisters.getRegister(rm);
-               }
-
-            } else {   //mod != 3
-               //SIB follows for (rm==4), SIB gives scale, index and base in this case
-               //disp32 is present for (mod==0 && rm==5) || (mod==2)
-               //disp8 is present for (mod==1)
-               //for (rm!=4) base is register at rm.
-               int scale = 0;
-               int index = 0;
-               int base = 0;
-               long disp = 0;
-               if(rm == 4) {
-                  int sib = readByte(bytesArray, byteIndex);
-                  byteIndex++;
-                  scale = (sib >> 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;
-   }
-
-}