New target "hc08" for the Motorola 68hc08 family of micros
[fw/sdcc] / src / SDCCicode.c
index 44dddc1175750e87adfba60a77b369db35302d45..eef790d2fe8894d1ed9b01ace2d8b18bcd465b3d 100644 (file)
@@ -51,6 +51,7 @@ operand *geniCodeArray2Ptr (operand *);
 operand *geniCodeRValue (operand *, bool);
 operand *geniCodeDerefPtr (operand *,int);
 int isLvaluereq(int lvl);
+void  setOClass (sym_link * ptr, sym_link * spec);
 
 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
 /* forward definition of ic print functions */
@@ -1093,8 +1094,7 @@ operandOperation (operand * left, operand * right,
                               (TYPE_UWORD) operandLitValue (right);
 
              retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
-             if (!options.lessPedantic &&
-                 ul != (TYPE_UWORD) ul)
+             if (ul != (TYPE_UWORD) ul)
                werror (W_INT_OVL);
            }
          else /* signed int */
@@ -1104,8 +1104,7 @@ operandOperation (operand * left, operand * right,
                             (TYPE_WORD) operandLitValue (right);
 
              retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
-             if (!options.lessPedantic &&
-                 l != (TYPE_WORD) l)
+             if (l != (TYPE_WORD) l)
                werror (W_INT_OVL);
            }
        }
@@ -1800,7 +1799,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
       if (IS_INTEGRAL(optype)) { 
        // maybe this is NULL, than it's ok. 
        if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
-         if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
+         if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
            // no way to set the storage
            if (IS_LITERAL(optype)) {
              werror(E_LITERAL_GENERIC);
@@ -1823,7 +1822,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit)
        }
       }
     } else { // from a pointer to a pointer
-      if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
+      if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
        // if not a pointer to a function
        if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
          if (implicit) { // if not to generic, they have to match 
@@ -2189,7 +2188,6 @@ aggrToPtr (sym_link * type, bool force)
   sym_link *etype;
   sym_link *ptype;
 
-
   if (IS_PTR (type) && !force)
     return type;
 
@@ -2288,14 +2286,14 @@ geniCodeStruct (operand * left, operand * right, bool islval)
   retype = getSpec (operandType (IC_RESULT (ic)));
   SPEC_SCLS (retype) = SPEC_SCLS (etype);
   SPEC_OCLS (retype) = SPEC_OCLS (etype);
-  SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); /* EEP - I'm doubtful about this */
-
+  SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
+  SPEC_CONST (retype) |= SPEC_CONST (etype);
+  
   if (IS_PTR (element->type))
     setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
-
+  
   IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
 
-
   ADDTOCHAIN (ic);
   return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
 }
@@ -2594,11 +2592,10 @@ geniCodeDerefPtr (operand * op,int lvl)
   else
     {
       retype = getSpec (rtype = copyLinkChain (optype->next));
+      /* outputclass needs 2b updated */
+      setOClass (optype, retype);
     }
-
-  /* outputclass needs 2b updated */
-  setOClass (optype, retype);
-
+  
   op->isGptr = IS_GENPTR (optype);
 
   op->isaddr = (IS_PTR (rtype) ||
@@ -2863,6 +2860,24 @@ geniCodeAssign (operand * left, operand * right, int nosupdate)
   return left;
 }
 
+/*-----------------------------------------------------------------*/
+/* geniCodeDummyRead - generate code for dummy read                */
+/*-----------------------------------------------------------------*/
+static void
+geniCodeDummyRead (operand * op)
+{
+  iCode *ic;
+  sym_link *type = operandType (op);
+
+  if (!IS_VOLATILE(type))
+    return;
+    
+  ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
+  ADDTOCHAIN (ic);
+
+  ic->nosupdate = 1;
+}
+
 /*-----------------------------------------------------------------*/
 /* geniCodeSEParms - generate code for side effecting fcalls       */
 /*-----------------------------------------------------------------*/
@@ -3212,6 +3227,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   operand *boundary;
   symbol *falseLabel;
   set *labels = NULL;
+  int needRangeCheck = !optimize.noJTabBoundary
+                       || tree->values.switchVals.swDefault;
 
   if (!tree || !caseVals)
     return 0;
@@ -3247,7 +3264,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   /* if the number of case statements <= 2 then */
   /* it is not economical to create the jump table */
   /* since two compares are needed for boundary conditions */
-  if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
+  if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
     return 0;
 
   if (tree->values.switchVals.swDefault)
@@ -3265,7 +3282,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   /* so we can create a jumptable */
   /* first we rule out the boundary conditions */
   /* if only optimization says so */
-  if (!optimize.noJTabBoundary)
+  if (needRangeCheck)
     {
       sym_link *cetype = getSpec (operandType (cond));
       /* no need to check the lower bound if
@@ -3287,7 +3304,8 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   if (min)
     {
       cond = geniCodeSubtract (cond, operandFromLit (min));
-      setOperandType (cond, UCHARTYPE);
+      if (!IS_LITERAL(getSpec(operandType(cond))))
+        setOperandType (cond, UCHARTYPE);
     }
 
   /* now create the jumptable */
@@ -3308,6 +3326,29 @@ geniCodeSwitch (ast * tree,int lvl)
   operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
   value *caseVals = tree->values.switchVals.swVals;
   symbol *trueLabel, *falseLabel;
+      
+  /* If the condition is a literal, then just jump to the */
+  /* appropriate case label. */
+  if (IS_LITERAL(getSpec(operandType(cond))))
+    {
+      int switchVal, caseVal;
+      
+      switchVal = (int) floatFromVal (cond->operand.valOperand);
+      while (caseVals)
+        {
+          caseVal = (int) floatFromVal (caseVals);
+          if (caseVal == switchVal)
+            {
+              SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
+                       tree->values.switchVals.swNum, caseVal);
+              trueLabel = newiTempLabel (buffer);
+              geniCodeGoto (trueLabel);
+              goto jumpTable;
+            }
+          caseVals = caseVals->next;
+        }
+      goto defaultOrBreak;
+    }
 
   /* if we can make this a jump table */
   if (geniCodeJumpTable (cond, caseVals, tree))
@@ -3332,7 +3373,7 @@ geniCodeSwitch (ast * tree,int lvl)
     }
 
 
-
+defaultOrBreak:
   /* if default is present then goto break else break */
   if (tree->values.switchVals.swDefault)
     {
@@ -3478,8 +3519,14 @@ ast2iCode (ast * tree,int lvl)
      (tree->opval.op == NULLOP ||
      tree->opval.op == BLOCK))
     {
-      ast2iCode (tree->left,lvl+1);
-      ast2iCode (tree->right,lvl+1);
+      if (tree->left && tree->left->type == EX_VALUE)
+        geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
+      else
+        ast2iCode (tree->left,lvl+1);
+      if (tree->right && tree->right->type == EX_VALUE)
+        geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
+      else
+        ast2iCode (tree->right,lvl+1);
       return NULL;
     }