Hello community,

here is the log from the commit of package libx86emu for openSUSE:Factory 
checked in at 2020-01-23 16:08:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libx86emu (Old)
 and      /work/SRC/openSUSE:Factory/.libx86emu.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libx86emu"

Thu Jan 23 16:08:18 2020 rev:29 rq:765278 version:2.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/libx86emu/libx86emu.changes      2019-08-24 
18:40:52.841789222 +0200
+++ /work/SRC/openSUSE:Factory/.libx86emu.new.26092/libx86emu.changes   
2020-01-23 16:08:26.415547883 +0100
@@ -1,0 +2,41 @@
+Fri Jan 17 12:32:27 UTC 2020 - [email protected]
+
+- merge gh#wfeldt/libx86emu#17
+- Introduce LDFLAGS variable in Makefiles
+- test: Link with the development version of the library
+- test: Sort tests by name
+- Add Travis CI configuration file and a badge in the README
+- Travis CI integration
+- 2.6
+
+--------------------------------------------------------------------
+Fri Jan 17 12:28:09 UTC 2020 - [email protected]
+
+- merge gh#wfeldt/libx86emu#22
+- decode: Prepare for SSE support
+- ops2: Add SSE instructions
+- ops2: Add packed SSE ops
+- Minimal SSE support
+
+--------------------------------------------------------------------
+Fri Jan 17 12:26:51 UTC 2020 - [email protected]
+
+- merge gh#wfeldt/libx86emu#21
+- prim_ops: Fix compiler warning
+
+--------------------------------------------------------------------
+Fri Jan 17 12:24:59 UTC 2020 - [email protected]
+
+- merge gh#wfeldt/libx86emu#24
+- ops2: Add cpuid support using a new handler
+- ops2: Introduce a callback function for MSR access
+- Push cpuid msr callback
+
+--------------------------------------------------------------------
+Thu Jan 16 15:45:23 UTC 2020 - [email protected]
+
+- merge gh#wfeldt/libx86emu#26
+- add '--32' option to demo program to start in 32-bit mode
+- 2.5
+
+--------------------------------------------------------------------

Old:
----
  libx86emu-2.4.tar.xz

New:
----
  libx86emu-2.6.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libx86emu.spec ++++++
--- /var/tmp/diff_new_pack.Zxqosk/_old  2020-01-23 16:08:27.051548260 +0100
+++ /var/tmp/diff_new_pack.Zxqosk/_new  2020-01-23 16:08:27.051548260 +0100
@@ -22,7 +22,7 @@
 Summary:        An x86 emulation library
 License:        BSD-3-Clause
 Group:          Development/Libraries/C and C++
-Version:        2.4
+Version:        2.6
 Release:        0
 Source:         %{name}-%{version}.tar.xz
 Url:            https://github.com/wfeldt/libx86emu

++++++ libx86emu-2.4.tar.xz -> libx86emu-2.6.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/.travis.yml 
new/libx86emu-2.6/.travis.yml
--- old/libx86emu-2.4/.travis.yml       1970-01-01 01:00:00.000000000 +0100
+++ new/libx86emu-2.6/.travis.yml       2020-01-17 13:32:27.000000000 +0100
@@ -0,0 +1,9 @@
+language: c
+
+before_install:
+- sudo apt-get update -qq
+- sudo apt-get install -qq nasm
+
+script:
+- make
+- make -C test
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/Makefile new/libx86emu-2.6/Makefile
--- old/libx86emu-2.4/Makefile  2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/Makefile  2020-01-17 13:32:27.000000000 +0100
@@ -13,6 +13,7 @@
 
 CC     = gcc
 CFLAGS = -g -O2 -fPIC -fvisibility=hidden -fomit-frame-pointer -Wall
+LDFLAGS =
 
 LIBDIR = /usr/lib$(shell ldd /bin/sh | grep -q /lib64/ && echo 64)
 LIBX86 = libx86emu
@@ -42,7 +43,7 @@
        install -m 644 -D include/x86emu.h $(DESTDIR)/usr/include/x86emu.h
 
 $(LIB_NAME): .depend $(OBJS)
-       $(CC) -shared -Wl,-soname,$(LIB_SONAME) $(OBJS) -o $(LIB_NAME)
+       $(CC) -shared -Wl,-soname,$(LIB_SONAME) $(OBJS) -o $(LIB_NAME) 
$(LDFLAGS)
        @ln -snf $(LIB_NAME) $(LIB_SONAME)
        @ln -snf $(LIB_SONAME) $(LIBX86).so
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/README.md new/libx86emu-2.6/README.md
--- old/libx86emu-2.4/README.md 2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/README.md 2020-01-17 13:32:27.000000000 +0100
@@ -1,5 +1,7 @@
 # x86 emulation library
 
