@@ -76,6 +76,13 @@ static inline unsigned cj_builder_scratch_capacity(void);
7676static inline void cj_builder_scratch_init (cj_builder_scratch * scratch );
7777static inline cj_operand cj_builder_scratch_acquire (cj_builder_scratch * scratch );
7878static inline void cj_builder_scratch_release (cj_builder_scratch * scratch );
79+ static inline unsigned cj_builder_arg_int_capacity (void );
80+ static inline void cj_builder_call_label (cj_ctx * ctx , cj_label target );
81+ static inline cj_operand
82+ cj_builder_call (cj_ctx * ctx , cj_builder_scratch * scratch , cj_label target ,
83+ const cj_operand * args , size_t arg_count );
84+ static inline cj_operand cj_builder_call_unary (cj_ctx * ctx , cj_builder_scratch * scratch ,
85+ cj_label target , cj_operand arg0 );
7986
8087#include <assert.h>
8188#include <stdint.h>
@@ -587,6 +594,15 @@ static inline unsigned cj_builder_scratch_capacity(void)
587594#endif
588595}
589596
597+ static inline unsigned cj_builder_arg_int_capacity (void )
598+ {
599+ #if defined(__x86_64__ ) || defined(_M_X64 )
600+ return 6 ;
601+ #elif defined(__aarch64__ ) || defined(_M_ARM64 )
602+ return 8 ;
603+ #endif
604+ }
605+
590606static inline void cj_builder_scratch_init (cj_builder_scratch * scratch )
591607{
592608 if (!scratch )
@@ -608,3 +624,50 @@ static inline void cj_builder_scratch_release(cj_builder_scratch *scratch)
608624 assert (scratch -> depth > 0 );
609625 scratch -> depth -- ;
610626}
627+
628+ static inline void cj_builder_call_label (cj_ctx * ctx , cj_label target )
629+ {
630+ #if defined(__x86_64__ ) || defined(_M_X64 )
631+ cj_call (ctx , target );
632+ #elif defined(__aarch64__ ) || defined(_M_ARM64 )
633+ cj_bl (ctx , target );
634+ #endif
635+ }
636+
637+ static inline cj_operand cj_builder_call_unary (cj_ctx * ctx , cj_builder_scratch * scratch ,
638+ cj_label target , cj_operand arg0 )
639+ {
640+ const cj_operand args [] = {arg0 };
641+ return cj_builder_call (ctx , scratch , target , args , 1 );
642+ }
643+
644+ static inline cj_operand
645+ cj_builder_call (cj_ctx * ctx , cj_builder_scratch * scratch , cj_label target ,
646+ const cj_operand * args , size_t arg_count )
647+ {
648+ if (!ctx )
649+ return cj_builder_return_reg ();
650+
651+ unsigned capacity = cj_builder_arg_int_capacity ();
652+ assert (arg_count <= capacity );
653+
654+ for (size_t i = 0 ; i < arg_count ; ++ i )
655+ {
656+ cj_operand reg = cj_builder_arg_int (ctx , (unsigned )i );
657+ cj_builder_assign (ctx , reg , args [i ]);
658+ }
659+
660+ if (scratch )
661+ cj_builder_scratch_release (scratch );
662+
663+ cj_builder_call_label (ctx , target );
664+
665+ if (scratch )
666+ {
667+ cj_operand dst = cj_builder_scratch_acquire (scratch );
668+ cj_builder_assign (ctx , dst , cj_builder_return_reg ());
669+ return dst ;
670+ }
671+
672+ return cj_builder_return_reg ();
673+ }
0 commit comments