system/corennnnn
Revisão | 4d93f30befb6e3adf37198c6c7f6727d1e570b94 (tree) |
---|---|
Hora | 2009-05-16 05:30:00 |
Autor | Jack Palevich <jackpal@goog...> |
Commiter | Jack Palevich |
ACC ARM code gen: Implement global variables.
Collapsed the inc/dec codegen into the loadEAX function, because it
allows us to generate better code for inc/dec'ing a global variable
on ARM, because we don't have to load the variable's address twice.
@@ -164,9 +164,7 @@ class compiler { | ||
164 | 164 | |
165 | 165 | virtual void storeEAX(int ea) = 0; |
166 | 166 | |
167 | - virtual void loadEAX(int ea) = 0; | |
168 | - | |
169 | - virtual void postIncrementOrDecrement(int n, int op) = 0; | |
167 | + virtual void loadEAX(int ea, bool isIncDec, int op) = 0; | |
170 | 168 | |
171 | 169 | virtual int beginFunctionCallArguments() = 0; |
172 | 170 |
@@ -429,62 +427,90 @@ class compiler { | ||
429 | 427 | |
430 | 428 | virtual void leaEAX(int ea) { |
431 | 429 | fprintf(stderr, "leaEAX(%d);\n", ea); |
432 | - if (ea < -1023 || ea > 1023 || ((ea & 3) != 0)) { | |
433 | - error("Offset out of range: %08x", ea); | |
434 | - } | |
435 | - if (ea < 0) { | |
436 | - o4(0xE24B0F00 | (0xff & ((-ea) >> 2))); // sub r0, fp, #ea | |
430 | + if (ea < LOCAL) { | |
431 | + // Local, fp relative | |
432 | + if (ea < -1023 || ea > 1023 || ((ea & 3) != 0)) { | |
433 | + error("Offset out of range: %08x", ea); | |
434 | + } | |
435 | + if (ea < 0) { | |
436 | + o4(0xE24B0F00 | (0xff & ((-ea) >> 2))); // sub r0, fp, #ea | |
437 | + } else { | |
438 | + o4(0xE28B0F00 | (0xff & (ea >> 2))); // add r0, fp, #ea | |
439 | + } | |
437 | 440 | } else { |
438 | - o4(0xE28B0F00 | (0xff & (ea >> 2))); // add r0, fp, #ea | |
441 | + // Global, absolute. | |
442 | + o4(0xE59F0000); // ldr r0, .L1 | |
443 | + o4(0xEA000000); // b .L99 | |
444 | + o4(ea); // .L1: .word 0 | |
445 | + // .L99: | |
439 | 446 | } |
440 | - | |
441 | 447 | } |
442 | 448 | |
443 | 449 | virtual void storeEAX(int ea) { |
444 | 450 | fprintf(stderr, "storeEAX(%d);\n", ea); |
445 | - if (ea < -4095 || ea > 4095) { | |
446 | - error("Offset out of range: %08x", ea); | |
447 | - } | |
448 | - if (ea < 0) { | |
449 | - o4(0xE50B0000 | (0xfff & (-ea))); // str r0, [fp,#-ea] | |
450 | - } else { | |
451 | - o4(0xE58B0000 | (0xfff & ea)); // str r0, [fp,#ea] | |
451 | + if (ea < LOCAL) { | |
452 | + // Local, fp relative | |
453 | + if (ea < -4095 || ea > 4095) { | |
454 | + error("Offset out of range: %08x", ea); | |
455 | + } | |
456 | + if (ea < 0) { | |
457 | + o4(0xE50B0000 | (0xfff & (-ea))); // str r0, [fp,#-ea] | |
458 | + } else { | |
459 | + o4(0xE58B0000 | (0xfff & ea)); // str r0, [fp,#ea] | |
460 | + } | |
461 | + } else{ | |
462 | + // Global, absolute | |
463 | + o4(0xE59F1000); // ldr r1, .L1 | |
464 | + o4(0xEA000000); // b .L99 | |
465 | + o4(ea); // .L1: .word 0 | |
466 | + o4(0xE5810000); // .L99: str r0, [r1] | |
452 | 467 | } |
453 | 468 | } |
454 | 469 | |
455 | - virtual void loadEAX(int ea) { | |
456 | - fprintf(stderr, "loadEAX(%d);\n", ea); | |
457 | - if (ea < -4095 || ea > 4095) { | |
458 | - error("Offset out of range: %08x", ea); | |
459 | - } | |
460 | - if (ea < 0) { | |
461 | - o4(0xE51B0000 | (0xfff & (-ea))); // ldr r0, [fp,#-ea] | |
470 | + virtual void loadEAX(int ea, bool isIncDec, int op) { | |
471 | + fprintf(stderr, "loadEAX(%d, %d, %d);\n", ea, isIncDec, op); | |
472 | + if (ea < LOCAL) { | |
473 | + // Local, fp relative | |
474 | + if (ea < -4095 || ea > 4095) { | |
475 | + error("Offset out of range: %08x", ea); | |
476 | + } | |
477 | + if (ea < 0) { | |
478 | + o4(0xE51B0000 | (0xfff & (-ea))); // ldr r0, [fp,#-ea] | |
479 | + } else { | |
480 | + o4(0xE59B0000 | (0xfff & ea)); // ldr r0, [fp,#ea] | |
481 | + } | |
462 | 482 | } else { |
463 | - o4(0xE59B0000 | (0xfff & ea)); // ldr r0, [fp,#ea] | |
483 | + // Global, absolute | |
484 | + o4(0xE59F2000); // ldr r2, .L1 | |
485 | + o4(0xEA000000); // b .L99 | |
486 | + o4(ea); // .L1: .word ea | |
487 | + o4(0xE5920000); // .L99: ldr r0, [r2] | |
464 | 488 | } |
465 | - } | |
466 | 489 | |
467 | - virtual void postIncrementOrDecrement(int ea, int op) { | |
468 | - fprintf(stderr, "postIncrementOrDecrement(%d, %d);\n", ea, op); | |
469 | - /* R0 has the original value. | |
470 | - */ | |
471 | - switch (op) { | |
472 | - case OP_INCREMENT: | |
473 | - o4(0xE2801001); // add r1, r0, #1 | |
474 | - break; | |
475 | - case OP_DECREMENT: | |
476 | - o4(0xE2401001); // sub r1, r0, #1 | |
477 | - break; | |
478 | - default: | |
479 | - error("unknown opcode: %d", op); | |
480 | - } | |
481 | - if (ea < -4095 || ea > 4095) { | |
482 | - error("Offset out of range: %08x", ea); | |
483 | - } | |
484 | - if (ea < 0) { | |
485 | - o4(0xE50B1000 | (0xfff & (-ea))); // str r1, [fp,#-ea] | |
486 | - } else { | |
487 | - o4(0xE58B1000 | (0xfff & ea)); // str r1, [fp,#ea] | |
490 | + if (isIncDec) { | |
491 | + switch (op) { | |
492 | + case OP_INCREMENT: | |
493 | + o4(0xE2801001); // add r1, r0, #1 | |
494 | + break; | |
495 | + case OP_DECREMENT: | |
496 | + o4(0xE2401001); // sub r1, r0, #1 | |
497 | + break; | |
498 | + default: | |
499 | + error("unknown opcode: %d", op); | |
500 | + } | |
501 | + if (ea < LOCAL) { | |
502 | + // Local, fp relative | |
503 | + // Don't need range check, was already checked above | |
504 | + if (ea < 0) { | |
505 | + o4(0xE50B1000 | (0xfff & (-ea))); // str r1, [fp,#-ea] | |
506 | + } else { | |
507 | + o4(0xE58B1000 | (0xfff & ea)); // str r1, [fp,#ea] | |
508 | + } | |
509 | + } else{ | |
510 | + // Global, absolute | |
511 | + // r2 is already set up from before. | |
512 | + o4(0xE5821000); // str r1, [r2] | |
513 | + } | |
488 | 514 | } |
489 | 515 | } |
490 | 516 |
@@ -723,15 +749,14 @@ class compiler { | ||
723 | 749 | gmov(6, ea); /* mov %eax, EA */ |
724 | 750 | } |
725 | 751 | |
726 | - virtual void loadEAX(int ea) { | |
752 | + virtual void loadEAX(int ea, bool isIncDec, int op) { | |
727 | 753 | gmov(8, ea); /* mov EA, %eax */ |
728 | - } | |
729 | - | |
730 | - virtual void postIncrementOrDecrement(int n, int op) { | |
731 | - /* Implement post-increment or post decrement. | |
732 | - */ | |
733 | - gmov(0, n); /* 83 ADD */ | |
734 | - o(decodeOp(op)); | |
754 | + if (isIncDec) { | |
755 | + /* Implement post-increment or post decrement. | |
756 | + */ | |
757 | + gmov(0, ea); /* 83 ADD */ | |
758 | + o(decodeOp(op)); | |
759 | + } | |
735 | 760 | } |
736 | 761 | |
737 | 762 | virtual int beginFunctionCallArguments() { |
@@ -1117,9 +1142,8 @@ class compiler { | ||
1117 | 1142 | pGen->storeEAX(n); |
1118 | 1143 | } else if (tok != '(') { |
1119 | 1144 | /* variable */ |
1120 | - pGen->loadEAX(n); | |
1145 | + pGen->loadEAX(n, tokl == 11, tokc); | |
1121 | 1146 | if (tokl == 11) { |
1122 | - pGen->postIncrementOrDecrement(n, tokc); | |
1123 | 1147 | next(); |
1124 | 1148 | } |
1125 | 1149 | } |