Add carry support to MostSignificantWord

This commit is contained in:
Tillmann Karras 2016-08-06 21:03:57 +01:00
parent 01aebcb385
commit b9f4f1ed0f
4 changed files with 23 additions and 11 deletions

View file

@ -339,9 +339,19 @@ void EmitX64::EmitLeastSignificantWord(IR::Block&, IR::Inst* inst) {
reg_alloc.RegisterAddDef(inst, inst->GetArg(0));
}
void EmitX64::EmitMostSignificantWord(IR::Block&, IR::Inst* inst) {
auto u64 = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr);
code->SHR(64, R(u64), Imm8(32));
void EmitX64::EmitMostSignificantWord(IR::Block& block, IR::Inst* inst) {
auto carry_inst = FindUseWithOpcode(inst, IR::Opcode::GetCarryFromOp);
auto result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr);
code->SHR(64, R(result), Imm8(32));
if (carry_inst) {
EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst);
X64Reg carry = reg_alloc.DefRegister(carry_inst, any_gpr);
code->SETcc(CC_C, R(carry));
}
}
void EmitX64::EmitLeastSignificantHalf(IR::Block&, IR::Inst* inst) {

View file

@ -127,8 +127,10 @@ IR::Value IREmitter::LeastSignificantWord(const IR::Value& value) {
return Inst(IR::Opcode::LeastSignificantWord, {value});
}
IR::Value IREmitter::MostSignificantWord(const IR::Value& value) {
return Inst(IR::Opcode::MostSignificantWord, {value});
IREmitter::ResultAndCarry IREmitter::MostSignificantWord(const IR::Value& value) {
auto result = Inst(IR::Opcode::MostSignificantWord, {value});
auto carry_out = Inst(IR::Opcode::GetCarryFromOp, {result});
return {result, carry_out};
}
IR::Value IREmitter::LeastSignificantHalf(const IR::Value& value) {

View file

@ -58,7 +58,7 @@ public:
IR::Value Pack2x32To1x64(const IR::Value& lo, const IR::Value& hi);
IR::Value LeastSignificantWord(const IR::Value& value);
IR::Value MostSignificantWord(const IR::Value& value);
ResultAndCarry MostSignificantWord(const IR::Value& value);
IR::Value LeastSignificantHalf(const IR::Value& value);
IR::Value LeastSignificantByte(const IR::Value& value);
IR::Value MostSignificantBit(const IR::Value& value);

View file

@ -52,7 +52,7 @@ bool ArmTranslatorVisitor::arm_SMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
auto addend = ir.Pack2x32To1x64(ir.GetRegister(dLo), ir.GetRegister(dHi));
auto result = ir.Add64(product, addend);
auto lo = ir.LeastSignificantWord(result);
auto hi = ir.MostSignificantWord(result);
auto hi = ir.MostSignificantWord(result).result;
ir.SetRegister(dLo, lo);
ir.SetRegister(dHi, hi);
if (S) {
@ -73,7 +73,7 @@ bool ArmTranslatorVisitor::arm_SMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
auto m64 = ir.SignExtendWordToLong(ir.GetRegister(m));
auto result = ir.Mul64(n64, m64);
auto lo = ir.LeastSignificantWord(result);
auto hi = ir.MostSignificantWord(result);
auto hi = ir.MostSignificantWord(result).result;
ir.SetRegister(dLo, lo);
ir.SetRegister(dHi, hi);
if (S) {
@ -96,7 +96,7 @@ bool ArmTranslatorVisitor::arm_UMAAL(Cond cond, Reg dHi, Reg dLo, Reg m, Reg n)
auto m64 = ir.ZeroExtendWordToLong(ir.GetRegister(m));
auto result = ir.Add64(ir.Add64(ir.Mul64(n64, m64), hi64), lo64);
ir.SetRegister(dLo, ir.LeastSignificantWord(result));
ir.SetRegister(dHi, ir.MostSignificantWord(result));
ir.SetRegister(dHi, ir.MostSignificantWord(result).result);
}
return true;
}
@ -112,7 +112,7 @@ bool ArmTranslatorVisitor::arm_UMLAL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
auto m64 = ir.ZeroExtendWordToLong(ir.GetRegister(m));
auto result = ir.Add64(ir.Mul64(n64, m64), addend);
auto lo = ir.LeastSignificantWord(result);
auto hi = ir.MostSignificantWord(result);
auto hi = ir.MostSignificantWord(result).result;
ir.SetRegister(dLo, lo);
ir.SetRegister(dHi, hi);
if (S) {
@ -133,7 +133,7 @@ bool ArmTranslatorVisitor::arm_UMULL(Cond cond, bool S, Reg dHi, Reg dLo, Reg m,
auto m64 = ir.ZeroExtendWordToLong(ir.GetRegister(m));
auto result = ir.Mul64(n64, m64);
auto lo = ir.LeastSignificantWord(result);
auto hi = ir.MostSignificantWord(result);
auto hi = ir.MostSignificantWord(result).result;
ir.SetRegister(dLo, lo);
ir.SetRegister(dHi, hi);
if (S) {