* src/SDCCsymt.c (compStructSize): allow signed bitfields for PIC ports
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 26 Oct 2005 11:08:11 +0000 (11:08 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 26 Oct 2005 11:08:11 +0000 (11:08 +0000)
* src/pic16/gen.c (genUnpackBits): support signed bitfields,
  (genAssign): emit warning when casting literals to generic pointer
    type, also applies when taking the address of a fixed variable,
  (genCast): improved casting to generic pointers
* src/pic16/glue.c (pic16emitStaticSeg): fixed(?) handling of fixed
  extern variables, added verbose error message
* device/include/pic16/{string.h,errno.h}: added #pragma library c

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

ChangeLog
device/include/pic16/errno.h
device/include/pic16/string.h
src/SDCCsymt.c
src/pic16/gen.c
src/pic16/glue.c

index 1d77aa81fe129849731d8b566402cadff497e61a..4c4acb9eb2ed6e99fd542f5f8e5479a4d6796d40 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-10-26 Raphael Neider <rneider AT web.de>
+
+       * src/SDCCsymt.c (compStructSize): allow signed bitfields for PIC ports
+       * src/pic16/gen.c (genUnpackBits): support signed bitfields,
+         (genAssign): emit warning when casting literals to generic pointer
+           type, also applies when taking the address of a fixed variable,
+         (genCast): improved casting to generic pointers
+       * src/pic16/glue.c (pic16emitStaticSeg): fixed(?) handling of fixed
+         extern variables, added verbose error message
+       * device/include/pic16/{string.h,errno.h}: added #pragma library c
+       
 2005-10-26 Bernhard Held <bernhard AT bernhardheld.de>
 
        * src/mcs51/gen.c (genMinus): fixed bug 1270906: reverse subtraction,
index c8aa5e17bc4a221a7a9ae52d4bb5c59846b09397..4247b70aa5fce173eeaedf75bf1ed6a6ea4682dc 100644 (file)
@@ -27,6 +27,9 @@
 #ifndef _PIC16_ERRNO_H
 #define _PIC16_ERRNO_H
 
+/* link with C library */
+#pragma library c
+
 extern int errno;
 
 /* Error Codes: */
index a680bd401fb0f2b1bea2279cff75487cbd5dfbec..e00d9fa77dc5b193c55387aae72095f049a4eba9 100644 (file)
@@ -32,6 +32,8 @@
 
 #define _STRING_SPEC   __data
 
+#pragma library c
+
 #ifndef NULL
 # define NULL (void *)0
 #endif
index a34b6bb736d602c8ddbc209803c53f2cbbffef60..fc5f9a40ace6cafe30008b692429bc3b526ca223 100644 (file)
@@ -1233,7 +1233,11 @@ compStructSize (int su, structdef * sdef)
 
             /* change it to a unsigned bit */
             SPEC_NOUN (loop->etype) = V_BITFIELD;
-            SPEC_USIGN (loop->etype) = 1;
+           if (TARGET_IS_PIC16 || TARGET_IS_PIC) {
+               /* PIC users requested signed bitfields as well */
+            } else {
+                SPEC_USIGN (loop->etype) = 1;
+           }
             SPEC_BLEN (loop->etype) = loop->bitVar;
 
             if (loop->bitVar == BITVAR_PAD) {
index 1435ca23a65d27bd2b987d661c0c4d5530d3323f..1f03cbb6dc5ce87cdcf75aea1756338afc060bec 100644 (file)
@@ -5028,6 +5028,7 @@ static void genCmp (operand *left,operand *right,
        pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
       } // if
     } else {
+      /* using PRODL as a temporary register here */
       pCodeOp *pctemp = pic16_popCopyReg(&pic16_pc_prodl);
       //pCodeOp *pctemp = pic16_popGetTempReg(1);
       pic16_mov2w (AOP(left), size);
@@ -5982,6 +5983,7 @@ static void genCmp (operand *left, operand *right,
         /* signed compare */
         DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__);
 
+        /* using PRODL:PRODH as a temporary register here */
         pct = pic16_popCopyReg(&pic16_pc_prodl);
         pct2 = pic16_popCopyReg(&pic16_pc_prodh);
         tlbl = newiTempLabel( NULL );
@@ -10510,6 +10512,9 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
 
     lbstr = SPEC_BSTR( letype );
 
+    DEBUGpic16_emitcode ("; ***","%s  %d - reading %s bitfield int %s destination",__FUNCTION__,__LINE__,
+       SPEC_USIGN(OP_SYM_ETYPE(left)) ? "an unsigned" : "a signed", SPEC_USIGN(OP_SYM_TYPE(result)) ? "an unsigned" : "a signed");
+    
 #if 1
     if((blen == 1) && (bstr < 8)) {
       /* it is a single bit, so use the appropriate bit instructions */
@@ -10523,14 +10528,23 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
         pic16_emitpcode(POC_BTFSC,
               pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr));
       } else {
+        /* this code does only handle __data pointers correctly */
+        assert (IS_DATA_PTR(operandType(left)));
        pic16_loadFSR0 (left, 0);
         pic16_emitpcode(POC_BTFSC,
               pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr));
       }
-       
-      pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
 
