diff options
| author | phorcys <phorcys@126.com> | 2025-07-09 14:10:14 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-09 08:10:14 +0200 |
| commit | aeec79ec008e373fa9797f3fabb0a03261526fe6 (patch) | |
| tree | 9d9424e31ddb2cffac66da6a53338aad778c4a8c | |
| parent | b1971c8ef3e7206ecc60993065f2c948af756d9b (diff) | |
| download | box64-aeec79ec008e373fa9797f3fabb0a03261526fe6.tar.gz box64-aeec79ec008e373fa9797f3fabb0a03261526fe6.zip | |
[LA64_DYNAREC] Add la64 avx bitwise ops. (#2780)
* avx VEX.66.0F 54/55/56/57 VANDPD/VANDNPD/VORPD/VXORPD * avx VEX.0F 54/55/56/57 VANDPS/VANDNPS/VORPS/VXORPS * avx VEX.66.0F DB/DF/EB/EF VPAND/VPANDN/VPOR/VPXOR * bmi1 VEX.0F38 F2 ANDN * bmi2 VEX.F2.0F3A F0 RORX
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx.c | 16 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx_0f.c | 24 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx_0f38.c | 87 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx_66_0f.c | 48 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_avx_f2_0f3a.c | 72 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 56 | ||||
| -rw-r--r-- | src/dynarec/la64/la64_emitter.h | 35 |
8 files changed, 307 insertions, 33 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index e9d86097..6050b3b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1097,10 +1097,12 @@ if(LARCH64_DYNAREC) "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_f30f.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_0f.c" + "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_0f38.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_66_0f.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_66_0f38.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_66_0f3a.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_f2_0f.c" + "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_f2_0f3a.c" "${BOX64_ROOT}/src/dynarec/la64/dynarec_la64_avx_f3_0f.c" ) endif() diff --git a/src/dynarec/la64/dynarec_la64_avx.c b/src/dynarec/la64/dynarec_la64_avx.c index 1a8a14a7..12e00db2 100644 --- a/src/dynarec/la64/dynarec_la64_avx.c +++ b/src/dynarec/la64/dynarec_la64_avx.c @@ -51,8 +51,8 @@ uintptr_t dynarec64_AVX(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int n if ((vex.m == VEX_M_0F) && (vex.p == VEX_P_NONE)) addr = dynarec64_AVX_0F(dyn, addr, ip, ninst, vex, ok, need_epilog); - // else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_NONE)) - // addr = dynarec64_AVX_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog); + else if ((vex.m == VEX_M_0F38) && (vex.p == VEX_P_NONE)) + addr = dynarec64_AVX_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog); else if ((vex.m == VEX_M_0F) && (vex.p == VEX_P_66)) addr = dynarec64_AVX_66_0F(dyn, addr, ip, ninst, vex, ok, need_epilog); else if ((vex.m == VEX_M_0F) && (vex.p == VEX_P_F2)) @@ -65,17 +65,17 @@ uintptr_t dynarec64_AVX(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int n addr = dynarec64_AVX_66_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog); // else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F2)) // addr = dynarec64_AVX_F2_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog); - // else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_F2)) - // addr = dynarec64_AVX_F2_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog); + else if ((vex.m == VEX_M_0F3A) && (vex.p == VEX_P_F2)) + addr = dynarec64_AVX_F2_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog); // else if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_F3)) // addr = dynarec64_AVX_F3_0F38(dyn, addr, ip, ninst, vex, ok, need_epilog); else { DEFAULT; } - if((*ok==-1) && (BOX64ENV(dynarec_log)>=LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing))) - if(!dyn->size || BOX64ENV(dynarec_log)>LOG_INFO || dyn->need_dump) { - dynarec_log(LOG_NONE, " Dynarec unimplemented VEX opcode size %d prefix %s map %s opcode %02X\n", 128<<vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); - } + if ((*ok == -1) && (BOX64ENV(dynarec_log) >= LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing))) + if (!dyn->size || BOX64ENV(dynarec_log) > LOG_INFO || dyn->need_dump) { + dynarec_log(LOG_NONE, " Dynarec unimplemented VEX opcode size %d prefix %s map %s opcode %02X\n", 128 << vex.l, avx_prefix_string(vex.p), avx_map_string(vex.m), opcode); + } return addr; } \ No newline at end of file diff --git a/src/dynarec/la64/dynarec_la64_avx_0f.c b/src/dynarec/la64/dynarec_la64_avx_0f.c index 52243184..47208926 100644 --- a/src/dynarec/la64/dynarec_la64_avx_0f.c +++ b/src/dynarec/la64/dynarec_la64_avx_0f.c @@ -233,6 +233,30 @@ uintptr_t dynarec64_AVX_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, in VPICKVE2GR_DU(gd, d1, 0); } break; + case 0x54: + INST_NAME("VANDPS Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VAND_Vxy(v0, v1, v2); + break; + case 0x55: + INST_NAME("VANDNPS Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VANDN_Vxy(v0, v1, v2); + break; + case 0x56: + INST_NAME("VORPS Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VOR_Vxy(v0, v1, v2); + break; + case 0x57: + INST_NAME("VXORPS Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VXOR_Vxy(v0, v1, v2); + break; case 0x77: if (!vex.l) { INST_NAME("VZEROUPPER"); diff --git a/src/dynarec/la64/dynarec_la64_avx_0f38.c b/src/dynarec/la64/dynarec_la64_avx_0f38.c new file mode 100644 index 00000000..fd2bcf5d --- /dev/null +++ b/src/dynarec/la64/dynarec_la64_avx_0f38.c @@ -0,0 +1,87 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <errno.h> + +#include "debug.h" +#include "env.h" +#include "box64context.h" +#include "box64cpu.h" +#include "emu/x64emu_private.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" + +#include "la64_printer.h" +#include "dynarec_la64_private.h" +#include "dynarec_la64_functions.h" +#include "../dynarec_helper.h" + +uintptr_t dynarec64_AVX_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) +{ + (void)ip; + (void)need_epilog; + + uint8_t opcode = F8; + uint8_t nextop, u8; + uint8_t gd, ed, vd; + uint8_t wback, wb1, wb2; + uint8_t eb1, eb2, gb1, gb2; + int32_t i32, i32_; + int cacheupd = 0; + int v0, v1, v2; + int q0, q1, q2; + int d0, d1, d2; + int s0; + uint64_t tmp64u; + int64_t j64; + int64_t fixedaddress; + int unscaled; + MAYUSE(wb1); + MAYUSE(wb2); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(gb1); + MAYUSE(gb2); + MAYUSE(q0); + MAYUSE(q1); + MAYUSE(d0); + MAYUSE(d1); + MAYUSE(s0); + MAYUSE(j64); + MAYUSE(cacheupd); + + rex_t rex = vex.rex; + + switch (opcode) { + case 0xF2: + INST_NAME("ANDN Gd, Vd, Ed"); + nextop = F8; + SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION); + GETGD; + GETED(0); + GETVD; + ANDN(gd, ed, vd); + if (!rex.w) { + BSTRPICK_D(gd, gd, 31, 0); + } + CLEAR_FLAGS(x6); + IFX (X_SF) { + SRLI_D(x6, gd, rex.w ? 63 : 31); + BEQZ(x6, 8); + ORI(xFlags, xFlags, 1 << F_SF); + } + IFX (X_ZF) { + BNEZ(gd, 8); + ORI(xFlags, xFlags, 1 << F_ZF); + } + SPILL_EFLAGS(); + break; + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/la64/dynarec_la64_avx_66_0f.c b/src/dynarec/la64/dynarec_la64_avx_66_0f.c index db6f4c96..3f04d192 100644 --- a/src/dynarec/la64/dynarec_la64_avx_66_0f.c +++ b/src/dynarec/la64/dynarec_la64_avx_66_0f.c @@ -227,6 +227,30 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, VPICKVE2GR_DU(gd, d1, 0); } break; + case 0x54: + INST_NAME("VANDPD Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VAND_Vxy(v0, v1, v2); + break; + case 0x55: + INST_NAME("VANDNPD Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VANDN_Vxy(v0, v1, v2); + break; + case 0x56: + INST_NAME("VORPD Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VOR_Vxy(v0, v1, v2); + break; + case 0x57: + INST_NAME("VXORPD Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VXOR_Vxy(v0, v1, v2); + break; case 0x6E: INST_NAME("VMOVD Gx, Ed"); nextop = F8; @@ -334,6 +358,18 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, VPICKVE2GR_DU(gd, d1, 0); } break; + case 0xDB: + INST_NAME("VPAND Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VAND_Vxy(v0, v1, v2); + break; + case 0xDF: + INST_NAME("VPANDN Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VANDN_Vxy(v0, v1, v2); + break; case 0xE7: INST_NAME("VMOVNTDQ Ex, Gx"); nextop = F8; @@ -350,6 +386,18 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, SMWRITE2(); } break; + case 0xEB: + INST_NAME("VPOR Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VOR_Vxy(v0, v1, v2); + break; + case 0xEF: + INST_NAME("VPXOR Gx, Vx, Ex"); + nextop = F8; + GETGY_empty_VYEY_xy(v0, v1, v2, 0); + VXOR_Vxy(v0, v1, v2); + break; case 0xF7: INST_NAME("VMASKMOVDQU Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_avx_f2_0f3a.c b/src/dynarec/la64/dynarec_la64_avx_f2_0f3a.c new file mode 100644 index 00000000..4181c68c --- /dev/null +++ b/src/dynarec/la64/dynarec_la64_avx_f2_0f3a.c @@ -0,0 +1,72 @@ +#include <stdio.h> +#include <stdlib.h> +#include <stddef.h> +#include <errno.h> + +#include "debug.h" +#include "env.h" +#include "box64context.h" +#include "box64cpu.h" +#include "emu/x64emu_private.h" +#include "x64emu.h" +#include "box64stack.h" +#include "callback.h" +#include "emu/x64run_private.h" +#include "x64trace.h" +#include "dynarec_native.h" + +#include "la64_printer.h" +#include "dynarec_la64_private.h" +#include "dynarec_la64_functions.h" +#include "../dynarec_helper.h" + +uintptr_t dynarec64_AVX_F2_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) +{ + (void)ip; + (void)need_epilog; + + uint8_t opcode = F8; + uint8_t nextop, u8; + uint8_t gd, ed, vd; + uint8_t wback, wb1, wb2; + uint8_t eb1, eb2, gb1, gb2; + int32_t i32, i32_; + int cacheupd = 0; + int v0, v1, v2; + int q0, q1, q2; + int d0, d1, d2; + int s0; + uint64_t tmp64u; + int64_t j64; + int64_t fixedaddress; + int unscaled; + MAYUSE(wb1); + MAYUSE(wb2); + MAYUSE(eb1); + MAYUSE(eb2); + MAYUSE(gb1); + MAYUSE(gb2); + MAYUSE(q0); + MAYUSE(q1); + MAYUSE(d0); + MAYUSE(d1); + MAYUSE(s0); + MAYUSE(j64); + MAYUSE(cacheupd); + + rex_t rex = vex.rex; + + switch (opcode) { + case 0xF0: + INST_NAME("RORX Gd, Ed, Ib"); + nextop = F8; + GETGD; + GETED(1); + u8 = F8; + ROTRIxw(gd, ed, u8 & (rex.w ? 0x3f : 0x1f)); + break; + default: + DEFAULT; + } + return addr; +} diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 010742dd..9e636cda 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -38,6 +38,8 @@ // GETGD get x64 register in gd #define GETGD gd = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3)); +// GETVD get x64 register in vd +#define GETVD vd = TO_NAT(vex.v) // GETGW extract x64 register in gd, that is i #define GETGW(i) \ @@ -327,7 +329,7 @@ } #define VEXTRINS_IMM_4_0(n, m) ((n & 0xf) << 4 | (m & 0xf)) -#define XVPERMI_IMM_4_0(n, m) ((n & 0xf) << 4 | (m & 0xf)) +#define XVPERMI_IMM_4_0(n, m) ((n & 0xf) << 4 | (m & 0xf)) // Get GX as a quad (might use x1) #define GETGX(a, w) \ @@ -435,9 +437,9 @@ BSTRINS_D(wback, ed, wb2 + 7, wb2); \ } -#define YMM_UNMARK_UPPER_ZERO(a) \ - do { \ - dyn->lsx.avxcache[a].zero_upper = 0; \ +#define YMM_UNMARK_UPPER_ZERO(a) \ + do { \ + dyn->lsx.avxcache[a].zero_upper = 0; \ } while (0) // AVX helpers @@ -608,36 +610,36 @@ } // Get empty GY, and non-written VY and EY -#define GETGY_empty_VYEY_xy(gx, vx, ex, D) \ - GETVYxy(vx, 0); \ - GETEYxy(ex, 0, D); \ +#define GETGY_empty_VYEY_xy(gx, vx, ex, D) \ + GETVYxy(vx, 0); \ + GETEYxy(ex, 0, D); \ GETGYxy_empty(gx); // Get empty GY, and non-written EY -#define GETGY_empty_EY_xy(gx, ex, D) \ - GETEYxy(ex, 0, D); \ +#define GETGY_empty_EY_xy(gx, ex, D) \ + GETEYxy(ex, 0, D); \ GETGYxy_empty(gx); // Get writable GY, and non-written VY and EY -#define GETGY_VYEY_xy(gx, vx, ex, D) \ - GETVYxy(vx, 0); \ - GETEYxy(ex, 0, D); \ +#define GETGY_VYEY_xy(gx, vx, ex, D) \ + GETVYxy(vx, 0); \ + GETEYxy(ex, 0, D); \ GETGYxy(gx, 1); // Get writable GY, and non-written EY -#define GETGY_EY_xy(gx, ex, D) \ - GETEYxy(ex, 0, D); \ +#define GETGY_EY_xy(gx, ex, D) \ + GETEYxy(ex, 0, D); \ GETGYxy(gx, 1); // Get writable EY, and non-written VY and GY -#define GETEY_VYGY_xy(ex, vx, gx, D) \ - GETVYxy(vx, 0); \ - GETGYxy(gx, 0); \ +#define GETEY_VYGY_xy(ex, vx, gx, D) \ + GETVYxy(vx, 0); \ + GETGYxy(gx, 0); \ GETEYxy(ex, 1, D); // Get writable EY, and non-written GY -#define GETEY_GY_xy(ex, gx, D) \ - GETGYxy(gx, 0); \ +#define GETEY_GY_xy(ex, gx, D) \ + GETGYxy(gx, 0); \ GETEYxy(ex, 1, D); // Get direction with size Z and based of F_DF flag, on register r ready for load/store fetching @@ -1095,10 +1097,12 @@ #define dynarec64_F20F STEPNAME(dynarec64_F20F) #define dynarec64_AVX STEPNAME(dynarec64_AVX) #define dynarec64_AVX_0F STEPNAME(dynarec64_AVX_0F) +#define dynarec64_AVX_0F38 STEPNAME(dynarec64_AVX_0F38) #define dynarec64_AVX_66_0F STEPNAME(dynarec64_AVX_66_0F) #define dynarec64_AVX_66_0F38 STEPNAME(dynarec64_AVX_66_0F38) #define dynarec64_AVX_66_0F3A STEPNAME(dynarec64_AVX_66_0F3A) -#define dynarec64_AVX_F2_0F STEPNAME(dynarec64_AVX_F3_0F) +#define dynarec64_AVX_F2_0F STEPNAME(dynarec64_AVX_F2_0F) +#define dynarec64_AVX_F2_0F3A STEPNAME(dynarec64_AVX_F2_0F3A) #define dynarec64_AVX_F3_0F STEPNAME(dynarec64_AVX_F3_0F) #define geted STEPNAME(geted) @@ -1198,11 +1202,11 @@ #define sse_forget_reg STEPNAME(sse_forget_reg) #define sse_reflect_reg STEPNAME(sse_reflect_reg) -#define avx_get_reg STEPNAME(avx_get_reg) -#define avx_get_reg_empty STEPNAME(avx_get_reg_empty) -#define avx_forget_reg STEPNAME(sse_forget_reg) -#define avx_reflect_reg STEPNAME(avx_reflect_reg) -#define avx_purgecache STEPNAME(avx_purgecache) +#define avx_get_reg STEPNAME(avx_get_reg) +#define avx_get_reg_empty STEPNAME(avx_get_reg_empty) +#define avx_forget_reg STEPNAME(sse_forget_reg) +#define avx_reflect_reg STEPNAME(avx_reflect_reg) +#define avx_purgecache STEPNAME(avx_purgecache) #define avx_reflect_reg_upper128 STEPNAME(avx_reflect_reg_upper128) @@ -1385,10 +1389,12 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); +uintptr_t dynarec64_AVX_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_66_0F38(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_66_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_F2_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); +uintptr_t dynarec64_AVX_F2_0F3A(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); uintptr_t dynarec64_AVX_F3_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog); diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index f9c9782c..00ca7bdd 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -2622,4 +2622,39 @@ LSX instruction starts with V, LASX instruction starts with XV. } \ } while (0) +#define VAND_Vxy(vd, vj, vk) \ + do { \ + if (vex.l) { \ + XVAND_V(vd, vj, vk); \ + } else { \ + VAND_V(vd, vj, vk); \ + } \ + } while (0) + +#define VANDN_Vxy(vd, vj, vk) \ + do { \ + if (vex.l) { \ + XVANDN_V(vd, vj, vk); \ + } else { \ + VANDN_V(vd, vj, vk); \ + } \ + } while (0) + +#define VOR_Vxy(vd, vj, vk) \ + do { \ + if (vex.l) { \ + XVOR_V(vd, vj, vk); \ + } else { \ + VOR_V(vd, vj, vk); \ + } \ + } while (0) + +#define VXOR_Vxy(vd, vj, vk) \ + do { \ + if (vex.l) { \ + XVXOR_V(vd, vj, vk); \ + } else { \ + VXOR_V(vd, vj, vk); \ + } \ + } while (0) #endif //__ARM64_EMITTER_H__ |