* src/SDCCicode.c (operandOperation): really fixed problem with bitops
[fw/sdcc] / src / SDCCicode.c
index 32f913aec7f0a10e33a7ac3013399320ebd9f20a..7eea91c05e319efb8672eaeb546a19939c3ceaeb 100644 (file)
@@ -67,6 +67,7 @@ PRINTFUNC (picIfx);
 PRINTFUNC (picJumpTable);
 PRINTFUNC (picInline);
 PRINTFUNC (picReceive);
+PRINTFUNC (picDummyRead);
 
 iCodeTable codeTable[] =
 {
@@ -113,6 +114,7 @@ iCodeTable codeTable[] =
   {RECEIVE, "recv", picReceive, NULL},
   {SEND, "send", picGenericOne, NULL},
   {ARRAYINIT, "arrayInit", picGenericOne, NULL},
+  {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}
 };
 
 /*-----------------------------------------------------------------*/
@@ -126,7 +128,7 @@ iCodeTable codeTable[] =
      pedantic>1: "char c=200" is not allowed (evaluates to -56)
 */
 
-void checkConstantRange(sym_link *ltype, value *val, char *msg, 
+void checkConstantRange(sym_link *ltype, value *val, char *msg,
                        int pedantic) {
   double max;
   int warnings=0;
@@ -216,7 +218,7 @@ printOperand (operand * op, FILE * file)
       if (SPEC_NOUN (opetype) == V_FLOAT)
        fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
       else
-       fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand));
+       fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
       printTypeChain (operandType (op), file);
       fprintf (file, "}");
       break;
@@ -461,10 +463,18 @@ PRINTFUNC (picReceive)
   fprintf (of, "\n");
 }
 
+PRINTFUNC (picDummyRead)
+{
+  fprintf (of, "\t");
+  fprintf (of, "%s ", s);
+  printOperand (IC_RIGHT (ic), of);
+  fprintf (of, "\n");
+}
+
 /*-----------------------------------------------------------------*/
 /* piCode - prints one iCode                                       */
 /*-----------------------------------------------------------------*/
-int 
+int
 piCode (void *item, FILE * of)
 {
   iCode *ic = item;
@@ -488,7 +498,7 @@ void PICC(iCode *ic)
 /*-----------------------------------------------------------------*/
 /* printiCChain - prints intermediate code for humans              */
 /*-----------------------------------------------------------------*/
-void 
+void
 printiCChain (iCode * icChain, FILE * of)
 {
   iCode *loop;
@@ -722,7 +732,7 @@ copyiCode (iCode * ic)
 iCodeTable *
 getTableEntry (int oper)
 {
-  int i;
+  unsigned i;
 
   for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
     if (oper == codeTable[i].icode)
@@ -845,7 +855,14 @@ isOperandVolatile (operand * op, bool chkTemp)
   if (IS_ITEMP (op) && !chkTemp)
     return 0;
 
-  return IS_VOLATILE(operandType(op));
+  opetype = getSpec (optype = operandType (op));
+    
+  if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))   
+    return 1;   
+    
+  if (IS_VOLATILE (opetype))   
+    return 1;   
+  return 0; 
 }
 
 /*-----------------------------------------------------------------*/
