Add IR opcode RotateRightExtended

to rotate through the carry flag
This commit is contained in:
Tillmann Karras 2016-07-31 19:07:35 +01:00
parent dacaeadb6a
commit 2488926341
4 changed files with 26 additions and 0 deletions

View file

@ -636,6 +636,24 @@ void EmitX64::EmitRotateRight(IR::Block& block, IR::Inst* inst) {
}
}
void EmitX64::EmitRotateRightExtended(IR::Block& block, IR::Inst* inst) {
auto carry_inst = FindUseWithOpcode(inst, IR::Opcode::GetCarryFromOp);
X64Reg result = reg_alloc.UseDefRegister(inst->GetArg(0), inst, any_gpr);
X64Reg carry = carry_inst
? reg_alloc.UseDefRegister(inst->GetArg(1), carry_inst, any_gpr)
: reg_alloc.UseRegister(inst->GetArg(1), any_gpr);
code->BT(32, R(carry), Imm8(0));
code->RCR(32, R(result), Imm8(1));
if (carry_inst) {
EraseInstruction(block, carry_inst);
reg_alloc.DecrementRemainingUses(inst);
code->SETcc(CC_C, R(carry));
}
}
static X64Reg DoCarry(RegAlloc& reg_alloc, const IR::Value& carry_in, IR::Inst* carry_out) {
if (carry_in.IsImmediate()) {
return carry_out ? reg_alloc.DefRegister(carry_out, any_gpr) : INVALID_REG;

View file

@ -138,6 +138,12 @@ IREmitter::ResultAndCarry IREmitter::RotateRight(const IR::Value& value_in, cons
return {result, carry_out};
}
IREmitter::ResultAndCarry IREmitter::RotateRightExtended(const IR::Value& value_in, const IR::Value& carry_in) {
auto result = Inst(IR::Opcode::RotateRightExtended, {value_in, carry_in});
auto carry_out = Inst(IR::Opcode::GetCarryFromOp, {result});
return {result, carry_out};
}
IREmitter::ResultAndCarryAndOverflow IREmitter::AddWithCarry(const IR::Value& a, const IR::Value& b, const IR::Value& carry_in) {
auto result = Inst(IR::Opcode::AddWithCarry, {a, b, carry_in});
auto carry_out = Inst(IR::Opcode::GetCarryFromOp, {result});

View file

@ -63,6 +63,7 @@ public:
ResultAndCarry LogicalShiftRight(const IR::Value& value_in, const IR::Value& shift_amount, const IR::Value& carry_in);
ResultAndCarry ArithmeticShiftRight(const IR::Value& value_in, const IR::Value& shift_amount, const IR::Value& carry_in);
ResultAndCarry RotateRight(const IR::Value& value_in, const IR::Value& shift_amount, const IR::Value& carry_in);
ResultAndCarry RotateRightExtended(const IR::Value& value_in, const IR::Value& carry_in);
ResultAndCarryAndOverflow AddWithCarry(const IR::Value& a, const IR::Value& b, const IR::Value& carry_in);
IR::Value Add(const IR::Value& a, const IR::Value& b);
ResultAndCarryAndOverflow SubWithCarry(const IR::Value& a, const IR::Value& b, const IR::Value& carry_in);

View file

@ -29,6 +29,7 @@ OPCODE(LogicalShiftLeft, T::U32, T::U32, T::U8,
OPCODE(LogicalShiftRight, T::U32, T::U32, T::U8, T::U1 )
OPCODE(ArithmeticShiftRight, T::U32, T::U32, T::U8, T::U1 )
OPCODE(RotateRight, T::U32, T::U32, T::U8, T::U1 )
OPCODE(RotateRightExtended, T::U32, T::U32, T::U1 )
OPCODE(AddWithCarry, T::U32, T::U32, T::U32, T::U1 )
OPCODE(SubWithCarry, T::U32, T::U32, T::U32, T::U1 )
OPCODE(And, T::U32, T::U32, T::U32 )