* Added support for doing shifts by helper functions
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Aug 2001 15:21:20 +0000 (15:21 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Aug 2001 15:21:20 +0000 (15:21 +0000)
* Fleshed out long support in the z80 port
* Fixed left and right shift in the z80 port.

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1122 4a8a32a2-be11-0410-ad9d-d568d2c75423

13 files changed:
src/SDCCicode.c
src/SDCCloop.c
src/SDCCopt.c
src/SDCCsymt.c
src/SDCCsymt.h
src/avr/main.c
src/ds390/main.c
src/izt/tlcs900h.c
src/mcs51/main.c
src/pic/main.c
src/port.h
src/z80/gen.c
src/z80/main.c

index 44403c9f610f3176216d7b4c9165eb84aeea001c..4e93c888ce17805e5b38e4ade37243139f6c8165 100644 (file)
@@ -1632,7 +1632,7 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt)
      if port has 1 byte muldiv */
   if (p2 && !IS_FLOAT (letype) &&
       !((resultIsInt) && (getSize (resType) != getSize (ltype)) && 
-       (port->muldiv.native_below == 1)))
+       (port->support.muldiv == 1)))
     {
       if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
        {
index ca70d4b338eb52bb9bbbee8e7492d54a12002163..a50bac498eaa411e1cb97cf5e0cd419fc00efba0 100644 (file)
@@ -947,8 +947,8 @@ loopInduction (region * loopReg, eBBlock ** ebbs, int count)
 
          /* ask port for size not worth if native instruction
             exist for multiply & divide */
-         if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->muldiv.native_below ||
-         getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->muldiv.native_below)
+         if (getSize (operandType (IC_LEFT (ic))) <= (unsigned long) port->support.muldiv ||
+         getSize (operandType (IC_RIGHT (ic))) <= (unsigned long) port->support.muldiv)
            continue;
 
          /* if this is a division then the remainder should be zero
index 8ed9c5979396b7cc4f29439cc08f03f1e93bf32d..33d7a3515dd766d14ff51d5682b3b8c59b27ee23 100644 (file)
@@ -340,6 +340,14 @@ convilong (iCode * ic, eBBlock * ebp, sym_link * type, int op)
                func = __muldiv[1][bwd][su];
              else if (op == '%')
                func = __muldiv[2][bwd][su];
+              else if (op == RRC)
+               func = __rlrr[1][bwd][su];
+              else if (op == RLC)
+               func = __rlrr[0][bwd][su];
+              else if (op == RIGHT_OP)
+               func = __rlrr[1][bwd][su];
+              else if (op == LEFT_OP)
+               func = __rlrr[0][bwd][su];
              else
                assert (0);
              goto found;
@@ -373,32 +381,36 @@ found:
       addiCodeToeBBlock (ebp, newic, ip);
       newic->lineno = lineno;
 
-
     }
   else
     {
-
       /* compiled as reentrant then push */
       /* push right */
       if (IS_REGPARM (func->args->next->etype))
-       newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+        {
+          newic = newiCode (SEND, IC_RIGHT (ic), NULL);
+        }
       else
        {
          newic = newiCode (IPUSH, IC_RIGHT (ic), NULL);
          newic->parmPush = 1;
-         bytesPushed += getSize(type);
+
+         bytesPushed += getSize(operandType(IC_RIGHT(ic)));
        }
       addiCodeToeBBlock (ebp, newic, ip);
       newic->lineno = lineno;
 
       /* insert push left */
       if (IS_REGPARM (func->args->etype))
-       newic = newiCode (SEND, IC_LEFT (ic), NULL);
+        {
+          newic = newiCode (SEND, IC_LEFT (ic), NULL);
+        }
       else
        {
          newic = newiCode (IPUSH, IC_LEFT (ic), NULL);
          newic->parmPush = 1;
-         bytesPushed += getSize(type);
+
+         bytesPushed += getSize(operandType(IC_LEFT(ic)));
        }
       addiCodeToeBBlock (ebp, newic, ip);
       newic->lineno = lineno;
@@ -452,11 +464,22 @@ convertToFcall (eBBlock ** ebbs, int count)
          /* if long / int mult or divide or mod */
          if (ic->op == '*' || ic->op == '/' || ic->op == '%')
            {
-
              sym_link *type = operandType (IC_LEFT (ic));
-             if (IS_INTEGRAL (type) && getSize (type) > port->muldiv.native_below)
-               convilong (ic, ebbs[i], type, ic->op);
+             if (IS_INTEGRAL (type) && getSize (type) > port->support.muldiv)
+                {
+                  convilong (ic, ebbs[i], type, ic->op);
+                }
            }
+          
+          if (ic->op == RRC || ic->op == RLC || ic->op == LEFT_OP || ic->op == RIGHT_OP)
+            {
+             sym_link *type = operandType (IC_LEFT (ic));
+
+             if (IS_INTEGRAL (type) && getSize (type) > port->support.shift && port->support.shift >= 0)
+                {
+                  convilong (ic, ebbs[i], type, ic->op);
+                }
+            }
        }
     }
 }
