diff --git a/src/backend/x64/a32_emit_x64.cpp b/src/backend/x64/a32_emit_x64.cpp index 887ad583..55c75bbb 100644 --- a/src/backend/x64/a32_emit_x64.cpp +++ b/src/backend/x64/a32_emit_x64.cpp @@ -770,6 +770,15 @@ void A32EmitX64::EmitA32BXWritePC(A32EmitContext& ctx, IR::Inst* inst) { } } +void A32EmitX64::EmitA32UpdateUpperLocationDescriptor(A32EmitContext& ctx, IR::Inst*) { + for (auto& inst : ctx.block) { + if (inst.GetOpcode() == IR::Opcode::A32BXWritePC) { + return; + } + } + EmitSetUpperLocationDescriptor(ctx.EndLocation(), ctx.Location()); +} + void A32EmitX64::EmitA32CallSupervisor(A32EmitContext& ctx, IR::Inst* inst) { ctx.reg_alloc.HostCall(nullptr); diff --git a/src/frontend/A32/ir_emitter.cpp b/src/frontend/A32/ir_emitter.cpp index ca1e91fe..024d9e0d 100644 --- a/src/frontend/A32/ir_emitter.cpp +++ b/src/frontend/A32/ir_emitter.cpp @@ -121,6 +121,10 @@ void IREmitter::LoadWritePC(const IR::U32& value) { } } +void IREmitter::UpdateUpperLocationDescriptor() { + Inst(Opcode::A32UpdateUpperLocationDescriptor); +} + void IREmitter::CallSupervisor(const IR::U32& value) { Inst(Opcode::A32CallSupervisor, value); } diff --git a/src/frontend/A32/ir_emitter.h b/src/frontend/A32/ir_emitter.h index 57aa40d2..8d3d8df3 100644 --- a/src/frontend/A32/ir_emitter.h +++ b/src/frontend/A32/ir_emitter.h @@ -47,6 +47,7 @@ public: void BranchWritePC(const IR::U32& value); void BXWritePC(const IR::U32& value); void LoadWritePC(const IR::U32& value); + void UpdateUpperLocationDescriptor(); void CallSupervisor(const IR::U32& value); void ExceptionRaised(Exception exception); diff --git a/src/frontend/ir/microinstruction.cpp b/src/frontend/ir/microinstruction.cpp index ac6d8152..3658aa74 100644 --- a/src/frontend/ir/microinstruction.cpp +++ b/src/frontend/ir/microinstruction.cpp @@ -155,6 +155,7 @@ bool Inst::ReadsFromCPSR() const { case Opcode::A32GetCFlag: case Opcode::A32GetVFlag: case Opcode::A32GetGEFlags: + case Opcode::A32UpdateUpperLocationDescriptor: case Opcode::A64GetCFlag: case Opcode::A64GetNZCVRaw: case Opcode::ConditionalSelect32: @@ -179,6 +180,7 @@ bool Inst::WritesToCPSR() const { case Opcode::A32OrQFlag: case Opcode::A32SetGEFlags: case Opcode::A32SetGEFlagsCompressed: + case Opcode::A32UpdateUpperLocationDescriptor: case Opcode::A64SetNZCVRaw: case Opcode::A64SetNZCV: return true; diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index a81a792f..d68a5f5c 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -31,6 +31,7 @@ A32OPC(GetGEFlags, U32, A32OPC(SetGEFlags, Void, U32 ) A32OPC(SetGEFlagsCompressed, Void, U32 ) A32OPC(BXWritePC, Void, U32 ) +A32OPC(UpdateUpperLocationDescriptor, Void, ) A32OPC(CallSupervisor, Void, U32 ) A32OPC(ExceptionRaised, Void, U32, U64 ) A32OPC(DataSynchronizationBarrier, Void, )