Mercurial > hg > CbC > old > device
comparison mc-code-mips.c @ 263:c922bade771d
MIPS go on...
author | kono |
---|---|
date | Sun, 16 May 2004 20:11:48 +0900 |
parents | 31d7f050ec0d |
children | 7de200d88747 |
comparison
equal
deleted
inserted
replaced
262:df917628e532 | 263:c922bade771d |
---|---|
14 #define TEXT_EMIT_MODE 0 | 14 #define TEXT_EMIT_MODE 0 |
15 #define DATA_EMIT_MODE 1 | 15 #define DATA_EMIT_MODE 1 |
16 #define RODATA_EMIT_MODE 2 | 16 #define RODATA_EMIT_MODE 2 |
17 | 17 |
18 static void data_mode(char *name); | 18 static void data_mode(char *name); |
19 static void text_mode(int alignment); | |
19 static void init_ptr_cache(); | 20 static void init_ptr_cache(); |
20 static void ld_indexx(int byte, int n, int xreg,int reg,int sign); | 21 static void ld_indexx(int byte, int n, int xreg,int reg,int sign); |
21 static void local_table(void); | 22 static void local_table(void); |
22 static void shift(char *op, int creg,int reg); | 23 static void shift(char *op, int creg,int reg); |
23 static int struct_push(int e4,int t,int arg); | 24 static int struct_push(int e4,int t,int arg); |
25 static int creg; | 26 static int creg; |
26 | 27 |
27 static int output_mode = TEXT_EMIT_MODE; | 28 static int output_mode = TEXT_EMIT_MODE; |
28 static int data_alignment = 0; | 29 static int data_alignment = 0; |
29 | 30 |
30 // static int code_disp_label; | 31 static FILE *asi; |
31 // static int disp_label; | 32 |
32 int code_top_label; | 33 static int cprestore_label; |
34 static int fmask_label; | |
35 static int fmask_offset_label; | |
36 static int mask_label; | |
37 static int mask_offset_label; | |
38 static int register_save_return_label; | |
39 static int register_save_label; | |
40 | |
33 | 41 |
34 static int r1_offset_label; | 42 static int r1_offset_label; |
35 static int lvar_offset_label; | 43 static int lvar_offset_label; |
36 // static int cprestore_label; | 44 // static int cprestore_label; |
37 static int max_func_args = 0; | 45 static int max_func_args = 0; |
864 } | 872 } |
865 while(lreg_sp > 0) { | 873 while(lreg_sp > 0) { |
866 free_register(lreg_stack[--lreg_sp]); | 874 free_register(lreg_stack[--lreg_sp]); |
867 } | 875 } |
868 use_int0(); | 876 use_int0(); |
869 text_mode(); | 877 text_mode(2); |
870 gexpr_code_init(); | 878 gexpr_code_init(); |
871 register_usage("gexpr_init"); | 879 register_usage("gexpr_init"); |
872 } | 880 } |
873 | 881 |
874 | 882 |
878 { | 886 { |
879 free_all_register(); | 887 free_all_register(); |
880 max_reg_var=0; max_freg_var=0; | 888 max_reg_var=0; max_freg_var=0; |
881 reg_sp = 0; | 889 reg_sp = 0; |
882 freg_sp = 0; | 890 freg_sp = 0; |
883 text_mode(); | 891 text_mode(3); |
884 } | 892 } |
885 | 893 |
886 #define reg_var_num(i) (REG_VAR_BASE-i) | 894 #define reg_var_num(i) (REG_VAR_BASE-i) |
887 | 895 |
888 int | 896 int |
1367 printf("$L_%d:\n",lb); | 1375 printf("$L_%d:\n",lb); |
1368 ascii(s); | 1376 ascii(s); |
1369 if (output_mode==TEXT_EMIT_MODE) { | 1377 if (output_mode==TEXT_EMIT_MODE) { |
1370 printf(".text\n"); | 1378 printf(".text\n"); |
1371 } else { | 1379 } else { |
1372 text_mode(); | 1380 text_mode(2); |
1373 } | 1381 } |
1374 printf("\tla %s,$L_%d\n",crn,lb); | 1382 printf("\tla %s,$L_%d\n",crn,lb); |
1375 } | 1383 } |
1376 | 1384 |
1377 #define MAX_COPY_LEN 20 | 1385 #define MAX_COPY_LEN 20 |
2425 void | 2433 void |
2426 code_opening(char *filename) | 2434 code_opening(char *filename) |
2427 { | 2435 { |
2428 static int count=0; | 2436 static int count=0; |
2429 /* this is called once per file */ | 2437 /* this is called once per file */ |
2430 #if 0 | |
2431 char *p=cheapp; | 2438 char *p=cheapp; |
2432 char *s,*t; | 2439 char *s,*t; |
2433 #endif | 2440 |
2434 printf("\t.file %d \"%s\"\n",count++,filename); | 2441 printf("\t.file %d \"%s\"\n",count++,filename); |
2435 printf(".abicalls\n"); | 2442 printf(".abicalls\n"); |
2436 printf(".text\n"); | 2443 printf(".text\n"); |
2437 #if 0 | 2444 |
2438 if (asi) { | 2445 if (asi) { |
2439 fclose(asi); | 2446 fclose(asi); |
2440 asi = 0; | 2447 asi = 0; |
2441 } | 2448 } |
2442 for (t=0,s=p;(*cheapp++ = *s++);) { | 2449 for (t=0,s=p;(*cheapp++ = *s++);) { |
2451 if (t==s-1) *cheapp++ = 0; | 2458 if (t==s-1) *cheapp++ = 0; |
2452 } | 2459 } |
2453 asi = fopen(p,"w"); | 2460 asi = fopen(p,"w"); |
2454 printf(".include \"%s\"\n",p); | 2461 printf(".include \"%s\"\n",p); |
2455 if (!asi) error(-1); | 2462 if (!asi) error(-1); |
2456 #endif | |
2457 } | 2463 } |
2458 | 2464 |
2459 void | 2465 void |
2460 rexpr(int e1, int l1, char *s,int t) | 2466 rexpr(int e1, int l1, char *s,int t) |
2461 { | 2467 { |
2535 if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { | 2541 if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { |
2536 printf("\tsw %s,%d($sp)\n",register_name(i),disp); | 2542 printf("\tsw %s,%d($sp)\n",register_name(i),disp); |
2537 disp += SIZE_OF_INT; | 2543 disp += SIZE_OF_INT; |
2538 } | 2544 } |
2539 } | 2545 } |
2546 for(i=0;i<32;i++) { | |
2547 if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { | |
2548 printf("\ts.s %s,%d($sp)\n",register_name(i),disp); | |
2549 disp += SIZE_OF_FLOAT; | |
2550 } | |
2551 } | |
2540 return disp; | 2552 return disp; |
2541 } | 2553 } |
2542 | 2554 |
2543 static int | 2555 static int |
2544 code_register_restore(reg_save,freg_save,disp) | 2556 code_register_restore(reg_save,freg_save,disp) |
2546 int i; | 2558 int i; |
2547 for(i=0;i<32;i++) { | 2559 for(i=0;i<32;i++) { |
2548 if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { | 2560 if (reg_var_num(0)>i&&i>reg_var_num(max_reg_var)) { |
2549 printf("\tlw %s,%d($sp)\n",register_name(i),disp); | 2561 printf("\tlw %s,%d($sp)\n",register_name(i),disp); |
2550 disp += SIZE_OF_INT; | 2562 disp += SIZE_OF_INT; |
2563 } | |
2564 } | |
2565 for(i=0;i<32;i++) { | |
2566 if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { | |
2567 printf("\tl.s %s,%d($sp)\n",register_name(i),disp); | |
2568 disp += SIZE_OF_FLOAT; | |
2551 } | 2569 } |
2552 } | 2570 } |
2553 return disp; | 2571 return disp; |
2554 } | 2572 } |
2555 | 2573 |
2579 } | 2597 } |
2580 } | 2598 } |
2581 return mask; | 2599 return mask; |
2582 } | 2600 } |
2583 | 2601 |
2584 static int | |
2585 code_fregister_save(reg_save,freg_save,disp) | |
2586 { | |
2587 int i; | |
2588 for(i=0;i<32;i++) { | |
2589 if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { | |
2590 printf("\tsw %s,%d($sp)\n",register_name(i),disp); | |
2591 disp += SIZE_OF_FLOAT; | |
2592 } | |
2593 } | |
2594 return disp; | |
2595 } | |
2596 | |
2597 static int | |
2598 code_fregister_restore(reg_save,freg_save,disp) | |
2599 { | |
2600 int i; | |
2601 for(i=0;i<32;i++) { | |
2602 if (freg_var_num(0)>i&&i>freg_var_num(max_reg_var)) { | |
2603 printf("\tsw %s,%d($sp)\n",register_name(i),disp); | |
2604 disp += SIZE_OF_FLOAT; | |
2605 } | |
2606 } | |
2607 return disp; | |
2608 } | |
2609 | |
2610 void | 2602 void |
2611 code_enter(char *name) | 2603 code_enter(char *name) |
2612 { | 2604 { |
2613 if (output_mode!=TEXT_EMIT_MODE) | 2605 if (output_mode!=TEXT_EMIT_MODE) |
2614 text_mode(); | 2606 text_mode(3); |
2615 else | 2607 else |
2616 printf("\t.align 3\n"); | 2608 printf("\t.align 3\n"); |
2617 if (stmode!=STATIC) | 2609 if (stmode!=STATIC) |
2618 printf(".globl _%s\n",name); | 2610 printf(".globl _%s\n",name); |
2619 #ifdef DOT_SIZE | 2611 #ifdef DOT_SIZE |
2620 printf("\t.type\t%s,@function\n",name); | 2612 printf("\t.type\t%s,@function\n",name); |
2621 #endif | 2613 #endif |
2622 code_top_label = backdef(); | 2614 |
2623 r1_offset_label = fwdlabel(); | |
2624 lvar_offset_label = 0; | |
2625 | |
2626 max_func_args = 0; | |
2627 } | |
2628 | |
2629 | |
2630 void | |
2631 code_enter1(int args) | |
2632 { | |
2633 // set_lreg(LREG_LREGISTER,0); | |
2634 set_ireg(CREG_REGISTER,0); | |
2635 set_freg(FREG_FREGISTER,0); | |
2636 } | |
2637 | |
2638 void | |
2639 code_leave(char *name) | |
2640 { | |
2641 int r1_offsetv; | |
2642 disp&= -SIZE_OF_INT; | |
2643 r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset; | |
2644 | |
2645 printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); | |
2646 | |
2647 printf("\t.align 2\n"); | |
2648 printf("%s:\n",name); | 2615 printf("%s:\n",name); |
2649 printf("\t.frame $fp,%d,$31\n",0); | 2616 printf("\t.frame $fp,%d,$31\n",0); |
2650 printf("\t.mask 0x%x,%d\n",code_mask(),0); | 2617 printf("\t.mask 0x%x,%d\n",code_mask(),0); |
2651 printf("\t.fmask 0x%x,%d\n",code_fmask(),0); | 2618 printf("\t.fmask 0x%x,%d\n",code_fmask(),0); |
2652 | 2619 |
2653 printf("\t.set noreorder\n"); | 2620 printf("\t.set noreorder\n"); |
2654 printf("\t.cpload $25\n"); | 2621 printf("\t.cpload $25\n"); |
2655 printf("\t.set reorder\n"); | 2622 printf("\t.set reorder\n"); |
2656 printf("\tsubu $sp,$sp,$L_%d\n",-r1_offsetv); | 2623 printf("\tsubu $sp,$sp,$L_%d\n", r1_offset_label = fwdlabel()); |
2657 printf("\t.cprestore %d\n",max_func_args); | 2624 printf("\t.cprestore %d\n",max_func_args); |
2658 printf("\tj $L_%d\n",code_top_label); | 2625 lvar_offset_label = fwdlabel(); |
2659 | 2626 |
2627 max_func_args = 0; | |
2628 } | |
2629 | |
2630 | |
2631 void | |
2632 code_enter1(int args) | |
2633 { | |
2634 // set_lreg(LREG_LREGISTER,0); | |
2635 set_ireg(CREG_REGISTER,0); | |
2636 set_freg(FREG_FREGISTER,0); | |
2637 } | |
2638 | |
2639 void | |
2640 code_leave(char *name) | |
2641 { | |
2642 int r1_offsetv; | |
2643 disp&= -SIZE_OF_INT; | |
2644 r1_offsetv = -disp+max_func_args*SIZE_OF_INT+code_disp_offset; | |
2645 | |
2646 printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); | |
2660 | 2647 |
2661 local_table(); | 2648 local_table(); |
2662 printf("\t.end %s\n",name); | 2649 printf("\t.end %s\n",name); |
2663 // free_all_register(); | 2650 // free_all_register(); |
2664 } | 2651 } |
2665 | 2652 |
2666 void | 2653 void |
2667 enter(char *name) | 2654 enter(char *name) |
2668 { | 2655 { |
2669 if (output_mode!=TEXT_EMIT_MODE) | 2656 if (output_mode!=TEXT_EMIT_MODE) |
2670 text_mode(); | 2657 text_mode(3); |
2671 else | 2658 else |
2672 printf("\t.align 2\n"); | 2659 printf("\t.align 3\n"); |
2673 code_top_label = backdef(); | |
2674 | 2660 |
2675 r1_offset_label = fwdlabel(); | 2661 max_func_args = 0; |
2662 | |
2676 lvar_offset_label = fwdlabel(); | 2663 lvar_offset_label = fwdlabel(); |
2677 | 2664 |
2678 max_func_args = 0; | 2665 printf(".ent %s\n",name); |
2666 printf("%s:\n",name); | |
2667 printf("\t.frame $fp,$L_%d,$31\t",r1_offset_label); | |
2668 printf("\t.mask 0x%x,%d\n",mask_label=fwdlabel(), | |
2669 mask_offset_label=fwdlabel()); | |
2670 printf("\t.fmask 0x%x,%d\n",fmask_label=fwdlabel(), | |
2671 fmask_offset_label=fwdlabel()); | |
2672 printf("\t.set noreorder\n"); | |
2673 printf("\t.cpload $25\n"); | |
2674 printf("\t.set reorder\n"); | |
2675 printf("\tsubu $sp,$sp,$L_%d\n",r1_offset_label=fwdlabel()); | |
2676 printf("\t.cprestore $L_%d\n",cprestore_label=fwdlabel()); | |
2677 printf("\tj $L_%d\n",register_save_label=fwdlabel()); | |
2678 register_save_return_label = backdef(); | |
2679 printf("\tmove $fp,$sp\n"); | |
2679 } | 2680 } |
2680 | 2681 |
2681 void | 2682 void |
2682 enter1() | 2683 enter1() |
2683 { | 2684 { |
2684 text_mode(); | 2685 text_mode(0); |
2685 // set_lreg(LREG_LREGISTER,0); | 2686 // set_lreg(LREG_LREGISTER,0); |
2686 set_ireg(CREG_REGISTER,0); | 2687 set_ireg(CREG_REGISTER,0); |
2687 set_freg(FREG_FREGISTER,0); | 2688 set_freg(FREG_FREGISTER,0); |
2688 } | 2689 } |
2689 | 2690 |
2702 freg_save = | 2703 freg_save = |
2703 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_FLOAT; | 2704 (REAL_MAX_FREGISTER-(FREG_VAR_BASE-max_freg_var))*SIZE_OF_FLOAT; |
2704 | 2705 |
2705 if (control) { | 2706 if (control) { |
2706 code_set_return_register(1); | 2707 code_set_return_register(1); |
2707 } | 2708 } else |
2709 text_mode(2); | |
2708 if (retcont) { | 2710 if (retcont) { |
2709 /* return from CbC segement */ | 2711 /* return from CbC segement */ |
2710 if (control) jmp(retlabel); | 2712 if (control) jmp(retlabel); |
2711 retcont1 = fwdlabel(); | 2713 retcont1 = fwdlabel(); |
2712 fwddef(retcont); | 2714 fwddef(retcont); |
2732 } | 2734 } |
2733 fwddef(retlabel); | 2735 fwddef(retlabel); |
2734 if (retcont) { | 2736 if (retcont) { |
2735 fwddef(retcont1); | 2737 fwddef(retcont1); |
2736 } | 2738 } |
2737 #if 0 | 2739 |
2738 fprintf(asi,"$L_%d=%d\n",r1_offset_label,0); | |
2739 fprintf(asi,"$L_%d=%d\n",lvar_offset_label,0); | |
2740 fprintf(asi,"$L_%d=0x%x\n",mask_label,code_mask_label()); | |
2741 fprintf(asi,"$L_%d=%d\n",mask1_label,0); | |
2742 fprintf(asi,"$L_%d=0x%x\n",fmask_label ,code_fmask_label()); | |
2743 fprintf(asi,"$L_%d=%d\n",fmask1_label,0); | |
2744 fprintf(asi,"$L_%d=%d\n",cprestore_label ,max_func_args); | |
2745 #endif | |
2746 | 2740 |
2747 disp &= -SIZE_OF_INT; | 2741 disp &= -SIZE_OF_INT; |
2748 r1_offsetv = round16(-disp) + | 2742 r1_offsetv = round16(-disp) + |
2749 max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+ | 2743 max_reg_var*SIZE_OF_INT+max_freg_var*SIZE_OF_FLOAT+ |
2750 round16(max_func_args); | 2744 round16(max_func_args); |
2751 | 2745 |
2752 printf(".set L_%d,%d\n",r1_offset_label,r1_offsetv); | 2746 fprintf(asi,"$L_%d=%d\n",r1_offset_label,r1_offsetv); |
2753 printf(".set L_%d,%d\n",lvar_offset_label,lvar_offsetv); | 2747 fprintf(asi,"$L_%d=%d\n",lvar_offset_label,lvar_offsetv); |
2754 | 2748 |
2755 printf("\tmove $sp,$fp\n"); | 2749 printf("\tmove $sp,$fp\n"); |
2756 code_fregister_restore(code_register_restore(disp)); | 2750 if (max_reg_var+max_freg_var) |
2751 code_register_restore(disp); | |
2757 printf("\tlw $31,%d($sp)\n",-disp); | 2752 printf("\tlw $31,%d($sp)\n",-disp); |
2758 printf("\tlw $fp,%d($sp)\n",-disp-4); | 2753 printf("\tlw $fp,%d($sp)\n",-disp-4); |
2759 printf("\taddu $sp,$sp,%d\n",r1_offsetv); | 2754 printf("\taddu $sp,$sp,%d\n",r1_offsetv); |
2760 printf("\tj $31\n"); | 2755 printf("\tj $31\n"); |
2761 | 2756 |
2762 printf("\t.align 2\n"); | |
2763 printf(".ent %s\n",name); | |
2764 printf("%s:\n",name); | |
2765 printf("\t.frame $fp,%d,$31\t",r1_offsetv); | |
2766 printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n", | 2757 printf("# vars= %d, regs= %d/%d, args= %d, extra= %d\n", |
2767 round16(-disp), | 2758 round16(-disp), |
2768 max_reg_var+2, | 2759 max_reg_var+2, |
2769 max_freg_var, | 2760 max_freg_var, |
2770 round16(max_func_args), | 2761 round16(max_func_args), |
2771 0 | 2762 0 |
2772 ); | 2763 ); |
2773 printf("\t.mask 0x%x,%d\n",code_mask(),code_mask_offset()); | 2764 fprintf(asi,"$L_%d=0x%x\n",mask_label,code_mask()); |
2774 printf("\t.fmask 0x%x,%d\n",code_fmask(),code_fmask_offset()); | 2765 fprintf(asi,"$L_%d=%d\n",mask_offset_label,code_mask_offset()); |
2775 | 2766 fprintf(asi,"$L_%d=0x%x\n",fmask_label,code_fmask()); |
2776 printf("\t.set noreorder\n"); | 2767 fprintf(asi,"$L_%d=%d\n",fmask_offset_label,code_fmask_offset()); |
2777 printf("\t.cpload $25\n"); | 2768 fprintf(asi,"$L_%d=%d\n",cprestore_label ,round16(max_func_args)); |
2778 printf("\t.set reorder\n"); | 2769 |
2779 printf("\tsubu $sp,$sp,%d\n",r1_offsetv); | 2770 if (max_reg_var+max_freg_var==0) { |
2780 printf("\t.cprestore %d\n",round16(max_func_args)); | 2771 fprintf(asi,"$L_%d=$L_%d\n", |
2781 code_fregister_save(code_register_save(disp)); | 2772 register_save_label,register_save_return_label); |
2782 printf("\tj $L_%d\n",code_top_label); | 2773 } else { |
2774 code_label(register_save_return_label); | |
2775 code_register_save(disp); | |
2776 jmp(register_save_return_label); | |
2777 } | |
2783 | 2778 |
2784 local_table(); | 2779 local_table(); |
2785 printf("\t.end %s\n",name); | 2780 printf("\t.end %s\n",name); |
2786 | 2781 |
2787 labelno++; | 2782 labelno++; |
2974 } | 2969 } |
2975 } | 2970 } |
2976 } | 2971 } |
2977 | 2972 |
2978 void | 2973 void |
2979 text_mode(void) | 2974 text_mode(int align) |
2980 { | 2975 { |
2981 if (output_mode!=TEXT_EMIT_MODE) { | 2976 if (output_mode!=TEXT_EMIT_MODE) { |
2982 printf(".text\n"); | 2977 printf(".text\n"); |
2983 printf("\t.align 2\n"); | 2978 if (align) printf("\t.align %d\n",align); |
2984 output_mode = TEXT_EMIT_MODE; | 2979 output_mode = TEXT_EMIT_MODE; |
2985 } | 2980 } |
2986 } | 2981 } |
2987 | 2982 |
2988 void | 2983 void |
3418 char *grn,*frn; | 3413 char *grn,*frn; |
3419 int d; | 3414 int d; |
3420 int cmp=0; | 3415 int cmp=0; |
3421 | 3416 |
3422 d=(op<FOP); | 3417 d=(op<FOP); |
3423 use_float(reg,d); | 3418 use_float(d,reg); |
3424 switch(op) { | 3419 switch(op) { |
3425 case FADD: opn="add.s"; break; | 3420 case FADD: opn="add.s"; break; |
3426 case DADD: opc="dpadd"; break; | 3421 case DADD: opc="dpadd"; break; |
3427 case FSUB: opn="sub.s"; break; | 3422 case FSUB: opn="sub.s"; break; |
3428 case DSUB: opc="dpsub"; break; | 3423 case DSUB: opc="dpsub"; break; |
4777 void | 4772 void |
4778 code_closing() | 4773 code_closing() |
4779 { | 4774 { |
4780 global_table(); | 4775 global_table(); |
4781 /* printf("\t.ident \"Micro-C compiled\"\n"); */ | 4776 /* printf("\t.ident \"Micro-C compiled\"\n"); */ |
4777 fclose(asi); asi=0; | |
4782 } | 4778 } |
4783 | 4779 |
4784 /* end */ | 4780 /* end */ |
4785 | 4781 |