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 }