mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-12 13:56:29 +00:00
A64: Implement logical
This commit is contained in:
@@ -132,8 +132,31 @@ void EmitX64<JST>::EmitGetGEFromOp(EmitContext&, IR::Inst*) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitGetNZCVFromOp(EmitContext&, IR::Inst*) {
|
||||
ASSERT_MSG(false, "should never happen");
|
||||
void EmitX64<JST>::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
const size_t bitsize = [&]{
|
||||
switch (args[0].GetType()) {
|
||||
case IR::Type::U8:
|
||||
return 8;
|
||||
case IR::Type::U16:
|
||||
return 16;
|
||||
case IR::Type::U32:
|
||||
return 32;
|
||||
case IR::Type::U64:
|
||||
return 64;
|
||||
default:
|
||||
ASSERT_MSG(false, "Unreachable");
|
||||
return 0;
|
||||
}
|
||||
}();
|
||||
|
||||
Xbyak::Reg64 nzcv = ctx.reg_alloc.ScratchGpr({HostLoc::RAX});
|
||||
Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[0]).changeBit(bitsize);
|
||||
code->cmp(value, 0);
|
||||
code->lahf();
|
||||
code->seto(code->al);
|
||||
ctx.reg_alloc.DefineValue(inst, nzcv);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
@@ -933,7 +956,7 @@ void EmitX64<JST>::EmitMul64(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitAnd(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64<JST>::EmitAnd32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32();
|
||||
@@ -953,7 +976,27 @@ void EmitX64<JST>::EmitAnd(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitEor(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64<JST>::EmitAnd64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(args[0]);
|
||||
|
||||
if (args[1].FitsInImmediateU32()) {
|
||||
u32 op_arg = args[1].GetImmediateU32();
|
||||
|
||||
code->and_(result, op_arg);
|
||||
} else {
|
||||
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
|
||||
op_arg.setBit(64);
|
||||
|
||||
code->and_(result, *op_arg);
|
||||
}
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitEor32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32();
|
||||
@@ -973,7 +1016,27 @@ void EmitX64<JST>::EmitEor(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitOr(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64<JST>::EmitEor64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(args[0]);
|
||||
|
||||
if (args[1].FitsInImmediateU32()) {
|
||||
u32 op_arg = args[1].GetImmediateU32();
|
||||
|
||||
code->xor_(result, op_arg);
|
||||
} else {
|
||||
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
|
||||
op_arg.setBit(64);
|
||||
|
||||
code->xor_(result, *op_arg);
|
||||
}
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitOr32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg32 result = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32();
|
||||
@@ -993,7 +1056,27 @@ void EmitX64<JST>::EmitOr(EmitContext& ctx, IR::Inst* inst) {
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitNot(EmitContext& ctx, IR::Inst* inst) {
|
||||
void EmitX64<JST>::EmitOr64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg64 result = ctx.reg_alloc.UseScratchGpr(args[0]);
|
||||
|
||||
if (args[1].FitsInImmediateU32()) {
|
||||
u32 op_arg = args[1].GetImmediateU32();
|
||||
|
||||
code->or_(result, op_arg);
|
||||
} else {
|
||||
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
|
||||
op_arg.setBit(64);
|
||||
|
||||
code->or_(result, *op_arg);
|
||||
}
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitNot32(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg32 result;
|
||||
@@ -1007,6 +1090,21 @@ void EmitX64<JST>::EmitNot(EmitContext& ctx, IR::Inst* inst) {
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitNot64(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Xbyak::Reg64 result;
|
||||
if (args[0].IsImmediate()) {
|
||||
result = ctx.reg_alloc.ScratchGpr();
|
||||
code->mov(result, ~args[0].GetImmediateU64());
|
||||
} else {
|
||||
result = ctx.reg_alloc.UseScratchGpr(args[0]);
|
||||
code->not_(result);
|
||||
}
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
template <typename JST>
|
||||
void EmitX64<JST>::EmitSignExtendByteToWord(EmitContext& ctx, IR::Inst* inst) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
Reference in New Issue
Block a user