Mercurial > hg > CbC > old > device
comparison mc-code-spu.c @ 719:4c5ac4025fbd
*** empty log message ***
author | kono |
---|---|
date | Wed, 28 Nov 2007 19:38:01 +0900 |
parents | d12029c499df |
children | 13e540e7d9bf |
comparison
equal
deleted
inserted
replaced
718:d12029c499df | 719:4c5ac4025fbd |
---|---|
384 | 384 |
385 static void | 385 static void |
386 lvar(int l,char *cext) | 386 lvar(int l,char *cext) |
387 { | 387 { |
388 if (large_lvar) { | 388 if (large_lvar) { |
389 printf("0(%s)\n##lvar0\n",register_name(large_lvar)); | 389 printf("0(%s)\n",register_name(large_lvar)); |
390 free_register(large_lvar); | 390 free_register(large_lvar); |
391 return; | 391 return; |
392 } | 392 } |
393 if (is_code(fnptr)) { | 393 if (is_code(fnptr)) { |
394 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | 394 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ |
395 printf("%d($sp)\n##lvar1\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | 395 printf("%d($sp)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); |
396 } else { | 396 } else { |
397 printf("%d($sp)\n",CODE_LVAR(l)); | 397 printf("%d($sp)\n",CODE_LVAR(l)); |
398 } | 398 } |
399 } else if (l<0) { /* local variable */ | 399 } else if (l<0) { /* local variable */ |
400 printf(".LC%d+%d($sp)\n",lvar_offset_label,FUNC_LVAR(l)); | 400 printf(".LC%d+%d($sp)\n",lvar_offset_label,FUNC_LVAR(l)); |
974 const_list_table(); | 974 const_list_table(); |
975 } | 975 } |
976 return i; | 976 return i; |
977 } | 977 } |
978 */ | 978 */ |
979 #if FLOAT_CODE | |
980 static int | |
981 search_double_const(int tag,int value1,int value2,int *label) | |
982 { | |
983 int p,i,j,list,prev; | |
984 | |
985 for(j=0;j<2;j++) { | |
986 i = 0; | |
987 if(j==1) { | |
988 if (!const_list_label) const_list_label = fwdlabel(); | |
989 *label = const_list_label; | |
990 if (const_list==0) { | |
991 const_list = glist3(tag,glist3(tag,0,value2),value1); | |
992 return 0; | |
993 } else { | |
994 prev = list = const_list; | |
995 } | |
996 } else { | |
997 prev =list = prev_const_list; *label = prev_const_list_label; | |
998 } | |
999 for(p = list; p ;prev=p,p=cadr(p),i+=SIZE_OF_INT) { | |
1000 if (car(p)!=tag) continue; | |
1001 switch(tag) { | |
1002 case DCONST: case LCONST: | |
1003 if (caddr(p)!=value1) continue; | |
1004 p = cadr(p); | |
1005 if (!p||car(p)!=tag) error(-1); | |
1006 if (caddr(p)!=value2) continue; | |
1007 return i; | |
1008 } | |
1009 prev = p; | |
1010 } | |
1011 } | |
1012 cadr(prev) = glist3(tag,glist3(tag,0,value2),value1); | |
1013 if (i>CONST_TBL_COUNT) { | |
1014 const_list_table(); | |
1015 } | |
1016 return i; | |
1017 } | |
1018 #endif | |
1019 | |
1020 static int inst_count; | |
1021 | |
1022 static void | |
1023 const_list_table() | |
1024 { | |
1025 int p,lb=0; | |
1026 inst_count = 0; | |
1027 | |
1028 if (const_list) { | |
1029 if (control) { | |
1030 lb = fwdlabel(); | |
1031 gen_jmp(lb); | |
1032 // printf("\t.align\t2\n"); | |
1033 } | |
1034 fwddef(const_list_label); | |
1035 control=0; | |
1036 for(p = const_list; p ; p = cadr(p)) { | |
1037 switch(car(p)) { | |
1038 case GVAR: printf("\t.word\t%s\n",(ncaddr(p))->nm); break; | |
1039 case DCONST: case LCONST: | |
1040 case CONST: printf("\t.word\t%d\n",caddr(p)); break; | |
1041 case LABEL: printf("\t.word\t.LC%d\n",caddr(p)); break; | |
1042 case LVAR: printf("\t.word\t.LC%d+%d\n", | |
1043 car(caddr(p)),cadr(caddr(p))); break; | |
1044 default: error(-1); | |
1045 } | |
1046 } | |
1047 if (lb) { | |
1048 fwddef(lb); // control==1 now | |
1049 } | |
1050 prev_const_list_label=const_list_label; | |
1051 const_list_label = 0; | |
1052 } | |
1053 for(p = prev_const_list; p ; p = cadr(p)) { | |
1054 if (car(p)==LVAR) { | |
1055 free_glist2(caddr(p)); | |
1056 } | |
1057 } | |
1058 free_glist3_a(prev_const_list); | |
1059 prev_const_list=const_list; | |
1060 const_list = 0; | |
1061 } | |
1062 | |
1063 | 979 |
1064 extern void | 980 extern void |
1065 code_ptr_cache_def(int r, NMTBL *nptr) | 981 code_ptr_cache_def(int r, NMTBL *nptr) |
1066 { | 982 { |
1067 char *rrn = register_name(r); | 983 char *rrn = register_name(r); |
1068 printf("\tlqd\t%s, %d($sp)\n",rrn,(nptr->sc)*16); | 984 printf("\tlqd\t%s, %d($sp)\n",rrn,(nptr->sc)*16); |
1069 } | |
1070 | |
1071 #define mask8(d,bit) (d & (255 << bit)) | |
1072 | |
1073 /* | |
1074 mode CONST or other (CMP is Ok only in stage 1 result) | |
1075 *p1 stage 1 const | |
1076 *p2 stage 2 const | |
1077 *p3 stage 3 const | |
1078 return 0 ... require 4 stage | |
1079 1 ... positive result | |
1080 -1 ... negative result | |
1081 | |
1082 */ | |
1083 static int | |
1084 make_const(int c,int *p1,int *p2,int *p3,int mode) | |
1085 { | |
1086 int sign,im,jm,km; | |
1087 int min_stage = 4; | |
1088 int msign=0,mim=0,mjm,mkm; | |
1089 int id,jd,kd; | |
1090 int i,j,k; | |
1091 int d; | |
1092 if (c == (d = mask8(c,0))) { | |
1093 min_stage=1; min_stage=1; msign = 1; | |
1094 mim = d;mjm = 0;mkm = 0; | |
1095 } else if (mode!=CONST) { | |
1096 if (-c == (d = mask8(-c,0))) { | |
1097 min_stage=1; min_stage=1; msign = -1; | |
1098 mim = d;mjm = 0;mkm = 0; | |
1099 } | |
1100 } else { | |
1101 if (~c== (d = mask8(~c,0))) { | |
1102 min_stage=1; min_stage=1; msign = -1; | |
1103 mim = d;mjm = 0;mkm = 0; | |
1104 } | |
1105 } | |
1106 for(sign=1;sign>=-1;sign-=2) { | |
1107 if (min_stage==1) break; | |
1108 for(i=24;i>=0;i-=2) { | |
1109 jm = km = 0; | |
1110 if (sign>0) { | |
1111 if (c == (d = mask8(c,i))) { | |
1112 min_stage=1; min_stage=1; msign = 1; | |
1113 mim = d;mjm = 0;mkm = 0; | |
1114 break; | |
1115 } | |
1116 id = c - d; | |
1117 } else if (mode!=CONST) { | |
1118 if (-c == (d = mask8(-c,i))) { | |
1119 min_stage=1; min_stage=1; msign = -1; | |
1120 mim = d;mjm = 0;mkm = 0; | |
1121 break; | |
1122 } | |
1123 id = -c - d; | |
1124 } else { | |
1125 if (~c== (d = mask8(~c,i))) { | |
1126 min_stage=1; min_stage=1; msign = -1; | |
1127 mim = d;mjm = 0;mkm = 0; | |
1128 break; | |
1129 } | |
1130 id = ~c - d; | |
1131 } | |
1132 if (d==0) continue; | |
1133 im = d; | |
1134 if (min_stage<=2) continue; | |
1135 for(j=i-8;j>=0;j-=2) { | |
1136 km = 0; | |
1137 if (!(jm=mask8(id,j))) continue; | |
1138 jd = id - jm; | |
1139 if (jd==0) { | |
1140 min_stage=2; msign = sign; | |
1141 mim = im;mjm = jm;mkm = km; | |
1142 break; | |
1143 } | |
1144 if (min_stage<=3) continue; | |
1145 for(k=j-8;k>=0;k-=2) { | |
1146 if (!(km=mask8(jd,k))) continue; | |
1147 kd = jd - km; | |
1148 if (kd==0) { | |
1149 min_stage=3; msign = sign; | |
1150 mim = im;mjm = jm;mkm = km; | |
1151 break; | |
1152 } | |
1153 } | |
1154 } | |
1155 } | |
1156 } | |
1157 if (min_stage<=3) { | |
1158 *p1 = mim; *p2= mjm; *p3 = mkm; | |
1159 return msign; | |
1160 } else return 0; | |
1161 } | 985 } |
1162 | 986 |
1163 static int | 987 static int |
1164 is_stage1_const(int c,int mode) | 988 is_stage1_const(int c,int mode) |
1165 { | 989 { |
1166 int sign,p1=0,p2=0,p3=0; | 990 return mode?(0<=c && c<262143): (-32768<=c && c<32767); |
1167 sign = make_const(c,&p1,&p2,&p3,mode); | |
1168 return (c==0||(p1&&!p2&&!p3))?sign:0; | |
1169 } | 991 } |
1170 | 992 |
1171 extern void | 993 extern void |
1172 code_const(int e2,int reg) { | 994 code_const(int e2,int reg) { |
1173 char *crn; | 995 char *crn; |
1216 char *crn = register_name(reg); | 1038 char *crn = register_name(reg); |
1217 char *rrn = register_name(r); | 1039 char *rrn = register_name(r); |
1218 char *rn2 = register_name(r+1); | 1040 char *rn2 = register_name(r+1); |
1219 char *drn; | 1041 char *drn; |
1220 int dreg; | 1042 int dreg; |
1221 int s,p1,p2,p3,h; | |
1222 char *add; | |
1223 if (offset==0) { | 1043 if (offset==0) { |
1224 if(r!=reg) | 1044 if(r!=reg) |
1225 printf("\tori\t%s, %s, 0\n",crn,rrn); | 1045 printf("\tori\t%s, %s, 0\n",crn,rrn); |
1226 } else if ((s=make_const(offset,&p1,&p2,&p3,0))) { | |
1227 add = s>0?"a":"sf"; | |
1228 //printf("\t%s\t%s, %s, %d\n",add,crn,rrn,p1); | |
1229 if (-32768<(p1+p2+p3)&&(p1+p2+p3)<32768) | |
1230 printf("\til\t%s,%d\n",rn2,(p1+p2+p3)); | |
1231 else if( (p1+p2+p3) > 32767 && (p1+p2+p3) < 262144) | |
1232 printf("\tila\t%s, %d\n",rn2,p1+p2+p3); | |
1233 else if( (p1+p2+p3) > 262143) { | |
1234 printf("\tilhu\t%s, %d\n",rn2,(p1+p2+p3)/65536); | |
1235 printf("\tiohl\t%s, %d\n",rn2,(p1+p2+p3)%65536); | |
1236 } else { | |
1237 h = (~(p1+p2+p3) >> 16) & 0xffff; | |
1238 h += 1; | |
1239 h = -h; | |
1240 printf("\tilhu\t%s,%d\n",crn,h); | |
1241 if(((p1+p2)&0xffff) > -262143) | |
1242 printf("\tiohl %s,%d\n",crn, ((p1+p2)&0xffff)); | |
1243 else | |
1244 printf("\tori %s,%s,%d\n",crn,crn,((p1+p2)&0xffff)); | |
1245 | |
1246 } | |
1247 | |
1248 printf("\t%s\t%s, %s, %s\n", add, crn, rrn ,rn2); | |
1249 } else { | 1046 } else { |
1250 drn = register_name(dreg = get_register()); | 1047 drn = register_name(dreg = get_register()); |
1251 printf("\ta\t%s, %s, %s\n",crn,drn,rrn); | 1048 printf("\ta\t%s, %s, %s\n",crn,drn,rrn); |
1252 free_register(dreg); | 1049 free_register(dreg); |
1253 } | 1050 } |
1282 free_register(reg); | 1079 free_register(reg); |
1283 } | 1080 } |
1284 } | 1081 } |
1285 | 1082 |
1286 | 1083 |
1287 #define cload(sz,sign) \ | 1084 /* |
1288 (sz==1?(sign?"lqd":"lqd"):sz==SIZE_OF_SHORT?(sign?"lqd":"lqd"):"lqd") | 1085 |
1086 store | |
1087 lqd $2,176($sp) | |
1088 cbd $3,0($sp) | |
1089 shufb $2,$4,$2,$3 | |
1090 stqd $2,176($sp) | |
1091 unsigned load | |
1092 rotqbyi $2,$2,13 | |
1093 andi $4,$2,0x00ff | |
1094 | |
1095 */ | |
1096 | |
1289 | 1097 |
1290 | 1098 |
1291 #define cext(sign,sz,reg) | 1099 #define cext(sign,sz,reg) |
1292 | 1100 |
1293 static char * | 1101 static char * |
1304 } | 1112 } |
1305 | 1113 |
1306 void | 1114 void |
1307 code_gvar(int e1,int reg) { | 1115 code_gvar(int e1,int reg) { |
1308 use_int(reg); | 1116 use_int(reg); |
1309 code_add(reg,cadr(e1),get_ptr_cache(ncaddr(e1))); | |
1310 return; | 1117 return; |
1311 } | 1118 } |
1312 | 1119 |
1313 void | 1120 void |
1314 code_rgvar(int e1,int reg) { | 1121 code_rgvar(int e1,int reg) { |
1315 use_int(reg); | 1122 use_int(reg); |
1316 code_ld("lqd",reg,cadr(e1),get_ptr_cache(ncaddr(e1)),""); | |
1317 } | 1123 } |
1318 | 1124 |
1319 void | 1125 void |
1320 code_crgvar(int e1,int reg,int sign,int sz){ | 1126 code_crgvar(int e1,int reg,int sign,int sz){ |
1321 use_int(reg); | 1127 use_int(reg); |
1322 code_ld(cload(sz,sign),reg,cadr(e1),get_ptr_cache(ncaddr(e1)), | |
1323 cext_at(sz,sign)); | |
1324 cext(sign,sz,reg); | 1128 cext(sign,sz,reg); |
1325 } | 1129 } |
1326 | 1130 |
1327 | 1131 |
1328 void | 1132 void |
1443 drn = register_name(reg); | 1247 drn = register_name(reg); |
1444 set_ireg(reg,0); | 1248 set_ireg(reg,0); |
1445 } else { | 1249 } else { |
1446 drn = register_name(reg); | 1250 drn = register_name(reg); |
1447 } | 1251 } |
1448 // ldrb r2, [ip, #-1]! @ zero_extendqisi2 | |
1449 // ??????offset???????????12bit! | |
1450 code_ld(cload(sz,sign),reg,0,xreg,cext_at(sz,sign)); | 1252 code_ld(cload(sz,sign),reg,0,xreg,cext_at(sz,sign)); |
1451 code_add(reg,dir,reg); | 1253 code_add(reg,dir,reg); |
1452 code_ldf(cstore(sz),drn,0,xreg,sz==SIZE_OF_SHORT?" @ movhi":""); | 1254 code_ldf(cstore(sz),drn,0,xreg,sz==SIZE_OF_SHORT?" @ movhi":""); |
1453 } | 1255 } |
1454 | 1256 |