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 GRPDecoder extends InstructionDecoder {
  30 
  31    final private int number;
  32    //Please refer to IA-32 Intel Architecture Software Developer's Manual Volume 2
  33    //APPENDIX A - Table A-4. Opcode Extensions for One and Two-byte Opcodes by Group Number.
  34    private static final InstructionDecoder grpTable[][] = {
  35       {
  36       new ArithmeticDecoder("addb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_ADD),
  37       new LogicalDecoder("orb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_OR),
  38       new ArithmeticDecoder("adcb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_ADDC),
  39       new ArithmeticDecoder("sbbb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SUBC),
  40       new LogicalDecoder("andb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_AND),
  41       new ArithmeticDecoder("subb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SUB),
  42       new LogicalDecoder("xorb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_XOR),
  43       new InstructionDecoder("cmpb", ADDR_E, b_mode, ADDR_I, b_mode)
  44       },
  45       {
  46       new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_ADD),
  47       new LogicalDecoder("orS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_OR),
  48       new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_ADDC),
  49       new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_SUBC),
  50       new LogicalDecoder("andS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_AND),
  51       new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_SUB),
  52       new LogicalDecoder("xorS", ADDR_E, v_mode, ADDR_I, v_mode, RTLOP_XOR),
  53       new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, v_mode)
  54       },
  55       {
  56       new ArithmeticDecoder("addS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_ADD), /*note: sIb here*/
  57       new LogicalDecoder("orS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_OR),
  58       new ArithmeticDecoder("adcS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_ADDC),
  59       new ArithmeticDecoder("sbbS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SUBC),
  60       new LogicalDecoder("andS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_AND),
  61       new ArithmeticDecoder("subS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SUB),
  62       new LogicalDecoder("xorS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_XOR),
  63       new InstructionDecoder("cmpS", ADDR_E, v_mode, ADDR_I, b_mode)
  64       },
  65       {
  66       new RotateDecoder("rolb", ADDR_E, b_mode, ADDR_I, b_mode),
  67       new RotateDecoder("rorb", ADDR_E, b_mode, ADDR_I, b_mode),
  68       new RotateDecoder("rclb", ADDR_E, b_mode, ADDR_I, b_mode),
  69       new RotateDecoder("rcrb", ADDR_E, b_mode, ADDR_I, b_mode),
  70       new ShiftDecoder("shlb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SLL),
  71       new ShiftDecoder("shrb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SRL),
  72       null,
  73       new ShiftDecoder("sarb", ADDR_E, b_mode, ADDR_I, b_mode, RTLOP_SRA),
  74       },
  75       {
  76       new RotateDecoder("rolS", ADDR_E, v_mode, ADDR_I, b_mode),
  77       new RotateDecoder("rorS", ADDR_E, v_mode, ADDR_I, b_mode),
  78       new RotateDecoder("rclS", ADDR_E, v_mode, ADDR_I, b_mode),
  79       new RotateDecoder("rcrS", ADDR_E, v_mode, ADDR_I, b_mode),
  80       new ShiftDecoder("shlS", ADDR_E, v_mode, ADDR_I, b_mode,  RTLOP_SLL),
  81       new ShiftDecoder("shrS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SRL),
  82       null,
  83       new ShiftDecoder("sarS", ADDR_E, v_mode, ADDR_I, b_mode, RTLOP_SRA)
  84       },
  85       {
  86       new RotateDecoder("rolb", ADDR_E, b_mode),
  87       new RotateDecoder("rorb", ADDR_E, b_mode),
  88       new RotateDecoder("rclb", ADDR_E, b_mode),
  89       new RotateDecoder("rcrb", ADDR_E, b_mode),
  90       new ShiftDecoder("shlb", ADDR_E, b_mode, RTLOP_SLL),
  91       new ShiftDecoder("shrb", ADDR_E, b_mode, RTLOP_SRL),
  92       null,
  93       new ShiftDecoder("sarb", ADDR_E, b_mode, RTLOP_SRA)
  94       },
  95       {
  96       new RotateDecoder("rolS", ADDR_E, v_mode),
  97       new RotateDecoder("rorS", ADDR_E, v_mode),
  98       new RotateDecoder("rclS", ADDR_E, v_mode),
  99       new RotateDecoder("rcrS", ADDR_E, v_mode),
 100       new ShiftDecoder("shlS", ADDR_E, v_mode, RTLOP_SLL),
 101       new ShiftDecoder("shrS", ADDR_E, v_mode, RTLOP_SRL),
 102       null,
 103       new ShiftDecoder("sarS", ADDR_E, v_mode, RTLOP_SRA)
 104       },
 105       {
 106       new RotateDecoder("rolb", ADDR_E, b_mode, ADDR_REG, CL),
 107       new RotateDecoder("rorb", ADDR_E, b_mode, ADDR_REG, CL),
 108       new RotateDecoder("rclb", ADDR_E, b_mode, ADDR_REG, CL),
 109       new RotateDecoder("rcrb", ADDR_E, b_mode, ADDR_REG, CL),
 110       new ShiftDecoder( "shlb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SLL),
 111       new ShiftDecoder("shrb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SRL),
 112       null,
 113       new ShiftDecoder("sarb", ADDR_E, b_mode, ADDR_REG, CL, RTLOP_SRA)
 114       },
 115       {
 116       new RotateDecoder("rolS", ADDR_E, v_mode, ADDR_REG, CL),
 117       new RotateDecoder("rorS", ADDR_E, v_mode, ADDR_REG, CL),
 118       new RotateDecoder("rclS", ADDR_E, v_mode, ADDR_REG, CL),
 119       new RotateDecoder("rcrS", ADDR_E, v_mode, ADDR_REG, CL),
 120       new ShiftDecoder("shlS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SLL),
 121       new ShiftDecoder("shrS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SRL),
 122       null,
 123       new ShiftDecoder("sarS", ADDR_E, v_mode, ADDR_REG, CL, RTLOP_SRA)
 124       },
 125       {
 126       new InstructionDecoder("testb", ADDR_E, b_mode, ADDR_I, b_mode),
 127       null, /*new InstructionDecoder("(bad)", ADDR_E, b_mode)*/
 128       new LogicalDecoder("notb", ADDR_E, b_mode, RTLOP_NOT),
 129       new InstructionDecoder("negb", ADDR_E, b_mode),
 130       new ArithmeticDecoder("mulb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_UMUL),
 131       new ArithmeticDecoder("imulb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_SMUL),
 132       new ArithmeticDecoder("divb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_UDIV),
 133       new ArithmeticDecoder("idivb", ADDR_REG, AL, ADDR_E, b_mode, RTLOP_SDIV)
 134       },
 135       {
 136       new InstructionDecoder("testS", ADDR_E, v_mode, ADDR_I, v_mode),
 137       null,
 138       new LogicalDecoder("notS", ADDR_E, v_mode, RTLOP_NOT),
 139       new InstructionDecoder("negS", ADDR_E, v_mode),
 140       new ArithmeticDecoder("mulS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_UMUL),
 141       new ArithmeticDecoder("imulS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SMUL),
 142       new ArithmeticDecoder("divS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SDIV),
 143       new ArithmeticDecoder("idivS", ADDR_REG, EAX, ADDR_E, v_mode, RTLOP_SDIV)
 144       },
 145       {
 146       new ArithmeticDecoder("incb", ADDR_E, b_mode, RTLOP_ADD),
 147       new ArithmeticDecoder("decb", ADDR_E, b_mode, RTLOP_SUB),
 148       null,
 149       null,
 150       null,
 151       null,
 152       null,
 153       null
 154       },
 155       {
 156       new ArithmeticDecoder("incS", ADDR_E, v_mode, RTLOP_ADD),
 157       new ArithmeticDecoder("decS", ADDR_E, v_mode, RTLOP_SUB),
 158       new CallDecoder("call", ADDR_E, v_mode),
 159       new CallDecoder("lcall", ADDR_E, p_mode),
 160       new JmpDecoder("jmp", ADDR_E, v_mode),
 161       new JmpDecoder("ljmp", ADDR_E, p_mode),
 162       new InstructionDecoder("pushS", ADDR_E, v_mode),
 163       null
 164       },
 165       {
 166       new InstructionDecoder("sldt", ADDR_E, w_mode),
 167       new InstructionDecoder("str", ADDR_E, w_mode),
 168       new InstructionDecoder("lldt", ADDR_E, w_mode),
 169       new InstructionDecoder("ltr", ADDR_E, w_mode),
 170       new InstructionDecoder("verr", ADDR_E, w_mode),
 171       new InstructionDecoder("verw", ADDR_E, w_mode),
 172       null,
 173       null
 174       },
 175       {
 176       new InstructionDecoder("sgdt", ADDR_E, w_mode),
 177       new InstructionDecoder("sidt", ADDR_E, w_mode),
 178       new InstructionDecoder("lgdt", ADDR_E, w_mode),
 179       new InstructionDecoder("lidt", ADDR_E, w_mode),
 180       new InstructionDecoder("smsw", ADDR_E, w_mode),
 181       null,
 182       new InstructionDecoder("lmsw", ADDR_E, w_mode),
 183       new InstructionDecoder("invlpg", ADDR_E, w_mode)
 184       },
 185       {
 186       null,
 187       null,
 188       null,
 189       null,
 190       new InstructionDecoder("btS", ADDR_E, v_mode, ADDR_I, b_mode),
 191       new InstructionDecoder("btsS", ADDR_E, v_mode, ADDR_I, b_mode),
 192       new InstructionDecoder("btrS", ADDR_E, v_mode, ADDR_I, b_mode),
 193       new InstructionDecoder("btcS", ADDR_E, v_mode, ADDR_I, b_mode)
 194       },
 195       /*16*/
 196       {
 197       null,
 198       new SSEInstructionDecoder("cmpxch8b", ADDR_W, q_mode),
 199       null,
 200       null,
 201       null,
 202       null,
 203       null,
 204       null
 205       },
 206       /*17*/
 207       {
 208       null,
 209       null,
 210       new SSEShiftDecoder("psrlw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL),
 211       null,
 212       new SSEShiftDecoder("psraw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRA),
 213       null,
 214       new SSEShiftDecoder("psllw", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL),
 215       null
 216       },
 217       /*18*/
 218       {
 219       null,
 220       null,
 221       new SSEShiftDecoder("psrld", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL),
 222       null,
 223       new SSEShiftDecoder("psrad", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRA),
 224       null,
 225       new SSEShiftDecoder("pslld", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL),
 226       null
 227       },
 228       /*19*/
 229       {
 230       null,
 231       null,
 232       new SSEShiftDecoder("psrlq", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SRL),
 233       null,
 234       null,
 235       null,
 236       new SSEShiftDecoder("psllq", ADDR_P, q_mode, ADDR_I, b_mode, RTLOP_SLL),
 237       null
 238       },
 239       /*20 - Grp15*/
 240       {
 241       new SSEInstructionDecoder("fxsave"),
 242       new SSEInstructionDecoder("fxrstor"),
 243       new SSEInstructionDecoder("ldmxcsr"),
 244       new SSEInstructionDecoder("stmxcsr"),
 245       null,
 246       null,
 247       null,
 248       new SSEInstructionDecoder("clflush")
 249       },
 250       /*21 - Grp16*/
 251       {
 252       new SSEInstructionDecoder("prefetchnta"),
 253       new SSEInstructionDecoder("prefetcht0"),
 254       new SSEInstructionDecoder("prefetcht1"),
 255       new SSEInstructionDecoder("prefetcht2"),
 256       null,
 257       null,
 258       null,
 259       null
 260       },
 261       /*22 - Grp12:66*/
 262       {
 263       null,
 264       null,
 265       new SSEShiftDecoder("psrlw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SRL),
 266       null,
 267       new SSEShiftDecoder("psraw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SRA),
 268       null,
 269       new SSEShiftDecoder("psllw", ADDR_P, dq_mode, ADDR_I, b_mode, RTLOP_SLL),
 270       null
 271       },
 272       /*23 - Grp13:66*/
 273       {
 274       null,
 275       null,
 276       new SSEShiftDecoder("psrld", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL),
 277       null,
 278       new SSEShiftDecoder("psrad", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRA),
 279       null,
 280       new SSEShiftDecoder("pslld", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL),
 281       null
 282       },
 283       /*24 - - Grp14:66*/
 284       {
 285       null,
 286       null,
 287       new SSEShiftDecoder("psrlq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL),
 288       new SSEShiftDecoder("psrldq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SRL),
 289       null,
 290       null,
 291       new SSEShiftDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL),
 292       new SSEShiftDecoder("psllq", ADDR_W, dq_mode, ADDR_I, b_mode, RTLOP_SLL)
 293       }
 294 };
 295 
 296    public GRPDecoder(String name, int number) {
 297       super(name);
 298       this.number = number;
 299    }
 300 
 301    public Instruction decode(byte[] bytesArray, int index, int instrStartIndex, int segmentOverride, int prefixes, X86InstructionFactory factory) {
 302       this.byteIndex = index;
 303       this.instrStartIndex = instrStartIndex;
 304       this.prefixes = prefixes;
 305 
 306       int ModRM = readByte(bytesArray, byteIndex);
 307       int reg = (ModRM >> 3) & 7;
 308 
 309       InstructionDecoder instrDecoder = grpTable[number][reg];
 310       Instruction instr = null;
 311       if(instrDecoder != null) {
 312          instr = instrDecoder.decode(bytesArray, byteIndex, instrStartIndex, segmentOverride, prefixes, factory);
 313          byteIndex = instrDecoder.getCurrentIndex();
 314       } else {
 315          instr = factory.newIllegalInstruction();
 316       }
 317 
 318       return instr;
 319    }
 320 }