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