* src/hc08/ralloc.c (canDefAccResult, canUseAccOperand,
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Sep 2004 05:48:13 +0000 (05:48 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Thu, 2 Sep 2004 05:48:13 +0000 (05:48 +0000)
packRegsForAccUse, packRegisters): new accumulator register
packing algorithm
* support/regression/ports/hc08/support.c (_putchar): suppress
warning of unused variable
* src/SDCCicode.c: added SWAP entry to codeTable

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

ChangeLog
src/SDCCicode.c
src/hc08/ralloc.c
support/regression/ports/hc08/support.c

index ac8553ce6d3b7fb1c519e274335312a067c5635a..32184368304804e172b18ec5011d2158a61b4a26 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2004-09-02 Erik Petrich <epetrich AT ivorytower.norman.ok.us>
+
+       * src/hc08/ralloc.c (canDefAccResult, canUseAccOperand,
+       packRegsForAccUse, packRegisters): new accumulator register
+       packing algorithm
+       * support/regression/ports/hc08/support.c (_putchar): suppress
+       warning of unused variable
+       * src/SDCCicode.c: added SWAP entry to codeTable
+
 2004-09-01 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * device/lib/sprintf.c: forgot to add this file before previous commit
index f65162404b713092cb5b2c5969f352e082b23e8f..34002152e0b901e0b730ea48c98affe070939265 100644 (file)
@@ -120,7 +120,8 @@ iCodeTable codeTable[] =
   {ARRAYINIT, "arrayInit", picGenericOne, NULL},
   {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
   {CRITICAL, "critical_start", picCritical, NULL},
-  {ENDCRITICAL, "critical_end", picEndCritical, NULL}
+  {ENDCRITICAL, "critical_end", picEndCritical, NULL},
+  {SWAP, "swap", picGenericOne, NULL}
 };
 
 /*-----------------------------------------------------------------*/
index 975f1469233cb5ffc8dc8b900084bb32ae304adf..ff0dcf5637a652e7b25d0f013cafb7389522171a 100644 (file)
@@ -2501,168 +2501,164 @@ bool operandUsesAcc2(operand *op)
 }
 
 /*-----------------------------------------------------------------*/
-/* packRegsForAccUse - pack registers for acc use                  */
+/* canUseAccOperand - return 1 if the iCode can gemerate a result  */
+/*                    in A or XA                                   */
 /*-----------------------------------------------------------------*/
-static void
-packRegsForAccUse (iCode * ic)
+static int
+canDefAccResult (iCode * ic)
 {
-  iCode *uic;
-
-  /* if this is an aggregate, e.g. a one byte char array */
-  if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
-    return;
-  }
-
-  /* if we are calling a reentrant function that has stack parameters */
-  #if 0
-  if (ic->op == CALL &&
-       IFFUNC_ISREENT(operandType(IC_LEFT(ic))) &&
-       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))))
-      return;
-
-  if (ic->op == PCALL &&
-       IFFUNC_ISREENT(operandType(IC_LEFT(ic))->next) &&
-       FUNC_HASSTACKPARM(operandType(IC_LEFT(ic))->next))
-      return;
-  #endif
-
-  /* if + or - then it has to be one byte result */
-  if ((ic->op == '+' || ic->op == '-')
-      && getSize (operandType (IC_RESULT (ic))) > 1)
-    return;
-
-
-  /* if shift operation make sure right side is a literal */
-  if (ic->op == RIGHT_OP &&
-      (!isOperandLiteral (IC_RIGHT (ic)) ||
-       (getSize (operandType (IC_RESULT (ic) )) > 1)))
-    return;
-
-  if (ic->op == LEFT_OP &&
-      (!isOperandLiteral (IC_RIGHT (ic)) ||
-       (getSize (operandType (IC_RESULT (ic) )) > 1)))
-    return;
-
-  if (IS_BITWISE_OP (ic) &&
-      getSize (operandType (IC_RESULT (ic))) > 1)
-    return;
-
-
-  /* has only one definition */
-  if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
-    return;
-
-  /* has only one use */
-  if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1)
-    return;
-
-  /* and the usage immediately follows this iCode */
-  if (!(uic = hTabItemWithKey (iCodehTab,
-                              bitVectFirstBit (OP_USES (IC_RESULT (ic))))))
-    return;
-
-  if (ic->next != uic)
-    return;
+  int size;
+  
+  if (ic->op == IFX || ic->op == JUMPTABLE)    /* these iCodes have no result */
+    return 0;
 
-  /* if it is a conditional branch then we definitely can */
-  if (uic->op == IFX)
-    goto accuse;
+  if (POINTER_SET (ic))
+    return 0;
 
-  if (uic->op == JUMPTABLE)
-    return;
+  if (!IC_RESULT (ic))
+    return 0;
 
