xref: /qemu/target/i386/tcg/cc_helper.c (revision 24899cdcd238f885e9b7c0c708f624aa29090c21)
15918fffbSBlue Swirl /*
25918fffbSBlue Swirl  *  x86 condition code helpers
35918fffbSBlue Swirl  *
45918fffbSBlue Swirl  *  Copyright (c) 2003 Fabrice Bellard
55918fffbSBlue Swirl  *
65918fffbSBlue Swirl  * This library is free software; you can redistribute it and/or
75918fffbSBlue Swirl  * modify it under the terms of the GNU Lesser General Public
85918fffbSBlue Swirl  * License as published by the Free Software Foundation; either
9d9ff33adSChetan Pant  * version 2.1 of the License, or (at your option) any later version.
105918fffbSBlue Swirl  *
115918fffbSBlue Swirl  * This library is distributed in the hope that it will be useful,
125918fffbSBlue Swirl  * but WITHOUT ANY WARRANTY; without even the implied warranty of
135918fffbSBlue Swirl  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
145918fffbSBlue Swirl  * Lesser General Public License for more details.
155918fffbSBlue Swirl  *
165918fffbSBlue Swirl  * You should have received a copy of the GNU Lesser General Public
175918fffbSBlue Swirl  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
185918fffbSBlue Swirl  */
195918fffbSBlue Swirl 
20b6a0aa05SPeter Maydell #include "qemu/osdep.h"
215918fffbSBlue Swirl #include "cpu.h"
222ef6175aSRichard Henderson #include "exec/helper-proto.h"
23ed69e831SClaudio Fontana #include "helper-tcg.h"
245918fffbSBlue Swirl 
255918fffbSBlue Swirl #define SHIFT 0
26f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
275918fffbSBlue Swirl #undef SHIFT
285918fffbSBlue Swirl 
295918fffbSBlue Swirl #define SHIFT 1
30f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
315918fffbSBlue Swirl #undef SHIFT
325918fffbSBlue Swirl 
335918fffbSBlue Swirl #define SHIFT 2
34f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
355918fffbSBlue Swirl #undef SHIFT
365918fffbSBlue Swirl 
375918fffbSBlue Swirl #ifdef TARGET_X86_64
385918fffbSBlue Swirl 
395918fffbSBlue Swirl #define SHIFT 3
40f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
415918fffbSBlue Swirl #undef SHIFT
425918fffbSBlue Swirl 
435918fffbSBlue Swirl #endif
445918fffbSBlue Swirl 
compute_all_adcx(target_ulong dst,target_ulong src1,target_ulong src2)45cd7f97caSRichard Henderson static target_ulong compute_all_adcx(target_ulong dst, target_ulong src1,
46cd7f97caSRichard Henderson                                      target_ulong src2)
47cd7f97caSRichard Henderson {
48cd7f97caSRichard Henderson     return (src1 & ~CC_C) | (dst * CC_C);
49cd7f97caSRichard Henderson }
50cd7f97caSRichard Henderson 
compute_all_adox(target_ulong dst,target_ulong src1,target_ulong src2)51cd7f97caSRichard Henderson static target_ulong compute_all_adox(target_ulong dst, target_ulong src1,
52cd7f97caSRichard Henderson                                      target_ulong src2)
53cd7f97caSRichard Henderson {
54cd7f97caSRichard Henderson     return (src1 & ~CC_O) | (src2 * CC_O);
55cd7f97caSRichard Henderson }
56cd7f97caSRichard Henderson 
compute_all_adcox(target_ulong dst,target_ulong src1,target_ulong src2)57cd7f97caSRichard Henderson static target_ulong compute_all_adcox(target_ulong dst, target_ulong src1,
58cd7f97caSRichard Henderson                                       target_ulong src2)
59cd7f97caSRichard Henderson {
60cd7f97caSRichard Henderson     return (src1 & ~(CC_C | CC_O)) | (dst * CC_C) | (src2 * CC_O);
61cd7f97caSRichard Henderson }
62cd7f97caSRichard Henderson 
helper_cc_compute_nz(target_ulong dst,target_ulong src1,int op)63*ae14b33dSPaolo Bonzini target_ulong helper_cc_compute_nz(target_ulong dst, target_ulong src1,
64*ae14b33dSPaolo Bonzini                                   int op)
65*ae14b33dSPaolo Bonzini {
66*ae14b33dSPaolo Bonzini     if (CC_OP_HAS_EFLAGS(op)) {
67*ae14b33dSPaolo Bonzini         return ~src1 & CC_Z;
68*ae14b33dSPaolo Bonzini     } else {
69*ae14b33dSPaolo Bonzini         MemOp size = cc_op_size(op);
70*ae14b33dSPaolo Bonzini         target_ulong mask = MAKE_64BIT_MASK(0, 8 << size);
71*ae14b33dSPaolo Bonzini 
72*ae14b33dSPaolo Bonzini         return dst & mask;
73*ae14b33dSPaolo Bonzini     }
74*ae14b33dSPaolo Bonzini }
75*ae14b33dSPaolo Bonzini 
helper_cc_compute_all(target_ulong dst,target_ulong src1,target_ulong src2,int op)76988c3eb0SRichard Henderson target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
77988c3eb0SRichard Henderson                                    target_ulong src2, int op)
785918fffbSBlue Swirl {
795918fffbSBlue Swirl     switch (op) {
805918fffbSBlue Swirl     default: /* should never happen */
815918fffbSBlue Swirl         return 0;
825918fffbSBlue Swirl 
835918fffbSBlue Swirl     case CC_OP_EFLAGS:
848601c0b6SRichard Henderson         return src1;
854885c3c4SRichard Henderson     case CC_OP_POPCNT:
86944f4001SPaolo Bonzini         return dst ? 0 : CC_Z;
875918fffbSBlue Swirl 
885918fffbSBlue Swirl     case CC_OP_MULB:
898601c0b6SRichard Henderson         return compute_all_mulb(dst, src1);
905918fffbSBlue Swirl     case CC_OP_MULW:
918601c0b6SRichard Henderson         return compute_all_mulw(dst, src1);
925918fffbSBlue Swirl     case CC_OP_MULL:
938601c0b6SRichard Henderson         return compute_all_mull(dst, src1);
945918fffbSBlue Swirl 
955918fffbSBlue Swirl     case CC_OP_ADDB:
968601c0b6SRichard Henderson         return compute_all_addb(dst, src1);
975918fffbSBlue Swirl     case CC_OP_ADDW:
988601c0b6SRichard Henderson         return compute_all_addw(dst, src1);
995918fffbSBlue Swirl     case CC_OP_ADDL:
1008601c0b6SRichard Henderson         return compute_all_addl(dst, src1);
1015918fffbSBlue Swirl 
1025918fffbSBlue Swirl     case CC_OP_ADCB:
103988c3eb0SRichard Henderson         return compute_all_adcb(dst, src1, src2);
1045918fffbSBlue Swirl     case CC_OP_ADCW:
105988c3eb0SRichard Henderson         return compute_all_adcw(dst, src1, src2);
1065918fffbSBlue Swirl     case CC_OP_ADCL:
107988c3eb0SRichard Henderson         return compute_all_adcl(dst, src1, src2);
1085918fffbSBlue Swirl 
1095918fffbSBlue Swirl     case CC_OP_SUBB:
1108601c0b6SRichard Henderson         return compute_all_subb(dst, src1);
1115918fffbSBlue Swirl     case CC_OP_SUBW:
1128601c0b6SRichard Henderson         return compute_all_subw(dst, src1);
1135918fffbSBlue Swirl     case CC_OP_SUBL:
1148601c0b6SRichard Henderson         return compute_all_subl(dst, src1);
1155918fffbSBlue Swirl 
1165918fffbSBlue Swirl     case CC_OP_SBBB:
117988c3eb0SRichard Henderson         return compute_all_sbbb(dst, src1, src2);
1185918fffbSBlue Swirl     case CC_OP_SBBW:
119988c3eb0SRichard Henderson         return compute_all_sbbw(dst, src1, src2);
1205918fffbSBlue Swirl     case CC_OP_SBBL:
121988c3eb0SRichard Henderson         return compute_all_sbbl(dst, src1, src2);
1225918fffbSBlue Swirl 
1235918fffbSBlue Swirl     case CC_OP_LOGICB:
1248601c0b6SRichard Henderson         return compute_all_logicb(dst, src1);
1255918fffbSBlue Swirl     case CC_OP_LOGICW:
1268601c0b6SRichard Henderson         return compute_all_logicw(dst, src1);
1275918fffbSBlue Swirl     case CC_OP_LOGICL:
1288601c0b6SRichard Henderson         return compute_all_logicl(dst, src1);
1295918fffbSBlue Swirl 
1305918fffbSBlue Swirl     case CC_OP_INCB:
1318601c0b6SRichard Henderson         return compute_all_incb(dst, src1);
1325918fffbSBlue Swirl     case CC_OP_INCW:
1338601c0b6SRichard Henderson         return compute_all_incw(dst, src1);
1345918fffbSBlue Swirl     case CC_OP_INCL:
1358601c0b6SRichard Henderson         return compute_all_incl(dst, src1);
1365918fffbSBlue Swirl 
1375918fffbSBlue Swirl     case CC_OP_DECB:
1388601c0b6SRichard Henderson         return compute_all_decb(dst, src1);
1395918fffbSBlue Swirl     case CC_OP_DECW:
1408601c0b6SRichard Henderson         return compute_all_decw(dst, src1);
1415918fffbSBlue Swirl     case CC_OP_DECL:
1428601c0b6SRichard Henderson         return compute_all_decl(dst, src1);
1435918fffbSBlue Swirl 
1445918fffbSBlue Swirl     case CC_OP_SHLB:
1458601c0b6SRichard Henderson         return compute_all_shlb(dst, src1);
1465918fffbSBlue Swirl     case CC_OP_SHLW:
1478601c0b6SRichard Henderson         return compute_all_shlw(dst, src1);
1485918fffbSBlue Swirl     case CC_OP_SHLL:
1498601c0b6SRichard Henderson         return compute_all_shll(dst, src1);
1505918fffbSBlue Swirl 
1515918fffbSBlue Swirl     case CC_OP_SARB:
1528601c0b6SRichard Henderson         return compute_all_sarb(dst, src1);
1535918fffbSBlue Swirl     case CC_OP_SARW:
1548601c0b6SRichard Henderson         return compute_all_sarw(dst, src1);
1555918fffbSBlue Swirl     case CC_OP_SARL:
1568601c0b6SRichard Henderson         return compute_all_sarl(dst, src1);
1575918fffbSBlue Swirl 
158bc4b43dcSRichard Henderson     case CC_OP_BMILGB:
159bc4b43dcSRichard Henderson         return compute_all_bmilgb(dst, src1);
160bc4b43dcSRichard Henderson     case CC_OP_BMILGW:
161bc4b43dcSRichard Henderson         return compute_all_bmilgw(dst, src1);
162bc4b43dcSRichard Henderson     case CC_OP_BMILGL:
163bc4b43dcSRichard Henderson         return compute_all_bmilgl(dst, src1);
164bc4b43dcSRichard Henderson 
16583a3a20eSRichard Henderson     case CC_OP_BLSIB:
16683a3a20eSRichard Henderson         return compute_all_blsib(dst, src1);
16783a3a20eSRichard Henderson     case CC_OP_BLSIW:
16883a3a20eSRichard Henderson         return compute_all_blsiw(dst, src1);
16983a3a20eSRichard Henderson     case CC_OP_BLSIL:
17083a3a20eSRichard Henderson         return compute_all_blsil(dst, src1);
17183a3a20eSRichard Henderson 
172cd7f97caSRichard Henderson     case CC_OP_ADCX:
173cd7f97caSRichard Henderson         return compute_all_adcx(dst, src1, src2);
174cd7f97caSRichard Henderson     case CC_OP_ADOX:
175cd7f97caSRichard Henderson         return compute_all_adox(dst, src1, src2);
176cd7f97caSRichard Henderson     case CC_OP_ADCOX:
177cd7f97caSRichard Henderson         return compute_all_adcox(dst, src1, src2);
178cd7f97caSRichard Henderson 
1795918fffbSBlue Swirl #ifdef TARGET_X86_64
1805918fffbSBlue Swirl     case CC_OP_MULQ:
1818601c0b6SRichard Henderson         return compute_all_mulq(dst, src1);
1825918fffbSBlue Swirl     case CC_OP_ADDQ:
1838601c0b6SRichard Henderson         return compute_all_addq(dst, src1);
1845918fffbSBlue Swirl     case CC_OP_ADCQ:
185988c3eb0SRichard Henderson         return compute_all_adcq(dst, src1, src2);
1865918fffbSBlue Swirl     case CC_OP_SUBQ:
1878601c0b6SRichard Henderson         return compute_all_subq(dst, src1);
1885918fffbSBlue Swirl     case CC_OP_SBBQ:
189988c3eb0SRichard Henderson         return compute_all_sbbq(dst, src1, src2);
1905918fffbSBlue Swirl     case CC_OP_LOGICQ:
1918601c0b6SRichard Henderson         return compute_all_logicq(dst, src1);
1925918fffbSBlue Swirl     case CC_OP_INCQ:
1938601c0b6SRichard Henderson         return compute_all_incq(dst, src1);
1945918fffbSBlue Swirl     case CC_OP_DECQ:
1958601c0b6SRichard Henderson         return compute_all_decq(dst, src1);
1965918fffbSBlue Swirl     case CC_OP_SHLQ:
1978601c0b6SRichard Henderson         return compute_all_shlq(dst, src1);
1985918fffbSBlue Swirl     case CC_OP_SARQ:
1998601c0b6SRichard Henderson         return compute_all_sarq(dst, src1);
200bc4b43dcSRichard Henderson     case CC_OP_BMILGQ:
201bc4b43dcSRichard Henderson         return compute_all_bmilgq(dst, src1);
20283a3a20eSRichard Henderson     case CC_OP_BLSIQ:
20383a3a20eSRichard Henderson         return compute_all_blsiq(dst, src1);
2045918fffbSBlue Swirl #endif
2055918fffbSBlue Swirl     }
2065918fffbSBlue Swirl }
2075918fffbSBlue Swirl 
cpu_cc_compute_all(CPUX86State * env)2082455e9cfSPaolo Bonzini uint32_t cpu_cc_compute_all(CPUX86State *env)
2095918fffbSBlue Swirl {
2102455e9cfSPaolo Bonzini     return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, CC_OP);
2115918fffbSBlue Swirl }
2125918fffbSBlue Swirl 
helper_cc_compute_c(target_ulong dst,target_ulong src1,target_ulong src2,int op)213988c3eb0SRichard Henderson target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
214988c3eb0SRichard Henderson                                  target_ulong src2, int op)
2155918fffbSBlue Swirl {
2165918fffbSBlue Swirl     switch (op) {
2175918fffbSBlue Swirl     default: /* should never happen */
2188601c0b6SRichard Henderson     case CC_OP_LOGICB:
2198601c0b6SRichard Henderson     case CC_OP_LOGICW:
2208601c0b6SRichard Henderson     case CC_OP_LOGICL:
2218601c0b6SRichard Henderson     case CC_OP_LOGICQ:
2224885c3c4SRichard Henderson     case CC_OP_POPCNT:
2235918fffbSBlue Swirl         return 0;
2245918fffbSBlue Swirl 
2255918fffbSBlue Swirl     case CC_OP_EFLAGS:
2268601c0b6SRichard Henderson     case CC_OP_SARB:
2278601c0b6SRichard Henderson     case CC_OP_SARW:
2288601c0b6SRichard Henderson     case CC_OP_SARL:
2298601c0b6SRichard Henderson     case CC_OP_SARQ:
230cd7f97caSRichard Henderson     case CC_OP_ADOX:
2318601c0b6SRichard Henderson         return src1 & 1;
2325918fffbSBlue Swirl 
2335918fffbSBlue Swirl     case CC_OP_INCB:
2345918fffbSBlue Swirl     case CC_OP_INCW:
2355918fffbSBlue Swirl     case CC_OP_INCL:
2368601c0b6SRichard Henderson     case CC_OP_INCQ:
2375918fffbSBlue Swirl     case CC_OP_DECB:
2385918fffbSBlue Swirl     case CC_OP_DECW:
2395918fffbSBlue Swirl     case CC_OP_DECL:
2408601c0b6SRichard Henderson     case CC_OP_DECQ:
2418601c0b6SRichard Henderson         return src1;
2428601c0b6SRichard Henderson 
2438601c0b6SRichard Henderson     case CC_OP_MULB:
2448601c0b6SRichard Henderson     case CC_OP_MULW:
2458601c0b6SRichard Henderson     case CC_OP_MULL:
2468601c0b6SRichard Henderson     case CC_OP_MULQ:
2478601c0b6SRichard Henderson         return src1 != 0;
2488601c0b6SRichard Henderson 
249cd7f97caSRichard Henderson     case CC_OP_ADCX:
250cd7f97caSRichard Henderson     case CC_OP_ADCOX:
251cd7f97caSRichard Henderson         return dst;
252cd7f97caSRichard Henderson 
2538601c0b6SRichard Henderson     case CC_OP_ADDB:
2548601c0b6SRichard Henderson         return compute_c_addb(dst, src1);
2558601c0b6SRichard Henderson     case CC_OP_ADDW:
2568601c0b6SRichard Henderson         return compute_c_addw(dst, src1);
2578601c0b6SRichard Henderson     case CC_OP_ADDL:
2588601c0b6SRichard Henderson         return compute_c_addl(dst, src1);
2598601c0b6SRichard Henderson 
2608601c0b6SRichard Henderson     case CC_OP_ADCB:
261988c3eb0SRichard Henderson         return compute_c_adcb(dst, src1, src2);
2628601c0b6SRichard Henderson     case CC_OP_ADCW:
263988c3eb0SRichard Henderson         return compute_c_adcw(dst, src1, src2);
2648601c0b6SRichard Henderson     case CC_OP_ADCL:
265988c3eb0SRichard Henderson         return compute_c_adcl(dst, src1, src2);
2668601c0b6SRichard Henderson 
2678601c0b6SRichard Henderson     case CC_OP_SUBB:
2688601c0b6SRichard Henderson         return compute_c_subb(dst, src1);
2698601c0b6SRichard Henderson     case CC_OP_SUBW:
2708601c0b6SRichard Henderson         return compute_c_subw(dst, src1);
2718601c0b6SRichard Henderson     case CC_OP_SUBL:
2728601c0b6SRichard Henderson         return compute_c_subl(dst, src1);
2738601c0b6SRichard Henderson 
2748601c0b6SRichard Henderson     case CC_OP_SBBB:
275988c3eb0SRichard Henderson         return compute_c_sbbb(dst, src1, src2);
2768601c0b6SRichard Henderson     case CC_OP_SBBW:
277988c3eb0SRichard Henderson         return compute_c_sbbw(dst, src1, src2);
2788601c0b6SRichard Henderson     case CC_OP_SBBL:
279988c3eb0SRichard Henderson         return compute_c_sbbl(dst, src1, src2);
2805918fffbSBlue Swirl 
2815918fffbSBlue Swirl     case CC_OP_SHLB:
2828601c0b6SRichard Henderson         return compute_c_shlb(dst, src1);
2835918fffbSBlue Swirl     case CC_OP_SHLW:
2848601c0b6SRichard Henderson         return compute_c_shlw(dst, src1);
2855918fffbSBlue Swirl     case CC_OP_SHLL:
2868601c0b6SRichard Henderson         return compute_c_shll(dst, src1);
2875918fffbSBlue Swirl 
288bc4b43dcSRichard Henderson     case CC_OP_BMILGB:
289bc4b43dcSRichard Henderson         return compute_c_bmilgb(dst, src1);
290bc4b43dcSRichard Henderson     case CC_OP_BMILGW:
291bc4b43dcSRichard Henderson         return compute_c_bmilgw(dst, src1);
292bc4b43dcSRichard Henderson     case CC_OP_BMILGL:
293bc4b43dcSRichard Henderson         return compute_c_bmilgl(dst, src1);
294bc4b43dcSRichard Henderson 
29583a3a20eSRichard Henderson     case CC_OP_BLSIB:
29683a3a20eSRichard Henderson         return compute_c_blsib(dst, src1);
29783a3a20eSRichard Henderson     case CC_OP_BLSIW:
29883a3a20eSRichard Henderson         return compute_c_blsiw(dst, src1);
29983a3a20eSRichard Henderson     case CC_OP_BLSIL:
30083a3a20eSRichard Henderson         return compute_c_blsil(dst, src1);
30183a3a20eSRichard Henderson 
3025918fffbSBlue Swirl #ifdef TARGET_X86_64
3035918fffbSBlue Swirl     case CC_OP_ADDQ:
3048601c0b6SRichard Henderson         return compute_c_addq(dst, src1);
3055918fffbSBlue Swirl     case CC_OP_ADCQ:
306988c3eb0SRichard Henderson         return compute_c_adcq(dst, src1, src2);
3075918fffbSBlue Swirl     case CC_OP_SUBQ:
3088601c0b6SRichard Henderson         return compute_c_subq(dst, src1);
3095918fffbSBlue Swirl     case CC_OP_SBBQ:
310988c3eb0SRichard Henderson         return compute_c_sbbq(dst, src1, src2);
3115918fffbSBlue Swirl     case CC_OP_SHLQ:
3128601c0b6SRichard Henderson         return compute_c_shlq(dst, src1);
313bc4b43dcSRichard Henderson     case CC_OP_BMILGQ:
314bc4b43dcSRichard Henderson         return compute_c_bmilgq(dst, src1);
31583a3a20eSRichard Henderson     case CC_OP_BLSIQ:
31683a3a20eSRichard Henderson         return compute_c_blsiq(dst, src1);
3175918fffbSBlue Swirl #endif
3185918fffbSBlue Swirl     }
3195918fffbSBlue Swirl }
3205918fffbSBlue Swirl 
helper_write_eflags(CPUX86State * env,target_ulong t0,uint32_t update_mask)321f0967a1aSBlue Swirl void helper_write_eflags(CPUX86State *env, target_ulong t0,
322f0967a1aSBlue Swirl                          uint32_t update_mask)
3235918fffbSBlue Swirl {
3245918fffbSBlue Swirl     cpu_load_eflags(env, t0, update_mask);
3255918fffbSBlue Swirl }
3265918fffbSBlue Swirl 
helper_read_eflags(CPUX86State * env)327f0967a1aSBlue Swirl target_ulong helper_read_eflags(CPUX86State *env)
3285918fffbSBlue Swirl {
3295918fffbSBlue Swirl     uint32_t eflags;
3305918fffbSBlue Swirl 
3312455e9cfSPaolo Bonzini     eflags = cpu_cc_compute_all(env);
33280cf2c81Sliguang     eflags |= (env->df & DF_MASK);
3335918fffbSBlue Swirl     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
3345918fffbSBlue Swirl     return eflags;
3355918fffbSBlue Swirl }
3365918fffbSBlue Swirl 
helper_clts(CPUX86State * env)337f0967a1aSBlue Swirl void helper_clts(CPUX86State *env)
3385918fffbSBlue Swirl {
3395918fffbSBlue Swirl     env->cr[0] &= ~CR0_TS_MASK;
3405918fffbSBlue Swirl     env->hflags &= ~HF_TS_MASK;
3415918fffbSBlue Swirl }
342