index f830136954bce1767e639ed8b77cac9d9f8f9db2..2037ea608b518dac9a7f88430ef4d48ed9a1e3b3 100644 (file)
@@ -2261,25 +2261,11 @@ symbol *__muldiv[3][3][2];
 sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
 symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
 
 sym_link *floatType;
 
-static void 
-_makeRegParam (symbol * sym)
-{
-  value *val;
-
-  val = sym->args;             /* loop thru all the arguments   */
-
-  /* reset regparm for the port */
-  (*port->reset_regparms) ();
-  while (val)
-    {
-      SPEC_REGPARM (val->etype) = 1;
-      val = val->next;
-    }
-}
-
 static char *
 _mangleFunctionName(char *in)
 {
@@ -2311,8 +2297,12 @@ initCSupport ()
   {
     "s", "u"
   };
+  const char *srlrr[] =
+  {
+    "rl", "rr"
+  };
 
-  int bwd, su, muldivmod, tofrom;
+  int bwd, su, muldivmod, tofrom, rlrr;
 
   floatType = newFloatLink ();
 
@@ -2381,8 +2371,22 @@ initCSupport ()
                       sbwd[bwd]);
               __muldiv[muldivmod][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[bwd][su], 2, options.intlong_rent);
              SPEC_NONBANKED (__muldiv[muldivmod][bwd][su]->etype) = 1;
-             if (bwd < port->muldiv.force_reg_param_below)
-               _makeRegParam (__muldiv[muldivmod][bwd][su]);
+           }
+       }
+    }
+
+  for (rlrr = 0; rlrr < 2; rlrr++)
+    {
+      for (bwd = 0; bwd < 3; bwd++)
+       {
+         for (su = 0; su < 2; su++)
+           {
+             sprintf (buffer, "_%s%s%s",
+                      srlrr[rlrr],
+                      ssu[su],
+                      sbwd[bwd]);
+              __rlrr[rlrr][bwd][su] = funcOfType (_mangleFunctionName(buffer), __multypes[bwd][su], __multypes[0][0], 2, options.intlong_rent);
+             SPEC_NONBANKED (__rlrr[rlrr][bwd][su]->etype) = 1;
            }
        }
     }
index 7033b2cdfde01f98a706637328c0a6a23c43dfaa..2b06d0dd653dc98e8c2d79c4edebc3246cb295e9 100644 (file)
@@ -383,6 +383,8 @@ extern symbol *__muldiv[3][3][2];
 extern sym_link *__multypes[3][2];
 /* Dims: to/from float, BYTE/WORD/DWORD, SIGNED/USIGNED */
 extern symbol *__conv[2][3][2];
+/* Dims: shift left/shift right, BYTE/WORD/DWORD, SIGNED/UNSIGNED */
+symbol *__rlrr[2][3][2];
 
 #define CHARTYPE       __multypes[0][0]
 #define UCHARTYPE      __multypes[0][1]
index 5ddc571edb913f02886b5e2474415998c047fe6a..a9bcd4696ce99e285b9adc059323d2c13cf772db 100644 (file)
@@ -190,7 +190,8 @@ PORT avr_port = {
         -1, 1, 4, 1, 1, 0},
        /* avr has an 8 bit mul */
        {
-        1, 0},
+          1, -1
+        },
        "_",
        _avr_init,
        _avr_parseOptions,
