Made bitfield a distinct type from bit so that bitfields
authorepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 18 Aug 2003 05:35:47 +0000 (05:35 +0000)
committerepetrich <epetrich@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 18 Aug 2003 05:35:47 +0000 (05:35 +0000)
convert as per ANSI C and bits retain their traditional
boolean style behaviour. Implemented bitfield support in
the z80 port.

* src/SDCCsymt.h,
* src/SDCCsymt.c,
* src/SDCCast.c,
* src/cdbFile.c,
* src/mcs51/gen.c,
* src/ds390/gen.c: bit v bitfield split
* src/z80/gen.c: New support for bitfields
* support/regression/tests/bitfields.c: reenabled z80,
added more tests

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

ChangeLog
src/SDCCast.c
src/SDCCsymt.c
src/SDCCsymt.h
src/cdbFile.c
src/ds390/gen.c
src/mcs51/gen.c
src/z80/gen.c
support/regression/tests/bitfields.c

index 54c16bdf9a12138474cd774c46c89ab126cb9b17..e534f0fd507d9bcee8a358c6b2771d40646f9886 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2003-08-18  Erik Petrich <epetrich@ivorytower.norman.ok.us>
+
+       Made bitfield a distinct type from bit so that bitfields
+       convert as per ANSI C and bits retain their traditional
+       boolean style behaviour. Implemented bitfield support in
+       the z80 port.
+
+       * src/SDCCsymt.h,
+       * src/SDCCsymt.c,
+       * src/SDCCast.c,
+       * src/cdbFile.c,
+       * src/mcs51/gen.c,
+       * src/ds390/gen.c: bit v bitfield split
+       * src/z80/gen.c: New support for bitfields
+       * support/regression/tests/bitfields.c: reenabled z80,
+       added more tests
+
 2003-08-17  Frieder Ferlemann <Frieder.Ferlemann@web.de>
 
        Rules 246.x, 247.x relate to bitfields, the others speed up
index 5741a4dfde7c7ca6e3fe597c7f2ce3a55967e1c6..c50f127d8ce03256b84ece9276cc47bccfc5f989 100644 (file)
@@ -2994,6 +2994,9 @@ decorateType (ast * tree)
                case V_STRUCT:
                    typeofv = TYPEOF_STRUCT;
                    break;
+               case V_BITFIELD:
+                   typeofv = TYPEOF_BITFIELD;
+                   break;
                case V_BIT:
                    typeofv = TYPEOF_BIT;
                    break;