+[![Build 
Status](https://travis-ci.org/wfeldt/libx86emu.svg?branch=master)](https://travis-ci.org/wfeldt/libx86emu)
+
 libx86emu is a small library to emulate x86 instructions. The focus here is 
not a complete emulation (go for qemu for this) but to cover enough for typical 
firmware blobs.
 
 At the moment 'regular' 32-bit instructions are covered together with basic 
protected mode support.
@@ -256,6 +258,54 @@
 
 Returns old function.
 
+### x86emu_set_cpuid_handler
+
+Execution hook
+
+    x86emu_cpuid_handler_t x86emu_set_cpuid_handler(x86emu_t *emu, 
x86emu_cpuid_handler_t handler);
+    typedef void (* x86emu_cpuid_handler_t)(x86emu_t *emu);
+
+Set a callback function that handles the CPUID instruction.
+Allows the user to use the host's CPUID or provide a custom implementation
+to emulate a specific CPU.
+
+Returns old function.
+
+There's no default implementation. Without the handler installed the programm
+will raise an #UD exception.
+
+### x86emu_set_rdmsr_handler
+
+Execution hook
+
+    x86emu_rdmsr_handler_t x86emu_set_rdmsr_handler(x86emu_t *emu, 
x86emu_rdmsr_handler_t handler);
+    typedef void (* x86emu_rdmsr_handler_t)(struct x86emu_s *);
+
+Set alternative callback function that handles the RDMSR instruction.
+Allows the user to use the host's MSR or provide a custom implementation
+to emulate a specific platform.
+
+Returns old function.
+
+The default callback function uses the *msr* array in the *x86emu_t* structure
+to read MSRs from and updates the *msr_perm* array.
+
+### x86emu_set_wrmsr_handler
+
+Execution hook
+
+    x86emu_wrmsr_handler_t x86emu_set_wrmsr_handler(x86emu_t *emu, 
x86emu_wrmsr_handler_t handler);
+    typedef void (* x86emu_wrmsr_handler_t)(struct x86emu_s *);
+
+Set alternative callback function that handles the WRMSR instruction.
+Allows the user to use the host's MSR or provide a custom implementation
+to emulate a specific platform.
+
+Returns old function.
+
+The default callback function uses the *msr* array in the *x86emu_t* structure
+to write MSRs to and updates the *msr_perm* array.
+
 ### x86emu_intr_raise
 
 Raise an interrupt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/VERSION new/libx86emu-2.6/VERSION
--- old/libx86emu-2.4/VERSION   2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/VERSION   2020-01-17 13:32:27.000000000 +0100
@@ -1 +1 @@
-2.4
+2.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/api.c new/libx86emu-2.6/api.c
--- old/libx86emu-2.4/api.c     2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/api.c     2020-01-17 13:32:27.000000000 +0100
@@ -36,6 +36,22 @@
 
 #define LINE_LEN 16
 
+static void x86emu_rdmsr(x86emu_t *emu)
+{
+  unsigned u = emu->x86.R_ECX;
+
+  emu->x86.R_EDX = emu->x86.msr[u] >> 32;
+  emu->x86.R_EAX = emu->x86.msr[u];
+  emu->x86.msr_perm[u] |= X86EMU_ACC_R;
+}
+
+static void x86emu_wrmsr(x86emu_t *emu)
+{
+  unsigned u = emu->x86.R_ECX;
+
+  emu->x86.msr[u] = ((u64) emu->x86.R_EDX << 32) + emu->x86.R_EAX;
+  emu->x86.msr_perm[u] |= X86EMU_ACC_W;
+}
 
 API_SYM x86emu_t *x86emu_new(unsigned def_mem_perm, unsigned def_io_perm)
 {
@@ -50,6 +66,8 @@
   if(def_io_perm) x86emu_set_io_perm(emu, 0, X86EMU_IO_PORTS - 1, def_io_perm);
 
   x86emu_set_memio_handler(emu, vm_memio);
+  x86emu_set_rdmsr_handler(emu, x86emu_rdmsr);
+  x86emu_set_wrmsr_handler(emu, x86emu_wrmsr);
 
   x86emu_reset(emu);
 
@@ -179,6 +197,41 @@
   return old;
 }
 
+API_SYM x86emu_cpuid_handler_t x86emu_set_cpuid_handler(x86emu_t *emu, 
x86emu_cpuid_handler_t handler)
+{
+  x86emu_cpuid_handler_t old = NULL;
+
+  if(emu) {
+    old = emu->cpuid;
+    emu->cpuid = handler;
+  }
+
+  return old;
+}
+
+API_SYM x86emu_wrmsr_handler_t x86emu_set_wrmsr_handler(x86emu_t *emu, 
x86emu_wrmsr_handler_t handler)
+{
+  x86emu_wrmsr_handler_t old = NULL;
+
+  if(emu) {
+    old = emu->wrmsr;
+    emu->wrmsr = handler;
+  }
+
+  return old;
+}
+
+API_SYM x86emu_rdmsr_handler_t x86emu_set_rdmsr_handler(x86emu_t *emu, 
x86emu_rdmsr_handler_t handler)
+{
+  x86emu_rdmsr_handler_t old = NULL;
+
+  if(emu) {
+    old = emu->rdmsr;
+    emu->rdmsr = handler;
+  }
+
+  return old;
+}
 
 API_SYM unsigned x86emu_read_byte(x86emu_t *emu, unsigned addr)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/changelog new/libx86emu-2.6/changelog
--- old/libx86emu-2.4/changelog 2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/changelog 2020-01-17 13:32:27.000000000 +0100
@@ -1,3 +1,23 @@
+2020-01-17:    2.6
+       - merge gh#wfeldt/libx86emu#24
+       - ops2: Add cpuid support using a new handler
+       - ops2: Introduce a callback function for MSR access
+       - merge gh#wfeldt/libx86emu#21
+       - prim_ops: Fix compiler warning
+       - merge gh#wfeldt/libx86emu#22
+       - decode: Prepare for SSE support
+       - ops2: Add SSE instructions
+       - ops2: Add packed SSE ops
+       - merge gh#wfeldt/libx86emu#17
+       - Introduce LDFLAGS variable in Makefiles
+       - test: Link with the development version of the library
+       - test: Sort tests by name
+       - Add Travis CI configuration file and a badge in the README
+
+2020-01-16:    2.5
+       - merge gh#wfeldt/libx86emu#26
+       - add '--32' option to demo program to start in 32-bit mode
+
 2019-08-20:    2.4
        - merge gh#wfeldt/libx86emu#19
        - decode: Fix compiler warning
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/decode.c new/libx86emu-2.6/decode.c
--- old/libx86emu-2.4/decode.c  2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/decode.c  2020-01-17 13:32:27.000000000 +0100
@@ -531,6 +531,22 @@
 
 /****************************************************************************
 PARAMETERS:
+offset - Offset to load data from
+
+RETURNS:
+Quad long value read from the absolute memory location.
+****************************************************************************/
+I128_reg_t fetch_data_qlong(x86emu_t *emu, u32 ofs)
+{
+  I128_reg_t ret;
+  for (int i = 0; i < sizeof(I128_reg_t); i++) {
+    ret.reg[i] = fetch_data_byte(emu, ofs + i);
+  }
+  return ret;
+}
+
+/****************************************************************************
+PARAMETERS:
 segment        - Segment to load data from
 offset - Offset to load data from
 
@@ -630,6 +646,22 @@
 
 /****************************************************************************
 PARAMETERS:
+offset - Offset to store data at
+val            - Value to store
+
+REMARKS:
+Writes a qlong value to an segmented memory location. The segment used is
+the current 'default' segment, which may have been overridden.
+****************************************************************************/
+void store_data_qlong(x86emu_t *emu, u32 ofs, I128_reg_t val)
+{
+  for (int i = 0; i < sizeof(I128_reg_t); i++) {
+    store_data_word_abs(emu, get_data_segment(emu), ofs, val.reg[i]);
+  }
+}
+
+/****************************************************************************
+PARAMETERS:
 segment        - Segment to store data at
 offset - Offset to store data at
 val            - Value to store
@@ -885,6 +917,56 @@
 
 /****************************************************************************
 PARAMETERS:
+reg    - SSE register to decode
+
+RETURNS:
+Pointer to the appropriate register
+
+REMARKS:
+Return a pointer to the register given by the R/RM field of the
+modrm byte, for dword operands.  Also enables the decoding of instructions.
+****************************************************************************/
+I128_reg_t* decode_rm_sse_register(x86emu_t *emu, int reg)
+{
+  switch(reg) {
+    case 0:
+      OP_DECODE("xmm0");
+      return &emu->x86.R_XMM0;
+
+    case 1:
+      OP_DECODE("xmm1");
+      return &emu->x86.R_XMM1;
+
+    case 2:
+      OP_DECODE("xmm2");
+      return &emu->x86.R_XMM2;
+
+    case 3:
+      OP_DECODE("xmm3");
+      return &emu->x86.R_XMM3;
+
+    case 4:
+      OP_DECODE("xmm4");
+      return &emu->x86.R_XMM4;
+
+    case 5:
+      OP_DECODE("xmm5");
+      return &emu->x86.R_XMM5;
+
+    case 6:
+      OP_DECODE("xmm6");
+      return &emu->x86.R_XMM6;
+
+    case 7:
+      OP_DECODE("xmm7");
+      return &emu->x86.R_XMM7;
+  }
+
+  return NULL;                /* NOTREACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
 reg    - Register to decode
 
 RETURNS:
@@ -997,6 +1079,11 @@
   decode_hex4(emu, p, ofs & 0xffff);
 }
 
+void decode_hex32(x86emu_t *emu, char **p, I128_reg_t ofs)
+{
+  for (int i = sizeof(ofs.reg) - 1; i >= 0; i--)
+    decode_hex2(emu, p, ofs.reg[i]);
+}
 
 void decode_hex_addr(x86emu_t *emu, char **p, u32 ofs)
 {
@@ -1726,6 +1813,25 @@
   if(ACCESS_FLAG(F_PF)) LOG_STR(" pf");
   if(ACCESS_FLAG(F_CF)) LOG_STR(" cf");
 
+  if (emu->x86.R_CR4 & CR4_OSFXSR) {
+    LOG_STR("\nxmm0 ");
+    decode_hex32(emu, p, emu->x86.R_XMM0);
+    LOG_STR("\nxmm1 ");
+    decode_hex32(emu, p, emu->x86.R_XMM1);
+    LOG_STR("\nxmm2 ");
+    decode_hex32(emu, p, emu->x86.R_XMM2);
+    LOG_STR("\nxmm3 ");
+    decode_hex32(emu, p, emu->x86.R_XMM3);
+    LOG_STR("\nxmm4 ");
+    decode_hex32(emu, p, emu->x86.R_XMM4);
+    LOG_STR("\nxmm5 ");
+    decode_hex32(emu, p, emu->x86.R_XMM5);
+    LOG_STR("\nxmm6 ");
+    decode_hex32(emu, p, emu->x86.R_XMM6);
+    LOG_STR("\nxmm7 ");
+    decode_hex32(emu, p, emu->x86.R_XMM7);
+    LOG_STR("\n");
+  }
   LOG_STR("\n");
 
   **p = 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/demo/x86emu-demo.c 
new/libx86emu-2.6/demo/x86emu-demo.c
--- old/libx86emu-2.4/demo/x86emu-demo.c        2019-08-20 16:23:47.000000000 
+0200
+++ new/libx86emu-2.6/demo/x86emu-demo.c        2020-01-17 13:32:27.000000000 
+0100
@@ -22,6 +22,7 @@
   { "load",       1, NULL, 'l'  },
   { "start",      1, NULL, 's'  },
   { "max",        1, NULL, 'm'  },
+  { "32",         0, NULL, 1001 },
   { }
 };
 
@@ -33,6 +34,7 @@
   } start;
   unsigned load;
   unsigned max_instructions;
+  unsigned bits_32:1;
   char *file;
 } opt;
 
@@ -69,6 +71,10 @@
         }
         break;
 
+      case 1001:
+        opt.bits_32 = 1;
+        break;
+
       default:
         help();
         return i == 'h' ? 0 : 1;
@@ -100,16 +106,13 @@
     "Load FILE and run x86 emulation.\n"
    "\n"
     "Options:\n"
-    "  -l, --load ADDRESS\n"
-    "      load FILE at ADDRESS into memory (default: 0x7c00).\n"
-    "  -s, --start ADDRESS\n"
-    "      start emulation at ADDRESS (default 0:0x7c00).\n"
-    "      Note: ADDRESS may contain a colon (':') to separate segment and 
offset values;\n"
-    "      if not, segment = 0 is assumed.\n"
-    "  -m, --max N\n"
-    "      stop after emulating N instructions.\n"
-    "  -h, --help\n"
-    "      show this text\n"
+    "  -l, --load ADDRESS      Load FILE at ADDRESS into memory (default 
0x7c00).\n"
+    "  -s, --start ADDRESS     Start emulation at ADDRESS (default 
0:0x7c00).\n"
+    "                          ADDRESS may contain a colon (':') to separate 
segment and\n"
+    "                          offset values. Without colon, segment 0 is 
assumed.\n"
+    "  -m, --max N             Stop after emulating N instructions.\n"
+    "      --32                Start in 32-bit mode (default 16-bit mode).\n"
+    "  -h, --help              Show this text\n"
   );
 }
 
@@ -154,6 +157,18 @@
 
   x86emu_set_seg_register(emu, emu->x86.R_CS_SEL, opt.start.segment);
   emu->x86.R_EIP = opt.start.offset;
+  if(opt.bits_32) {
+    /* set default data/address size to 32 bit */
+    emu->x86.R_CS_ACC |= (1 << 10);
+
+    /* maximize descriptor limits */
+    emu->x86.R_CS_LIMIT =
+    emu->x86.R_DS_LIMIT =
+    emu->x86.R_ES_LIMIT =
+    emu->x86.R_FS_LIMIT =
+    emu->x86.R_GS_LIMIT =
+    emu->x86.R_SS_LIMIT = ~0;
+  }
 
   if(!(f = fopen(file, "r"))) return 0;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/include/decode.h 
new/libx86emu-2.6/include/decode.h
--- old/libx86emu-2.4/include/decode.h  2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/include/decode.h  2020-01-17 13:32:27.000000000 +0100
@@ -75,12 +75,14 @@
 u16 fetch_data_word_abs(x86emu_t *emu, sel_t *seg, u32 offset);
 u32 fetch_data_long(x86emu_t *emu, u32 offset);
 u32 fetch_data_long_abs(x86emu_t *emu, sel_t *seg, u32 offset);
+I128_reg_t fetch_data_qlong(x86emu_t *emu, u32 ofs);
 void store_data_byte(x86emu_t *emu, u32 offset, u8 val);
 void store_data_byte_abs(x86emu_t *emu, sel_t *seg, u32 offset, u8 val);
 void store_data_word(x86emu_t *emu, u32 offset, u16 val);
 void store_data_word_abs(x86emu_t *emu, sel_t *seg, u32 offset, u16 val);
 void store_data_long(x86emu_t *emu, u32 offset, u32 val);
 void store_data_long_abs(x86emu_t *emu, sel_t *seg, u32 offset, u32 val);
+void store_data_qlong(x86emu_t *emu, u32 ofs, I128_reg_t val);
 u8 fetch_io_byte(x86emu_t *emu, u32 offset);
 u16 fetch_io_word(x86emu_t *emu, u32 offset);
 u32 fetch_io_long(x86emu_t *emu, u32 offset);
@@ -91,6 +93,7 @@
 u16* decode_rm_word_register(x86emu_t *emu, int reg);
 u32* decode_rm_long_register(x86emu_t *emu, int reg);
 sel_t *decode_rm_seg_register(x86emu_t *emu, int reg);
+I128_reg_t* decode_rm_sse_register(x86emu_t *emu, int reg);
 u32 decode_rm00_address(x86emu_t *emu, int rm);
 u32 decode_rm01_address(x86emu_t *emu, int rm);
 u32 decode_rm10_address(x86emu_t *emu, int rm);
@@ -102,6 +105,7 @@
 void decode_hex2(x86emu_t *emu, char **p, u32 ofs);
 void decode_hex4(x86emu_t *emu, char **p, u32 ofs);
 void decode_hex8(x86emu_t *emu, char **p, u32 ofs);
+void decode_hex32(x86emu_t *emu, char **p, I128_reg_t ofs);
 void decode_hex_addr(x86emu_t *emu, char **p, u32 ofs);
 void decode_hex2s(x86emu_t *emu, char **p, s32 ofs);
 void decode_hex4s(x86emu_t *emu, char **p, s32 ofs);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/include/x86emu.h 
new/libx86emu-2.6/include/x86emu.h
--- old/libx86emu-2.4/include/x86emu.h  2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/include/x86emu.h  2020-01-17 13:32:27.000000000 +0100
@@ -58,6 +58,8 @@
 #define s32 int32_t
 #define s64 int64_t
 
+#define FP_SP_SIZE 4
+#define FP_DP_SIZE 8
 
 /*
  * General EAX, EBX, ECX, EDX type registers.  Note that for
@@ -77,6 +79,10 @@
 #ifdef __BIG_ENDIAN__
 
 typedef struct {
+  u8 reg[16];
+} I128_reg_t;
+
+typedef struct {
   u32 e_reg;
 } I32_reg_t;
 
@@ -91,6 +97,10 @@
 #else /* !__BIG_ENDIAN__ */
 
 typedef struct {
+  u8 reg[16];
+} I128_reg_t;
+
+typedef struct {
   u32 e_reg;
 } I32_reg_t;
 
@@ -119,6 +129,9 @@
   u32 FLAGS;
 };
 
+struct i386_see_regs {
+  I128_reg_t XMM[8];
+};
 
 typedef struct {
   union {
@@ -216,6 +229,16 @@
 #define R_EIP          spc.IP.I32_reg.e_reg
 #define R_EFLG         spc.FLAGS
 
+/* SSE registers */
+#define R_XMM0         sse.XMM[0]
+#define R_XMM1         sse.XMM[1]
+#define R_XMM2         sse.XMM[2]
+#define R_XMM3         sse.XMM[3]
+#define R_XMM4         sse.XMM[4]
+#define R_XMM5         sse.XMM[5]
+#define R_XMM6         sse.XMM[6]
+#define R_XMM7         sse.XMM[7]
+
 /* segment registers */
 #define R_ES_INDEX     0
 #define R_CS_INDEX     1
@@ -304,15 +327,16 @@
 #define R_REAL_TSC     msr[0x12]
 
 /* flag conditions   */
-#define FB_CF 0x0001            /* CARRY flag  */
-#define FB_PF 0x0004            /* PARITY flag */
-#define FB_AF 0x0010            /* AUX  flag   */
-#define FB_ZF 0x0040            /* ZERO flag   */
-#define FB_SF 0x0080            /* SIGN flag   */
-#define FB_TF 0x0100            /* TRAP flag   */
-#define FB_IF 0x0200            /* INTERRUPT ENABLE flag */
-#define FB_DF 0x0400            /* DIR flag    */
-#define FB_OF 0x0800            /* OVERFLOW flag */
+#define FB_CF 0x000001            /* CARRY flag  */
+#define FB_PF 0x000004            /* PARITY flag */
+#define FB_AF 0x000010            /* AUX  flag   */
+#define FB_ZF 0x000040            /* ZERO flag   */
+#define FB_SF 0x000080            /* SIGN flag   */
+#define FB_TF 0x000100            /* TRAP flag   */
+#define FB_IF 0x000200            /* INTERRUPT ENABLE flag */
+#define FB_DF 0x000400            /* DIR flag    */
+#define FB_OF 0x000800            /* OVERFLOW flag */
+#define FB_ID 0x200000            /* ID flag */
 
 /* 80286 and above always have bit#1 set */
 #define F_ALWAYS_ON  (0x0002)   /* flag bits always on */
@@ -335,6 +359,11 @@
 #define F_DF 0x0400             /* DIR flag    */
 #define F_OF 0x0800             /* OVERFLOW flag */
 
+#define CR0_MP         (1 <<  1)
+#define CR0_EM         (1 <<  2)
+#define CR4_OSFXSR     (1 <<  9)
+#define CR4_OSXMMEXCPT (1 << 10)
+
 #define X86EMU_TOGGLE_FLAG(emu, flag)     (emu->x86.R_FLG ^= (flag))
 #define X86EMU_SET_FLAG(emu, flag)        (emu->x86.R_FLG |= (flag))
 #define X86EMU_CLEAR_FLAG(emu, flag)      (emu->x86.R_FLG &= ~(flag))
@@ -380,11 +409,15 @@
 typedef unsigned (* x86emu_memio_handler_t)(struct x86emu_s *, u32 addr, u32 
*val, unsigned type);
 typedef int (* x86emu_intr_handler_t)(struct x86emu_s *, u8 num, unsigned 
type);
 typedef int (* x86emu_code_handler_t)(struct x86emu_s *);
+typedef void (* x86emu_cpuid_handler_t)(struct x86emu_s *);
+typedef void (* x86emu_wrmsr_handler_t)(struct x86emu_s *);
+typedef void (* x86emu_rdmsr_handler_t)(struct x86emu_s *);
 typedef void (* x86emu_flush_func_t)(struct x86emu_s *, char *buf, unsigned 
size);
 
 typedef struct {
   struct i386_general_regs gen;
   struct i386_special_regs spc;
+  struct i386_see_regs sse;
   sel_t seg[8];
   sel_t ldt;
   sel_t tr;
@@ -486,8 +519,11 @@
 typedef struct x86emu_s {
   x86emu_regs_t x86;
   x86emu_code_handler_t code_check;
+  x86emu_cpuid_handler_t cpuid;
   x86emu_memio_handler_t memio;
   x86emu_intr_handler_t intr;
+  x86emu_wrmsr_handler_t wrmsr;
+  x86emu_wrmsr_handler_t rdmsr;
   x86emu_mem_t *mem;
   struct {
     unsigned char *map;
@@ -532,6 +568,9 @@
 void x86emu_set_page(x86emu_t *emu, unsigned page, void *address);
 void x86emu_reset_access_stats(x86emu_t *emu);
 
+x86emu_rdmsr_handler_t x86emu_set_rdmsr_handler(x86emu_t *emu, 
x86emu_rdmsr_handler_t handler);
+x86emu_wrmsr_handler_t x86emu_set_wrmsr_handler(x86emu_t *emu, 
x86emu_wrmsr_handler_t handler);
+x86emu_cpuid_handler_t x86emu_set_cpuid_handler(x86emu_t *emu, 
x86emu_cpuid_handler_t handler);
 x86emu_code_handler_t x86emu_set_code_handler(x86emu_t *emu, 
x86emu_code_handler_t handler);
 x86emu_intr_handler_t x86emu_set_intr_handler(x86emu_t *emu, 
x86emu_intr_handler_t handler);
 x86emu_memio_handler_t x86emu_set_memio_handler(x86emu_t *emu, 
x86emu_memio_handler_t handler);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/ops.c new/libx86emu-2.6/ops.c
--- old/libx86emu-2.4/ops.c     2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/ops.c     2020-01-17 13:32:27.000000000 +0100
@@ -2386,9 +2386,15 @@
 static void x86emuOp_pushf_word(x86emu_t *emu, u8 op1)
 {
   u32 flags;
+  u32 mask = F_MSK;
+
+  if(emu->cpuid) {
+    /* Advertise CPUID support */
+    mask |= FB_ID;
+  }
 
   /* clear out *all* bits not representing flags, and turn on real bits */
-  flags = (emu->x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
+  flags = (emu->x86.R_EFLG & mask) | F_ALWAYS_ON;
 
   if(MODE_DATA32) {
     OP_DECODE("pushfd");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/ops2.c new/libx86emu-2.6/ops2.c
--- old/libx86emu-2.4/ops2.c    2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/ops2.c    2020-01-17 13:32:27.000000000 +0100
@@ -280,6 +280,209 @@
   OP_DECODE("wbinvd");
 }
 
+static void x86emuOp2_sse_enabled_check(x86emu_t *emu)
+{
+  if (emu->x86.R_CR0 & CR0_EM || !(emu->x86.R_CR0 & CR0_MP))
+    INTR_RAISE_UD(emu);
+  if (!(emu->x86.R_CR4 & CR4_OSFXSR))
+    INTR_RAISE_UD(emu);
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x10-0x11 0xf,0x28-0x29 0xf,0x2b-0x2c
+****************************************************************************/
+static void x86emuOp2_SSEmovops(x86emu_t *emu, u8 op2)
+{
+  int mod, rl, rh;
+  I128_reg_t *src, *dst, tmp;
+  u32 addr = 0;
+
+  switch(op2 & 0xfe) {
+    case 0x10:
+      OP_DECODE("movups ");
+      break;
+    case 0x28:
+      OP_DECODE("movaps ");
+      break;
+    case 0x2b:
+      OP_DECODE("movntps ");
+      break;
+  }
+
+  x86emuOp2_sse_enabled_check(emu);
+
+  fetch_decode_modrm(emu, &mod, &rh, &rl);
+
+  if(mod == 3) {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    src = decode_rm_sse_register(emu, rl);
+    memcpy(dst, src, sizeof(*dst));
+  }
+  else {
+    if(!(op2 & 1)) {
+      dst = decode_rm_sse_register(emu, rh);
+      OP_DECODE(",");
+      addr = decode_rm_address(emu, mod, rl);
+      tmp = fetch_data_qlong(emu, addr);
+      /* check memory alignment if not movups */
+      if (((op2 & 0xfe) != 0x10) && (addr & 0xf)) {
+        INTR_RAISE_GP(emu, 0);
+        return;
+      }
+      memcpy(dst, &tmp, sizeof(*dst));
+    } else {
+      addr = decode_rm_address(emu, mod, rh);
+      OP_DECODE(",");
+      src = decode_rm_sse_register(emu, rl);
+      /* check memory alignment if not movups */
+      if(((op2 & 0xfe) != 0x10) && (addr & 0xf)) {
+        INTR_RAISE_GP(emu, 0);
+        return;
+      }
+      memcpy(&tmp, src, sizeof(tmp));
+      store_data_qlong(emu, addr, tmp);
+    }
+  }
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x12-0x13 0x0f,0x16-0x17
+****************************************************************************/
+static void x86emuOp2_SSEmovpackedops(x86emu_t *emu, u8 op2)
+{
+  int mod, rl, rh;
+  I128_reg_t *src, *dst;
+  u32 addr;
+
+  fetch_decode_modrm(emu, &mod, &rh, &rl);
+
+  switch(op2) {
+    case 0x12:
+      if (mod == 3)
+        OP_DECODE("movhlps ");
+      else
+        OP_DECODE("movlps ");
+      break;
+    case 0x13:
+      OP_DECODE("movlps ");
+      break;
+    case 0x16:
+      if (mod == 3)
+        OP_DECODE("movhlps ");
+      else
+        OP_DECODE("movhps ");
+      break;
+    case 0x17:
+      OP_DECODE("movhps ");
+      break;
+    default:
+      INTR_RAISE_UD(emu);
+      break;
+  }
+
+  x86emuOp2_sse_enabled_check(emu);
+
+  if(mod == 3) {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    src = decode_rm_sse_register(emu, rl);
+    for(int i = 0; i < FP_SP_SIZE * 2; i++) {
+      if (op2 == 0x12) {
+        dst->reg[i] = src->reg[i + FP_SP_SIZE * 2];
+      } else if (op2 == 0x16) {
+        dst->reg[i+ FP_SP_SIZE * 2] = src->reg[i];
+      }
+    }
+  }else{
+    if (op2 & 1) {
+      addr = decode_rm_address(emu, mod, rl);
+      OP_DECODE(",");
+      src = decode_rm_sse_register(emu, rh);
+
+      for(int i = 0; i < FP_SP_SIZE * 2; i++) {
+        if (op2 == 0x13) {
+          store_data_byte(emu, addr + i, src->reg[i]);
+        } else if (op2 == 0x17) {
+          store_data_byte(emu, addr + i, src->reg[i+FP_SP_SIZE*2]);
+        }
+      }
+    } else {
+      dst = decode_rm_sse_register(emu, rh);
+      OP_DECODE(",");
+      addr = decode_rm_address(emu, mod, rl);
+
+      for(int i = 0; i < FP_SP_SIZE * 2; i++) {
+        if (op2 == 0x12) {
+          dst->reg[i] = fetch_data_byte(emu, addr + i);
+        } else if (op2 == 0x16) {
+          dst->reg[i+FP_SP_SIZE*2] = fetch_data_byte(emu, addr + i);
+        }
+      }
+    }
+  }
+}
+
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0x14-0x15
+****************************************************************************/
+static void x86emuOp2_SSEpackops(x86emu_t *emu, u8 op2)
+{
+  int mod, rl, rh, off;
+  I128_reg_t *src, *dst, tmp, arith;
+  u32 addr;
+
+  switch(op2) {
+    case 0x14:
+      OP_DECODE("unpcklps ");
+      break;
+    case 0x15:
+      OP_DECODE("unpckhps ");
+      break;
+    default:
+      INTR_RAISE_UD(emu);
+      break;
+  }
+
+  x86emuOp2_sse_enabled_check(emu);
+
+  fetch_decode_modrm(emu, &mod, &rh, &rl);
+
+  if(mod == 3) {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    src = decode_rm_sse_register(emu, rl);
+  } else {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    addr = decode_rm_address(emu, mod, rl);
+    tmp = fetch_data_qlong(emu, addr);
+    src = &tmp;
+  }
+
+  if(op2 == 0x14) {
+    off = 0;
+  } else {
+    off = 2;
+  }
+
+  arith.reg[0] = dst->reg[off + 0];
+  arith.reg[1] = src->reg[off + 0];
+  arith.reg[2] = dst->reg[off + 1];
+  arith.reg[3] = src->reg[off + 1];
+  arith.reg[4] = dst->reg[off + 4];
+  arith.reg[5] = src->reg[off + 4];
+  arith.reg[6] = dst->reg[off + 5];
+  arith.reg[7] = src->reg[off + 5];
+
+  for(int i = 0; i < FP_SP_SIZE; i++) {
+    dst->reg[i] = arith.reg[i];
+  }
+}
 
 /****************************************************************************
 REMARKS:
@@ -389,8 +592,9 @@
     INTR_RAISE_UD(emu);
   }
   else {
-    emu->x86.msr[u] = ((u64) emu->x86.R_EDX << 32) + emu->x86.R_EAX;
-    emu->x86.msr_perm[u] |= X86EMU_ACC_W;
+    if(emu->wrmsr) {
+      emu->wrmsr(emu);
+    }
   }
 }
 
@@ -421,14 +625,13 @@
   OP_DECODE("rdmsr");
 
   u = emu->x86.R_ECX;
-
   if(u >= X86EMU_MSRS) {
     INTR_RAISE_UD(emu);
   }
   else {
-    emu->x86.R_EDX = emu->x86.msr[u] >> 32;
-    emu->x86.R_EAX = emu->x86.msr[u];
-    emu->x86.msr_perm[u] |= X86EMU_ACC_R;
+    if(emu->rdmsr) {
+      emu->rdmsr(emu);
+    }
   }
 }
 
@@ -597,6 +800,68 @@
 
 /****************************************************************************
 REMARKS:
+Handles opcode 0x0f,0x54-57
+****************************************************************************/
+static void x86emuOp2_SSElogicalops(x86emu_t *emu, u8 op2)
+{
+  int mod, rl, rh;
+  I128_reg_t *src, *dst, tmp;
+  u32 addr;
+
+  switch(op2) {
+    case 0x54:
+      OP_DECODE("andps ");
+      break;
+    case 0x55:
+      OP_DECODE("andnps ");
+      break;
+    case 0x56:
+      OP_DECODE("orps ");
+      break;
+    case 0x57:
+      OP_DECODE("xorps ");
+      break;
+    default:
+      INTR_RAISE_UD(emu);
+      break;
+  }
+
+  x86emuOp2_sse_enabled_check(emu);
+
+  fetch_decode_modrm(emu, &mod, &rh, &rl);
+
+  if(mod == 3) {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    src = decode_rm_sse_register(emu, rl);
+  }
+  else {
+    dst = decode_rm_sse_register(emu, rh);
+    OP_DECODE(",");
+    addr = decode_rm_address(emu, mod, rl);
+    tmp = fetch_data_qlong(emu, addr);
+    src = &tmp;
+  }
+  for(int i = 0; i < sizeof(dst->reg); i++) {
+    switch(op2) {
+      case 0x54:
+        dst->reg[i] &= src->reg[i];
+        break;
+      case 0x55:
+        dst->reg[i] &= ~src->reg[i];
+        break;
+      case 0x56:
+        dst->reg[i] |= src->reg[i];
+        break;
+      case 0x57:
+        dst->reg[i] ^= src->reg[i];
+        break;
+    }
+  }
+}
+
+/****************************************************************************
+REMARKS:
 Handles opcode 0x0f,0x80-0x8F
 ****************************************************************************/
 static void x86emuOp2_long_jump(x86emu_t *emu, u8 op2)
@@ -679,6 +944,21 @@
   x86emu_set_seg_register(emu, emu->x86.R_FS_SEL, MODE_DATA32 ? pop_long(emu) 
: pop_word(emu));
 }
 
+/****************************************************************************
+REMARKS:
+Handles opcode 0x0f,0xa2
+****************************************************************************/
+static void x86emuOp2_cpuid(x86emu_t *emu, u8 op2)
+{
+  OP_DECODE("cpuid ");
+
+  if(emu->cpuid) {
+    emu->cpuid(emu);
+  }
+  else {
+    INTR_RAISE_UD(emu);
+  }
+}
 
 /****************************************************************************
 REMARKS:
@@ -1781,14 +2061,14 @@
   /*  0x0e */ x86emuOp2_illegal_op,
   /*  0x0f */ x86emuOp2_illegal_op,
 
-  /*  0x10 */ x86emuOp2_illegal_op,
-  /*  0x11 */ x86emuOp2_illegal_op,
-  /*  0x12 */ x86emuOp2_illegal_op,
-  /*  0x13 */ x86emuOp2_illegal_op,
-  /*  0x14 */ x86emuOp2_illegal_op,
-  /*  0x15 */ x86emuOp2_illegal_op,
-  /*  0x16 */ x86emuOp2_illegal_op,
-  /*  0x17 */ x86emuOp2_illegal_op,
+  /*  0x10 */ x86emuOp2_SSEmovops,
+  /*  0x11 */ x86emuOp2_SSEmovops,
+  /*  0x12 */ x86emuOp2_SSEmovpackedops,
+  /*  0x13 */ x86emuOp2_SSEmovpackedops,
+  /*  0x14 */ x86emuOp2_SSEpackops,
+  /*  0x15 */ x86emuOp2_SSEpackops,
+  /*  0x16 */ x86emuOp2_SSEmovpackedops,
+  /*  0x17 */ x86emuOp2_SSEmovpackedops,
   /*  0x18 */ x86emuOp2_illegal_op,
   /*  0x19 */ x86emuOp2_illegal_op,
   /*  0x1a */ x86emuOp2_illegal_op,
@@ -1806,11 +2086,11 @@
   /*  0x25 */ x86emuOp2_illegal_op,
   /*  0x26 */ x86emuOp2_illegal_op,  /* mov treg,reg32 (ring 0 PM) */
   /*  0x27 */ x86emuOp2_illegal_op,
-  /*  0x28 */ x86emuOp2_illegal_op,
-  /*  0x29 */ x86emuOp2_illegal_op,
+  /*  0x28 */ x86emuOp2_SSEmovops,
+  /*  0x29 */ x86emuOp2_SSEmovops,
   /*  0x2a */ x86emuOp2_illegal_op,
-  /*  0x2b */ x86emuOp2_illegal_op,
-  /*  0x2c */ x86emuOp2_illegal_op,
+  /*  0x2b */ x86emuOp2_SSEmovops,
+  /*  0x2c */ x86emuOp2_SSEmovops,
   /*  0x2d */ x86emuOp2_illegal_op,
   /*  0x2e */ x86emuOp2_illegal_op,
   /*  0x2f */ x86emuOp2_illegal_op,
@@ -1853,10 +2133,10 @@
   /*  0x51 */ x86emuOp2_illegal_op,
   /*  0x52 */ x86emuOp2_illegal_op,
   /*  0x53 */ x86emuOp2_illegal_op,
-  /*  0x54 */ x86emuOp2_illegal_op,
-  /*  0x55 */ x86emuOp2_illegal_op,
-  /*  0x56 */ x86emuOp2_illegal_op,
-  /*  0x57 */ x86emuOp2_illegal_op,
+  /*  0x54 */ x86emuOp2_SSElogicalops,
+  /*  0x55 */ x86emuOp2_SSElogicalops,
+  /*  0x56 */ x86emuOp2_SSElogicalops,
+  /*  0x57 */ x86emuOp2_SSElogicalops,
   /*  0x58 */ x86emuOp2_illegal_op,
   /*  0x59 */ x86emuOp2_illegal_op,
   /*  0x5a */ x86emuOp2_illegal_op,
@@ -1936,7 +2216,7 @@
 
   /*  0xa0 */ x86emuOp2_push_FS,
   /*  0xa1 */ x86emuOp2_pop_FS,
-  /*  0xa2 */ x86emuOp2_illegal_op,
+  /*  0xa2 */ x86emuOp2_cpuid,
   /*  0xa3 */ x86emuOp2_bt_R,
   /*  0xa4 */ x86emuOp2_shld_IMM,
   /*  0xa5 */ x86emuOp2_shld_CL,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/prim_ops.c new/libx86emu-2.6/prim_ops.c
--- old/libx86emu-2.4/prim_ops.c        2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/prim_ops.c        2020-01-17 13:32:27.000000000 +0100
@@ -2684,6 +2684,7 @@
 
     case 3:    /* BE */
       cond = (flags & F_CF) != 0;
+      /* fallthrough */
 
     case 2:    /* Z */
       cond |= (flags & F_ZF) != 0;
@@ -2699,6 +2700,7 @@
 
     case 7:    /* LE */
       cond = (flags & F_ZF) != 0;
+      /* fallthrough */
 
     case 6:    /* L */
       cond |= ((flags & F_SF) != 0) ^ ((flags & F_OF) != 0);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libx86emu-2.4/test/Makefile 
new/libx86emu-2.6/test/Makefile
--- old/libx86emu-2.4/test/Makefile     2019-08-20 16:23:47.000000000 +0200
+++ new/libx86emu-2.6/test/Makefile     2020-01-17 13:32:27.000000000 +0100
@@ -1,8 +1,9 @@
 CC         = gcc
 CFLAGS     = -g -Wall -fomit-frame-pointer -O2
-TST_FILES  = $(wildcard *.tst)
+LDFLAGS    =
+TST_FILES  = $(sort $(wildcard *.tst))
 INIT_FILES = $(addsuffix .init,$(basename $(wildcard *.tst)))
-RES_FILES  = $(addsuffix .result,$(basename $(wildcard *.tst)))
+RES_FILES  = $(sort $(addsuffix .result,$(basename $(wildcard *.tst))))
 TEST_OPTS  = --verbose --show code,regs,data,acc,io,ints,attr,time
 
 export LD_LIBRARY_PATH=..
@@ -17,7 +18,7 @@
        @./x86test $(TEST_OPTS) *.init
 
 x86test: x86test.c
-       $(CC) $(CFLAGS) $< -lx86emu -o $@
+       $(CC) $(CFLAGS) $< -I ../include -L .. -lx86emu -o $@ $(LDFLAGS)
 
 %.result: %.init
        @./x86test $(TEST_OPTS) $<


Reply via email to