-#if 0
-  if (POINTER_SET (uic) &&
-      getSize (aggrToPtr (operandType (IC_RESULT (uic)), FALSE)) > 1)
-    return;
-#endif
+  if (!IS_ITEMP (IC_RESULT (ic)))
+    return 0;
+  
+  /* I don't think an iTemp can be an aggregate, but just in case */
+  if (IS_AGGREGATE(operandType(IC_RESULT(ic))))
+    return 0;
 
-  /* if the usage is not is an assignment
-     or an arithmetic / bitwise / shift operation then not */
-  if (uic->op != '=' &&
-      !IS_ARITHMETIC_OP (uic) &&
-      !IS_BITWISE_OP (uic) &&
-      (uic->op != LEFT_OP) &&
-      (uic->op != RIGHT_OP) &&
-      (uic->op != GETHBIT) &&
-      (uic->op != RETURN) &&
-      (uic->op != '~') &&
-      (uic->op != '!'))
-    return;
+  size = getSize (operandType (IC_RESULT (ic)));
 
-#if 0
-  /* if used in ^ operation then make sure right is not a 
-     literal (WIML: Why is this?) */
-  if (uic->op == '^' && isOperandLiteral (IC_RIGHT (uic)))
-    return;
+  if (size == 1)
+    {
+      /* All 1 byte operations should safely generate an accumulator result */
+      return 1;
+    }
+  else if (size == 2)
+    {
+      switch (ic->op)
+        {
+        case LEFT_OP:
+        case RIGHT_OP:
+          return isOperandLiteral (IC_RIGHT (ic));
+        case CALL:
+        case PCALL:
+        case '*':
+        case RECEIVE:
+        case '=': /* assignment, since POINTER_SET is already ruled out */
+          return 1;
+
+        default:
+          return 0;
+        }
+    }
+  
+  return 0;
+}
 
-  /* if shift operation make sure right side is not a literal */
-  /* WIML: Why is this? */
-  if (uic->op == RIGHT_OP &&
-      (isOperandLiteral (IC_RIGHT (uic)) ||
-       getSize (operandType (IC_RESULT (uic))) > 1))
-    return;
-  if (uic->op == LEFT_OP &&
-      (isOperandLiteral (IC_RIGHT (uic)) ||
-       getSize (operandType (IC_RESULT (uic))) > 1))
-    return;
-#endif
+/*-----------------------------------------------------------------*/
+/* canUseAccOperand - return 1 if the iCode can use the operand    */
+/*                    when passed in A or XA                       */
+/*-----------------------------------------------------------------*/
+static int
+canUseAccOperand (iCode * ic, operand * op)
+{
+  int size;
+  operand * otherOp;
+  
+  if (ic->op == IFX)
+    {
+      if (isOperandEqual (op, IC_COND (ic)))
+        return 1;
+      else
+        return 0;
+    }
+  
+  if (ic->op == JUMPTABLE)
+    {
+      if (isOperandEqual (op, IC_JTCOND (ic)))
+        return 1;
+      else
+        return 0;
+    }
 
-  /* make sure that the result of this icode is not on the
-     stack, since acc is used to compute stack offset */
-#if 0
-  if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
-      OP_SYMBOL (IC_RESULT (uic))->onStack)
-    return;
-#else
-//  if (isOperandOnStack(IC_RESULT(uic)))
-//    return;
-#endif
+  if (POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic)))
+    return 1;
 
-  /* if the usage has only one operand then we can */
-  if (IC_LEFT (uic) == NULL ||
-      IC_RIGHT (uic) == NULL)
-    goto accuse;
+  if (isOperandEqual (op, IC_LEFT (ic)))
+    otherOp = IC_RIGHT (ic);
+  else if (isOperandEqual (op, IC_RIGHT (ic)))
+    otherOp = IC_LEFT (ic);
+  else
+    return 0;
 
-#if 0
-  /* if the other operand uses the accumulator then we cannot */
-  if ( (IC_LEFT(uic)->key == IC_RESULT(ic)->key &&
-       operandUsesAcc2(IC_RIGHT(uic))) ||
-       (IC_RIGHT(uic)->key == IC_RESULT(ic)->key &&
-       operandUsesAcc2(IC_LEFT(uic))) ) 
-    return;
+  /* Generation of SEND is deferred until CALL; not safe */
+  /* if there are intermediate iCodes */
+  if (ic->op == SEND && ic->next && ic->next != CALL)
+    return 0;
+        
+  size = getSize (operandType (op));
+  if (size == 1)
+    {
+      /* All 1 byte operations should safely use an accumulator operand */
+      return 1;
+    }
+  else if (size == 2)
+    {
+      switch (ic->op)
+        {
+        case LEFT_OP:
+        case RIGHT_OP:
+          return isOperandLiteral (IC_RIGHT (ic));
+        case SEND:
+          return 1;
+        default:
+          return 0;
+        }
+    }
+  
+  return 0;
+}
 
-  /* make sure this is on the left side if not commutative */
-  /* except for '-', which has been written to be able to
-     handle reversed operands */
-  if (!(isCommutativeOp2(ic->op) || ic->op == '-') &&
-       IC_LEFT (uic)->key != IC_RESULT (ic)->key)
-    return;
-#endif
 
