Mercurial > hg > CbC > old > device
comparison mc-code-powerpc.c @ 660:3e1dba5758d8
*** empty log message ***
author | kono |
---|---|
date | Wed, 31 Jan 2007 16:06:04 +0900 |
parents | cddab906095e |
children | c9df4e08da9b |
comparison
equal
deleted
inserted
replaced
659:2a3b1cddd45f | 660:3e1dba5758d8 |
---|---|
151 #define LREG_LREGISTER (MAX_TMP_REG+LREG_OFFSET) | 151 #define LREG_LREGISTER (MAX_TMP_REG+LREG_OFFSET) |
152 | 152 |
153 | 153 |
154 static int max_reg_var, max_freg_var; | 154 static int max_reg_var, max_freg_var; |
155 | 155 |
156 #ifdef __APPLE__ | |
156 static char *reg_name[] = { | 157 static char *reg_name[] = { |
157 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", | 158 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9", |
158 "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", | 159 "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19", |
159 "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", | 160 "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29", |
160 "r30","r31", | 161 "r30","r31", |
161 "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", | 162 "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9", |
162 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", | 163 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19", |
163 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", | 164 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29", |
164 "f30","f31" | 165 "f30","f31" |
165 }; | 166 }; |
167 #else | |
168 // PS3 (PowerPC Fedora Core) | |
169 static char *reg_name[] = { | |
170 "0","1","2","3","4","5","6","7","8","9", | |
171 "10","11","12","13","14","15","16","17","18","19", | |
172 "20","21","22","23","24","25","26","27","28","29", | |
173 "30","31", | |
174 "0","1","2","3","4","5","6","7","8","9", | |
175 "10","11","12","13","14","15","16","17","18","19", | |
176 "20","21","22","23","24","25","26","27","28","29", | |
177 "30","31" | |
178 }; | |
179 #endif | |
166 | 180 |
167 #define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) | 181 #define round4(i) ((i+(SIZE_OF_INT-1))&~(SIZE_OF_INT-1)) |
168 | 182 |
169 #define register_name(i) reg_name[i] | 183 #define register_name(i) reg_name[i] |
170 #define fregister_name(i) reg_name[i] | 184 #define fregister_name(i) reg_name[i] |
370 printf("## offset cargn\t%d %d\n",CALLEE_ARG+r1_offsetv,my_func_args); | 384 printf("## offset cargn\t%d %d\n",CALLEE_ARG+r1_offsetv,my_func_args); |
371 #endif | 385 #endif |
372 } | 386 } |
373 | 387 |
374 static int large_offset_reg; | 388 static int large_offset_reg; |
389 | |
390 #ifdef __APPLE__ | |
375 | 391 |
376 static void | 392 static void |
377 lvar(int l) | 393 lvar(int l) |
378 { | 394 { |
379 char *rn; | 395 char *rn; |
446 printf("\taddis %s,r1,ha16(%d)\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); | 462 printf("\taddis %s,r1,ha16(%d)\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); |
447 } | 463 } |
448 } else { /* callee's arguments */ | 464 } else { /* callee's arguments */ |
449 if (LARGE_OFFSET(CALLEE_ARG(l))) { | 465 if (LARGE_OFFSET(CALLEE_ARG(l))) { |
450 rn=register_name(large_offset_reg=get_register()); | 466 rn=register_name(large_offset_reg=get_register()); |
451 printf("\taddis %s,r30,lo16(%d+L_%d)\n", | 467 printf("\taddis %s,r30,ha16(%d+L_%d)\n", |
452 rn,CALLEE_ARG(l),lvar_offset_label); | 468 rn,CALLEE_ARG(l),lvar_offset_label); |
453 } | 469 } |
454 } | 470 } |
455 } | 471 } |
456 | 472 |
473 #else /* PS3 */ | |
474 | |
475 static void | |
476 lvar(int l) | |
477 { | |
478 char *rn; | |
479 if (!large_offset_reg) { | |
480 if (is_code(fnptr)) { | |
481 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
482 printf("%d@l(1)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | |
483 } else | |
484 printf("%d@l(30)\n",CODE_LVAR(l)); | |
485 } else if (l<0) { /* local variable */ | |
486 printf("%d@l(30)\n",FUNC_LVAR(l)); | |
487 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
488 printf("%d@l(1)\n",CALLER_ARG(l-ARG_LVAR_OFFSET)); | |
489 } else { /* callee's arguments */ | |
490 printf("%d+L_%d@l(30)\n",CALLEE_ARG(l),lvar_offset_label); | |
491 } | |
492 } else { | |
493 rn = register_name(large_offset_reg); | |
494 if (is_code(fnptr)) { | |
495 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
496 printf("%d@l(%s)\n",CODE_CALLER_ARG(l-ARG_LVAR_OFFSET),rn); | |
497 } else | |
498 printf("%d@l(%s)\n",CODE_LVAR(l),rn); | |
499 } else if (l<0) { /* local variable */ | |
500 printf("%d@l(%s)\n",FUNC_LVAR(l),rn); | |
501 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
502 printf("%d@l(%s)\n",CALLER_ARG(l-ARG_LVAR_OFFSET),rn); | |
503 } else { /* callee's arguments */ | |
504 printf("%d+L_%d@l(%s)\n",CALLEE_ARG(l),lvar_offset_label,rn); | |
505 } | |
506 free_register(large_offset_reg); | |
507 } | |
508 } | |
509 | |
510 /* if size of local variables / input variables is more then 64k, | |
511 lo16 does not work. We have to use ha16 also. But we can't know | |
512 the exact size in one path compile. We may safely use lvar16ha | |
513 if disp or max_func_args > 32k. Of course this is redundant for | |
514 smaller offset. But who cares who use very large local variables? | |
515 */ | |
516 | |
517 #define LARGE_OFFSET(l) (l<-32000||l>32000) | |
518 | |
519 static void | |
520 lvar_intro(int l) | |
521 { | |
522 char *rn; | |
523 large_offset_reg=0; | |
524 if (is_code(fnptr)) { | |
525 if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
526 if (LARGE_OFFSET(CODE_CALLER_ARG(l-ARG_LVAR_OFFSET))) { | |
527 rn=register_name(large_offset_reg=get_register()); | |
528 printf("\tla %s,1,%d@ha\n",rn, | |
529 CODE_CALLER_ARG(l-ARG_LVAR_OFFSET)); | |
530 } | |
531 } else { | |
532 if (LARGE_OFFSET(CODE_LVAR(l))) { | |
533 rn=register_name(large_offset_reg=get_register()); | |
534 printf("\tla %s,30,%d@ha\n",rn,CODE_LVAR(l)); | |
535 } | |
536 } | |
537 } else if (l<0) { /* local variable */ | |
538 if (LARGE_OFFSET(FUNC_LVAR(l))) { | |
539 rn=register_name(large_offset_reg=get_register()); | |
540 printf("\tla %s,30,%d@ha\n",rn,FUNC_LVAR(l)); | |
541 } | |
542 } else if (l>=ARG_LVAR_OFFSET) { /* caller's arguments */ | |
543 if (LARGE_OFFSET(CALLER_ARG(l-ARG_LVAR_OFFSET))) { | |
544 rn=register_name(large_offset_reg=get_register()); | |
545 printf("\tla %s,1,%d@ha\n",rn,CALLER_ARG(l-ARG_LVAR_OFFSET)); | |
546 } | |
547 } else { /* callee's arguments */ | |
548 if (LARGE_OFFSET(CALLEE_ARG(l))) { | |
549 rn=register_name(large_offset_reg=get_register()); | |
550 printf("\tla %s,30,%d+L_%d@ha\n", | |
551 rn,CALLEE_ARG(l),lvar_offset_label); | |
552 } | |
553 } | |
554 } | |
555 #endif | |
457 | 556 |
458 void | 557 void |
459 code_lvar(int e2,int reg) { | 558 code_lvar(int e2,int reg) { |
460 use_int(reg); | 559 use_int(reg); |
461 lvar_intro(e2); | 560 lvar_intro(e2); |
1138 xreg = reg; | 1237 xreg = reg; |
1139 } | 1238 } |
1140 return xreg; | 1239 return xreg; |
1141 } | 1240 } |
1142 | 1241 |
1242 #ifdef __APPLE__ | |
1143 static int code_base; | 1243 static int code_base; |
1244 #endif | |
1144 | 1245 |
1145 extern void | 1246 extern void |
1146 code_ptr_cache_def(int r,NMTBL *nptr) | 1247 code_ptr_cache_def(int r,NMTBL *nptr) |
1147 { | 1248 { |
1148 char *rrn = register_name(r); | 1249 char *rrn = register_name(r); |
1250 #ifdef __APPLE__ | |
1149 if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { | 1251 if (nptr->sc==STATIC && !(is_code(nptr)||is_function(nptr))) { |
1150 printf("\taddis %s,r31,ha16(_%s-L_%d)\n", | 1252 printf("\taddis %s,r31,ha16(_%s-L_%d)\n", |
1151 rrn,nptr->nm,code_base); | 1253 rrn,nptr->nm,code_base); |
1152 printf("\tla %s,lo16(_%s-L_%d)(%s)\n", | 1254 printf("\tla %s,lo16(_%s-L_%d)(%s)\n", |
1153 rrn,nptr->nm,code_base,rrn); | 1255 rrn,nptr->nm,code_base,rrn); |
1155 printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n", | 1257 printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-L_%d)\n", |
1156 rrn,nptr->nm,code_base); | 1258 rrn,nptr->nm,code_base); |
1157 printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n", | 1259 printf("\tlwz %s,lo16(L_%s$non_lazy_ptr-L_%d)(%s)\n", |
1158 rrn,nptr->nm,code_base,rrn); | 1260 rrn,nptr->nm,code_base,rrn); |
1159 } | 1261 } |
1262 #else | |
1263 printf("\tlis %s,%s@ha\n", | |
1264 rrn,nptr->nm); | |
1265 printf("\tla %s,%s@l(%s)\n", | |
1266 rrn,nptr->nm,rrn); | |
1267 #endif | |
1160 } | 1268 } |
1161 | 1269 |
1162 static char *cload(int sz) { return sz==1?"lbz":sz==SIZE_OF_SHORT?"lhz":"lwz"; } | 1270 static char *cload(int sz) { return sz==1?"lbz":sz==SIZE_OF_SHORT?"lhz":"lwz"; } |
1163 static char *cstore(int sz) { return sz==1?"stb":sz==SIZE_OF_SHORT?"sth":"stw"; } | 1271 static char *cstore(int sz) { return sz==1?"stb":sz==SIZE_OF_SHORT?"sth":"stw"; } |
1164 | 1272 |
1182 | 1290 |
1183 void | 1291 void |
1184 code_label(int labelno) | 1292 code_label(int labelno) |
1185 { | 1293 { |
1186 clear_ptr_cache(); | 1294 clear_ptr_cache(); |
1295 #ifdef __APPLE__ | |
1187 printf("L_%d:\n",labelno); | 1296 printf("L_%d:\n",labelno); |
1297 #else | |
1298 printf(".LC%d:\n",labelno); | |
1299 #endif | |
1188 } | 1300 } |
1189 | 1301 |
1190 static void | 1302 static void |
1191 code_add(int reg,int offset,int r) | 1303 code_add(int reg,int offset,int r) |
1192 { | 1304 { |
1194 char *rrn = register_name(r); | 1306 char *rrn = register_name(r); |
1195 if (offset==0) { | 1307 if (offset==0) { |
1196 if(r!=reg) | 1308 if(r!=reg) |
1197 printf("\tmr %s,%s\n",crn,rrn); | 1309 printf("\tmr %s,%s\n",crn,rrn); |
1198 } else if (LARGE_OFFSET(offset)) { | 1310 } else if (LARGE_OFFSET(offset)) { |
1311 #ifdef __APPLE__ | |
1199 printf("\tla %s,lo16(%d)(%s)\n",crn,offset,rrn); | 1312 printf("\tla %s,lo16(%d)(%s)\n",crn,offset,rrn); |
1200 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); | 1313 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); |
1314 #else | |
1315 printf("\tla %s,%d@l(%s)\n",crn,offset,rrn); | |
1316 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); | |
1317 #endif | |
1201 } else | 1318 } else |
1202 printf("\taddi %s,%s,%d\n",crn,rrn,offset); | 1319 printf("\taddi %s,%s,%d\n",crn,rrn,offset); |
1203 } | 1320 } |
1204 | 1321 |
1205 static void | 1322 static void |
1206 code_ld(char *ld,int reg,int offset,int r) | 1323 code_ld(char *ld,int reg,int offset,int r) |
1207 { | 1324 { |
1208 char *crn = register_name(reg); | 1325 char *crn = register_name(reg); |
1209 char *rrn = register_name(r); | 1326 char *rrn = register_name(r); |
1210 if (LARGE_OFFSET(offset)) { | 1327 if (LARGE_OFFSET(offset)) { |
1328 #ifdef __APPLE__ | |
1211 printf("\taddis %s,%s,ha16(%d)\n",crn,rrn,offset); | 1329 printf("\taddis %s,%s,ha16(%d)\n",crn,rrn,offset); |
1212 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,crn); | 1330 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,crn); |
1331 #else | |
1332 printf("\taddis %s,%s,%d@ha\n",crn,rrn,offset); | |
1333 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,crn); | |
1334 #endif | |
1213 } else | 1335 } else |
1214 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); | 1336 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); |
1215 } | 1337 } |
1216 | 1338 |
1217 static void | 1339 static void |
1220 char *rrn = register_name(r); | 1342 char *rrn = register_name(r); |
1221 int reg; | 1343 int reg; |
1222 char *lrn; | 1344 char *lrn; |
1223 if (offset<-32768||32767<offset) { | 1345 if (offset<-32768||32767<offset) { |
1224 lrn = register_name(reg = get_register()); | 1346 lrn = register_name(reg = get_register()); |
1347 #ifdef __APPLE__ | |
1225 printf("\taddis %s,%s,ha16(%d)\n",lrn,rrn,offset); | 1348 printf("\taddis %s,%s,ha16(%d)\n",lrn,rrn,offset); |
1226 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,lrn); | 1349 printf("\t%s %s,lo16(%d)(%s)\n",ld,crn,offset,lrn); |
1350 #else | |
1351 printf("\taddis %s,%s,%d@ha\n",lrn,rrn,offset); | |
1352 printf("\t%s %s,%d@l(%s)\n",ld,crn,offset,lrn); | |
1353 #endif | |
1227 free_register(reg); | 1354 free_register(reg); |
1228 } else | 1355 } else |
1229 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); | 1356 printf("\t%s %s,%d(%s)\n",ld,crn,offset,rrn); |
1230 } | 1357 } |
1231 | 1358 |
1316 void | 1443 void |
1317 code_label_value(int label,int reg) { | 1444 code_label_value(int label,int reg) { |
1318 char *crn; | 1445 char *crn; |
1319 use_int(reg); | 1446 use_int(reg); |
1320 crn = register_name(reg); | 1447 crn = register_name(reg); |
1448 #ifdef __APPLE___ | |
1321 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,label,code_base); | 1449 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,label,code_base); |
1322 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,label,code_base,crn); | 1450 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,label,code_base,crn); |
1451 #else | |
1452 printf("\tlis %s,.LC%d@ha\n",crn,label); | |
1453 printf("\tla %s,.LC%d@l(%s)\n",crn,label,crn); | |
1454 #endif | |
1323 return; | 1455 return; |
1324 } | 1456 } |
1325 | 1457 |
1326 void | 1458 void |
1327 code_const(int e2,int reg) { | 1459 code_const(int e2,int reg) { |
1328 char *crn; | 1460 char *crn; |
1329 use_int(reg); | 1461 use_int(reg); |
1330 crn = register_name(reg); | 1462 crn = register_name(reg); |
1331 // printf("## 0x%08x\n",e2); | 1463 // printf("## 0x%08x\n",e2); |
1464 #ifdef __APPLE__ | |
1332 if (-32768<e2&&e2<32768) | 1465 if (-32768<e2&&e2<32768) |
1333 printf("\tli %s,%d\n",crn,e2); | 1466 printf("\tli %s,%d\n",crn,e2); |
1334 else if ((e2&0xffff)==0) | 1467 else if ((e2&0xffff)==0) |
1335 printf("\tlis %s,ha16(%d)\n",crn,e2); | 1468 printf("\tlis %s,ha16(%d)\n",crn,e2); |
1336 else { | 1469 else { |
1337 printf("\tlis %s,ha16(%d)\n",crn,e2); | 1470 printf("\tlis %s,ha16(%d)\n",crn,e2); |
1338 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); | 1471 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2); |
1339 } | 1472 } |
1473 #else | |
1474 if (-32768<e2&&e2<32768) | |
1475 printf("\tli %s,%d\n",crn,e2); | |
1476 else if ((e2&0xffff)==0) | |
1477 printf("\tlis %s,%d@ha\n",crn,e2); | |
1478 else { | |
1479 printf("\tlis %s,%d@ha\n",crn,e2); | |
1480 printf("\taddi %s,%s,%d@l\n",crn,crn,e2); | |
1481 } | |
1482 #endif | |
1340 } | 1483 } |
1341 | 1484 |
1342 void | 1485 void |
1343 code_neg(int creg) { | 1486 code_neg(int creg) { |
1344 use_int(creg); | 1487 use_int(creg); |
1355 | 1498 |
1356 | 1499 |
1357 void | 1500 void |
1358 code_lnot(int creg) { | 1501 code_lnot(int creg) { |
1359 use_int(creg); | 1502 use_int(creg); |
1503 #ifdef __APPLE__ | |
1360 printf("\tsubfic r0,%s,0\n", register_name(creg)); | 1504 printf("\tsubfic r0,%s,0\n", register_name(creg)); |
1361 printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg)); | 1505 printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg)); |
1506 #else | |
1507 printf("\tsubfic 0,%s,0\n", register_name(creg)); | |
1508 printf("\tadde %s,0,%s\n", register_name(creg),register_name(creg)); | |
1509 #endif | |
1362 } | 1510 } |
1363 | 1511 |
1364 void | 1512 void |
1365 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { | 1513 code_preinc(int e1,int e2,int dir,int sign,int sz,int reg) { |
1366 char *xrn,*drn; | 1514 char *xrn,*drn; |
1423 | 1571 |
1424 void | 1572 void |
1425 code_return(int creg) { | 1573 code_return(int creg) { |
1426 char *crn; | 1574 char *crn; |
1427 use_int(creg); | 1575 use_int(creg); |
1428 crn = register_name(creg); | 1576 code_label_value(retcont,creg); |
1429 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,retcont,code_base); | |
1430 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,retcont,code_base,crn); | |
1431 } | 1577 } |
1432 | 1578 |
1433 #define R1SAVE 0 | 1579 #define R1SAVE 0 |
1434 | 1580 |
1435 void | 1581 void |
1436 code_environment(int creg) { | 1582 code_environment(int creg) { |
1437 /* save frame pointer */ | 1583 /* save frame pointer */ |
1438 use_int(creg); | 1584 use_int(creg); |
1439 #if R1SAVE | 1585 #if R1SAVE |
1440 printf("\tlwz %s,0(r1)\n",register_name(creg)); | 1586 printf("\tlwz %s,0(%s)\n",register_name(creg),register_name(1)); |
1441 #else | 1587 #else |
1442 printf("\tmr %s,r30\n",register_name(creg)); | 1588 printf("\tmr %s,%s\n",register_name(creg),register_name(30)); |
1443 // int l = 0; | 1589 // int l = 0; |
1444 // printf("\tla %s,",register_name(creg)); | 1590 // printf("\tla %s,",register_name(creg)); |
1445 // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); | 1591 // printf("lo16(%d+L_%d)(r30)\n",FUNC_LVAR,lvar_offset_label); |
1446 #endif | 1592 #endif |
1447 } | 1593 } |
1511 code_cmp_crgvar(int e1,int reg,int sz,int label,int cond) { | 1657 code_cmp_crgvar(int e1,int reg,int sz,int label,int cond) { |
1512 use_int(reg); | 1658 use_int(reg); |
1513 code_ld(cload(sz),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); | 1659 code_ld(cload(sz),reg,cadr(e1),get_ptr_cache((NMTBL*)caddr(e1))); |
1514 cext(0,sz,reg); | 1660 cext(0,sz,reg); |
1515 inc_cmpflag(); | 1661 inc_cmpflag(); |
1662 #ifdef __APPLE__ | |
1516 printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(reg)); | 1663 printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(reg)); |
1664 #else | |
1665 printf("\tcmpwi %d,%s,0\n",cmpflag,register_name(reg)); | |
1666 #endif | |
1517 jcond(label,cond); | 1667 jcond(label,cond); |
1518 } | 1668 } |
1519 | 1669 |
1520 | 1670 |
1521 void | 1671 void |
1553 | 1703 |
1554 void | 1704 void |
1555 code_cmp_register(int e2,int label,int cond) { | 1705 code_cmp_register(int e2,int label,int cond) { |
1556 use_int(e2); | 1706 use_int(e2); |
1557 inc_cmpflag(); | 1707 inc_cmpflag(); |
1708 #ifdef __APPLE__ | |
1558 printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(e2)); | 1709 printf("\tcmpwi cr%d,%s,0\n",cmpflag,register_name(e2)); |
1710 #else | |
1711 printf("\tcmpwi %d,%s,0\n",cmpflag,register_name(e2)); | |
1712 #endif | |
1559 jcond(label,cond); | 1713 jcond(label,cond); |
1560 } | 1714 } |
1561 | 1715 |
1562 | 1716 |
1563 void | 1717 void |
1564 code_string(int e1,int creg) | 1718 code_string(int e1,int creg) |
1565 { | 1719 { |
1566 int lb; | 1720 int lb; |
1567 char *crn; | |
1568 NMTBL *n = (NMTBL *)cadr(e1); | 1721 NMTBL *n = (NMTBL *)cadr(e1); |
1569 if ((lb=attr_value(n,LABEL))) { | 1722 if ((lb=attr_value(n,LABEL))) { |
1570 // already defined | 1723 // already defined |
1571 return code_label_value(lb,creg) ; | 1724 return code_label_value(lb,creg) ; |
1572 } | 1725 } |
1573 | 1726 |
1574 use_int(creg); | 1727 use_int(creg); |
1575 crn = register_name(creg); | |
1576 lb = emit_string_label(); | 1728 lb = emit_string_label(); |
1577 ascii(n->nm); | 1729 ascii(n->nm); |
1578 if (output_mode==TEXT_EMIT_MODE) { | 1730 if (output_mode==TEXT_EMIT_MODE) { |
1579 printf(".text\n"); | 1731 printf(".text\n"); |
1580 } else { | 1732 } else { |
1581 text_mode(0); | 1733 text_mode(0); |
1582 } | 1734 } |
1583 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",crn,lb,code_base); | 1735 code_label_value(lb,creg); |
1584 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",crn,lb,code_base,crn); | |
1585 set_attr(n,LABEL,lb); | 1736 set_attr(n,LABEL,lb); |
1586 } | 1737 } |
1587 | 1738 |
1588 #define MAX_COPY_LEN 20 | 1739 #define MAX_COPY_LEN 20 |
1589 // #define MAX_COPY_LEN 10 | 1740 // #define MAX_COPY_LEN 10 |
1646 | 1797 |
1647 l = list3(3,0,to); | 1798 l = list3(3,0,to); |
1648 l = list3(4,l,from); | 1799 l = list3(4,l,from); |
1649 parallel_rassign(l); | 1800 parallel_rassign(l); |
1650 | 1801 |
1802 #ifdef __APPLE__ | |
1651 printf("\tli r5,%d\n",length>0?length:-length); | 1803 printf("\tli r5,%d\n",length>0?length:-length); |
1652 /* offset should be ignored */ | 1804 /* offset should be ignored */ |
1653 /* overrap must be allowed */ | 1805 /* overrap must be allowed */ |
1654 printf("\tbl L_%s$stub\n",memmove); | 1806 printf("\tbl L_%s$stub\n",memmove); |
1807 #else | |
1808 printf("\tli 5,%d\n",length>0?length:-length); | |
1809 /* offset should be ignored */ | |
1810 /* overrap must be allowed */ | |
1811 printf("\tbl %s\n",memmove); | |
1812 #endif | |
1655 extern_define(memmove,0,FUNCTION,1); | 1813 extern_define(memmove,0,FUNCTION,1); |
1656 set_ireg(RET_REGISTER,0); | 1814 set_ireg(RET_REGISTER,0); |
1657 //if (creg!=to) { | 1815 //if (creg!=to) { |
1658 // free_register(to); to = creg; | 1816 // free_register(to); to = creg; |
1659 //} | 1817 //} |
1777 { | 1935 { |
1778 // save_stack,clear_ptr_cache is assumed | 1936 // save_stack,clear_ptr_cache is assumed |
1779 if (!is_longlong_reg(reg)) { error(-1); return; } | 1937 if (!is_longlong_reg(reg)) { error(-1); return; } |
1780 if (mode) { | 1938 if (mode) { |
1781 if (regv_l(reg)!=3) | 1939 if (regv_l(reg)!=3) |
1782 printf("\tmr r3,%s\n", lregister_name_high(reg)); | 1940 printf("\tmr %s,%s\n", register_name(3),lregister_name_high(reg)); |
1783 if (regv_l(reg)!=4) | 1941 if (regv_l(reg)!=4) |
1784 printf("\tmr r4,%s\n", lregister_name_low(reg)); | 1942 printf("\tmr %s,%s\n", register_name(4),lregister_name_low(reg)); |
1785 } | 1943 } |
1786 } | 1944 } |
1787 | 1945 |
1788 static void | 1946 static void |
1789 set_lreg_operand1(int reg,int mode) | 1947 set_lreg_operand1(int reg,int mode) |
1790 { | 1948 { |
1791 // save_stack,clear_ptr_cache is assumed | 1949 // save_stack,clear_ptr_cache is assumed |
1792 if (!is_longlong_reg(reg)) { error(-1); return; } | 1950 if (!is_longlong_reg(reg)) { error(-1); return; } |
1793 if (mode) { | 1951 if (mode) { |
1794 if (regv_l(reg)!=5) | 1952 if (regv_l(reg)!=5) |
1795 printf("\tmr r5,%s\n", lregister_name_high(reg)); | 1953 printf("\tmr %s,%s\n", register_name(5),lregister_name_high(reg)); |
1796 if (regv_l(reg)!=6) | 1954 if (regv_l(reg)!=6) |
1797 printf("\tmr r6,%s\n", lregister_name_low(reg)); | 1955 printf("\tmr %s,%s\n", register_name(6),lregister_name_low(reg)); |
1798 } | 1956 } |
1799 } | 1957 } |
1800 | 1958 |
1801 static void | 1959 static void |
1802 use_reg(int arg) | 1960 use_reg(int arg) |
2246 for(;arg_assign;arg_assign=cadr(arg_assign)) { | 2404 for(;arg_assign;arg_assign=cadr(arg_assign)) { |
2247 g_expr_u(car(arg_assign)); | 2405 g_expr_u(car(arg_assign)); |
2248 } | 2406 } |
2249 clear_ptr_cache(); | 2407 clear_ptr_cache(); |
2250 if (car(e2) == FNAME) { | 2408 if (car(e2) == FNAME) { |
2409 #ifdef __APPLE__ | |
2251 printf("\tbl\tL_%s$stub\n",fn->nm); | 2410 printf("\tbl\tL_%s$stub\n",fn->nm); |
2411 #else | |
2412 printf("\tbl\t%s\n",fn->nm); | |
2413 #endif | |
2252 } else { | 2414 } else { |
2253 jrn = register_name(cadr(jmp)); | 2415 jrn = register_name(cadr(jmp)); |
2254 printf("\tmtctr %s\n",jrn); | 2416 printf("\tmtctr %s\n",jrn); |
2255 printf("\tbctrl\n"); | 2417 printf("\tbctrl\n"); |
2256 } | 2418 } |
2286 use_int(reg); | 2448 use_int(reg); |
2287 g = get_register(); | 2449 g = get_register(); |
2288 crn = register_name(reg); | 2450 crn = register_name(reg); |
2289 grn = register_name(g); | 2451 grn = register_name(g); |
2290 // printf("\trlwinm r0,%s,0,0,27\n",crn); | 2452 // printf("\trlwinm r0,%s,0,0,27\n",crn); |
2291 printf("\tlwz %s,0(r1)\n",grn); | 2453 printf("\tlwz %s,0(%s)\n",grn,register_name(1)); |
2292 printf("\tneg %s,%s\n",crn,crn); | 2454 printf("\tneg %s,%s\n",crn,crn); |
2293 printf("\tstwux %s,r1,%s\n",grn,crn); | 2455 printf("\tstwux %s,%s,%s\n",grn,register_name(1),crn); |
2294 // printf("\tstw %s,0(r1)\n",grn); | 2456 // printf("\tstw %s,0(r1)\n",grn); |
2295 if (!max_func_arg_label) max_func_arg_label = fwdlabel(); | 2457 if (!max_func_arg_label) max_func_arg_label = fwdlabel(); |
2458 #ifdef __APPLE__ | |
2296 printf("\taddis r1,r1,ha16(L_%d)\n",max_func_arg_label); | 2459 printf("\taddis r1,r1,ha16(L_%d)\n",max_func_arg_label); |
2297 printf("\taddi %s,r1,lo16(L_%d)\n",crn,max_func_arg_label); | 2460 printf("\taddi %s,r1,lo16(L_%d)\n",crn,max_func_arg_label); |
2461 #else | |
2462 printf("\taddis 1,1,.LC%d@ha\n",max_func_arg_label); | |
2463 printf("\taddi %s,1,.LC%d@l\n",crn,max_func_arg_label); | |
2464 #endif | |
2298 free_register(g); | 2465 free_register(g); |
2299 } | 2466 } |
2300 | 2467 |
2301 void | 2468 void |
2302 code_frame_pointer(int e3) { | 2469 code_frame_pointer(int e3) { |
2303 use_int(e3); | 2470 use_int(e3); |
2304 #if R1SAVE | 2471 #if R1SAVE |
2305 printf("\tmr r1,%s\n",register_name(e3)); | 2472 printf("\tmr %s,%s\n",register_name(1),register_name(e3)); |
2306 #else | 2473 #else |
2307 printf("\tmr r30,%s\n",register_name(e3)); | 2474 printf("\tmr %s,%s\n",register_name(30),register_name(e3)); |
2308 #endif | 2475 #endif |
2309 } | 2476 } |
2310 | 2477 |
2311 int | 2478 int |
2312 code_frame_pointer_register() | 2479 code_frame_pointer_register() |
2324 | 2491 |
2325 void | 2492 void |
2326 code_jmp(char *s) { | 2493 code_jmp(char *s) { |
2327 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; | 2494 max_reg_var = REG_VAR_BASE-REG_VAR_MIN; |
2328 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; | 2495 max_freg_var = FREG_VAR_BASE-FREG_VAR_MIN; |
2496 #ifdef __APPLE__ | |
2329 printf("\tb L_%s$stub\n",s); | 2497 printf("\tb L_%s$stub\n",s); |
2498 #else | |
2499 printf("\tb %s\n",s); | |
2500 #endif | |
2330 control=0; | 2501 control=0; |
2331 } | 2502 } |
2332 | 2503 |
2333 | 2504 |
2334 void | 2505 void |
2339 printf("\tmtctr %s\n",register_name(e2)); | 2510 printf("\tmtctr %s\n",register_name(e2)); |
2340 printf("\tbctr\n"); | 2511 printf("\tbctr\n"); |
2341 control=0; | 2512 control=0; |
2342 } | 2513 } |
2343 | 2514 |
2515 static void | |
2516 code_add_op(char *op, char *crn, int offset, char *rrn) | |
2517 { | |
2518 #ifdef __APPLE__ | |
2519 if (LARGE_OFFSET(offset)) { | |
2520 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); | |
2521 } | |
2522 printf("\t%s %s,lo16(%d)(%s)\n",cload(sz),rrn,offset,crn); | |
2523 #else | |
2524 if (LARGE_OFFSET(offset)) { | |
2525 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); | |
2526 } | |
2527 printf("\t%s %s,%d@l(%s)\n",cload(sz),rrn,offset,crn); | |
2528 #endif | |
2529 } | |
2530 | |
2344 void | 2531 void |
2345 code_rindirect(int e1, int reg,int offset, int sign,int sz) | 2532 code_rindirect(int e1, int reg,int offset, int sign,int sz) |
2346 { | 2533 { |
2347 char *crn,*rrn; | 2534 char *crn,*rrn; |
2348 g_expr(e1); | 2535 g_expr(e1); |
2349 if (!is_int_reg(creg)) error(-1); | 2536 if (!is_int_reg(creg)) error(-1); |
2350 crn=register_name(creg); | 2537 crn=register_name(creg); |
2351 use_int(reg); | 2538 use_int(reg); |
2352 rrn=register_name(reg); | 2539 rrn=register_name(reg); |
2353 if (LARGE_OFFSET(offset)) { | 2540 code_add_op(cload(sz),rrn,offset,crn); |
2354 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); | |
2355 } | |
2356 printf("\t%s %s,lo16(%d)(%s)\n",cload(sz),rrn,offset,crn); | |
2357 cext(sign,sz,reg); | 2541 cext(sign,sz,reg); |
2358 } | 2542 } |
2359 | 2543 |
2360 #if FLOAT_CODE | 2544 #if FLOAT_CODE |
2361 int | 2545 int |
2364 char *crn; | 2548 char *crn; |
2365 g_expr(e1); | 2549 g_expr(e1); |
2366 if (!is_int_reg(creg)) error(-1); | 2550 if (!is_int_reg(creg)) error(-1); |
2367 crn=register_name(creg); | 2551 crn=register_name(creg); |
2368 use_float(d,reg); | 2552 use_float(d,reg); |
2369 if (LARGE_OFFSET(offset)) { | 2553 code_add_op(fload(d),fregister_name(reg),offset,crn); |
2370 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); | |
2371 } | |
2372 printf("\t%s %s,lo16(%d)(%s)\n",fload(d), | |
2373 fregister_name(reg),offset,crn); | |
2374 | 2554 |
2375 return d?DOUBLE:FLOAT; | 2555 return d?DOUBLE:FLOAT; |
2376 } | 2556 } |
2377 #endif | 2557 #endif |
2378 | 2558 |
2379 #if LONGLONG_CODE | 2559 #if LONGLONG_CODE |
2560 | |
2561 | |
2380 static void | 2562 static void |
2381 lload(int creg,int reg,int offset) | 2563 lload(int creg,int reg,int offset) |
2382 { | 2564 { |
2383 char *crn = register_name(creg); | 2565 char *crn = register_name(creg); |
2566 #ifdef __APPLE__ | |
2384 if (LARGE_OFFSET(offset)) { | 2567 if (LARGE_OFFSET(offset)) { |
2385 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); | 2568 printf("\taddis %s,%s,ha16(%d)\n",crn,crn,offset); |
2386 } | 2569 } |
2387 #if ENDIAN_L==0 | 2570 #if ENDIAN_L==0 |
2388 if (creg!=regv_l(reg)) { | 2571 if (creg!=regv_l(reg)) { |
2399 } else { | 2582 } else { |
2400 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); | 2583 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); |
2401 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); | 2584 printf("\tlwz %s,lo16(%d)(%s)\n",lregister_name_high(reg),offset,crn); |
2402 } | 2585 } |
2403 #endif | 2586 #endif |
2587 #else | |
2588 if (LARGE_OFFSET(offset)) { | |
2589 printf("\taddis %s,%s,%d@ha\n",crn,crn,offset); | |
2590 } | |
2591 #if ENDIAN_L==0 | |
2592 if (creg!=regv_l(reg)) { | |
2593 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); | |
2594 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); | |
2595 } else { | |
2596 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset+SIZE_OF_INT,crn); | |
2597 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset,crn); | |
2598 } | |
2599 #else | |
2600 if (creg!=regv_h(reg)) { | |
2601 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); | |
2602 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); | |
2603 } else { | |
2604 printf("\tlwz %s,%d@l(%s)\n",lregister_name_low(reg),offset+SIZE_OF_INT,crn); | |
2605 printf("\tlwz %s,%d@l(%s)\n",lregister_name_high(reg),offset,crn); | |
2606 } | |
2607 #endif | |
2608 | |
2609 #endif | |
2404 } | 2610 } |
2405 | 2611 |
2406 int | 2612 int |
2407 code_lrindirect(int e1, int reg, int offset, int us) | 2613 code_lrindirect(int e1, int reg, int offset, int us) |
2408 { | 2614 { |
2429 code_assign_lvar(int e2,int creg,int byte) { | 2635 code_assign_lvar(int e2,int creg,int byte) { |
2430 char *crn; | 2636 char *crn; |
2431 use_int(creg); | 2637 use_int(creg); |
2432 crn=register_name(creg); | 2638 crn=register_name(creg); |
2433 lvar_intro(e2); | 2639 lvar_intro(e2); |
2434 printf("\t%s %s,",cstore(byte),crn); | 2640 printf("\t%s %s,",cstore(byte),crn); |
2435 lvar(e2); | 2641 lvar(e2); |
2436 } | 2642 } |
2437 | 2643 |
2438 void | 2644 void |
2439 code_assign_register(int e2,int byte,int creg) { | 2645 code_assign_register(int e2,int byte,int creg) { |
2611 v = ilog(v); | 2817 v = ilog(v); |
2612 case URSHIFT: | 2818 case URSHIFT: |
2613 printf("\tsrwi %s,%s,%d\n",crn,crn,v); | 2819 printf("\tsrwi %s,%s,%d\n",crn,crn,v); |
2614 return; | 2820 return; |
2615 case ADD: | 2821 case ADD: |
2822 #ifdef __APPLE__ | |
2616 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v); | 2823 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,v); |
2824 #else | |
2825 printf("\taddi %s,%s,%d@l\n",crn,crn,v); | |
2826 #endif | |
2617 break; | 2827 break; |
2618 case SUB: | 2828 case SUB: |
2829 #ifdef __APPLE__ | |
2619 printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v); | 2830 printf("\taddi %s,%s,lo16(-%d)\n",crn,crn,v); |
2831 #else | |
2832 printf("\taddi %s,%s,-%d@l\n",crn,crn,v); | |
2833 #endif | |
2620 break; | 2834 break; |
2621 case CMP: | 2835 case CMP: |
2622 inc_cmpflag(); | 2836 inc_cmpflag(); |
2837 #ifdef __APPLE__ | |
2623 printf("\tcmpwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); | 2838 printf("\tcmpwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); |
2839 #else | |
2840 printf("\tcmpwi %d,%s,%d@l\n",cmpflag,crn,v); | |
2841 #endif | |
2624 break; | 2842 break; |
2625 case UCMP: | 2843 case UCMP: |
2626 inc_cmpflag(); | 2844 inc_cmpflag(); |
2845 #ifdef __APPLE__ | |
2627 printf("\tcmplwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); | 2846 printf("\tcmplwi cr%d,%s,lo16(%d)\n",cmpflag,crn,v); |
2847 #else | |
2848 printf("\tcmplwi %d,%s,%d@l\n",cmpflag,crn,v); | |
2849 #endif | |
2628 break; | 2850 break; |
2629 case EOR: | 2851 case EOR: |
2852 #ifdef __APPLE__ | |
2630 printf("\txori %s,%s,lo16(%d)\n",crn,crn,v); | 2853 printf("\txori %s,%s,lo16(%d)\n",crn,crn,v); |
2854 #else | |
2855 printf("\txori %s,%s,%d@l\n",crn,crn,v); | |
2856 #endif | |
2631 break; | 2857 break; |
2632 case BOR: | 2858 case BOR: |
2859 #ifdef __APPLE__ | |
2633 printf("\tori %s,%s,lo16(%d)\n",crn,crn,v); | 2860 printf("\tori %s,%s,lo16(%d)\n",crn,crn,v); |
2861 #else | |
2862 printf("\tori %s,%s,%d@l\n",crn,crn,v); | |
2863 #endif | |
2634 break; | 2864 break; |
2635 case MUL: | 2865 case MUL: |
2636 case UMUL: | 2866 case UMUL: |
2637 if ((l=ilog(v))) { | 2867 if ((l=ilog(v))) { |
2638 printf("\tslwi %s,%s,%d\n",crn,crn,l); | 2868 printf("\tslwi %s,%s,%d\n",crn,crn,l); |
2639 } else | 2869 } else |
2870 #ifdef __APPLE__ | |
2640 printf("\tmulli %s,%s,lo16(%d)\n",crn,crn,v); | 2871 printf("\tmulli %s,%s,lo16(%d)\n",crn,crn,v); |
2872 #else | |
2873 printf("\tmulli %s,%s,%d@l\n",crn,crn,v); | |
2874 #endif | |
2641 break; | 2875 break; |
2642 default: | 2876 default: |
2643 error(-1); | 2877 error(-1); |
2644 } | 2878 } |
2645 } | 2879 } |
2676 { | 2910 { |
2677 int reg,regsv; | 2911 int reg,regsv; |
2678 /* used in dosiwtch() */ | 2912 /* used in dosiwtch() */ |
2679 inc_cmpflag(); | 2913 inc_cmpflag(); |
2680 if (-32767<e&&e<32767) { | 2914 if (-32767<e&&e<32767) { |
2915 #ifdef __APPLE__ | |
2681 printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e); | 2916 printf("\tcmpwi cr%d,%s,%d\n",cmpflag,register_name(csreg),e); |
2917 #else | |
2918 printf("\tcmpwi %d,%s,%d\n",cmpflag,register_name(csreg),e); | |
2919 #endif | |
2682 jcond(label,cond); | 2920 jcond(label,cond); |
2683 } else { | 2921 } else { |
2684 regsv = regs[csreg]; regs[csreg]=USING_REG; | 2922 regsv = regs[csreg]; regs[csreg]=USING_REG; |
2685 reg = get_register(); | 2923 reg = get_register(); |
2686 regs[csreg]= regsv; | 2924 regs[csreg]= regsv; |
2687 code_const(e,reg); | 2925 code_const(e,reg); |
2926 #ifdef __APPLE__ | |
2688 printf("\tcmpw cr%d,%s,%s\n",cmpflag,register_name(csreg),register_name(reg)); | 2927 printf("\tcmpw cr%d,%s,%s\n",cmpflag,register_name(csreg),register_name(reg)); |
2928 #else | |
2929 printf("\tcmpw %d,%s,%s\n",cmpflag,register_name(csreg),register_name(reg)); | |
2930 #endif | |
2689 jcond(label,cond); | 2931 jcond(label,cond); |
2690 free_register(reg); | 2932 free_register(reg); |
2691 } | 2933 } |
2692 } | 2934 } |
2693 | 2935 |
2770 | 3012 |
2771 static void | 3013 static void |
2772 jcond(int l, char cond) | 3014 jcond(int l, char cond) |
2773 { | 3015 { |
2774 if (cond==LT) { | 3016 if (cond==LT) { |
3017 #ifdef __APPLE__ | |
2775 printf("\tb%s cr%d,L_%d\n",code_ge(0),cmpflag,l); | 3018 printf("\tb%s cr%d,L_%d\n",code_ge(0),cmpflag,l); |
3019 #else | |
3020 printf("\tb%s %d,L_%d\n",code_ge(0),cmpflag,l); | |
3021 #endif | |
2776 } else if (cond==1||cond==0) { | 3022 } else if (cond==1||cond==0) { |
3023 #ifdef __APPLE__ | |
2777 printf("\tb%s cr%d,L_%d\n",cond?"ne":"eq",cmpflag,l); | 3024 printf("\tb%s cr%d,L_%d\n",cond?"ne":"eq",cmpflag,l); |
3025 #else | |
3026 printf("\tb%s %d,.LC%d\n",cond?"ne":"eq",cmpflag,l); | |
3027 #endif | |
2778 } else error(-1); | 3028 } else error(-1); |
2779 } | 3029 } |
2780 | 3030 |
2781 void | 3031 void |
2782 jmp(int l) | 3032 jmp(int l) |
2783 { | 3033 { |
3034 #ifdef __APPLE__ | |
2784 printf("\tb\tL_%d\n",l); | 3035 printf("\tb\tL_%d\n",l); |
3036 #else | |
3037 printf("\tb\t.LC%d\n",l); | |
3038 #endif | |
2785 } | 3039 } |
2786 | 3040 |
2787 extern void | 3041 extern void |
2788 code_comment(char *s) | 3042 code_comment(char *s) |
2789 { | 3043 { |
2791 } | 3045 } |
2792 | 3046 |
2793 void | 3047 void |
2794 code_enter(char *name) | 3048 code_enter(char *name) |
2795 { | 3049 { |
3050 #ifdef __APPLE__ | |
2796 if (output_mode!=TEXT_EMIT_MODE) | 3051 if (output_mode!=TEXT_EMIT_MODE) |
2797 text_mode(0); | 3052 text_mode(0); |
2798 else | 3053 else |
2799 printf("\t.align 2\n"); | 3054 printf("\t.align 2\n"); |
2800 if (stmode!=STATIC) | 3055 if (stmode!=STATIC) |
2813 printf("\tbcl 20,31,L_%d\n",code_base = fwdlabel()); | 3068 printf("\tbcl 20,31,L_%d\n",code_base = fwdlabel()); |
2814 fwddef(code_base); | 3069 fwddef(code_base); |
2815 printf("\tmflr r31\n"); | 3070 printf("\tmflr r31\n"); |
2816 max_func_args = 0; | 3071 max_func_args = 0; |
2817 clear_ptr_cache(); | 3072 clear_ptr_cache(); |
3073 #else | |
3074 if (output_mode!=TEXT_EMIT_MODE) | |
3075 text_mode(0); | |
3076 else | |
3077 printf("\t.align 2\n"); | |
3078 if (stmode!=STATIC) | |
3079 printf(".globl %s\n",name); | |
3080 #ifdef DOT_SIZE | |
3081 printf("\t.type\t%s,@function\n",name); | |
3082 #endif | |
3083 printf("%s:\n",name); | |
3084 code_disp_label=fwdlabel(); | |
3085 #if 0 | |
3086 printf("\tla r1,lo16(L_%d)(r30)\n",code_disp_label); | |
3087 #else | |
3088 printf("\tla r1,.LC%d@l(r30)\n",code_disp_label); | |
3089 printf("\taddis r1,r1,.LC%d@ha\n",code_disp_label); | |
3090 #endif | |
3091 max_func_args = 0; | |
3092 clear_ptr_cache(); | |
3093 #endif | |
2818 } | 3094 } |
2819 | 3095 |
2820 | 3096 |
2821 void | 3097 void |
2822 code_enter1(int args) | 3098 code_enter1(int args) |
2830 code_leave(char *name) | 3106 code_leave(char *name) |
2831 { | 3107 { |
2832 int r1_offsetv; | 3108 int r1_offsetv; |
2833 disp&= -SIZE_OF_INT; | 3109 disp&= -SIZE_OF_INT; |
2834 r1_offsetv = -disp+max_func_args*SIZE_OF_INT -code_disp_offset0 +8+32+48; | 3110 r1_offsetv = -disp+max_func_args*SIZE_OF_INT -code_disp_offset0 +8+32+48; |
2835 | 3111 #ifdef __APPLE__ |
2836 printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv); | 3112 printf(".set L_%d,%d\n",code_disp_label,-r1_offsetv); |
2837 if (max_func_arg_label) { | 3113 if (max_func_arg_label) { |
2838 printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); | 3114 printf(".set L_%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); |
2839 max_func_arg_label = 0; | 3115 max_func_arg_label = 0; |
2840 } | 3116 } |
3117 #else | |
3118 printf(".set .LC%d,%d\n",code_disp_label,-r1_offsetv); | |
3119 if (max_func_arg_label) { | |
3120 printf(".set .LC%d,%d\n",max_func_arg_label,max_func_args*SIZE_OF_INT+24); | |
3121 max_func_arg_label = 0; | |
3122 } | |
3123 #endif | |
2841 local_table(); | 3124 local_table(); |
2842 // free_all_register(); | 3125 // free_all_register(); |
2843 } | 3126 } |
2844 | 3127 |
2845 void | 3128 void |
2846 enter(char *name) | 3129 enter(char *name) |
2847 { | 3130 { |
3131 #ifdef __APPLE__ | |
2848 if (output_mode!=TEXT_EMIT_MODE) | 3132 if (output_mode!=TEXT_EMIT_MODE) |
2849 text_mode(0); | 3133 text_mode(0); |
2850 else | 3134 else |
2851 printf("\t.align 2\n"); | 3135 printf("\t.align 2\n"); |
2852 if (stmode!=STATIC) | 3136 if (stmode!=STATIC) |
2871 printf("\tlis r31,ha16(-L_%d)\n",r1_offset_label); | 3155 printf("\tlis r31,ha16(-L_%d)\n",r1_offset_label); |
2872 printf("\taddi r31,r31,lo16(-L_%d)\n",r1_offset_label); | 3156 printf("\taddi r31,r31,lo16(-L_%d)\n",r1_offset_label); |
2873 printf("\tstwux r1,r1,r31\n"); | 3157 printf("\tstwux r1,r1,r31\n"); |
2874 #endif | 3158 #endif |
2875 printf("\tmflr r31\n"); | 3159 printf("\tmflr r31\n"); |
3160 #else | |
3161 if (output_mode!=TEXT_EMIT_MODE) | |
3162 text_mode(0); | |
3163 else | |
3164 printf("\t.align 2\n"); | |
3165 if (stmode!=STATIC) | |
3166 printf(".globl _%s\n",name); | |
3167 /* | |
3168 printf("\t.type\t%s,@function\n",name); | |
3169 */ | |
3170 printf("%s:\n",name); | |
3171 code_setup=fwdlabel(); | |
3172 printf("\tmflr 0\n"); | |
3173 printf("\tbl .LC%d\n",code_setup); | |
3174 r1_offset_label = fwdlabel(); | |
3175 lvar_offset_label = fwdlabel(); | |
3176 #if 0 | |
3177 printf("\taddi r30,r1,lo16(-L_%d)\n",lvar_offset_label); | |
3178 printf("\tstwu r1,lo16(-L_%d)(r1)\n",r1_offset_label); | |
3179 // printf("\tmr r30,r1\n"); | |
3180 #else | |
3181 printf("\taddi 30,1,-L_%d@l\n",lvar_offset_label); | |
3182 printf("\tlis 31,-L_%d@ha\n",r1_offset_label); | |
3183 printf("\taddi 31,31,-L_%d@l\n",r1_offset_label); | |
3184 printf("\tstwux 1,1,31\n"); | |
3185 #endif | |
3186 printf("\tmflr 31\n"); | |
3187 #endif | |
2876 max_func_args = 0; | 3188 max_func_args = 0; |
2877 clear_ptr_cache(); | 3189 clear_ptr_cache(); |
2878 } | 3190 } |
2879 | 3191 |
2880 void | 3192 void |
2896 } | 3208 } |
2897 | 3209 |
2898 void | 3210 void |
2899 code_label_call(int l) | 3211 code_label_call(int l) |
2900 { | 3212 { |
3213 #ifdef __APPLE__ | |
2901 printf("\tbl\tL_%d\n",l); | 3214 printf("\tbl\tL_%d\n",l); |
3215 #else | |
3216 printf("\tbl\t.LC%d\n",l); | |
3217 #endif | |
2902 } | 3218 } |
2903 | 3219 |
2904 void | 3220 void |
2905 code_ret() | 3221 code_ret() |
2906 { | 3222 { |
3506 if (output_mode==TEXT_EMIT_MODE) { | 3822 if (output_mode==TEXT_EMIT_MODE) { |
3507 printf(".text\n"); | 3823 printf(".text\n"); |
3508 } else { | 3824 } else { |
3509 text_mode(0); | 3825 text_mode(0); |
3510 } | 3826 } |
3511 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); | 3827 code_label_value(lb,rrn); |
3512 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); | |
3513 if (d) { | 3828 if (d) { |
3514 printf("\tlfd %s,0(%s)\n",frn,rrn); | 3829 printf("\tlfd %s,0(%s)\n",frn,rrn); |
3515 } else { | 3830 } else { |
3516 printf("\tlfs %s,0(%s)\n",frn,rrn); | 3831 printf("\tlfs %s,0(%s)\n",frn,rrn); |
3517 } | 3832 } |
3565 if (output_mode==TEXT_EMIT_MODE) { | 3880 if (output_mode==TEXT_EMIT_MODE) { |
3566 printf(".text\n"); | 3881 printf(".text\n"); |
3567 } else { | 3882 } else { |
3568 text_mode(0); | 3883 text_mode(0); |
3569 } | 3884 } |
3570 printf("\taddis %s,r31,ha16(L_%d-L_%d)\n",rrn,lb,code_base); | 3885 code_label_value(lb,rrn); |
3571 printf("\tla %s,lo16(L_%d-L_%d)(%s)\n",rrn,lb,code_base,rrn); | |
3572 if (d) { | 3886 if (d) { |
3573 printf("\tlfd %s,0(%s)\n",frn,rrn); | 3887 printf("\tlfd %s,0(%s)\n",frn,rrn); |
3574 } else { | 3888 } else { |
3575 printf("\tlfs %s,0(%s)\n",frn,rrn); | 3889 printf("\tlfs %s,0(%s)\n",frn,rrn); |
3576 } | 3890 } |