fixed the bit=~bit bug
[fw/sdcc] / src / mcs51 / gen.c
index 4a1025f69b3ffa59a9731a068bd065aaffddb8c8..7b208a361970f009d3cd9b297b6b3167e31b8dcf 100644 (file)
@@ -67,9 +67,7 @@ static char *spname;
 
 char *fReturn8051[] =
 {"dpl", "dph", "b", "a"};
-char *fReturn390[] =
-{"dpl", "dph", "dpx", "b", "a"};
-unsigned fReturnSize = 4;      /* shared with ralloc.c */
+unsigned fReturnSizeMCS51 = 4; /* shared with ralloc.c */
 char **fReturn = fReturn8051;
 static char *accUse[] =
 {"a", "b"};
@@ -297,7 +295,7 @@ aopForSym (iCode * ic, symbol * sym, bool result)
   /* assign depending on the storage class */
   /* if it is on the stack or indirectly addressable */
   /* space we need to assign either r0 or r1 to it   */
-  if ((sym->onStack && !options.stack10bit) || sym->iaccess)
+  if (sym->onStack || sym->iaccess)
     {
       sym->aop = aop = newAsmop (0);
       aop->aopu.aop_ptr = getFreePtr (ic, &aop, result);
@@ -335,35 +333,6 @@ aopForSym (iCode * ic, symbol * sym, bool result)
       return aop;
     }
 
-  if (sym->onStack && options.stack10bit)
-    {
-      /* It's on the 10 bit stack, which is located in
-       * far data space.
-       */
-
-      if (_G.accInUse)
-       emitcode ("push", "acc");
-
-      emitcode ("mov", "a,_bp");
-      emitcode ("add", "a,#0x%02x",
-               ((sym->stack < 0) ?
-                ((char) (sym->stack - _G.nRegsSaved)) :
-                ((char) sym->stack)) & 0xff);
-
-      genSetDPTR (1);
-      emitcode ("mov", "dpx1,#0x40");
-      emitcode ("mov", "dph1,#0x00");
-      emitcode ("mov", "dpl1, a");
-      genSetDPTR (0);
-
-      if (_G.accInUse)
-       emitcode ("pop", "acc");
-
-      sym->aop = aop = newAsmop (AOP_DPTR2);
-      aop->size = getSize (sym->type);
-      return aop;
-    }
-
   /* if in bit space */
   if (IN_BITSPACE (space))
     {
@@ -638,7 +607,7 @@ aopOp (operand * op, iCode * ic, bool result)
          int i;
          aop = op->aop = sym->aop = newAsmop (AOP_STR);
          aop->size = getSize (sym->type);
-         for (i = 0; i < fReturnSize; i++)
+         for (i = 0; i < fReturnSizeMCS51; i++)
            aop->aopu.aop_str[i] = fReturn[i];
          return;
        }
@@ -715,15 +684,6 @@ freeAsmop (operand * op, asmop * aaop, iCode * ic, bool pop)
 
        getFreePtr (ic, &aop, FALSE);
 
