qemu/target/i386/cc_helper.c
<<
>>
Prefs
   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 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
  24const uint8_t parity_table[256] = {
  25    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  26    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  27    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  28    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  29    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  30    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  31    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  32    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  33    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  34    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  35    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  36    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  37    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  38    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  39    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  40    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  41    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  42    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  43    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  44    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  45    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  46    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  47    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  48    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  49    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  50    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  51    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  52    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  53    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  54    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  55    CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
  56    0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
  57};
  58
  59#define SHIFT 0
  60#include "cc_helper_template.h"
  61#undef SHIFT
  62
  63#define SHIFT 1
  64#include "cc_helper_template.h"
  65#undef SHIFT
  66
  67#define SHIFT 2
  68#include "cc_helper_template.h"
  69#undef SHIFT
  70
  71#ifdef TARGET_X86_64
  72
  73#define SHIFT 3
  74#include "cc_helper_template.h"
  75#undef SHIFT
  76
  77#endif
  78
  79static target_ulong compute_all_adcx(target_ulong dst, target_ulong src1,
  80                                     target_ulong src2)
  81{
  82    return (src1 & ~CC_C) | (dst * CC_C);
  83}
  84
  85static target_ulong compute_all_adox(target_ulong dst, target_ulong src1,
  86                                     target_ulong src2)
  87{
  88    return (src1 & ~CC_O) | (src2 * CC_O);
  89}
  90
  91static target_ulong compute_all_adcox(target_ulong dst, target_ulong src1,
  92                                      target_ulong src2)
  93{
  94    return (src1 & ~(CC_C | CC_O)) | (dst * CC_C) | (src2 * CC_O);
  95}
  96
  97target_ulong helper_cc_compute_all(target_ulong dst, target_ulong src1,
  98                                   target_ulong src2, int op)
  99{
 100    switch (op) {
 101    default: /* should never happen */
 102        return 0;
 103
 104    case CC_OP_EFLAGS:
 105        return src1;
 106    case CC_OP_CLR:
 107        return CC_Z | CC_P;
 108    case CC_OP_POPCNT:
 109        return src1 ? 0 : CC_Z;
 110
 111    case CC_OP_MULB:
 112        return compute_all_mulb(dst, src1);
 113    case CC_OP_MULW:
 114        return compute_all_mulw(dst, src1);
 115    case CC_OP_MULL:
 116        return compute_all_mull(dst, src1);
 117
 118    case CC_OP_ADDB:
 119        return compute_all_addb(dst, src1);
 120    case CC_OP_ADDW:
 121        return compute_all_addw(dst, src1);
 122    case CC_OP_ADDL:
 123        return compute_all_addl(dst, src1);
 124
 125    case CC_OP_ADCB:
 126        return compute_all_adcb(dst, src1, src2);
 127    case CC_OP_ADCW:
 128        return compute_all_adcw(dst, src1, src2);
 129    case CC_OP_ADCL:
 130        return compute_all_adcl(dst, src1, src2);
 131
 132    case CC_OP_SUBB:
 133        return compute_all_subb(dst, src1);
 134    case CC_OP_SUBW:
 135        return compute_all_subw(dst, src1);
 136    case CC_OP_SUBL:
 137        return compute_all_subl(dst, src1);
 138
 139    case CC_OP_SBBB:
 140        return compute_all_sbbb(dst, src1, src2);
 141    case CC_OP_SBBW:
 142        return compute_all_sbbw(dst, src1, src2);
 143    case CC_OP_SBBL:
 144        return compute_all_sbbl(dst, src1, src2);
 145
 146    case CC_OP_LOGICB:
 147        return compute_all_logicb(dst, src1);
 148    case CC_OP_LOGICW:
 149        return compute_all_logicw(dst, src1);
 150    case CC_OP_LOGICL:
 151        return compute_all_logicl(dst, src1);
 152
 153    case CC_OP_INCB:
 154        return compute_all_incb(dst, src1);
 155    case CC_OP_INCW:
 156        return compute_all_incw(dst, src1);
 157    case CC_OP_INCL:
 158        return compute_all_incl(dst, src1);
 159
 160    case CC_OP_DECB:
 161        return compute_all_decb(dst, src1);
 162    case CC_OP_DECW:
 163        return compute_all_decw(dst, src1);
 164    case CC_OP_DECL:
 165        return compute_all_decl(dst, src1);
 166
 167    case CC_OP_SHLB:
 168        return compute_all_shlb(dst, src1);
 169    case CC_OP_SHLW:
 170        return compute_all_shlw(dst, src1);
 171    case CC_OP_SHLL:
 172        return compute_all_shll(dst, src1);
 173
 174    case CC_OP_SARB:
 175        return compute_all_sarb(dst, src1);
 176    case CC_OP_SARW:
 177        return compute_all_sarw(dst, src1);
 178    case CC_OP_SARL:
 179        return compute_all_sarl(dst, src1);
 180
 181    case CC_OP_BMILGB:
 182        return compute_all_bmilgb(dst, src1);
 183    case CC_OP_BMILGW:
 184        return compute_all_bmilgw(dst, src1);
 185    case CC_OP_BMILGL:
 186        return compute_all_bmilgl(dst, src1);
 187
 188    case CC_OP_ADCX:
 189        return compute_all_adcx(dst, src1, src2);
 190    case CC_OP_ADOX:
 191        return compute_all_adox(dst, src1, src2);
 192    case CC_OP_ADCOX:
 193        return compute_all_adcox(dst, src1, src2);
 194
 195#ifdef TARGET_X86_64
 196    case CC_OP_MULQ:
 197        return compute_all_mulq(dst, src1);
 198    case CC_OP_ADDQ:
 199        return compute_all_addq(dst, src1);
 200    case CC_OP_ADCQ:
 201        return compute_all_adcq(dst, src1, src2);
 202    case CC_OP_SUBQ:
 203        return compute_all_subq(dst, src1);
 204    case CC_OP_SBBQ:
 205        return compute_all_sbbq(dst, src1, src2);
 206    case CC_OP_LOGICQ:
 207        return compute_all_logicq(dst, src1);
 208    case CC_OP_INCQ:
 209        return compute_all_incq(dst, src1);
 210    case CC_OP_DECQ:
 211        return compute_all_decq(dst, src1);
 212    case CC_OP_SHLQ:
 213        return compute_all_shlq(dst, src1);
 214    case CC_OP_SARQ:
 215        return compute_all_sarq(dst, src1);
 216    case CC_OP_BMILGQ:
 217        return compute_all_bmilgq(dst, src1);
 218#endif
 219    }
 220}
 221
 222uint32_t cpu_cc_compute_all(CPUX86State *env, int op)
 223{
 224    return helper_cc_compute_all(CC_DST, CC_SRC, CC_SRC2, op);
 225}
 226
 227target_ulong helper_cc_compute_c(target_ulong dst, target_ulong src1,
 228                                 target_ulong src2, int op)
 229{
 230    switch (op) {
 231    default: /* should never happen */
 232    case CC_OP_LOGICB:
 233    case CC_OP_LOGICW:
 234    case CC_OP_LOGICL:
 235    case CC_OP_LOGICQ:
 236    case CC_OP_CLR:
 237    case CC_OP_POPCNT:
 238        return 0;
 239
 240    case CC_OP_EFLAGS:
 241    case CC_OP_SARB:
 242    case CC_OP_SARW:
 243    case CC_OP_SARL:
 244    case CC_OP_SARQ:
 245    case CC_OP_ADOX:
 246        return src1 & 1;
 247
 248    case CC_OP_INCB:
 249    case CC_OP_INCW:
 250    case CC_OP_INCL:
 251    case CC_OP_INCQ:
 252    case CC_OP_DECB:
 253    case CC_OP_DECW:
 254    case CC_OP_DECL:
 255    case CC_OP_DECQ:
 256        return src1;
 257
 258    case CC_OP_MULB:
 259    case CC_OP_MULW:
 260    case CC_OP_MULL:
 261    case CC_OP_MULQ:
 262        return src1 != 0;
 263
 264    case CC_OP_ADCX:
 265    case CC_OP_ADCOX:
 266        return dst;
 267
 268    case CC_OP_ADDB:
 269        return compute_c_addb(dst, src1);
 270    case CC_OP_ADDW:
 271        return compute_c_addw(dst, src1);
 272    case CC_OP_ADDL:
 273        return compute_c_addl(dst, src1);
 274
 275    case CC_OP_ADCB:
 276        return compute_c_adcb(dst, src1, src2);
 277    case CC_OP_ADCW:
 278        return compute_c_adcw(dst, src1, src2);
 279    case CC_OP_ADCL:
 280        return compute_c_adcl(dst, src1, src2);
 281
 282    case CC_OP_SUBB:
 283        return compute_c_subb(dst, src1);
 284    case CC_OP_SUBW:
 285        return compute_c_subw(dst, src1);
 286    case CC_OP_SUBL:
 287        return compute_c_subl(dst, src1);
 288
 289    case CC_OP_SBBB:
 290        return compute_c_sbbb(dst, src1, src2);
 291    case CC_OP_SBBW:
 292        return compute_c_sbbw(dst, src1, src2);
 293    case CC_OP_SBBL:
 294        return compute_c_sbbl(dst, src1, src2);
 295
 296    case CC_OP_SHLB:
 297        return compute_c_shlb(dst, src1);
 298    case CC_OP_SHLW:
 299        return compute_c_shlw(dst, src1);
 300    case CC_OP_SHLL:
 301        return compute_c_shll(dst, src1);
 302
 303    case CC_OP_BMILGB:
 304        return compute_c_bmilgb(dst, src1);
 305    case CC_OP_BMILGW:
 306        return compute_c_bmilgw(dst, src1);
 307    case CC_OP_BMILGL:
 308        return compute_c_bmilgl(dst, src1);
 309
 310#ifdef TARGET_X86_64
 311    case CC_OP_ADDQ:
 312        return compute_c_addq(dst, src1);
 313    case CC_OP_ADCQ:
 314        return compute_c_adcq(dst, src1, src2);
 315    case CC_OP_SUBQ:
 316        return compute_c_subq(dst, src1);
 317    case CC_OP_SBBQ:
 318        return compute_c_sbbq(dst, src1, src2);
 319    case CC_OP_SHLQ:
 320        return compute_c_shlq(dst, src1);
 321    case CC_OP_BMILGQ:
 322        return compute_c_bmilgq(dst, src1);
 323#endif
 324    }
 325}
 326
 327void helper_write_eflags(CPUX86State *env, target_ulong t0,
 328                         uint32_t update_mask)
 329{
 330    cpu_load_eflags(env, t0, update_mask);
 331}
 332
 333target_ulong helper_read_eflags(CPUX86State *env)
 334{
 335    uint32_t eflags;
 336
 337    eflags = cpu_cc_compute_all(env, CC_OP);
 338    eflags |= (env->df & DF_MASK);
 339    eflags |= env->eflags & ~(VM_MASK | RF_MASK);
 340    return eflags;
 341}
 342
 343void helper_clts(CPUX86State *env)
 344{
 345    env->cr[0] &= ~CR0_TS_MASK;
 346    env->hflags &= ~HF_TS_MASK;
 347}
 348
 349void helper_reset_rf(CPUX86State *env)
 350{
 351    env->eflags &= ~RF_MASK;
 352}
 353
 354void helper_cli(CPUX86State *env)
 355{
 356    env->eflags &= ~IF_MASK;
 357}
 358
 359void helper_sti(CPUX86State *env)
 360{
 361    env->eflags |= IF_MASK;
 362}
 363
 364void helper_clac(CPUX86State *env)
 365{
 366    env->eflags &= ~AC_MASK;
 367}
 368
 369void helper_stac(CPUX86State *env)
 370{
 371    env->eflags |= AC_MASK;
 372}
 373
 374#if 0
 375/* vm86plus instructions */
 376void helper_cli_vm(CPUX86State *env)
 377{
 378    env->eflags &= ~VIF_MASK;
 379}
 380
 381void helper_sti_vm(CPUX86State *env)
 382{
 383    env->eflags |= VIF_MASK;
 384    if (env->eflags & VIP_MASK) {
 385        raise_exception_ra(env, EXCP0D_GPF, GETPC());
 386    }
 387}
 388#endif
 389