xref: /openbmc/qemu/target/i386/tcg/cc_helper.c (revision 784155cdcb02ffaae44afecab93861070e7d652d)
1  /*
2   *  x86 condition code helpers
3   *
4   *  Copyright (c) 2003 Fabrice Bellard
5   *
6   * This library is free software; you can redistribute it and/or
7   * modify it under the terms of the GNU Lesser General Public
8   * License as published by the Free Software Foundation; either
9   * version 2.1 of the License, or (at your option) any later version.
10   *
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   *
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  #include "qemu/osdep.h"
21  #include "cpu.h"
22  #include "exec/helper-proto.h"
23  #include "helper-tcg.h"
24  
25  const uint8_t parity_table[256] = {
26      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
27      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
28      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
29      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
30      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
31      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
32      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
33      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
34      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
35      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
36      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
37      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
38      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
39      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
40      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
41      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
42      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
43      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
44      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
45      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
46      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
47      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
48      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
49      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
50      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
51      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
52      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
53      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
54      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
55      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
56      CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
57      0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
58  };
59  
60  #define SHIFT 0
61  #include "cc_helper_template.h.inc"
62  #undef SHIFT
63  
64  #define SHIFT 1
65  #include "cc_helper_template.h.inc"
66  #undef SHIFT
67  
68  #define SHIFT 2
69  #include "cc_helper_template.h.inc"
70  #undef SHIFT
71  
72  #ifdef TARGET_X86_64
73  
74  #define SHIFT 3
75  #include "cc_helper_template.h.inc"
76  #undef SHIFT
77  
78  #endif
79  
80  static target_ulong compute_all_adcx(target_ulong dst, target_ulong src1,
81                                       target_ulong src2)
82  {
83      return (src1 & ~CC_C) | (dst * CC_C);
84  }
85  
86  static target_ulong compute_all_adox(target_ulong dst, target_ulong src1,
87                                       target_ulong src2)
88  {
89      return (src1 & ~CC_O) | (src2 * CC_O);
90  }
91  
92  static target_ulong compute_all_adcox(target_ulong dst, target_ulong src1,
93                                        target_ulong src2)
94  {
95      return (src1 & ~(CC_C | CC_O)) | (dst * CC_C) | (src2 * CC_O);
96  }
97  
98  target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
99                                     target_ulong src2, int op)
100  {
101      switch (op) {
102      default: /* should never happen */
103          return 0;
104  
105      case CC_OP_EFLAGS:
106          return src1;
107      case CC_OP_CLR:
108          return CC_Z | CC_P;
109      case CC_OP_POPCNT:
110          return src1 ? 0 : CC_Z;
111  
112      case CC_OP_MULB:
113          return compute_all_mulb(dst, src1);
114      case CC_OP_MULW:
115          return compute_all_mulw(dst, src1);
116      case CC_OP_MULL:
117          return compute_all_mull(dst, src1);
118  
119      case CC_OP_ADDB:
120          return compute_all_addb(dst, src1);
121      case CC_OP_ADDW:
122          return compute_all_addw(dst, src1);
123      case CC_OP_ADDL:
124          return compute_all_addl(dst, src1);
125  
126      case CC_OP_ADCB:
127          return compute_all_adcb(dst, src1, src2);
128      case CC_OP_ADCW:
129          return compute_all_adcw(dst, src1, src2);
130      case CC_OP_ADCL:
131          return compute_all_adcl(dst, src1, src2);
132  
133      case CC_OP_SUBB:
134          return compute_all_subb(dst, src1);
135      case CC_OP_SUBW:
136          return compute_all_subw(dst, src1);
137      case CC_OP_SUBL:
138          return compute_all_subl(dst, src1);
139  
140      case CC_OP_SBBB:
141          return compute_all_sbbb(dst, src1, src2);
142      case CC_OP_SBBW:
143          return compute_all_sbbw(dst, src1, src2);
144      case CC_OP_SBBL:
145          return compute_all_sbbl(dst, src1, src2);
146  
147      case CC_OP_LOGICB:
148          return compute_all_logicb(dst, src1);
149      case CC_OP_LOGICW:
150          return compute_all_logicw(dst, src1);
151      case CC_OP_LOGICL:
152          return compute_all_logicl(dst, src1);
153  
154      case CC_OP_INCB:
155          return compute_all_incb(dst, src1);
156      case CC_OP_INCW:
157          return compute_all_incw(dst, src1);
158      case CC_OP_INCL:
159          return compute_all_incl(dst, src1);
160  
161      case CC_OP_DECB:
162          return compute_all_decb(dst, src1);
163      case CC_OP_DECW:
164          return compute_all_decw(dst, src1);
165      case CC_OP_DECL:
166          return compute_all_decl(dst, src1);
167  
168      case CC_OP_SHLB:
169          return compute_all_shlb(dst, src1);
170      case CC_OP_SHLW:
171          return compute_all_shlw(dst, src1);
172      case CC_OP_SHLL:
173          return compute_all_shll(dst, src1);
174  
175      case CC_OP_SARB:
176          return compute_all_sarb(dst, src1);
177      case CC_OP_SARW:
178          return compute_all_sarw(dst, src1);
179      case CC_OP_SARL:
180          return compute_all_sarl(dst, src1);
181  
182      case CC_OP_BMILGB:
183          return compute_all_bmilgb(dst, src1);
184      case CC_OP_BMILGW:
185          return compute_all_bmilgw(dst, src1);
186      case CC_OP_BMILGL:
187          return compute_all_bmilgl(dst, src1);
188  
189      case CC_OP_ADCX:
190          return compute_all_adcx(dst, src1, src2);
191      case CC_OP_ADOX:
192          return compute_all_adox(dst, src1, src2);
193      case CC_OP_ADCOX:
194          return compute_all_adcox(dst, src1, src2);
195  
196  #ifdef TARGET_X86_64
197      case CC_OP_MULQ:
198          return compute_all_mulq(dst, src1);
199      case CC_OP_ADDQ:
200          return compute_all_addq(dst, src1);
201      case CC_OP_ADCQ:
202          return compute_all_adcq(dst, src1, src2);
203      case CC_OP_SUBQ:
204          return compute_all_subq(dst, src1);
205      case CC_OP_SBBQ:
206          return compute_all_sbbq(dst, src1, src2);
207      case CC_OP_LOGICQ:
208          return compute_all_logicq(dst, src1);
209      case CC_OP_INCQ:
210          return compute_all_incq(dst, src1);
211      case CC_OP_DECQ:
212          return compute_all_decq(dst, src1);
213      case CC_OP_SHLQ:
214          return compute_all_shlq(dst, src1);
215      case CC_OP_SARQ:
216          return compute_all_sarq(dst, src1);
217      case CC_OP_BMILGQ:
218          return compute_all_bmilgq(dst, src1);
219  #endif
220      }
221  }
222  
223  uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
224  {
225      return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, op);
226  }
227  
228  target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
229                                   target_ulong src2, int op)
230  {
231      switch (op) {
232      default: /* should never happen */
233      case CC_OP_LOGICB:
234      case CC_OP_LOGICW:
235      case CC_OP_LOGICL:
236      case CC_OP_LOGICQ:
237      case CC_OP_CLR:
238      case CC_OP_POPCNT:
239          return 0;
240  
241      case CC_OP_EFLAGS:
242      case CC_OP_SARB:
243      case CC_OP_SARW:
244      case CC_OP_SARL:
245      case CC_OP_SARQ:
246      case CC_OP_ADOX:
247          return src1 & 1;
248  
249      case CC_OP_INCB:
250      case CC_OP_INCW:
251      case CC_OP_INCL:
252      case CC_OP_INCQ:
253      case CC_OP_DECB:
254      case CC_OP_DECW:
255      case CC_OP_DECL:
256      case CC_OP_DECQ:
257          return src1;
258  
259      case CC_OP_MULB:
260      case CC_OP_MULW:
261      case CC_OP_MULL:
262      case CC_OP_MULQ:
263          return src1 != 0;
264  
265      case CC_OP_ADCX:
266      case CC_OP_ADCOX:
267          return dst;
268  
269      case CC_OP_ADDB:
270          return compute_c_addb(dst, src1);
271      case CC_OP_ADDW:
272          return compute_c_addw(dst, src1);
273      case CC_OP_ADDL:
274          return compute_c_addl(dst, src1);
275  
276      case CC_OP_ADCB:
277          return compute_c_adcb(dst, src1, src2);
278      case CC_OP_ADCW:
279          return compute_c_adcw(dst, src1, src2);
280      case CC_OP_ADCL:
281          return compute_c_adcl(dst, src1, src2);
282  
283      case CC_OP_SUBB:
284          return compute_c_subb(dst, src1);
285      case CC_OP_SUBW:
286          return compute_c_subw(dst, src1);
287      case CC_OP_SUBL:
288          return compute_c_subl(dst, src1);
289  
290      case CC_OP_SBBB:
291          return compute_c_sbbb(dst, src1, src2);
292      case CC_OP_SBBW:
293          return compute_c_sbbw(dst, src1, src2);
294      case CC_OP_SBBL:
295          return compute_c_sbbl(dst, src1, src2);
296  
297      case CC_OP_SHLB:
298          return compute_c_shlb(dst, src1);
299      case CC_OP_SHLW:
300          return compute_c_shlw(dst, src1);
301      case CC_OP_SHLL:
302          return compute_c_shll(dst, src1);
303  
304      case CC_OP_BMILGB:
305          return compute_c_bmilgb(dst, src1);
306      case CC_OP_BMILGW:
307          return compute_c_bmilgw(dst, src1);
308      case CC_OP_BMILGL:
309          return compute_c_bmilgl(dst, src1);
310  
311  #ifdef TARGET_X86_64
312      case CC_OP_ADDQ:
313          return compute_c_addq(dst, src1);
314      case CC_OP_ADCQ:
315          return compute_c_adcq(dst, src1, src2);
316      case CC_OP_SUBQ:
317          return compute_c_subq(dst, src1);
318      case CC_OP_SBBQ:
319          return compute_c_sbbq(dst, src1, src2);
320      case CC_OP_SHLQ:
321          return compute_c_shlq(dst, src1);
322      case CC_OP_BMILGQ:
323          return compute_c_bmilgq(dst, src1);
324  #endif
325      }
326  }
327  
328  void helper_write_eflags(CPUX86State *env, target_ulong t0,
329                           uint32_t update_mask)
330  {
331      cpu_load_eflags(env, t0, update_mask);
332  }
333  
334  target_ulong helper_read_eflags(CPUX86State *env)
335  {
336      uint32_t eflags;
337  
338      eflags = cpu_cc_compute_all(env, CC_OP);
339      eflags |= (env->df & DF_MASK);
340      eflags |= env->eflags & ~(VM_MASK | RF_MASK);
341      return eflags;
342  }
343  
344  void helper_clts(CPUX86State *env)
345  {
346      env->cr[0] &= ~CR0_TS_MASK;
347      env->hflags &= ~HF_TS_MASK;
348  }
349