2018-01-25 18:51:45 +01:00
|
|
|
/* This file is part of the dynarmic project.
|
|
|
|
* Copyright (c) 2018 MerryMage
|
|
|
|
* This software may be used and distributed according to the terms of the GNU
|
|
|
|
* General Public icense version 2 or any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <climits>
|
|
|
|
|
2018-08-14 20:13:47 +02:00
|
|
|
#include "backend/x64/block_of_code.h"
|
|
|
|
#include "backend/x64/emit_x64.h"
|
2018-01-25 18:51:45 +01:00
|
|
|
#include "common/common_types.h"
|
2018-07-29 09:48:28 +02:00
|
|
|
#include "common/crypto/crc32.h"
|
2018-01-25 18:51:45 +01:00
|
|
|
#include "frontend/ir/microinstruction.h"
|
|
|
|
#include "frontend/ir/opcodes.h"
|
|
|
|
|
|
|
|
namespace Dynarmic::BackendX64 {
|
|
|
|
|
|
|
|
using namespace Xbyak::util;
|
2018-07-29 09:48:28 +02:00
|
|
|
namespace CRC32 = Common::Crypto::CRC32;
|
2018-01-25 18:51:45 +01:00
|
|
|
|
|
|
|
static void EmitCRC32Castagnoli(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, const int data_size) {
|
|
|
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
|
|
|
|
|
|
|
if (code.DoesCpuSupport(Xbyak::util::Cpu::tSSE42)) {
|
|
|
|
const Xbyak::Reg32 crc = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32();
|
|
|
|
const Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[1]).changeBit(data_size);
|
|
|
|
code.crc32(crc, value);
|
|
|
|
ctx.reg_alloc.DefineValue(inst, crc);
|
|
|
|
} else {
|
2018-01-29 18:31:50 +01:00
|
|
|
ctx.reg_alloc.HostCall(inst, args[0], args[1], {});
|
|
|
|
code.mov(code.ABI_PARAM3, data_size / CHAR_BIT);
|
2018-07-29 09:48:28 +02:00
|
|
|
code.CallFunction(&CRC32::ComputeCRC32Castagnoli);
|
2018-01-25 18:51:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-28 07:41:58 +01:00
|
|
|
static void EmitCRC32ISO(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, const int data_size) {
|
|
|
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
|
|
|
|
2018-01-29 18:31:50 +01:00
|
|
|
ctx.reg_alloc.HostCall(inst, args[0], args[1], {});
|
|
|
|
code.mov(code.ABI_PARAM3, data_size / CHAR_BIT);
|
2018-07-29 09:48:28 +02:00
|
|
|
code.CallFunction(&CRC32::ComputeCRC32ISO);
|
2018-01-28 07:41:58 +01:00
|
|
|
}
|
|
|
|
|
2018-01-25 18:51:45 +01:00
|
|
|
void EmitX64::EmitCRC32Castagnoli8(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32Castagnoli(code, ctx, inst, 8);
|
2018-01-25 18:51:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32Castagnoli16(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32Castagnoli(code, ctx, inst, 16);
|
2018-01-25 18:51:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32Castagnoli32(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32Castagnoli(code, ctx, inst, 32);
|
2018-01-25 18:51:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32Castagnoli64(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32Castagnoli(code, ctx, inst, 64);
|
2018-01-25 18:51:45 +01:00
|
|
|
}
|
|
|
|
|
2018-01-28 07:41:58 +01:00
|
|
|
void EmitX64::EmitCRC32ISO8(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32ISO(code, ctx, inst, 8);
|
2018-01-28 07:41:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32ISO16(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32ISO(code, ctx, inst, 16);
|
2018-01-28 07:41:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32ISO32(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32ISO(code, ctx, inst, 32);
|
2018-01-28 07:41:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmitX64::EmitCRC32ISO64(EmitContext& ctx, IR::Inst* inst) {
|
2018-02-03 15:28:57 +01:00
|
|
|
EmitCRC32ISO(code, ctx, inst, 64);
|
2018-01-28 07:41:58 +01:00
|
|
|
}
|
|
|
|
|
2018-01-25 18:51:45 +01:00
|
|
|
} // namespace Dynarmic::BackendX64
|