• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/corennnnn


Commit MetaInfo

Revisão4d93f30befb6e3adf37198c6c7f6727d1e570b94 (tree)
Hora2009-05-16 05:30:00
AutorJack Palevich <jackpal@goog...>
CommiterJack Palevich

Mensagem de Log

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.

Mudança Sumário

Diff

--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -164,9 +164,7 @@ class compiler {
164164
165165 virtual void storeEAX(int ea) = 0;
166166
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;
170168
171169 virtual int beginFunctionCallArguments() = 0;
172170
@@ -429,62 +427,90 @@ class compiler {
429427
430428 virtual void leaEAX(int ea) {
431429 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+ }
437440 } 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:
439446 }
440-
441447 }
442448
443449 virtual void storeEAX(int ea) {
444450 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]
452467 }
453468 }
454469
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+ }
462482 } 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]
464488 }
465- }
466489
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+ }
488514 }
489515 }
490516
@@ -723,15 +749,14 @@ class compiler {
723749 gmov(6, ea); /* mov %eax, EA */
724750 }
725751
726- virtual void loadEAX(int ea) {
752+ virtual void loadEAX(int ea, bool isIncDec, int op) {
727753 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+ }
735760 }
736761
737762 virtual int beginFunctionCallArguments() {
@@ -1117,9 +1142,8 @@ class compiler {
11171142 pGen->storeEAX(n);
11181143 } else if (tok != '(') {
11191144 /* variable */
1120- pGen->loadEAX(n);
1145+ pGen->loadEAX(n, tokl == 11, tokc);
11211146 if (tokl == 11) {
1122- pGen->postIncrementOrDecrement(n, tokc);
11231147 next();
11241148 }
11251149 }