From bb253f37086d48106d59feb66b57957ba9d4715c Mon Sep 17 00:00:00 2001 From: phorcys Date: Thu, 26 Jun 2025 16:42:23 +0800 Subject: [LA64_DYNAREC] Add la64 avx load/store ops part 2. (#2773) * VEX.0f VMOVLPS/VMOVHPS/VMOVLHPS/VMOVHLPS * VEX.66.0f VMOVLPD/VMOVHPD --- src/dynarec/la64/dynarec_la64_avx_0f.c | 59 +++++++++++++++++++++++++++++++ src/dynarec/la64/dynarec_la64_avx_66_0f.c | 54 ++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) diff --git a/src/dynarec/la64/dynarec_la64_avx_0f.c b/src/dynarec/la64/dynarec_la64_avx_0f.c index 9c693fc3..e5b3af89 100644 --- a/src/dynarec/la64/dynarec_la64_avx_0f.c +++ b/src/dynarec/la64/dynarec_la64_avx_0f.c @@ -99,6 +99,65 @@ uintptr_t dynarec64_AVX_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, in SMWRITE2(); } break; + case 0x12: + nextop = F8; + GETVYx(v1, 0); + if (MODREG) { + INST_NAME("VMOVHLPS Gx, Vx, Ex"); + GETEYx(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(0, 1)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(1, 1)); + } else { + INST_NAME("VMOVLPS Gx, Vx, Ex"); + GETEYSD(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(0, 0)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(1, 1)); + } + break; + case 0x13: + nextop = F8; + INST_NAME("VMOVLPS Ex, Gx"); + GETGYx(v0, 0); + if (MODREG) { + DEFAULT; + return addr; + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 1, 0); + FST_D(v0, ed, fixedaddress); + SMWRITE2(); + } + break; + case 0x16: + nextop = F8; + GETVYx(v1, 0); + if (MODREG) { + INST_NAME("VMOVLHPS Gx, Vx, Ex"); + GETEYx(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(1, 0)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(0, 0)); + } else { + INST_NAME("VMOVHPS Gx, Vx, Ex"); + GETEYSD(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(1, 0)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(0, 0)); + } + break; + case 0x17: + nextop = F8; + INST_NAME("VMOVHPS Ex, Gx"); + GETGYx(v0, 0); + if (MODREG) { + DEFAULT; + return addr; + } else { + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 1, 0); + VSTELM_D(v0, ed, fixedaddress, 1); + SMWRITE2(); + } case 0x28: INST_NAME("VMOVAPS Gx, Ex"); nextop = F8; diff --git a/src/dynarec/la64/dynarec_la64_avx_66_0f.c b/src/dynarec/la64/dynarec_la64_avx_66_0f.c index 95004d73..852c145b 100644 --- a/src/dynarec/la64/dynarec_la64_avx_66_0f.c +++ b/src/dynarec/la64/dynarec_la64_avx_66_0f.c @@ -99,6 +99,60 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, SMWRITE2(); } break; + case 0x12: + INST_NAME("VMOVLPD Gx, Vx, Eq"); + nextop = F8; + if (MODREG) { + // access register instead of memory is bad opcode! + DEFAULT; + return addr; + } + GETVYx(v1, 0); + GETEYSD(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(0, 0)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(1, 1)); + break; + case 0x13: + INST_NAME("VMOVLPD Eq, Gx"); + nextop = F8; + if (MODREG) { + // access register instead of memory is bad opcode! + DEFAULT; + return addr; + } + GETGYx(v0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 1, 0); + FST_D(v0, ed, fixedaddress); + SMWRITE2(); + break; + case 0x16: + INST_NAME("VMOVHPD Gx, Vx, Eq"); + nextop = F8; + if (MODREG) { + // access register instead of memory is bad opcode! + DEFAULT; + return addr; + } + GETVYx(v1, 0); + GETEYSD(v2, 0, 0); + GETGYx_empty(v0); + VEXTRINS_D(v0, v2, VEXTRINS_IMM_4_0(1, 0)); + VEXTRINS_D(v0, v1, VEXTRINS_IMM_4_0(0, 0)); + break; + case 0x17: + INST_NAME("VMOVHPD Eq, Gx"); + nextop = F8; + if (MODREG) { + // access register instead of memory is bad opcode! + DEFAULT; + return addr; + } + GETGYx(v0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x5, &fixedaddress, rex, NULL, 1, 0); + FST_D(v0, ed, fixedaddress); + SMWRITE2(); + break; case 0x28: INST_NAME("VMOVAPD Gx, Ex"); nextop = F8; -- cgit 1.4.1