1 : /* Copyright (c) 2010 The Native Client Authors. All rights reserved.
2 : * Use of this source code is governed by a BSD-style license that can be
3 : * found in the LICENSE file.
4 : */
5 :
6 : /*
7 : * ncdecodex87.c - Handles x87 instructions.
8 : *
9 : * Note: These instructions are derived from tabler A-10 in Appendx
10 : * section A.2.7 - x87 Encodings in AMD document 24594-Rev.3.14-September
11 : * 2007, "AMD64 Architecture Programmer's manual Volume 3: General-Purpose
12 : * and System Instructions".
13 : *
14 : * Note: This modeling code doesn't handle several aspects of floating point
15 : * operations. This includes:
16 : *
17 : * 1) Doesn't model condition flags.
18 : * 2) Doesn't model floating point stack adjustments.
19 : * 3) Doesn't model all differences in size of pointed to memory ($Mf is used
20 : * in such cases).
21 : *
22 : * Note: %st0 and %st1 have been inserted and made explicit, when necessary
23 : * to match the disassembler xed.
24 : */
25 :
26 : #ifndef NACL_TRUSTED_BUT_NOT_TCB
27 : #error("This file is not meant for use in the TCB")
28 : #endif
29 :
30 : #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_forms.h"
31 : #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tablegen.h"
32 :
33 1 : void NaClDefX87Insts(struct NaClSymbolTable* st) {
34 : /* See Table A-10 in AMD manual for source of definitions.
35 : * Note: Added register ST0 when used in instructions, but
36 : * not explicitly listed in table A-10. This information
37 : * was derived from xed tests.
38 : */
39 :
40 : /* Define D8 x87 instructions. */
41 :
42 1 : NaClDefine("d8/0: Fadd %st0, $Md", NACLi_X87, st, Binary);
43 1 : NaClDefine("d8/1: Fmul %st0, $Md", NACLi_X87, st, Binary);
44 1 : NaClDefine("d8/2: Fcom %st0, $Md", NACLi_X87, st, Compare);
45 1 : NaClDefine("d8/3: Fcomp %st0, $Md", NACLi_X87, st, Compare);
46 1 : NaClDefine("d8/4: Fsub %st0, $Md", NACLi_X87, st, Binary);
47 1 : NaClDefine("d8/5: Fsubr %st0, $Md", NACLi_X87, st, Binary);
48 1 : NaClDefine("d8/6: Fdiv %st0, $Md", NACLi_X87, st, Binary);
49 1 : NaClDefine("d8/7: Fdivr %st0, $Md", NACLi_X87, st, Binary);
50 1 : NaClDefIter("d8C0+@i: Fadd %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
51 1 : NaClDefIter("d8C8+@i: Fmul %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
52 1 : NaClDefIter("d8d0+@i: Fcom %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
53 1 : NaClDefIter("d8d8+@i: Fcomp %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
54 1 : NaClDefIter("d8e0+@i: Fsub %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
55 1 : NaClDefIter("d8e8+@i: Fsubr %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
56 1 : NaClDefIter("d8f0+@i: Fdiv %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
57 1 : NaClDefIter("d8f8+@i: Fdivr %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
58 :
59 : /* Define D9 x87 instructions. */
60 :
61 1 : NaClDefine("d9/0: Fld %st0, $Md", NACLi_X87, st, Move);
62 1 : NaClDefine("d9/1: Invalid", NACLi_INVALID, st, Other);
63 1 : NaClDefine("d9/2: Fst $Md, %st0", NACLi_X87, st, Move);
64 1 : NaClDefine("d9/3: Fstp $Md, %st0", NACLi_X87, st, Move);
65 1 : NaClDefine("d9/4: Fldenv $Mf", NACLi_X87, st, Uses);
66 1 : NaClDefine("d9/5: Fldcw $Mw", NACLi_X87, st, Uses);
67 1 : NaClDefine("d9/6: Fnstenv $Mf", NACLi_X87, st, UnarySet);
68 1 : NaClDefine("d9/7: Fnstcw $Mw", NACLi_X87, st, UnarySet);
69 1 : NaClDefIter("d9c0+@i: Fld %st0, %st@i", 0, 7, NACLi_X87, st, Move);
70 1 : NaClDefIter("d9c8+@i: Fxch %st0, %st@i", 0, 7, NACLi_X87, st, Exchange);
71 1 : NaClDefine("d9d0: Fnop", NACLi_X87, st, Other);
72 1 : NaClDefIter("d9d0+@i: Invalid", 1, 7, NACLi_INVALID, st, Other);
73 1 : NaClDefIter("d9d8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
74 1 : NaClDefine("d9e0: Fchs %st0", NACLi_X87, st, UnaryUpdate);
75 1 : NaClDefine("d9e1: Fabs %st0", NACLi_X87, st, UnaryUpdate);
76 1 : NaClDefIter("d9e0+@i: Invalid", 2, 3, NACLi_INVALID, st, Other);
77 1 : NaClDefine("d9e4: Ftst %st0", NACLi_X87, st, Uses);
78 1 : NaClDefine("d9e5: Fxam %st0", NACLi_X87, st, Uses);
79 1 : NaClDefIter("d9e0+@i: Invalid", 6, 7, NACLi_INVALID, st, Other);
80 1 : NaClDefine("d9e8: Fld1 %st0", NACLi_X87, st, UnaryUpdate);
81 1 : NaClDefine("d9e9: Fldl2t %st0", NACLi_X87, st, UnaryUpdate);
82 1 : NaClDefine("d9ea: Fldl2e %st0", NACLi_X87, st, UnaryUpdate);
83 1 : NaClDefine("d9eb: Fldpi %st0", NACLi_X87, st, UnaryUpdate);
84 1 : NaClDefine("d9ec: Fldlg2 %st0", NACLi_X87, st, UnaryUpdate);
85 1 : NaClDefine("d9ed: Fldln2 %st0", NACLi_X87, st, UnaryUpdate);
86 1 : NaClDefine("d9ee: Fldz %st0", NACLi_X87, st, UnaryUpdate);
87 1 : NaClDefine("d9ef: Invalid", NACLi_INVALID, st, Other);
88 1 : NaClDefine("d9f0: F2xm1 %st0", NACLi_X87, st, UnaryUpdate);
89 1 : NaClDefine("d9f1: Fyl2x %st0 %st1", NACLi_X87, st, Binary);
90 1 : NaClDefine("d9f2: Fptan %st0 %st1", NACLi_X87, st, Move);
91 1 : NaClDefine("d9f3: Fpatan %st0, %st1", NACLi_X87, st, Binary);
92 1 : NaClDefine("d9f4: Fxtract %st0, %st1", NACLi_X87, st, Move);
93 1 : NaClDefine("d9f5: Fprem1 %st0, %st1", NACLi_X87, st, Binary);
94 1 : NaClDefine("d9f6: Fdecstp", NACLi_X87, st, Other);
95 1 : NaClDefine("d9f7: Fincstp", NACLi_X87, st, Other);
96 1 : NaClDefine("d9f8: Fprem %st0, %st1", NACLi_X87, st, Binary);
97 1 : NaClDefine("d9f9: Fyl2xp1 %st0, %st1", NACLi_X87, st, Binary);
98 1 : NaClDefine("d9fa: Fsqrt %st0", NACLi_X87, st, UnaryUpdate);
99 : /* NaClDefine("d9fb: Fsincos %st0, %st1", NACLi_X87, st, Move); */
100 1 : NaClDefine("d9fb: Fsincos %st0, %st1", NACLi_X87_FSINCOS, st, Move);
101 1 : NaClDefine("d9fc: Frndint %st0", NACLi_X87, st, UnaryUpdate);
102 1 : NaClDefine("d9fd: Fscale %st0, %st1", NACLi_X87, st, Binary);
103 1 : NaClDefine("d9fe: Fsin %st0", NACLi_X87, st, UnaryUpdate);
104 1 : NaClDefine("d9ff: Fcos %st0", NACLi_X87, st, UnaryUpdate);
105 :
106 : /* Define DA x87 instructions. */
107 :
108 1 : NaClDefine("da/0: Fiadd %st0, $Md", NACLi_X87, st, Binary);
109 1 : NaClDefine("da/1: Fimul %st0, $Md", NACLi_X87, st, Binary);
110 1 : NaClDefine("da/2: Ficom %st0, $Md", NACLi_X87, st, Binary);
111 1 : NaClDefine("da/3: Ficomp %st0, $Md", NACLi_X87, st, Binary);
112 1 : NaClDefine("da/4: Fisub %st0, $Md", NACLi_X87, st, Binary);
113 1 : NaClDefine("da/5: Fisubr %st0, $Md", NACLi_X87, st, Binary);
114 1 : NaClDefine("da/6: Fidiv %st0, $Md", NACLi_X87, st, Binary);
115 1 : NaClDefine("da/7: Fidivr %st0, $Md", NACLi_X87, st, Binary);
116 1 : NaClDefIter("dac0+@i: Fcmovb %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
117 1 : NaClDefIter("dac8+@i: Fcmove %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
118 1 : NaClDefIter("dad0+@i: Fcmovbe %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
119 1 : NaClDefIter("dad8+@i: Fcmovu %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
120 1 : NaClDefIter("dae0+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
121 1 : NaClDefine("dae8: Invalid", NACLi_INVALID, st, Other);
122 1 : NaClDefine("dae9: Fucompp %st0, %st1", NACLi_X87, st, Compare);
123 1 : NaClDefIter("dae8+@i: Invalid", 2, 7, NACLi_INVALID, st, Other);
124 1 : NaClDefIter("daf0+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
125 1 : NaClDefIter("daf8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
126 :
127 : /* Define DB x87 instructions. */
128 :
129 1 : NaClDefine("db/0: Fild %st0, $Md", NACLi_X87, st, Move);
130 1 : NaClDefine("db/1: Fisttp $Md, %st0", NACLi_X87, st, Move);
131 1 : NaClDefine("db/2: Fist $Md, %st0", NACLi_X87, st, Move);
132 1 : NaClDefine("db/3: Fistp $Md, %st0", NACLi_X87, st, Move);
133 1 : NaClDefine("db/4: Invalid", NACLi_INVALID, st, Other);
134 1 : NaClDefine("db/5: Fld %st0, $Mf", NACLi_X87, st, Move);
135 1 : NaClDefine("db/6: Invalid", NACLi_INVALID, st, Other);
136 1 : NaClDefine("db/7: Fstp $Mf, %st0", NACLi_X87, st, Move);
137 1 : NaClDefIter("dbc0+@i: Fcmovnb %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
138 1 : NaClDefIter("dbc8+@i: Fcmovne %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
139 1 : NaClDefIter("dbd0+@i: Fcmovnbe %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
140 1 : NaClDefIter("dbd8+@i: Fcmovnu %st0, %st@i", 0, 7, NACLi_X87, st, Binary);
141 1 : NaClDefIter("dbe0+@i: Invalid", 0, 1, NACLi_INVALID, st, Other);
142 1 : NaClDefine("dbe2: Fnclex", NACLi_X87, st, Other);
143 1 : NaClDefine("dbe3: Fninit", NACLi_X87, st, Other);
144 1 : NaClDefIter("dbe0+@i: Invalid", 4, 7, NACLi_INVALID, st, Other);
145 1 : NaClDefIter("dbe8+@i: Fucomi %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
146 1 : NaClDefIter("dbf0+@i: Fcomi %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
147 1 : NaClDefIter("dbf8+@i: Invalid", NACLi_INVALID, 0, 7, st, Other);
148 :
149 : /* Define DC x87 instructions. */
150 :
151 1 : NaClDefine("dc/0: Fadd %st0, $Mq", NACLi_X87, st, Binary);
152 1 : NaClDefine("dc/1: Fmul %st0, $Mq", NACLi_X87, st , Binary);
153 1 : NaClDefine("dc/2: Fcom %st0, $Mq", NACLi_X87, st, Compare);
154 1 : NaClDefine("dc/3: Fcomp %st0, $Mq", NACLi_X87, st, Compare);
155 1 : NaClDefine("dc/4: Fsub %st0, $Mq", NACLi_X87, st, Binary);
156 1 : NaClDefine("dc/5: Fsubr %st0, $Mq", NACLi_X87, st, Binary);
157 1 : NaClDefine("dc/6: Fdiv %st0, $Mq", NACLi_X87, st, Binary);
158 1 : NaClDefine("dc/7: Fdivr %st0, $Mq", NACLi_X87, st, Binary);
159 1 : NaClDefIter("dcc0+@i: Fadd %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
160 1 : NaClDefIter("dcc8+@i: Fmul %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
161 1 : NaClDefIter("dcd0+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
162 1 : NaClDefIter("dcd8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
163 1 : NaClDefIter("dce0+@i: Fsubr %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
164 1 : NaClDefIter("dce8+@i: Fsub %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
165 1 : NaClDefIter("dcf0+@i: Fdivr %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
166 1 : NaClDefIter("dcf8+@i: Fdiv %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
167 :
168 : /* Define DD x87 instructions. */
169 :
170 1 : NaClDefine("dd/0: Fld %st0, $Mq", NACLi_X87, st, Move);
171 1 : NaClDefine("dd/1: Fisttp $Mq, %st0", NACLi_X87, st, Move);
172 1 : NaClDefine("dd/2: Fst $Mq, %st0", NACLi_X87, st, Move);
173 1 : NaClDefine("dd/3: Fstp $Mq, %st0", NACLi_X87, st, Move);
174 1 : NaClDefine("dd/4: Frstor $Mf", NACLi_X87, st, Uses);
175 1 : NaClDefine("dd/5: Invalid", NACLi_INVALID, st, Other);
176 1 : NaClDefine("dd/6: Fnsave $Mf", NACLi_X87, st, UnarySet);
177 1 : NaClDefine("dd/7: Fnstsw $Mw", NACLi_X87, st, UnarySet);
178 1 : NaClDefIter("ddc0+@i: Ffree %st@i", 0, 7, NACLi_X87, st, Other);
179 1 : NaClDefIter("ddc8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
180 1 : NaClDefIter("ddd0+@i: Fst %st@i, %st0", 0, 7, NACLi_X87, st, Move);
181 1 : NaClDefIter("ddd8+@i: Fstp %st@i %st0", 0, 7, NACLi_X87, st, Move);
182 1 : NaClDefIter("dde0+@i: Fucom %st0, %st@i", 0, 7, NACLi_X87, st , Compare);
183 1 : NaClDefIter("dde8+@i: Fucomp %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
184 1 : NaClDefIter("ddf0+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
185 1 : NaClDefIter("ddf8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
186 :
187 :
188 : /* Define DE x87 instructions. */
189 :
190 1 : NaClDefine("de/0: Fiadd %st0, $Mw", NACLi_X87, st, Binary);
191 1 : NaClDefine("de/1: Fimul %st0, $Mw", NACLi_X87, st, Binary);
192 1 : NaClDefine("de/2: Ficom %st0, $Mw", NACLi_X87, st, Compare);
193 1 : NaClDefine("de/3: Ficomp %st0, $Mw", NACLi_X87, st, Compare);
194 1 : NaClDefine("de/4: Fisub %st0, $Mw", NACLi_X87, st, Binary);
195 1 : NaClDefine("de/5: Fisubr %st0, $Mw", NACLi_X87, st, Binary);
196 1 : NaClDefine("de/6: Fidiv %st0, $Mw", NACLi_X87, st, Binary);
197 1 : NaClDefine("de/7: Fidivr %st0, $Mw", NACLi_X87, st, Binary);
198 1 : NaClDefIter("dec0+@i: Faddp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
199 1 : NaClDefIter("dec8+@i: Fmulp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
200 1 : NaClDefIter("ded0+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
201 1 : NaClDefine("ded8: Invalid", NACLi_INVALID, st, Other);
202 1 : NaClDefine("ded9: Fcompp %st0, %st1", NACLi_X87, st, Compare);
203 1 : NaClDefIter("ded8+@i: Invalid", 2, 7, NACLi_INVALID, st, Other);
204 1 : NaClDefIter("dee0+@i: Fsubrp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
205 1 : NaClDefIter("dee8+@i: Fsubp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
206 1 : NaClDefIter("def0+@i: Fdivrp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
207 1 : NaClDefIter("def8+@i: Fdivp %st@i, %st0", 0, 7, NACLi_X87, st, Binary);
208 :
209 : /* Define DF x87 instructions. */
210 1 : NaClDefine("df/0: Fild %st0, $Mw", NACLi_X87, st , Move);
211 1 : NaClDefine("df/1: Fisttp $Mw, %st0", NACLi_X87, st, Move);
212 1 : NaClDefine("df/2: Fist $Mw, %st0", NACLi_X87, st, Move);
213 1 : NaClDefine("df/3: Fistp $Mw, %st0", NACLi_X87, st, Move);
214 1 : NaClDefine("df/4: Fbld %st0, $Mf", NACLi_X87, st, Move);
215 1 : NaClDefine("df/5: Fild %st0, $Mf", NACLi_X87, st, Move);
216 1 : NaClDefine("df/6: Fbstp $Mf, %st0", NACLi_X87, st , Move);
217 1 : NaClDefine("df/7: Fistp $Mf, %st0", NACLi_X87, st, Move);
218 1 : NaClDefIter("dfc0+@i: Invalid", 0, 7, NACLi_X87, st, Other);
219 1 : NaClDefIter("dfc8+@i: Invalid", 0, 7, NACLi_X87, st, Other);
220 1 : NaClDefIter("dfd0+@i: Invalid", 0, 7, NACLi_X87, st, Other);
221 1 : NaClDefIter("dfd8+@i: Invalid", 0, 7, NACLi_X87, st, Other);
222 1 : NaClDefine("dfe0: Fnstsw %ax", NACLi_X87, st, UnarySet);
223 1 : NaClDefIter("dfe0+@i: Invalid", 1, 7, NACLi_INVALID, st, Other);
224 1 : NaClDefIter("dfe8+@i: Fucomip %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
225 1 : NaClDefIter("dff0+@i: Fcomip %st0, %st@i", 0, 7, NACLi_X87, st, Compare);
226 1 : NaClDefIter("dff8+@i: Invalid", 0, 7, NACLi_INVALID, st, Other);
227 :
228 : /* todo(karl) What about "9b db e2 Fclex" ? */
229 : /* todo(karl) What about "9b db e3 finit" ? */
230 : /* todo(karl) What about "9b d9 /6 Fstenv" ? */
231 : /* todo(karl) What about "9b d9 /7 Fstcw" ? */
232 : /* todo(karl) What about "9b dd /6 Fsave" ? */
233 : /* todo(karl) What about "9b dd /7 Fstsw" ? */
234 : /* todo(karl) What about "9b df e0 Fstsw" ? */
235 1 : }
|