Mercurial > hg > truffle
diff agent/src/share/classes/sun/jvm/hotspot/asm/x86/GRPDecoder.java @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | c18cbe5936b8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/agent/src/share/classes/sun/jvm/hotspot/asm/x86/GRPDecoder.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,320 @@ +/* + * 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.*; + +public class GRPDecoder extends InstructionDecoder { + + final private int number; + //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2 + //APPENDIX A - Table A-4. Opcode Extensions for One and Two-byte Opcodes by Group Number. + private static final InstructionDecoder grpTable[][] = { + { + new ArithmeticDecoder("addb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_ADD), + new LogicalDecoder("orb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_OR), + new ArithmeticDecoder("adcb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_ADDC), + new ArithmeticDecoder("sbbb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SUBC), + new LogicalDecoder("andb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_AND), + new ArithmeticDecoder("subb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SUB), + new LogicalDecoder("xorb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_XOR), + new InstructionDecoder("cmpb", ADDR_E, b_mode, ADDR_I, b_mode) + }, + { + new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_ADD), + new LogicalDecoder("orS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_OR), + new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_ADDC), + new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_SUBC), + new LogicalDecoder("andS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_AND), + new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_SUB), + new LogicalDecoder("xorS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_XOR), + new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, v_mode) + }, + { + new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_ADD), /*note: sIb here*/ + new LogicalDecoder("orS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_OR), + new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_ADDC), + new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SUBC), + new LogicalDecoder("andS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_AND), + new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SUB), + new LogicalDecoder("xorS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_XOR), + new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, b_mode) + }, + { + new RotateDecoder("rolb", ADDR_E, b_mode, ADDR_I, b_mode), + new RotateDecoder("rorb", ADDR_E, b_mode, ADDR_I, b_mode), + new RotateDecoder("rclb", ADDR_E, b_mode, ADDR_I, b_mode), + new RotateDecoder("rcrb", ADDR_E, b_mode, ADDR_I, b_mode), + new ShiftDecoder("shlb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SLL), + new ShiftDecoder("shrb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new ShiftDecoder("sarb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SRA), + }, + { + new RotateDecoder("rolS", ADDR_E, v_mode, ADDR_I, b_mode), + new RotateDecoder("rorS", ADDR_E, v_mode, ADDR_I, b_mode), + new RotateDecoder("rclS", ADDR_E, v_mode, ADDR_I, b_mode), + new RotateDecoder("rcrS", ADDR_E, v_mode, ADDR_I, b_mode), + new ShiftDecoder("shlS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SLL), + new ShiftDecoder("shrS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new ShiftDecoder("sarS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SRA) + }, + { + new RotateDecoder("rolb", ADDR_E, b_mode), + new RotateDecoder("rorb", ADDR_E, b_mode), + new RotateDecoder("rclb", ADDR_E, b_mode), + new RotateDecoder("rcrb", ADDR_E, b_mode), + new ShiftDecoder("shlb", ADDR_E, b_mode, RTLOP_SLL), + new ShiftDecoder("shrb", ADDR_E, b_mode, RTLOP_SRL), + null, + new ShiftDecoder("sarb", ADDR_E, b_mode, RTLOP_SRA) + }, + { + new RotateDecoder("rolS", ADDR_E, v_mode), + new RotateDecoder("rorS", ADDR_E, v_mode), + new RotateDecoder("rclS", ADDR_E, v_mode), + new RotateDecoder("rcrS", ADDR_E, v_mode), + new ShiftDecoder("shlS", ADDR_E, v_mode, RTLOP_SLL), + new ShiftDecoder("shrS", ADDR_E, v_mode, RTLOP_SRL), + null, + new ShiftDecoder("sarS", ADDR_E, v_mode, RTLOP_SRA) + }, + { + new RotateDecoder("rolb", ADDR_E, b_mode, ADDR_REG, CL), + new RotateDecoder("rorb", ADDR_E, b_mode, ADDR_REG, CL), + new RotateDecoder("rclb", ADDR_E, b_mode, ADDR_REG, CL), + new RotateDecoder("rcrb", ADDR_E, b_mode, ADDR_REG, CL), + new ShiftDecoder( "shlb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SLL), + new ShiftDecoder("shrb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SRL), + null, + new ShiftDecoder("sarb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SRA) + }, + { + new RotateDecoder("rolS", ADDR_E, v_mode, ADDR_REG, CL), + new RotateDecoder("rorS", ADDR_E, v_mode, ADDR_REG, CL), + new RotateDecoder("rclS", ADDR_E, v_mode, ADDR_REG, CL), + new RotateDecoder("rcrS", ADDR_E, v_mode, ADDR_REG, CL), + new ShiftDecoder("shlS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SLL), + new ShiftDecoder("shrS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SRL), + null, + new ShiftDecoder("sarS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SRA) + }, + { + new InstructionDecoder("testb", ADDR_E, b_mode, ADDR_I, b_mode), + null, /*new InstructionDecoder("(bad)", ADDR_E, b_mode)*/ + new LogicalDecoder("notb", ADDR_E, b_mode, RTLOP_NOT), + new InstructionDecoder("negb", ADDR_E, b_mode), + new ArithmeticDecoder("mulb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_UMUL), + new ArithmeticDecoder("imulb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_SMUL), + new ArithmeticDecoder("divb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_UDIV), + new ArithmeticDecoder("idivb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_SDIV) + }, + { + new InstructionDecoder("testS", ADDR_E, v_mode, ADDR_I, v_mode), + null, + new LogicalDecoder("notS", ADDR_E, v_mode, RTLOP_NOT), + new InstructionDecoder("negS", ADDR_E, v_mode), + new ArithmeticDecoder("mulS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_UMUL), + new ArithmeticDecoder("imulS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SMUL), + new ArithmeticDecoder("divS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SDIV), + new ArithmeticDecoder("idivS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SDIV) + }, + { + new ArithmeticDecoder("incb", ADDR_E, b_mode, RTLOP_ADD), + new ArithmeticDecoder("decb", ADDR_E, b_mode, RTLOP_SUB), + null, + null, + null, + null, + null, + null + }, + { + new ArithmeticDecoder("incS", ADDR_E, v_mode, RTLOP_ADD), + new ArithmeticDecoder("decS", ADDR_E, v_mode, RTLOP_SUB), + new CallDecoder("call", ADDR_E, v_mode), + new CallDecoder("lcall", ADDR_E, p_mode), + new JmpDecoder("jmp", ADDR_E, v_mode), + new JmpDecoder("ljmp", ADDR_E, p_mode), + new InstructionDecoder("pushS", ADDR_E, v_mode), + null + }, + { + new InstructionDecoder("sldt", ADDR_E, w_mode), + new InstructionDecoder("str", ADDR_E, w_mode), + new InstructionDecoder("lldt", ADDR_E, w_mode), + new InstructionDecoder("ltr", ADDR_E, w_mode), + new InstructionDecoder("verr", ADDR_E, w_mode), + new InstructionDecoder("verw", ADDR_E, w_mode), + null, + null + }, + { + new InstructionDecoder("sgdt", ADDR_E, w_mode), + new InstructionDecoder("sidt", ADDR_E, w_mode), + new InstructionDecoder("lgdt", ADDR_E, w_mode), + new InstructionDecoder("lidt", ADDR_E, w_mode), + new InstructionDecoder("smsw", ADDR_E, w_mode), + null, + new InstructionDecoder("lmsw", ADDR_E, w_mode), + new InstructionDecoder("invlpg", ADDR_E, w_mode) + }, + { + null, + null, + null, + null, + new InstructionDecoder("btS", ADDR_E, v_mode, ADDR_I, b_mode), + new InstructionDecoder("btsS", ADDR_E, v_mode, ADDR_I, b_mode), + new InstructionDecoder("btrS", ADDR_E, v_mode, ADDR_I, b_mode), + new InstructionDecoder("btcS", ADDR_E, v_mode, ADDR_I, b_mode) + }, + /*16*/ + { + null, + new SSEInstructionDecoder("cmpxch8b", ADDR_W, q_mode), + null, + null, + null, + null, + null, + null + }, + /*17*/ + { + null, + null, + new SSEShiftDecoder("psrlw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new SSEShiftDecoder("psraw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRA), + null, + new SSEShiftDecoder("psllw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL), + null + }, + /*18*/ + { + null, + null, + new SSEShiftDecoder("psrld", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new SSEShiftDecoder("psrad", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRA), + null, + new SSEShiftDecoder("pslld", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL), + null + }, + /*19*/ + { + null, + null, + new SSEShiftDecoder("psrlq", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + null, + null, + new SSEShiftDecoder("psllq", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL), + null + }, + /*20 - Grp15*/ + { + new SSEInstructionDecoder("fxsave"), + new SSEInstructionDecoder("fxrstor"), + new SSEInstructionDecoder("ldmxcsr"), + new SSEInstructionDecoder("stmxcsr"), + null, + null, + null, + new SSEInstructionDecoder("clflush") + }, + /*21 - Grp16*/ + { + new SSEInstructionDecoder("prefetchnta"), + new SSEInstructionDecoder("prefetcht0"), + new SSEInstructionDecoder("prefetcht1"), + new SSEInstructionDecoder("prefetcht2"), + null, + null, + null, + null + }, + /*22 - Grp12:66*/ + { + null, + null, + new SSEShiftDecoder("psrlw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new SSEShiftDecoder("psraw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SRA), + null, + new SSEShiftDecoder("psllw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SLL), + null + }, + /*23 - Grp13:66*/ + { + null, + null, + new SSEShiftDecoder("psrld", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + new SSEShiftDecoder("psrad", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRA), + null, + new SSEShiftDecoder("pslld", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL), + null + }, + /*24 - - Grp14:66*/ + { + null, + null, + new SSEShiftDecoder("psrlq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL), + new SSEShiftDecoder("psrldq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL), + null, + null, + new SSEShiftDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL), + new SSEShiftDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL) + } +}; + + public GRPDecoder(String name, int number) { + super(name); + this.number = number; + } + + public Instruction decode(byte[] bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) { + this.byteIndex = index; + this.instrStartIndex = instrStartIndex; + this.prefixes = prefixes; + + int ModRM = readByte(bytesArray, byteIndex); + int reg = (ModRM >> 3) & 7; + + InstructionDecoder instrDecoder = grpTable[number][reg]; + Instruction instr = null; + if(instrDecoder != null) { + instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory); + byteIndex = instrDecoder.getCurrentIndex(); + } else { + instr = factory.newIllegalInstruction(); + } + + return instr; + } +}