-       if (options.stack10bit)
-         {
-           /* I'm not sure what to do here yet... */
-           /* #STUB */
-           fprintf (stderr,
-                    "*** Warning: probably generating bad code for "
-                    "10 bit stack mode.\n");
-         }
-
        if (stk)
          {
            emitcode ("mov", "a,_bp");
@@ -924,7 +884,6 @@ static void
 aopPut (asmop * aop, char *s, int offset)
 {
   char *d = buffer;
-  symbol *lbl;
 
   if (aop->size && offset > (aop->size - 1))
     {
@@ -1079,17 +1038,22 @@ aopPut (asmop * aop, char *s, int offset)
            emitcode ("mov", "%s,c", aop->aopu.aop_dir);
          else
            {
-             lbl = newiTempLabel (NULL);
-
              if (strcmp (s, "a"))
                {
                  MOVA (s);
                }
-             emitcode ("clr", "c");
-             emitcode ("jz", "%05d$", lbl->key + 100);
-             emitcode ("cpl", "c");
-             emitcode ("", "%05d$:", lbl->key + 100);
-             emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+#if 0 // jwk: I am not 1000% sure
+             {
+               symbol *lbl = newiTempLabel (NULL);
+               emitcode ("clr", "c");
+               emitcode ("jz", "%05d$", lbl->key + 100);
+               emitcode ("cpl", "c");
+               emitcode ("", "%05d$:", lbl->key + 100);
+               emitcode ("mov", "%s,c", aop->aopu.aop_dir);
+             }
+#else
+             emitcode ("mov", "%s,acc.0", aop->aopu.aop_dir);
+#endif
            }
        }
       break;
@@ -1152,17 +1116,15 @@ pointToEnd (asmop * aop)
 static void
 reAdjustPreg (asmop * aop)
 {
-  int size;
-
   aop->coff = 0;
-  if ((size = aop->size) <= 1)
+  if ((aop->coff==0) || aop->size <= 1)
     return;
-  size--;
+
   switch (aop->type)
     {
     case AOP_R0:
     case AOP_R1:
-      while (size--)
+      while (aop->coff--)
        emitcode ("dec", "%s", aop->aopu.aop_ptr->name);
       break;
     case AOP_DPTR:
@@ -1171,7 +1133,7 @@ reAdjustPreg (asmop * aop)
        {
          genSetDPTR (1);
        }
-      while (size--)
+      while (aop->coff--)
        {
          emitcode ("lcall", "__decdptr");
        }
@@ -2031,12 +1993,6 @@ genPcall (iCode * ic)
   emitcode ("mov", "a,#(%05d$ >> 8)", (rlbl->key + 100));
   emitcode ("push", "acc");
 
-  if (options.model == MODEL_FLAT24)
-    {
-      emitcode ("mov", "a,#(%05d$ >> 16)", (rlbl->key + 100));
-      emitcode ("push", "acc");
-    }
-
   /* now push the calling address */
   aopOp (IC_LEFT (ic), ic, FALSE);
 
@@ -2222,20 +2178,6 @@ genFunction (iCode * ic)
        emitcode ("push", "dpl");
       if (!inExcludeList ("dph"))
        emitcode ("push", "dph");
-      if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
-       {
-         emitcode ("push", "dpx");
-         /* Make sure we're using standard DPTR */
-         emitcode ("push", "dps");
-         emitcode ("mov", "dps, #0x00");
-         if (options.stack10bit)
-           {
-             /* This ISR could conceivably use DPTR2. Better save it. */
-             emitcode ("push", "dpl1");
-             emitcode ("push", "dph1");
-             emitcode ("push", "dpx1");
-           }
-       }
       /* if this isr has no bank i.e. is going to
          run with bank 0 , then we need to save more
          registers :-) */
@@ -2434,17 +2376,6 @@ genEndFunction (iCode * ic)
            }
        }
 
-      if (options.model == MODEL_FLAT24 && !inExcludeList ("dpx"))
-       {
-         if (options.stack10bit)
-           {
-             emitcode ("pop", "dpx1");
-             emitcode ("pop", "dph1");
-             emitcode ("pop", "dpl1");
-           }
-         emitcode ("pop", "dps");
-         emitcode ("pop", "dpx");
-       }
       if (!inExcludeList ("dph"))
        emitcode ("pop", "dph");
       if (!inExcludeList ("dpl"))
@@ -3223,8 +3154,9 @@ genMultbits (operand * left,
 
 
 /*-----------------------------------------------------------------*/
-/* genMultOneByte : 8 bit multiplication & division                */
+/* genMultOneByte : 8*8=8/16 bit multiplication                    */
 /*-----------------------------------------------------------------*/
+#if 0 // REMOVE ME
 static void
 genMultOneByte (operand * left,
                operand * right,
@@ -3315,6 +3247,108 @@ genMultOneByte (operand * left,
          aopPut (AOP (result), "a", offset++);
     }
 }
+#else
+static void
+genMultOneByte (operand * left,
+               operand * right,
+               operand * result)
+{
+  sym_link *opetype = operandType (result);
+  symbol *lbl;
+  int size=AOP_SIZE(result);
+
+  //emitcode (";",__FUNCTION__);
+  if (size<1 || size>2) {
+    // this should never happen
+      fprintf (stderr, "size!=1||2 (%d) in %s at line:%d \n", 
+              AOP_SIZE(result), __FUNCTION__, lineno);
+      exit (1);
+  }
+
+  /* (if two literals: the value is computed before) */
+  /* if one literal, literal on the right */
+  if (AOP_TYPE (left) == AOP_LIT)
+    {
+      operand *t = right;
+      right = left;
+      left = t;
+      //emitcode (";", "swapped left and right");
+    }
+
+  if (SPEC_USIGN(opetype)
+      // ignore the sign of left and right, what else can we do?
+      || (SPEC_USIGN(operandType(left)) && 
+         SPEC_USIGN(operandType(right)))) {
+    // just an unsigned 8*8=8/16 multiply
+    //emitcode (";","unsigned");
+    emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+    MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+    emitcode ("mul", "ab");
+    aopPut (AOP (result), "a", 0);
+    if (size==2) {
+      aopPut (AOP (result), "b", 1);
+    }
+    return;
+  }
+
+  // we have to do a signed multiply
+
+  //emitcode (";", "signed");
+  emitcode ("clr", "F0"); // reset sign flag
+  emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+  MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+
+  lbl=newiTempLabel(NULL);
+  emitcode ("jnb", "acc.7,%05d$",  lbl->key+100);
+  // left side is negative, 8-bit two's complement, this fails for -128
+  emitcode ("setb", "F0"); // set sign flag
+  emitcode ("cpl", "a");
+  emitcode ("inc", "a");
+
+  emitcode ("", "%05d$:", lbl->key+100);
+  emitcode ("xch", "a,b");
+
+  /* if literal */
+  if (AOP_TYPE(right)==AOP_LIT) {
+    /* AND literal negative */
+    if ((int) floatFromVal (AOP (right)->aopu.aop_lit) < 0) {
+      // two's complement for literal<0
+      emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
+      emitcode ("cpl", "a");
+      emitcode ("inc", "a");
+    }
+  } else {
+    lbl=newiTempLabel(NULL);
+    emitcode ("jnb", "acc.7,%05d$", lbl->key+100);
+    // right side is negative, 8-bit two's complement
+    emitcode ("xrl", "PSW,#0x20"); // xrl sign flag
+    emitcode ("cpl", "a");
+    emitcode ("inc", "a");
+    emitcode ("", "%05d$:", lbl->key+100);
+  }
+  emitcode ("mul", "ab");
+    
+  lbl=newiTempLabel(NULL);
+  emitcode ("jnb", "F0,%05d$", lbl->key+100);
+  // only ONE op was negative, we have to do a 8/16-bit two's complement
+  emitcode ("cpl", "a"); // lsb
+  if (size==1) {
+    emitcode ("inc", "a");
+  } else {
+    emitcode ("add", "a,#1");
+    emitcode ("xch", "a,b");
+    emitcode ("cpl", "a"); // msb
+    emitcode ("addc", "a,#0");
+    emitcode ("xch", "a,b");
+  }
+
+  emitcode ("", "%05d$:", lbl->key+100);
+  aopPut (AOP (result), "a", 0);
+  if (size==2) {
+    aopPut (AOP (result), "b", 1);
+  }
+}
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genMult - generates code for multiplication                     */
@@ -5507,18 +5541,25 @@ AccAXLsh (char *x, int shCount)
 
       break;
     case 6:                    // AAAAAABB:CCCCCCDD
-
       emitcode ("anl", "a,#0x%02x",
                SRMask[shCount]);       // 000000BB:CCCCCCDD
-
       emitcode ("mov", "c,acc.0");     // c = B
-
       emitcode ("xch", "a,%s", x);     // CCCCCCDD:000000BB
-
+#if 0 // REMOVE ME
       AccAXRrl1 (x);           // BCCCCCCD:D000000B
-
       AccAXRrl1 (x);           // BBCCCCCC:DD000000
-
+#else
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+      emitcode("rrc","a"); 
+      emitcode("mov","c,acc.0"); //<< get correct bit 
+      emitcode("xch","a,%s", x); 
+
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+      emitcode("rrc","a"); 
+      emitcode("xch","a,%s", x); 
+#endif
       break;
     case 7:                    // a:x <<= 7
 
@@ -6966,10 +7007,6 @@ genFarPointerGet (operand * left,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
          emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
-         if (options.model == MODEL_FLAT24)
-           {
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE));
-           }
        }
     }
   /* so dptr know contains the address */
