Re: x86 emulator bug

Alex Deucher <[email protected]>
Newsgroups gmane.comp.xfree86.devel
Message-ID <[email protected]>
On Thu, 10 Feb 2005 10:08:20 -0000, Charles Dobson <[email protected]> wrote:
> I am not sure if I should post this here or on bugzilla.

post your patch in bugzilla.

Thanks,

Alex

> 
> While trying to get a Silicon Motion SM722 video controller
> working with Solaris, I have discovered a problem with the
> emulation of the SHLD and SHRD (double precision shift)
> instructions of the x86 emulator.
> According to the Intel Pentium User Guide Vol 3, these
> instructions can shift upto 31 bits with both 16 and 32
> bit operands. The emulator code will only work with shifts
> of upto 15 bits for 16 bit operands.
> 
> The file is
> xc/extras/x86emu/src/x86emu/prim_ops.c
> 
> I have modified the two functions as below.
> I am not positive the flags are set correctly so
> would appreciated someone else to check these.
> 
> u16 shld_word (u16 d, u16 fill, u8 s)
> {
>     unsigned int cnt, res, cf;
> 
>     if (s < 32) {
>         cnt = s % 32;
>         if (cnt > 0) {
>             if (cnt > 15) {
>                 res = (unsigned int)fill << (cnt - 16);
>                 if (cnt == 16)
>                     cf = d & 0x1;
>                 else
>                     cf = res & 0x10000;
>             }
>             else {
>                 res = (d << cnt) | (fill >> (16-cnt));
>                 cf = d & (1 << (16 - cnt));
>             }
>             CONDITIONAL_SET_FLAG(cf, F_CF);
>             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
>             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
>             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
>         } else {
>             res = d;
>         }
>         if (cnt == 1) {
>             CONDITIONAL_SET_FLAG((((res & 0x8000) == 0x8000) ^
>                                   (ACCESS_FLAG(F_CF) != 0)), F_OF);
>         } else {
>             CLEAR_FLAG(F_OF);
>         }
>     } else {
>         res = 0;
>         CONDITIONAL_SET_FLAG((d << (s-1)) & 0x8000, F_CF);
>         CLEAR_FLAG(F_OF);
>         CLEAR_FLAG(F_SF);
>         SET_FLAG(F_PF);
>         SET_FLAG(F_ZF);
>     }
>     return (u16)res;
> }
> 
> u16 shrd_word (u16 d, u16 fill, u8 s)
> {
>     unsigned int cnt, res, cf;
> 
>     if (s < 32) {
>         cnt = s % 32;
>         if (cnt > 0) {
>             if (cnt > 15) {
>                 if (cnt == 16)
>                     cf = d & 0x8000;
>                 else
>                     cf = fill & (1 << (cnt - 17));
>                 res = fill >> (cnt - 16);
>             } else {
>                 cf = d & (1 << (cnt - 1));
>                 res = (d >> cnt) | (fill << (16 - cnt));
>             }
>             CONDITIONAL_SET_FLAG(cf, F_CF);
>             CONDITIONAL_SET_FLAG((res & 0xffff) == 0, F_ZF);
>             CONDITIONAL_SET_FLAG(res & 0x8000, F_SF);
>             CONDITIONAL_SET_FLAG(PARITY(res & 0xff), F_PF);
>         } else {
>             res = d;
>         }
> 
>         if (cnt == 1) {
>             CONDITIONAL_SET_FLAG(XOR2(res >> 14), F_OF);
>         } else {
>             CLEAR_FLAG(F_OF);
>         }
>     } else {
>         res = 0;
>         CLEAR_FLAG(F_CF);
>         CLEAR_FLAG(F_OF);
>         SET_FLAG(F_ZF);
>         CLEAR_FLAG(F_SF);
>         CLEAR_FLAG(F_PF);
>     }
>     return (u16)res;
> }
> 
> Charles Dobson.
> Concurrent Technologies Plc.
> 
> _______________________________________________
> Devel mailing list
> [email protected]
> http://XFree86.Org/mailman/listinfo/devel
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.