-      pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));      
+      if (SPEC_USIGN(OP_SYM_ETYPE(left))) {
+        /* unsigned bitfields result in either 0 or 1 */
+        pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg));
+      } else {
+        /* signed bitfields result in either 0 or -1 */
+        pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_wreg));
+      }
+      pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 ));
+      
+      pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result)));
       return;
     }
 
@@ -10566,7 +10580,17 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp
                pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype))));
 */
 
+               /* extend signed bitfields to 8 bits */
+               if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen < 8))
+               {
+                       assert (blen + bstr > 0);
+                       pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr + blen - 1));
+                       pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xFF << (bstr + blen)));
+               }
+
                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+
+               pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result)));
          return ;
        }
 
@@ -12365,6 +12389,16 @@ static void genAssign (iCode *ic)
        goto release;
   }
 
+  if (AOP_TYPE(right) == AOP_LIT && IS_SYMOP(result) && IS_GENPTR(OP_SYM_TYPE(result)))
+  {
+    /* Arrg -- a literal is cast into a generic pointer: how shall we decide which TAG
+     *         to assign (__data, __code, __eeprom, ???)??? */
+    fprintf (stderr, "%s:%u(%s): creating generic pointer from literal defaults to __data TYPE*.\n\tPlease explicitly cast to (__data|__code) TYPE* in line %u if neccessary!\n",
+       __FILE__, __LINE__, __FUNCTION__, ic->lineno);
+    /* assume __data space */
+    lit = (lit & 0x00ffff) | 0x800000;
+    //exit (-1);
+  }
 
 
 #if 0
@@ -12737,6 +12771,77 @@ static void genCast (iCode *ic)
          && IS_BITFIELD(getSpec(rtype))) {
          DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__);
         }
+       
+       /* port from pic14 to cope with generic pointers */
+       if (IS_PTR(restype))
+       {
+         operand *result = IC_RESULT(ic);
+         //operand *left = IC_LEFT(ic);
+         operand *right = IC_RIGHT(ic);
+         int tag = 0xff;
+         
+         /* copy common part */
+         int max, size = AOP_SIZE(result);
+         if (size > AOP_SIZE(right)) size = AOP_SIZE(right);
+         DEBUGpic16_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+         /* warn if we discard generic opinter tag */
+         if (!IS_GENPTR(restype) && IS_GENPTR(rtype) && (AOP_SIZE(result) < AOP_SIZE(right)))
+         {
+           //fprintf (stderr, "%s:%u: discarding generic pointer type tag\n", __FUNCTION__, __LINE__);
+         } // if
+
+         max = size;
+         while (size--)
+         {
+           pic16_mov2w (AOP(right), size);
+           pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size));
+         } // while
+         pic16_addSign(result, max, 0);
+
+         /* upcast into generic pointer type? */
+         if (IS_GENPTR(restype) && !IS_GENPTR(rtype))
+         {
+           //fprintf (stderr, "%s:%u: must determine pointer type (IS_PTR: %d, DCL_TYPE: %d)\n", __FUNCTION__, __LINE__, IS_PTR(rtype), IS_PTR(rtype) ? DCL_TYPE(rtype) : 0);
+           if (IS_PTR(rtype))
+           {
+             switch (DCL_TYPE(rtype))
+             {
+             case POINTER:     /* __data */
+             case FPOINTER:    /* __data */
+               assert (AOP_SIZE(right) == 2);
+               tag = 0x80;
+               break;
+
+             case CPOINTER:    /* __code */
+               assert (AOP_SIZE(right) == 2);
+               tag = 0x00;
+               break;
+               
+             case GPOINTER:    /* unknown destination, __data or __code */
+               assert (AOP_SIZE(right) == 3);
+               /* tag taken from right operand */
+               break;
+               
+             default:
+               assert (!"unhandled pointer type");
+             } // switch
+           } else {
+             /* convert other values into pointers to __data space */
+             fprintf (stderr, "%s:%u(%s): creating generic pointer from non-pointer type -- assuming __data space\n", __FILE__, __LINE__, __FUNCTION__);
+             tag = 0x80;
+           }
+
+           assert (AOP_SIZE(result) == 3);
+           if (tag == 0) {
+             pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 2));
+           } else {
+             pic16_emitpcode(POC_MOVLW, pic16_popGetLit(tag));
+             pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), 2));
+           }
+         } // if
+         goto release;
+       }
 
        /* if they are the same size : or less */
        if (AOP_SIZE(result) <= AOP_SIZE(right)) {
index 7cea40809bc040bb77c2714004e510434cec1257..dcb109afcce5809790a44cb651ccc44219b80caa 100644 (file)
@@ -1251,7 +1251,7 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
         }
 
        /* if it is "extern" then do nothing */
-       if (IS_EXTERN (sym->etype) && !SPEC_ABSA(sym->etype)) {
+       if (IS_EXTERN (sym->etype)/* && !SPEC_ABSA(sym->etype)*/) {
                checkAddSym(&externs, sym);
          continue;
        }
@@ -1323,6 +1323,7 @@ CODESPACE: %d\tCONST: %d\tPTRCONST: %d\tSPEC_CONST: %d\n", __FUNCTION__,
 
                pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
              } else {
+               fprintf (stderr, "%s:%u(%s): do not know how to intialize symbol %s\n", __FILE__, __LINE__, __FUNCTION__, sym->rname);
                assert(0);
              }
            }