From ebd185968d44a9df732dd07dd1583e2196ef743a Mon Sep 17 00:00:00 2001
From: SachinVin <sachinvinayak2000@gmail.com>
Date: Sun, 21 Jul 2019 12:26:41 +0530
Subject: [PATCH] backend\A64\emit_a64_data_processing.cpp: Implement Division

---
 src/backend/A64/emit_a64_data_processing.cpp | 42 ++++++++++++++++++++
 src/backend/A64/emit_a64_floating_point.cpp  |  1 -
 src/backend/A64/opcodes.inc                  |  8 ++--
 src/frontend/A32/decoder/arm_a64.inc         |  4 +-
 4 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/src/backend/A64/emit_a64_data_processing.cpp b/src/backend/A64/emit_a64_data_processing.cpp
index c8bb2c49..b6d619c7 100644
--- a/src/backend/A64/emit_a64_data_processing.cpp
+++ b/src/backend/A64/emit_a64_data_processing.cpp
@@ -896,6 +896,48 @@ void EmitA64::EmitMul64(EmitContext& ctx, IR::Inst* inst) {
     ctx.reg_alloc.DefineValue(inst, result);
 }
 
+
+void EmitA64::EmitUnsignedDiv32(EmitContext& ctx, IR::Inst* inst) {
+    auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+
+    const ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0]));
+    const ARM64Reg divisor = DecodeReg(ctx.reg_alloc.UseGpr(args[1]));
+
+    code.UDIV(result, result, divisor);
+    ctx.reg_alloc.DefineValue(inst, result);
+}
+
+void EmitA64::EmitUnsignedDiv64(EmitContext& ctx, IR::Inst* inst) {
+    auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+
+    const ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]);
+    const ARM64Reg divisor = ctx.reg_alloc.UseGpr(args[1]);
+
+    code.UDIV(result, result, divisor);
+    ctx.reg_alloc.DefineValue(inst, result);
+}
+
+void EmitA64::EmitSignedDiv32(EmitContext& ctx, IR::Inst* inst) {
+    auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+
+    const ARM64Reg result = DecodeReg(ctx.reg_alloc.UseScratchGpr(args[0]));
+    const ARM64Reg divisor = DecodeReg(ctx.reg_alloc.UseGpr(args[1]));
+
+    code.SDIV(result, result, divisor);
+    ctx.reg_alloc.DefineValue(inst, result);
+}
+
+void EmitA64::EmitSignedDiv64(EmitContext& ctx, IR::Inst* inst) {
+    auto args = ctx.reg_alloc.GetArgumentInfo(inst);
+
+    const ARM64Reg result = ctx.reg_alloc.UseScratchGpr(args[0]);
+    const ARM64Reg divisor = ctx.reg_alloc.UseGpr(args[1]);
+
+    code.SDIV(result, result, divisor);
+    ctx.reg_alloc.DefineValue(inst, result);
+}
+
+
 void EmitA64::EmitAnd32(EmitContext& ctx, IR::Inst* inst) {
     auto args = ctx.reg_alloc.GetArgumentInfo(inst);
 
diff --git a/src/backend/A64/emit_a64_floating_point.cpp b/src/backend/A64/emit_a64_floating_point.cpp
index a1078cae..8c21657f 100644
--- a/src/backend/A64/emit_a64_floating_point.cpp
+++ b/src/backend/A64/emit_a64_floating_point.cpp
@@ -286,7 +286,6 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
     result = fsize == 32 ? EncodeRegToSingle(result) : EncodeRegToDouble(result);
     operand = fsize == 32 ? EncodeRegToSingle(operand) : EncodeRegToDouble(operand);
 
-
     if constexpr (std::is_member_function_pointer_v<Function>) {
         (code.fp_emitter.*fn)(result, result, operand);
     }
diff --git a/src/backend/A64/opcodes.inc b/src/backend/A64/opcodes.inc
index b9cc2a20..fbd02d75 100644
--- a/src/backend/A64/opcodes.inc
+++ b/src/backend/A64/opcodes.inc
@@ -118,10 +118,10 @@ OPCODE(Mul32,                                               U32,            U32,
 OPCODE(Mul64,                                               U64,            U64,            U64                                             )
 //OPCODE(SignedMultiplyHigh64,                                U64,            U64,            U64                                             )
 //OPCODE(UnsignedMultiplyHigh64,                              U64,            U64,            U64                                             )
-//OPCODE(UnsignedDiv32,                                       U32,            U32,            U32                                             )
-//OPCODE(UnsignedDiv64,                                       U64,            U64,            U64                                             )
-//OPCODE(SignedDiv32,                                         U32,            U32,            U32                                             )
-//OPCODE(SignedDiv64,                                         U64,            U64,            U64                                             )
+OPCODE(UnsignedDiv32,                                       U32,            U32,            U32                                             )
+OPCODE(UnsignedDiv64,                                       U64,            U64,            U64                                             )
+OPCODE(SignedDiv32,                                         U32,            U32,            U32                                             )
+OPCODE(SignedDiv64,                                         U64,            U64,            U64                                             )
 OPCODE(And32,                                               U32,            U32,            U32                                             )
 OPCODE(And64,                                               U64,            U64,            U64                                             )
 OPCODE(Eor32,                                               U32,            U32,            U32                                             )
diff --git a/src/frontend/A32/decoder/arm_a64.inc b/src/frontend/A32/decoder/arm_a64.inc
index 3140149b..fa8efbdf 100644
--- a/src/frontend/A32/decoder/arm_a64.inc
+++ b/src/frontend/A32/decoder/arm_a64.inc
@@ -206,8 +206,8 @@ INST(arm_REVSH,         "REVSH",               "cccc011011111111dddd11111011mmmm
 //INST(arm_USAT16,        "USAT16",              "cccc01101110vvvvdddd11110011nnnn") // v6
 
 // Divide instructions
-//INST(arm_SDIV,          "SDIV",                "cccc01110001dddd1111mmmm0001nnnn") // v7a
-//INST(arm_UDIV,          "UDIV",                "cccc01110011dddd1111mmmm0001nnnn") // v7a
+INST(arm_SDIV,          "SDIV",                "cccc01110001dddd1111mmmm0001nnnn") // v7a
+INST(arm_UDIV,          "UDIV",                "cccc01110011dddd1111mmmm0001nnnn") // v7a
 
 // Multiply (Normal) instructions
 INST(arm_MLA,           "MLA",                 "cccc0000001Sddddaaaammmm1001nnnn") // v2