Implemented UMULH and SMULH instructions

This commit is contained in:
FernandoS27 2018-01-27 12:32:07 -04:00 committed by MerryMage
parent 1a7b7b541a
commit 586854117b
6 changed files with 56 additions and 2 deletions

View file

@ -901,6 +901,28 @@ void EmitX64::EmitMul64(EmitContext& ctx, IR::Inst* inst) {
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);
} }
void EmitX64::EmitUnsignedMultiplyHigh64(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ctx.reg_alloc.ScratchGpr({HostLoc::RDX});
ctx.reg_alloc.UseScratch(args[0], HostLoc::RAX);
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
code.mul(*op_arg);
ctx.reg_alloc.DefineValue(inst, rdx);
}
void EmitX64::EmitSignedMultiplyHigh64(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
ctx.reg_alloc.ScratchGpr({HostLoc::RDX});
ctx.reg_alloc.UseScratch(args[0], HostLoc::RAX);
OpArg op_arg = ctx.reg_alloc.UseOpArg(args[1]);
code.imul(*op_arg);
ctx.reg_alloc.DefineValue(inst, rdx);
}
void EmitX64::EmitUnsignedDiv32(EmitContext& ctx, IR::Inst* inst) { void EmitX64::EmitUnsignedDiv32(EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst); auto args = ctx.reg_alloc.GetArgumentInfo(inst);

View file

@ -299,10 +299,10 @@ INST(MADD, "MADD", "z0011
INST(MSUB, "MSUB", "z0011011000mmmmm1aaaaannnnnddddd") INST(MSUB, "MSUB", "z0011011000mmmmm1aaaaannnnnddddd")
INST(SMADDL, "SMADDL", "10011011001mmmmm0aaaaannnnnddddd") INST(SMADDL, "SMADDL", "10011011001mmmmm0aaaaannnnnddddd")
INST(SMSUBL, "SMSUBL", "10011011001mmmmm1aaaaannnnnddddd") INST(SMSUBL, "SMSUBL", "10011011001mmmmm1aaaaannnnnddddd")
//INST(SMULH, "SMULH", "10011011010mmmmm011111nnnnnddddd") INST(SMULH, "SMULH", "10011011010mmmmm011111nnnnnddddd")
INST(UMADDL, "UMADDL", "10011011101mmmmm0aaaaannnnnddddd") INST(UMADDL, "UMADDL", "10011011101mmmmm0aaaaannnnnddddd")
INST(UMSUBL, "UMSUBL", "10011011101mmmmm1aaaaannnnnddddd") INST(UMSUBL, "UMSUBL", "10011011101mmmmm1aaaaannnnnddddd")
//INST(UMULH, "UMULH", "10011011110mmmmm011111nnnnnddddd") INST(UMULH, "UMULH", "10011011110mmmmm011111nnnnnddddd")
// Data Processing - FP and SIMD - AES // Data Processing - FP and SIMD - AES
INST(AESE, "AESE", "0100111000101000010010nnnnnddddd") INST(AESE, "AESE", "0100111000101000010010nnnnnddddd")

View file

@ -56,6 +56,16 @@ bool TranslatorVisitor::SMSUBL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) {
return true; return true;
} }
bool TranslatorVisitor::SMULH(Reg Rm, Reg Rn, Reg Rd) {
const IR::U64 m = X(64, Rm);
const IR::U64 n = X(64, Rn);
const IR::U64 result = ir.SignedMultiplyHigh(n, m);
X(64, Rd, result);
return true;
}
bool TranslatorVisitor::UMADDL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) { bool TranslatorVisitor::UMADDL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) {
const IR::U64 a = X(64, Ra); const IR::U64 a = X(64, Ra);
const IR::U64 m = ir.ZeroExtendToLong(X(32, Rm)); const IR::U64 m = ir.ZeroExtendToLong(X(32, Rm));
@ -78,6 +88,16 @@ bool TranslatorVisitor::UMSUBL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) {
return true; return true;
} }
bool TranslatorVisitor::UMULH(Reg Rm, Reg Rn, Reg Rd) {
const IR::U64 m = X(64, Rm);
const IR::U64 n = X(64, Rn);
const IR::U64 result = ir.UnsignedMultiplyHigh(n, m);
X(64, Rd, result);
return true;
}
bool TranslatorVisitor::UDIV(bool sf, Reg Rm, Reg Rn, Reg Rd) { bool TranslatorVisitor::UDIV(bool sf, Reg Rm, Reg Rn, Reg Rd) {
const size_t datasize = sf ? 64 : 32; const size_t datasize = sf ? 64 : 32;

View file

@ -280,6 +280,14 @@ U32U64 IREmitter::Mul(const U32U64& a, const U32U64& b) {
return Inst<U64>(Opcode::Mul64, a, b); return Inst<U64>(Opcode::Mul64, a, b);
} }
U64 IREmitter::UnsignedMultiplyHigh(const U64& a, const U64& b) {
return Inst<U64>(Opcode::UnsignedMultiplyHigh64, a, b);
}
U64 IREmitter::SignedMultiplyHigh(const U64& a, const U64& b) {
return Inst<U64>(Opcode::SignedMultiplyHigh64, a, b);
}
U32 IREmitter::UnsignedDiv(const U32& a, const U32& b) { U32 IREmitter::UnsignedDiv(const U32& a, const U32& b) {
return Inst<U32>(Opcode::UnsignedDiv32, a, b); return Inst<U32>(Opcode::UnsignedDiv32, a, b);
} }

View file

@ -112,6 +112,8 @@ public:
U32 Mul(const U32& a, const U32& b); U32 Mul(const U32& a, const U32& b);
U64 Mul(const U64& a, const U64& b); U64 Mul(const U64& a, const U64& b);
U32U64 Mul(const U32U64& a, const U32U64& b); U32U64 Mul(const U32U64& a, const U32U64& b);
U64 UnsignedMultiplyHigh(const U64& a, const U64& b);
U64 SignedMultiplyHigh(const U64& a, const U64& b);
U32 UnsignedDiv(const U32& a, const U32& b); U32 UnsignedDiv(const U32& a, const U32& b);
U64 UnsignedDiv(const U64& a, const U64& b); U64 UnsignedDiv(const U64& a, const U64& b);
U32U64 UnsignedDiv(const U32U64& a, const U32U64& b); U32U64 UnsignedDiv(const U32U64& a, const U32U64& b);

View file

@ -98,6 +98,8 @@ OPCODE(Sub32, T::U32, T::U32, T::U32,
OPCODE(Sub64, T::U64, T::U64, T::U64, T::U1 ) OPCODE(Sub64, T::U64, T::U64, T::U64, T::U1 )
OPCODE(Mul32, T::U32, T::U32, T::U32 ) OPCODE(Mul32, T::U32, T::U32, T::U32 )
OPCODE(Mul64, T::U64, T::U64, T::U64 ) OPCODE(Mul64, T::U64, T::U64, T::U64 )
OPCODE(SignedMultiplyHigh64, T::U64, T::U64, T::U64 )
OPCODE(UnsignedMultiplyHigh64, T::U64, T::U64, T::U64 )
OPCODE(UnsignedDiv32, T::U32, T::U32, T::U32 ) OPCODE(UnsignedDiv32, T::U32, T::U32, T::U32 )
OPCODE(UnsignedDiv64, T::U64, T::U64, T::U64 ) OPCODE(UnsignedDiv64, T::U64, T::U64, T::U64 )
OPCODE(SignedDiv32, T::U32, T::U32, T::U32 ) OPCODE(SignedDiv32, T::U32, T::U32, T::U32 )