-#if 0
-  // this is too dangerous and need further restrictions
-  // see bug #447547
+/*-----------------------------------------------------------------*/
+/* packRegsForAccUse - pack registers for acc use                  */
+/*-----------------------------------------------------------------*/
+static int
+packRegsForAccUse (iCode * ic)
+{
+  iCode * uic;
+  operand * op;
 
-  /* if one of them is a literal then we can */
-  if ((IC_LEFT (uic) && IS_OP_LITERAL (IC_LEFT (uic))) ||
-      (IC_RIGHT (uic) && IS_OP_LITERAL (IC_RIGHT (uic))))
-    {
-      OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
-      return;
-    }
-#endif
+  if (!canDefAccResult (ic))
+    return 0;
+  
+  op = IC_RESULT (ic);
+    
+  /* has only one definition */
+  if (bitVectnBitsOn (OP_DEFS (op)) > 1)
+    return 0;
 
-accuse:
+  /* has only one use */
+  if (bitVectnBitsOn (OP_USES (op)) > 1)
+    return 0;
 
+  uic = ic->next;
+  if (!uic)
+    return 0;
+  
+  if (!canUseAccOperand (uic, op))
+    return 0;
+    
+  #if 0
   if ((POINTER_GET(uic))
       || (ic->op == ADDRESS_OF && uic->op == '+' && IS_OP_LITERAL (IC_RIGHT (uic))))
     {
       OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HX;
       return;
     }
+  #endif
   
   OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_XA;
+  return 1;
 }
 
 /*-----------------------------------------------------------------*/
@@ -2892,6 +2888,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
          continue;
        }
 
+      #if 0
       /* if the condition of an if instruction
          is defined in the previous GET_POINTER instruction and
         this is the only usage then
@@ -2905,7 +2902,43 @@ packRegisters (eBBlock ** ebpp, int blockno)
           OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
           continue;
         }
-
+      
+      if (ic->op != IFX && ic->op !=JUMPTABLE && !POINTER_SET (ic)
+          && IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic))
+          && getSize (operandType (IC_RESULT (ic))) == 1
+          && bitVectnBitsOn (OP_USES (IC_RESULT (ic))) == 1
+          && ic->next
+          && OP_SYMBOL (IC_RESULT (ic))->liveTo <= ic->next->seq)
+        {
+          int accuse = 0;
+          
+          if (ic->next->op == IFX)
+            {
+              if (isOperandEqual (IC_RESULT (ic), IC_COND (ic->next)))
+                accuse = 1;
+            }
+          else if (ic->next->op == JUMPTABLE)
+            {
+               if (isOperandEqual (IC_RESULT (ic), IC_JTCOND (ic->next)))
+                 accuse = 1;
+            }
+          else
+            {
+               if (isOperandEqual (IC_RESULT (ic), IC_LEFT (ic->next)))
+                 accuse = 1;
+               if (isOperandEqual (IC_RESULT (ic), IC_RIGHT (ic->next)))
+                 accuse = 1;
+            }
+          
+          if (accuse)
+            {
+              OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
+              continue;
+            }
+          
+        }
+      #endif
+        
       /* reduce for support function calls */
       if (ic->supportRtn || (ic->op != IFX && ic->op != JUMPTABLE))
        packRegsForSupport (ic, ebp);
@@ -3005,33 +3038,7 @@ packRegisters (eBBlock ** ebpp, int blockno)
          packForPush (ic, ebpp, blockno);
        }
 
-
-      #if 1
-      /* pack registers for accumulator use, when the
-         result of an arithmetic or bit wise operation
-         has only one use, that use is immediately following
-         the defintion and the using iCode has only one
-         operand or has two operands but one is literal &
-         the result of that operation is not on stack then
-         we can leave the result of this operation in x:a
-         combination */
-      if ((IS_ARITHMETIC_OP (ic)
-          || IS_CONDITIONAL(ic)
-          || IS_BITWISE_OP (ic)
-          || ic->op == '='
-           || ic->op == '!'
-           || ic->op == '~'
-          || ic->op == GETHBIT
-          || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == CALL
-          || (ic->op == ADDRESS_OF && isOperandOnStack (IC_LEFT (ic)))
-           || ic->op == RECEIVE
-           || POINTER_GET (ic)
-         ) &&
-         IS_ITEMP (IC_RESULT (ic)) &&
-         getSize (operandType (IC_RESULT (ic))) <= 1)
-
-       packRegsForAccUse (ic);
-      #endif
+      packRegsForAccUse (ic);
     }
 }
 
index 3a847d4356d52d9a186610560265658bf3e4ccab..efb77ca640a3a697958178d02229d3673e7ecfab 100644 (file)
@@ -2,6 +2,7 @@
 void
 _putchar(unsigned char c)
 {
+  c;
   _asm
     .db 0x9e, 0xed
   _endasm;