index 3ba40fc609554b9689f7dd5a34a1738eec757cf0..213417265cd98563e122c22c8ea536f7e98fbd35 100644 (file)
@@ -48,6 +48,7 @@ char *nounName(sym_link *sl) {
     case V_VOID: return "void";
     case V_STRUCT: return "struct";
     case V_LABEL: return "label";
+    case V_BITFIELD: return "bitfield";
     case V_BIT: return "bit";
     case V_SBIT: return "sbit";
     case V_DOUBLE: return "double";
@@ -754,8 +755,9 @@ getSize (sym_link * p)
        case V_LABEL:
          return 0;
        case V_SBIT:
-         return BITSIZE;
        case V_BIT:
+         return BITSIZE;
+       case V_BITFIELD:
          return ((SPEC_BLEN (p) / 8) + (SPEC_BLEN (p) % 8 ? 1 : 0));
        default:
          return 0;
@@ -818,8 +820,9 @@ bitsForType (sym_link * p)
        case V_LABEL:
          return 0;
        case V_SBIT:
-         return 1;
        case V_BIT:
+         return 1;
+       case V_BITFIELD:
          return SPEC_BLEN (p);
        default:
          return 0;
@@ -1076,7 +1079,7 @@ compStructSize (int su, structdef * sdef)
        if (loop->bitVar) {
 
            /* change it to a unsigned bit */
-           SPEC_NOUN (loop->etype) = V_BIT;
+           SPEC_NOUN (loop->etype) = V_BITFIELD;
            SPEC_USIGN (loop->etype) = 1;
            SPEC_BLEN (loop->etype) = loop->bitVar;
 
@@ -1256,6 +1259,7 @@ checkSClass (symbol * sym, int isProto)
   if ((IS_ARRAY (sym->type) || IS_PTR (sym->type)) &&
       (SPEC_NOUN (sym->etype) == V_BIT ||
        SPEC_NOUN (sym->etype) == V_SBIT ||
+       SPEC_NOUN (sym->etype) == V_BITFIELD ||
        SPEC_SCLS (sym->etype) == S_SFR))
     werror (E_BIT_ARRAY, sym->name);
 
@@ -1985,6 +1989,7 @@ void
 printTypeChain (sym_link * start, FILE * of)
 {
   int nlr = 0;
+  value *args;
   sym_link * type, * search;
   STORAGE_CLASS scls;
 
@@ -2044,6 +2049,15 @@ printTypeChain (sym_link * start, FILE * of)
              fprintf (of, "function %s %s", 
                       (IFFUNC_ISBUILTIN(type) ? "__builtin__" : " "),
                       (IFFUNC_ISJAVANATIVE(type) ? "_JavaNative" : " "));
+             fprintf (of, "( ");
+             for (args = FUNC_ARGS(type); 
+                  args; 
+                  args=args->next) {
+               printTypeChain(args->type, of);
+               if (args->next)
+                 fprintf(of, ", ");
+             }
+             fprintf (of, ") ");
              break;
            case GPOINTER:
              fprintf (of, "generic* ");
@@ -2115,7 +2129,11 @@ printTypeChain (sym_link * start, FILE * of)
              break;
 
            case V_BIT:
-             fprintf (of, "bit {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
+             fprintf (of, "bit");
+             break;
+
+           case V_BITFIELD:
+             fprintf (of, "bitfield {%d,%d}", SPEC_BSTR (type), SPEC_BLEN (type));
              break;
 
            case V_DOUBLE:
index 3c8bf447b7cc153a85b4d282a72e1739e46c21fe..c41303ed24b4f4a95745838d9250750cc0061e84 100644 (file)
@@ -42,6 +42,7 @@ enum {
     TYPEOF_LONG,
     TYPEOF_FLOAT,
     TYPEOF_BIT,
+    TYPEOF_BITFIELD,
     TYPEOF_SBIT,
     TYPEOF_SFR,
     TYPEOF_VOID,
@@ -98,6 +99,7 @@ typedef enum
     V_STRUCT,
     V_LABEL,
     V_BIT,
+    V_BITFIELD,
     V_SBIT,
     V_DOUBLE
   }
@@ -444,10 +446,12 @@ extern sym_link *validateLink(sym_link    *l,
                           x->select.d.ptr_volatile)
 #define IS_INTEGRAL(x) (IS_SPEC(x) && (x->select.s.noun == V_INT ||  \
                                        x->select.s.noun == V_CHAR || \
+                                       x->select.s.noun == V_BITFIELD || \
                                        x->select.s.noun == V_BIT ||  \
                                        x->select.s.noun == V_SBIT ))
-#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BIT))
-#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun  == V_BIT ||   \
+#define IS_BITFIELD(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD))
+#define IS_BITVAR(x) (IS_SPEC(x) && (x->select.s.noun == V_BITFIELD || \
+                                     x->select.s.noun  == V_BIT ||   \
                                      x->select.s.noun == V_SBIT ))
 #define IS_FLOAT(x)  (IS_SPEC(x) && x->select.s.noun == V_FLOAT)
 #define IS_ARITHMETIC(x) (IS_INTEGRAL(x) || IS_FLOAT(x))
index d4a345204e420a9624a62368b98140d761d0694a..ea9e55598254bcbafff8af7439165dbc8a7fa81b 100644 (file)
@@ -338,6 +338,7 @@ void cdbTypeInfo (sym_link * type)
            
            case V_SBIT: fprintf (cdbFilePtr, "SX"); break;
            case V_BIT: 
+           case V_BITFIELD: 
              fprintf (cdbFilePtr, "SB%d$%d", SPEC_BSTR (type), 
                       SPEC_BLEN (type));
              break;
