• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

BASIC compiler/interpreter for PIC32MX/MZ-80K


Commit MetaInfo

修訂c6fc4cfbaca492f00f4aca9ddc27cce8efd3d377 (tree)
時間2019-02-05 07:10:30
作者Katsumi <kmorimatsu@sour...>
CommiterKatsumi

Log Message

Standardize arguments construction routines.

Change Summary

差異

--- /dev/null
+++ b/mips/megalopa/args.c
@@ -0,0 +1,108 @@
1+/*
2+ This file is provided under the LGPL license ver 2.1.
3+ Written by Katsumi.
4+ http://hp.vector.co.jp/authors/VA016157/
5+ kmorimatsu@users.sourceforge.jp
6+*/
7+
8+/*
9+ This file is shared by Megalopa and Zoea
10+*/
11+
12+#include "compiler.h"
13+
14+const unsigned int g_initial_s5_stack[3]={
15+ 0, // -8($s5): no object
16+ (unsigned int) &g_initial_s5_stack[2], // -4($s5): previous $s5 (recursive)
17+ 0 // 0($s5): no parameter
18+};
19+
20+static int g_args_stack;
21+/*
22+ See ARGS_SP_XXXX and ARGS_S5_XXXX in compiler.h
23+ At least 4 stacks are needed even without argument
24+ 4($sp) = -12($s5): $sp
25+ 8($sp) = -8($s5): $v0 - pointer to object or previous -8($s5)
26+ 12($sp) = -4($s5): previous $s5
27+ 16($sp) = 0($s5): number of arguments
28+ 20($sp) = 4($s5): first argument
29+ $v0 must be the pointer to an object before comming to this code.
30+ After this code, -12($s5) must be set to $sp: 0xAEBDFFF4 sw sp,-12(s5)
31+*/
32+char* prepare_args_stack(char start_char){
33+ // start_char is either ',' or '('
34+ // When ',' mode, there must be a ',' if argument(s) exist(s).
35+ // When '(' mode, there shouldn't be a '(', because this character has passed.
36+ char* err;
37+ int opos,stack;
38+ stack=0;
39+ opos=g_objpos;
40+ check_obj_space(2);
41+ g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx
42+ // 8(sp) is for $v0, which is pointer to an object
43+ g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp)
44+ next_position();
45+ do {
46+ if (!stack) {
47+ // First parameter if exists
48+ stack=16;
49+ if (start_char==','){
50+ if (g_source[g_srcpos]!=',') break;
51+ } else if (start_char=='('){
52+ if (g_source[g_srcpos]!='(') return ERR_SYNTAX;
53+ g_srcpos++;
54+ next_position();
55+ if (g_source[g_srcpos]==')') break;
56+ g_srcpos--;
57+ } else {
58+ return ERR_UNKNOWN;
59+ }
60+ }
61+ g_srcpos++;
62+ stack+=4;
63+ err=get_stringFloatOrValue();
64+ if (err) return err;
65+ check_obj_space(1);
66+ g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp)
67+ next_position();
68+ } while (g_source[g_srcpos]==',');
69+ // 12(sp) is for $s5, 16(sp) is for # of parameters
70+ check_obj_space(5);
71+ g_object[g_objpos++]=0xAFB5000C; // sw s5,12(sp)
72+ g_object[g_objpos++]=0x34020000|(stack/4-4); // ori v0,zero,xx
73+ g_object[g_objpos++]=0xAFA20010; // sw v0,16(sp)
74+ g_object[g_objpos++]=0x27B50010; // addiu s5,sp,16
75+ g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above)
76+ // All done. Register # of stacks to global var.
77+ g_args_stack=stack;
78+ return 0;
79+}
80+
81+char* remove_args_stack(void){
82+ // Remove stack
83+ check_obj_space(2);
84+ g_object[g_objpos++]=0x8FB5000C; // lw s5,12(sp)
85+ g_object[g_objpos++]=0x27BD0000|g_args_stack; // addiu sp,sp,xx
86+ return 0;
87+}
88+
89+char* args_function_main(void){
90+ char* err;
91+ int i;
92+ err=get_value();
93+ if (err) return err;
94+ i=g_object[g_objpos-1];
95+ if ((i>>16)==0x3402) {
96+ // Previous object is "ori v0,zero,xxxx".
97+ i&=0xffff;
98+ i=i<<2;
99+ g_object[g_objpos-1]=0x8EA20000|i; // lw v0,xx(s5)
100+ } else {
101+ check_obj_space(3);
102+ g_object[g_objpos++]=0x00021080; // sll v0,v0,0x2
103+ g_object[g_objpos++]=0x02A21021; // addu v0,s5,v0
104+ g_object[g_objpos++]=0x8C420000; // lw v0,0(v0)
105+ }
106+ return 0;
107+}
108+
--- a/mips/megalopa/class.c
+++ b/mips/megalopa/class.c
@@ -319,51 +319,22 @@ char* obj_method(int method){
319319 // Parameters preparation (to $s5) here.
320320 next_position();
321321 opos=g_objpos;
322-
323322 // Begin parameter(s) construction routine
324- // Note that this comment must be copied
325- // when inserting simiar routine to source
326-
327- stack=12;
328- g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx
329- // 4(sp) is for $v0 (pointer to object)
330- g_object[g_objpos++]=0xAFA20004; // sw v0,4(sp)
331- if (g_source[g_srcpos]!=')') {
332- g_srcpos--;
333- do {
334- g_srcpos++;
335- stack+=4;
336- err=get_stringFloatOrValue();
337- if (err) return err;
338- check_obj_space(1);
339- g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp)
340- next_position();
341- } while(g_source[g_srcpos]==',');
342- }
323+ err=prepare_args_stack('(');
324+ if (err) return err;
343325 if (g_source[g_srcpos]!=')') return ERR_SYNTAX;
344326 g_srcpos++;
345- // 8(sp) is for $s5, 12(sp) is for # of arguments
346- check_obj_space(4);
347- g_object[g_objpos++]=0xAFB50008; // sw s5,8(sp)
348- g_object[g_objpos++]=0x34020000|(stack/4-3); // ori v0,zero,xx
349- g_object[g_objpos++]=0xAFA2000C; // sw v0,12(sp)
350- g_object[g_objpos++]=0x27B50008; // addiu s5,sp,8
351- g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above)
352-
353- // End parameter(s) construction routine
354- // Note that this comment must be copied
355- // when inserting simiar routine to source
356-
357327 // Determine address of method and store fields to local variables.
358328 check_obj_space(3);
359- g_object[g_objpos++]=0x8FA20004; // lw v0,4(sp)
329+ g_object[g_objpos++]=0x8FA20000|ARGS_SP_V0_OBJ; // lw v0,8(sp)
360330 g_object[g_objpos++]=0x3C050000|((method>>16)&0x0000FFFF); // lui a1,xxxx
361331 g_object[g_objpos++]=0x34A50000|(method&0x0000FFFF); // ori a1,a1,xxxx
362332 call_quicklib_code(lib_pre_method,ASM_ADDU_A0_V0_ZERO);
363333 // Call method address here. Same routine for GOSUB statement with integer value is used.
364334 check_obj_space(6);
365- g_object[g_objpos++]=0x04130003; // bgezall zero,label1
366335 g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4
336+ g_object[g_objpos++]=0x04130003; // bgezall zero,label1
337+ g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5)
367338 g_object[g_objpos++]=0x10000003; // beq zero,zero,label2
368339 g_object[g_objpos++]=0x00000000; // nop
369340 // label1:
@@ -371,14 +342,11 @@ char* obj_method(int method){
371342 g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp) // label2:
372343 // Restore fields from local variables.
373344 check_obj_space(3);
374- g_object[g_objpos++]=0x8FA40004; // lw a0,4(sp)
375- g_object[g_objpos++]=0x3C050000|((method>>16)&0x0000FFFF); // lui a1,xxxx
376- g_object[g_objpos++]=0x34A50000|(method&0x0000FFFF); // ori a1,a1,xxxx
377- call_quicklib_code(lib_post_method,ASM_ADDU_A2_V0_ZERO);
345+ g_object[g_objpos++]=0x8FA40008; // lw a0,8(sp)
346+ call_quicklib_code(lib_post_method,ASM_ADDU_A1_V0_ZERO);
378347 // Remove stack
379- check_obj_space(2);
380- g_object[g_objpos++]=0x8FB50008; // lw s5,8(sp)
381- g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx
348+ err=remove_args_stack();
349+ if (err) return err;
382350 return 0;
383351 }
384352
@@ -402,17 +370,15 @@ char* _obj_field(char mode){
402370 int i;
403371 char* err;
404372 do {
405- i=check_var_name(); // TODO: consider accepting reserbed var names for field name
373+ i=check_var_name();
406374 if (i<65536) return ERR_SYNTAX;
407375 if (g_source[g_srcpos]=='(' && mode==OBJ_FIELD_INTEGER) {
408376 // This is a method
409- g_srcpos++;
410377 return obj_method(i);
411378 } else if (g_source[g_srcpos+1]=='(') {
412379 if (g_source[g_srcpos]==mode) {
413380 // This is a string/float method
414381 g_srcpos++;
415- g_srcpos++;
416382 return obj_method(i);
417383 }
418384 } else if (g_source[g_srcpos]==mode && mode==OBJ_FIELD_STRING) {
@@ -539,8 +505,8 @@ int lib_pre_method(int* object, int methodname){
539505 return class[1];
540506 }
541507
542-int lib_post_method(int* object, int methodname, int v0){
543- // Note that existence of the method was checked in above function before reaching this function.
508+int lib_post_method(int* object, int v0){
509+ // Note that v0 (a1) contains the return value from a method.
544510 int i,num,nums;
545511 int* class;
546512 // Restore local variables to object field values
@@ -706,51 +672,25 @@ char* static_method(char type){
706672
707673 }
708674 if (g_source[g_srcpos]!='(') return ERR_SYNTAX;
709- g_srcpos++;
710-
711675 // Begin parameter(s) construction routine
712- // Note that this comment must be copied
713- // when inserting simiar routine to source
714-
715- stack=8;
716- opos=g_objpos;
717- g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx
718- while(g_source[g_srcpos]==',') {
719- g_srcpos++;
720- stack+=4;
721- err=get_stringFloatOrValue();
722- if (err) return err;
723- check_obj_space(1);
724- g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp)
725- next_position();
726- }
727- // 4(sp) is for $s5, 8(sp) is for # of parameters
728- check_obj_space(5);
729- g_object[g_objpos++]=0xAFB50004; // sw s5,4(sp)
730- g_object[g_objpos++]=0x34020000|(stack/4-2); // ori v0,zero,xx
731- g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp)
732- g_object[g_objpos++]=0x27B50004; // addiu s5,sp,4
733- g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above)
734-
735- // End parameter(s) construction routine
736- // Note that this comment must be copied
737- // when inserting simiar routine to source
738-
676+ check_obj_space(1);
677+ g_object[g_objpos++]=0x34020000; // ori v0,zero,0
678+ err=prepare_args_stack('(');
679+ if (err) return err;
739680 // Calling subroutine, which is static method of class
740- check_obj_space(6);
741- g_object[g_objpos++]=0x04130003; // bgezall zero,label1
681+ check_obj_space(7);
742682 g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4
683+ g_object[g_objpos++]=0x04130003; // bgezall zero,label1
684+ g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5)
743685 g_object[g_objpos++]=0x10000003; // beq zero,zero,label2
744686 g_object[g_objpos++]=0x00000000; // nop
745687 // label1:
746688 g_object[g_objpos++]=0x08000000|((method&0x0FFFFFFF)>>2); // j xxxx
747689 g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp)
748- // label2:
690+ // label2:
749691 // Remove stack
750- check_obj_space(2);
751- g_object[g_objpos++]=0x8FB50004; // lw s5,4(sp)
752- g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx
753-
692+ err=remove_args_stack();
693+ if (err) return err;
754694 return 0;
755695 }
756696
--- a/mips/megalopa/compiler.c
+++ b/mips/megalopa/compiler.c
@@ -57,6 +57,8 @@ void start_program(void* addr, void* memory){
5757 asm volatile("la $v0,%0"::"i"(&g_end_addr));
5858 asm volatile("la $v1,label");
5959 asm volatile("sw $v1,0($v0)");
60+ // Set s5 for initial_s5_stack
61+ asm volatile("la $s5,%0"::"i"(&g_initial_s5_stack[2]));
6062 // Set s7 for easy calling call_library()
6163 asm volatile("la $s7,%0"::"i"(&call_library));
6264 // Set fp and execute program
--- a/mips/megalopa/compiler.h
+++ b/mips/megalopa/compiler.h
@@ -335,6 +335,11 @@ char* update_class_info(int class);
335335 char* construct_class_structure(int class);
336336 void delete_cmpdata_for_class();
337337
338+extern const unsigned int g_initial_s5_stack[3];
339+char* prepare_args_stack(char start_char);
340+char* remove_args_stack(void);
341+char* args_function_main(void);
342+
338343 char* begin_compiling_class(int class);
339344 char* end_compiling_class(int class);
340345 char* new_function();
@@ -344,7 +349,7 @@ char* string_obj_field();
344349 char* float_obj_field();
345350 int lib_obj_field(int* object, int fieldname);
346351 int lib_pre_method(int* object, int methodname);
347-int lib_post_method(int* object, int methodname, int v0);
352+int lib_post_method(int* object, int v0);
348353 char* method_statement();
349354 char* delete_statement();
350355 char* call_statement();
@@ -391,6 +396,16 @@ char* static_method(char type);
391396 #define CMPDATA_FIELD 3
392397 #define CMPDATA_STATIC 4
393398
399+/* Stack position for values in args.c */
400+#define ARGS_SP_SP 4
401+#define ARGS_SP_V0_OBJ 8
402+#define ARGS_SP_PREV_S5 12
403+#define ARGS_SP_NUM_ARGS 16
404+#define ARGS_S5_SP (-12 & 0xFFFF)
405+#define ARGS_S5_V0_OBJ (-8 & 0xFFFF)
406+#define ARGS_S5_PREV_S5 (-4 & 0xFFFF)
407+#define ARGS_S5_NUM_ARGS (0 & 0xFFFF)
408+
394409 /*
395410 Hidden varname 31 bit values
396411 Note that max number of 31 bit value is 0x61504BFF (for ZZZZZZ)
--- a/mips/megalopa/debug.c
+++ b/mips/megalopa/debug.c
@@ -229,26 +229,14 @@ static const char bastext[]=
229229 "USECLASS CLASS1\n"
230230 "CLS\n"
231231 "a=new(CLASS1)\n"
232-"call a.INIT(123,456)\n"
233-"CLASS1::TEST=123\n"
234-"CLASS1::TEST2=456\n"
235-"print CLASS1::TEST3(),\n"
236-"print CLASS1::TEST4#(),\n"
237-"print CLASS1::TEST5$(),\n"
232+"b=new(CLASS1)\n"
233+"call a.TEST4(123)\n"
234+"call b.TEST4(456)\n"
235+"print a.TEST7(),b.TEST7()\n"
238236 "\n"
239237 "\n"
240238 "\n"
241239 "\n"
242-"end\n"
243-"for i=1 to 150\n"
244-" a=new(CLASS1)\n"
245-" delete a\n"
246-" cursor 0,0\n"
247-" print i,\n"
248-"next\n"
249-"\n"
250-"\n"
251-"\n"
252240 "\n"
253241 "\n";
254242
@@ -256,13 +244,18 @@ static const char bastext[]=
256244 static const char classtext[]=
257245 "REM\n"
258246 "STATIC TEST,TEST2\n"
247+"FIELD PRIVATE TEST6\n"
259248 "METHOD TEST3\n"
249+" for i=-2 to 2:print args(i),:next\n"
250+" print\n"
260251 "return TEST+TEST2\n"
261252 "METHOD TEST4\n"
253+" TEST6=args(1)\n"
262254 "return 3.14\n"
263255 "METHOD TEST5\n"
264256 "return hex$(0xabc)\n"
265-"\n"
257+"METHOD TEST7\n"
258+"return TEST6\n"
266259 "\n"
267260 "\n"
268261 "\n"
@@ -282,8 +275,9 @@ static const void* debugjumptable[]={
282275 int _debug_test(int a0, int a1, int a2, int a3, int param4, int param5){
283276 asm volatile(".set noreorder");
284277 asm volatile("lw $a0,0($v1)");
285- asm volatile("nop");
286- asm volatile("nop");
278+ asm volatile("sw $sp,-12($s5)");
279+ asm volatile("lw $sp,-12($s5)");
280+ asm volatile("lw $v0,-8($s5)");
287281 asm volatile("nop");
288282 asm volatile("nop");
289283 asm volatile("nop");
--- a/mips/megalopa/function.c
+++ b/mips/megalopa/function.c
@@ -261,23 +261,7 @@ char* inkey_function(void){
261261 }
262262
263263 char* args_function(void){
264- char* err;
265- int i;
266- err=get_value();
267- if (err) return err;
268- i=g_object[g_objpos-1];
269- if ((i>>16)==0x3402) {
270- // Previous object is "ori v0,zero,xxxx".
271- i&=0xffff;
272- i=(i+1)<<2;
273- g_object[g_objpos-1]=0x8EA20000|i; // lw v0,xx(s5)
274- } else {
275- check_obj_space(3);
276- g_object[g_objpos++]=0x00021080; // sll v0,v0,0x2
277- g_object[g_objpos++]=0x02A21021; // addu v0,s5,v0
278- g_object[g_objpos++]=0x8C420004; // lw v0,4(v0)
279- }
280- return 0;
264+ return args_function_main();
281265 }
282266
283267 char* system_function(void){
--- a/mips/megalopa/megalopa.mcp
+++ b/mips/megalopa/megalopa.mcp
@@ -70,6 +70,7 @@ file_042=.
7070 file_043=.
7171 file_044=.
7272 file_045=.
73+file_046=.
7374 [GENERATED_FILES]
7475 file_000=no
7576 file_001=no
@@ -117,6 +118,7 @@ file_042=no
117118 file_043=no
118119 file_044=no
119120 file_045=no
121+file_046=no
120122 [OTHER_FILES]
121123 file_000=no
122124 file_001=no
@@ -160,10 +162,11 @@ file_038=no
160162 file_039=no
161163 file_040=no
162164 file_041=no
163-file_042=yes
165+file_042=no
164166 file_043=yes
165167 file_044=yes
166168 file_045=yes
169+file_046=yes
167170 [FILE_INFO]
168171 file_000=compiler.c
169172 file_001=debug.c
@@ -192,25 +195,26 @@ file_023=io.c
192195 file_024=i2c.c
193196 file_025=spi.c
194197 file_026=class.c
195-file_027=api.h
196-file_028=compiler.h
197-file_029=debug.h
198-file_030=editor.h
199-file_031=keyinput.h
200-file_032=main.h
201-file_033=ps2keyboard.h
202-file_034=sdfsio370f.h
203-file_035=lib_video_megalopa.h
204-file_036=envspecific.h
205-file_037=io.h
206-file_038=ps2keyboard370f.X.a
207-file_039=sdfsio370fLib.X.a
208-file_040=lib_videoout_megalopa.X.a
209-file_041=app_p32MX370F512H.ld
210-file_042=help.txt
211-file_043=reservednames.js
212-file_044=class.txt
213-file_045=sharedfiles.js
198+file_027=args.c
199+file_028=api.h
200+file_029=compiler.h
201+file_030=debug.h
202+file_031=editor.h
203+file_032=keyinput.h
204+file_033=main.h
205+file_034=ps2keyboard.h
206+file_035=sdfsio370f.h
207+file_036=lib_video_megalopa.h
208+file_037=envspecific.h
209+file_038=io.h
210+file_039=ps2keyboard370f.X.a
211+file_040=sdfsio370fLib.X.a
212+file_041=lib_videoout_megalopa.X.a
213+file_042=app_p32MX370F512H.ld
214+file_043=help.txt
215+file_044=reservednames.js
216+file_045=class.txt
217+file_046=sharedfiles.js
214218 [SUITE_INFO]
215219 suite_guid={62D235D8-2DB2-49CD-AF24-5489A6015337}
216220 suite_state=
--- a/mips/megalopa/statement.c
+++ b/mips/megalopa/statement.c
@@ -359,9 +359,10 @@ char* gosub_statement_sub(){
359359 // Label/number is constant.
360360 // Linker will change following codes later.
361361 // Note that 0x0812xxxx and 0x0813xxxx are specific codes for these.
362- check_obj_space(6);
363- g_object[g_objpos++]=0x04130003; // bgezall zero,label1
362+ check_obj_space(7);
364363 g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4
364+ g_object[g_objpos++]=0x04130003; // bgezall zero,label1
365+ g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5)
365366 g_object[g_objpos++]=0x10000003; // beq zero,zero,label2
366367 g_object[g_objpos++]=0x08120000|((g_label>>16)&0x0000FFFF); // nop
367368 // label1:
@@ -373,15 +374,16 @@ char* gosub_statement_sub(){
373374 err=get_value();
374375 if (err) return err;
375376 call_lib_code(LIB_LABEL);
376- check_obj_space(6);
377- g_object[g_objpos++]=0x04130003; // bgezall zero,label1
378- g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4
379- g_object[g_objpos++]=0x10000003; // beq zero,zero,label2
380- g_object[g_objpos++]=0x00000000; // nop
381- // label1:
382- g_object[g_objpos++]=0x00400008; // jr v0
383- g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp)
384- // label2:
377+ check_obj_space(7);
378+ g_object[g_objpos++]=0x27BDFFFC; // addiu sp,sp,-4
379+ g_object[g_objpos++]=0x04130003; // bgezall zero,label1
380+ g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5)
381+ g_object[g_objpos++]=0x10000003; // beq zero,zero,label2
382+ g_object[g_objpos++]=0x00000000; // nop
383+ // label1:
384+ g_object[g_objpos++]=0x00400008; // jr v0
385+ g_object[g_objpos++]=0xAFBF0004; // sw ra,4(sp)
386+ // label2:
385387 }
386388 return 0;
387389 }
@@ -397,34 +399,10 @@ char* gosub_statement(){
397399 next_position();
398400 // Rewind object and construct argument-creating routine.
399401 g_objpos=opos;
400-
401402 // Begin parameter(s) construction routine
402- // Note that this comment must be copied
403- // when inserting simiar routine to source
404-
405- stack=8;
406- g_object[g_objpos++]=0x27BD0000; // addiu sp,sp,-xx
407- while(g_source[g_srcpos]==',') {
408- g_srcpos++;
409- stack+=4;
410- err=get_stringFloatOrValue();
411- if (err) return err;
412- check_obj_space(1);
413- g_object[g_objpos++]=0xAFA20000|stack; // sw v0,xx(sp)
414- next_position();
415- }
416- // 4(sp) is for $s5, 8(sp) is for # of parameters
417- check_obj_space(5);
418- g_object[g_objpos++]=0xAFB50004; // sw s5,4(sp)
419- g_object[g_objpos++]=0x34020000|(stack/4-2); // ori v0,zero,xx
420- g_object[g_objpos++]=0xAFA20008; // sw v0,8(sp)
421- g_object[g_objpos++]=0x27B50004; // addiu s5,sp,4
422- g_object[opos]|=((0-stack)&0xFFFF); // addiu sp,sp,-xx (See above)
423-
424- // End parameter(s) construction routine
425- // Note that this comment must be copied
426- // when inserting simiar routine to source
427-
403+ g_object[g_objpos++]=0x8EA20000|ARGS_S5_V0_OBJ; // lw v0,-8(s5)
404+ err=prepare_args_stack(',');
405+ if (err) return err;
428406 // Rewind source and construct GOSUB routine again.
429407 opos=spos;
430408 spos=g_srcpos;
@@ -432,9 +410,8 @@ char* gosub_statement(){
432410 err=gosub_statement_sub();
433411 if (err) return err;
434412 // Remove stack
435- check_obj_space(2);
436- g_object[g_objpos++]=0x8FB50004; // lw s5,4(sp)
437- g_object[g_objpos++]=0x27BD0000|stack; // addiu sp,sp,xx
413+ err=remove_args_stack();
414+ if (err) return err;
438415 // All done, go back to right source position
439416 g_srcpos=spos;
440417 return 0;
@@ -450,10 +427,11 @@ char* return_statement(){
450427 err=get_stringFloatOrValue();
451428 if (err) return err;
452429 }
453- check_obj_space(3);
454- g_object[g_objpos++]=0x8FA30004; // lw v1,4(sp)
455- g_object[g_objpos++]=0x00600008; // jr v1
456- g_object[g_objpos++]=0x27BD0004; // addiu sp,sp,4
430+ check_obj_space(4);
431+ g_object[g_objpos++]=0x8EBD0000|ARGS_S5_SP; // lw sp,-12(s5)
432+ g_object[g_objpos++]=0x8FA30004; // lw v1,4(sp)
433+ g_object[g_objpos++]=0x00600008; // jr v1
434+ g_object[g_objpos++]=0x27BD0004; // addiu sp,sp,4
457435 return 0;
458436 }
459437
@@ -1258,6 +1236,9 @@ char* var_statement(){
12581236 call_lib_code(LIB_VAR_PUSH);
12591237
12601238 } while (g_source[g_srcpos-1]==',');
1239+ // Renew sp stored in s5 stack.
1240+ check_obj_space(1);
1241+ g_object[g_objpos++]=0xAEBD0000|ARGS_S5_SP; // sw sp,-12(s5)
12611242 return 0;
12621243 }
12631244