From 0398fc9b41c80cc769ac6082b58c703d866f8b8e Mon Sep 17 00:00:00 2001 From: SachinVin Date: Fri, 19 Jul 2019 20:02:53 +0530 Subject: [PATCH] backend\A64\emit_a64_data_processing.cpp: Implement 64bit Logical Instructions --- src/backend/A64/emit_a64_data_processing.cpp | 129 +++++++++---------- src/backend/A64/opcodes.inc | 8 +- 2 files changed, 66 insertions(+), 71 deletions(-) diff --git a/src/backend/A64/emit_a64_data_processing.cpp b/src/backend/A64/emit_a64_data_processing.cpp index 446260a3..9b25608f 100644 --- a/src/backend/A64/emit_a64_data_processing.cpp +++ b/src/backend/A64/emit_a64_data_processing.cpp @@ -921,24 +921,22 @@ void EmitA64::EmitAnd32(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } -//void EmitA64::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].FitsInImmediateS32()) { -// u32 op_arg = u32(args[1].GetImmediateS32()); -// -// 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); -//} +void EmitA64::EmitAnd64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Arm64Gen::ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + + if (args[1].IsImmediate()) { + u32 op_arg = args[1].GetImmediateU32(); + code.ANDI2R(result, result, op_arg, code.ABI_SCRATCH1); + } + else { + Arm64Gen::ARM64Reg op_arg = ctx.reg_alloc.UseGpr(args[1]); + code.AND(result, result, op_arg); + } + + ctx.reg_alloc.DefineValue(inst, result); +} void EmitA64::EmitEor32(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -956,24 +954,22 @@ void EmitA64::EmitEor32(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } -//void EmitA64::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].FitsInImmediateS32()) { -// u32 op_arg = u32(args[1].GetImmediateS32()); -// -// 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); -//} +void EmitA64::EmitEor64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Arm64Gen::ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + + if (args[1].IsImmediate()) { + u32 op_arg = args[1].GetImmediateU32(); + code.EORI2R(result, result, op_arg, code.ABI_SCRATCH1); + } + else { + Arm64Gen::ARM64Reg op_arg = ctx.reg_alloc.UseGpr(args[1]); + code.EOR(result, result, op_arg); + } + + ctx.reg_alloc.DefineValue(inst, result); +} void EmitA64::EmitOr32(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -991,24 +987,22 @@ void EmitA64::EmitOr32(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } -//void EmitA64::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].FitsInImmediateS32()) { -// u32 op_arg = u32(args[1].GetImmediateS32()); -// -// 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); -//} +void EmitA64::EmitOr64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Arm64Gen::ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]); + + if (args[1].IsImmediate()) { + u32 op_arg = args[1].GetImmediateU32(); + code.ORRI2R(result, result, op_arg, code.ABI_SCRATCH1); + } + else { + Arm64Gen::ARM64Reg op_arg = ctx.reg_alloc.UseGpr(args[1]); + code.ORR(result, result, op_arg); + } + + ctx.reg_alloc.DefineValue(inst, result); +} void EmitA64::EmitNot32(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); @@ -1024,19 +1018,20 @@ void EmitA64::EmitNot32(EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.DefineValue(inst, result); } -//void EmitA64::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); -//} +void EmitA64::EmitNot64(EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + + Arm64Gen::ARM64Reg result; + if (args[0].IsImmediate()) { + result = DecodeReg(ctx.reg_alloc.ScratchGpr()); + code.MOVI2R(result, u32(~args[0].GetImmediateU32())); + } + else { + result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0])); + code.MVN(result, result); + } + ctx.reg_alloc.DefineValue(inst, result); +} void EmitA64::EmitSignExtendByteToWord(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); diff --git a/src/backend/A64/opcodes.inc b/src/backend/A64/opcodes.inc index a8646602..5fb8530b 100644 --- a/src/backend/A64/opcodes.inc +++ b/src/backend/A64/opcodes.inc @@ -123,13 +123,13 @@ OPCODE(Mul64, U64, U64, //OPCODE(SignedDiv32, U32, U32, U32 ) //OPCODE(SignedDiv64, U64, U64, U64 ) OPCODE(And32, U32, U32, U32 ) -//OPCODE(And64, U64, U64, U64 ) +OPCODE(And64, U64, U64, U64 ) OPCODE(Eor32, U32, U32, U32 ) -//OPCODE(Eor64, U64, U64, U64 ) +OPCODE(Eor64, U64, U64, U64 ) OPCODE(Or32, U32, U32, U32 ) -//OPCODE(Or64, U64, U64, U64 ) +OPCODE(Or64, U64, U64, U64 ) OPCODE(Not32, U32, U32 ) -//OPCODE(Not64, U64, U64 ) +OPCODE(Not64, U64, U64 ) OPCODE(SignExtendByteToWord, U32, U8 ) OPCODE(SignExtendHalfToWord, U32, U16 ) OPCODE(SignExtendByteToLong, U64, U8 )