From c0f4bcb5d4bef655a04a3a1ea4db4ac0bcdb8e40 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 15 Jan 2025 03:29:58 +1100 Subject: cpu/drcbe*.cpp: Added write byte with explicit mask. This wasn't added to the DRC implementations when it was added to the address space classes. --- src/devices/cpu/drcbearm64.cpp | 34 ++++++++++++++++++++++++++++++++-- src/devices/cpu/drcbearm64.h | 2 ++ src/devices/cpu/drcbec.cpp | 8 ++++++++ src/devices/cpu/drcbex64.cpp | 40 ++++++++++++++++++++++++++++++++++------ src/devices/cpu/drcbex64.h | 3 ++- src/devices/cpu/drcbex86.cpp | 11 +++++++++-- 6 files changed, 87 insertions(+), 11 deletions(-) diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp index 29702390bcf..b9851e3bf70 100644 --- a/src/devices/cpu/drcbearm64.cpp +++ b/src/devices/cpu/drcbearm64.cpp @@ -922,6 +922,7 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach if (m_space[space]) { resolve_accessor(m_resolved_accessors[space].read_byte, *m_space[space], static_cast(&address_space::read_byte)); + resolve_accessor(m_resolved_accessors[space].read_byte_masked, *m_space[space], static_cast(&address_space::read_byte)); resolve_accessor(m_resolved_accessors[space].read_word, *m_space[space], static_cast(&address_space::read_word)); resolve_accessor(m_resolved_accessors[space].read_word_masked, *m_space[space], static_cast(&address_space::read_word)); resolve_accessor(m_resolved_accessors[space].read_dword, *m_space[space], static_cast(&address_space::read_dword)); @@ -930,6 +931,7 @@ drcbe_arm64::drcbe_arm64(drcuml_state &drcuml, device_t &device, drc_cache &cach resolve_accessor(m_resolved_accessors[space].read_qword_masked, *m_space[space], static_cast(&address_space::read_qword)); resolve_accessor(m_resolved_accessors[space].write_byte, *m_space[space], static_cast(&address_space::write_byte)); + resolve_accessor(m_resolved_accessors[space].write_byte_masked, *m_space[space], static_cast(&address_space::write_byte)); resolve_accessor(m_resolved_accessors[space].write_word, *m_space[space], static_cast(&address_space::write_word)); resolve_accessor(m_resolved_accessors[space].write_word_masked, *m_space[space], static_cast(&address_space::write_word)); resolve_accessor(m_resolved_accessors[space].write_dword, *m_space[space], static_cast(&address_space::write_dword)); @@ -2081,7 +2083,21 @@ void drcbe_arm64::op_readm(a64::Assembler &a, const uml::instruction &inst) mov_reg_param(a, 4, REG_PARAM2, addrp); mov_reg_param(a, inst.size(), REG_PARAM3, maskp); - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + { + if (resolved.read_byte_masked.func) + { + get_imm_relative(a, REG_PARAM1, resolved.read_byte_masked.obj); + call_arm_addr(a, resolved.read_byte_masked.func); + } + else + { + get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]); + emit_ldr_mem(a, TEMP_REG1, &trampolines.read_byte_masked); + a.blr(TEMP_REG1); + } + } + else if (spacesizep.size() == SIZE_WORD) { if (resolved.read_word_masked.func) { @@ -2222,7 +2238,21 @@ void drcbe_arm64::op_writem(a64::Assembler &a, const uml::instruction &inst) mov_reg_param(a, inst.size(), REG_PARAM3, srcp); mov_reg_param(a, inst.size(), REG_PARAM4, maskp); - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + { + if (resolved.write_byte_masked.func) + { + get_imm_relative(a, REG_PARAM1, resolved.write_byte_masked.obj); + call_arm_addr(a, resolved.write_byte_masked.func); + } + else + { + get_imm_relative(a, REG_PARAM1, (uintptr_t)m_space[spacesizep.space()]); + emit_ldr_mem(a, TEMP_REG1, &trampolines.write_byte_masked); + a.blr(TEMP_REG1); + } + } + else if (spacesizep.size() == SIZE_WORD) { if (resolved.write_word_masked.func) { diff --git a/src/devices/cpu/drcbearm64.h b/src/devices/cpu/drcbearm64.h index 4cbbaa7cf26..20938f214fe 100644 --- a/src/devices/cpu/drcbearm64.h +++ b/src/devices/cpu/drcbearm64.h @@ -259,6 +259,7 @@ private: { resolved_handler read_byte; + resolved_handler read_byte_masked; resolved_handler read_word; resolved_handler read_word_masked; resolved_handler read_dword; @@ -267,6 +268,7 @@ private: resolved_handler read_qword_masked; resolved_handler write_byte; + resolved_handler write_byte_masked; resolved_handler write_word; resolved_handler write_word_masked; resolved_handler write_dword; diff --git a/src/devices/cpu/drcbec.cpp b/src/devices/cpu/drcbec.cpp index 82cfc10979a..c058d256a18 100644 --- a/src/devices/cpu/drcbec.cpp +++ b/src/devices/cpu/drcbec.cpp @@ -871,6 +871,10 @@ int drcbe_c::execute(code_handle &entry) PARAM0 = m_space[PARAM2]->read_dword(PARAM1); break; + case MAKE_OPCODE_SHORT(OP_READM1, 4, 0): // READM dst,src1,mask,space_BYTE + PARAM0 = m_space[PARAM3]->read_byte(PARAM1, PARAM2); + break; + case MAKE_OPCODE_SHORT(OP_READM2, 4, 0): // READM dst,src1,mask,space_WORD PARAM0 = m_space[PARAM3]->read_word(PARAM1, PARAM2); break; @@ -891,6 +895,10 @@ int drcbe_c::execute(code_handle &entry) m_space[PARAM2]->write_dword(PARAM0, PARAM1); break; + case MAKE_OPCODE_SHORT(OP_WRITEM1, 4, 0): // WRITEM dst,src1,mask,space_BYTE + m_space[PARAM3]->write_byte(PARAM0, PARAM1, PARAM2); + break; + case MAKE_OPCODE_SHORT(OP_WRITEM2, 4, 0): // WRITEM dst,src1,mask,space_WORD m_space[PARAM3]->write_word(PARAM0, PARAM1, PARAM2); break; diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index 880ad231868..14f89a35cbd 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -706,6 +706,7 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u if (m_space[space]) { resolve_accessor(m_resolved_accessors[space].read_byte, *m_space[space], static_cast(&address_space::read_byte)); + resolve_accessor(m_resolved_accessors[space].read_byte_masked, *m_space[space], static_cast(&address_space::read_byte)); resolve_accessor(m_resolved_accessors[space].read_word, *m_space[space], static_cast(&address_space::read_word)); resolve_accessor(m_resolved_accessors[space].read_word_masked, *m_space[space], static_cast(&address_space::read_word)); resolve_accessor(m_resolved_accessors[space].read_dword, *m_space[space], static_cast(&address_space::read_dword)); @@ -714,6 +715,7 @@ drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, u resolve_accessor(m_resolved_accessors[space].read_qword_masked, *m_space[space], static_cast(&address_space::read_qword)); resolve_accessor(m_resolved_accessors[space].write_byte, *m_space[space], static_cast(&address_space::write_byte)); + resolve_accessor(m_resolved_accessors[space].write_byte_masked, *m_space[space], static_cast(&address_space::write_byte)); resolve_accessor(m_resolved_accessors[space].write_word, *m_space[space], static_cast(&address_space::write_word)); resolve_accessor(m_resolved_accessors[space].write_word_masked, *m_space[space], static_cast(&address_space::write_word)); resolve_accessor(m_resolved_accessors[space].write_dword, *m_space[space], static_cast(&address_space::write_dword)); @@ -838,7 +840,6 @@ void drcbe_x64::reset() a.emitArgsAssignment(frame, args); a.sub(rsp, 40); - a.mov(MABS(&m_near.hashstacksave), rsp); a.mov(MABS(&m_near.stacksave), rsp); a.stmxcsr(MABS(&m_near.ssemode)); a.jmp(Gpq(REG_PARAM2)); @@ -847,7 +848,7 @@ void drcbe_x64::reset() m_exit = dst + a.offset(); a.bind(a.newNamedLabel("exit_point")); a.ldmxcsr(MABS(&m_near.ssemode)); - a.mov(rsp, MABS(&m_near.hashstacksave)); + a.mov(rsp, MABS(&m_near.stacksave)); a.add(rsp, 40); a.emitEpilog(frame); @@ -1613,7 +1614,7 @@ void drcbe_x64::op_hashjmp(Assembler &a, const instruction &inst) // load the stack base Label nocode = a.newLabel(); - a.mov(rsp, MABS(&m_near.hashstacksave)); // mov rsp,[hashstacksave] + a.mov(rsp, MABS(&m_near.stacksave)); // mov rsp,[stacksave] // fixed mode cases if (modep.is_immediate() && m_hash.is_mode_populated(modep.immediate())) @@ -2616,12 +2617,26 @@ void drcbe_x64::op_readm(Assembler &a, const instruction &inst) mov_reg_param(a, Gpd(REG_PARAM3), maskp); // mov param3,maskp else mov_reg_param(a, Gpq(REG_PARAM3), maskp); // mov param3,maskp - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + { + if (resolved.read_byte_masked.func) + { + mov_r64_imm(a, Gpq(REG_PARAM1), resolved.read_byte_masked.obj); // mov param1,space + smart_call_r64(a, resolved.read_byte_masked.func, rax); // call read_byte_masked + } + else + { + mov_r64_imm(a, Gpq(REG_PARAM1), (uintptr_t)m_space[spacesizep.space()]); // mov param1,space + smart_call_m64(a, (x86code **)&trampolines.read_byte_masked); // call read_byte_masked + } + a.movzx(dstreg, al); // movzx dstreg,al + } + else if (spacesizep.size() == SIZE_WORD) { if (resolved.read_word_masked.func) { mov_r64_imm(a, Gpq(REG_PARAM1), resolved.read_word_masked.obj); // mov param1,space - smart_call_r64(a, resolved.read_word_masked.func, rax); // call read_byte_masked + smart_call_r64(a, resolved.read_word_masked.func, rax); // call read_word_masked } else { @@ -2781,7 +2796,20 @@ void drcbe_x64::op_writem(Assembler &a, const instruction &inst) mov_reg_param(a, Gpq(REG_PARAM3), srcp); // mov param3,srcp mov_reg_param(a, Gpq(REG_PARAM4), maskp); // mov param4,maskp } - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + { + if (resolved.write_byte.func) + { + mov_r64_imm(a, Gpq(REG_PARAM1), resolved.write_byte_masked.obj); // mov param1,space + smart_call_r64(a, resolved.write_byte_masked.func, rax); // call write_byte_masked + } + else + { + mov_r64_imm(a, Gpq(REG_PARAM1), (uintptr_t)m_space[spacesizep.space()]); // mov param1,space + smart_call_m64(a, (x86code **)&trampolines.write_byte_masked); // call write_byte_masked + } + } + else if (spacesizep.size() == SIZE_WORD) { if (resolved.write_word.func) { diff --git a/src/devices/cpu/drcbex64.h b/src/devices/cpu/drcbex64.h index 826b56d8b32..b2c9195bd9e 100644 --- a/src/devices/cpu/drcbex64.h +++ b/src/devices/cpu/drcbex64.h @@ -263,7 +263,6 @@ private: double double1; // 1.0 in double-precision void * stacksave; // saved stack pointer - void * hashstacksave; // saved stack pointer for hashjmp uint8_t flagsmap[0x1000]; // flags map uint64_t flagsunmap[0x20]; // flags unmapper @@ -276,6 +275,7 @@ private: { resolved_handler read_byte; + resolved_handler read_byte_masked; resolved_handler read_word; resolved_handler read_word_masked; resolved_handler read_dword; @@ -284,6 +284,7 @@ private: resolved_handler read_qword_masked; resolved_handler write_byte; + resolved_handler write_byte_masked; resolved_handler write_word; resolved_handler write_word_masked; resolved_handler write_dword; diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp index 6d7c6c1de1d..6be6ab0af41 100644 --- a/src/devices/cpu/drcbex86.cpp +++ b/src/devices/cpu/drcbex86.cpp @@ -3527,7 +3527,12 @@ void drcbe_x86::op_readm(Assembler &a, const instruction &inst) emit_mov_m64_p64(a, qword_ptr(esp, 8), maskp); // mov [esp+8],maskp emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + { + a.call(imm(m_accessors[spacesizep.space()].read_byte_masked)); // call read_byte_masked + a.movzx(dstreg, al); // movzx dstreg,al + } + else if (spacesizep.size() == SIZE_WORD) { a.call(imm(m_accessors[spacesizep.space()].read_word_masked)); // call read_word_masked a.movzx(dstreg, ax); // movzx dstreg,ax @@ -3636,7 +3641,9 @@ void drcbe_x86::op_writem(Assembler &a, const instruction &inst) } emit_mov_m32_p32(a, dword_ptr(esp, 4), addrp); // mov [esp+4],addrp a.mov(dword_ptr(esp, 0), imm(m_space[spacesizep.space()])); // mov [esp],space - if (spacesizep.size() == SIZE_WORD) + if (spacesizep.size() == SIZE_BYTE) + a.call(imm(m_accessors[spacesizep.space()].write_byte_masked)); // call write_byte_masked + else if (spacesizep.size() == SIZE_WORD) a.call(imm(m_accessors[spacesizep.space()].write_word_masked)); // call write_word_masked else if (spacesizep.size() == SIZE_DWORD) a.call(imm(m_accessors[spacesizep.space()].write_dword_masked)); // call write_dword_masked -- cgit v1.2.3