* src/SDCCicode.c (fgeniCodeAssign): fixed bug 1369874, don't use volatile variables...
[fw/sdcc] / src / SDCCicode.c
index ee4783cd8978a02ffd7092349b093201d450e4f6..513c7b6ccee6a2aaf7cc8fe47e7d04f0465d9136 100644 (file)
@@ -80,6 +80,9 @@ iCodeTable codeTable[] =
   {RRC, "rrc", picGenericOne, NULL},
   {RLC, "rlc", picGenericOne, NULL},
   {GETHBIT, "ghbit", picGenericOne, NULL},
+  {GETABIT, "gabit", picGenericOne, NULL},
+  {GETBYTE, "gbyte", picGenericOne, NULL},
+  {GETWORD, "gword", picGenericOne, NULL},
   {UNARYMINUS, "-", picGenericOne, NULL},
   {IPUSH, "push", picGenericOne, NULL},
   {IPOP, "pop", picGenericOne, NULL},
@@ -230,7 +233,7 @@ printOperand (operand * op, FILE * file)
       opetype = getSpec (operandType (op));
       if (IS_FLOAT (opetype))
         fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
-      if (IS_FIXED16X16 (opetype))
+      else if (IS_FIXED16X16 (opetype))
         fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
       else
         fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
@@ -986,6 +989,34 @@ isOperandInFarSpace (operand * op)
   return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
 }
 
+/*-----------------------------------------------------------------*/
+/* isOperandInPagedSpace - return true if operand is in pagedSpace */
+/*-----------------------------------------------------------------*/
+bool
+isOperandInPagedSpace (operand * op)
+{
+  sym_link *etype;
+
+  if (!op)
+    return FALSE;
+
+  if (!IS_SYMOP (op))
+    return FALSE;
+
+  if (!IS_TRUE_SYMOP (op))
+    {
+      if (SPIL_LOC (op))
+        etype = SPIL_LOC (op)->etype;
+      else
+        return FALSE;
+    }
+  else
+    {
+      etype = getSpec (operandType (op));
+    }
+  return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
 /*------------------------------------------------------------------*/
 /* isOperandInDirSpace - will return true if operand is in dirSpace */
 /*------------------------------------------------------------------*/
@@ -1296,15 +1327,12 @@ operandOperation (operand * left, operand * right,
                                  (TYPE_UDWORD) operandLitValue (right));
       break;
     case EQ_OP:
-      if (IS_FLOAT (let) ||
-          IS_FLOAT (ret))
+      if (IS_FLOAT (let) || IS_FLOAT (ret))
         {
           retval = operandFromLit (operandLitValue (left) ==
                                    operandLitValue (right));
         }
-      else
-      if (IS_FIXED16X16 (let) ||
-          IS_FIXED16X16 (ret))
+      else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
         {
           retval = operandFromLit (operandLitValue (left) ==
                                    operandLitValue (right));
@@ -1389,6 +1417,23 @@ operandOperation (operand * left, operand * right,
                                  (i >> 1));
       }
       break;
+    case GETABIT:
+      retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
+                                (TYPE_UDWORD)operandLitValue(right)) & 1);
+      break;
+    case GETBYTE:
+      retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
+                                (TYPE_UDWORD)operandLitValue(right)) & 0xFF);
+      break;
+    case GETWORD:
+      retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
+                                (TYPE_UDWORD)operandLitValue(right)) & 0xFFFF);
+      break;
+
+    case GETHBIT:
+      retval = operandFromLit (((TYPE_UDWORD)operandLitValue(left) >>
+                                ((getSize (let) * 8) - 1)) & 1);
+      break;
 
     case UNARYMINUS:
       retval = operandFromValue (valCastLiteral (type,
@@ -2150,7 +2195,7 @@ geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
   /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
      efficient in most cases than 2 bytes result = 2 bytes << literal
      if port has 1 byte muldiv */
-  if (p2 && !IS_FLOAT (letype) && !IS_FIXED (letype)
+  if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
       && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
            && (port->support.muldiv == 1))
       && strcmp (port->target, "pic16") != 0  /* don't shift for pic */
@@ -2201,8 +2246,8 @@ geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
       !IS_FLOAT (letype) &&
       !IS_FIXED (letype) &&
       IS_UNSIGNED(letype) &&
-      (p2 = powof2 ((TYPE_UDWORD)
-                    floatFromVal (right->operand.valOperand)))) {
+      ((p2 = powof2 ((TYPE_UDWORD)
+                    floatFromVal (right->operand.valOperand))) > 0)) {
     ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
   }
   else
@@ -2598,8 +2643,7 @@ geniCodePostInc (operand * op)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (rvtype))
+  else if (IS_FIXED16X16 (rvtype))
     ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('+', rv, operandFromLit (size));
