about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-01-26 15:39:05 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-01-26 15:39:05 +0100
commit1d0d7e9e0901cdd20b6adffabd56eeb2ae2e2737 (patch)
treec9c1bbe8b74f9a8804a3ecaf7a9319b335694f22 /src
parentaab6bc086986bd22d513f05175276e5907340f86 (diff)
downloadbox64-1d0d7e9e0901cdd20b6adffabd56eeb2ae2e2737.tar.gz
box64-1d0d7e9e0901cdd20b6adffabd56eeb2ae2e2737.zip
Reworked 0F 01 opcode ([ARM64_DYNAREC] too)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c39
-rw-r--r--src/emu/x64run0f.c61
2 files changed, 54 insertions, 46 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 79058758..5b4253ab 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -65,6 +65,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
         case 0x01:

             // TODO:, /0 is SGDT. While 0F 01 D0 is XGETBV, etc...

             nextop = F8;

+            if(MODREG)

             switch(nextop) {

                 case 0xD0:

                     INST_NAME("FAKE xgetbv");

@@ -78,15 +79,35 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     *ok = 0;

                     break;

                 default:

-                    switch((nextop>>3)&7) {

-                        case 0: // SGDT

-                            INST_NAME("FAKE sgdt Ed");

-                            addr = fakeed(dyn, addr, ninst, nextop);

-                                // do nothing for now...

-                            break;

-                        default:

-                            DEFAULT;

-                    }

+                    DEFAULT;

+            } else

+                switch((nextop>>3)&7) {

+                    case 0: // SGDT

+                        INST_NAME("SGDT Ed");

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);

+                        MOV32w(x1, 0x7f);

+                        STURH_I9(x1, wback, 0);

+                        MOV32w(x1, 0x000c);

+                        STURH_I9(x1, wback, 2);

+                        MOV32w(x1, 0xd000);

+                        STURH_I9(x1, wback, 4);

+                        break;

+                    case 1:

+                        INST_NAME("SIDT Ed");

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);

+                        MOV32w(x1, 0xfff);

+                        STURH_I9(x1, wback, 0);

+                        STURw_I9(xZR, wback, 2);

+                        break;

+                    case 4:

+                        INST_NAME("SMSW Ew");

+                        addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);

+                        // dummy for now... Do I need to track CR0 state?

+                        MOV32w(x1, (1<<0) | (1<<4)); // only PE and ET set...

+                        STURH_I9(x1, wback, 0);

+                        break;

+                    default:

+                        DEFAULT;

             }

             break;

 

diff --git a/src/emu/x64run0f.c b/src/emu/x64run0f.c
index 03147a9e..6fe11ca9 100644
--- a/src/emu/x64run0f.c
+++ b/src/emu/x64run0f.c
@@ -86,48 +86,35 @@ uintptr_t Run0F(x64emu_t *emu, rex_t rex, uintptr_t addr, int *step)
                 return 0;

             break;

         case 0x01:                      /* XGETBV, SGDT, etc... */

-            // this is a privilege opcode...

             nextop = F8;

             GETED(0);

+            if(MODREG)

             switch(nextop) {

                 case 0xD0:

-                #ifndef TEST_INTERPRETER

-                emit_signal(emu, SIGILL, (void*)R_RIP, 0);

-                #endif

-                break;

+                    #ifndef TEST_INTERPRETER

+                    emit_signal(emu, SIGILL, (void*)R_RIP, 0);

+                    #endif

+                    break;

                 default:

-                    if(rex.is32bits) {

-                        switch((nextop>>3)&7) {

-                            case 0:                 /* SGDT Ed */

-                                GETED(0);

-                                ED->word[0] = 0x7f;    // dummy return...

-                                ED->word[1] = 0x000c;

-                                ED->word[2] = 0xd000;

-                                break;

-                            case 1:                 /* SIDT Ed */

-                                GETED(0);

-                                ED->word[0] = 0xfff;    // dummy return, like "disabled"

-                                ED->word[1] = 0;

-                                ED->word[2] = 0;

-                                break;

-                            case 4:                 /* SMSW Ew */

-                                GETED(0);

-                                // dummy for now... Do I need to track CR0 state?

-                                ED->word[0] = (1<<0) | (1<<4); // only PE and ET set...

-                                break;

-                            default:

-                                return 0;

-                        }

-

-                    } else {

-                        switch((nextop>>3)&7) {

-                            case 0: // SGDT

-                                    // do nothing for now...

-                                break;

-                            default:

-                                return 0;

-                        }

-                    }

+                    return 0;

+            } else

+                switch((nextop>>3)&7) {

+                    case 0:                 /* SGDT Ed */

+                        ED->word[0] = 0x7f;    // dummy return...

+                        ED->word[1] = 0x000c;

+                        ED->word[2] = 0xd000;

+                        break;

+                    case 1:                 /* SIDT Ed */

+                        ED->word[0] = 0xfff;    // dummy return, like "disabled"

+                        ED->word[1] = 0;

+                        ED->word[2] = 0;

+                        break;

+                    case 4:                 /* SMSW Ew */

+                        // dummy for now... Do I need to track CR0 state?

+                        ED->word[0] = (1<<0) | (1<<4); // only PE and ET set...

+                        break;

+                    default:

+                        return 0;

             }

             break;