Fixed numerous bitfield problems.
[fw/sdcc] / src / ds390 / gen.c
index f697a3b1e045ba3e3c4c0f9f1d8511289b772b89..a5b88a727074fcfea5f1604816c9bd147b00dcf8 100644 (file)
@@ -4000,7 +4000,7 @@ genPlus (iCode * ic)
   if ( AOP_IS_STR(IC_LEFT(ic)) &&
       isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) {
       aopOp (IC_RIGHT (ic), ic, TRUE, FALSE);
-      size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
+      size = (int)floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit);
       if (size <= 9) {
          while (size--) emitcode ("inc","dptr");
       } else {
@@ -4586,7 +4586,7 @@ genMultOneByte (operand * left,
 
   /* if literal */
   if (AOP_TYPE(right)==AOP_LIT) {
-    signed char val=floatFromVal (AOP (right)->aopu.aop_lit);
+    signed char val=(signed char)floatFromVal (AOP (right)->aopu.aop_lit);
     /* AND literal negative */
     if ((int) val < 0) {
       emitcode ("cpl", "F0"); // complement sign flag
@@ -4667,7 +4667,7 @@ static void genMultTwoByte (operand *left, operand *right,
        if (!umult) {
                emitcode("clr","F0");
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                emitcode("setb","F0");
                                val = -val;
@@ -5010,7 +5010,7 @@ static void genDivTwoByte (operand *left, operand *right,
        /* load up MB with right */
        if (!umult) {
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                lbl = newiTempLabel(NULL);
                                emitcode ("jbc","F0,!tlabel",lbl->key+100);
@@ -5267,7 +5267,7 @@ static void genModTwoByte (operand *left, operand *right,
        /* load up MB with right */
        if (!umult) {
                if (AOP_TYPE(right) == AOP_LIT) {
-                       int val=floatFromVal (AOP (right)->aopu.aop_lit);
+                       int val=(int)floatFromVal (AOP (right)->aopu.aop_lit);
                        if (val < 0) {
                                val = -val;
                        } 
@@ -8979,13 +8979,15 @@ static void
 genUnpackBits (operand * result, char *rname, int ptype)
 {
   int shCnt;
-  int rlen;
+  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)
@@ -9025,12 +9027,12 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
       emitcode ("anl", "a,#!constbyte",
                ((unsigned char) -1) >> (8 - SPEC_BLEN (etype)));
-      aopPut (AOP (result), "a", offset);
-      return;
+      aopPut (AOP (result), "a", offset++);
+      goto finish;
     }
 
   /* bit field did not fit in a byte  */
-  rlen = SPEC_BLEN (etype) - 8;
+  rlen = SPEC_BLEN (etype);
   aopPut (AOP (result), "a", offset++);
 
   while (1)
@@ -9077,11 +9079,17 @@ genUnpackBits (operand * result, char *rname, int ptype)
 
   if (rlen)
     {
-      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (rlen));
-      aopPut (AOP (result), "a", offset);
+      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1) >> (8-rlen));
+      aopPut (AOP (result), "a", offset++);
     }
 
-  return;
+finish:
+  if (offset < rsize)
+    {
+      rsize -=offset;
+      while (rsize--)
+        aopPut (AOP (result), zero, offset++);
+    }
 }
 
 
@@ -9760,6 +9768,7 @@ genPackBits (sym_link * etype,
             operand * right,
             char *rname, int p_type)
 {
+  int shCount = 0;
   int offset = 0;
   int rLen;
   int blen, bstr;
@@ -9774,12 +9783,17 @@ genPackBits (sym_link * etype,
   /* 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 (SPEC_BSTR (etype));
+      AccLsh (shCount);
 
       if (SPEC_BLEN (etype) < 8)
        {                       /* if smaller than a byte */
 
+          emitcode ("anl", "a,#0x%02x", (~mask) & 0xff);
 
          switch (p_type)
            {
@@ -9801,9 +9815,7 @@ genPackBits (sym_link * etype,
              break;
            }
 
-         emitcode ("anl", "a,#!constbyte", (unsigned char)
-                   ((unsigned char) (0xFF << (blen + bstr)) |
-                    (unsigned char) (0xFF >> (8 - bstr))));
+         emitcode ("anl", "a,#!constbyte", mask);
          emitcode ("orl", "a,b");
          if (p_type == GPOINTER)
            emitcode ("pop", "b");
@@ -9872,6 +9884,9 @@ genPackBits (sym_link * etype,
   /* 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)
        {
@@ -9893,7 +9908,7 @@ genPackBits (sym_link * etype,
          break;
        }
 
-      emitcode ("anl", "a,#!constbyte", ((unsigned char) -1 << rLen));
+      emitcode ("anl", "a,#!constbyte", (((unsigned char) -1 << rLen) & 0xff));
       emitcode ("orl", "a,b");
     }
 
@@ -12604,6 +12619,42 @@ static void genSystemGetCurrentID(iCode *ic,int nparms, operand **parms,char *na
        }
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  operand *right;
+  int size, offset;
+
+  D(emitcode(";     genDummyRead",""));
+
+  right = IC_RIGHT (ic);
+
+  aopOp (right, ic, FALSE, FALSE);
+
+  /* if the result is a bit */
+  if (AOP_TYPE (right) == AOP_CRY)
+    {
+      emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir);
+      goto release;
+    }
+
+  /* bit variables done */
+  /* general case */
+  size = AOP_SIZE (right);
+  offset = 0;
+  while (size--)
+    {
+      emitcode ("mov", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE, FALSE));
+      offset++;
+    }
+
+release:
+  freeAsmop (right, NULL, ic, TRUE);
+}
+
 /*-----------------------------------------------------------------*/
 /* genBuiltIn - calls the appropriate function to  generating code */
 /* for a built in function                                        */
@@ -12973,6 +13024,10 @@ gen390Code (iCode * lic)
          else addSet (&_G.sendSet, ic);
          break;
 
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
 #if 0 // obsolete, and buggy for != xdata
        case ARRAYINIT:
            genArrayInit(ic);