@@ -2639,8 +2683,7 @@ geniCodePreInc (operand * op, bool lvalue)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (roptype))
+  else if (IS_FIXED16X16 (roptype))
     ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('+', rop, operandFromLit (size));
@@ -2690,8 +2733,7 @@ geniCodePostDec (operand * op)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (rvtype))
     ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (rvtype))
+  else if (IS_FIXED16X16 (rvtype))
     ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('-', rv, operandFromLit (size));
@@ -2731,8 +2773,7 @@ geniCodePreDec (operand * op, bool lvalue)
     werror(W_SIZEOF_VOID);
   if (IS_FLOAT (roptype))
     ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
-  else
-  if (IS_FIXED16X16 (roptype))
+  else if (IS_FIXED16X16 (roptype))
     ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
   else
     ic = newiCode ('-', rop, operandFromLit (size));
@@ -2813,6 +2854,7 @@ geniCodeAddressOf (operand * op)
   ADDTOCHAIN (ic);
   return IC_RESULT (ic);
 }
+
 /*-----------------------------------------------------------------*/
 /* setOClass - sets the output class depending on the pointer type */
 /*-----------------------------------------------------------------*/
@@ -3122,6 +3164,19 @@ geniCodeUnary (operand * op, int oper)
   return IC_RESULT (ic);
 }
 
+/*-----------------------------------------------------------------*/
+/* geniCodeBinary - for a generic binary operation                 */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeBinary (operand * left, operand * right, int oper)
+{
+  iCode *ic = newiCode (oper, left, right);
+
+  IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
+  ADDTOCHAIN (ic);
+  return IC_RESULT (ic);
+}
+
 /*-----------------------------------------------------------------*/
 /* geniCodeConditional - geniCode for '?' ':' operation            */
 /*-----------------------------------------------------------------*/
@@ -3209,12 +3264,16 @@ geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
       isOperandGlobal (left))
     {
       symbol *sym = NULL;
+      operand *newRight;
 
       if (IS_TRUE_SYMOP (right))
         sym = OP_SYMBOL (right);
       ic = newiCode ('=', NULL, right);
-      IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
-      SPIL_LOC (right) = sym;
+      IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
+      /* avoid double fetch from volatile right, see bug 1369874 */
+      if (!isOperandVolatile (right, FALSE))
+        SPIL_LOC (newRight) = sym;
+      right = newRight;
       ADDTOCHAIN (ic);
     }
 
@@ -4220,15 +4279,6 @@ ast2iCode (ast * tree,int lvl)
 #endif
 
     case '~':
-      {
-        sym_link *ltype = operandType (left);
-        operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
-        if ((SPEC_NOUN(ltype) == V_CHAR) && IS_UNSIGNED(ltype))
-          {
-            setOperandType (op, INTTYPE);
-          }
-        return op;
-      }
     case RRC:
     case RLC:
     case SWAP:
@@ -4241,6 +4291,16 @@ ast2iCode (ast * tree,int lvl)
         setOperandType (op, UCHARTYPE);
         return op;
       }
+    case GETABIT:
+    case GETBYTE:
+    case GETWORD:
+      {
+        operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
+                                      geniCodeRValue (right, FALSE),
+                                      tree->opval.op);
+        setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
+        return op;
+      }
     case AND_OP:
     case OR_OP:
       return geniCodeLogicAndOr (tree, lvl);