comparison mc-code-mips.c @ 376:d81e1be4036f lvar-offset-done

frame offset fix MIPS
author kono
date Mon, 12 Jul 2004 12:37:18 +0900
parents 9bc42f69f653
children b3c6c479c522
comparison
equal deleted inserted replaced
375:91849fdeea60 376:d81e1be4036f
1 /* Micro-C Code Generation Part for Power PC (Mac OS X) */ 1 /* Micro-C Code Generation Part for MIPS (ps2linux) */
2 /* $Id$ */ 2 /* $Id$ */
3 3
4 4
5 #include <stdio.h> 5 #include <stdio.h>
6 #include "mc.h" 6 #include "mc.h"
314 *SIZE_OF_INT *SIZE_OF_INT 314 *SIZE_OF_INT *SIZE_OF_INT
315 prev $sp=$fp $fp $sp 315 prev $sp=$fp $fp $sp
316 316
317 317
318 <-------r1_offset------------------------------> 318 <-------r1_offset------------------------------>
319 <------------lvar_offset-------> 319 <--lvar_offset-->
320 <-arg_offset-> 320 <-arg_offset->
321 r+ +-----------+----+---------------+----------+-------------+----+ 321 r+ +-----------+----+---------------+----------+-------------+----+
322 callee arg xxx register save local caller arg xxx 322 callee arg xxx register save local caller arg xxx
323 ($r31)($fp) reg_save disp max_func_args*SIZE_OF_INT 323 ($r31)($fp) reg_save disp max_func_args*SIZE_OF_INT
324 lvar>0 lvar<0 lvar>0x1000 0000 324 lvar>0 lvar<0 lvar>0x1000 0000
325 prev $sp=$fp $sp=$fp 325 prev $fp prev $sp $fp $sp
326 */ 326 */
327 327
328 #define arg_offset 8 328 #define arg_offset 8
329 #define arg_offset1 0 329 #define arg_offset1 0
330 int disp_offset = 0; 330 int disp_offset = 0;
353 r1_offsetv = lvar_offsetv + arg_offset + SIZE_OF_INT*2 + 353 r1_offsetv = lvar_offsetv + arg_offset + SIZE_OF_INT*2 +
354 max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+2*SIZE_OF_INT ; 354 max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+2*SIZE_OF_INT ;
355 lvar_offsetv += round16(r1_offsetv)-r1_offsetv; 355 lvar_offsetv += round16(r1_offsetv)-r1_offsetv;
356 r1_offsetv = round16(r1_offsetv); 356 r1_offsetv = round16(r1_offsetv);
357 357
358 #if 0 358 #if 1
359 printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n", 359 printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n",
360 round16(-disp), 360 round16(-disp),
361 max_reg_var+2, 361 max_reg_var+2,
362 max_freg_var, 362 max_freg_var,
363 round16(max_func_args*SIZE_OF_INT), 363 round16(max_func_args*SIZE_OF_INT),
388 fprintf(asi,"$L_%d=0x%x\n",fmask_label,code_fmask()); 388 fprintf(asi,"$L_%d=0x%x\n",fmask_label,code_fmask());
389 fprintf(asi,"$L_%d=%d\n",fmask_offset_label,code_fmask_offset()); 389 fprintf(asi,"$L_%d=%d\n",fmask_offset_label,code_fmask_offset());
390 fprintf(asi,"$L_%d=%d\n",cprestore_label , 390 fprintf(asi,"$L_%d=%d\n",cprestore_label ,
391 round16((max_func_args>2?max_func_args:2)*SIZE_OF_INT)); 391 round16((max_func_args>2?max_func_args:2)*SIZE_OF_INT));
392 fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv); 392 fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv);
393 fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv); 393 fprintf(asi,"$L_%d=%d\n",lvar_offset_label,r1_offsetv-lvar_offsetv);
394 394
395 return r1_offsetv; 395 return r1_offsetv;
396 } 396 }
397 397
398 static void 398 static void
402 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 402 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
403 printf("%d($sp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 403 printf("%d($sp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
404 } else 404 } else
405 printf("%d($fp)\n",CODE_LVAR(l)); 405 printf("%d($fp)\n",CODE_LVAR(l));
406 } else if (l<0) { /* local variable */ 406 } else if (l<0) { /* local variable */
407 printf("%d+$L_%d($fp)\n",FUNC_LVAR(l),lvar_offset_label); 407 printf("%d($fp)\n",FUNC_LVAR(l));
408 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 408 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
409 printf("%d($sp)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); 409 printf("%d($sp)\n",CALLER_ARG(l-ARG_LVAR_OFFSET));
410 } else { /* callee's arguments */ 410 } else { /* callee's arguments */
411 printf("%d+$L_%d($fp)\n",CALLEE_ARG(l),r1_offset_label); 411 printf("%d+$L_%d($fp)\n",CALLEE_ARG(l),lvar_offset_label);
412 } 412 }
413 } 413 }
414 414
415 static void 415 static void
416 lvar_address(int l,int creg) 416 lvar_address(int l,int creg)
420 printf("\taddu\t%s,$sp,%d\n", 420 printf("\taddu\t%s,$sp,%d\n",
421 register_name(creg),CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); 421 register_name(creg),CODE_CALLER_ARG(l-ARG_LVAR_OFFSET));
422 } else 422 } else
423 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR(l)); 423 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR(l));
424 } else if (l<0) { /* local variable */ 424 } else if (l<0) { /* local variable */
425 printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg), 425 printf("\taddu\t%s,$fp,%d\n",register_name(creg),
426 FUNC_LVAR(l),lvar_offset_label); 426 FUNC_LVAR(l));
427 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ 427 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */
428 printf("\taddu\t%s,$sp,%d\n", 428 printf("\taddu\t%s,$sp,%d\n",
429 register_name(creg),CALLER_ARG(l-ARG_LVAR_OFFSET)); 429 register_name(creg),CALLER_ARG(l-ARG_LVAR_OFFSET));
430 } else { /* callee's arguments */ 430 } else { /* callee's arguments */
431 printf("\taddu\t%s,$fp,%d+$L_%d\n", 431 printf("\taddu\t%s,$fp,%d+$L_%d\n",
432 register_name(creg),CALLEE_ARG(l),r1_offset_label); 432 register_name(creg),CALLEE_ARG(l),lvar_offset_label);
433 } 433 }
434 } 434 }
435 435
436 436
437 #define lvar_intro(e) /* do nothing */ 437 #define lvar_intro(e) /* do nothing */
1400 #if R1SAVE 1400 #if R1SAVE
1401 use_int(creg); 1401 use_int(creg);
1402 printf("\tlw %s,0($fp)\n",register_name(creg)); 1402 printf("\tlw %s,0($fp)\n",register_name(creg));
1403 #else 1403 #else
1404 use_int(creg); 1404 use_int(creg);
1405 #if 0
1405 printf("\taddu %s,",register_name(creg)); 1406 printf("\taddu %s,",register_name(creg));
1406 printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label); 1407 printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label);
1408 #else
1409 printf("\tmove %s,$fp\n",register_name(creg));
1410 #endif
1407 #endif 1411 #endif
1408 } 1412 }
1409 1413
1410 static int rexpr_bool(int e1, int reg); 1414 static int rexpr_bool(int e1, int reg);
1411 1415
2280 } 2284 }
2281 2285
2282 2286
2283 void 2287 void
2284 code_fix_frame_pointer(int offset) { 2288 code_fix_frame_pointer(int offset) {
2289 #if 0
2285 printf("\tla $fp,"); 2290 printf("\tla $fp,");
2286 printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label); 2291 printf("%d+$L_%d($sp)\n",FUNC_LVAR(0),lvar_offset_label);
2292 #endif
2287 } 2293 }
2288 2294
2289 // MIPS $25 (=$jp) contains calling function address. 2295 // MIPS $25 (=$jp) contains calling function address.
2290 // It is used in cpload $25 to get global address table $gp. 2296 // It is used in cpload $25 to get global address table $gp.
2291 2297
2930 static int 2936 static int
2931 code_register_save(int reg_save,int freg_save,int disp) 2937 code_register_save(int reg_save,int freg_save,int disp)
2932 { 2938 {
2933 int i; 2939 int i;
2934 for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) { 2940 for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) {
2935 printf("\tsw %s,$L_%d-%d($sp)\n",register_name(i), 2941 printf("\tsw %s,-%d($13)\n",register_name(i),
2936 r1_offset_label,-disp); 2942 -disp);
2937 disp -= SIZE_OF_INT; 2943 disp -= SIZE_OF_INT;
2938 } 2944 }
2939 for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) { 2945 for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) {
2940 printf("\ts.s %s,$L_%d-%d($sp)\n",register_name(i), 2946 printf("\ts.s %s,-%d($13)\n",register_name(i),
2941 r1_offset_label,-disp); 2947 -disp);
2942 disp -= SIZE_OF_FLOAT; 2948 disp -= SIZE_OF_FLOAT;
2943 } 2949 }
2944 return disp; 2950 return disp;
2945 } 2951 }
2946 2952
2947 static int 2953 static int
2948 code_register_restore(int reg_save,int freg_save,int disp) 2954 code_register_restore(int reg_save,int freg_save,int disp)
2949 { 2955 {
2950 int i; 2956 int i;
2951 for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) { 2957 for (i=reg_var_num(0);i>reg_var_num(reg_save);i--) {
2952 printf("\tlw %s,$L_%d-%d($sp)\n",register_name(i), 2958 printf("\tlw %s,-%d($13)\n",register_name(i),
2953 r1_offset_label,-disp); 2959 -disp);
2954 disp -= SIZE_OF_INT; 2960 disp -= SIZE_OF_INT;
2955 } 2961 }
2956 for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) { 2962 for (i=freg_var_num(0);i>freg_var_num(freg_save);i--) {
2957 printf("\tl.s %s,$L_%d-%d($sp)\n",register_name(i), 2963 printf("\tl.s %s,-%d($13)\n",register_name(i),
2958 r1_offset_label,-disp); 2964 -disp);
2959 disp -= SIZE_OF_FLOAT; 2965 disp -= SIZE_OF_FLOAT;
2960 } 2966 }
2961 return disp; 2967 return disp;
2962 } 2968 }
2963 2969
3052 3058
3053 if (stmode!=STATIC) 3059 if (stmode!=STATIC)
3054 printf("\t.globl\t%s\n",name); 3060 printf("\t.globl\t%s\n",name);
3055 printf(".ent %s\n",name); 3061 printf(".ent %s\n",name);
3056 printf("%s:\n",name); 3062 printf("%s:\n",name);
3057 printf("\t.frame $fp,$L_%d,$31\n",r1_offset_label=fwdlabel()); 3063 printf("\t.frame $sp,$L_%d,$31\n",r1_offset_label=fwdlabel());
3058 printf("\t.mask $L_%d,$L_%d\n",mask_label=fwdlabel(), 3064 printf("\t.mask $L_%d,$L_%d\n",mask_label=fwdlabel(),
3059 mask_offset_label=fwdlabel()); 3065 mask_offset_label=fwdlabel());
3060 printf("\t.fmask $L_%d,$L_%d\n",fmask_label=fwdlabel(), 3066 printf("\t.fmask $L_%d,$L_%d\n",fmask_label=fwdlabel(),
3061 fmask_offset_label=fwdlabel()); 3067 fmask_offset_label=fwdlabel());
3062 printf("\t.set noreorder\n"); 3068 printf("\t.set noreorder\n");
3063 printf("\t.cpload $25\n"); 3069 printf("\t.cpload $25\n");
3064 printf("\t.set reorder\n"); 3070 printf("\t.set reorder\n");
3071 printf("\tmove $13,$sp\n");
3065 printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label); 3072 printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label);
3066 printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel()); 3073 printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel());
3067 printf("\tsw $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset); 3074 printf("\tsw $31,-%d($13)\n",arg_offset);
3068 printf("\tsw $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT); 3075 printf("\tsw $fp,-%d($13)\n",arg_offset+SIZE_OF_INT);
3069 printf("\tj $L_%d\n",register_save_label=fwdlabel()); 3076 printf("\tj $L_%d\n",register_save_label=fwdlabel());
3070 register_save_return_label = backdef(); 3077 register_save_return_label = backdef();
3071 printf("\tmove $fp,$sp\n"); 3078 printf("\tsubu $fp,$13,$L_%d\n",lvar_offset_label);
3072 } 3079 }
3073 3080
3074 void 3081 void
3075 enter1() 3082 enter1()
3076 { 3083 {
3115 if (creg!=RET_REGISTER) 3122 if (creg!=RET_REGISTER)
3116 set_ireg(RET_REGISTER,1); 3123 set_ireg(RET_REGISTER,1);
3117 } 3124 }
3118 #if R1SAVE 3125 #if R1SAVE
3119 #else 3126 #else
3127 #if 0
3120 printf("\tsubu $fp,"); 3128 printf("\tsubu $fp,");
3121 printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label); 3129 printf("$fp,%d+$L_%d\n",FUNC_LVAR(0),lvar_offset_label);
3122 // printf("\tj $L_%d\n",retcont1); 3130 // printf("\tj $L_%d\n",retcont1);
3123 #endif 3131 #endif
3132 #endif
3124 } 3133 }
3125 fwddef(retlabel); 3134 fwddef(retlabel);
3126 // if (retcont) { 3135 // if (retcont) {
3127 // fwddef(retcont1); 3136 // fwddef(retcont1);
3128 // } 3137 // }
3129 3138
3130 r1_offsetv = code_offset_set(fnptr); 3139 r1_offsetv = code_offset_set(fnptr);
3131 3140
3132 printf("\tmove $sp,$fp\n"); 3141 printf("\taddu $13,$fp,$L_%d\n",lvar_offset_label);
3133 printf("\tlw $31,$L_%d-%d($sp)\n",r1_offset_label,arg_offset); 3142 printf("\tlw $31,-%d($13)\n",arg_offset);
3134 printf("\tlw $fp,$L_%d-%d($sp)\n",r1_offset_label,arg_offset+SIZE_OF_INT); 3143 printf("\tlw $fp,-%d($13)\n",arg_offset+SIZE_OF_INT);
3135 if (max_reg_var+max_freg_var) 3144 if (max_reg_var+max_freg_var)
3136 code_register_restore(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2); 3145 code_register_restore(max_reg_var,max_freg_var,-arg_offset-SIZE_OF_INT*2);
3137 printf("\taddu $sp,$sp,%d\n",r1_offsetv); 3146 printf("\tmove $sp,$13\n");
3138 printf("\tj $31\n"); 3147 printf("\tj $31\n");
3139 3148
3140 // leave part end 3149 // leave part end
3141 3150
3142 // entry part (save register) 3151 // entry part (save register)