xref: /openbmc/qemu/target/i386/tcg/cc_helper.c (revision c94bee4cd6693c1c65ba43bb8970cf909dec378b)
11b248f14SClaudio Fontana /*
21b248f14SClaudio Fontana  *  x86 condition code helpers
31b248f14SClaudio Fontana  *
41b248f14SClaudio Fontana  *  Copyright (c) 2003 Fabrice Bellard
51b248f14SClaudio Fontana  *
61b248f14SClaudio Fontana  * This library is free software; you can redistribute it and/or
71b248f14SClaudio Fontana  * modify it under the terms of the GNU Lesser General Public
81b248f14SClaudio Fontana  * License as published by the Free Software Foundation; either
91b248f14SClaudio Fontana  * version 2.1 of the License, or (at your option) any later version.
101b248f14SClaudio Fontana  *
111b248f14SClaudio Fontana  * This library is distributed in the hope that it will be useful,
121b248f14SClaudio Fontana  * but WITHOUT ANY WARRANTY; without even the implied warranty of
131b248f14SClaudio Fontana  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
141b248f14SClaudio Fontana  * Lesser General Public License for more details.
151b248f14SClaudio Fontana  *
161b248f14SClaudio Fontana  * You should have received a copy of the GNU Lesser General Public
171b248f14SClaudio Fontana  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
181b248f14SClaudio Fontana  */
191b248f14SClaudio Fontana 
201b248f14SClaudio Fontana #include "qemu/osdep.h"
211b248f14SClaudio Fontana #include "cpu.h"
221b248f14SClaudio Fontana #include "exec/helper-proto.h"
23ed69e831SClaudio Fontana #include "helper-tcg.h"
241b248f14SClaudio Fontana 
251b248f14SClaudio Fontana #define SHIFT 0
26f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
271b248f14SClaudio Fontana #undef SHIFT
281b248f14SClaudio Fontana 
291b248f14SClaudio Fontana #define SHIFT 1
30f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
311b248f14SClaudio Fontana #undef SHIFT
321b248f14SClaudio Fontana 
331b248f14SClaudio Fontana #define SHIFT 2
34f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
351b248f14SClaudio Fontana #undef SHIFT
361b248f14SClaudio Fontana 
371b248f14SClaudio Fontana #ifdef TARGET_X86_64
381b248f14SClaudio Fontana 
391b248f14SClaudio Fontana #define SHIFT 3
40f1cc7c28SPhilippe Mathieu-Daudé #include "cc_helper_template.h.inc"
411b248f14SClaudio Fontana #undef SHIFT
421b248f14SClaudio Fontana 
431b248f14SClaudio Fontana #endif
441b248f14SClaudio Fontana 
compute_all_adcx(target_ulong dst,target_ulong src1,target_ulong src2)451b248f14SClaudio Fontana static target_ulong compute_all_adcx(target_ulong dst, target_ulong src1,
461b248f14SClaudio Fontana                                      target_ulong src2)
471b248f14SClaudio Fontana {
481b248f14SClaudio Fontana     return (src1 & ~CC_C) | (dst * CC_C);
491b248f14SClaudio Fontana }
501b248f14SClaudio Fontana 
compute_all_adox(target_ulong dst,target_ulong src1,target_ulong src2)511b248f14SClaudio Fontana static target_ulong compute_all_adox(target_ulong dst, target_ulong src1,
521b248f14SClaudio Fontana                                      target_ulong src2)
531b248f14SClaudio Fontana {
541b248f14SClaudio Fontana     return (src1 & ~CC_O) | (src2 * CC_O);
551b248f14SClaudio Fontana }
561b248f14SClaudio Fontana 
compute_all_adcox(target_ulong dst,target_ulong src1,target_ulong src2)571b248f14SClaudio Fontana static target_ulong compute_all_adcox(target_ulong dst, target_ulong src1,
581b248f14SClaudio Fontana                                       target_ulong src2)
591b248f14SClaudio Fontana {
601b248f14SClaudio Fontana     return (src1 & ~(CC_C | CC_O)) | (dst * CC_C) | (src2 * CC_O);
611b248f14SClaudio Fontana }
621b248f14SClaudio Fontana 
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)761b248f14SClaudio Fontana target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
771b248f14SClaudio Fontana                                    target_ulong src2, int op)
781b248f14SClaudio Fontana {
791b248f14SClaudio Fontana     switch (op) {
801b248f14SClaudio Fontana     default: /* should never happen */
811b248f14SClaudio Fontana         return 0;
821b248f14SClaudio Fontana 
831b248f14SClaudio Fontana     case CC_OP_EFLAGS:
841b248f14SClaudio Fontana         return src1;
851b248f14SClaudio Fontana     case CC_OP_POPCNT:
86944f4001SPaolo Bonzini         return dst ? 0 : CC_Z;
871b248f14SClaudio Fontana 
881b248f14SClaudio Fontana     case CC_OP_MULB:
891b248f14SClaudio Fontana         return compute_all_mulb(dst, src1);
901b248f14SClaudio Fontana     case CC_OP_MULW:
911b248f14SClaudio Fontana         return compute_all_mulw(dst, src1);
921b248f14SClaudio Fontana     case CC_OP_MULL:
931b248f14SClaudio Fontana         return compute_all_mull(dst, src1);
941b248f14SClaudio Fontana 
951b248f14SClaudio Fontana     case CC_OP_ADDB:
961b248f14SClaudio Fontana         return compute_all_addb(dst, src1);
971b248f14SClaudio Fontana     case CC_OP_ADDW:
981b248f14SClaudio Fontana         return compute_all_addw(dst, src1);
991b248f14SClaudio Fontana     case CC_OP_ADDL:
1001b248f14SClaudio Fontana         return compute_all_addl(dst, src1);
1011b248f14SClaudio Fontana 
1021b248f14SClaudio Fontana     case CC_OP_ADCB:
1031b248f14SClaudio Fontana         return compute_all_adcb(dst, src1, src2);
1041b248f14SClaudio Fontana     case CC_OP_ADCW:
1051b248f14SClaudio Fontana         return compute_all_adcw(dst, src1, src2);
1061b248f14SClaudio Fontana     case CC_OP_ADCL:
1071b248f14SClaudio Fontana         return compute_all_adcl(dst, src1, src2);
1081b248f14SClaudio Fontana 
1091b248f14SClaudio Fontana     case CC_OP_SUBB:
1101b248f14SClaudio Fontana         return compute_all_subb(dst, src1);
1111b248f14SClaudio Fontana     case CC_OP_SUBW:
1121b248f14SClaudio Fontana         return compute_all_subw(dst, src1);
1131b248f14SClaudio Fontana     case CC_OP_SUBL:
1141b248f14SClaudio Fontana         return compute_all_subl(dst, src1);
1151b248f14SClaudio Fontana 
1161b248f14SClaudio Fontana     case CC_OP_SBBB:
1171b248f14SClaudio Fontana         return compute_all_sbbb(dst, src1, src2);
1181b248f14SClaudio Fontana     case CC_OP_SBBW:
1191b248f14SClaudio Fontana         return compute_all_sbbw(dst, src1, src2);
1201b248f14SClaudio Fontana     case CC_OP_SBBL:
1211b248f14SClaudio Fontana         return compute_all_sbbl(dst, src1, src2);
1221b248f14SClaudio Fontana 
1231b248f14SClaudio Fontana     case CC_OP_LOGICB:
1241b248f14SClaudio Fontana         return compute_all_logicb(dst, src1);
1251b248f14SClaudio Fontana     case CC_OP_LOGICW:
1261b248f14SClaudio Fontana         return compute_all_logicw(dst, src1);
1271b248f14SClaudio Fontana     case CC_OP_LOGICL:
1281b248f14SClaudio Fontana         return compute_all_logicl(dst, src1);
1291b248f14SClaudio Fontana 
1301b248f14SClaudio Fontana     case CC_OP_INCB:
1311b248f14SClaudio Fontana         return compute_all_incb(dst, src1);
1321b248f14SClaudio Fontana     case CC_OP_INCW:
1331b248f14SClaudio Fontana         return compute_all_incw(dst, src1);
1341b248f14SClaudio Fontana     case CC_OP_INCL:
1351b248f14SClaudio Fontana         return compute_all_incl(dst, src1);
1361b248f14SClaudio Fontana 
1371b248f14SClaudio Fontana     case CC_OP_DECB:
1381b248f14SClaudio Fontana         return compute_all_decb(dst, src1);
1391b248f14SClaudio Fontana     case CC_OP_DECW:
1401b248f14SClaudio Fontana         return compute_all_decw(dst, src1);
1411b248f14SClaudio Fontana     case CC_OP_DECL:
1421b248f14SClaudio Fontana         return compute_all_decl(dst, src1);
1431b248f14SClaudio Fontana 
1441b248f14SClaudio Fontana     case CC_OP_SHLB:
1451b248f14SClaudio Fontana         return compute_all_shlb(dst, src1);
1461b248f14SClaudio Fontana     case CC_OP_SHLW:
1471b248f14SClaudio Fontana         return compute_all_shlw(dst, src1);
1481b248f14SClaudio Fontana     case CC_OP_SHLL:
1491b248f14SClaudio Fontana         return compute_all_shll(dst, src1);
1501b248f14SClaudio Fontana 
1511b248f14SClaudio Fontana     case CC_OP_SARB:
1521b248f14SClaudio Fontana         return compute_all_sarb(dst, src1);
1531b248f14SClaudio Fontana     case CC_OP_SARW:
1541b248f14SClaudio Fontana         return compute_all_sarw(dst, src1);
1551b248f14SClaudio Fontana     case CC_OP_SARL:
1561b248f14SClaudio Fontana         return compute_all_sarl(dst, src1);
1571b248f14SClaudio Fontana 
1581b248f14SClaudio Fontana     case CC_OP_BMILGB:
1591b248f14SClaudio Fontana         return compute_all_bmilgb(dst, src1);
1601b248f14SClaudio Fontana     case CC_OP_BMILGW:
1611b248f14SClaudio Fontana         return compute_all_bmilgw(dst, src1);
1621b248f14SClaudio Fontana     case CC_OP_BMILGL:
1631b248f14SClaudio Fontana         return compute_all_bmilgl(dst, src1);
1641b248f14SClaudio Fontana 
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 
1721b248f14SClaudio Fontana     case CC_OP_ADCX:
1731b248f14SClaudio Fontana         return compute_all_adcx(dst, src1, src2);
1741b248f14SClaudio Fontana     case CC_OP_ADOX:
1751b248f14SClaudio Fontana         return compute_all_adox(dst, src1, src2);
1761b248f14SClaudio Fontana     case CC_OP_ADCOX:
1771b248f14SClaudio Fontana         return compute_all_adcox(dst, src1, src2);
1781b248f14SClaudio Fontana 
1791b248f14SClaudio Fontana #ifdef TARGET_X86_64
1801b248f14SClaudio Fontana     case CC_OP_MULQ:
1811b248f14SClaudio Fontana         return compute_all_mulq(dst, src1);
1821b248f14SClaudio Fontana     case CC_OP_ADDQ:
1831b248f14SClaudio Fontana         return compute_all_addq(dst, src1);
1841b248f14SClaudio Fontana     case CC_OP_ADCQ:
1851b248f14SClaudio Fontana         return compute_all_adcq(dst, src1, src2);
1861b248f14SClaudio Fontana     case CC_OP_SUBQ:
1871b248f14SClaudio Fontana         return compute_all_subq(dst, src1);
1881b248f14SClaudio Fontana     case CC_OP_SBBQ:
1891b248f14SClaudio Fontana         return compute_all_sbbq(dst, src1, src2);
1901b248f14SClaudio Fontana     case CC_OP_LOGICQ:
1911b248f14SClaudio Fontana         return compute_all_logicq(dst, src1);
1921b248f14SClaudio Fontana     case CC_OP_INCQ:
1931b248f14SClaudio Fontana         return compute_all_incq(dst, src1);
1941b248f14SClaudio Fontana     case CC_OP_DECQ:
1951b248f14SClaudio Fontana         return compute_all_decq(dst, src1);
1961b248f14SClaudio Fontana     case CC_OP_SHLQ:
1971b248f14SClaudio Fontana         return compute_all_shlq(dst, src1);
1981b248f14SClaudio Fontana     case CC_OP_SARQ:
1991b248f14SClaudio Fontana         return compute_all_sarq(dst, src1);
2001b248f14SClaudio Fontana     case CC_OP_BMILGQ:
2011b248f14SClaudio Fontana         return compute_all_bmilgq(dst, src1);
20283a3a20eSRichard Henderson     case CC_OP_BLSIQ:
20383a3a20eSRichard Henderson         return compute_all_blsiq(dst, src1);
2041b248f14SClaudio Fontana #endif
2051b248f14SClaudio Fontana     }
2061b248f14SClaudio Fontana }
2071b248f14SClaudio Fontana 
cpu_cc_compute_all(CPUX86State * env)2082455e9cfSPaolo Bonzini uint32_t cpu_cc_compute_all(CPUX86State *env)
2091b248f14SClaudio Fontana {
2102455e9cfSPaolo Bonzini     return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, CC_OP);
2111b248f14SClaudio Fontana }
2121b248f14SClaudio Fontana 
helper_cc_compute_c(target_ulong dst,target_ulong src1,target_ulong src2,int op)2131b248f14SClaudio Fontana target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
2141b248f14SClaudio Fontana                                  target_ulong src2, int op)
2151b248f14SClaudio Fontana {
2161b248f14SClaudio Fontana     switch (op) {
2171b248f14SClaudio Fontana     default: /* should never happen */
2181b248f14SClaudio Fontana     case CC_OP_LOGICB:
2191b248f14SClaudio Fontana     case CC_OP_LOGICW:
2201b248f14SClaudio Fontana     case CC_OP_LOGICL:
2211b248f14SClaudio Fontana     case CC_OP_LOGICQ:
2221b248f14SClaudio Fontana     case CC_OP_POPCNT:
2231b248f14SClaudio Fontana         return 0;
2241b248f14SClaudio Fontana 
2251b248f14SClaudio Fontana     case CC_OP_EFLAGS:
2261b248f14SClaudio Fontana     case CC_OP_SARB:
2271b248f14SClaudio Fontana     case CC_OP_SARW:
2281b248f14SClaudio Fontana     case CC_OP_SARL:
2291b248f14SClaudio Fontana     case CC_OP_SARQ:
2301b248f14SClaudio Fontana     case CC_OP_ADOX:
2311b248f14SClaudio Fontana         return src1 & 1;
2321b248f14SClaudio Fontana 
2331b248f14SClaudio Fontana     case CC_OP_INCB:
2341b248f14SClaudio Fontana     case CC_OP_INCW:
2351b248f14SClaudio Fontana     case CC_OP_INCL:
2361b248f14SClaudio Fontana     case CC_OP_INCQ:
2371b248f14SClaudio Fontana     case CC_OP_DECB:
2381b248f14SClaudio Fontana     case CC_OP_DECW:
2391b248f14SClaudio Fontana     case CC_OP_DECL:
2401b248f14SClaudio Fontana     case CC_OP_DECQ:
2411b248f14SClaudio Fontana         return src1;
2421b248f14SClaudio Fontana 
2431b248f14SClaudio Fontana     case CC_OP_MULB:
2441b248f14SClaudio Fontana     case CC_OP_MULW:
2451b248f14SClaudio Fontana     case CC_OP_MULL:
2461b248f14SClaudio Fontana     case CC_OP_MULQ:
2471b248f14SClaudio Fontana         return src1 != 0;
2481b248f14SClaudio Fontana 
2491b248f14SClaudio Fontana     case CC_OP_ADCX:
2501b248f14SClaudio Fontana     case CC_OP_ADCOX:
2511b248f14SClaudio Fontana         return dst;
2521b248f14SClaudio Fontana 
2531b248f14SClaudio Fontana     case CC_OP_ADDB:
2541b248f14SClaudio Fontana         return compute_c_addb(dst, src1);
2551b248f14SClaudio Fontana     case CC_OP_ADDW:
2561b248f14SClaudio Fontana         return compute_c_addw(dst, src1);
2571b248f14SClaudio Fontana     case CC_OP_ADDL:
2581b248f14SClaudio Fontana         return compute_c_addl(dst, src1);
2591b248f14SClaudio Fontana 
2601b248f14SClaudio Fontana     case CC_OP_ADCB:
2611b248f14SClaudio Fontana         return compute_c_adcb(dst, src1, src2);
2621b248f14SClaudio Fontana     case CC_OP_ADCW:
2631b248f14SClaudio Fontana         return compute_c_adcw(dst, src1, src2);
2641b248f14SClaudio Fontana     case CC_OP_ADCL:
2651b248f14SClaudio Fontana         return compute_c_adcl(dst, src1, src2);
2661b248f14SClaudio Fontana 
2671b248f14SClaudio Fontana     case CC_OP_SUBB:
2681b248f14SClaudio Fontana         return compute_c_subb(dst, src1);
2691b248f14SClaudio Fontana     case CC_OP_SUBW:
2701b248f14SClaudio Fontana         return compute_c_subw(dst, src1);
2711b248f14SClaudio Fontana     case CC_OP_SUBL:
2721b248f14SClaudio Fontana         return compute_c_subl(dst, src1);
2731b248f14SClaudio Fontana 
2741b248f14SClaudio Fontana     case CC_OP_SBBB:
2751b248f14SClaudio Fontana         return compute_c_sbbb(dst, src1, src2);
2761b248f14SClaudio Fontana     case CC_OP_SBBW:
2771b248f14SClaudio Fontana         return compute_c_sbbw(dst, src1, src2);
2781b248f14SClaudio Fontana     case CC_OP_SBBL:
2791b248f14SClaudio Fontana         return compute_c_sbbl(dst, src1, src2);
2801b248f14SClaudio Fontana 
2811b248f14SClaudio Fontana     case CC_OP_SHLB:
2821b248f14SClaudio Fontana         return compute_c_shlb(dst, src1);
2831b248f14SClaudio Fontana     case CC_OP_SHLW:
2841b248f14SClaudio Fontana         return compute_c_shlw(dst, src1);
2851b248f14SClaudio Fontana     case CC_OP_SHLL:
2861b248f14SClaudio Fontana         return compute_c_shll(dst, src1);
2871b248f14SClaudio Fontana 
2881b248f14SClaudio Fontana     case CC_OP_BMILGB:
2891b248f14SClaudio Fontana         return compute_c_bmilgb(dst, src1);
2901b248f14SClaudio Fontana     case CC_OP_BMILGW:
2911b248f14SClaudio Fontana         return compute_c_bmilgw(dst, src1);
2921b248f14SClaudio Fontana     case CC_OP_BMILGL:
2931b248f14SClaudio Fontana         return compute_c_bmilgl(dst, src1);
2941b248f14SClaudio Fontana 
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 
3021b248f14SClaudio Fontana #ifdef TARGET_X86_64
3031b248f14SClaudio Fontana     case CC_OP_ADDQ:
3041b248f14SClaudio Fontana         return compute_c_addq(dst, src1);
3051b248f14SClaudio Fontana     case CC_OP_ADCQ:
3061b248f14SClaudio Fontana         return compute_c_adcq(dst, src1, src2);
3071b248f14SClaudio Fontana     case CC_OP_SUBQ:
3081b248f14SClaudio Fontana         return compute_c_subq(dst, src1);
3091b248f14SClaudio Fontana     case CC_OP_SBBQ:
3101b248f14SClaudio Fontana         return compute_c_sbbq(dst, src1, src2);
3111b248f14SClaudio Fontana     case CC_OP_SHLQ:
3121b248f14SClaudio Fontana         return compute_c_shlq(dst, src1);
3131b248f14SClaudio Fontana     case CC_OP_BMILGQ:
3141b248f14SClaudio Fontana         return compute_c_bmilgq(dst, src1);
31583a3a20eSRichard Henderson     case CC_OP_BLSIQ:
31683a3a20eSRichard Henderson         return compute_c_blsiq(dst, src1);
3171b248f14SClaudio Fontana #endif
3181b248f14SClaudio Fontana     }
3191b248f14SClaudio Fontana }
3201b248f14SClaudio Fontana 
helper_write_eflags(CPUX86State * env,target_ulong t0,uint32_t update_mask)3211b248f14SClaudio Fontana void helper_write_eflags(CPUX86State *env, target_ulong t0,
3221b248f14SClaudio Fontana                          uint32_t update_mask)
3231b248f14SClaudio Fontana {
3241b248f14SClaudio Fontana     cpu_load_eflags(env, t0, update_mask);
3251b248f14SClaudio Fontana }
3261b248f14SClaudio Fontana 
helper_read_eflags(CPUX86State * env)3271b248f14SClaudio Fontana target_ulong helper_read_eflags(CPUX86State *env)
3281b248f14SClaudio Fontana {
3291b248f14SClaudio Fontana     uint32_t eflags;
3301b248f14SClaudio Fontana 
3312455e9cfSPaolo Bonzini     eflags = cpu_cc_compute_all(env);
3321b248f14SClaudio Fontana     eflags |= (env->df & DF_MASK);
3331b248f14SClaudio Fontana     eflags |= env->eflags & ~(VM_MASK | RF_MASK);
3341b248f14SClaudio Fontana     return eflags;
3351b248f14SClaudio Fontana }
3361b248f14SClaudio Fontana 
helper_clts(CPUX86State * env)3371b248f14SClaudio Fontana void helper_clts(CPUX86State *env)
3381b248f14SClaudio Fontana {
3391b248f14SClaudio Fontana     env->cr[0] &= ~CR0_TS_MASK;
3401b248f14SClaudio Fontana     env->hflags &= ~HF_TS_MASK;
3411b248f14SClaudio Fontana }
342