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