|
|
@ -632,16 +632,14 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::ReturnToDispatch, IR::LocationDescri |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor, bool is_single_step) { |
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDescriptor, bool is_single_step) { |
|
|
|
|
|
// Used for patches and linking
|
|
|
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) { |
|
|
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) { |
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.ReturnFromRunCode(); |
|
|
code.ReturnFromRunCode(); |
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
if (conf.enable_cycle_counting) { |
|
|
if (conf.enable_cycle_counting) { |
|
|
code.cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0); |
|
|
code.cmp(qword[rsp + ABI_SHADOW_SPACE + offsetof(StackLayout, cycles_remaining)], 0); |
|
|
|
|
|
|
|
|
patch_information[terminal.next].jg.push_back(code.getCurr()); |
|
|
patch_information[terminal.next].jg.push_back(code.getCurr()); |
|
|
if (const auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
if (const auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
EmitPatchJg(terminal.next, next_bb->entrypoint); |
|
|
EmitPatchJg(terminal.next, next_bb->entrypoint); |
|
|
@ -650,7 +648,6 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
code.cmp(dword[r15 + offsetof(A64JitState, halt_reason)], 0); |
|
|
code.cmp(dword[r15 + offsetof(A64JitState, halt_reason)], 0); |
|
|
|
|
|
|
|
|
patch_information[terminal.next].jz.push_back(code.getCurr()); |
|
|
patch_information[terminal.next].jz.push_back(code.getCurr()); |
|
|
if (const auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
if (const auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
EmitPatchJz(terminal.next, next_bb->entrypoint); |
|
|
EmitPatchJz(terminal.next, next_bb->entrypoint); |
|
|
@ -658,20 +655,18 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlock terminal, IR::LocationDesc |
|
|
EmitPatchJz(terminal.next); |
|
|
EmitPatchJz(terminal.next); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.ForceReturnFromRunCode(); |
|
|
code.ForceReturnFromRunCode(); |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor, bool is_single_step) { |
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor, bool is_single_step) { |
|
|
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) { |
|
|
if (!conf.HasOptimization(OptimizationFlag::BlockLinking) || is_single_step) { |
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(rax, A64::LocationDescriptor{terminal.next}.PC()); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.mov(qword[r15 + offsetof(A64JitState, pc)], rax); |
|
|
code.ReturnFromRunCode(); |
|
|
code.ReturnFromRunCode(); |
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
patch_information[terminal.next].jmp.push_back(code.getCurr()); |
|
|
patch_information[terminal.next].jmp.push_back(code.getCurr()); |
|
|
if (auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
if (auto next_bb = GetBasicBlock(terminal.next)) { |
|
|
EmitPatchJmp(terminal.next, next_bb->entrypoint); |
|
|
EmitPatchJmp(terminal.next, next_bb->entrypoint); |
|
|
@ -679,6 +674,7 @@ void A64EmitX64::EmitTerminalImpl(IR::Term::LinkBlockFast terminal, IR::Location |
|
|
EmitPatchJmp(terminal.next); |
|
|
EmitPatchJmp(terminal.next); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor, bool is_single_step) { |
|
|
void A64EmitX64::EmitTerminalImpl(IR::Term::PopRSBHint, IR::LocationDescriptor, bool is_single_step) { |
|
|
if (!conf.HasOptimization(OptimizationFlag::ReturnStackBuffer) || is_single_step) { |
|
|
if (!conf.HasOptimization(OptimizationFlag::ReturnStackBuffer) || is_single_step) { |
|
|
|