0
|
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 }
|