]> git.gag.com Git - fw/sdcc/commitdiff
* src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning
authormaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 19 Dec 2004 18:44:03 +0000 (18:44 +0000)
committermaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 19 Dec 2004 18:44:03 +0000 (18:44 +0000)
* src/ds390/main.c (_ds390_regparm): don't pass bit params in registers
* src/ds390/ralloc.c (serialRegAssign): spill bits
* src/mcs51/gen.c (genCpl): fixed bit=~(char) bugs, added warning
* support/Util/SDCCerr.c,
* support/Util/SDCCerr.h: added warning W_COMPLEMENT for using bit=~(bit)
* support/regression/tests/bitvars.c: added tests for bitwise complement(~)
* support/regression/tests/bitwise.c: added test for bitwise complement(~)

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3606 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/ds390/gen.c
src/ds390/main.c
src/ds390/ralloc.c
src/mcs51/gen.c
support/Util/SDCCerr.c
support/Util/SDCCerr.h
support/regression/tests/bitvars.c
support/regression/tests/bitwise.c

index 32d9349d35351e2ed1e447ca748c4878c236321b..059d1cb52a39076bbf51c0bd012790a31628c928 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2004-12-19 Maarten Brock <sourceforge.brock AT dse.nl>
+
+       * src/ds390/gen.c (genCpl): fixed bit=~(char/bit) bugs, added warning
+       * src/ds390/main.c (_ds390_regparm): don't pass bit params in registers
+       * src/ds390/ralloc.c (serialRegAssign): spill bits
+       * src/mcs51/gen.c (genCpl): fixed bit=~(char) bugs, added warning
+       * support/Util/SDCCerr.c,
+       * support/Util/SDCCerr.h: added warning W_COMPLEMENT for using bit=~(bit)
+       * support/regression/tests/bitvars.c: added tests for bitwise complement(~)
+       * support/regression/tests/bitwise.c: added test for bitwise complement(~)
+
 2004-12-09 Maarten Brock <sourceforge.brock AT dse.nl>
 
        * device/include/sdcc-lib.h: inserted LGPL, added includes
index 518e36ccd0355eb121f7039a5d44e15e9effa3ca..945637411fc5bd8701d08d14862e544a79b2c1cc 100644 (file)
@@ -1914,25 +1914,43 @@ genCpl (iCode * ic)
   int offset = 0;
   int size;
   symbol *tlbl;
+  sym_link *letype = getSpec (operandType (IC_LEFT (ic)));
 
-  D (emitcode (";", "genCpl "););
-
+  D(emitcode (";", "genCpl"));
 
   /* assign asmOps to operand & result */
   aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
   aopOp (IC_RESULT (ic), ic, TRUE, AOP_USESDPTR(IC_LEFT (ic)));
 
   /* special case if in bit space */
-  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY) {
-    if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY) {
-      emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir);
-      emitcode ("cpl", "c");
-      emitcode ("mov", "%s,c", IC_RESULT (ic)->aop->aopu.aop_dir);
+  if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
+    {
+      char *l;
+
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY ||
+          (SPEC_USIGN (letype) && IS_CHAR (letype)))
+        {
+          /* promotion rules are responsible for this strange result:
+             bit -> int -> ~int -> bit
+             uchar -> int -> ~int -> bit
+          */
+          werror(W_COMPLEMENT);
+          emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir);
       goto release;
     }
     tlbl=newiTempLabel(NULL);
-    emitcode ("cjne", "%s,#0x01,%05d$",
-              aopGet(AOP(IC_LEFT(ic)), 0, FALSE,FALSE,NULL), tlbl->key+100);
+      l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, FALSE,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,#0xFF,%05d$", l, tlbl->key + 100);
+        }
+      else
+        {
+          MOVA (l);
+          emitcode ("cjne", "a,#0xFF,%05d$", tlbl->key + 100);
+        }
     emitcode ("", "%05d$:", tlbl->key+100);
     outBitC (IC_RESULT(ic));
     goto release;
