mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-24 14:11:05 +00:00
Promoted shifts conditional branches to select
This commit is contained in:
parent
9c3c193a4c
commit
cf4914e4fc
@ -39,17 +39,7 @@ ARMFuncs::ResultCarry ARMFuncs::Shift_C(InstructionBlock* instruction, llvm::Val
|
|||||||
{
|
{
|
||||||
auto ir_builder = instruction->IrBuilder();
|
auto ir_builder = instruction->IrBuilder();
|
||||||
|
|
||||||
// amount_zero_basic_block will not recieve any code, it used only for the phi
|
auto amount_zero = ir_builder->CreateICmpEQ(amount, ir_builder->getInt32(0));
|
||||||
auto amount_zero_basic_block = instruction->CreateBasicBlock("ShiftCAmount0");
|
|
||||||
auto amount_not_zero_basic_block = instruction->CreateBasicBlock("ShiftCAmountNot0");
|
|
||||||
auto phi_basic_block = instruction->CreateBasicBlock("ShiftCPhi");
|
|
||||||
|
|
||||||
ir_builder->CreateCondBr(ir_builder->CreateICmpEQ(amount, ir_builder->getInt32(0)), amount_zero_basic_block, amount_not_zero_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(amount_zero_basic_block);
|
|
||||||
ir_builder->CreateBr(phi_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(amount_not_zero_basic_block);
|
|
||||||
ResultCarry result_amount_not_zero = {};
|
ResultCarry result_amount_not_zero = {};
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@ -60,19 +50,11 @@ ARMFuncs::ResultCarry ARMFuncs::Shift_C(InstructionBlock* instruction, llvm::Val
|
|||||||
case SRType::RRX: result_amount_not_zero = RRX_C(instruction, value, carry_in); break;
|
case SRType::RRX: result_amount_not_zero = RRX_C(instruction, value, carry_in); break;
|
||||||
default: assert(false, "Invalid shift type");
|
default: assert(false, "Invalid shift type");
|
||||||
}
|
}
|
||||||
auto pred = ir_builder->GetInsertBlock(); // The basic block might have changed and needs to be current for the phi
|
|
||||||
ir_builder->CreateBr(phi_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(phi_basic_block);
|
auto result = ir_builder->CreateSelect(amount_zero, value, result_amount_not_zero.result);
|
||||||
auto result_phi = ir_builder->CreatePHI(ir_builder->getInt32Ty(), 2);
|
auto carry = ir_builder->CreateSelect(amount_zero, carry_in, result_amount_not_zero.carry);
|
||||||
auto carry_phi = ir_builder->CreatePHI(ir_builder->getInt1Ty(), 2);
|
|
||||||
|
|
||||||
result_phi->addIncoming(value, amount_zero_basic_block);
|
return{ result, carry };
|
||||||
result_phi->addIncoming(result_amount_not_zero.result, pred);
|
|
||||||
carry_phi->addIncoming(carry_in, amount_zero_basic_block);
|
|
||||||
carry_phi->addIncoming(result_amount_not_zero.carry, pred);
|
|
||||||
|
|
||||||
return{ result_phi, carry_phi };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates code for LSL, LSR that checks for 0 shift
|
// Generates code for LSL, LSR that checks for 0 shift
|
||||||
@ -82,28 +64,10 @@ llvm::Value* ShiftZeroCheck(
|
|||||||
{
|
{
|
||||||
auto ir_builder = instruction->IrBuilder();
|
auto ir_builder = instruction->IrBuilder();
|
||||||
|
|
||||||
// amount_zero_basic_block will not recieve any code, it used only for the phi
|
auto amount_zero = ir_builder->CreateICmpEQ(shift, ir_builder->getInt32(0));
|
||||||
auto amount_zero_basic_block = instruction->CreateBasicBlock("ShiftZeroCheckAmount0");
|
|
||||||
auto amount_not_zero_basic_block = instruction->CreateBasicBlock("ShiftZeroCheckAmountNot0");
|
|
||||||
auto phi_basic_block = instruction->CreateBasicBlock("ShiftZeroCheckPhi");
|
|
||||||
|
|
||||||
ir_builder->CreateCondBr(ir_builder->CreateICmpEQ(shift, ir_builder->getInt32(0)), amount_zero_basic_block, amount_not_zero_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(amount_zero_basic_block);
|
|
||||||
ir_builder->CreateBr(phi_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(amount_not_zero_basic_block);
|
|
||||||
auto result_amount_not_zero = non_zero_function(instruction, x, shift);
|
auto result_amount_not_zero = non_zero_function(instruction, x, shift);
|
||||||
auto pred = ir_builder->GetInsertBlock(); // The basic block might have changed and needs to be current for the phi
|
|
||||||
ir_builder->CreateBr(phi_basic_block);
|
|
||||||
|
|
||||||
ir_builder->SetInsertPoint(phi_basic_block);
|
return ir_builder->CreateSelect(amount_zero, x, result_amount_not_zero.result);
|
||||||
auto phi = ir_builder->CreatePHI(ir_builder->getInt32Ty(), 2);
|
|
||||||
|
|
||||||
phi->addIncoming(x, amount_zero_basic_block);
|
|
||||||
phi->addIncoming(result_amount_not_zero.result, pred);
|
|
||||||
|
|
||||||
return phi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ARMFuncs::ResultCarry ARMFuncs::LSL_C(InstructionBlock* instruction, llvm::Value* x, llvm::Value* shift)
|
ARMFuncs::ResultCarry ARMFuncs::LSL_C(InstructionBlock* instruction, llvm::Value* x, llvm::Value* shift)
|
||||||
|
Loading…
Reference in New Issue
Block a user