Implemented UMULH and SMULH instructions
This commit is contained in:
parent
1a7b7b541a
commit
586854117b
6 changed files with 56 additions and 2 deletions
|
@ -901,6 +901,28 @@ void EmitX64::EmitMul64(EmitContext& ctx, IR::Inst* inst) {
|
|||
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) {
|
||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||
|
||||
|
|
|
@ -299,10 +299,10 @@ INST(MADD, "MADD", "z0011
|
|||
INST(MSUB, "MSUB", "z0011011000mmmmm1aaaaannnnnddddd")
|
||||
INST(SMADDL, "SMADDL", "10011011001mmmmm0aaaaannnnnddddd")
|
||||
INST(SMSUBL, "SMSUBL", "10011011001mmmmm1aaaaannnnnddddd")
|
||||
//INST(SMULH, "SMULH", "10011011010mmmmm011111nnnnnddddd")
|
||||
INST(SMULH, "SMULH", "10011011010mmmmm011111nnnnnddddd")
|
||||
INST(UMADDL, "UMADDL", "10011011101mmmmm0aaaaannnnnddddd")
|
||||
INST(UMSUBL, "UMSUBL", "10011011101mmmmm1aaaaannnnnddddd")
|
||||
//INST(UMULH, "UMULH", "10011011110mmmmm011111nnnnnddddd")
|
||||
INST(UMULH, "UMULH", "10011011110mmmmm011111nnnnnddddd")
|
||||
|
||||
// Data Processing - FP and SIMD - AES
|
||||
INST(AESE, "AESE", "0100111000101000010010nnnnnddddd")
|
||||
|
|
|
@ -56,6 +56,16 @@ bool TranslatorVisitor::SMSUBL(Reg Rm, Reg Ra, Reg Rn, Reg Rd) {
|
|||
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) {
|
||||
const IR::U64 a = X(64, Ra);
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
const size_t datasize = sf ? 64 : 32;
|
||||
|
||||
|
|
|
@ -280,6 +280,14 @@ U32U64 IREmitter::Mul(const U32U64& a, const U32U64& 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) {
|
||||
return Inst<U32>(Opcode::UnsignedDiv32, a, b);
|
||||
}
|
||||
|
|
|
@ -112,6 +112,8 @@ public:
|
|||
U32 Mul(const U32& a, const U32& b);
|
||||
U64 Mul(const U64& a, const U64& 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);
|
||||
U64 UnsignedDiv(const U64& a, const U64& b);
|
||||
U32U64 UnsignedDiv(const U32U64& a, const U32U64& b);
|
||||
|
|
|
@ -98,6 +98,8 @@ OPCODE(Sub32, T::U32, T::U32, T::U32,
|
|||
OPCODE(Sub64, T::U64, T::U64, T::U64, T::U1 )
|
||||
OPCODE(Mul32, T::U32, T::U32, T::U32 )
|
||||
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(UnsignedDiv64, T::U64, T::U64, T::U64 )
|
||||
OPCODE(SignedDiv32, T::U32, T::U32, T::U32 )
|
||||
|
|
Loading…
Reference in a new issue