direct-io.hg

changeset 13377:2b50acbdf01b

[XEN] Emulate BSF/BSR. Fix ARPL emulation.
Fix building POPA emulation on x86/32.
Fix asm constraints for in-memory operands.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Sun Jan 14 17:22:24 2007 +0000 (2007-01-14)
parents 179453a85929
children b2a31053955d
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Sun Jan 14 16:12:42 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Sun Jan 14 17:22:24 2007 +0000
     1.3 @@ -219,7 +219,8 @@ static uint8_t twobyte_table[256] = {
     1.4      0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
     1.5      /* 0xB8 - 0xBF */
     1.6      0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
     1.7 -    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
     1.8 +    DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
     1.9 +    ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
    1.10      /* 0xC0 - 0xC7 */
    1.11      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
    1.12      0, 0, 0, ImplicitOps|ModRM,
    1.13 @@ -322,7 +323,8 @@ do{ unsigned long _tmp;                 
    1.14              _op"w %"_wx"3,%1; "                                            \
    1.15              _POST_EFLAGS("0","4","2")                                      \
    1.16              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.17 -            : _wy ((_src).val), "i" (EFLAGS_MASK) );                       \
    1.18 +            : _wy ((_src).val), "i" (EFLAGS_MASK),                         \
    1.19 +              "m" (_eflags), "m" ((_dst).val) );                           \
    1.20          break;                                                             \
    1.21      case 4:                                                                \
    1.22          __asm__ __volatile__ (                                             \
    1.23 @@ -330,7 +332,8 @@ do{ unsigned long _tmp;                 
    1.24              _op"l %"_lx"3,%1; "                                            \
    1.25              _POST_EFLAGS("0","4","2")                                      \
    1.26              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.27 -            : _ly ((_src).val), "i" (EFLAGS_MASK) );                       \
    1.28 +            : _ly ((_src).val), "i" (EFLAGS_MASK),                         \
    1.29 +              "m" (_eflags), "m" ((_dst).val) );                           \
    1.30          break;                                                             \
    1.31      case 8:                                                                \
    1.32          __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy);           \
    1.33 @@ -347,7 +350,8 @@ do{ unsigned long _tmp;                 
    1.34              _op"b %"_bx"3,%1; "                                            \
    1.35              _POST_EFLAGS("0","4","2")                                      \
    1.36              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.37 -            : _by ((_src).val), "i" (EFLAGS_MASK) );                       \
    1.38 +            : _by ((_src).val), "i" (EFLAGS_MASK),                         \
    1.39 +              "m" (_eflags), "m" ((_dst).val) );                           \
    1.40          break;                                                             \
    1.41      default:                                                               \
    1.42          __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\
    1.43 @@ -378,7 +382,7 @@ do{ unsigned long _tmp;                 
    1.44              _op"b %1; "                                                    \
    1.45              _POST_EFLAGS("0","3","2")                                      \
    1.46              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.47 -            : "i" (EFLAGS_MASK) );                                         \
    1.48 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
    1.49          break;                                                             \
    1.50      case 2:                                                                \
    1.51          __asm__ __volatile__ (                                             \
    1.52 @@ -386,7 +390,7 @@ do{ unsigned long _tmp;                 
    1.53              _op"w %1; "                                                    \
    1.54              _POST_EFLAGS("0","3","2")                                      \
    1.55              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.56 -            : "i" (EFLAGS_MASK) );                                         \
    1.57 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
    1.58          break;                                                             \
    1.59      case 4:                                                                \
    1.60          __asm__ __volatile__ (                                             \
    1.61 @@ -394,7 +398,7 @@ do{ unsigned long _tmp;                 
    1.62              _op"l %1; "                                                    \
    1.63              _POST_EFLAGS("0","3","2")                                      \
    1.64              : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
    1.65 -            : "i" (EFLAGS_MASK) );                                         \
    1.66 +            : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );        \
    1.67          break;                                                             \
    1.68      case 8:                                                                \
    1.69          __emulate_1op_8byte(_op, _dst, _eflags);                           \
    1.70 @@ -410,7 +414,8 @@ do{ __asm__ __volatile__ (              
    1.71          _op"q %"_qx"3,%1; "                                             \
    1.72          _POST_EFLAGS("0","4","2")                                       \
    1.73          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
    1.74 -        : _qy ((_src).val), "i" (EFLAGS_MASK) );                        \
    1.75 +        : _qy ((_src).val), "i" (EFLAGS_MASK),                          \
    1.76 +          "m" (_eflags), "m" ((_dst).val) );                            \
    1.77  } while (0)
    1.78  #define __emulate_1op_8byte(_op, _dst, _eflags)                         \
    1.79  do{ __asm__ __volatile__ (                                              \
    1.80 @@ -418,7 +423,7 @@ do{ __asm__ __volatile__ (              
    1.81          _op"q %1; "                                                     \
    1.82          _POST_EFLAGS("0","3","2")                                       \
    1.83          : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
    1.84 -        : "i" (EFLAGS_MASK) );                                          \
    1.85 +        : "i" (EFLAGS_MASK), "m" (_eflags), "m" ((_dst).val) );         \
    1.86  } while (0)
    1.87  #elif defined(__i386__)
    1.88  #define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
    1.89 @@ -1097,7 +1102,9 @@ x86_emulate(
    1.90              /* arpl */
    1.91              uint16_t src_val = dst.val;
    1.92              dst = src;
    1.93 -            if ( (src_val & 3) > (dst.val & 3) )
    1.94 +            _regs.eflags &= ~EFLG_ZF;
    1.95 +            _regs.eflags |= ((src_val & 3) > (dst.val & 3)) ? EFLG_ZF : 0;
    1.96 +            if ( _regs.eflags & EFLG_ZF )
    1.97                  dst.val  = (dst.val & ~3) | (src_val & 3);
    1.98              else
    1.99                  dst.type = OP_NONE;
   1.100 @@ -1661,8 +1668,10 @@ x86_emulate(
   1.101      case 0x61: /* popa */ {
   1.102          int i;
   1.103          unsigned long dummy_esp, *regs[] = {
   1.104 -            &_regs.edi, &_regs.esi, &_regs.ebp, &dummy_esp,
   1.105 -            &_regs.ebx, &_regs.edx, &_regs.ecx, &_regs.eax };
   1.106 +            (unsigned long *)&_regs.edi, (unsigned long *)&_regs.esi,
   1.107 +            (unsigned long *)&_regs.ebp, (unsigned long *)&dummy_esp,
   1.108 +            (unsigned long *)&_regs.ebx, (unsigned long *)&_regs.edx,
   1.109 +            (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
   1.110          generate_exception_if(mode_64bit(), EXC_UD);
   1.111          for ( i = 0; i < 8; i++ )
   1.112              if ( (rc = ops->read(x86_seg_ss,
   1.113 @@ -2008,6 +2017,26 @@ x86_emulate(
   1.114          dst.val   = (uint8_t)src.val;
   1.115          break;
   1.116  
   1.117 +    case 0xbc: /* bsf */ {
   1.118 +        int zf;
   1.119 +        asm ( "bsf %2,%0; setc %b1"
   1.120 +              : "=r" (dst.val), "=q" (zf)
   1.121 +              : "r" (src.val), "1" (0) );
   1.122 +        _regs.eflags &= ~EFLG_ZF;
   1.123 +        _regs.eflags |= zf ? EFLG_ZF : 0;
   1.124 +        break;
   1.125 +    }
   1.126 +
   1.127 +    case 0xbd: /* bsr */ {
   1.128 +        int zf;
   1.129 +        asm ( "bsr %2,%0; setc %b1"
   1.130 +              : "=r" (dst.val), "=q" (zf)
   1.131 +              : "r" (src.val), "1" (0) );
   1.132 +        _regs.eflags &= ~EFLG_ZF;
   1.133 +        _regs.eflags |= zf ? EFLG_ZF : 0;
   1.134 +        break;
   1.135 +    }
   1.136 +
   1.137      case 0xb7: /* movzx rm16,r{16,32,64} */
   1.138          dst.val = (uint16_t)src.val;
   1.139          break;