* sdcc.spec: updated
[fw/sdcc] / src / mcs51 / gen.c
index 8cad6c3c944a2d1f174a4d24c10f20baea1963f2..649c643e5ea6f50e6b464777b546b4369137ce52 100644 (file)
@@ -3195,6 +3195,7 @@ genPlus (iCode * ic)
   int skip_bytes = 0;
   char *add = "add";
   asmop *leftOp, *rightOp;
+  operand * op;
 
   /* special cases :- */
 
@@ -3256,26 +3257,58 @@ genPlus (iCode * ic)
     goto release;
 
   size = getDataSize (IC_RESULT (ic));
+  leftOp = AOP(IC_LEFT(ic));
+  rightOp = AOP(IC_RIGHT(ic));
+  op=IC_LEFT(ic);
+
+  /* if this is an add for an array access
+     at a 256 byte boundary */
+  if ( 2 == size
+       && AOP_TYPE (op) == AOP_IMMD
+       && IS_SYMOP (op)
+       && IS_SPEC (OP_SYM_ETYPE (op))
+       && SPEC_ABSA (OP_SYM_ETYPE (op))
+       && (SPEC_ADDR (OP_SYM_ETYPE (op)) & 0xff) == 0
+     )
+    {
+      D(emitcode (";     genPlus aligned array",""));
+      aopPut (AOP (IC_RESULT (ic)),
+             aopGet (rightOp, 0, FALSE, FALSE),
+             0,
+             isOperandVolatile (IC_RESULT (ic), FALSE));
+
+      if( 1 == getDataSize (IC_RIGHT (ic)) )
+       {
+         aopPut (AOP (IC_RESULT (ic)),
+                 aopGet (leftOp, 1, FALSE, FALSE),
+                 1,
+                 isOperandVolatile (IC_RESULT (ic), FALSE));
+       }
+      else
+        {
+         MOVA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE, FALSE));
+         emitcode ("add", "a,%s", aopGet (rightOp, 1, FALSE, FALSE));
+         aopPut (AOP (IC_RESULT (ic)), "a", 1, isOperandVolatile (IC_RESULT (ic), FALSE));
+       }
+      goto release;
+    }
 
   /* if the lower bytes of a literal are zero skip the addition */
   if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT )
-    {          
+    {
        while ((0 == ((unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) & (0xff << skip_bytes*8))) &&
               (skip_bytes+1 < size))
-         {  
+         {
            skip_bytes++;
         }
        if (skip_bytes)
          D(emitcode (";     genPlus shortcut",""));
     }
 
-  leftOp = AOP(IC_LEFT(ic));
-  rightOp = AOP(IC_RIGHT(ic));
-  
   while (size--)
     {
       if( offset >= skip_bytes )
-        {      
+        {
          if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset))
            {
              emitcode("mov", "b,a");
@@ -3642,8 +3675,16 @@ genMultOneByte (operand * left,
     // just an unsigned 8*8=8/16 multiply
     //emitcode (";","unsigned");
     // TODO: check for accumulator clash between left & right aops?
-    emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
-    MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+  
+    if( AOP_TYPE(right)==AOP_LIT ){
+      // moving to accumulator first helps peepholes 
+      MOVA (aopGet (AOP (left), 0, FALSE, FALSE));
+      emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE));
+    } else {
+      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, isOperandVolatile (result, FALSE));
     if (size==2) {
@@ -7157,7 +7198,7 @@ static void
 genRightShift (iCode * ic)
 {
   operand *right, *left, *result;
-  sym_link *retype;
+  sym_link *letype;
   int size, offset;
   char *l;
   symbol *tlbl, *tlbl1;
@@ -7166,9 +7207,9 @@ genRightShift (iCode * ic)
 
   /* if signed then we do it the hard way preserve the
      sign bit moving it inwards */
-  retype = getSpec (operandType (IC_RESULT (ic)));
+  letype = getSpec (operandType (IC_LEFT (ic)));
 
-  if (!SPEC_USIGN (retype))
+  if (!SPEC_USIGN (letype))
     {
       genSignedRightShift (ic);
       return;
@@ -9074,34 +9115,58 @@ genReceive (iCode * ic)
 static void
 genDummyRead (iCode * ic)
 {
-  operand *right;
+  operand *op;
   int size, offset;
 
   D(emitcode(";     genDummyRead",""));
 
-  right = IC_RIGHT (ic);
+  op = IC_RIGHT (ic);
+  if (op && IS_SYMOP (op))
+    {
+      aopOp (op, ic, FALSE);
 
-  aopOp (right, ic, FALSE);
+      /* if the result is a bit */
+      if (AOP_TYPE (op) == AOP_CRY)
+        emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+      else
+       {
+         /* bit variables done */
+         /* general case */
+         size = AOP_SIZE (op);
+         offset = 0;
+         while (size--)
+         {
+           MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+           offset++;
+         }
+       }
 
-  /* if the result is a bit */
-  if (AOP_TYPE (right) == AOP_CRY)
-    {
-      emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
-      goto release;
+      freeAsmop (op, NULL, ic, TRUE);
     }
 
-  /* bit variables done */
-  /* general case */
-  size = AOP_SIZE (right);
-  offset = 0;
-  while (size--)
+  op = IC_LEFT (ic);
+  if (op && IS_SYMOP (op))
     {
-      MOVA (aopGet (AOP (right), offset, FALSE, FALSE));
-      offset++;
-    }
+      aopOp (op, ic, FALSE);
 
-release:
-  freeAsmop (right, NULL, ic, TRUE);
+      /* if the result is a bit */
+      if (AOP_TYPE (op) == AOP_CRY)
+        emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir);
+      else
+       {
+         /* bit variables done */
+         /* general case */
+         size = AOP_SIZE (op);
+         offset = 0;
+         while (size--)
+         {
+           MOVA (aopGet (AOP (op), offset, FALSE, FALSE));
+           offset++;
+         }
+       }
+
+      freeAsmop (op, NULL, ic, TRUE);
+    }
 }
 
 /*-----------------------------------------------------------------*/