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) { (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