From cb2a623faa78b02b93b402f665030f6b75cdf0a9 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Mon, 30 Oct 2023 16:38:15 +0100 Subject: Added full SSE 4.2 support --- src/emu/x64compstrings.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/emu/x64compstrings.c (limited to 'src/emu/x64compstrings.c') diff --git a/src/emu/x64compstrings.c b/src/emu/x64compstrings.c new file mode 100644 index 00000000..72781ebb --- /dev/null +++ b/src/emu/x64compstrings.c @@ -0,0 +1,120 @@ +#include + +#include "box64stack.h" +#include "x64emu.h" +#include "x64run_private.h" +#include "x64emu_private.h" +#include "x64compstrings.h" + +static int overrideIfDataInvalid(sse_regs_t* mem, int lmem, sse_regs_t* reg, int lreg, int j, int i, int imm8) +{ + int valid1 = (i>2)&3) { + case 0b00: + case 0b01: return 0; + case 0b10: + case 0b11: return 1; + } + if(!valid1 && valid2) + switch((imm8>>2)&3) { + case 0b00: + case 0b01: + case 0b10: return 0; + case 0b11: return 1; + } + if(valid1 && !valid2) + return 0; + switch((imm8>>2)&3) { + case 0b01: // range + switch (imm8&3) { + case 0b00: // ub + return (i&1)?((reg->ub[i]>=mem->ub[j])):((reg->ub[i]<=mem->ub[j])); + case 0b01: // uw + return (i&1)?((reg->uw[i]>=mem->uw[j])):((reg->uw[i]<=mem->uw[j])); + case 0b10: // sb + return (i&1)?((reg->sb[i]>=mem->sb[j])):((reg->sb[i]<=mem->sb[j])); + case 0b11: // sw + return (i&1)?((reg->sw[i]>=mem->sw[j])):((reg->sw[i]<=mem->sw[j])); + } + break; + default: // the others + switch (imm8&1) { + case 0: // byte + return (reg->ub[i] == mem->ub[j]); + case 1: // word + return (reg->uw[i] == mem->uw[j]); + } + } +} + +uint32_t sse42_compare_string_explicit_len(x64emu_t* emu, sse_regs_t* mem, int lmem, sse_regs_t* reg, int lreg, uint8_t imm8) +{ + // get number of packed byte/word + int n_packed = (imm8&1)?8:16; + if(lreg<0) lreg = -lreg; + if(lmem<0) lmem = -lmem; + if(lreg>n_packed) lreg = n_packed; + if(lmem>n_packed) lmem = n_packed; + // aggregate to intres1 + uint32_t intres1 = 0; + switch((imm8>>2)&3) { + case 0b00: //Equal any + for(int j=0; j>4)&3) { + case 0b01: intres2 ^= ((1<uw[lmem]) ++lmem; + while(lreg<8 && reg->uw[lreg]) ++lreg; + } else { + while(lmem<16 && mem->ub[lmem]) ++lmem; + while(lreg<16 && reg->ub[lreg]) ++lreg; + } + return sse42_compare_string_explicit_len(emu, mem, lmem, reg, lreg, imm8); +} \ No newline at end of file -- cgit 1.4.1