index 9eecde6d7f0920b285ae3c8ab1fca8cd3d59b8fd..419896b1231fb2cea4226063e72446138dfbcde6 100644 (file)
@@ -9115,127 +9115,6 @@ finish:
        aopPut (AOP (result), zero, offset++);
     }
 }
-#if 0
-/*-----------------------------------------------------------------*/
-/* genUnpackBits - generates code for unpacking bits               */
-/*-----------------------------------------------------------------*/
-static void
-genUnpackBits (operand * result, char *rname, int ptype)
-{
-  int shCnt;
-  int rlen = 0;
-  sym_link *etype;
-  int offset = 0;
-  int rsize;
-
-  D (emitcode (";", "genUnpackBits "););
-
-  etype = getSpec (operandType (result));
-  rsize = getSize (operandType (result));
-
-  /* read the first byte  */
-  switch (ptype)
-    {
-
-    case POINTER:
-    case IPOINTER:
-      emitcode ("mov", "a,@%s", rname);
-      break;
-
-    case PPOINTER:
-      emitcode ("movx", "a,@%s", rname);
-      break;
-
-    case FPOINTER:
-      emitcode ("movx", "a,@dptr");
-      break;
-
-    case CPOINTER:
-      emitcode ("clr", "a");
-      emitcode ("movc", "a,@a+dptr");
-      break;
-
-    case GPOINTER:
-      emitcode ("lcall", "__gptrget");
-      break;
-    }
-
-  /* if we have bitdisplacement then it fits   */
-  /* into this byte completely or if length is */
-  /* less than a byte                          */
-  if (((shCnt = SPEC_BSTR (etype)) != 0) || (SPEC_BLEN (etype) <= 8))
-    {
-
-      /* shift right acc */
-      AccRsh (shCnt);
-
-      emitcode ("anl", "a,#!constbyte",
-               ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
-      aopPut (AOP (result), "a", offset++);
-      goto finish;
-    }
-
-  /* bit field did not fit in a byte  */
-  rlen = SPEC_BLEN (etype);
-  aopPut (AOP (result), "a", offset++);
-
-  while (1)
-    {
-
-      switch (ptype)
-       {
-       case POINTER:
-       case IPOINTER:
-         emitcode ("inc", "%s", rname);
-         emitcode ("mov", "a,@%s", rname);
-         break;
-
-       case PPOINTER:
-         emitcode ("inc", "%s", rname);
-         emitcode ("movx", "a,@%s", rname);
-         break;
-
-       case FPOINTER:
-         emitcode ("inc", "dptr");
-         emitcode ("movx", "a,@dptr");
-         break;
-
-       case CPOINTER:
-         emitcode ("clr", "a");
-         emitcode ("inc", "dptr");
-         emitcode ("movc", "a,@a+dptr");
-         break;
-
-       case GPOINTER:
-         emitcode ("inc", "dptr");
-         emitcode ("lcall", "__gptrget");
-         break;
-       }
-
-      rlen -= 8;
-      /* if we are done */
-      if (rlen < 8)
-       break;
-
-      aopPut (AOP (result), "a", offset++);
-
-    }
-
-  if (rlen)
-    {
-      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8-rlen));
-      aopPut (AOP (result), "a", offset++);
-    }
-
-finish:
-  if (offset < rsize)
-    {
-      rsize -=offset;
-      while (rsize--)
-        aopPut (AOP (result), zero, offset++);
-    }
-}
-#endif
 
 
 /*-----------------------------------------------------------------*/
