File tree Expand file tree Collapse file tree 2 files changed +54
-2
lines changed Expand file tree Collapse file tree 2 files changed +54
-2
lines changed Original file line number Diff line number Diff line change @@ -947,7 +947,31 @@ func_t *add_func(char *func_name, bool synthesize)
947947 hashmap_put (FUNC_MAP , func_name , func );
948948 /* Use interned string for function name */
949949 strcpy (func -> return_def .var_name , intern_string (func_name ));
950- func -> stack_size = 4 ;
950+ /* Prepare space for function arguments and global pointer.
951+ *
952+ * For Arm architecture, the first four arguments are passed to r0 ~ r3,
953+ * and any additional arguments are passed to the stack.
954+ *
955+ * +-------------+ <-- sp + 20
956+ * | (val of ip) |
957+ * +-------------+ <-- sp + 16
958+ * | arg 8 |
959+ * +-------------+ <-- sp + 12
960+ * | arg 7 |
961+ * +-------------+ <-- sp + 8
962+ * | arg 6 |
963+ * +-------------+ <-- sp + 4
964+ * | arg 5 |
965+ * +-------------+ <-- sp
966+ *
967+ * However, register r12 (ip) holds the global pointer that points to
968+ * global stack, but this register may be changed after an external call.
969+ *
970+ * Therefore, the current strategy is preparing additional space for ip,
971+ * saves its orignal value to stack before an external call, and restore
972+ * it from the stack after the external function returns.
973+ * */
974+ func -> stack_size = 20 ;
951975
952976 if (synthesize )
953977 return func ;
Original file line number Diff line number Diff line change @@ -768,12 +768,40 @@ void reg_alloc(void)
768768 if (!callee_func -> num_params )
769769 spill_alive (bb , insn );
770770
771- if (dynlink )
771+ if (dynlink ) {
772772 callee_func -> is_used = true;
773+ if (!callee_func -> bbs ) {
774+ int ofs = 0 ;
775+ if (args > 4 ) {
776+ /* Store args to stack for Arm output */
777+ for (int i = 4 ; i < args ; i ++ ) {
778+ ir = bb_add_ph2_ir (bb , OP_store );
779+ ir -> src0 = i ;
780+ ir -> src1 = ofs ;
781+ ofs += 4 ;
782+ }
783+ }
784+ /* FIXME:
785+ * use a better way to preserve global pointer */
786+ ir = bb_add_ph2_ir (bb , OP_store );
787+ ir -> src0 = 12 ;
788+ ir -> src1 = 16 ;
789+ }
790+ }
773791
774792 ir = bb_add_ph2_ir (bb , OP_call );
775793 strcpy (ir -> func_name , insn -> str );
776794
795+ if (dynlink ) {
796+ if (!callee_func -> bbs ) {
797+ /* FIXME:
798+ * use a better way to restore global pointer */
799+ ir = bb_add_ph2_ir (bb , OP_load );
800+ ir -> dest = 12 ;
801+ ir -> src0 = 16 ;
802+ }
803+ }
804+
777805 is_pushing_args = false;
778806 args = 0 ;
779807
You can’t perform that action at this time.
0 commit comments