xa51, work in progress
[fw/sdcc] / src / xa51 / gen.c
index fb73945827d967c6150321e2e52ae9be4eaf746d..ddadefa85a2c012ca4e9590f1a318b531593540a 100755 (executable)
@@ -143,9 +143,7 @@ static void emitcode (char *inst, char *fmt,...) {
 
 char *getStackOffset(int stack) {
   static char gsoBuf[1024];
-  sprintf (gsoBuf, "r7+(%d%+d%+d%+d)", stack,
-          FUNC_ISISR(currFunc->type) ? 
-            port->stack.isr_overhead : port->stack.call_overhead,
+  sprintf (gsoBuf, "r7+(%d%+d%+d)", stack,
           currFunc->stack, _G.nRegsSaved);
   return gsoBuf;
 }
@@ -334,7 +332,7 @@ static asmop *aopForSym(symbol *sym,
        }
     } else {
       aop->type=AOP_FAR;
-      emitcode ("mov", "r0,#%s ; aopForSym:far", sym->rname);
+      emitcode ("mov.w", "r0,#%s ; aopForSym:far", sym->rname);
       sprintf (aop->name[0], "[r0]");
       if (size>2) {
        sprintf (aop->name[1], "[r0+2]");
@@ -863,28 +861,31 @@ genEndFunction (iCode * ic)
 /*-----------------------------------------------------------------*/
 static void genRet (iCode * ic) {
 
-  printIc ("genRet", ic, 0,1,0);
-
-  aopOp(IC_LEFT(ic), TRUE, TRUE);
+  if (!IC_LEFT(ic)) {
+    printIc ("genRet", ic, 0, 0, 0);
+  } else {
+    printIc ("genRet", ic, 0, 1, 0);
+    aopOp(IC_LEFT(ic), TRUE, TRUE);
+    switch (AOP_SIZE(IC_LEFT(ic)))
+      {
+      case 4:
+       emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
+       emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
+       break;
+      case 3:
+       emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
+       // fall through
+      case 2:
+       emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
+       break;
+      case 1:
+       emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
+       break;
+      default:
+       bailOut("genRet");
+      }
+  }
 
-  switch (AOP_SIZE(IC_LEFT(ic)))
-    {
-    case 4:
-      emitcode ("mov", "r1,%s", AOP_NAME(IC_LEFT(ic))[1]);
-      emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      break;
-    case 3:
-      emitcode ("mov", "r1l,%s", AOP_NAME(IC_LEFT(ic))[1]);
-      // fall through
-    case 2:
-      emitcode ("mov", "r0,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      break;
-    case 1:
-      emitcode ("mov", "r0l,%s", AOP_NAME(IC_LEFT(ic))[0]);
-      break;
-    default:
-      bailOut("genRet");
-    }
   emitcode ("jmp", "%05d$", returnLabel->key+100);
 }
 
@@ -943,6 +944,27 @@ static void genPlus (iCode * ic) {
   aopOp(left, !aopIsPtr(result), !aopIsDir(result));
   aopOp(right, !aopIsPtr(result), !aopIsDir(result));
 
+  // special case for * = * + char, needs a closer look
+  // heck, this shouldn't have come here but bug-223113 does
+  if (size==3 && AOP_SIZE(right)==1) {
+    emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+    emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+    return;
+  }
+
+  // special case for (whatever)* = (whatever)** + char, needs a closer look
+  // heck, this shouldn't have come here but bug-441448 does
+  if (size==2 && AOP_SIZE(right)==1) {
+    emitcode ("mov", "r1l,%s", AOP_NAME(right)[0]);
+    emitcode ("mov", "r1h,#0"); // ptr arith unsigned????????????
+    emitcode ("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    emitcode ("add.w", "%s,r1", AOP_NAME(result)[0]);
+    return;
+  }
+
   if (size>1) {
     instr="add.w";
   } else {
@@ -1223,7 +1245,11 @@ static void genPointerGet (iCode * ic, iCode *pi) {
   bool codePointer=IS_CODEPTR(operandType(left));
   int size;
 
-  printIc ("genPointerGet", ic, 1,1,0);
+  if (pi) {
+    printIc ("genPointerGet pi", ic, 1,1,0);
+  } else {
+    printIc ("genPointerGet", ic, 1,1,0);
+  }
 
   if (!IS_PTR(operandType(left))) {
     bailOut ("genPointerGet: pointer required");
@@ -1236,7 +1262,7 @@ static void genPointerGet (iCode * ic, iCode *pi) {
     symbol *tlbl1=newiTempLabel(NULL);
     symbol *tlbl2=newiTempLabel(NULL);
     emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
-    emitcode ("bne", "%05d$", tlbl1->key+100);
+    emitcode ("beq", "%05d$", tlbl1->key+100);
     // far/near pointer
     if (pi) {
       emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
@@ -1274,6 +1300,10 @@ static void genPointerGet (iCode * ic, iCode *pi) {
 
   switch (AOP_TYPE(left)) 
     {
+    case AOP_LIT:
+      emitcode("mov","r1,%s", AOP_NAME(left)[0]);
+      sprintf (AOP_NAME(left)[0], "r1");
+      // fall through
     case AOP_REG:
       if (size>1) {
        if (codePointer) {
@@ -1402,7 +1432,7 @@ static void genIfx (iCode * ic, iCode * popIc) {
   int size;
   char *instr;
   bool trueOrFalse;
-  symbol *jlbl, *tlbl;
+  symbol *jlbl, *tlbl=newiTempLabel(NULL);
   operand *cond=IC_COND(ic);
 
   emitcode (";", "genIfx(%d) cond=%s trueLabel:%s falseLabel:%s", 
@@ -1423,14 +1453,15 @@ static void genIfx (iCode * ic, iCode * popIc) {
   switch (AOP_TYPE(cond) )
     {
     case AOP_BIT:
-      emitcode (trueOrFalse ? "jb" : "jnb", "%s,%05d$", 
-               AOP_NAME(cond)[0], jlbl->key+100);
+      emitcode (trueOrFalse ? "jnb" : "jb", "%s,%05d$", 
+               AOP_NAME(cond)[0], tlbl->key+100);
+      emitcode ("jmp", "%05d$", jlbl->key+100);
+      emitcode ("", "%05d$:", tlbl->key+100);
       return;
     case AOP_REG:
     case AOP_DIR:
     case AOP_FAR:
     case AOP_STK:
-      tlbl=newiTempLabel(NULL);
       if (size>1) {
        instr="cmp.w";
       } else {
@@ -1469,7 +1500,7 @@ static void genAddrOf (iCode * ic) {
              getStackOffset(OP_SYMBOL(left)->stack));
     if (size > 2) {
       // this must be a generic pointer
-      emitcode ("mov", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
+      emitcode ("mov.b", "%s,#0x%02x", AOP_NAME(IC_RESULT(ic))[1], FPOINTER);
     }
     return;
   }
@@ -1634,6 +1665,7 @@ static void genCast (iCode * ic) {
       } else {
        /* we have to go by the storage class */
        if (!SPEC_OCLS(etype)) {
+         ptrType=0; // hush the compiler
          bailOut("genCast: unknown storage class");
        } else {
          ptrType = PTR_TYPE (SPEC_OCLS (etype));
@@ -1644,13 +1676,13 @@ static void genCast (iCode * ic) {
       switch (ptrType)
        {
        case POINTER:
-         emitcode ("mov", "%s,#0x00", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x00", AOP_NAME(result)[1]);
          break;
        case FPOINTER:
-         emitcode ("mov", "%s,#0x01", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x01", AOP_NAME(result)[1]);
          break;
        case CPOINTER:
-         emitcode ("mov", "%s,#0x02", AOP_NAME(result)[1]);
+         emitcode ("mov.b", "%s,#0x02", AOP_NAME(result)[1]);
          break;
        default:
          bailOut("genCast: got unknown storage class");
@@ -1674,29 +1706,41 @@ static void genCast (iCode * ic) {
     case 0x11:
       emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
       return;
+    case 0x42:
+      emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
+      if (signedness) {
+       emitcode("sext", "%s", AOP_NAME(result)[1]);
+      } else {
+       emitcode("mov", "%s,#0", AOP_NAME(result)[1]);
+      }
+      return;
     case 0x41:
     case 0x21:
       emitcode("mov", "r1l,%s", AOP_NAME(right)[0]);
       if (signedness) {
        emitcode("sext", "r1h");
       } else {
-       emitcode("mov", "rlh,#0");
+       emitcode("mov", "r1h,#0");
       }
       emitcode("mov", "%s,r1", AOP_NAME(result)[0]);
       if (size==2)
        return;
       // fall through: case 0x41
-      emitcode("sext", AOP_NAME(result)[1]);
+      if (signedness) {
+       emitcode("sext", "r1");
+      } else {
+       emitcode("mov", "r1,#0");
+      }
+      emitcode("mov", "%s,r1", AOP_NAME(result)[1]);
       return;
-    case 14:
-    case 12:
+    case 0x14:
+    case 0x12:
       emitcode("mov", "r1,%s", AOP_NAME(right)[0]);
       emitcode("mov", "%s,r1l", AOP_NAME(result)[0]);
       return;
-    case 24:
-      emitcode("mov", "%s,%s", AOP_NAME(result)[0], AOP_NAME(right)[0]);
-      return;
     }
+  fprintf(stderr, "genCast: unknown size: %d:%d\n",
+         AOP_SIZE(result), AOP_SIZE(right));
   bailOut("genCast: unknown size");
 }