Mercurial > hg > CbC > old > device
comparison mc-code-mips.c @ 252:1452eb0eab20
*** empty log message ***
author | kono |
---|---|
date | Wed, 12 May 2004 19:13:19 +0900 |
parents | fb6efe8ff816 |
children | 7b2762739df6 |
comparison
equal
deleted
inserted
replaced
251:fb6efe8ff816 | 252:1452eb0eab20 |
---|---|
25 static int creg; | 25 static int creg; |
26 | 26 |
27 static int output_mode = TEXT_EMIT_MODE; | 27 static int output_mode = TEXT_EMIT_MODE; |
28 static int data_alignment = 0; | 28 static int data_alignment = 0; |
29 | 29 |
30 static int code_disp_label; | 30 // static int code_disp_label; |
31 // static int disp_label; | 31 // static int disp_label; |
32 int code_top_label; | 32 int code_top_label; |
33 | 33 |
34 // static int r1_offset_label; | 34 static int r1_offset_label; |
35 static int lvar_offset_label; | 35 static int lvar_offset_label; |
36 // static int cprestore_label; | 36 // static int cprestore_label; |
37 static int max_func_args = 0; | 37 static int max_func_args = 0; |
38 static int max_func_iargs = 0; | 38 static int max_func_iargs = 0; |
39 | 39 |
288 function call stack frame | 288 function call stack frame |
289 <------r1_offset------------------------------> | 289 <------r1_offset------------------------------> |
290 <------------lvar_offset-------> | 290 <------------lvar_offset-------> |
291 r+ +------------+---+---------------+----------+--------------+----+ - | 291 r+ +------------+---+---------------+----------+--------------+----+ - |
292 callee arg xx register save local caller arg xx | 292 callee arg xx register save local caller arg xx |
293 reg_save disp max_func_args*SIZE_OF_INT | 293 ($fp) reg_save disp max_func_args*SIZE_OF_INT |
294 lvar>0 lvar<0 lvar>0x1000 0000 | 294 lvar>0 lvar<0 lvar>0x1000 0000 |
295 | 295 prev $sp=$fp $sp=$fp |
296 | |
296 code segment stack frame | 297 code segment stack frame |
297 | 298 |
298 * gotoを呼び出した関数のr1 ! r1(goto前のr1) | 299 * gotoを呼び出した関数のr1 ! r1(goto前のr1) |
299 # * r30 <---r1_offset---------> r1 | 300 # * r30 <---r1_offset---------> r1 |
300 r+ +----------+--+----------+----------------+-----------+----------+----+ | 301 r+ +----------+--+----------+----------------+-----------+----------+----+ |
301 cousin arg xx reg save !callee arg !code local caller arg xx | 302 cousin arg xx reg save !callee arg !code local caller arg xx |
302 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 | 303 ($fp)r20-r29 lvar>0 lvar<0 lvar>0x1000 000 |
303 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> | 304 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> |
304 *SIZE_OF_INT *SIZE_OF_INT | 305 *SIZE_OF_INT *SIZE_OF_INT |
306 prev $sp=$fp $fp $sp | |
305 | 307 |
306 */ | 308 */ |
307 int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12; | 309 int arg_offset = 24; int arg_offset1 = 24; int disp_offset = -12; |
308 // #define func_disp_offset 60 | 310 // #define func_disp_offset 60 |
309 #define func_disp_offset 68 | 311 #define func_disp_offset 68 |
354 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 356 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
355 printf("%d($fp)\n",CODE_CALLER_ARG); | 357 printf("%d($fp)\n",CODE_CALLER_ARG); |
356 } else | 358 } else |
357 printf("%d($fp)\n",CODE_LVAR); | 359 printf("%d($fp)\n",CODE_LVAR); |
358 } else if (l<0) { /* local variable */ | 360 } else if (l<0) { /* local variable */ |
359 printf("%d($fp)\n",FUNC_LVAR); | 361 printf("%d+$L_%d($fp)\n",FUNC_LVAR,lvar_offset_label); |
360 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 362 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
361 printf("%d($fp)\n",CALLER_ARG); | 363 printf("%d($fp)\n",CALLER_ARG); |
362 } else { /* callee's arguments */ | 364 } else { /* callee's arguments */ |
363 printf("%d($fp)\n",CALLEE_ARG); | 365 printf("%d+$L_%d($fp)\n",CALLEE_ARG,r1_offset_label); |
364 } | 366 } |
365 } | 367 } |
366 | 368 |
367 static void | 369 static void |
368 lvar_address(int l,int creg) | 370 lvar_address(int l,int creg) |
371 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 373 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
372 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); | 374 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_CALLER_ARG); |
373 } else | 375 } else |
374 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); | 376 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CODE_LVAR); |
375 } else if (l<0) { /* local variable */ | 377 } else if (l<0) { /* local variable */ |
376 printf("\taddu\t%s,$fp,%d\n",register_name(creg),FUNC_LVAR); | 378 printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg),FUNC_LVAR,lvar_offset_label); |
377 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 379 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
378 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); | 380 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLER_ARG); |
379 } else { /* callee's arguments */ | 381 } else { /* callee's arguments */ |
380 printf("\taddu\t%s,$fp,%d\n",register_name(creg),CALLEE_ARG); | 382 printf("\taddu\t%s,$fp,%d+$L_%d\n",register_name(creg),CALLEE_ARG,r1_offset_label); |
381 } | 383 } |
382 } | 384 } |
383 | 385 |
384 | 386 |
385 #define lvar_intro(e) /* do nothing */ | 387 #define lvar_intro(e) /* do nothing */ |
2137 | 2139 |
2138 void | 2140 void |
2139 tosop(int op,int creg,int oreg) | 2141 tosop(int op,int creg,int oreg) |
2140 { | 2142 { |
2141 int dx = -1; | 2143 int dx = -1; |
2144 int ox = -1; | |
2142 char *orn,*crn; | 2145 char *orn,*crn; |
2143 // creg = creg op oreg | 2146 // creg = creg op oreg |
2144 | 2147 |
2145 use_int(creg); | 2148 use_int(creg); |
2146 if(oreg==-1) { | 2149 if(oreg==-1) { |
2147 error(-1); | 2150 error(-1); |
2148 } else if (oreg<= -REG_LVAR_OFFSET) { | 2151 } else if (oreg<= -REG_LVAR_OFFSET) { |
2149 dx = get_register(); if (dx<0) error(-1); | 2152 ox = get_register(); if (ox<0) error(-1); |
2150 code_rlvar(oreg+REG_LVAR_OFFSET,dx); | 2153 code_rlvar(oreg+REG_LVAR_OFFSET,ox); |
2151 oreg = dx; | 2154 oreg = ox; |
2152 } | 2155 } |
2153 | 2156 |
2154 switch(op) { | 2157 switch(op) { |
2155 case LSHIFT: | 2158 case LSHIFT: |
2156 case ULSHIFT: | 2159 case ULSHIFT: |
2157 shift("sll",creg,oreg); | 2160 shift("sll",creg,oreg); |
2161 if(ox!=-1) free_register(ox); | |
2158 return; | 2162 return; |
2159 case RSHIFT: | 2163 case RSHIFT: |
2160 shift("sra",creg,oreg); | 2164 shift("sra",creg,oreg); |
2165 if(ox!=-1) free_register(ox); | |
2161 return; | 2166 return; |
2162 case URSHIFT: | 2167 case URSHIFT: |
2163 shift("srl",creg,oreg); | 2168 shift("srl",creg,oreg); |
2169 if(ox!=-1) free_register(ox); | |
2164 return; | 2170 return; |
2165 } | 2171 } |
2166 orn = register_name(oreg); | 2172 orn = register_name(oreg); |
2167 crn = register_name(creg); | 2173 crn = register_name(creg); |
2168 switch(op) { | 2174 switch(op) { |
2212 break; | 2218 break; |
2213 default: | 2219 default: |
2214 error(-1); | 2220 error(-1); |
2215 } | 2221 } |
2216 if(dx!=-1) free_register(dx); | 2222 if(dx!=-1) free_register(dx); |
2223 if(ox!=-1) free_register(ox); | |
2217 } | 2224 } |
2218 | 2225 |
2219 int | 2226 int |
2220 code_const_op_p(int op,int v) | 2227 code_const_op_p(int op,int v) |
2221 { | 2228 { |
2222 if (car(v)!=CONST) return 0; | 2229 if (car(v)!=CONST) return 0; |
2223 if (op==BAND||op==DIV||op==UDIV||op==MOD||op==UMOD||op==EOR||op==MUL||op==UMUL) return 0; | 2230 if (!(op==LSHIFT|| op==ULSHIFT|| op==RSHIFT|| op==URSHIFT|| op==ADD|| op==SUB|| op==CMP|| op==BOR)) return 0; |
2224 v = cadr(v); | 2231 v = cadr(v); |
2225 return (-32766<v&&v<32767); | 2232 return (-32766<v&&v<32767); |
2226 } | 2233 } |
2227 | 2234 |
2228 void | 2235 void |
2295 char *rn; | 2302 char *rn; |
2296 if(chk) return; | 2303 if(chk) return; |
2297 rn = register_name(reg = get_register()); | 2304 rn = register_name(reg = get_register()); |
2298 printf("\tli %s,%d\n",rn,e); | 2305 printf("\tli %s,%d\n",rn,e); |
2299 printf("\tsltu %s,%s,%s\n",rn,register_name(csreg),rn); | 2306 printf("\tsltu %s,%s,%s\n",rn,register_name(csreg),rn); |
2307 free_register(reg); | |
2300 } | 2308 } |
2301 | 2309 |
2302 void | 2310 void |
2303 code_opening(char *filename) | 2311 code_opening(char *filename) |
2304 { | 2312 { |
2372 { | 2380 { |
2373 if (chk) return; | 2381 if (chk) return; |
2374 printf("## %s",s); | 2382 printf("## %s",s); |
2375 } | 2383 } |
2376 | 2384 |
2385 static unsigned int | |
2386 code_mask() | |
2387 { | |
2388 int i; | |
2389 unsigned int mask=0; | |
2390 for(i=0;i<32;i++) { | |
2391 if (i==28||i==31||(REG_VAR_MIN<=i&&i<=REG_VAR_MIN+max_reg_var)) { | |
2392 mask |= (1<<i); | |
2393 } | |
2394 } | |
2395 return mask; | |
2396 } | |
2397 | |
2398 static unsigned int | |
2399 code_fmask() | |
2400 { | |
2401 int i; | |
2402 unsigned int mask=0; | |
2403 for(i=0;i<32;i++) { | |
2404 if (FREG_VAR_MIN<=i&&i<=FREG_VAR_MIN+max_freg_var) { | |
2405 mask |= (1<<i); | |
2406 } | |
2407 } | |
2408 return mask; | |
2409 } | |
2410 | |
2377 void | 2411 void |
2378 code_enter(char *name) | 2412 code_enter(char *name) |
2379 { | 2413 { |
2380 if (output_mode!=TEXT_EMIT_MODE) | 2414 if (output_mode!=TEXT_EMIT_MODE) |
2381 text_mode(); | 2415 text_mode(); |
2384 if (stmode!=STATIC) | 2418 if (stmode!=STATIC) |
2385 printf(".globl _%s\n",name); | 2419 printf(".globl _%s\n",name); |
2386 #ifdef DOT_SIZE | 2420 #ifdef DOT_SIZE |
2387 printf("\t.type\t%s,@function\n",name); | 2421 printf("\t.type\t%s,@function\n",name); |
2388 #endif | 2422 #endif |
2389 // printf("\t.set noreorder\n"); | 2423 code_top_label = backdef(); |
2390 // printf("\t.cpload $25\n"); | 2424 r1_offset_label = fwdlabel(); |
2391 // printf("\t.set reorder\n"); | 2425 lvar_offset_label = 0; |
2392 printf("\tsubu $sp,$sp,$L_%d\n",code_disp_label); | |
2393 // printf("\t.cprestore $L_%d\n",cprestore_label); | |
2394 | 2426 |
2395 max_func_args = 0; | 2427 max_func_args = 0; |
2396 max_func_iargs = 0; | 2428 max_func_iargs = 0; |
2397 } | 2429 } |
2398 | 2430 |
2410 { | 2442 { |
2411 int r1_offsetv; | 2443 int r1_offsetv; |
2412 disp&= -SIZE_OF_INT; | 2444 disp&= -SIZE_OF_INT; |
2413 r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset; | 2445 r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset; |
2414 | 2446 |
2415 printf(".set $L_%d,%d\n",code_disp_label,-r1_offsetv); | 2447 printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); |
2448 | |
2449 printf("\t.align 2\n"); | |
2450 printf("%s:\n",name); | |
2451 printf("\t.frame $fp,%d,$31\n",0); | |
2452 printf("\t.mask 0x%x,%d\n",code_mask(),0); | |
2453 printf("\t.fmask 0x%x,%d\n",code_fmask(),0); | |
2454 | |
2455 printf("\t.set noreorder\n"); | |
2456 printf("\t.cpload $25\n"); | |
2457 printf("\t.set reorder\n"); | |
2458 printf("\tsubu $sp,$sp,$L_%d\n",-r1_offsetv); | |
2459 printf("\t.cprestore %d\n",max_func_iargs); | |
2460 printf("\tj $L_%d\n",code_top_label); | |
2461 | |
2462 | |
2416 local_table(); | 2463 local_table(); |
2417 printf("\t.end %s\n",name); | 2464 printf("\t.end %s\n",name); |
2418 // free_all_register(); | 2465 // free_all_register(); |
2419 } | 2466 } |
2420 | 2467 |
2425 text_mode(); | 2472 text_mode(); |
2426 else | 2473 else |
2427 printf("\t.align 2\n"); | 2474 printf("\t.align 2\n"); |
2428 printf(".ent %s\n",name); | 2475 printf(".ent %s\n",name); |
2429 code_top_label = backdef(); | 2476 code_top_label = backdef(); |
2477 | |
2478 r1_offset_label = fwdlabel(); | |
2479 lvar_offset_label = fwdlabel(); | |
2430 | 2480 |
2431 max_func_args = 0; | 2481 max_func_args = 0; |
2432 max_func_iargs = 0; | 2482 max_func_iargs = 0; |
2433 } | 2483 } |
2434 | 2484 |
2439 // set_lreg(LREG_LREGISTER,0); | 2489 // set_lreg(LREG_LREGISTER,0); |
2440 set_ireg(CREG_REGISTER,0); | 2490 set_ireg(CREG_REGISTER,0); |
2441 set_freg(FREG_FREGISTER,0); | 2491 set_freg(FREG_FREGISTER,0); |
2442 } | 2492 } |
2443 | 2493 |
2444 static unsigned int | |
2445 code_mask() | |
2446 { | |
2447 int i; | |
2448 unsigned int mask=0; | |
2449 for(i=0;i<32;i++) { | |
2450 if (i==28||i==31||(REG_VAR_MIN<=i&&i<=REG_VAR_MIN+max_reg_var)) { | |
2451 mask |= (1<<i); | |
2452 } | |
2453 } | |
2454 return mask; | |
2455 } | |
2456 | |
2457 static unsigned int | |
2458 code_fmask() | |
2459 { | |
2460 int i; | |
2461 unsigned int mask=0; | |
2462 for(i=0;i<32;i++) { | |
2463 if (FREG_VAR_MIN<=i&&i<=FREG_VAR_MIN+max_freg_var) { | |
2464 mask |= (1<<i); | |
2465 } | |
2466 } | |
2467 return mask; | |
2468 } | |
2469 | |
2470 static void | 2494 static void |
2471 code_register_save(reg_save,freg_save,disp) | 2495 code_register_save(reg_save,freg_save,disp) |
2472 { | 2496 { |
2473 int i; | 2497 int i; |
2474 for(i=REG_VAR_MIN;i<=max_reg_var;i++) { | 2498 for(i=REG_VAR_MIN;i<=max_reg_var;i++) { |
2499 void | 2523 void |
2500 leave(int control, char *name) | 2524 leave(int control, char *name) |
2501 { | 2525 { |
2502 int retcont1=0,sz; | 2526 int retcont1=0,sz; |
2503 int r1_offsetv; | 2527 int r1_offsetv; |
2528 int lvar_offsetv; | |
2504 | 2529 |
2505 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; | 2530 if (max_freg_var>=0 && max_freg_var<=3) max_freg_var=3; |
2506 reg_save = | 2531 reg_save = |
2507 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*size_of_int; | 2532 (REAL_MAX_REGISTER-(REG_VAR_BASE-max_reg_var))*size_of_int; |
2508 freg_save = | 2533 freg_save = |
2553 fprintf(asi,"$L_%d=%d\n",cprestore_label ,max_func_iargs); | 2578 fprintf(asi,"$L_%d=%d\n",cprestore_label ,max_func_iargs); |
2554 #endif | 2579 #endif |
2555 | 2580 |
2556 disp &= -size_of_int; | 2581 disp &= -size_of_int; |
2557 r1_offsetv = disp; | 2582 r1_offsetv = disp; |
2583 printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); | |
2584 printf(".set L_%d,%d\n",lvar_offset_label,lvar_offsetv); | |
2585 | |
2558 | 2586 |
2559 printf("\tmove $sp,$fp\n"); | 2587 printf("\tmove $sp,$fp\n"); |
2560 code_register_restore(reg_save,freg_save,disp); | 2588 code_register_restore(reg_save,freg_save,disp); |
2561 printf("\tlw $31,%d($sp)\n",-disp); | 2589 printf("\tlw $31,%d($sp)\n",-disp); |
2562 printf("\tlw $fp,%d($sp)\n",-disp-4); | 2590 printf("\tlw $fp,%d($sp)\n",-disp-4); |
4004 | 4032 |
4005 void | 4033 void |
4006 ltosop(int op,int reg,int oreg) | 4034 ltosop(int op,int reg,int oreg) |
4007 { | 4035 { |
4008 int dx = -1; | 4036 int dx = -1; |
4037 int ox = -1; | |
4009 char *orn_h,*crn_h,*drn_h; | 4038 char *orn_h,*crn_h,*drn_h; |
4010 char *orn_l,*crn_l,*drn_l; | 4039 char *orn_l,*crn_l,*drn_l; |
4011 char *drn; | 4040 char *drn; |
4012 // creg = creg op oreg | 4041 // creg = creg op oreg |
4013 | 4042 |
4014 use_longlong(reg); | 4043 use_longlong(reg); |
4015 if(oreg==-1) { | 4044 if(oreg==-1) { |
4016 error(-1); | 4045 error(-1); |
4017 } else if (oreg<= -REG_LVAR_OFFSET) { | 4046 } else if (oreg<= -REG_LVAR_OFFSET) { |
4018 dx = get_lregister(); if (dx<0) error(-1); | 4047 ox = get_lregister(); if (ox<0) error(-1); |
4019 use_reg(dx); | 4048 use_reg(ox); |
4020 code_rlvar(oreg+REG_LVAR_OFFSET,dx); | 4049 code_rlvar(oreg+REG_LVAR_OFFSET,ox); |
4021 oreg = dx; | 4050 oreg = ox; |
4022 } | 4051 } |
4023 | 4052 |
4024 switch(op) { | 4053 switch(op) { |
4025 case LLSHIFT: | 4054 case LLSHIFT: |
4026 case LULSHIFT: | 4055 case LULSHIFT: |
4027 code_asld_lib(oreg); // ___ashldi3$stub | 4056 code_asld_lib(oreg); // ___ashldi3$stub |
4028 check_lreg(reg); | 4057 check_lreg(reg); |
4058 if(ox!=-1) free_register(ox); | |
4029 return; | 4059 return; |
4030 case LRSHIFT: | 4060 case LRSHIFT: |
4031 code_asrd_lib(oreg); // ___ashrdi3$stub | 4061 code_asrd_lib(oreg); // ___ashrdi3$stub |
4032 check_lreg(reg); | 4062 check_lreg(reg); |
4063 if(ox!=-1) free_register(ox); | |
4033 return; | 4064 return; |
4034 case LURSHIFT: | 4065 case LURSHIFT: |
4035 code_lsrd_lib(oreg); // ___lshrdi3$stub | 4066 code_lsrd_lib(oreg); // ___lshrdi3$stub |
4036 check_lreg(reg); | 4067 check_lreg(reg); |
4068 if(ox!=-1) free_register(ox); | |
4037 return; | 4069 return; |
4038 } | 4070 } |
4039 orn_h = lregister_name_high(oreg); | 4071 orn_h = lregister_name_high(oreg); |
4040 orn_l = lregister_name_low(oreg); | 4072 orn_l = lregister_name_low(oreg); |
4041 crn_h = lregister_name_high(reg); | 4073 crn_h = lregister_name_high(reg); |
4114 check_lreg(reg); | 4146 check_lreg(reg); |
4115 break; | 4147 break; |
4116 default: | 4148 default: |
4117 error(-1); | 4149 error(-1); |
4118 } | 4150 } |
4151 if(ox!=-1) free_register(ox); | |
4119 if(dx!=-1) free_register(dx); | 4152 if(dx!=-1) free_register(dx); |
4120 } | 4153 } |
4121 | 4154 |
4122 int | 4155 int |
4123 code_lconst_op_p(int op,int e) | 4156 code_lconst_op_p(int op,int e) |