xa51, work in progress
[fw/sdcc] / src / xa51 / gen.c
index a2762237d495fca97a6c5b911a454e96b4ca474b..74f0947db8789e2193907fd299c81439e7fe1dc3 100755 (executable)
@@ -96,6 +96,8 @@ static char *MOV="mov";
 static char *MOVB="mov.b";
 static char *MOVW="mov.w";
 static char *MOVC="movc";
+static char *MOVCB="movc.b";
+static char *MOVCW="movc.w";
 
 static char *R1L="r1l";
 static char *R1="r1";
@@ -444,7 +446,7 @@ bool aopIsPtr(operand *op) {
   }
 }
       
-char *opRegName(operand *op, int offset, char *opName) {
+char *opRegName(operand *op, int offset, char *opName, bool decorate) {
 
   if (IS_SYMOP(op)) {
     if (OP_SYMBOL(op)->onStack) {
@@ -469,17 +471,21 @@ char *opRegName(operand *op, int offset, char *opName) {
       }
       // fall through
     case V_CHAR:
-      sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+      sprintf (opName, "#%s0x%02x", decorate?"(char)":"", 
+              SPEC_CVAL(OP_VALUE(op)->type).v_int);
       break;
     case V_INT:
       if (SPEC_LONG(OP_VALUE(op)->type)) {
-       sprintf (opName, "#0x%02lx", SPEC_CVAL(OP_VALUE(op)->type).v_long);
+       sprintf (opName, "#%s0x%02lx", decorate?"(long)":"",
+                SPEC_CVAL(OP_VALUE(op)->type).v_long);
       } else {
-       sprintf (opName, "#0x%02x", SPEC_CVAL(OP_VALUE(op)->type).v_int);
+       sprintf (opName, "#%s0x%02x", decorate?"(int)":"",
+                SPEC_CVAL(OP_VALUE(op)->type).v_int);
       }
       break;
     case V_FLOAT:
-      sprintf (opName, "#%f", SPEC_CVAL(OP_VALUE(op)->type).v_float);
+      sprintf (opName, "#%s%f", decorate?"(float)":"",
+              SPEC_CVAL(OP_VALUE(op)->type).v_float);
       break;
     default: 
       bailOut("opRegName: unexpected noun");
@@ -551,7 +557,7 @@ char * printOp (operand *op) {
     strcat (line, "unknown");
     return line;
   } else if (IS_VALOP(op)) {
-    opRegName(op, 0, line);
+    opRegName(op, 0, line, 1);
   } else if (IS_TYPOP(op)) {
     sprintf (line, "[");
     if (isPtr) {
@@ -692,10 +698,43 @@ static void genUminus (iCode * ic) {
 }
 
 /*-----------------------------------------------------------------*/
-/* genIpush - genrate code for pushing this gets a little complex  */
+/* genIpush - generate code for pushing                            */
 /*-----------------------------------------------------------------*/
 static void genIpush (iCode * ic) {
+  operand *left=IC_LEFT(ic);
+
   printIc ("genIpush", ic, 0,1,0);
+  aopOp(left,FALSE,FALSE);
+  if (AOP_TYPE(left)==AOP_LIT) {
+    switch (AOP_SIZE(left)) 
+      {
+      case 1:
+       emitcode ("mov", "r1l,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1l");
+       return;
+      case 2:
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       return;
+      case 3:
+       emitcode ("mov", "r1l,%s", AOP_NAME(left)[1]);
+       emitcode ("push", "r1l");
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       return;
+      case 4:
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[1]);
+       emitcode ("push", "r1");
+       emitcode ("mov", "r1,%s", AOP_NAME(left)[0]);
+       emitcode ("push", "r1");
+       return;
+      }
+  } else {
+    if (AOP_SIZE(left)>2) {
+      emitcode ("push", "%s", AOP_NAME(left)[1]);
+    }
+    emitcode ("push", "%s", AOP_NAME(left)[0]);
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -709,8 +748,37 @@ static void genIpop (iCode * ic) {
 /* genCall - generates a call statement                            */
 /*-----------------------------------------------------------------*/
 static void genCall (iCode * ic) {
-  emitcode (";", "genCall %s result=%s", OP_SYMBOL(IC_LEFT(ic))->name,
+  operand *result=IC_RESULT(ic);
+
+  emitcode (";", "genCall(%d) %s result=%s", ic->lineno,
+           OP_SYMBOL(IC_LEFT(ic))->name,
            printOp (IC_RESULT(ic)));
+  emitcode ("call", "%s", OP_SYMBOL(IC_LEFT(ic))->rname);
+
+  /* if we need to assign a result value */
+  if (IS_ITEMP (IC_RESULT(ic)) &&
+      OP_SYMBOL (IC_RESULT (ic))->nRegs) {
+    aopOp(result,FALSE,FALSE);
+    switch (AOP_SIZE(result))
+      {
+      case 1:
+       emitcode ("mov", "%s,r0l", AOP_NAME(result)[0]);
+       return;
+      case 2:
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      case 3:
+       // generic pointer
+       emitcode ("mov", "%s,r1l", AOP_NAME(result)[1]);
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      case 4:
+       emitcode ("mov", "%s,r1", AOP_NAME(result)[1]);
+       emitcode ("mov", "%s,r0", AOP_NAME(result)[0]);
+       return;
+      }
+    bailOut("genCall");
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -984,11 +1052,14 @@ static iCode *hasInc (operand *op, iCode *ic, int osize) {
 
   while (lic) {
     /* if operand of the form op = op + <sizeof *op> */
-    if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) &&
-       isOperandEqual(IC_RESULT(lic),op) && 
-       isOperandLiteral(IC_RIGHT(lic)) &&
-       operandLitValue(IC_RIGHT(lic)) == isize) {
-      return lic;
+    if (lic->op == '+') {
+      if (isOperandEqual(IC_LEFT(lic),op) &&
+         //isOperandEqual(IC_RESULT(lic),op) && 
+         isOperandLiteral(IC_RIGHT(lic)) &&
+         operandLitValue(IC_RIGHT(lic)) == isize) {
+       emitcode (";", "Found hasInc");
+       return lic;
+      }
     }
     /* if the operand used or deffed */
     if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) {
@@ -1132,6 +1203,7 @@ static void genRightShift (iCode * ic) {
 static void genPointerGet (iCode * ic, iCode *pi) {
   char *instr, *scratchReg;
   operand *result=IC_RESULT(ic), *left=IC_LEFT(ic);
+  bool codePointer=IS_CODEPTR(operandType(left));
   int size;
 
   printIc ("genPointerGet", ic, 1,1,0);
@@ -1149,17 +1221,35 @@ static void genPointerGet (iCode * ic, iCode *pi) {
     emitcode ("cmp", "%s,#0x%02x", AOP_NAME(left)[1], CPOINTER);
     emitcode ("bne", "%05d$", tlbl1->key+100);
     // far/near pointer
-    emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    if (pi) {
+      emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+      pi->generated=1;
+    } else {
+      emitcode ("mov", "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+    }
     if (size>2) {
-      emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      if (pi) {
+       emitcode ("mov", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      } else {
+       emitcode ("mov", "%s,[%s+2]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      }
     }
     emitcode ("br", "%05d$", tlbl2->key+100);
     emitcode ("", "%05d$:", tlbl1->key+100);
     // code pointer
-    emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
-    emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
+    if (pi) {
+      emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+      pi->generated=1;
+    } else {
+      emitcode ("mov", "r0,%s", AOP_NAME(left)[0]);
+      emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[0]);
+    }
     if (size>2) {
-      emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1], AOP_NAME(left)[1]);
+      if (pi) {
+       emitcode ("movc", "%s,[%s+]", AOP_NAME(result)[1], AOP_NAME(left)[0]);
+      } else {
+       emitcode ("movc", "%s,[r0+]", AOP_NAME(result)[1]);
+      }
     }
     emitcode ("", "%05d$:", tlbl2->key+100);
     return;
@@ -1169,10 +1259,18 @@ static void genPointerGet (iCode * ic, iCode *pi) {
     {
     case AOP_REG:
       if (size>1) {
-       instr=MOVW;
+       if (codePointer) {
+         instr=MOVCW;
+       } else {
+         instr=MOVW;
+       }
        scratchReg=R1;
       } else {
-       instr=MOVB;
+       if (codePointer) {
+         instr=MOVCB;
+       } else {
+         instr=MOVB;
+       }
        scratchReg=R1L;
       }
       if (AOP_TYPE(result)==AOP_STK) {
@@ -1180,15 +1278,26 @@ static void genPointerGet (iCode * ic, iCode *pi) {
        emitcode (MOV, "%s,%s", AOP_NAME(result)[0], scratchReg);
       } else {
        if (pi) {
-         emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+         emitcode (instr, "%s,[%s+]", AOP_NAME(result)[0], 
+                   AOP_NAME(left)[0]);
          pi->generated=1;
        } else {
-         emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], AOP_NAME(left)[0]);
+         if (codePointer) {
+           emitcode (MOV, "r1,%s", AOP_NAME(left)[0]);
+           emitcode (instr, "%s,[r1+]", AOP_NAME(result)[0]);
+         } else {
+           emitcode (instr, "%s,[%s]", AOP_NAME(result)[0], 
+                     AOP_NAME(left)[0]);
+         }
        }
       }
       if (size > 2) {
        if (size==3) {
-         instr=MOVB;
+         if (codePointer) {
+           instr=MOVCB;
+         } else {
+           instr=MOVB;
+         }
          scratchReg=R1L;
        }
        if (AOP_TYPE(result)==AOP_STK) {
@@ -1199,8 +1308,12 @@ static void genPointerGet (iCode * ic, iCode *pi) {
            emitcode (instr, "%s,[%s+]", AOP_NAME(result)[1], 
                      AOP_NAME(left)[0]);
          } else {
-           emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1], 
-                     AOP_NAME(left)[0]);
+           if (codePointer) {
+             emitcode (instr, "%s,[r1]", AOP_NAME(result)[1]);
+           } else {
+             emitcode (instr, "%s,[%s+2]", AOP_NAME(result)[1], 
+                       AOP_NAME(left)[0]);
+           }
          }
        }
       }
@@ -1686,7 +1799,7 @@ void genXA51Code (iCode * lic) {
        break;
        
       case GET_VALUE_AT_ADDRESS:
-       genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_LEFT(ic)))));
+       genPointerGet (ic, hasInc(IC_LEFT(ic), ic, getSize(operandType(IC_RESULT(ic)))));
        break;
        
       case '=':