| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- using ARMeilleure.Decoders;
- using ARMeilleure.IntermediateRepresentation;
- using ARMeilleure.Translation;
- using System;
- using static ARMeilleure.Instructions.InstEmitHelper;
- namespace ARMeilleure.Instructions
- {
- static partial class InstEmit
- {
- public static void Madd(ArmEmitterContext context) => EmitMul(context, isAdd: true);
- public static void Msub(ArmEmitterContext context) => EmitMul(context, isAdd: false);
- private static void EmitMul(ArmEmitterContext context, bool isAdd)
- {
- OpCodeMul op = (OpCodeMul)context.CurrOp;
- Operand a = GetIntOrZR(context, op.Ra);
- Operand n = GetIntOrZR(context, op.Rn);
- Operand m = GetIntOrZR(context, op.Rm);
- Operand res = context.Multiply(n, m);
- res = isAdd ? context.Add(a, res) : context.Subtract(a, res);
- SetIntOrZR(context, op.Rd, res);
- }
- public static void Smaddl(ArmEmitterContext context) => EmitMull(context, MullFlags.SignedAdd);
- public static void Smsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.SignedSubtract);
- public static void Umaddl(ArmEmitterContext context) => EmitMull(context, MullFlags.Add);
- public static void Umsubl(ArmEmitterContext context) => EmitMull(context, MullFlags.Subtract);
- [Flags]
- private enum MullFlags
- {
- Subtract = 0,
- Add = 1 << 0,
- Signed = 1 << 1,
- SignedAdd = Signed | Add,
- SignedSubtract = Signed | Subtract
- }
- private static void EmitMull(ArmEmitterContext context, MullFlags flags)
- {
- OpCodeMul op = (OpCodeMul)context.CurrOp;
- Operand GetExtendedRegister32(int index)
- {
- Operand value = GetIntOrZR(context, index);
- if ((flags & MullFlags.Signed) != 0)
- {
- return context.SignExtend32(value.Type, value);
- }
- else
- {
- return context.ZeroExtend32(value.Type, value);
- }
- }
- Operand a = GetIntOrZR(context, op.Ra);
- Operand n = GetExtendedRegister32(op.Rn);
- Operand m = GetExtendedRegister32(op.Rm);
- Operand res = context.Multiply(n, m);
- res = (flags & MullFlags.Add) != 0 ? context.Add(a, res) : context.Subtract(a, res);
- SetIntOrZR(context, op.Rd, res);
- }
- public static void Smulh(ArmEmitterContext context)
- {
- OpCodeMul op = (OpCodeMul)context.CurrOp;
- Operand n = GetIntOrZR(context, op.Rn);
- Operand m = GetIntOrZR(context, op.Rm);
- Operand d = context.Multiply64HighSI(n, m);
- SetIntOrZR(context, op.Rd, d);
- }
- public static void Umulh(ArmEmitterContext context)
- {
- OpCodeMul op = (OpCodeMul)context.CurrOp;
- Operand n = GetIntOrZR(context, op.Rn);
- Operand m = GetIntOrZR(context, op.Rm);
- Operand d = context.Multiply64HighUI(n, m);
- SetIntOrZR(context, op.Rd, d);
- }
- }
- }
|