--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/asm/x86/FloatDecoder.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,253 @@
+/*
+ * 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 FloatDecoder extends FPInstructionDecoder {
+
+ public FloatDecoder() {
+ super(null);
+ }
+
+ //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2
+ //APPENDIX A - Escape opcodes
+
+ /*When ModR/M byte is within 00h to BFh*/
+ private static final FPInstructionDecoder floatMapOne[][] = {
+ /* d8 */
+ {
+ new FPArithmeticDecoder("fadds", ADDR_E, v_mode, RTLOP_ADD),
+ new FPArithmeticDecoder("fmuls", ADDR_E, v_mode, RTLOP_SMUL),
+ new FPInstructionDecoder("fcoms", ADDR_E, v_mode),
+ new FPInstructionDecoder("fcomps", ADDR_E, v_mode),
+ new FPArithmeticDecoder("fsubs", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fsubrs", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fdivs", ADDR_E, v_mode, RTLOP_SDIV),
+ new FPArithmeticDecoder("fdivrs", ADDR_E, v_mode, RTLOP_SDIV)
+ },
+ /* d9 */
+ {
+ new FPLoadDecoder("flds", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fsts", ADDR_E, v_mode),
+ new FPStoreDecoder("fstps", ADDR_E, v_mode),
+ new FPStoreDecoder("fldenv", ADDR_E, v_mode),
+ new FPStoreDecoder("fldcw", ADDR_E, v_mode),
+ new FPStoreDecoder("fNstenv", ADDR_E, v_mode),
+ new FPStoreDecoder("fNstcw", ADDR_E, v_mode)
+ },
+ /* da */
+ {
+ new FPArithmeticDecoder("fiaddl", ADDR_E, v_mode, RTLOP_ADD),
+ new FPArithmeticDecoder("fimull", ADDR_E, v_mode, RTLOP_SMUL),
+ new FPInstructionDecoder("ficoml", ADDR_E, v_mode),
+ new FPInstructionDecoder("ficompl", ADDR_E, v_mode),
+ new FPArithmeticDecoder("fisubl", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fisubrl", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fidivl", ADDR_E, v_mode, RTLOP_SDIV),
+ new FPArithmeticDecoder("fidivrl", ADDR_E, v_mode, RTLOP_SDIV)
+ },
+ /* db */
+ {
+ new FPLoadDecoder("fildl", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fistl", ADDR_E, v_mode),
+ new FPStoreDecoder("fistpl", ADDR_E, v_mode),
+ null,
+ new FPLoadDecoder("fldt", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fstpt", ADDR_E, v_mode)
+ },
+ /* dc */
+ {
+ new FPArithmeticDecoder("faddl", ADDR_E, v_mode, RTLOP_ADD),
+ new FPArithmeticDecoder("fmull", ADDR_E, v_mode, RTLOP_SMUL),
+ new FPInstructionDecoder("fcoml", ADDR_E, v_mode),
+ new FPInstructionDecoder("fcompl", ADDR_E, v_mode),
+ new FPArithmeticDecoder("fsubl", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fsubrl", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fdivl", ADDR_E, v_mode, RTLOP_SDIV),
+ new FPArithmeticDecoder("fdivrl", ADDR_E, v_mode, RTLOP_SDIV)
+ },
+ /* dd */
+ {
+ new FPLoadDecoder("fldl", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fstl", ADDR_E, v_mode),
+ new FPStoreDecoder("fstpl", ADDR_E, v_mode),
+ new FPStoreDecoder("frstor", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fNsave", ADDR_E, v_mode),
+ new FPStoreDecoder("fNstsw", ADDR_E, v_mode)
+ },
+ /* de */
+ {
+ new FPArithmeticDecoder("fiadd", ADDR_E, v_mode, RTLOP_ADD),
+ new FPArithmeticDecoder("fimul", ADDR_E, v_mode, RTLOP_SMUL),
+ new FPInstructionDecoder("ficom", ADDR_E, v_mode),
+ new FPInstructionDecoder("ficomp", ADDR_E, v_mode),
+ new FPArithmeticDecoder("fisub", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fisubr", ADDR_E, v_mode, RTLOP_SUB),
+ new FPArithmeticDecoder("fidiv", ADDR_E, v_mode, RTLOP_SDIV),
+ new FPArithmeticDecoder("fidivr", ADDR_E, v_mode, RTLOP_SDIV)
+ },
+ /* df */
+ {
+ new FPLoadDecoder("fild", ADDR_E, v_mode),
+ null,
+ new FPStoreDecoder("fist", ADDR_E, v_mode),
+ new FPStoreDecoder("fistp", ADDR_E, v_mode),
+ new FPLoadDecoder("fbld", ADDR_E, v_mode),
+ new FPLoadDecoder("fildll", ADDR_E, v_mode),
+ new FPStoreDecoder("fbstp", ADDR_E, v_mode),
+ new FPStoreDecoder("fistpll", ADDR_E, v_mode)
+ }
+ };
+
+ /*When ModR/M byte is outside 00h to BFh*/
+ private static final FPInstructionDecoder floatMapTwo[][] = {
+
+ /* d8 */
+ /*parameter for ADDR_FPREG, 0 means ST(0), 1 means ST at rm value. */
+ {
+ new FPArithmeticDecoder("fadd", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_ADD),
+ new FPArithmeticDecoder("fmul", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SMUL),
+ new FPInstructionDecoder("fcom", ADDR_FPREG, 1),
+ new FPInstructionDecoder("fcomp", ADDR_FPREG, 1),
+ new FPArithmeticDecoder("fsub", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SUB),
+ new FPArithmeticDecoder("fsubr", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SUB),
+ new FPArithmeticDecoder("fdiv", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SDIV),
+ new FPArithmeticDecoder("fdivr", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SDIV)
+ },
+ /* d9 */
+ {
+ new FPLoadDecoder("fld", ADDR_FPREG, 1),
+ new FPInstructionDecoder("fxch", ADDR_FPREG, 1),
+ new FloatGRPDecoder(null, 0),
+ null,
+ new FloatGRPDecoder(null, 1),
+ new FloatGRPDecoder(null, 2),
+ new FloatGRPDecoder(null, 3),
+ new FloatGRPDecoder(null, 4)
+ },
+ /* da */
+ {
+ null,
+ null,
+ null,
+ null,
+ null,
+ new FloatGRPDecoder(null, 5),
+ null,
+ null
+ },
+ /* db */
+ {
+ null,
+ null,
+ null,
+ null,
+ new FloatGRPDecoder(null, 6),
+ null,
+ null,
+ null
+ },
+ /* dc */
+ {
+ new FPArithmeticDecoder("fadd", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_ADD),
+ new FPArithmeticDecoder("fmul", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SMUL),
+ null,
+ null,
+ new FPArithmeticDecoder("fsub", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
+ new FPArithmeticDecoder("fsubr",ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
+ new FPArithmeticDecoder("fdiv", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV),
+ new FPArithmeticDecoder("fdivr", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV)
+ },
+ /* dd */
+ {
+ new FPInstructionDecoder("ffree", ADDR_FPREG, 1),
+ null,
+ new FPStoreDecoder("fst", ADDR_FPREG, 1),
+ new FPStoreDecoder("fstp", ADDR_FPREG, 1),
+ new FPInstructionDecoder("fucom", ADDR_FPREG, 1),
+ new FPInstructionDecoder("fucomp", ADDR_FPREG, 1),
+ null,
+ null
+ },
+ /* de */
+ {
+ new FPArithmeticDecoder("faddp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_ADD),
+ new FPArithmeticDecoder("fmulp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SMUL),
+ null,
+ new FloatGRPDecoder(null, 7),
+ new FPArithmeticDecoder("fsubrp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
+ new FPArithmeticDecoder("fsubp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
+ new FPArithmeticDecoder("fdivrp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV),
+ new FPArithmeticDecoder("fdivp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV)
+ },
+ /* df */
+ {
+ null,
+ null,
+ null,
+ null,
+ new FloatGRPDecoder(null, 7),
+ null,
+ null,
+ null
+ }
+ };
+
+ 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;
+ int regOrOpcode = (ModRM >> 3) & 7;
+ int rm = ModRM & 7;
+
+ int floatOpcode = InstructionDecoder.readByte(bytesArray, instrStartIndex);
+ FPInstructionDecoder instrDecoder = null;
+
+ if(ModRM < 0xbf) {
+ instrDecoder = floatMapOne[floatOpcode - 0xd8][reg];
+ }
+ else {
+ instrDecoder = floatMapTwo[floatOpcode - 0xd8][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;
+ }
+}