Add IR opcode RotateRightExtended
to rotate through the carry flag
This commit is contained in:
parent
dacaeadb6a
commit
2488926341
4 changed files with 26 additions and 0 deletions
|
@ -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) {
|
static X64Reg DoCarry(RegAlloc& reg_alloc, const IR::Value& carry_in, IR::Inst* carry_out) {
|
||||||
if (carry_in.IsImmediate()) {
|
if (carry_in.IsImmediate()) {
|
||||||
return carry_out ? reg_alloc.DefRegister(carry_out, any_gpr) : INVALID_REG;
|
return carry_out ? reg_alloc.DefRegister(carry_out, any_gpr) : INVALID_REG;
|
||||||
|
|
|
@ -138,6 +138,12 @@ IREmitter::ResultAndCarry IREmitter::RotateRight(const IR::Value& value_in, cons
|
||||||
return {result, carry_out};
|
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) {
|
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 result = Inst(IR::Opcode::AddWithCarry, {a, b, carry_in});
|
||||||
auto carry_out = Inst(IR::Opcode::GetCarryFromOp, {result});
|
auto carry_out = Inst(IR::Opcode::GetCarryFromOp, {result});
|
||||||
|
|
|
@ -63,6 +63,7 @@ public:
|
||||||
ResultAndCarry LogicalShiftRight(const IR::Value& value_in, const IR::Value& shift_amount, const IR::Value& carry_in);
|
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 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 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);
|
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);
|
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);
|
ResultAndCarryAndOverflow SubWithCarry(const IR::Value& a, const IR::Value& b, const IR::Value& carry_in);
|
||||||
|
|
|
@ -29,6 +29,7 @@ OPCODE(LogicalShiftLeft, T::U32, T::U32, T::U8,
|
||||||
OPCODE(LogicalShiftRight, T::U32, T::U32, T::U8, T::U1 )
|
OPCODE(LogicalShiftRight, T::U32, T::U32, T::U8, T::U1 )
|
||||||
OPCODE(ArithmeticShiftRight, 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(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(AddWithCarry, T::U32, T::U32, T::U32, T::U1 )
|
||||||
OPCODE(SubWithCarry, 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 )
|
OPCODE(And, T::U32, T::U32, T::U32 )
|
||||||
|
|
Loading…
Reference in a new issue