]> git.gag.com Git - fw/sdcc/blobdiff - src/mcs51/gen.c
* src/SDCCmain.c,
[fw/sdcc] / src / mcs51 / gen.c
index c453a7925c9c415c7cc5cdf19313200c48531347..7f254ef7faf3b57d2bac33429a1d464dac8a36f7 100644 (file)
@@ -1449,25 +1449,25 @@ genCpl (iCode * ic)
          goto release;
        }
 
-    tlbl=newiTempLabel(NULL);
-    if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC ||
-       AOP_TYPE (IC_LEFT (ic)) == AOP_REG ||
-       IS_AOP_PREG (IC_LEFT (ic)))
-      {
-       emitcode ("cjne", "%s,#0x01,%05d$",
-                 aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE),
-                 tlbl->key + 100);
-      }
-    else
-      {
-        char *l = aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE);
-        MOVA (l);
-        emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
-      }
-    emitcode ("", "%05d$:", tlbl->key + 100);
-    outBitC (IC_RESULT(ic));
-    goto release;
-  }
+      tlbl=newiTempLabel(NULL);
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC ||
+         AOP_TYPE (IC_LEFT (ic)) == AOP_REG ||
+         IS_AOP_PREG (IC_LEFT (ic)))
+       {
+         emitcode ("cjne", "%s,#0x01,%05d$",
+                   aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE),
+                   tlbl->key + 100);
+       }
+      else
+       {
+         char *l = aopGet (AOP (IC_LEFT (ic)), 0, FALSE, FALSE);
+         MOVA (l);
+         emitcode ("cjne", "a,#0x01,%05d$", tlbl->key + 100);
+       }
+      emitcode ("", "%05d$:", tlbl->key + 100);
+      outBitC (IC_RESULT(ic));
+      goto release;
+    }
 
   size = AOP_SIZE (IC_RESULT (ic));
   while (size--)
@@ -2604,9 +2604,12 @@ genFunction (iCode * ic)
   /* if critical function then turn interrupts off */
   if (IFFUNC_ISCRITICAL (ftype))
     {
-      emitcode ("mov", "c,ea");
+      symbol *tlbl = newiTempLabel (NULL);
+      emitcode ("setb", "c");
+      emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+      emitcode ("clr", "c");
+      emitcode ("", "%05d$:", (tlbl->key + 100));
       emitcode ("push", "psw"); /* save old ea via c in psw */
-      emitcode ("clr", "ea");
     }
 }
 
@@ -4260,12 +4263,14 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
      if the right is in a pointer register and left
      is not */
   if ((AOP_TYPE (left) == AOP_LIT) ||
+      (AOP_TYPE (left) == AOP_IMMD) ||
       (IS_AOP_PREG (right) && !IS_AOP_PREG (left)))
     {
       operand *t = right;
       right = left;
       left = t;
     }
+  
   if (AOP_TYPE (right) == AOP_LIT)
     lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit);
 
@@ -4289,6 +4294,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl)
   else if (AOP_TYPE (right) == AOP_REG ||
           AOP_TYPE (right) == AOP_DIR ||
           AOP_TYPE (right) == AOP_LIT ||
+           AOP_TYPE (right) == AOP_IMMD ||
           (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) ||
           (IS_AOP_PREG (left) && !IS_AOP_PREG (right)))
     {
@@ -9004,6 +9010,65 @@ release:
   freeAsmop (right, NULL, ic, TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genCritical - generate code for start of a critical sequence    */
+/*-----------------------------------------------------------------*/
+static void
+genCritical (iCode *ic)
+{
+  symbol *tlbl = newiTempLabel (NULL);
+
+  D(emitcode(";     genCritical",""));
+  
+  if (IC_RESULT (ic))
+    aopOp (IC_RESULT (ic), ic, TRUE);
+
+  emitcode ("setb", "c");
+  emitcode ("jbc", "ea,%05d$", (tlbl->key + 100)); /* atomic test & clear */
+  emitcode ("clr", "c");
+  emitcode ("", "%05d$:", (tlbl->key + 100));
+
+  if (IC_RESULT (ic))
+    outBitC (IC_RESULT (ic)); /* save old ea in an operand */
+  else
+    emitcode ("push", "psw"); /* save old ea via c in psw on top of stack*/
+
+  if (IC_RESULT (ic))
+    freeAsmop (IC_RESULT (ic), NULL, ic, TRUE);
+}
+
+/*-----------------------------------------------------------------*/
+/* genEndCritical - generate code for end of a critical sequence   */
+/*-----------------------------------------------------------------*/
+static void
+genEndCritical (iCode *ic)
+{
+  D(emitcode(";     genEndCritical",""));
+  
+  if (IC_RIGHT (ic))
+    {
+      aopOp (IC_RIGHT (ic), ic, FALSE);
+      if (AOP_TYPE (IC_RIGHT (ic)) == AOP_CRY)
+        {
+         emitcode ("mov", "c,%s", IC_RIGHT (ic)->aop->aopu.aop_dir);
+          emitcode ("mov", "ea,c");
+        }
+      else
+        {
+          MOVA (aopGet (AOP (IC_RIGHT (ic)), 0, FALSE, FALSE));
+          emitcode ("rrc", "a");
+          emitcode ("mov", "ea,c");
+        }
+      freeAsmop (IC_RIGHT (ic), NULL, ic, TRUE);
+    }
+  else
+    {
+      emitcode ("pop", "psw"); /* restore ea via c in psw on top of stack */
+      emitcode ("mov", "ea,c");
+    }
+}
+
+
 /*-----------------------------------------------------------------*/
 /* gen51Code - generate code for 8051 based controllers            */
 /*-----------------------------------------------------------------*/
@@ -9262,6 +9327,14 @@ gen51Code (iCode * lic)
          genDummyRead (ic);
          break;
 
+       case CRITICAL:
+         genCritical (ic);
+         break;
+
+       case ENDCRITICAL:
+         genEndCritical (ic);
+         break;
+
        default:
          ic = ic;
        }