From e4588d1f454e283d7df8c60be42641570928571f Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Fri, 11 Feb 2022 17:23:00 +0700 Subject: asmjit: mame integration --- 3rdparty/asmjit/src/asmjit/core/api-config.h | 2 + COPYING | 2 +- scripts/src/3rdparty.lua | 69 ++++++++---- src/devices/cpu/drcbex64.cpp | 158 ++++++++++++++------------- src/devices/cpu/drcbex64.h | 5 +- src/devices/cpu/drcbex86.cpp | 64 +++++------ src/devices/cpu/drcbex86.h | 2 +- 7 files changed, 171 insertions(+), 131 deletions(-) diff --git a/3rdparty/asmjit/src/asmjit/core/api-config.h b/3rdparty/asmjit/src/asmjit/core/api-config.h index a0fb979eb33..6bd5beecc0a 100644 --- a/3rdparty/asmjit/src/asmjit/core/api-config.h +++ b/3rdparty/asmjit/src/asmjit/core/api-config.h @@ -52,6 +52,8 @@ // Build Options // ============= +#define ASMJIT_STATIC + // NOTE: Doxygen cannot document macros that are not defined, that's why we have to define them and then undefine // them immediately, so it won't use the macros with its own preprocessor. #ifdef _DOXYGEN diff --git a/COPYING b/COPYING index aa77b5f2959..b1ee893acbf 100644 --- a/COPYING +++ b/COPYING @@ -238,7 +238,7 @@ can include it to GNU GPL or GNU LGPL code. AsmJit - a lightweight library for machine code generation. -Copyright (c) 2008-2020 The AsmJit Authors +Copyright (c) 2008-2021 The AsmJit Authors Nano SVG - Simple stupid SVG parser Copyright (c) 2013-14 Mikko Mononen memon@inside.org diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua index 899a78eba2f..6060edb068a 100644 --- a/scripts/src/3rdparty.lua +++ b/scripts/src/3rdparty.lua @@ -2215,11 +2215,6 @@ project "asmjit" uuid "4539757c-6e99-4bae-b3d0-b342a7c49539" kind "StaticLib" - configuration { "gmake" } - buildoptions { - "-Wno-unused-but-set-variable", - } - configuration { } if _OPTIONS["targetos"]=="macosx" and _OPTIONS["gcc"]~=nil then @@ -2231,30 +2226,65 @@ project "asmjit" end files { + MAME_DIR .. "3rdparty/asmjit/src/asmjit/a64.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/asmjit-scope-begin.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/asmjit-scope-end.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/asmjit.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64archtraits_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64assembler.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64assembler.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64builder.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64builder.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64compiler.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64compiler.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64emithelper.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64emithelper_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64emitter.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64formatter.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64formatter_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64func.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64func_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64globals.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64instapi.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64instapi_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64instdb.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64instdb.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64instdb_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64operand.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64operand.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64rapass.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64rapass_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/a64utils.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/armformatter.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/armformatter_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/armglobals.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/arm/armoperand.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/api-build_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/api-config.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/arch.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/arch.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/archcommons.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/archtraits.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/archtraits.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/assembler.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/assembler.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/builder.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/builder.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/callconv.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/callconv.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codebuffer.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codebufferwriter_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codeholder.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codeholder.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codewriter.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/codewriter_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/compiler.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/compiler.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/compilerdefs.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/constpool.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/constpool.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/cpuinfo.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/cpuinfo.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/datatypes.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/emithelper.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/emithelper_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/emitter.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/emitter.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/emitterutils.cpp", @@ -2263,11 +2293,13 @@ project "asmjit" MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/environment.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/errorhandler.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/errorhandler.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/features.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/formatter.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/formatter.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/formatter_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/func.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/func.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/funcargscontext.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/funcargscontext_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/globals.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/globals.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/inst.cpp", @@ -2316,29 +2348,26 @@ project "asmjit" MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/zonetree.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/zonevector.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/core/zonevector.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86archdata.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86archdata_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86archtraits_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86assembler.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86assembler.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86builder.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86builder.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86callconv.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86callconv_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86compiler.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86compiler.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86emithelper.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86emithelper_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86emitter.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86features.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86features.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86formatter.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86formatter_p.h", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86func.cpp", + MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86func_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86globals.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86instapi.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86instapi_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86instdb.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86instdb.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86instdb_p.h", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86internal.cpp", - MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86internal_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86opcode_p.h", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86operand.cpp", MAME_DIR .. "3rdparty/asmjit/src/asmjit/x86/x86operand.h", diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp index d48e43d80b7..22c523dc550 100644 --- a/src/devices/cpu/drcbex64.cpp +++ b/src/devices/cpu/drcbex64.cpp @@ -236,7 +236,7 @@ const Gp::Id REG_PARAM4 = Gp::kIdCx; //************************************************************************** #define X86_CONDITION(condition) (condition_map[condition - uml::COND_Z]) -#define X86_NOT_CONDITION(condition) (condition_map[condition - uml::COND_Z] ^ 1) +#define X86_NOT_CONDITION(condition) negateCond(condition_map[condition - uml::COND_Z]) #define assert_no_condition(inst) assert((inst).condition() == uml::COND_ALWAYS) #define assert_any_condition(inst) assert((inst).condition() == uml::COND_ALWAYS || ((inst).condition() >= uml::COND_Z && (inst).condition() < uml::COND_MAX)) @@ -276,24 +276,24 @@ static uint32_t float_register_map[REG_F_COUNT] = }; // condition mapping table -static const Condition::Code condition_map[uml::COND_MAX - uml::COND_Z] = +static const CondCode condition_map[uml::COND_MAX - uml::COND_Z] = { - Condition::Code::kZ, // COND_Z = 0x80, requires Z - Condition::Code::kNZ, // COND_NZ, requires Z - Condition::Code::kS, // COND_S, requires S - Condition::Code::kNS, // COND_NS, requires S - Condition::Code::kC, // COND_C, requires C - Condition::Code::kNC, // COND_NC, requires C - Condition::Code::kO, // COND_V, requires V - Condition::Code::kNO, // COND_NV, requires V - Condition::Code::kP, // COND_U, requires U - Condition::Code::kNP, // COND_NU, requires U - Condition::Code::kA, // COND_A, requires CZ - Condition::Code::kBE, // COND_BE, requires CZ - Condition::Code::kG, // COND_G, requires SVZ - Condition::Code::kLE, // COND_LE, requires SVZ - Condition::Code::kL, // COND_L, requires SV - Condition::Code::kGE, // COND_GE, requires SV + CondCode::kZ, // COND_Z = 0x80, requires Z + CondCode::kNZ, // COND_NZ, requires Z + CondCode::kS, // COND_S, requires S + CondCode::kNS, // COND_NS, requires S + CondCode::kC, // COND_C, requires C + CondCode::kNC, // COND_NC, requires C + CondCode::kO, // COND_V, requires V + CondCode::kNO, // COND_NV, requires V + CondCode::kP, // COND_U, requires U + CondCode::kNP, // COND_NU, requires U + CondCode::kA, // COND_A, requires CZ + CondCode::kBE, // COND_BE, requires CZ + CondCode::kG, // COND_G, requires SVZ + CondCode::kLE, // COND_LE, requires SVZ + CondCode::kL, // COND_L, requires SV + CondCode::kGE, // COND_GE, requires SV }; #if 0 @@ -490,20 +490,26 @@ inline Xmm drcbe_x64::be_parameter::select_register(Xmm defreg) const return defreg; } -template T drcbe_x64::be_parameter::select_register(T defreg, be_parameter const &checkparam) const +Gp drcbe_x64::be_parameter::select_register(Gp defreg, be_parameter const &checkparam) const { if (*this == checkparam) return defreg; return select_register(defreg); } -template T drcbe_x64::be_parameter::select_register(T defreg, be_parameter const &checkparam, be_parameter const &checkparam2) const +Gp drcbe_x64::be_parameter::select_register(Gp defreg, be_parameter const &checkparam, be_parameter const &checkparam2) const { if (*this == checkparam || *this == checkparam2) return defreg; return select_register(defreg); } +Xmm drcbe_x64::be_parameter::select_register(Xmm defreg, be_parameter const &checkparam) const +{ + if (*this == checkparam) + return defreg; + return select_register(defreg); +} //------------------------------------------------- // select_register - select a register to use, @@ -819,7 +825,7 @@ size_t drcbe_x64::emit(CodeHolder &ch) if (cachetop == nullptr) return 0; - err = ch.copyFlattenedData(drccodeptr(ch.baseAddress()), code_size, CodeHolder::kCopyWithPadding); + err = ch.copyFlattenedData(drccodeptr(ch.baseAddress()), code_size, CopySectionFlags::kPadTargetBuffer); if (err) throw emu_fatalerror("asmjit::CodeHolder::copyFlattenedData() error %d", err); @@ -844,26 +850,26 @@ void drcbe_x64::reset() x86code *dst = (x86code *)m_cache.top(); CodeHolder ch; - ch.init(hostEnvironment(), uint64_t(dst)); + ch.init(Environment::host(), uint64_t(dst)); FileLogger logger(m_log_asmjit); if (logger.file()) { - logger.setFlags(FormatOptions::Flags::kFlagHexOffsets | FormatOptions::Flags::kFlagHexImms | FormatOptions::Flags::kFlagMachineCode); - logger.setIndentation(FormatOptions::IndentationType::kIndentationCode, 4); + logger.setFlags(FormatFlags::kHexOffsets | FormatFlags::kHexImms | FormatFlags::kMachineCode); + logger.setIndentation(FormatIndentationGroup::kCode, 4); ch.setLogger(&logger); } Assembler a(&ch); if (logger.file()) - a.addValidationOptions(BaseEmitter::kValidationOptionIntermediate); + a.addDiagnosticOptions(DiagnosticOptions::kValidateIntermediate); // generate an entry point m_entry = (x86_entry_point_func)dst; a.bind(a.newNamedLabel("entry_point")); FuncDetail entry_point; - entry_point.init(FuncSignatureT(CallConv::kIdHost), hostEnvironment()); + entry_point.init(FuncSignatureT(CallConvId::kHost), Environment::host()); FuncFrame frame; frame.init(entry_point); @@ -939,21 +945,21 @@ void drcbe_x64::generate(drcuml_block &block, const instruction *instlist, uint3 x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63); CodeHolder ch; - ch.init(hostEnvironment(), uint64_t(dst)); + ch.init(Environment::host(), uint64_t(dst)); ThrowableErrorHandler e; ch.setErrorHandler(&e); FileLogger logger(m_log_asmjit); if (logger.file()) { - logger.setFlags(FormatOptions::Flags::kFlagHexOffsets | FormatOptions::Flags::kFlagHexImms | FormatOptions::Flags::kFlagMachineCode); - logger.setIndentation(FormatOptions::IndentationType::kIndentationCode, 4); + logger.setFlags(FormatFlags::kHexOffsets | FormatFlags::kHexImms | FormatFlags::kMachineCode); + logger.setIndentation(FormatIndentationGroup::kCode, 4); ch.setLogger(&logger); } Assembler a(&ch); if (logger.file()) - a.addValidationOptions(BaseEmitter::kValidationOptionIntermediate); + a.addDiagnosticOptions(DiagnosticOptions::kValidateIntermediate); // generate code std::string blockname; @@ -1031,7 +1037,6 @@ void drcbe_x64::get_info(drcbe_info &info) void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const &dst, be_parameter const ¶m, std::function optimize) { bool const is64 = dst.size() == 8; - u32 const rs = is64 ? Gpq::kSignature : Gpd::kSignature; if (param.is_immediate()) { @@ -1052,10 +1057,10 @@ void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const if (dst.isMem()) { // use temporary register for memory,memory - Gp const reg = param.select_register(is64 ? rax : eax); + Gp const tmp = is64 ? param.select_register(rax) : param.select_register(eax); - a.mov(reg, MABS(param.memory())); // mov reg,param - a.emit(opcode, dst, reg); // op [dst],reg + a.mov(tmp, MABS(param.memory())); // mov tmp,param + a.emit(opcode, dst, tmp); // op [dst],tmp } else if (opcode != Inst::kIdTest) // most instructions are register,memory @@ -1066,7 +1071,7 @@ void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const } else if (param.is_int_register()) { - Gp const src = Gp(rs, param.ireg()); + Gp const src = Gp::fromTypeAndId(is64 ? RegType::kX86_Gpq : RegType::kX86_Gpd, param.ireg()); a.emit(opcode, dst, src); // op dst,param } @@ -1119,30 +1124,27 @@ void drcbe_x64::mov_param_reg(Assembler &a, be_parameter const ¶m, Gp const void drcbe_x64::mov_mem_param(Assembler &a, Mem const &mem, be_parameter const ¶m) { bool const is64 = mem.size() == 8; - u32 const rs = is64 ? Gpq::kSignature : Gpd::kSignature; if (param.is_immediate()) { if (is64 && !short_immediate(param.immediate())) { - Gp const tmp = Gp(rs, Gp::kIdAx); - - a.mov(tmp, param.immediate()); // mov tmp,param - a.mov(mem, tmp); // mov [mem],tmp + a.mov(rax, param.immediate()); // mov tmp,param + a.mov(mem, rax); // mov [mem],tmp } else a.mov(mem, param.immediate()); // mov [mem],param } else if (param.is_memory()) { - Gp const tmp = Gp(rs, Gp::kIdAx); + Gp const tmp = Gp::fromTypeAndId(is64 ? RegType::kX86_Gpq : RegType::kX86_Gpd, Gp::kIdAx); a.mov(tmp, MABS(param.memory())); // mov tmp,[param] a.mov(mem, tmp); // mov [mem],tmp } else if (param.is_int_register()) { - Gp const src = Gp(rs, param.ireg()); + Gp const src = Gp::fromTypeAndId(is64 ? RegType::kX86_Gpq : RegType::kX86_Gpd, param.ireg()); a.mov(mem, src); // mov [mem],param } @@ -2149,7 +2151,7 @@ void drcbe_x64::op_loads(Assembler &a, const instruction &inst) Gp basereg = get_base_register_and_offset(a, basep.memory(), rdx, baseoffs); // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax); // immediate index if (indp.is_immediate()) @@ -2640,7 +2642,7 @@ void drcbe_x64::op_carry(Assembler &a, const instruction &inst) be_parameter srcp(*this, inst.param(0), PTYPE_MRI); be_parameter bitp(*this, inst.param(1), PTYPE_MRI); - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; + Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg()); // degenerate case: source is immediate if (srcp.is_immediate() && bitp.is_immediate()) @@ -2663,14 +2665,14 @@ void drcbe_x64::op_carry(Assembler &a, const instruction &inst) if (srcp.is_memory()) a.bt(MABS(srcp.memory(), inst.size()), bitp.immediate()); // bt [srcp],bitp else if (srcp.is_int_register()) - a.bt(Gp(rs, srcp.ireg()), bitp.immediate()); // bt srcp,bitp + a.bt(src, bitp.immediate()); // bt srcp,bitp } else { if (srcp.is_memory()) a.bt(MABS(srcp.memory(), inst.size()), ecx); // bt [srcp],ecx else if (srcp.is_int_register()) - a.bt(Gp(rs, srcp.ireg()), ecx); // bt srcp,ecx + a.bt(src, ecx); // bt srcp,ecx } } @@ -2690,7 +2692,7 @@ void drcbe_x64::op_set(Assembler &a, const instruction &inst) be_parameter dstp(*this, inst.param(0), PTYPE_MR); // pick a target register for the general case - Gp dstreg = dstp.select_register(inst.size() == 4 ? eax : rax); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax); // set to AL a.set(X86_CONDITION(inst.condition()), al); // setcc al @@ -2714,8 +2716,6 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst) be_parameter dstp(*this, inst.param(0), PTYPE_MR); be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; - // add a conditional branch unless a conditional move is possible Label skip = a.newLabel(); if (inst.condition() != uml::COND_ALWAYS && !(dstp.is_int_register() && !srcp.is_immediate())) @@ -2723,8 +2723,11 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst) // register to memory if (dstp.is_memory() && srcp.is_int_register()) - a.mov(MABS(dstp.memory()), Gp(rs, srcp.ireg())); // mov [dstp],srcp + { + Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg()); + a.mov(MABS(dstp.memory()), src); // mov [dstp],srcp + } // immediate to memory else if (dstp.is_memory() && srcp.is_immediate() && short_immediate(srcp.immediate())) a.mov(MABS(dstp.memory(), inst.size()), s32(srcp.immediate())); // mov [dstp],srcp @@ -2732,19 +2735,22 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst) // conditional memory to register else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_memory()) { - a.cmov(X86_CONDITION(inst.condition()), Gp(rs, dstp.ireg()), MABS(srcp.memory())); // cmovcc dstp,[srcp] + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); + a.cmov(X86_CONDITION(inst.condition()), dst, MABS(srcp.memory())); // cmovcc dstp,[srcp] } // conditional register to register else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_int_register()) { - a.cmov(X86_CONDITION(inst.condition()), Gp(rs, dstp.ireg()), Gp(rs, srcp.ireg())); // cmovcc dstp,srcp + Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg()); + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); + a.cmov(X86_CONDITION(inst.condition()), dst, src); // cmovcc dstp,srcp } // general case else { - Gp dstreg = dstp.select_register(inst.size() == 4 ? eax : rax); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax); mov_reg_param(a, dstreg, srcp, true); // mov dstreg,srcp mov_param_reg(a, dstp, dstreg); // mov dstp,dstreg @@ -2854,7 +2860,7 @@ void drcbe_x64::op_roland(Assembler &a, const instruction &inst) be_parameter maskp(*this, inst.param(3), PTYPE_MRI); // pick a target register - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, shiftp, maskp); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, shiftp, maskp) : dstp.select_register(rax, shiftp, maskp); mov_reg_param(a, dstreg, srcp); // mov dstreg,srcp if (!shiftp.is_immediate_value(0)) @@ -2978,24 +2984,27 @@ void drcbe_x64::op_add(Assembler &a, const instruction &inst) // reg = reg + imm else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && short_immediate(src2p.immediate()) && !inst.flags()) { - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); + Gp const src1 = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, src1p.ireg()); - a.lea(Gp(rs, dstp.ireg()), ptr(Gp(rs, src1p.ireg()), src2p.immediate())); // lea dstp,[src1p+src2p] + a.lea(dst, ptr(src1, src2p.immediate())); // lea dstp,[src1p+src2p] } // reg = reg + reg else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_int_register() && !inst.flags()) { - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); + Gp const src1 = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, src1p.ireg()); + Gp const src2 = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, src2p.ireg()); - a.lea(Gp(rs, dstp.ireg()), ptr(Gp(rs, src1p.ireg()), Gp(rs, src2p.ireg()))); // lea dstp,[src1p+src2p] + a.lea(dst, ptr(src1, src2)); // lea dstp,[src1p+src2p] } // general case else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdAdd, dstreg, src2p, // add dstreg,src2p @@ -3034,7 +3043,7 @@ void drcbe_x64::op_addc(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p, true); // mov dstreg,src1p alu_op_param(a, Inst::kIdAdc, dstreg, src2p); // adc dstreg,src2p @@ -3071,9 +3080,8 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst) // reg = reg - imm else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && short_immediate(src2p.immediate()) && !inst.flags()) { - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; - Gp const dst = Gp(rs, dstp.ireg()); - Gp const src1 = Gp(rs, src1p.ireg()); + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); + Gp const src1 = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, src1p.ireg()); a.lea(dst, ptr(src1, -src2p.immediate())); // lea dstp,[src1p-src2p] } @@ -3082,7 +3090,7 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdSub, dstreg, src2p, // sub dstreg,src2p @@ -3120,7 +3128,7 @@ void drcbe_x64::op_subc(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p, true); // mov dstreg,src1p alu_op_param(a, Inst::kIdSbb, dstreg, src2p); // sbb dstreg,src2p @@ -3152,7 +3160,7 @@ void drcbe_x64::op_cmp(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp src1reg = src1p.select_register((inst.size() == 4) ? eax : rax); + Gp src1reg = (inst.size() == 4) ? src1p.select_register(eax) : src1p.select_register(rax); if (src1p.is_immediate()) { @@ -3634,7 +3642,7 @@ void drcbe_x64::op_and(Assembler &a, const instruction &inst) normalize_commutative(src1p, src2p); // pick a target register - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); // dstp == src1p in memory if (dstp.is_memory() && dstp == src1p) @@ -3749,7 +3757,7 @@ void drcbe_x64::op_test(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp src1reg = src1p.select_register((inst.size() == 4) ? eax : rax); + Gp src1reg = (inst.size() == 4) ? src1p.select_register(eax) : src1p.select_register(rax); mov_reg_param(a, src1reg, src1p); // mov src1reg,src1p alu_op_param(a, Inst::kIdTest, src1reg, src2p); // test src1reg,src2p @@ -3812,7 +3820,7 @@ void drcbe_x64::op_or(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdOr, dstreg, src2p, // or dstreg,src2p @@ -3888,9 +3896,9 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst) // dstp == src1p register else if (dstp.is_int_register() && dstp == src1p) { - u32 const rs = (inst.size() == 4) ? Gpd::kSignature : Gpq::kSignature; + Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg()); - alu_op_param(a, Inst::kIdXor, Gp(rs, dstp.ireg()), src2p, // xor dstp,src2p + alu_op_param(a, Inst::kIdXor, dst, src2p, // xor dstp,src2p [inst](Assembler &a, Operand const &dst, be_parameter const &src) { // optimize all-zero and all-one cases @@ -3909,7 +3917,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst) else { // pick a target register for the general case - Gp dstreg = dstp.select_register((inst.size() == 4) ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p alu_op_param(a, Inst::kIdXor, dstreg, src2p, // xor dstreg,src2p @@ -4033,7 +4041,7 @@ void drcbe_x64::op_bswap(Assembler &a, const instruction &inst) be_parameter srcp(*this, inst.param(1), PTYPE_MRI); // pick a target register - Gp dstreg = dstp.select_register(inst.size() == 4 ? eax : rax); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax); mov_reg_param(a, dstreg, srcp); // mov dstreg,src1p a.bswap(dstreg); // bswap dstreg @@ -4067,7 +4075,7 @@ template void drcbe_x64::op_shift(Assembler &a, const uml::ins else { // pick a target register - Gp dstreg = dstp.select_register(inst.size() == 4 ? eax : rax, src2p); + Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax, src2p) : dstp.select_register(rax, src2p); if (carry) mov_reg_param(a, dstreg, src1p, true); // mov dstreg,src1p @@ -4355,7 +4363,7 @@ void drcbe_x64::op_ftoint(Assembler &a, const instruction &inst) assert(roundp.is_rounding()); // pick a target register for the general case - Gp dstreg = dstp.select_register((sizep.size() == SIZE_DWORD) ? eax : rax); + Gp dstreg = (sizep.size() == SIZE_DWORD) ? dstp.select_register(eax) : dstp.select_register(rax); // set rounding mode if necessary if (roundp.rounding() != ROUND_DEFAULT && roundp.rounding() != ROUND_TRUNC) diff --git a/src/devices/cpu/drcbex64.h b/src/devices/cpu/drcbex64.h index 08fb0658744..51e0c94fed3 100644 --- a/src/devices/cpu/drcbex64.h +++ b/src/devices/cpu/drcbex64.h @@ -102,8 +102,9 @@ private: // helpers asmjit::x86::Gp select_register(asmjit::x86::Gp defreg) const; asmjit::x86::Xmm select_register(asmjit::x86::Xmm defreg) const; - template T select_register(T defreg, be_parameter const &checkparam) const; - template T select_register(T defreg, be_parameter const &checkparam, be_parameter const &checkparam2) const; + asmjit::x86::Gp select_register(asmjit::x86::Gp defreg, be_parameter const &checkparam) const; + asmjit::x86::Gp select_register(asmjit::x86::Gp defreg, be_parameter const &checkparam, be_parameter const &checkparam2) const; + asmjit::x86::Xmm select_register(asmjit::x86::Xmm defreg, be_parameter const &checkparam) const; private: // private constructor diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp index e13b15163e7..be7352a4601 100644 --- a/src/devices/cpu/drcbex86.cpp +++ b/src/devices/cpu/drcbex86.cpp @@ -130,7 +130,7 @@ const uint32_t PTYPE_MF = PTYPE_M | PTYPE_F; //************************************************************************** #define X86_CONDITION(condition) (condition_map[condition - uml::COND_Z]) -#define X86_NOT_CONDITION(condition) (condition_map[condition - uml::COND_Z] ^ 1) +#define X86_NOT_CONDITION(condition) negateCond(condition_map[condition - uml::COND_Z]) #define assert_no_condition(inst) assert((inst).condition() == uml::COND_ALWAYS) #define assert_any_condition(inst) assert((inst).condition() == uml::COND_ALWAYS || ((inst).condition() >= uml::COND_Z && (inst).condition() < uml::COND_MAX)) @@ -159,24 +159,24 @@ static uint8_t flags_map[0x1000]; static uint32_t flags_unmap[0x20]; // condition mapping table -static const Condition::Code condition_map[uml::COND_MAX - uml::COND_Z] = -{ - Condition::Code::kZ, // COND_Z = 0x80, requires Z - Condition::Code::kNZ, // COND_NZ, requires Z - Condition::Code::kS, // COND_S, requires S - Condition::Code::kNS, // COND_NS, requires S - Condition::Code::kC, // COND_C, requires C - Condition::Code::kNC, // COND_NC, requires C - Condition::Code::kO, // COND_V, requires V - Condition::Code::kNO, // COND_NV, requires V - Condition::Code::kP, // COND_U, requires U - Condition::Code::kNP, // COND_NU, requires U - Condition::Code::kA, // COND_A, requires CZ - Condition::Code::kBE, // COND_BE, requires CZ - Condition::Code::kG, // COND_G, requires SVZ - Condition::Code::kLE, // COND_LE, requires SVZ - Condition::Code::kL, // COND_L, requires SV - Condition::Code::kGE, // COND_GE, requires SV +static const CondCode condition_map[uml::COND_MAX - uml::COND_Z] = +{ + CondCode::kZ, // COND_Z = 0x80, requires Z + CondCode::kNZ, // COND_NZ, requires Z + CondCode::kS, // COND_S, requires S + CondCode::kNS, // COND_NS, requires S + CondCode::kC, // COND_C, requires C + CondCode::kNC, // COND_NC, requires C + CondCode::kO, // COND_V, requires V + CondCode::kNO, // COND_NV, requires V + CondCode::kP, // COND_U, requires U + CondCode::kNP, // COND_NU, requires U + CondCode::kA, // COND_A, requires CZ + CondCode::kBE, // COND_BE, requires CZ + CondCode::kG, // COND_G, requires SVZ + CondCode::kLE, // COND_LE, requires SVZ + CondCode::kL, // COND_L, requires SV + CondCode::kGE, // COND_GE, requires SV }; // FPU control register mapping @@ -353,7 +353,7 @@ drcbe_x86::be_parameter::be_parameter(drcbe_x86 &drcbe, parameter const ¶m, // checkparam //------------------------------------------------- -inline Gp drcbe_x86::be_parameter::select_register(Gp const &defreg) const +inline Gpd drcbe_x86::be_parameter::select_register(Gpd const &defreg) const { if (m_type == PTYPE_INT_REGISTER) return Gpd(m_value); @@ -517,7 +517,7 @@ drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, u m_log(nullptr), m_log_asmjit(nullptr), m_logged_common(false), - m_sse3(CpuInfo::host().features().as().hasSSE3()), + m_sse3(CpuInfo::host().features().x86().hasSSE3()), m_entry(nullptr), m_exit(nullptr), m_nocode(nullptr), @@ -624,7 +624,7 @@ size_t drcbe_x86::emit(CodeHolder &ch) if (cachetop == nullptr) return 0; - err = ch.copyFlattenedData(drccodeptr(ch.baseAddress()), code_size, CodeHolder::kCopyWithPadding); + err = ch.copyFlattenedData(drccodeptr(ch.baseAddress()), code_size, CopySectionFlags::kPadTargetBuffer); if (err) throw emu_fatalerror("asmjit::CodeHolder::copyFlattenedData() error %d", err); @@ -649,26 +649,26 @@ void drcbe_x86::reset() x86code *dst = (x86code *)m_cache.top(); CodeHolder ch; - ch.init(hostEnvironment(), uint64_t(dst)); + ch.init(Environment::host(), uint64_t(dst)); FileLogger logger(m_log_asmjit); if (logger.file()) { - logger.setFlags(FormatOptions::Flags::kFlagHexOffsets | FormatOptions::Flags::kFlagHexImms | FormatOptions::Flags::kFlagMachineCode); - logger.setIndentation(FormatOptions::IndentationType::kIndentationCode, 4); + logger.setFlags(FormatFlags::kHexOffsets | FormatFlags::kHexImms | FormatFlags::kMachineCode); + logger.setIndentation(FormatIndentationGroup::kCode, 4); ch.setLogger(&logger); } Assembler a(&ch); if (logger.file()) - a.addValidationOptions(BaseEmitter::kValidationOptionIntermediate); + a.addDiagnosticOptions(DiagnosticOptions::kValidateIntermediate); // generate an entry point m_entry = (x86_entry_point_func)dst; a.bind(a.newNamedLabel("entry_point")); FuncDetail entry_point; - entry_point.init(FuncSignatureT(CallConv::kIdHost), hostEnvironment()); + entry_point.init(FuncSignatureT(CallConvId::kHost), Environment::host()); FuncFrame frame; frame.init(entry_point); @@ -822,21 +822,21 @@ void drcbe_x86::generate(drcuml_block &block, const instruction *instlist, uint3 x86code *dst = (x86code *)(uint64_t(m_cache.top() + 63) & ~63); CodeHolder ch; - ch.init(hostEnvironment(), uint64_t(dst)); + ch.init(Environment::host(), uint64_t(dst)); ThrowableErrorHandler e; ch.setErrorHandler(&e); FileLogger logger(m_log_asmjit); if (logger.file()) { - logger.setFlags(FormatOptions::Flags::kFlagHexOffsets | FormatOptions::Flags::kFlagHexImms | FormatOptions::Flags::kFlagMachineCode); - logger.setIndentation(FormatOptions::IndentationType::kIndentationCode, 4); + logger.setFlags(FormatFlags::kHexOffsets | FormatFlags::kHexImms | FormatFlags::kMachineCode); + logger.setIndentation(FormatIndentationGroup::kCode, 4); ch.setLogger(&logger); } Assembler a(&ch); if (logger.file()) - a.addValidationOptions(BaseEmitter::kValidationOptionIntermediate); + a.addDiagnosticOptions(DiagnosticOptions::kValidateIntermediate); // generate code std::string blockname; @@ -3416,7 +3416,7 @@ void drcbe_x86::op_sext(Assembler &a, const instruction &inst) assert(sizep.is_size()); // pick a target register for the general case - Gp const dstreg = (inst.size() == 8) ? eax : dstp.select_register(eax); + Gp const dstreg = dstp.select_register(eax); // convert 8-bit source registers to EAX if (sizep.size() == SIZE_BYTE && srcp.is_int_register() && (srcp.ireg() & 4)) diff --git a/src/devices/cpu/drcbex86.h b/src/devices/cpu/drcbex86.h index 0213eb1e06d..9feb21f379b 100644 --- a/src/devices/cpu/drcbex86.h +++ b/src/devices/cpu/drcbex86.h @@ -99,7 +99,7 @@ private: bool is_immediate_value(uint64_t value) const { return (m_type == PTYPE_IMMEDIATE && m_value == value); } // helpers - asmjit::x86::Gp select_register(asmjit::x86::Gp const &defreg) const; + asmjit::x86::Gpd select_register(asmjit::x86::Gpd const &defreg) const; asmjit::x86::Xmm select_register(asmjit::x86::Xmm defreg) const; template T select_register(T defreg, be_parameter const &checkparam) const; template T select_register(T defreg, be_parameter const &checkparam, be_parameter const &checkparam2) const; -- cgit v1.2.3