A64: Add enable_optimizations configuration option

Allow library users to disable optimizations for debugging reasons.
This commit is contained in:
MerryMage 2020-04-19 15:54:46 +01:00
parent 8bef1afb9a
commit 0c51313479
4 changed files with 42 additions and 4 deletions

View file

@ -116,6 +116,14 @@ struct UserConfig {
size_t processor_id = 0;
ExclusiveMonitor* global_monitor = nullptr;
/// When set to false, this disables all optimizations than can't otherwise be disabled
/// by setting other configuration options. This includes:
/// - IR optimizations
/// - Block linking optimizations
/// - RSB optimizations
/// This is intended to be used for debugging.
bool enable_optimizations = true;
/// When set to true, UserCallbacks::DataCacheOperationRaised will be called when any
/// data cache instruction is executed. Notably DC ZVA will not implicitly do anything.
/// When set to false, UserCallbacks::DataCacheOperationRaised will never be called.

View file

@ -350,6 +350,14 @@ void A64EmitX64::GenTerminalHandlers() {
}
}
void A64EmitX64::EmitPushRSB(EmitContext& ctx, IR::Inst* inst) {
if (!conf.enable_optimizations) {
return;
}
EmitX64::EmitPushRSB(ctx, inst);
}
void A64EmitX64::EmitA64SetCheckBit(A64EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
const Xbyak::Reg8 to_store = ctx.reg_alloc.UseGpr(args[0]).cvt8();
@ -1156,6 +1164,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::ReturnToDispatch, IR::LocationDescri
}
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor) {
if (!conf.enable_optimizations) {
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
code.ReturnFromRunCode();
return;
}
code.cmp(qword[r15 + offsetof(A64JitState, cycles_remaining)], 0);
patch_information[terminal.next].jg.emplace_back(code.getCurr());
@ -1170,6 +1185,13 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc
}
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor) {
if (!conf.enable_optimizations) {
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC());
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax);
code.ReturnFromRunCode();
return;
}
patch_information[terminal.next].jmp.emplace_back(code.getCurr());
if (auto next_bb = GetBasicBlock(terminal.next)) {
EmitPatchJmp(terminal.next, next_bb->entrypoint);
@ -1179,6 +1201,11 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location
}
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor) {
if (!conf.enable_optimizations) {
code.ReturnFromRunCode();
return;
}
code.jmp(terminal_handler_pop_rsb_hint);
}

View file

@ -79,6 +79,7 @@ protected:
void EmitExclusiveWrite(A64EmitContext& ctx, IR::Inst* inst, size_t bitsize);
// Microinstruction emitters
void EmitPushRSB(EmitContext& ctx, IR::Inst* inst);
#define OPCODE(...)
#define A32OPC(...)
#define A64OPC(name, type, ...) void EmitA64##name(A64EmitContext& ctx, IR::Inst* inst);

View file

@ -231,10 +231,12 @@ private:
const auto get_code = [this](u64 vaddr) { return conf.callbacks->MemoryReadCode(vaddr); };
IR::Block ir_block = A64::Translate(A64::LocationDescriptor{current_location}, get_code, {conf.define_unpredictable_behaviour});
Optimization::A64CallbackConfigPass(ir_block, conf);
Optimization::A64GetSetElimination(ir_block);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
if (conf.enable_optimizations) {
Optimization::A64GetSetElimination(ir_block);
Optimization::ConstantPropagation(ir_block);
Optimization::DeadCodeElimination(ir_block);
Optimization::A64MergeInterpretBlocksPass(ir_block, conf.callbacks);
}
// printf("%s\n", IR::DumpBlock(ir_block).c_str());
Optimization::VerificationPass(ir_block);
return emitter.Emit(ir_block).entrypoint;