diff options
author | Jack Palevich <jackpal@google.com> | 2009-07-13 16:56:28 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-07-13 16:56:28 -0700 |
commit | 25c0ccaed43e8ecd1827248890c57c97d0ce80c7 (patch) | |
tree | aec89ab393492b7100212646e4e22c57ad9e36ab /libacc | |
parent | 45431bc2528246f829383abda8c2cd72c57fcb65 (diff) | |
download | system_core-25c0ccaed43e8ecd1827248890c57c97d0ce80c7.zip system_core-25c0ccaed43e8ecd1827248890c57c97d0ce80c7.tar.gz system_core-25c0ccaed43e8ecd1827248890c57c97d0ce80c7.tar.bz2 |
Implement support for "char" local and global variables.
Diffstat (limited to 'libacc')
-rw-r--r-- | libacc/acc.cpp | 70 | ||||
-rw-r--r-- | libacc/tests/data/char.c | 13 | ||||
-rw-r--r-- | libacc/tests/test.py | 6 |
3 files changed, 86 insertions, 3 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp index fb7ec80..7f726f1 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -1019,6 +1019,25 @@ class Compiler : public ErrorSink { LOG_API("storeR0(%d);\n", ea); TypeTag tag = pType->tag; switch (tag) { + case TY_CHAR: + if (ea > -LOCAL && ea < LOCAL) { + // Local, fp relative + if (ea < -4095 || ea > 4095) { + error("Offset out of range: %08x", ea); + } + if (ea < 0) { + o4(0xE54B0000 | (0xfff & (-ea))); // strb r0, [fp,#-ea] + } else { + o4(0xE5CB0000 | (0xfff & ea)); // strb r0, [fp,#ea] + } + } else{ + // Global, absolute + o4(0xE59F1000); // ldr r1, .L1 + o4(0xEA000000); // b .L99 + o4(ea); // .L1: .word 0 + o4(0xE5C10000); // .L99: strb r0, [r1] + } + break; case TY_POINTER: case TY_INT: case TY_FLOAT: @@ -1079,8 +1098,32 @@ class Compiler : public ErrorSink { virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) { LOG_API("loadR0(%d, %d, %d, %d);\n", ea, isIncDec, op, pType); - TypeTag tag = collapseType(pType->tag); + TypeTag tag = pType->tag; switch (tag) { + case TY_CHAR: + if (ea < LOCAL) { + // Local, fp relative + if (ea < -4095 || ea > 4095) { + error("Offset out of range: %08x", ea); + } + if (ea < 0) { + o4(0xE55B0000 | (0xfff & (-ea))); // ldrb r0, [fp,#-ea] + } else { + o4(0xE5DB0000 | (0xfff & ea)); // ldrb r0, [fp,#ea] + } + } else { + // Global, absolute + o4(0xE59F2000); // ldr r2, .L1 + o4(0xEA000000); // b .L99 + o4(ea); // .L1: .word ea + o4(0xE5D20000); // .L99: ldrb r0, [r2] + } + + if (isIncDec) { + error("inc/dec not implemented for char."); + } + break; + case TY_POINTER: case TY_INT: case TY_FLOAT: if (ea < LOCAL) { @@ -2027,6 +2070,13 @@ class Compiler : public ErrorSink { virtual void storeR0(int ea, Type* pType) { TypeTag tag = pType->tag; switch (tag) { + case TY_CHAR: + if (ea < -LOCAL || ea > LOCAL) { + oad(0xa2, ea); // movb %al,ea + } else { + oad(0x8588, ea); // movb %al,ea(%ebp) + } + break; case TY_INT: case TY_POINTER: gmov(6, ea); /* mov %eax, EA */ @@ -2052,10 +2102,24 @@ class Compiler : public ErrorSink { } virtual void loadR0(int ea, bool isIncDec, int op, Type* pType) { - TypeTag tag = collapseType(pType->tag); + TypeTag tag = pType->tag; switch (tag) { + case TY_CHAR: + if (ea < -LOCAL || ea > LOCAL) { + oad(0x05BE0F, ea); // movsbl ea,%eax + } else { + oad(0x85BE0F, ea); // movsbl ea(%ebp),%eax + } + if (isIncDec) { + error("inc/dec not implemented for char."); + } + break; case TY_INT: - gmov(8, ea); /* mov EA, %eax */ + case TY_POINTER: + if (tag == TY_CHAR) { + } else { + gmov(8, ea); /* mov EA, %eax */ + } if (isIncDec) { /* Implement post-increment or post decrement. */ diff --git a/libacc/tests/data/char.c b/libacc/tests/data/char.c new file mode 100644 index 0000000..8c63ba2 --- /dev/null +++ b/libacc/tests/data/char.c @@ -0,0 +1,13 @@ +char ga; +char gb; + +int main() { + char a = 'c'; + char b = a * 3; + printf("a = %d, b = %d\n", a, b); + ga = 'd'; + gb = ga * 3; + printf("ga = %d, gb = %d\n", ga, gb); + return 0; +} + diff --git a/libacc/tests/test.py b/libacc/tests/test.py index 702f49d..02999f0 100644 --- a/libacc/tests/test.py +++ b/libacc/tests/test.py @@ -250,6 +250,12 @@ Testing read/write (float*): 8.8 9.9 Testing read/write (double*): 8.8 9.9 """) + def testChar(self): + self.compileCheck(["-R", "data/char.c"], """Executing compiled code: +result: 0""", """a = 99, b = 41 +ga = 100, gb = 44""") + + if __name__ == '__main__': if not outputCanRun(): print "Many tests are expected to fail, because acc is not a 32-bit x86 Linux executable." |