comparison mc-code-powerpc.c @ 724:e60c3d8dadd6

convert to UTF-8
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 08 Nov 2008 15:11:06 +0900
parents c1542a2482b1
children f3fccac64cbe
comparison
equal deleted inserted replaced
723:c2fb8e2b1dca 724:e60c3d8dadd6
1 /* Micro-C Code Generation Part for Power PC (Mac OS X) */ 1 /* Micro-C Code Generation Part for Power PC (Mac OS X) */
2 2
3 /* 3 /*
4 ************************************************************************ 4 ************************************************************************
5 ** Copyright (C) 2006 Shinji Kono 5 ** Copyright (C) 2006 Shinji Kono
6 ** Ϣ衧 ΰؾ󹩳ز 6 ** 連絡先: 琉球大学情報工学科 河野 真治
7 ** E-Mail Address: kono@ie.u-ryukyu.ac.jp 7 ** (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
8 ** 8 **
9 ** ΥΤʤʣ̡ѡޤ 9 ** このソースのいかなる複写,改変,修正も許諾します。ただし、
10 ** κݤˤϡï׸򼨤ʬĤȡ 10 ** その際には、誰が貢献したを示すこの部分を残すこと。
11 ** ۤ仨Ͽʤɤ䤤碌ɬפޤ 11 ** 再配布や雑誌の付録などの問い合わせも必要ありません。
12 ** Ѥ嵭ȿʤϰϤǵĤޤ 12 ** 営利利用も上記に反しない範囲で許可します。
13 ** Хʥۤκݤˤversion message¸뤳ȤȤޤ 13 ** バイナリの配布の際にはversion messageを保存することを条件とします。
14 ** ΥץˤĤƤä˲ݾڤ⤷ʤ餺 14 ** このプログラムについては特に何の保証もしない、悪しからず。
15 ** 15 **
16 ** Everyone is permitted to do anything on this program 16 ** Everyone is permitted to do anything on this program
17 ** including copying, modifying, improving, 17 ** including copying, modifying, improving,
18 ** as long as you don't try to pretend that you wrote it. 18 ** as long as you don't try to pretend that you wrote it.
19 ** i.e., the above copyright notice has to appear in all copies. 19 ** i.e., the above copyright notice has to appear in all copies.
204 #define ENDIAN 1 204 #define ENDIAN 1
205 #define ENDIAN_L 1 205 #define ENDIAN_L 1
206 #define ENDIAN_D 1 206 #define ENDIAN_D 1
207 207
208 static int reg_sp; /* REGister Stack-Pointer */ 208 static int reg_sp; /* REGister Stack-Pointer */
209 static int reg_stack[MAX_MAX]; /* ºݤΥ쥸ΰ */ 209 static int reg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
210 210
211 /* floating point registers */ 211 /* floating point registers */
212 212
213 static int freg_sp; /* floating point REGister Stack-Pointer */ 213 static int freg_sp; /* floating point REGister Stack-Pointer */
214 static int freg_stack[MAX_MAX]; /* ºݤΥ쥸ΰ */ 214 static int freg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
215 215
216 static int lreg_sp; /* longlong REGister Stack-Pointer */ 216 static int lreg_sp; /* longlong REGister Stack-Pointer */
217 static int lreg_stack[MAX_MAX]; /* ºݤΥ쥸ΰ */ 217 static int lreg_stack[MAX_MAX]; /* 実際のレジスタの領域 */
218 218
219 #ifdef __APPLE__ 219 #ifdef __APPLE__
220 #define REG_sp 1 220 #define REG_sp 1
221 #define REG_fp 30 221 #define REG_fp 30
222 #define REG_VAR_BASE 29 222 #define REG_VAR_BASE 29
240 #define FREG_VAR_MIN 20 240 #define FREG_VAR_MIN 20
241 #define MIN_TMP_FREG 1 241 #define MIN_TMP_FREG 1
242 #define MAX_TMP_FREG 9 242 #define MAX_TMP_FREG 9
243 #endif 243 #endif
244 244
245 int MAX_REGISTER=30; /* PowerPCΥ쥸10ĤޤǻȤ*/ 245 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/
246 int MAX_FREGISTER=31; 246 int MAX_FREGISTER=31;
247 #define REAL_MAX_REGISTER 32 /* PowerPCΥ쥸32Ȥ*/ 247 #define REAL_MAX_REGISTER 32 /* PowerPCのレジスタが32ということ*/
248 #define REAL_MAX_FREGISTER 32 /* PowerPCΥ쥸32Ȥ*/ 248 #define REAL_MAX_FREGISTER 32 /* PowerPCのレジスタが32ということ*/
249 #define REAL_MAX_LREGISTER 16 249 #define REAL_MAX_LREGISTER 16
250 250
251 #define FREG_OFFSET REAL_MAX_REGISTER 251 #define FREG_OFFSET REAL_MAX_REGISTER
252 #define LREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER) 252 #define LREG_OFFSET (REAL_MAX_REGISTER+REAL_MAX_FREGISTER)
253 253
465 lvar>0 lvar<0 lvar>0x1000 0000 465 lvar>0 lvar<0 lvar>0x1000 0000
466 466
467 467
468 code segment stack frame 468 code segment stack frame
469 469
470 * gotoƤӽФؿr1 ! r1(gotor1) 470 * gotoを呼び出した関数のr1 ! r1(goto前のr1)
471 # * r30 <---r1_offset---------> r1 471 # * r30 <---r1_offset---------> r1
472 r+ +----------+--+----------+----------------+-----------+----------+----+ 472 r+ +----------+--+----------+----------------+-----------+----------+----+
473 cousin arg xx reg save !callee arg !code local caller arg xx 473 cousin arg xx reg save !callee arg !code local caller arg xx
474 r20-r29 lvar>0 lvar<0 lvar>0x1000 000 474 r20-r29 lvar>0 lvar<0 lvar>0x1000 000
475 f20-f31 <-my_func_args--><--disp-----><-max_func_arg-> 475 f20-f31 <-my_func_args--><--disp-----><-max_func_arg->
849 } 849 }
850 850
851 851
852 int 852 int
853 get_register(void) 853 get_register(void)
854 { /* ȤƤʤ쥸Ĵ٤ */ 854 { /* 使われていないレジスタを調べる */
855 int i,j,reg; 855 int i,j,reg;
856 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) { 856 for(i=MAX_TMP_REG;i>MIN_TMP_REG;i--) {
857 if (regs[i]) continue; /* ȤƤ */ 857 if (regs[i]) continue; /* 使われている */
858 regs[i]=USING_REG; /* Υ쥸ȤȤ */ 858 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
859 return i; /* ξɽֹ֤ */ 859 return i; /* その場所を表す番号を返す */
860 } 860 }
861 /* PTR_CACHE Ĥ֤ */ 861 /* PTR_CACHE をつぶす */
862 if ((i=last_ptr_cache())) { 862 if ((i=last_ptr_cache())) {
863 clear_ptr_cache_reg(i); 863 clear_ptr_cache_reg(i);
864 regs[i]=USING_REG; /* Υ쥸ȤȤ */ 864 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
865 return i; /* ξɽֹ֤ */ 865 return i; /* その場所を表す番号を返す */
866 } 866 }
867 /* search register stack */ 867 /* search register stack */
868 for(i=0;i<reg_sp;i++) { 868 for(i=0;i<reg_sp;i++) {
869 if ((reg=reg_stack[i])>=0) { 869 if ((reg=reg_stack[i])>=0) {
870 code_assign_lvar( 870 code_assign_lvar(
885 } 885 }
886 } 886 }
887 #endif 887 #endif
888 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 888 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
889 reg =REG_VAR_BASE-i; 889 reg =REG_VAR_BASE-i;
890 if (! regs[reg]) { /* ȤƤʤʤ */ 890 if (! regs[reg]) { /* 使われていないなら */
891 regs[reg]=USING_REG; /* Υ쥸ȤȤ */ 891 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
892 if (i>max_reg_var) max_reg_var=i; 892 if (i>max_reg_var) max_reg_var=i;
893 return reg; /* ξɽֹ֤ */ 893 return reg; /* その場所を表す番号を返す */
894 } 894 }
895 } 895 }
896 /* Ƥ꤬ʤʤ顢顼 (äïȤäƤ?) */ 896 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
897 error(RGERR); return creg; 897 error(RGERR); return creg;
898 } 898 }
899 899
900 #if 0 900 #if 0
901 int 901 int
907 } 907 }
908 #endif 908 #endif
909 909
910 int 910 int
911 pop_register(void) 911 pop_register(void)
912 { /* 쥸ͤФ */ 912 { /* レジスタから値を取り出す */
913 return reg_stack[--reg_sp]; 913 return reg_stack[--reg_sp];
914 } 914 }
915 915
916 #if FLOAT_CODE 916 #if FLOAT_CODE
917 int 917 int
918 get_dregister(int d) 918 get_dregister(int d)
919 { /* ȤƤʤ쥸Ĵ٤ */ 919 { /* 使われていないレジスタを調べる */
920 int i,reg; 920 int i,reg;
921 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) { 921 for(i=MAX_TMP_FREG+FREG_OFFSET;i>MIN_TMP_FREG+FREG_OFFSET;i--) {
922 if (regs[i]) continue; /* ȤƤ */ 922 if (regs[i]) continue; /* 使われている */
923 regs[i]=USING_REG; /* Υ쥸ȤȤ */ 923 regs[i]=USING_REG; /* そのレジスタを使うことを宣言し */
924 return i; /* ξɽֹ֤ */ 924 return i; /* その場所を表す番号を返す */
925 } 925 }
926 /* search register stack */ 926 /* search register stack */
927 for(i=0;i<freg_sp;i++) { 927 for(i=0;i<freg_sp;i++) {
928 if ((reg=freg_stack[i])>=0) { 928 if ((reg=freg_stack[i])>=0) {
929 code_dassign_lvar( 929 code_dassign_lvar(
932 return reg; 932 return reg;
933 } 933 }
934 } 934 }
935 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) { 935 for(i=0;i<FREG_VAR_BASE-REG_VAR_MIN;i++) {
936 reg =FREG_VAR_BASE-i+FREG_OFFSET; 936 reg =FREG_VAR_BASE-i+FREG_OFFSET;
937 if (! regs[reg]) { /* ȤƤʤʤ */ 937 if (! regs[reg]) { /* 使われていないなら */
938 regs[reg]=USING_REG; /* Υ쥸ȤȤ */ 938 regs[reg]=USING_REG; /* そのレジスタを使うことを宣言し */
939 if (i>max_freg_var) max_freg_var=i; 939 if (i>max_freg_var) max_freg_var=i;
940 return reg; /* ξɽֹ֤ */ 940 return reg; /* その場所を表す番号を返す */
941 } 941 }
942 } 942 }
943 /* Ƥ꤬ʤʤ顢顼 (äïȤäƤ?) */ 943 /* 空いている場所がないなら、エラー (いったい誰が使ってるの?) */
944 error(REG_ERR); return freg; 944 error(REG_ERR); return freg;
945 } 945 }
946 946
947 #if 0 947 #if 0
948 int 948 int
954 } 954 }
955 #endif 955 #endif
956 956
957 int 957 int
958 pop_fregister(void) 958 pop_fregister(void)
959 { /* 쥸ͤФ */ 959 { /* レジスタから値を取り出す */
960 return freg_stack[--freg_sp]; 960 return freg_stack[--freg_sp];
961 } 961 }
962 #endif 962 #endif
963 963
964 964
1038 int max_reg_var_save=max_reg_var; 1038 int max_reg_var_save=max_reg_var;
1039 ll = get_lregister0(); 1039 ll = get_lregister0();
1040 if (ll==-1) goto not_found; 1040 if (ll==-1) goto not_found;
1041 if (regs[ll]==0) { 1041 if (regs[ll]==0) {
1042 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 1042 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
1043 if (! regs[REG_VAR_BASE-i]) { /* ȤƤʤʤ */ 1043 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
1044 /* Υ쥸ȤȤ */ 1044 /* そのレジスタを使うことを宣言し */
1045 regs[REG_VAR_BASE-i]=USING_REG; 1045 regs[REG_VAR_BASE-i]=USING_REG;
1046 if (i>max_reg_var) max_reg_var=i; 1046 if (i>max_reg_var) max_reg_var=i;
1047 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) { 1047 for(j=0;j<REG_VAR_BASE-REG_VAR_MIN;j++) {
1048 if (! regs[REG_VAR_BASE-j]) { 1048 if (! regs[REG_VAR_BASE-j]) {
1049 /* ȤƤʤʤ */ 1049 /* 使われていないなら */
1050 /* Υ쥸ȤȤ */ 1050 /* そのレジスタを使うことを宣言し */
1051 regs[REG_VAR_BASE-j]=REG_VAR; 1051 regs[REG_VAR_BASE-j]=REG_VAR;
1052 if (j>max_reg_var) max_reg_var=j; 1052 if (j>max_reg_var) max_reg_var=j;
1053 /* ξɽֹ֤ */ 1053 /* その場所を表す番号を返す */
1054 regs[ll]=REG_VAR; 1054 regs[ll]=REG_VAR;
1055 regv_l(ll) = REG_VAR_BASE-j; 1055 regv_l(ll) = REG_VAR_BASE-j;
1056 regv_h(ll) = REG_VAR_BASE-i; 1056 regv_h(ll) = REG_VAR_BASE-i;
1057 return list3n(LREGISTER,ll,n); 1057 return list3n(LREGISTER,ll,n);
1058 } 1058 }
1059 } 1059 }
1060 /* ҤȤĤʤä */ 1060 /* ひとつしかなかった */
1061 regs[REG_VAR_BASE-i]=0; 1061 regs[REG_VAR_BASE-i]=0;
1062 max_reg_var=max_reg_var_save; 1062 max_reg_var=max_reg_var_save;
1063 goto not_found; 1063 goto not_found;
1064 } 1064 }
1065 } 1065 }
1075 free_register(xreg); 1075 free_register(xreg);
1076 } 1076 }
1077 1077
1078 void 1078 void
1079 1079
1080 free_register(int i) { /* ʤʤä쥸 */ 1080 free_register(int i) { /* いらなくなったレジスタを開放 */
1081 // printf("## free_register %d\n",i); 1081 // printf("## free_register %d\n",i);
1082 if (is_longlong_reg(i)) { 1082 if (is_longlong_reg(i)) {
1083 regs[regv_l(i)]=0; 1083 regs[regv_l(i)]=0;
1084 regs[regv_h(i)]=0; 1084 regs[regv_h(i)]=0;
1085 } 1085 }
1370 int 1370 int
1371 get_register_var(NMTBL *n) 1371 get_register_var(NMTBL *n)
1372 { 1372 {
1373 int i; 1373 int i;
1374 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) { 1374 for(i=0;i<REG_VAR_BASE-REG_VAR_MIN;i++) {
1375 if (! regs[REG_VAR_BASE-i]) { /* ȤƤʤʤ */ 1375 if (! regs[REG_VAR_BASE-i]) { /* 使われていないなら */
1376 /* Υ쥸ȤȤ */ 1376 /* そのレジスタを使うことを宣言し */
1377 regs[REG_VAR_BASE-i]=REG_VAR; 1377 regs[REG_VAR_BASE-i]=REG_VAR;
1378 if (i>max_reg_var) max_reg_var=i; 1378 if (i>max_reg_var) max_reg_var=i;
1379 /* ξɽֹ֤ */ 1379 /* その場所を表す番号を返す */
1380 return list3n(REGISTER,REG_VAR_BASE-i,n); 1380 return list3n(REGISTER,REG_VAR_BASE-i,n);
1381 } 1381 }
1382 } 1382 }
1383 return list3n(LVAR,new_lvar(SIZE_OF_INT),0); 1383 return list3n(LVAR,new_lvar(SIZE_OF_INT),0);
1384 } 1384 }
1386 int 1386 int
1387 get_dregister_var(NMTBL *n,int d) 1387 get_dregister_var(NMTBL *n,int d)
1388 { 1388 {
1389 int i; 1389 int i;
1390 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) { 1390 for(i=0;i<FREG_VAR_BASE-FREG_VAR_MIN;i++) {
1391 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* ȤƤʤʤ */ 1391 if (! regs[FREG_VAR_BASE-i+FREG_OFFSET]) { /* 使われていないなら */
1392 regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*Υ쥸ȤȤ*/ 1392 regs[FREG_VAR_BASE-i+FREG_OFFSET]=REG_VAR; /*そのレジスタを使うことを宣言し*/
1393 if (i>max_freg_var) max_freg_var=i; 1393 if (i>max_freg_var) max_freg_var=i;
1394 /* ξɽֹ֤ */ 1394 /* その場所を表す番号を返す */
1395 return list3n(DREGISTER, 1395 return list3n(DREGISTER,
1396 FREG_VAR_BASE-i+FREG_OFFSET,n); 1396 FREG_VAR_BASE-i+FREG_OFFSET,n);
1397 } 1397 }
1398 } 1398 }
1399 return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0); 1399 return list3n(LVAR,new_lvar(SIZE_OF_DOUBLE),0);
1403 emit_push() 1403 emit_push()
1404 { 1404 {
1405 int new_reg,old=creg; 1405 int new_reg,old=creg;
1406 if (!is_int_reg(creg)) error(-1); 1406 if (!is_int_reg(creg)) error(-1);
1407 if (reg_sp>MAX_MAX) error(-1); 1407 if (reg_sp>MAX_MAX) error(-1);
1408 new_reg = get_register(); /* Ф˼ */ 1408 new_reg = get_register(); /* 絶対に取れる */
1409 if (new_reg==creg) error(-1); // freed creg 1409 if (new_reg==creg) error(-1); // freed creg
1410 reg_stack[reg_sp++] = creg; /* push 뤫˥쥸Ȥ */ 1410 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */
1411 ireg = creg = new_reg; 1411 ireg = creg = new_reg;
1412 if (!regs[creg]) regs[creg]=USING_REG; 1412 if (!regs[creg]) regs[creg]=USING_REG;
1413 return old; 1413 return old;
1414 } 1414 }
1415 1415
2263 2263
2264 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT) 2264 #define caller_arg_offset_v(arg) (ARG_LVAR_OFFSET+(arg)*SIZE_OF_INT)
2265 2265
2266 /* 2266 /*
2267 use input register as current register 2267 use input register as current register
2268 ʤǡʤʣʤ? 2268 なんで、こんなに複雑なんだ?
2269 षINPUT_REG ߤ mark 򤤤줿? 2269 むしろ、INPUT_REG みたいな mark をいれたら?
2270 */ 2270 */
2271 2271
2272 static void 2272 static void
2273 use_input_reg(int reg,int mode) 2273 use_input_reg(int reg,int mode)
2274 { 2274 {
2276 if (ireg&&reg == ireg) { 2276 if (ireg&&reg == ireg) {
2277 if (creg==ireg) creg = 0; 2277 if (creg==ireg) creg = 0;
2278 ireg = 0; 2278 ireg = 0;
2279 } 2279 }
2280 if (lreg) { 2280 if (lreg) {
2281 // free_regsiter(lreg) Ǥ󤸤ʤ? 2281 // free_regsiter(lreg) でいいんじゃないの?
2282 if (regv_l(lreg)==reg) { 2282 if (regv_l(lreg)==reg) {
2283 regs[lreg]=0; 2283 regs[lreg]=0;
2284 if (regv_h(lreg)>reg&&regs[regv_h(lreg)]==USING_REG) { 2284 if (regv_h(lreg)>reg&&regs[regv_h(lreg)]==USING_REG) {
2285 free_register(regv_h(lreg)); 2285 free_register(regv_h(lreg));
2286 } 2286 }
4881 emit_dpush(int d) 4881 emit_dpush(int d)
4882 { 4882 {
4883 int new_reg; 4883 int new_reg;
4884 if (!is_float_reg(creg)) error(-1); 4884 if (!is_float_reg(creg)) error(-1);
4885 if (freg_sp>MAX_MAX) error(-1); 4885 if (freg_sp>MAX_MAX) error(-1);
4886 new_reg = get_dregister(1); /* Ф˼ */ 4886 new_reg = get_dregister(1); /* 絶対に取れる */
4887 freg_stack[freg_sp++] = freg; /* push 뤫˥쥸Ȥ */ 4887 freg_stack[freg_sp++] = freg; /* push するかわりにレジスタを使う */
4888 creg = freg = new_reg; 4888 creg = freg = new_reg;
4889 } 4889 }
4890 4890
4891 #endif 4891 #endif
4892 4892
5802 emit_lpush() 5802 emit_lpush()
5803 { 5803 {
5804 int new_reg; 5804 int new_reg;
5805 if (!is_longlong_reg(creg)) error(-1); 5805 if (!is_longlong_reg(creg)) error(-1);
5806 if (lreg_sp>MAX_MAX) error(-1); 5806 if (lreg_sp>MAX_MAX) error(-1);
5807 new_reg = get_lregister(); /* Ф˼(?) */ 5807 new_reg = get_lregister(); /* 絶対に取れる(?) */
5808 lreg_stack[lreg_sp++] = creg; /* push 뤫˥쥸Ȥ */ 5808 lreg_stack[lreg_sp++] = creg; /* push するかわりにレジスタを使う */
5809 lreg = creg = new_reg; 5809 lreg = creg = new_reg;
5810 } 5810 }
5811 5811
5812 void 5812 void
5813 code_i2ll(int reg) 5813 code_i2ll(int reg)