@@ -1021,7 +1038,7 @@ operandOperation (operand * left, operand * right,
 {
   sym_link *let , *ret=NULL;
   operand *retval = (operand *) 0;
-  
+
   assert (isOperandLiteral (left));
   let = getSpec(operandType(left));
   if (right) {
@@ -1063,27 +1080,27 @@ operandOperation (operand * left, operand * right,
          werror (E_DIVIDE_BY_ZERO);
          retval = right;
       }
-      else 
-       retval = operandFromLit ((SPEC_USIGN(let) ? 
+      else
+       retval = operandFromLit ((SPEC_USIGN(let) ?
                                  (unsigned long) operandLitValue (left) :
                                  (long) operandLitValue (left)) %
-                                (SPEC_USIGN(ret) ? 
+                                (SPEC_USIGN(ret) ?
                                  (unsigned long) operandLitValue (right) :
                                  (long) operandLitValue (right)));
 
       break;
     case LEFT_OP:
-      retval = operandFromLit ((SPEC_USIGN(let) ? 
+      retval = operandFromLit ((SPEC_USIGN(let) ?
                                  (unsigned long) operandLitValue (left) :
                                  (long) operandLitValue (left)) <<
-                                (SPEC_USIGN(ret) ? 
+                                (SPEC_USIGN(ret) ?
                                  (unsigned long) operandLitValue (right) :
                                  (long) operandLitValue (right)));
       break;
     case RIGHT_OP: {
       double lval = operandLitValue(left), rval = operandLitValue(right);
       double res=0;
-      switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0)) 
+      switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
        {
        case 0: // left=unsigned right=unsigned
          res=(unsigned long)lval >> (unsigned long)rval;
@@ -1126,16 +1143,19 @@ operandOperation (operand * left, operand * right,
                               operandLitValue (right));
       break;
     case BITWISEAND:
-      retval = operandFromLit ((long)operandLitValue(left) & 
-                              (long)operandLitValue(right));
+      retval = operandFromValue (valCastLiteral (type,
+                                                 (unsigned long)operandLitValue(left) &
+                                                (unsigned long)operandLitValue(right)));
       break;
     case '|':
-      retval = operandFromLit ((long)operandLitValue (left) |
-                              (long)operandLitValue (right));
+      retval = operandFromValue (valCastLiteral (type,
+                                                 (unsigned long)operandLitValue(left) |
+                                                (unsigned long)operandLitValue(right)));
       break;
     case '^':
-      retval = operandFromLit ((long)operandLitValue (left) ^
-                              (long)operandLitValue (right));
+      retval = operandFromValue (valCastLiteral (type,
+                                                 (unsigned long)operandLitValue(left) ^
+                                                (unsigned long)operandLitValue(right)));
       break;
     case AND_OP:
       retval = operandFromLit (operandLitValue (left) &&
@@ -1147,7 +1167,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RRC:
       {
-       long i = (long) operandLitValue (left);
+       unsigned long i = (unsigned long) operandLitValue (left);
 
        retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
                                 (i << 1));
@@ -1155,7 +1175,7 @@ operandOperation (operand * left, operand * right,
       break;
     case RLC:
       {
-       long i = (long) operandLitValue (left);
+       unsigned long i = (unsigned long) operandLitValue (left);
 
        retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
                                 (i >> 1));
@@ -1167,7 +1187,7 @@ operandOperation (operand * left, operand * right,
       break;
 
     case '~':
-      retval = operandFromLit (~((long) operandLitValue (left)));
+      retval = operandFromLit (~((unsigned long) operandLitValue (left)));
       break;
 
     case '!':
@@ -1514,10 +1534,13 @@ operandFromAst (ast * tree,int lvl)
 
     case EX_LINK:
       return operandFromLink (tree->opval.lnk);
-    }
+      break;
 
-  assert (0);
-  /*  Just to keep the comiler happy */
+    default:
+      assert (0);
+    }
+  
+  /*  Just to keep the compiler happy */
   return (operand *) 0;
 }
 
@@ -2051,12 +2074,6 @@ geniCodeAdd (operand * left, operand * right, int lvl)
   int isarray = 0;
   LRTYPE;
 
-#if 0
-  /* if left is an array then array access */
-  if (IS_ARRAY (ltype))
-    return geniCodeArray (left, right,lvl);
-#endif
-
   /* if the right side is LITERAL zero */
   /* return the left side              */
   if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
@@ -2118,11 +2135,10 @@ aggrToPtr (sym_link * type, bool force)
     return type;
 
   etype = getSpec (type);
-  ptype = newLink ();
+  ptype = newLink (DECLARATOR);
 
   ptype->next = type;
 
-#ifdef JWK
   /* if the output class is code */
   if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
     DCL_PTR_CONST (ptype) = port->mem.code_ro;
@@ -2135,9 +2151,6 @@ aggrToPtr (sym_link * type, bool force)
   /* the variable was volatile then pointer to volatile */
   if (IS_VOLATILE (etype))
     DCL_PTR_VOLATILE (ptype) = 1;
-#else
-  DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
-#endif
 
   return ptype;
 }
@@ -2151,7 +2164,6 @@ geniCodeArray2Ptr (operand * op)
   sym_link *optype = operandType (op);
   sym_link *opetype = getSpec (optype);
 
-#ifdef JWK
   /* set the pointer depending on the storage class */
   if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
     DCL_PTR_CONST (optype) = port->mem.code_ro;
@@ -2164,9 +2176,6 @@ geniCodeArray2Ptr (operand * op)
   /* the variable was volatile then pointer to volatile */
   if (IS_VOLATILE (opetype))
     DCL_PTR_VOLATILE (optype) = 1;
-#else
-  DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
-#endif
 
   op->isaddr = 0;
   return op;
@@ -2451,10 +2460,8 @@ geniCodeAddressOf (operand * op)
 /*  return op; */
 /*     } */
 
-  p = newLink ();
-  p->class = DECLARATOR;
+  p = newLink (DECLARATOR);
 
-#ifdef JWK
   /* set the pointer depending on the storage class */
   if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
     DCL_PTR_CONST (p) = port->mem.code_ro;
@@ -2465,10 +2472,6 @@ geniCodeAddressOf (operand * op)
 
   if (IS_VOLATILE (opetype))
     DCL_PTR_VOLATILE (p) = 1;
-#else
-  DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
-#endif
-
 
   p->next = copyLinkChain (optype);
 
@@ -2538,16 +2541,19 @@ geniCodeDerefPtr (operand * op,int lvl)
   sym_link *rtype, *retype;
   sym_link *optype = operandType (op);
 
-  /* if this is a pointer then generate the rvalue */
-  if (IS_PTR (optype))
+  // if this is an array then array access
+  if (IS_ARRAY (optype)) {
+    // don't worry, this will be optimized out later
+    return geniCodeArray (op, operandFromLit (0), lvl);
+  }
+
+  // just in case someone screws up
+  wassert (IS_PTR (optype));
+
+  if (IS_TRUE_SYMOP (op))
     {
-      if (IS_TRUE_SYMOP (op))
-       {
-         op->isaddr = 1;
-         op = geniCodeRValue (op, TRUE);
-       }
-      else
-       op = geniCodeRValue (op, TRUE);
+      op->isaddr = 1;
+      op = geniCodeRValue (op, TRUE);
     }
 
   /* now get rid of the pointer part */
@@ -2560,9 +2566,8 @@ geniCodeDerefPtr (operand * op,int lvl)
       retype = getSpec (rtype = copyLinkChain (optype->next));
     }
 
-  /* if this is a pointer then outputclass needs 2b updated */
-  if (IS_PTR (optype))
-    setOClass (optype, retype);
+  /* outputclass needs 2b updated */
+  setOClass (optype, retype);
 
   op->isGptr = IS_GENPTR (optype);
 
@@ -3552,9 +3557,25 @@ ast2iCode (ast * tree,int lvl)
     case RIGHT_OP:
       return geniCodeRightShift (geniCodeRValue (left, FALSE),
                                 geniCodeRValue (right, FALSE));
-    case CAST:
+    case CAST: 
+#if 0 // this indeed needs a second thought
+      {
+       operand *op;
+       
+       // let's keep this simple: get the rvalue we need
+       op=geniCodeRValue (right, FALSE);
+       // now cast it to whatever we want
+       op=geniCodeCast (operandType(left), op, FALSE);
+       // if this is going to be used as an lvalue, make it so
+       if (tree->lvalue) {
+         op->isaddr=1;
+       }
+       return op;
+      }
+#else // bug #604575, is it a bug ????
       return geniCodeCast (operandType (left),
                           geniCodeRValue (right, FALSE), FALSE);
+#endif
 
     case '~':
     case '!':