index 1301e60396426f34f23ecb1b5f884cb7828eb961..3bafacb7ce2cff0a826d7a1fe8c2b3aa65988fe9 100644 (file)
@@ -248,7 +248,7 @@ PORT ds390_port =
   },
     /* ds390 has an 8 bit mul */
   {
-    1, 0
+    1, -1
   },
   "_",
   _ds390_init,
index addb859799d1cbc4b81db1876b3287e9b67d4610..bc9d8d50faec7225df11dcc81709cd0f9502bdff 100644 (file)
@@ -181,7 +181,7 @@ PORT tlcs900h_port =
   },
     /* tlcs900h has an 16 bit mul */
   {
-    2, 0
+    2, -1
   },
   "_",
   _tlcs900h_init,
index f7af7756f45fef0e067e5ab1f5ef5fc9249d6eba..68e32ea3f8b77dfaaff991003e0107a1b4d35cc2 100644 (file)
@@ -188,7 +188,7 @@ PORT mcs51_port =
   },
     /* mcs51 has an 8 bit mul */
   {
-    1, 0
+    1, -1
   },
   "_",
   _mcs51_init,
index d2222421511fc8c49c96355c79d0aaddd3571cbb..d411f5003944e553949b234f5041278d1863043e 100644 (file)
@@ -272,7 +272,7 @@ PORT pic_port =
   },
     /* pic14 has an 8 bit mul */
   {
-    1, 0
+    1, -1
   },
   "_",
   _pic14_init,
index 9bf97e4959a0c5cee4144d69ac46274149e7a780..d53dd0ce0b68879288cdc2d074734b705d408083 100644 (file)
@@ -148,13 +148,10 @@ typedef struct
        /** One more than the smallest 
            mul/div operation the processor can do nativley 
            Eg if the processor has an 8 bit mul, nativebelow is 2 */
-       unsigned native_below;
-       /** The mul/div/mod functions will be made to use regparams
-           for sizeof(param) < log2(force_reg)
-           i.e. Use 2 for WORD and BYTE, 0 for none. */
-       int force_reg_param_below;
+       unsigned muldiv;
+        unsigned shift;
       }
-    muldiv;
+    support;
 
 /** Prefix to add to a C function (eg "_") */
     const char *fun_prefix;
index ffef364818ec9c0c860d9fd2d5943f6694de1c8e..77764b7fcb75163655bbb47f27bcdc50d293464a 100644 (file)
@@ -794,10 +794,6 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
   char *s = buffer;
   char *rs;
 
-#if 0
-  if (aop->size != 2 && aop->type != AOP_HL)
-    return NULL;
-#endif
   /* depending on type */
   switch (aop->type)
     {
@@ -809,9 +805,9 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
        tsprintf (s, "!hashedstr + %d", aop->aopu.aop_immd, offset);
       else
        tsprintf (s, "%s + %d", aop->aopu.aop_immd, offset);
-      rs = Safe_calloc (1, strlen (s) + 1);
-      strcpy (rs, s);
-      return rs;
+
+      return gc_strdup(s);
+
     case AOP_LIT:
       {
        value *val = aop->aopu.aop_lit;
@@ -822,14 +818,24 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
            unsigned long v = (unsigned long) floatFromVal (val);
 
            if (offset == 2)
-             v >>= 16;
+              {
+                v >>= 16;
+              }
+            else if (offset == 0)
+              {
+                // OK
+              }
+            else 
+              {
+                wassertl(0, "Encountered an invalid offset while fetching a literal");
+              }
 
            if (with_hash)
              tsprintf (buffer, "!immedword", v);
            else
              tsprintf (buffer, "!constword", v);
-           rs = Safe_calloc (1, strlen (buffer) + 1);
-           return strcpy (rs, buffer);
+
+            return gc_strdup(buffer);
          }
        else
          {
@@ -938,7 +944,7 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
 {
   const char *l;
   const char *pair = _pairs[pairId].name;
-  l = aopGetLitWordLong (left, 0, FALSE);
+  l = aopGetLitWordLong (left, offset, FALSE);
   wassert (l && pair);
 
   if (isPtr (pair))
@@ -980,10 +986,7 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset)
       _G.pairs[pairId].offset = offset;
     }
   /* Both a lit on the right and a true symbol on the left */
-  if (offset)
-    emit2 ("ld %s,!hashedstr + %u", pair, l, offset);
-  else
-    emit2 ("ld %s,!hashedstr", pair, l);
+  emit2 ("ld %s,!hashedstr", pair, l);
 }
 
 static void
