Mercurial > hg > CbC > old > device
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) |