1 /* |
|
2 * Copyright (c) 2002, 2003, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * 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 } |
|