index 27a64e8df5ca4ac946f19ff283657b3a22fe7a49..17b52ae02c3a2c118cd1eda1c9656d7f2c8803fe 100644 (file)
@@ -78,6 +78,8 @@ _ds390_reset_regparm (void)
 static int
 _ds390_regparm (sym_link * l)
 {
+    if (IS_SPEC(l) && (SPEC_NOUN(l) == V_BIT))
+        return 0;
     if (options.parms_in_bank1 == 0) {
        /* simple can pass only the first parameter in a register */
        if (regParmFlg)
index def06af2e1a9e36dcb04af4227b3db8a0a17ec9f..fbb65ed8174bbdffb2a4db8bf59433602d00f963 100644 (file)
@@ -1271,7 +1271,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
 
       unusedLRs = deassignUnsedLRs(ebbs[i]);
 
-      /* of all instructions do */
+      /* for all instructions do */
       for (ic = ebbs[i]->sch; ic; ic = ic->next)
         {
 
@@ -1325,6 +1325,16 @@ serialRegAssign (eBBlock ** ebbs, int count)
                   spillThis (sym);
                   continue;
                 }
+
+              /* if this is a bit variable then don't use precious registers
+                 along with expensive bit-to-char conversions but just spill
+                 it */
+              if (SPEC_NOUN(sym->etype) == V_BIT)
+                {
+                  spillThis (sym);
+                  continue;
+                }
+
               /* if trying to allocate this will cause
                  a spill and there is nothing to spill
                  or this one is rematerializable then
index c386b7609d4536e9ef7d4b1a6eef0c6eb3e90809..84c20daf674c1aff14b3e3fc3b17d205696cae2b 100644 (file)
@@ -1668,8 +1668,9 @@ genCpl (iCode * ic)
   int offset = 0;
   int size;
   symbol *tlbl;
+  sym_link *letype = getSpec (operandType (IC_LEFT (ic)));
 
-  D(emitcode (";     genCpl",""));
+  D(emitcode (";", "genCpl"));
 
   /* assign asmOps to operand & result */
   aopOp (IC_LEFT (ic), ic, FALSE);
@@ -1678,27 +1679,32 @@ genCpl (iCode * ic)
   /* special case if in bit space */
   if (AOP_TYPE (IC_RESULT (ic)) == AOP_CRY)
     {
-      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY)
+      char *l;
+
+      if (AOP_TYPE (IC_LEFT (ic)) == AOP_CRY ||
+          (SPEC_USIGN (letype) && IS_CHAR (letype)))
         {
-          /* promotion rules are responsible for this strange result: */
+          /* promotion rules are responsible for this strange result:
+             bit -> int -> ~int -> bit
+             uchar -> int -> ~int -> bit
+          */
+          werror(W_COMPLEMENT);
           emitcode ("setb", "%s", IC_RESULT (ic)->aop->aopu.aop_dir);
           goto release;
         }
 
       tlbl=newiTempLabel(NULL);
+      l = aopGet (AOP (IC_LEFT (ic)), offset++, FALSE, FALSE);
       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);
+          emitcode ("cjne", "%s,#0xFF,%05d$", l, 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 ("cjne", "a,#0xFF,%05d$", tlbl->key + 100);
         }
       emitcode ("", "%05d$:", tlbl->key + 100);
       outBitC (IC_RESULT(ic));
index 2bdf092de38011faf3fb423db623f9e3f48ee9b3..e0674aebe74fb082e51175a9bb18fd82844585eb 100644 (file)
@@ -417,6 +417,8 @@ struct
 { W_POSSBUG2, ERROR_LEVEL_WARNING,
    "possible code generation error at %s line %d,\n"
    " please report problem and send source code at SDCC-USER list on SF.Net"},
+{ W_COMPLEMENT, ERROR_LEVEL_WARNING,
+   "using ~ on bit/bool/unsigned char variables can give unexpected results due to promotion to int" },
 };
 
 /*
index 92abb906069363fe2b71d58d7d8fdf21472f7864..728c97539481db9813b402d0e4e4eb928e19ca5b 100644 (file)
@@ -195,6 +195,7 @@ SDCCERR - SDCC Standard error handler
 #define E_PREVIOUS_DEF                177 /* previously defined here */
 #define W_SIZEOF_VOID                 178 /* size of void is zero */
 #define W_POSSBUG2                    179 /* possible bug, new format */
+#define W_COMPLEMENT                  180 /* ~bit can give unexpected results */
 
 #define MAX_ERROR_WARNING             256 /* size of disable warnings array */
 
index 6bcc10494342c1a855d547d642bb2dec866d4c7f..fe48a04d2296ac1432d1a69bce107d8aee8c558e 100644 (file)
@@ -1,24 +1,63 @@
 /** Bit vars test.
 
+    type: bool, char, unsigned char, unsigned short, unsigned long
 */
+
 #include <testfwk.h>
+#include <stdbool.h>
+
+#ifndef PORT_HOST
+#pragma disable_warning 180 //no warning about using complement on bit/unsigned char
+#endif
 
-#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80) || defined (PORT_HOST)
+#if defined (SDCC_STACK_AUTO) || defined (SDCC_hc08) || defined (SDCC_z80)
 #define NO_BITS
 #endif
 
 #ifndef NO_BITS
-char foo(bit a, bit b, char c)
+
+#define TYPE_{type}
+
+char foo(bool a, bool b, char c)
 {
   return a + b + c;
 }
+
+char complement(bool a, bool b)
+{
+  return (a == b);
+}
+
+{type} _0 = 0, _1 = 1, _ff = 0xFF, _ffff = -1;
+
 #endif
 
 void
 testBits(void)
 {
 #ifndef NO_BITS
-  bit x = 2;
+  bool x = 2;
   ASSERT (foo(x,3,4) == 6);
+  
+  ASSERT (complement (~_0, 1));
+  ASSERT (complement (~_1, 1));
+
+#if defined TYPE_char
+  ASSERT (complement (~_ff, 0));
+#else
+  ASSERT (complement (~_ff, 1));
+#endif
+
+#if defined TYPE_bool
+  ASSERT (complement (~_ffff, 1));
+#elif defined TYPE_char
+  ASSERT (complement (~_ffff, 0));
+#else
+  if (sizeof({type}) < sizeof(int))
+    ASSERT (complement (~_ffff, 1));
+  else
+    ASSERT (complement (~_ffff, 0));
+#endif
+
 #endif
 }
index 1ddc6f7ee05064c0bc2ee07c3e4d4fb470baab56..3805822f828d783238c2c3b73cb024fcc7ccd357 100644 (file)
@@ -1,6 +1,6 @@
 /** Test the bitwise operators.
     
-    type: char, int, long
+    type: char, short, long
     attr: volatile,
     storage: static,
  */
@@ -28,4 +28,6 @@ testTwoOpBitwise(void)
     ASSERT(({type})(right ^ left) == ({type})0xFC1B);
     ASSERT(({type})(left ^ 0xc1ec) == ({type})0xFC1B);
     ASSERT(({type})(0x3df7 ^ right) == ({type})0xFC1B);
+
+    ASSERT(({type})(~left) == ({type})0xFFFFC208);
 }