@@ -1796,42 +1799,6 @@ genIpush (iCode * ic)
   if (!ic->parmPush)
     {
       wassertl(0, "Encountered an unsupported spill push.");
-#if 0
-      /* and the item is spilt then do nothing */
-      if (OP_SYMBOL (IC_LEFT (ic))->isspilt)
-       return;
-
-      aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
-      size = AOP_SIZE (IC_LEFT (ic));
-      /* push it on the stack */
-      if (isPair (AOP (IC_LEFT (ic))))
-       {
-         emit2 ("push %s", getPairName (AOP (IC_LEFT (ic))));
-         _G.stack.pushed += 2;
-       }
-      else
-       {
-         offset = size;
-         while (size--)
-           {
-             /* Simple for now - load into A and PUSH AF */
-             if (AOP (IC_LEFT (ic))->type == AOP_IY)
-               {
-                 char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE);
-                 wassert (l);
-                 emit2 ("ld a,(%s)", l);
-               }
-             else
-               {
-                 l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE);
-                 emit2 ("ld a,%s", l);
-               }
-             emit2 ("push af");
-             emit2 ("inc sp");
-             _G.stack.pushed++;
-           }
-       }
-#endif
       return;
     }
 
@@ -4308,47 +4275,48 @@ genRLC (iCode * ic)
 static void
 shiftR2Left2Result (operand * left, int offl,
                    operand * result, int offr,
-                   int shCount, int sign)
+                   int shCount, int is_signed)
 {
+  int size = 2;
+  int offset = 0;
+  symbol *tlbl, *tlbl1;
+  const char *l;
+
   movLeft2Result (left, offl, result, offr, 0);
   movLeft2Result (left, offl + 1, result, offr + 1, 0);
 
-  if (sign)
+  /*  if (AOP(result)->type == AOP_REG) { */
+  
+  tlbl = newiTempLabel (NULL);
+  tlbl1 = newiTempLabel (NULL);
+  
+  /* Left is already in result - so now do the shift */
+  if (shCount > 1)
     {
-      wassert (0);
+      emit2 ("ld a,!immedbyte+1", shCount);
+      emit2 ("!shortjp !tlabel", tlbl1->key + 100);
+      emitLabel (tlbl->key + 100);
     }
-  else
+  
+  offset = 0;
+  while (size--)
     {
-      /*  if (AOP(result)->type == AOP_REG) { */
-      int size = 2;
-      int offset = 0;
-      symbol *tlbl, *tlbl1;
-      const char *l;
-
-      tlbl = newiTempLabel (NULL);
-      tlbl1 = newiTempLabel (NULL);
-
-      /* Left is already in result - so now do the shift */
-      if (shCount > 1)
-       {
-         emit2 ("ld a,!immedbyte+1", shCount);
-         emit2 ("!shortjp !tlabel", tlbl1->key + 100);
-         emitLabel (tlbl->key + 100);
-       }
-
-      emit2 ("or a,a");
-      offset = size;
-      while (size--)
-       {
-         l = aopGet (AOP (result), --offset, FALSE);
-         emit2 ("rr %s", l);
-       }
-      if (shCount > 1)
-       {
-         emitLabel (tlbl1->key + 100);
-         emit2 ("dec a");
-         emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
-       }
+      l = aopGet (AOP (result), size, FALSE);
+      if (offset == 0)
+        {
+          emit2 ("%s %s", is_signed ? "sra" : "srl", l);
+        }
+      else
+        {
+          emit2 ("rr %s", l);
+        }
+      offset++;
+    }
+  if (shCount > 1)
+    {
+      emitLabel (tlbl1->key + 100);
+      emit2 ("dec a");
+      emit2 ("!shortjp nz,!tlabel", tlbl->key + 100);
     }
 }
 
