88#include " cinderx/Jit/codegen/gen_asm_utils.h"
99#include " cinderx/Jit/frame.h"
1010#include " cinderx/Jit/generators_rt.h"
11+ #include " cinderx/Jit/hir/hir.h"
1112#include " cinderx/Jit/jit_rt.h"
1213#include " cinderx/Jit/lir/instruction.h"
1314#include " cinderx/Jit/lir/printer.h"
@@ -823,23 +824,64 @@ void translateYieldValue(Environ* env, const Instruction* instr) {
823824 PhyLocation value_out = instr->getInput (1 )->getStackSlot ();
824825 as->mov (x86::rax, x86::ptr (x86::rbp, value_out.loc ));
825826 }
827+ #elif defined(CINDER_AARCH64)
828+ a64::Builder* as = env->as ;
826829
827- // Arbitrary scratch register for use in emitStoreGenYieldPoint()
830+ // Value to send goes to x0 so it can be yielded (returned) by epilogue.
831+ if (instr->getInput (1 )->isImm ()) {
832+ as->mov (a64::x0, instr->getInput (1 )->getConstant ());
833+ } else {
834+ PhyLocation value_out = instr->getInput (1 )->getStackSlot ();
835+ as->ldr (
836+ a64::x0,
837+ arch::ptr_resolve (as, arch::fp, value_out.loc , arch::reg_scratch_0));
838+ }
839+ #else
840+ CINDER_UNSUPPORTED
841+ #endif
842+ }
843+
844+ void translateStoreGenYieldPoint (Environ* env, const Instruction* instr) {
845+ #if defined(CINDER_X86_64)
846+ arch::Builder* as = env->as ;
828847 auto scratch_r = x86::r9;
829- auto resume_label = as->newLabel ();
830- emitStoreGenYieldPoint (as, env, instr, resume_label, x86::rbp, scratch_r);
848+ env->pending_yield_resume_label = as->newLabel ();
849+ emitStoreGenYieldPoint (
850+ as, env, instr, env->pending_yield_resume_label , x86::rbp, scratch_r);
851+ #elif defined(CINDER_AARCH64)
852+ a64::Builder* as = env->as ;
853+ auto scratch_r = arch::reg_scratch_0;
854+ env->pending_yield_resume_label = as->newLabel ();
855+ emitStoreGenYieldPoint (
856+ as, env, instr, env->pending_yield_resume_label , arch::fp, scratch_r);
857+ #else
858+ CINDER_UNSUPPORTED
859+ #endif
860+ }
831861
832- // Jump to epilogue
833- as->jmp (env->exit_for_yield_label );
862+ void translateBranchToYieldExit (Environ* env, const Instruction*) {
863+ #if defined(CINDER_X86_64)
864+ env->as ->jmp (env->exit_for_yield_label );
865+ #elif defined(CINDER_AARCH64)
866+ env->as ->b (env->exit_for_yield_label );
867+ #else
868+ CINDER_UNSUPPORTED
869+ #endif
870+ }
871+
872+ void translateResumeGenYield (Environ* env, const Instruction* instr) {
873+ #if defined(CINDER_X86_64)
874+ arch::Builder* as = env->as ;
834875
835876 // Resumed execution in this generator begins here
836- as->bind (resume_label );
877+ as->bind (env-> pending_yield_resume_label );
837878
838879#if PY_VERSION_HEX < 0x030C0000
839880 // On 3.10, for yield-from yield points, store the finish_yield_from arg
840881 // (RDX from resume entry) into GenDataFooter so the subsequent Send
841882 // instruction can load it.
842- if (instr->isInYieldFromContext ()) {
883+ if (instr->origin () &&
884+ static_cast <const hir::YieldValue*>(instr->origin ())->isYieldFrom ()) {
843885 auto fyf_offset = offsetof (GenDataFooter, finishYieldFrom);
844886 as->mov (x86::qword_ptr (x86::rbp, fyf_offset), x86::rdx);
845887 }
@@ -850,32 +892,15 @@ void translateYieldValue(Environ* env, const Instruction* instr) {
850892#elif defined(CINDER_AARCH64)
851893 a64::Builder* as = env->as ;
852894
853- // Value to send goes to x0 so it can be yielded (returned) by epilogue.
854- if (instr->getInput (1 )->isImm ()) {
855- as->mov (a64::x0, instr->getInput (1 )->getConstant ());
856- } else {
857- PhyLocation value_out = instr->getInput (1 )->getStackSlot ();
858- as->ldr (
859- a64::x0,
860- arch::ptr_resolve (as, arch::fp, value_out.loc , arch::reg_scratch_0));
861- }
862-
863- // Arbitrary scratch register for use in emitStoreGenYieldPoint()
864- auto scratch_r = arch::reg_scratch_0;
865- auto resume_label = as->newLabel ();
866- emitStoreGenYieldPoint (as, env, instr, resume_label, arch::fp, scratch_r);
867-
868- // Jump to epilogue
869- as->b (env->exit_for_yield_label );
870-
871895 // Resumed execution in this generator begins here
872- as->bind (resume_label );
896+ as->bind (env-> pending_yield_resume_label );
873897
874898#if PY_VERSION_HEX < 0x030C0000
875899 // On 3.10, for yield-from yield points, store the finish_yield_from arg
876900 // (X2 from resume entry) into GenDataFooter so the subsequent Send
877901 // instruction can load it.
878- if (instr->isInYieldFromContext ()) {
902+ if (instr->origin () &&
903+ static_cast <const hir::YieldValue*>(instr->origin ())->isYieldFrom ()) {
879904 auto fyf_offset = offsetof (GenDataFooter, finishYieldFrom);
880905 as->str (
881906 a64::x2,
@@ -1702,6 +1727,18 @@ BEGIN_RULES(Instruction::kYieldValue)
17021727 GEN (ANY , CALL_C (translateYieldValue))
17031728END_RULES
17041729
1730+ BEGIN_RULES (Instruction::kStoreGenYieldPoint )
1731+ GEN (ANY , CALL_C (translateStoreGenYieldPoint))
1732+ END_RULES
1733+
1734+ BEGIN_RULES (Instruction::kBranchToYieldExit )
1735+ GEN (ANY , CALL_C (translateBranchToYieldExit))
1736+ END_RULES
1737+
1738+ BEGIN_RULES (Instruction::kResumeGenYield )
1739+ GEN (ANY , CALL_C (translateResumeGenYield))
1740+ END_RULES
1741+
17051742BEGIN_RULES (Instruction::kYieldExitPoint )
17061743 GEN (ANY , CALL_C (translateYieldExitPoint))
17071744END_RULES
@@ -2993,6 +3030,18 @@ BEGIN_RULES(Instruction::kYieldValue)
29933030 GEN (ANY , CALL_C (translateYieldValue))
29943031END_RULES
29953032
3033+ BEGIN_RULES (Instruction::kStoreGenYieldPoint )
3034+ GEN (ANY , CALL_C (translateStoreGenYieldPoint))
3035+ END_RULES
3036+
3037+ BEGIN_RULES (Instruction::kBranchToYieldExit )
3038+ GEN (ANY , CALL_C (translateBranchToYieldExit))
3039+ END_RULES
3040+
3041+ BEGIN_RULES (Instruction::kResumeGenYield )
3042+ GEN (ANY , CALL_C (translateResumeGenYield))
3043+ END_RULES
3044+
29963045BEGIN_RULES (Instruction::kYieldExitPoint )
29973046 GEN (ANY , CALL_C (translateYieldExitPoint))
29983047END_RULES
0 commit comments