summaryrefslogtreecommitdiffstats
path: root/libacc
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-07-13 16:56:28 -0700
committerJack Palevich <jackpal@google.com>2009-07-13 16:56:28 -0700
commit25c0ccaed43e8ecd1827248890c57c97d0ce80c7 (patch)
treeaec89ab393492b7100212646e4e22c57ad9e36ab /libacc
parent45431bc2528246f829383abda8c2cd72c57fcb65 (diff)
downloadsystem_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.cpp70
-rw-r--r--libacc/tests/data/char.c13
-rw-r--r--libacc/tests/test.py6
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."