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)