@@ -7019,10 +7056,6 @@ emitcodePointerGet (operand * left,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
          emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
-         if (options.model == MODEL_FLAT24)
-           {
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE));
-           }
        }
     }
   /* so dptr know contains the address */
@@ -7076,15 +7109,7 @@ genGenPointerGet (operand * left,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (left), 0, FALSE, FALSE));
          emitcode ("mov", "dph,%s", aopGet (AOP (left), 1, FALSE, FALSE));
-         if (options.model == MODEL_FLAT24)
-           {
-             emitcode ("mov", "dpx,%s", aopGet (AOP (left), 2, FALSE, FALSE));
-             emitcode ("mov", "b,%s", aopGet (AOP (left), 3, FALSE, FALSE));
-           }
-         else
-           {
-             emitcode ("mov", "b,%s", aopGet (AOP (left), 2, FALSE, FALSE));
-           }
+         emitcode ("mov", "b,%s", aopGet (AOP (left), 2, FALSE, FALSE));
        }
     }
   /* so dptr know contains the address */
@@ -7592,10 +7617,6 @@ genFarPointerSet (operand * right,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
          emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
-         if (options.model == MODEL_FLAT24)
-           {
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE));
-           }
        }
     }
   /* so dptr know contains the address */
@@ -7650,15 +7671,7 @@ genGenPointerSet (operand * right,
        {                       /* we need to get it byte by byte */
          emitcode ("mov", "dpl,%s", aopGet (AOP (result), 0, FALSE, FALSE));
          emitcode ("mov", "dph,%s", aopGet (AOP (result), 1, FALSE, FALSE));
-         if (options.model == MODEL_FLAT24)
-           {
-             emitcode ("mov", "dpx,%s", aopGet (AOP (result), 2, FALSE, FALSE));
-             emitcode ("mov", "b,%s", aopGet (AOP (result), 3, FALSE, FALSE));
-           }
-         else
-           {
-             emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE));
-           }
+         emitcode ("mov", "b,%s", aopGet (AOP (result), 2, FALSE, FALSE));
        }
     }
   /* so dptr know contains the address */