@@ -10031,179 +9910,6 @@ genPackBits (sym_link * etype,
 
 }
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* genPackBits - generates code for packed bit storage             */
-/*-----------------------------------------------------------------*/
-static void
-genPackBits (sym_link * etype,
-            operand * right,
-            char *rname, int p_type)
-{
-  int shCount = 0;
-  int offset = 0;
-  int rLen;
-  int blen, bstr;
-  char *l;
-
-  blen = SPEC_BLEN (etype);
-  bstr = SPEC_BSTR (etype);
-
-  MOVA (aopGet (AOP (right), offset++, FALSE, FALSE, NULL));
-
-  /* if the bit lenth is less than or    */
-  /* it exactly fits a byte then         */
-  if (SPEC_BLEN (etype) <= 8)
-    {
-      unsigned char mask = ((unsigned char) (0xFF << (blen + bstr)) |
-                            (unsigned char) (0xFF >> (8 - bstr)));
-      shCount = SPEC_BSTR (etype);
-      
-      /* shift left acc */
-      AccLsh (shCount);
-
-      if (SPEC_BLEN (etype) < 8)
-       {                       /* if smaller than a byte */
-
-          emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
-
-         switch (p_type)
-           {
-           case POINTER:
-             emitcode ("mov", "b,a");
-             emitcode ("mov", "a,@%s", rname);
-             break;
-
-           case FPOINTER:
-             emitcode ("mov", "b,a");
-             emitcode ("movx", "a,@dptr");
-             break;
-
-           case GPOINTER:
-             emitcode ("push", "b");
-             emitcode ("push", "acc");
-             emitcode ("lcall", "__gptrget");
-             emitcode ("pop", "b");
-             break;
-           }
-
-         emitcode ("anl", "a,#!constbyte", mask);
-         emitcode ("orl", "a,b");
-         if (p_type == GPOINTER)
-           emitcode ("pop", "b");
-       }
-    }
-
-  switch (p_type)
-    {
-    case POINTER:
-      emitcode ("mov", "@%s,a", rname);
-      break;
-
-    case FPOINTER:
-      emitcode ("movx", "@dptr,a");
-      break;
-
-    case GPOINTER:
-      emitcode ("lcall", "__gptrput");
-      break;
-    }
-
-  /* if we r done */
-  if (SPEC_BLEN (etype) <= 8)
-    return;
-
-  emitcode ("inc", "%s", rname);
-  rLen = SPEC_BLEN (etype);
-
-  /* now generate for lengths greater than one byte */
-  while (1)
-    {
-
-      l = aopGet (AOP (right), offset++, FALSE, TRUE, NULL);
-
-      rLen -= 8;
-      if (rLen < 8)
-       break;
-
-      switch (p_type)
-       {
-       case POINTER:
-         if (*l == '@')
-           {
-             MOVA (l);
-             emitcode ("mov", "@%s,a", rname);
-           }
-         else
-           emitcode ("mov", "@%s,%s", rname, l);
-         break;
-
-       case FPOINTER:
-         MOVA (l);
-         emitcode ("movx", "@dptr,a");
-         break;
-
-       case GPOINTER:
-         MOVA (l);
-         emitcode ("lcall", "__gptrput");
-         break;
-       }
-      emitcode ("inc", "%s", rname);
-    }
-
-  MOVA (l);
-
-  /* last last was not complete */
-  if (rLen)
-    {
-      emitcode ("anl", "a,#!constbyte",
-                (~(((unsigned char) -1 << rLen) & 0xff)) & 0xff);
-
-      /* save the byte & read byte */
-      switch (p_type)
-       {
-       case POINTER:
-         emitcode ("mov", "b,a");
-         emitcode ("mov", "a,@%s", rname);
-         break;
-
-       case FPOINTER:
-         emitcode ("mov", "b,a");
-         emitcode ("movx", "a,@dptr");
-         break;
-
-       case GPOINTER:
-         emitcode ("push", "b");
-         emitcode ("push", "acc");
-         emitcode ("lcall", "__gptrget");
-         emitcode ("pop", "b");
-         break;
-       }
-
-      emitcode ("anl", "a,#!constbyte", (((unsigned char) -1 << rLen) & 0xff));
-      emitcode ("orl", "a,b");
-    }
-
-  if (p_type == GPOINTER)
-    emitcode ("pop", "b");
-
-  switch (p_type)
-    {
-
-    case POINTER:
-      emitcode ("mov", "@%s,a", rname);
-      break;
-
-    case FPOINTER:
-      emitcode ("movx", "@dptr,a");
-      break;
-
-    case GPOINTER:
-      emitcode ("lcall", "__gptrput");
-      break;
-    }
-}
-#endif
 
 /*-----------------------------------------------------------------*/
 /* genDataPointerSet - remat pointer to data space                 */
@@ -11306,8 +11012,8 @@ genCast (iCode * ic)
   aopOp (result, ic, FALSE, AOP_USESDPTR(right));
 
   /* if the result is a bit */
