about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-03-14 10:01:00 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-03-14 10:01:00 +0100
commit8115b4705109028650bdf0236b23a4991ddaaed2 (patch)
tree019025eb43bc079317003b5f7c6538a5e5590569 /src
parent6384cc6e8614e7cb4837a9e3c44e84cb206c267a (diff)
downloadbox64-8115b4705109028650bdf0236b23a4991ddaaed2.tar.gz
box64-8115b4705109028650bdf0236b23a4991ddaaed2.zip
Added 64 66 83 opcodes ([ARM64_DYNAREC] too)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_6664.c93
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h15
-rw-r--r--src/emu/x64run6664.c25
3 files changed, 132 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_6664.c b/src/dynarec/arm64/dynarec_arm64_6664.c
index 0372a8a1..d5b14771 100644
--- a/src/dynarec/arm64/dynarec_arm64_6664.c
+++ b/src/dynarec/arm64/dynarec_arm64_6664.c
@@ -27,8 +27,9 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 
     uint8_t opcode = F8;
     uint8_t nextop;
-    uint8_t gd, ed;
+    uint8_t gd, ed, wb1, wback;
     int64_t j64;
+    int16_t i16;
     int v0, v1;
     int64_t fixedaddress;
     int unscaled;
@@ -119,6 +120,96 @@ uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             }
             break;
 
+        case 0x83:
+            nextop = F8;
+            switch((nextop>>3)&7) {
+                case 0: //ADD
+                    if(opcode==0x81) {INST_NAME("ADD Ew, Iw");} else {INST_NAME("ADD Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_add16(dyn, ninst, ed, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 1: //OR
+                    if(opcode==0x81) {INST_NAME("OR Ew, Iw");} else {INST_NAME("OR Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_or16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 2: //ADC
+                    if(opcode==0x81) {INST_NAME("ADC Ew, Iw");} else {INST_NAME("ADC Ew, Ib");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_adc16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 3: //SBB
+                    if(opcode==0x81) {INST_NAME("SBB Ew, Iw");} else {INST_NAME("SBB Ew, Ib");}
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_sbb16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 4: //AND
+                    if(opcode==0x81) {INST_NAME("AND Ew, Iw");} else {INST_NAME("AND Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_and16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 5: //SUB
+                    if(opcode==0x81) {INST_NAME("SUB Ew, Iw");} else {INST_NAME("SUB Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_sub16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 6: //XOR
+                    if(opcode==0x81) {INST_NAME("XOR Ew, Iw");} else {INST_NAME("XOR Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    MOVZw(x5, i16);
+                    emit_xor16(dyn, ninst, x1, x5, x2, x4);
+                    EWBACK;
+                    break;
+                case 7: //CMP
+                    if(opcode==0x81) {INST_NAME("CMP Ew, Iw");} else {INST_NAME("CMP Ew, Ib");}
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    GETEWO(x1, (opcode==0x81)?2:1);
+                    if(opcode==0x81) i16 = F16S; else i16 = F8S;
+                    if(i16) {
+                        MOVZw(x2, i16);
+                        emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5);
+                    } else
+                        emit_cmp16_0(dyn, ninst, x1, x3, x4);
+                    break;
+            }
+            break;
+            
         case 0x89:
             INST_NAME("MOV FS:Ew, Gw");
             nextop = F8;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 8faff5d6..e1e94f88 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -280,6 +280,21 @@
                     ed = i;                 \
                     wb1 = 1;                \
                 }
+//GETEWO will use i for ed, i is also Offset, and can use r3 for wback.
+#define GETEWO(i, D) if(MODREG) {               \
+                    wback = xRAX+(nextop&7)+(rex.b<<3);\
+                    UXTHw(i, wback);            \
+                    ed = i;                     \
+                    wb1 = 0;                    \
+                } else {                        \
+                    SMREAD();                   \
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, (1<<1)-1, rex, NULL, 0, D); \
+                    ADDx_REG(x3, wback, i);     \
+                    if(wback!=x3) wback = x3;   \
+                    LDH(i, wback, fixedaddress);\
+                    wb1 = 1;                    \
+                    ed = i;                     \
+                }
 //GETSEW will use i for ed, and can use r3 for wback. This is the Signed version
 #define GETSEW(i, D) if(MODREG) {           \
                     wback = xRAX+(nextop&7)+(rex.b<<3);\
diff --git a/src/emu/x64run6664.c b/src/emu/x64run6664.c
index c91b3cbc..a76f2bc7 100644
--- a/src/emu/x64run6664.c
+++ b/src/emu/x64run6664.c
@@ -30,6 +30,8 @@ uintptr_t Run6664(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
 {

     uint8_t opcode;

     uint8_t nextop;

+    uint16_t tmp16u;

+    int16_t tmp16s;

     reg64_t *oped, *opgd;

     sse_regs_t *opex, *opgx;

     #ifdef TEST_INTERPRETER

@@ -117,6 +119,29 @@ uintptr_t Run6664(x64emu_t *emu, rex_t rex, int seg, uintptr_t addr)
             else

                 cmp16(emu, EW->word[0], GW->word[0]);

             break;

+

+        case 0x83:                              /* GRP3 Ew,Ib */

+            nextop = F8;

+            GETEW_OFFS((opcode==0x81)?2:1, tlsdata);

+            GETGW;

+            if(opcode==0x81) 

+                tmp16u = F16;

+            else {

+                tmp16s = F8S;

+                tmp16u = (uint16_t)tmp16s;

+            }

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

+                case 0: EW->word[0] = add16(emu, EW->word[0], tmp16u); break;

+                case 1: EW->word[0] =  or16(emu, EW->word[0], tmp16u); break;

+                case 2: EW->word[0] = adc16(emu, EW->word[0], tmp16u); break;

+                case 3: EW->word[0] = sbb16(emu, EW->word[0], tmp16u); break;

+                case 4: EW->word[0] = and16(emu, EW->word[0], tmp16u); break;

+                case 5: EW->word[0] = sub16(emu, EW->word[0], tmp16u); break;

+                case 6: EW->word[0] = xor16(emu, EW->word[0], tmp16u); break;

+                case 7:               cmp16(emu, EW->word[0], tmp16u); break;

+            }

+            break;

+

         case 0x89:                              /* MOV FS:Ew,Gw */

             nextop = F8;

             GETEW_OFFS(0, tlsdata);