@@ -7806,25 +7819,10 @@ genAddrOf (iCode * ic)
       /* fill the result with zero */
       size = AOP_SIZE (IC_RESULT (ic)) - 1;
 
-
-      if (options.stack10bit && size < (FPTRSIZE - 1))
-       {
-         fprintf (stderr,
-                  "*** warning: pointer to stack var truncated.\n");
-       }
-
       offset = 1;
       while (size--)
        {
-         /* Yuck! */
-         if (options.stack10bit && offset == 2)
-           {
-             aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++);
-           }
-         else
-           {
-             aopPut (AOP (IC_RESULT (ic)), zero, offset++);
-           }
+         aopPut (AOP (IC_RESULT (ic)), zero, offset++);
        }
 
       goto release;
@@ -8265,11 +8263,11 @@ genReceive (iCode * ic)
     {
 
       int size = getSize (operandType (IC_RESULT (ic)));
-      int offset = fReturnSize - size;
+      int offset = fReturnSizeMCS51 - size;
       while (size--)
        {
-         emitcode ("push", "%s", (strcmp (fReturn[fReturnSize - offset - 1], "a") ?
-                               fReturn[fReturnSize - offset - 1] : "acc"));
+         emitcode ("push", "%s", (strcmp (fReturn[fReturnSizeMCS51 - offset - 1], "a") ?
+                               fReturn[fReturnSizeMCS51 - offset - 1] : "acc"));
          offset++;
        }
       aopOp (IC_RESULT (ic), ic, FALSE);