1 /*
   2  * Copyright 2002-2003 Sun Microsystems, Inc.  All Rights Reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20  * CA 95054 USA or visit www.sun.com if you need additional information or
  21  * have any questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.asm.x86;
  26 
  27 import sun.jvm.hotspot.asm.*;
  28 
  29 public class FloatDecoder extends FPInstructionDecoder {
  30 
  31    public FloatDecoder() {
  32       super(null);
  33    }
  34 
  35    //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2
  36    //APPENDIX A - Escape opcodes
  37 
  38    /*When ModR/M byte is within 00h to BFh*/
  39    private static final FPInstructionDecoder floatMapOne[][] = {
  40       /* d8 */
  41       {
  42       new FPArithmeticDecoder("fadds", ADDR_E, v_mode, RTLOP_ADD),
  43       new FPArithmeticDecoder("fmuls", ADDR_E, v_mode, RTLOP_SMUL),
  44       new FPInstructionDecoder("fcoms", ADDR_E, v_mode),
  45       new FPInstructionDecoder("fcomps", ADDR_E, v_mode),
  46       new FPArithmeticDecoder("fsubs", ADDR_E, v_mode, RTLOP_SUB),
  47       new FPArithmeticDecoder("fsubrs", ADDR_E, v_mode, RTLOP_SUB),
  48       new FPArithmeticDecoder("fdivs", ADDR_E, v_mode, RTLOP_SDIV),
  49       new FPArithmeticDecoder("fdivrs", ADDR_E, v_mode, RTLOP_SDIV)
  50       },
  51       /*  d9 */
  52       {
  53       new FPLoadDecoder("flds", ADDR_E, v_mode),
  54       null,
  55       new FPStoreDecoder("fsts", ADDR_E, v_mode),
  56       new FPStoreDecoder("fstps", ADDR_E, v_mode),
  57       new FPStoreDecoder("fldenv", ADDR_E, v_mode),
  58       new FPStoreDecoder("fldcw", ADDR_E, v_mode),
  59       new FPStoreDecoder("fNstenv", ADDR_E, v_mode),
  60       new FPStoreDecoder("fNstcw", ADDR_E, v_mode)
  61       },
  62       /* da */
  63       {
  64       new FPArithmeticDecoder("fiaddl", ADDR_E, v_mode, RTLOP_ADD),
  65       new FPArithmeticDecoder("fimull", ADDR_E, v_mode, RTLOP_SMUL),
  66       new FPInstructionDecoder("ficoml", ADDR_E, v_mode),
  67       new FPInstructionDecoder("ficompl", ADDR_E, v_mode),
  68       new FPArithmeticDecoder("fisubl", ADDR_E, v_mode, RTLOP_SUB),
  69       new FPArithmeticDecoder("fisubrl", ADDR_E, v_mode, RTLOP_SUB),
  70       new FPArithmeticDecoder("fidivl", ADDR_E, v_mode, RTLOP_SDIV),
  71       new FPArithmeticDecoder("fidivrl", ADDR_E, v_mode, RTLOP_SDIV)
  72       },
  73       /* db */
  74       {
  75       new FPLoadDecoder("fildl", ADDR_E, v_mode),
  76       null,
  77       new FPStoreDecoder("fistl", ADDR_E, v_mode),
  78       new FPStoreDecoder("fistpl", ADDR_E, v_mode),
  79       null,
  80       new FPLoadDecoder("fldt", ADDR_E, v_mode),
  81       null,
  82       new FPStoreDecoder("fstpt", ADDR_E, v_mode)
  83       },
  84       /* dc */
  85       {
  86       new FPArithmeticDecoder("faddl", ADDR_E, v_mode, RTLOP_ADD),
  87       new FPArithmeticDecoder("fmull", ADDR_E, v_mode, RTLOP_SMUL),
  88       new FPInstructionDecoder("fcoml", ADDR_E, v_mode),
  89       new FPInstructionDecoder("fcompl", ADDR_E, v_mode),
  90       new FPArithmeticDecoder("fsubl", ADDR_E, v_mode, RTLOP_SUB),
  91       new FPArithmeticDecoder("fsubrl", ADDR_E, v_mode, RTLOP_SUB),
  92       new FPArithmeticDecoder("fdivl", ADDR_E, v_mode, RTLOP_SDIV),
  93       new FPArithmeticDecoder("fdivrl", ADDR_E, v_mode, RTLOP_SDIV)
  94       },
  95       /* dd */
  96       {
  97       new FPLoadDecoder("fldl", ADDR_E, v_mode),
  98       null,
  99       new FPStoreDecoder("fstl", ADDR_E, v_mode),
 100       new FPStoreDecoder("fstpl", ADDR_E, v_mode),
 101       new FPStoreDecoder("frstor", ADDR_E, v_mode),
 102       null,
 103       new FPStoreDecoder("fNsave", ADDR_E, v_mode),
 104       new FPStoreDecoder("fNstsw", ADDR_E, v_mode)
 105       },
 106       /* de */
 107       {
 108       new FPArithmeticDecoder("fiadd", ADDR_E, v_mode, RTLOP_ADD),
 109       new FPArithmeticDecoder("fimul", ADDR_E, v_mode, RTLOP_SMUL),
 110       new FPInstructionDecoder("ficom", ADDR_E, v_mode),
 111       new FPInstructionDecoder("ficomp", ADDR_E, v_mode),
 112       new FPArithmeticDecoder("fisub", ADDR_E, v_mode, RTLOP_SUB),
 113       new FPArithmeticDecoder("fisubr", ADDR_E, v_mode, RTLOP_SUB),
 114       new FPArithmeticDecoder("fidiv", ADDR_E, v_mode, RTLOP_SDIV),
 115       new FPArithmeticDecoder("fidivr", ADDR_E, v_mode, RTLOP_SDIV)
 116       },
 117       /* df */
 118       {
 119       new FPLoadDecoder("fild", ADDR_E, v_mode),
 120       null,
 121       new FPStoreDecoder("fist", ADDR_E, v_mode),
 122       new FPStoreDecoder("fistp", ADDR_E, v_mode),
 123       new FPLoadDecoder("fbld", ADDR_E, v_mode),
 124       new FPLoadDecoder("fildll", ADDR_E, v_mode),
 125       new FPStoreDecoder("fbstp", ADDR_E, v_mode),
 126       new FPStoreDecoder("fistpll", ADDR_E, v_mode)
 127       }
 128    };
 129 
 130    /*When ModR/M byte is outside 00h to BFh*/
 131    private static final FPInstructionDecoder floatMapTwo[][] = {
 132 
 133       /* d8 */
 134       /*parameter for ADDR_FPREG, 0 means ST(0), 1 means ST at rm value. */
 135       {
 136       new FPArithmeticDecoder("fadd", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_ADD),
 137       new FPArithmeticDecoder("fmul", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SMUL),
 138       new FPInstructionDecoder("fcom", ADDR_FPREG, 1),
 139       new FPInstructionDecoder("fcomp", ADDR_FPREG, 1),
 140       new FPArithmeticDecoder("fsub", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SUB),
 141       new FPArithmeticDecoder("fsubr", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SUB),
 142       new FPArithmeticDecoder("fdiv", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SDIV),
 143       new FPArithmeticDecoder("fdivr", ADDR_FPREG, 0, ADDR_FPREG, 1, RTLOP_SDIV)
 144       },
 145       /* d9 */
 146       {
 147       new FPLoadDecoder("fld", ADDR_FPREG, 1),
 148       new FPInstructionDecoder("fxch", ADDR_FPREG, 1),
 149       new FloatGRPDecoder(null, 0),
 150       null,
 151       new FloatGRPDecoder(null, 1),
 152       new FloatGRPDecoder(null, 2),
 153       new FloatGRPDecoder(null, 3),
 154       new FloatGRPDecoder(null, 4)
 155       },
 156       /* da */
 157       {
 158       null,
 159       null,
 160       null,
 161       null,
 162       null,
 163       new FloatGRPDecoder(null, 5),
 164       null,
 165       null
 166       },
 167       /* db */
 168       {
 169       null,
 170       null,
 171       null,
 172       null,
 173       new FloatGRPDecoder(null, 6),
 174       null,
 175       null,
 176       null
 177       },
 178       /* dc */
 179       {
 180       new FPArithmeticDecoder("fadd", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_ADD),
 181       new FPArithmeticDecoder("fmul", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SMUL),
 182       null,
 183       null,
 184       new FPArithmeticDecoder("fsub", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
 185       new FPArithmeticDecoder("fsubr",ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
 186       new FPArithmeticDecoder("fdiv", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV),
 187       new FPArithmeticDecoder("fdivr", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV)
 188       },
 189       /* dd */
 190       {
 191       new FPInstructionDecoder("ffree", ADDR_FPREG, 1),
 192       null,
 193       new FPStoreDecoder("fst", ADDR_FPREG, 1),
 194       new FPStoreDecoder("fstp", ADDR_FPREG, 1),
 195       new FPInstructionDecoder("fucom", ADDR_FPREG, 1),
 196       new FPInstructionDecoder("fucomp", ADDR_FPREG, 1),
 197       null,
 198       null
 199       },
 200       /* de */
 201       {
 202       new FPArithmeticDecoder("faddp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_ADD),
 203       new FPArithmeticDecoder("fmulp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SMUL),
 204       null,
 205       new FloatGRPDecoder(null, 7),
 206       new FPArithmeticDecoder("fsubrp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
 207       new FPArithmeticDecoder("fsubp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SUB),
 208       new FPArithmeticDecoder("fdivrp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV),
 209       new FPArithmeticDecoder("fdivp", ADDR_FPREG, 1, ADDR_FPREG, 0, RTLOP_SDIV)
 210       },
 211       /* df */
 212       {
 213       null,
 214       null,
 215       null,
 216       null,
 217       new FloatGRPDecoder(null, 7),
 218       null,
 219       null,
 220       null
 221       }
 222    };
 223 
 224    public Instruction decode(byte[] bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) {
 225       this.byteIndex = index;
 226       this.instrStartIndex = instrStartIndex;
 227       this.prefixes = prefixes;
 228 
 229       int ModRM = readByte(bytesArray, byteIndex);
 230       int reg = (ModRM >> 3) & 7;
 231       int regOrOpcode = (ModRM >> 3) & 7;
 232       int rm = ModRM & 7;
 233 
 234       int floatOpcode = InstructionDecoder.readByte(bytesArray, instrStartIndex);
 235       FPInstructionDecoder instrDecoder = null;
 236 
 237       if(ModRM < 0xbf) {
 238          instrDecoder = floatMapOne[floatOpcode - 0xd8][reg];
 239       }
 240       else {
 241          instrDecoder = floatMapTwo[floatOpcode - 0xd8][reg];
 242       }
 243 
 244       Instruction instr = null;
 245       if(instrDecoder != null) {
 246          instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory);
 247          byteIndex = instrDecoder.getCurrentIndex();
 248       } else {
 249           instr = factory.newIllegalInstruction();
 250       }
 251       return instr;
 252    }
 253 }