-  // if (AOP_TYPE (result) == AOP_CRY) /* works only for true symbols */
-  if (IS_BITVAR(OP_SYMBOL(result)->type))
+  if (IS_BITVAR (OP_SYMBOL (result)->type)
+      && !IS_BITFIELD (OP_SYMBOL (result)->type) )
     {
       /* if the right size is a literal then
          we know what the value is */
index 1034905e7b6ae8fd436525a3adce4d8a3a1acfd8..7e1494c8a4bfeba26d80c990835c8b160d159807 100644 (file)
@@ -8613,7 +8613,9 @@ genCast (iCode * ic)
   aopOp (result, ic, FALSE);
 
   /* if the result is a bit (and not a bitfield) */
-  if (AOP_TYPE (result) == AOP_CRY)
+  // if (AOP_TYPE (result) == AOP_CRY)
+  if (IS_BITVAR (OP_SYMBOL (result)->type)
+      && !IS_BITFIELD (OP_SYMBOL (result)->type) )
     {
       /* if the right size is a literal then
          we know what the value is */
index 7231edf2b9ef1cf9894c46ede6d6745f1fbb0149..6e79130709596c33e297c2bac6b05ec7954db445 100644 (file)
@@ -5469,6 +5469,7 @@ AccRol (int shCount)
 {
   shCount &= 0x0007;           // shCount : 0..7
 
+#if 0
   switch (shCount)
     {
     case 0:
@@ -5504,6 +5505,43 @@ AccRol (int shCount)
       emit2 ("srl a");
       break;
     }
+#else
+  switch (shCount)
+    {
+    case 0:
+      break;
+    case 1:
+      emit2 ("rlca");
+      break;
+    case 2:
+      emit2 ("rlca");
+      emit2 ("rlca");
+      break;
+    case 3:
+      emit2 ("rlca");
+      emit2 ("rlca");
+      emit2 ("rlca");
+      break;
+    case 4:
+      emit2 ("rlca");
+      emit2 ("rlca");
+      emit2 ("rlca");
+      emit2 ("rlca");
+      break;
+    case 5:
+      emit2 ("rrca");
+      emit2 ("rrca");
+      emit2 ("rrca");
+      break;
+    case 6:
+      emit2 ("rrca");
+      emit2 ("rrca");
+      break;
+    case 7:
+      emit2 ("rrca");
+      break;
+    }
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -6015,6 +6053,82 @@ genRightShift (iCode * ic)
   freeAsmop (result, NULL, ic);
 }
 
+
+/*-----------------------------------------------------------------*/
+/* genUnpackBits - generates code for unpacking bits               */
+/*-----------------------------------------------------------------*/
+static void
+genUnpackBits (operand * result, int pair)
+{
+  int offset = 0;      /* result byte offset */
+  int rsize;           /* result size */
+  int rlen = 0;                /* remaining bitfield length */
+  sym_link *etype;     /* bitfield type information */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
+
+  emitDebug ("; genUnpackBits");
+
+  etype = getSpec (operandType (result));
+  rsize = getSize (operandType (result));
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
+    {
+      emit2 ("ld a,!*pair", _pairs[pair].name);
+      AccRsh (bstr);
+      emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (8 - blen));
+      aopPut (AOP (result), "a", offset++);
+      goto finish;
+    }
+
+  /* TODO: what if pair == PAIR_DE ? */
+  if (getPairId (AOP (result)) == PAIR_HL)
+    {
+      wassertl (rsize == 2, "HL must be of size 2");
+      emit2 ("ld a,!*hl");
+      emit2 ("inc hl");
+      emit2 ("ld h,!*hl");
+      emit2 ("ld l,a");
+      emit2 ("ld a,h");
+      emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (16 - blen));
+      emit2 ("ld h,a");
+      spillPair (PAIR_HL);
+      return;
+    }
+
+  /* Bit field did not fit in a byte. Copy all
+     but the partial byte at the end.  */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      emit2 ("ld a,!*pair", _pairs[pair].name);
+      aopPut (AOP (result), "a", offset++);
+      if (rlen>8)
+        {
+          emit2 ("inc %s", _pairs[pair].name);
+          _G.pairs[pair].offset++;
+        }
+    }
+
+  /* Handle the partial byte at the end */
+  if (rlen)
+    {
+      emit2 ("ld a,!*pair", _pairs[pair].name);
+      emit2 ("and a,!immedbyte", ((unsigned char) -1) >> (8 - rlen));
+      aopPut (AOP (result), "a", offset++);
+    }
+
+finish:
+  if (offset < rsize)
+    {
+      rsize -= offset;
+      while (rsize--)
+       aopPut (AOP (result), "!zero", offset++);
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* genGenPointerGet -  get value from generic pointer space        */
 /*-----------------------------------------------------------------*/
@@ -6034,7 +6148,7 @@ genGenPointerGet (operand * left,
 
   size = AOP_SIZE (result);
 
-  if (isPair (AOP (left)) && size == 1)
+  if (isPair (AOP (left)) && size == 1 && !IS_BITVAR (retype))
     {
       /* Just do it */
       if (isPtrPair (AOP (left)))
@@ -6052,7 +6166,7 @@ genGenPointerGet (operand * left,
       goto release;
     }
 
-  if (getPairId (AOP (left)) == PAIR_IY)
+  if (getPairId (AOP (left)) == PAIR_IY && !IS_BITVAR (retype))
     {
       /* Just do it */
       offset = 0;
@@ -6075,7 +6189,10 @@ genGenPointerGet (operand * left,
   /* if bit then unpack */
   if (IS_BITVAR (retype))
     {
-      wassert (0);
+      genUnpackBits (result, pair);
+      freeAsmop (left, NULL, ic);
+      goto release;
+      //wassert (0);
     }
   else if (getPairId (AOP (result)) == PAIR_HL)
     {
@@ -6175,6 +6292,149 @@ isRegOrLit (asmop * aop)
   return FALSE;
 }
 
+
+/*-----------------------------------------------------------------*/
+/* genPackBits - generates code for packed bit storage             */
+/*-----------------------------------------------------------------*/
+static void
+genPackBits (sym_link * etype,
+            operand * right,
+            int pair,
+            iCode *ic)
+{
+  int offset = 0;      /* source byte offset */
+  int rlen = 0;                /* remaining bitfield length */
+  int blen;            /* bitfield length */
+  int bstr;            /* bitfield starting bit within byte */
+  int litval;          /* source literal value (if AOP_LIT) */
+  unsigned char mask;  /* bitmask within current byte */
+  int extraPair;       /* a tempory register */
+  bool needPopExtra=0; /* need to restore original value of temp reg */
+
+  emitDebug (";     genPackBits","");
+
+  blen = SPEC_BLEN (etype);
+  bstr = SPEC_BSTR (etype);
+
+  /* If the bitfield length is less than a byte */
+  if (blen < 8)
+    {
+      mask = ((unsigned char) (0xFF << (blen + bstr)) |
+             (unsigned char) (0xFF >> (8 - bstr)));
+
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with a bitfield length <8 and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval <<= bstr;
+          litval &= (~mask) & 0xff;
+          emit2 ("ld a,!*pair", _pairs[pair].name);
+          if ((mask|litval)!=0xff)
+            emit2 ("and a,!immedbyte", mask);
+          if (litval)
+            emit2 ("or a,!immedbyte", litval);
+          emit2 ("ld !*pair,a", _pairs[pair].name);
+          return;
+        }
+      else
+        {
+          /* Case with a bitfield length <8 and arbitrary source
+          */
+          _moveA (aopGet (AOP (right), 0, FALSE));
+          /* shift and mask source value */
+          AccLsh (bstr);
+          emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+          extraPair = getFreePairId(ic);
+          if (extraPair == PAIR_INVALID)
+            {
+              extraPair = PAIR_BC;
+              if (getPairId (AOP (right)) != PAIR_BC
+                  || !isLastUse (ic, right))
+                {
+                  _push (extraPair);
+                  needPopExtra = 1;
+                }
+            }
+          emit2 ("ld %s,a", _pairs[extraPair].l);
+          emit2 ("ld a,!*pair", _pairs[pair].name);
+
+          emit2 ("and a,!immedbyte", mask);
+          emit2 ("or a,%s", _pairs[extraPair].l);
+          emit2 ("ld !*pair,a", _pairs[pair].name);
+          if (needPopExtra)
+            _pop (extraPair);
+          return;
+        }
+    }
+
+  /* Bit length is greater than 7 bits. In this case, copy  */
+  /* all except the partial byte at the end                 */
+  for (rlen=blen;rlen>=8;rlen-=8)
+    {
+      emit2 ("ld a,%s", aopGet (AOP (right), offset++, FALSE) );
+      emit2 ("ld !*pair,a", _pairs[pair].name);
+      if (rlen>8)
+        {
+          emit2 ("inc %s", _pairs[pair].name);
+          _G.pairs[pair].offset++;
+        }
+    }
+
+  /* If there was a partial byte at the end */
+  if (rlen)
+    {
+      mask = (((unsigned char) -1 << rlen) & 0xff);
+      
+      if (AOP_TYPE (right) == AOP_LIT)
+        {
+          /* Case with partial byte and literal source
+          */
+          litval = (int) floatFromVal (AOP (right)->aopu.aop_lit);
+          litval >>= (blen-rlen);
+          litval &= (~mask) & 0xff;
+          emit2 ("ld a,!*pair", _pairs[pair].name);
+          if ((mask|litval)!=0xff)
+            emit2 ("and a,!immedbyte", mask);
+          if (litval)
+            emit2 ("or a,!immedbyte", litval);
+        }
+      else
+        {
+          /* Case with partial byte and arbitrary source
+          */
+          _moveA (aopGet (AOP (right), offset++, FALSE));
+          emit2 ("and a,!immedbyte", (~mask) & 0xff);
+
+          extraPair = getFreePairId(ic);
+          if (extraPair == PAIR_INVALID)
+            {
+              extraPair = getPairId (AOP (right));
+              if (!isLastUse (ic, right) || (extraPair == PAIR_INVALID))
+                extraPair = PAIR_BC;
+
+              if (getPairId (AOP (right)) != PAIR_BC
+                  || !isLastUse (ic, right))
+                {
+                  _push (extraPair);
+                  needPopExtra = 1;
+                }
+            }
+          emit2 ("ld %s,a", _pairs[extraPair].l);
+          emit2 ("ld a,!*pair", _pairs[pair].name);
+
+          emit2 ("and a,!immedbyte", mask);
+          emit2 ("or a,%s", _pairs[extraPair].l);
+          if (needPopExtra)
+            _pop (extraPair);
+
+        }
+      emit2 ("ld !*pair,a", _pairs[pair].name);
+    }
+}
+
+
 /*-----------------------------------------------------------------*/
 /* genGenPointerSet - stores the value into a pointer location        */
 /*-----------------------------------------------------------------*/
@@ -6184,7 +6444,9 @@ genGenPointerSet (operand * right,
 {
   int size, offset;
   sym_link *retype = getSpec (operandType (right));
+  sym_link *letype = getSpec (operandType (result));
   PAIR_ID pairId = PAIR_HL;
+  bool isBitvar;
   
   aopOp (result, ic, FALSE, FALSE);
   aopOp (right, ic, FALSE, FALSE);
@@ -6194,8 +6456,11 @@ genGenPointerSet (operand * right,
 
   size = AOP_SIZE (right);
 
+  isBitvar = IS_BITVAR(retype) || IS_BITVAR(letype);
+  emitDebug("; isBitvar = %d", isBitvar);
+
   /* Handle the exceptions first */
-  if (isPair (AOP (result)) && size == 1)
+  if (isPair (AOP (result)) && size == 1 && !isBitvar)
     {
       /* Just do it */
       const char *l = aopGet (AOP (right), 0, FALSE);
@@ -6212,7 +6477,7 @@ genGenPointerSet (operand * right,
       goto release;
     }
   
-  if ( getPairId( AOP (result)) == PAIR_IY)
+  if ( getPairId( AOP (result)) == PAIR_IY && !isBitvar)
     {
       /* Just do it */
       const char *l = aopGet (AOP (right), 0, FALSE);
@@ -6233,7 +6498,8 @@ genGenPointerSet (operand * right,
         }
       goto release;
     }
-  else if (getPairId (AOP (result)) == PAIR_HL && !isLastUse (ic, result))
+  else if (getPairId (AOP (result)) == PAIR_HL && !isLastUse (ic, result)
+           && !isBitvar)
     {
       offset = 0;
 
@@ -6275,9 +6541,11 @@ genGenPointerSet (operand * right,
   freeAsmop (result, NULL, ic);
 
   /* if bit then unpack */
-  if (IS_BITVAR (retype))
+  if (isBitvar)
     {
-      wassert (0);
+      genPackBits ((IS_BITVAR (retype) ? retype : letype), right, pairId, ic);
+      goto release;
+      //wassert (0);
     }
   else
     {
index fb106afd0d2774f050d71176f6741729c92ae2d3..cf7d004bc8e573aebb7bff977541ec1cb0ac2abf 100644 (file)
@@ -126,7 +126,6 @@ testBitfieldSizeof(void)
 void
 testBitfieldsSingleBitLiteral(void)
 {
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
   size2b_bf.b0 = 0; 
   size2b_bf.b1 = 0; 
   size2b_bf.b2 = 0; 
@@ -174,13 +173,11 @@ testBitfieldsSingleBitLiteral(void)
   ASSERT(size2b_bf.b7==0);
   ASSERT(size2b_bf.b8==0);
   ASSERT(size2b_bf.b9==1);
-#endif
 }
 
 void
 testBitfieldsSingleBit(void)
 {
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
   volatile unsigned char c;
 
   c = 0;
@@ -233,13 +230,11 @@ testBitfieldsSingleBit(void)
   ASSERT(size2b_bf.b7==0);
   ASSERT(size2b_bf.b8==0);
   ASSERT(size2b_bf.b9==1);
-#endif
 }
 
 void
-testBitfieldsMultibit(void)
+testBitfieldsMultibitLiteral(void)
 {
-#if !defined(SDCC_z80) && !defined(SDCC_gbz80)
   size2c_bf.b0 = 0xff; /* should truncate to 0x0f */
   size2c_bf.b1 = 0;
   ASSERT(size2c_bf.b0==0x0f);
@@ -269,7 +264,48 @@ testBitfieldsMultibit(void)
   size2d_bf.b1 = 5;
   ASSERT(size2d_bf.b0==0x0a46);
   ASSERT(size2d_bf.b1==5);
-#endif
+}
+
+void
+testBitfieldsMultibit(void)
+{
+  volatile int allones = 0xffff;
+  volatile int zero = 0;
+  volatile int x;
+  
+  size2c_bf.b0 = allones;      /* should truncate to 0x0f */
+  size2c_bf.b1 = zero;
+  ASSERT(size2c_bf.b0==0x0f);
+  ASSERT(size2c_bf.b1==0);
+
+  size2c_bf.b1 = allones;      /* should truncate to 0x1f */
+  size2c_bf.b0 = zero;
+  ASSERT(size2c_bf.b0==0);
+  ASSERT(size2c_bf.b1==0x1f);
+
+  size2d_bf.b0 = allones; /* should truncate to 0x0fff */
+  size2d_bf.b1 = zero;
+  ASSERT(size2d_bf.b0==0x0fff);
+  ASSERT(size2d_bf.b1==0);
+
+  size2d_bf.b1 = allones; /* should truncate to 0x07 */
+  size2d_bf.b0 = zero;
+  ASSERT(size2d_bf.b0==0);
+  ASSERT(size2d_bf.b1==0x07);
+
+  x = 0x0321;
+  size2d_bf.b0 = x;
+  x = 1;
+  size2d_bf.b1 = x;
+  ASSERT(size2d_bf.b0==0x0321);
+  ASSERT(size2d_bf.b1==1);
+
+  x = 0x0a46;
+  size2d_bf.b0 = x;
+  x = 5;
+  size2d_bf.b1 = x;
+  ASSERT(size2d_bf.b0==0x0a46);
+  ASSERT(size2d_bf.b1==5);
 }
 
 void