From 0b9008680a739ea35fc4b12179ac091381a96ca2 Mon Sep 17 00:00:00 2001 From: SachinVin Date: Tue, 16 Jul 2019 17:48:18 +0530 Subject: [PATCH] backend\A64\emit_a64_data_processing.cpp: Implement Sext an Zext ops --- src/backend/A64/emit_a64_data_processing.cpp | 80 ++++++++++++++++++++ src/backend/A64/opcodes.inc | 20 ++--- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/src/backend/A64/emit_a64_data_processing.cpp b/src/backend/A64/emit_a64_data_processing.cpp index cf7fe7d8..8278558d 100644 --- a/src/backend/A64/emit_a64_data_processing.cpp +++ b/src/backend/A64/emit_a64_data_processing.cpp @@ -1037,4 +1037,84 @@ void EmitA64::EmitNot32(EmitContext& ctx, IR::Inst* inst) { // } // ctx.reg_alloc.DefineValue(inst, result); //} + +void EmitA64::EmitSignExtendByteToWord(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Arm64Gen::ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); + code.SXTB(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitSignExtendHalfToWord(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Arm64Gen::ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); + code.SXTH(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitSignExtendByteToLong(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + code.SXTB(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitSignExtendHalfToLong(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + code.SXTH(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitSignExtendWordToLong(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + code.SXTW(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitZeroExtendByteToWord(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Arm64Gen::ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); + code.UXTB(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitZeroExtendHalfToWord(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + Arm64Gen::ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); + code.UXTH(result, result); + ctx.reg_alloc.DefineValue(inst, result); +} + +void EmitA64::EmitZeroExtendByteToLong(EmitContext& ctx, IR::Inst* inst) { + // x64 zeros upper 32 bits on a 32-bit move + EmitZeroExtendByteToWord(ctx, inst); +} + +void EmitA64::EmitZeroExtendHalfToLong(EmitContext& ctx, IR::Inst* inst) { + // x64 zeros upper 32 bits on a 32-bit move + EmitZeroExtendHalfToWord(ctx, inst); +} + +void EmitA64::EmitZeroExtendWordToLong(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + code.MOV(result, DecodeReg(result)); + ctx.reg_alloc.DefineValue(inst, result); +} + +//void EmitA64::EmitZeroExtendLongToQuad(EmitContext& ctx, IR::Inst* inst) { +// auto args = ctx.reg_alloc.GetArgumentInfo(inst); +// if (args[0].IsInGpr()) { +// Xbyak::Reg64 source = ctx.reg_alloc.UseGpr(args[0]); +// Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); +// code.movq(result, source); +// ctx.reg_alloc.DefineValue(inst, result); +// } else { +// Xbyak::Xmm result = ctx.reg_alloc.UseScratchXmm(args[0]); +// code.movq(result, result); +// ctx.reg_alloc.DefineValue(inst, result); +// } +//} } // namespace Dynarmic::BackendA64 diff --git a/src/backend/A64/opcodes.inc b/src/backend/A64/opcodes.inc index aa7c0f7e..a2ee3049 100644 --- a/src/backend/A64/opcodes.inc +++ b/src/backend/A64/opcodes.inc @@ -129,16 +129,16 @@ OPCODE(Or32, U32, U32, //OPCODE(Or64, U64, U64, U64 ) OPCODE(Not32, U32, U32 ) //OPCODE(Not64, U64, U64 ) -//OPCODE(SignExtendByteToWord, U32, U8 ) -//OPCODE(SignExtendHalfToWord, U32, U16 ) -//OPCODE(SignExtendByteToLong, U64, U8 ) -//OPCODE(SignExtendHalfToLong, U64, U16 ) -//OPCODE(SignExtendWordToLong, U64, U32 ) -//OPCODE(ZeroExtendByteToWord, U32, U8 ) -//OPCODE(ZeroExtendHalfToWord, U32, U16 ) -//OPCODE(ZeroExtendByteToLong, U64, U8 ) -//OPCODE(ZeroExtendHalfToLong, U64, U16 ) -//OPCODE(ZeroExtendWordToLong, U64, U32 ) +OPCODE(SignExtendByteToWord, U32, U8 ) +OPCODE(SignExtendHalfToWord, U32, U16 ) +OPCODE(SignExtendByteToLong, U64, U8 ) +OPCODE(SignExtendHalfToLong, U64, U16 ) +OPCODE(SignExtendWordToLong, U64, U32 ) +OPCODE(ZeroExtendByteToWord, U32, U8 ) +OPCODE(ZeroExtendHalfToWord, U32, U16 ) +OPCODE(ZeroExtendByteToLong, U64, U8 ) +OPCODE(ZeroExtendHalfToLong, U64, U16 ) +OPCODE(ZeroExtendWordToLong, U64, U32 ) //OPCODE(ZeroExtendLongToQuad, U128, U64 ) //OPCODE(ByteReverseWord, U32, U32 ) //OPCODE(ByteReverseHalf, U16, U16 )