about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorLeslie Zhai <zhaixiang@loongson.cn>2024-12-07 16:58:20 +0800
committerGitHub <noreply@github.com>2024-12-07 09:58:20 +0100
commiteb299f500b296266a1da2f30495de3fb0805f41a (patch)
tree8497971548d260f3b5ad495f0e14a643f9845025 /src
parenta25b50d3aa653e716ec1bb949c18686d0c03bcc5 (diff)
downloadbox64-eb299f500b296266a1da2f30495de3fb0805f41a.tar.gz
box64-eb299f500b296266a1da2f30495de3fb0805f41a.zip
[LA64_DYNAREC] Added AES opcodes (#2122)
* [LA64_DYNAREC] Added AES opcodes

* [LA64_DYNAREC] Use LSX instruction instead
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 4c42c327..4daba8bf 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -316,6 +316,82 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETEX(q1, 0, 0);
                     VSIGNCOV_W(q0, q1, q0);
                     break;
+                case 0xDB:
+                    INST_NAME("AESIMC Gx, Ex"); // AES-NI
+                    nextop = F8;
+                    GETEX(q1, 0, 0);
+                    GETGX_empty(q0);
+                    if (q0 != q1) {
+                        VOR_V(q0, q1, q1);
+                    }
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aesimc, -1);
+                    break;
+                case 0xDC:
+                    INST_NAME("AESENC Gx, Ex"); // AES-NI
+                    nextop = F8;
+                    GETG;
+                    GETEX(q1, 0, 0);
+                    if (MODREG && (gd == (nextop & 7) + (rex.b << 3))) {
+                        d0 = fpu_get_scratch(dyn);
+                        VOR_V(d0, q1, q1);
+                    } else
+                        d0 = -1;
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aese, -1);
+                    GETGX(q0, 1);
+                    VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
+                    break;
+                case 0xDD:
+                    INST_NAME("AESENCLAST Gx, Ex"); // AES-NI
+                    nextop = F8;
+                    GETG;
+                    GETEX(q1, 0, 0);
+                    if (MODREG && (gd == (nextop & 7) + (rex.b << 3))) {
+                        d0 = fpu_get_scratch(dyn);
+                        VOR_V(d0, q1, q1);
+                    } else
+                        d0 = -1;
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aeselast, -1);
+                    GETGX(q0, 1);
+                    VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
+                    break;
+                case 0xDE:
+                    INST_NAME("AESDEC Gx, Ex"); // AES-NI
+                    nextop = F8;
+                    GETG;
+                    GETEX(q1, 0, 0);
+                    if (MODREG && (gd == (nextop & 7) + (rex.b << 3))) {
+                        d0 = fpu_get_scratch(dyn);
+                        VOR_V(d0, q1, q1);
+                    } else
+                        d0 = -1;
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aesd, -1);
+                    GETGX(q0, 1);
+                    VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
+                    break;
+                case 0xDF:
+                    INST_NAME("AESDECLAST Gx, Ex"); // AES-NI
+                    nextop = F8;
+                    GETG;
+                    GETEX(q1, 0, 0);
+                    if (MODREG && (gd == (nextop & 7) + (rex.b << 3))) {
+                        d0 = fpu_get_scratch(dyn);
+                        VOR_V(d0, q1, q1);
+                    } else
+                        d0 = -1;
+                    sse_forget_reg(dyn, ninst, gd);
+                    MOV32w(x1, gd);
+                    CALL(native_aesdlast, -1);
+                    GETGX(q0, 1);
+                    VXOR_V(q0, q0, (d0 != -1) ? d0 : q1);
+                    break;
                 default:
                     DEFAULT;
             }