@@ -4392,8 +4360,11 @@ shiftL2Left2Result (operand * left, int offl,
     emit2 ("or a,a");
     while (size--)
       {
-       l = aopGet (AOP (result), offset++, FALSE);
+       l = aopGet (AOP (result), offset, FALSE);
+
        emit2 ("rl %s", l);
+
+        offset++;
       }
     if (shCount > 1)
       {
@@ -4681,7 +4652,9 @@ genLeftShift (iCode * ic)
   emit2 ("!shortjp !tlabel", tlbl1->key + 100);
   emitLabel (tlbl->key + 100);
   l = aopGet (AOP (result), offset, FALSE);
+
   emit2 ("or a,a");
+
   while (size--)
     {
       l = aopGet (AOP (result), offset++, FALSE);
@@ -4699,7 +4672,7 @@ genLeftShift (iCode * ic)
 /* genrshOne - left shift two bytes by known amount != 0           */
 /*-----------------------------------------------------------------*/
 static void
-genrshOne (operand * result, operand * left, int shCount)
+genrshOne (operand * result, operand * left, int shCount, int is_signed)
 {
   /* Errk */
   int size = AOP_SIZE (result);
@@ -4709,19 +4682,24 @@ genrshOne (operand * result, operand * left, int shCount)
   wassert (shCount < 8);
 
   l = aopGet (AOP (left), 0, FALSE);
+
+  emit2 ("or a,a");
+
   if (AOP (result)->type == AOP_REG)
     {
       aopPut (AOP (result), l, 0);
       l = aopGet (AOP (result), 0, FALSE);
       while (shCount--)
-       emit2 ("srl %s", l);
+        {
+          emit2 ("%s %s", is_signed ? "sra" : "srl", l);
+        }
     }
   else
     {
       _moveA (l);
       while (shCount--)
        {
-         emit2 ("srl a");
+         emit2 ("%s a", is_signed ? "sra" : "srl");
        }
       aopPut (AOP (result), "a", 0);
     }
@@ -4803,7 +4781,8 @@ static void
 genRightShiftLiteral (operand * left,
                      operand * right,
                      operand * result,
-                     iCode * ic)
+                     iCode * ic,
+                      int sign)
 {
   int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit);
   int size;
@@ -4832,17 +4811,17 @@ genRightShiftLiteral (operand * left,
       switch (size)
        {
        case 1:
-         genrshOne (result, left, shCount);
+         genrshOne (result, left, shCount, sign);
          break;
        case 2:
          /* PENDING: sign support */
-         genrshTwo (result, left, shCount, FALSE);
+         genrshTwo (result, left, shCount, sign);
          break;
        case 4:
-         wassert (0);
+         wassertl (0, "Asked to shift right a long which should be a function call");
          break;
        default:
-         wassert (0);
+         wassertl (0, "Entered default case in right shift delegate");
        }
     }
   freeAsmop (left, NULL, ic);
@@ -4886,7 +4865,7 @@ genRightShift (iCode * ic)
      as efficiently as possible */
   if (AOP_TYPE (right) == AOP_LIT)
     {
-      genRightShiftLiteral (left, right, result, ic);
+      genRightShiftLiteral (left, right, result, ic, is_signed);
       return;
     }
 
@@ -4925,14 +4904,13 @@ genRightShift (iCode * ic)
       l = aopGet (AOP (result), offset--, FALSE);
       if (first)
        {
-         if (is_signed)
-           emit2 ("sra %s", l);
-         else
-           emit2 ("srl %s", l);
+          emit2 ("%s %s", is_signed ? "sra" : "srl", l);
          first = 0;
        }
       else
-       emit2 ("rr %s", l);
+        {
+          emit2 ("rr %s", l);
+        }
     }
   emitLabel (tlbl1->key + 100);
   emit2 ("dec a");
index aa8d569c15f16641d644652b6912a8138f2068db..9fb9b075889771a832d36fb49a00e8069083ef81 100644 (file)
@@ -511,7 +511,7 @@ PORT z80_port =
   },
     /* Z80 has no native mul/div commands */
   {
-    0, 0
+    0, 2
   },
   "_",
   _z80_init,