* sim/ucsim/configure.in,
authorbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 6 Mar 2004 11:44:05 +0000 (11:44 +0000)
committerbernhardheld <bernhardheld@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sat, 6 Mar 2004 11:44:05 +0000 (11:44 +0000)
* sim/ucsim/configure,
* sim/ucsim/Makefile.in: use docdir
* src/SDCC.y: fixed sbit atrributes
* src/SDCCast.c (getResultTypeFromType): added support for bitfields
* src/SDCCast.c (decorateType): |^& need special promotion handling
* src/SDCCast.h,
* src/SDCCsymt.h: moved definition of RESULT_TYPE
* src/SDCCsymt.h (computeType),
* src/SDCCicode.c: computeType() needs op
* src/SDCCsymt.c (checkTypeSanity),
* doc/sddman.lyx: "plain" bitfields are unsigned
* src/SDCCsymt.c (computeTypeOr): added
* src/SDCCsymt.c (computeType): added support for bitfields, fixed |^& ops
* src/SDCCval.c (val*): computeType() needs op
* src/SDCCval.c (valCastLiteral): fixed casting of bitfields
* support/regression/tests/onebyte.c: added tests for |^&

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

13 files changed:
ChangeLog
doc/sdccman.lyx
sim/ucsim/configure
sim/ucsim/configure.in
sim/ucsim/doc/Makefile.in
src/SDCC.y
src/SDCCast.c
src/SDCCast.h
src/SDCCicode.c
src/SDCCsymt.c
src/SDCCsymt.h
src/SDCCval.c
support/regression/tests/onebyte.c

index a07891ff75b90a7f345b95710660d212085ad335..d467f9349afa561a6148ddbda87c5776bba8fd17 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-03-06 Bernhard Held <bernhard AT bernhardheld.de>
+
+       * sim/ucsim/configure.in,
+       * sim/ucsim/configure,
+       * sim/ucsim/doc/Makefile.in: use docdir
+       * src/SDCC.y: fixed sbit atrributes
+       * src/SDCCast.c (getResultTypeFromType): added support for bitfields
+       * src/SDCCast.c (decorateType): |^& need special promotion handling
+       * src/SDCCast.h,
+       * src/SDCCsymt.h: moved definition of RESULT_TYPE
+       * src/SDCCsymt.h (computeType),
+       * src/SDCCicode.c: computeType() needs op
+       * src/SDCCsymt.c (checkTypeSanity),
+       * doc/sddman.lyx: "plain" bitfields are unsigned
+       * src/SDCCsymt.c (computeTypeOr): added
+       * src/SDCCsymt.c (computeType): added support for bitfields, fixed
+       |^& ops
+       * src/SDCCval.c (val*): computeType() needs op
+       * src/SDCCval.c (valCastLiteral): fixed casting of bitfields
+       * support/regression/tests/onebyte.c: added tests for |^&
+
 2004-03-06 Hans Dorn <hjdorn AT users.sourceforge.net>
 
        * src/pic16/gen.c: (genpic16Code) use copy of printILine's output
index be855b59c46443a6f53664772cfc3e711a21c40a..8b6f8ed12c22e92cf6f27d65ab4e5cb67bb3eb58 100644 (file)
@@ -8275,7 +8275,16 @@ Apart from this 8051 specific storage class most architectures support ANSI-C
 
 \end_inset 
 
+
+\newline 
+
+\layout Standard
+
+In accordance with ISO/IEC 9899 bits and bitfields without an explicit signed
+ modifier are implemented as unsigned.
+\layout Standard
+
+
 \begin_inset Foot
 collapsed false
 
index 6e25642273266399bfd5a2f079d28acf17f892d6..865f6db97f6fab6ae566195e36d38ff12089f524 100755 (executable)
@@ -467,7 +467,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS AWK VERSION VERSIONHI VERSIONLO VERSIONP enable_ucsim enable_dlso enable_51 enable_avr enable_z80 enable_hc08 enable_xa enable_serio CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CXXCPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB STRIP build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS ac_ct_CC LN_S ECHO ac_ct_STRIP CPP EGREP LIBTOOL LIBTOOL_DEPS dl_ok DL panel_ok curses_ok CURSES_LIBS M_OR_MM SHAREDLIB PICOPT dlso_ok LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS AWK VERSION VERSIONHI VERSIONLO VERSIONP enable_ucsim enable_dlso enable_51 enable_avr enable_z80 enable_hc08 enable_xa enable_serio CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT CXXCPP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB STRIP build build_cpu build_vendor build_os host host_cpu host_vendor host_os CC CFLAGS ac_ct_CC LN_S ECHO ac_ct_STRIP CPP EGREP LIBTOOL LIBTOOL_DEPS dl_ok DL panel_ok curses_ok CURSES_LIBS M_OR_MM SHAREDLIB PICOPT dlso_ok docdir LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -940,6 +940,10 @@ ac_env_CPP_set=${CPP+set}
 ac_env_CPP_value=$CPP
 ac_cv_env_CPP_set=${CPP+set}
 ac_cv_env_CPP_value=$CPP
+ac_env_docdir_set=${docdir+set}
+ac_env_docdir_value=$docdir
+ac_cv_env_docdir_set=${docdir+set}
+ac_cv_env_docdir_value=$docdir
 
 #
 # Report the --help message.
@@ -1045,6 +1049,7 @@ Some influential environment variables:
   CC          C compiler command
   CFLAGS      C compiler flags
   CPP         C preprocessor
+  docdir      documentation installation directory
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
@@ -4883,7 +4888,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4886 "configure"' > conftest.$ac_ext
+  echo '#line 4891 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5430,7 +5435,7 @@ chmod -w .
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
 compiler_c_o=no
-if { (eval echo configure:5433: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+if { (eval echo configure:5438: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
   # The compiler can only warn and ignore the option if not recognized
   # So say no if there are warnings
   if test -s out/conftest.err; then
@@ -7275,7 +7280,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 7278 "configure"
+#line 7283 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -7373,7 +7378,7 @@ else
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 7376 "configure"
+#line 7381 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12721,6 +12726,12 @@ cat >>confdefs.h <<_ACEOF
 _ACEOF
 
 
+# *nix default: "${datadir}/sdcc/doc"
+
+if test "${docdir}" = ""; then
+    docdir="\${datadir}"/sdcc/doc
+fi
+
 
 # Generating output files
 # ===========================================================================
@@ -13401,6 +13412,7 @@ s,@M_OR_MM@,$M_OR_MM,;t t
 s,@SHAREDLIB@,$SHAREDLIB,;t t
 s,@PICOPT@,$PICOPT,;t t
 s,@dlso_ok@,$dlso_ok,;t t
+s,@docdir@,$docdir,;t t
 s,@LIBOBJS@,$LIBOBJS,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF
index 9f25ae00e102ba942a50faec9914ab0b65f0963c..eb113efcd7b88d26f0d948b0c396beda4e8ed268 100644 (file)
@@ -466,6 +466,12 @@ fi
 AC_DEFINE_UNQUOTED(_A_, "${A}")
 AC_DEFINE_UNQUOTED(_M_, "${M}")
 
+# *nix default: "${datadir}/sdcc/doc"
+AC_ARG_VAR(docdir, documentation installation directory)
+if test "${docdir}" = ""; then
+    docdir="\${datadir}"/sdcc/doc
+fi
+AC_SUBST(docdir)
 
 # Generating output files
 # ===========================================================================
index 3cabe9c97c3cf3d66249ebc2f33b5080ee2ffc96..10e628aa347bdf836ff272c9e27b1a2f13dadd33 100644 (file)
@@ -22,7 +22,7 @@ man1dir         = $(mandir)/man1
 man2dir         = $(mandir)/man2
 infodir         = @infodir@
 srcdir          = @srcdir@
-docdir         = $(prefix)/share/sdcc/doc/ucsim
+docdir         = @docdir@/ucsim
 
 
 # Compiling entire program or any subproject
index c66605232e1b0bdc8903bc6314360920c88012f3..c5944eaf8dd0e8b4fce9aa2c398fc8810dd7228e 100644 (file)
@@ -702,6 +702,8 @@ sfr_reg_bit
                $$ = newLink(SPECIFIER) ;
                SPEC_NOUN($$) = V_SBIT;
                SPEC_SCLS($$) = S_SBIT;
+              SPEC_BLEN($$) = 1;
+              SPEC_BSTR($$) = 0;
               ignoreTypedefType = 1;
             }
    |  sfr_attributes
index 5308992cf4efbcfb9855ff352de4587f59c689d2..8e20910cf1c505dae56081cc9e485c210bbe0a52 100644 (file)
@@ -2019,10 +2019,18 @@ RESULT_TYPE
 getResultTypeFromType (sym_link *type)
 {
   /* type = getSpec (type); */
-  if (IS_BITVAR (type))
+  if (IS_BIT (type))
     return RESULT_TYPE_BIT;
   if (IS_BITFIELD (type))
-    return RESULT_TYPE_CHAR;
+    {
+      int blen = SPEC_BLEN (type);
+      
+      if (blen <= 1)
+        return RESULT_TYPE_BIT;
+      if (blen <= 8)
+        return RESULT_TYPE_CHAR;
+      return RESULT_TYPE_INT;
+    }
   if (IS_CHAR (type))
     return RESULT_TYPE_CHAR;
   if (   IS_INT (type)
@@ -2556,7 +2564,10 @@ decorateType (ast * tree, RESULT_TYPE resultType)
 
          tree->left  = addCast (tree->left,  resultType, FALSE);
          tree->right = addCast (tree->right, resultType, FALSE);
-         TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
+         TTYPE (tree) = computeType (LTYPE (tree),
+                                     RTYPE (tree),
+                                     resultType,
+                                     tree->opval.op);
          TETYPE (tree) = getSpec (TTYPE (tree));
 
           /* if left is a literal exchange left & right */
@@ -2774,7 +2785,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           resultType,
+                                           tree->opval.op));
 
       return tree;
 
@@ -2806,7 +2818,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                           resultType,
+                                           tree->opval.op));
 
       /* if right is a literal and */
       /* left is also a division by a literal then */
@@ -2872,7 +2885,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                           resultType,
+                                           tree->opval.op));
       return tree;
 
       /*------------------------------------------------------------------*/
@@ -2987,7 +3001,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                                   computeType (LTYPE (tree),
                                                RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                               resultType,
+                                               tree->opval.op));
 
       return tree;
 
@@ -3121,8 +3136,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
           tree->right = addCast (tree->right, resultType, TRUE);
           TETYPE (tree) = getSpec (TTYPE (tree) =
                                     computeType (LTYPE (tree),
-                                                 RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                 RTYPE (tree),
+                                                 resultType,
+                                                 tree->opval.op));
        }
        
       return tree;
@@ -3226,8 +3242,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          tree->right = addCast (tree->right, resultType, TRUE);
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                     computeType (LTYPE (tree),
-                                                 RTYPE (tree),
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                 RTYPE (tree),
+                                                 resultType,
+                                                 tree->opval.op));
        }
 
       LRVAL (tree) = RRVAL (tree) = 1;
@@ -3374,8 +3391,9 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          tree->left = addCast (tree->left, resultType, TRUE);
          TETYPE (tree) = getSpec (TTYPE (tree) =
                                       computeType (LTYPE (tree),
-                                                   NULL,
-                              resultType == RESULT_TYPE_CHAR ? FALSE : TRUE));
+                                                   NULL,
+                                                   resultType,
+                                                   tree->opval.op));
        }
       else /* RIGHT_OP */
        {
@@ -3858,7 +3876,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
          goto errorTreeReturn;
        }
 
-      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE);
+      TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree),
+                                  resultType, tree->opval.op);
       TETYPE (tree) = getSpec (TTYPE (tree));
       return tree;
 
@@ -3941,7 +3960,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           RESULT_TYPE_NOPROM,
+                                           tree->opval.op));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "-=");
@@ -3983,7 +4003,8 @@ decorateType (ast * tree, RESULT_TYPE resultType)
       TETYPE (tree) = getSpec (TTYPE (tree) =
                               computeType (LTYPE (tree),
                                            RTYPE (tree),
-                                           FALSE));
+                                           RESULT_TYPE_NOPROM,
+                                           tree->opval.op));
 
       if (!tree->initMode && IS_CONSTANT (LETYPE (tree)))
        werror (E_CODE_WRITE, "+=");
index 04211fa9e2cbe01b67579f059cc0e423762cf598..d46ad5f18c9076023ae5d1c96c556625bc9f39ad 100644 (file)
@@ -170,17 +170,6 @@ ast;
                          x == AND_ASSIGN || x == OR_ASSIGN || x == INC_OP || x == DEC_OP)
 #define IS_DEREF_OP(x) (( x->opval.op == '*' && x->right == NULL) || x->opval.op == '.')
 
-typedef enum
-{
-  RESULT_TYPE_NONE = 0,
-  RESULT_CHECK = 0, /* TODO: replace all occurences with the appropriate type and remove me */
-  RESULT_TYPE_BIT,
-  RESULT_TYPE_CHAR,
-  RESULT_TYPE_INT,
-  RESULT_TYPE_OTHER,
-  RESULT_TYPE_IFX,
-} RESULT_TYPE;
-
 /* forward declarations for global variables */
 extern ast *staticAutos;
 extern FILE *codeOutFile;
index 5c875c1a182ea55549b978a385537a60b4f43a63..f4e50eba162c9333a736ee99c9196b129101bc24 100644 (file)
@@ -45,7 +45,6 @@ symbol *entryLabel;           /* function entry  label */
 
 /*-----------------------------------------------------------------*/
 /* forward definition of some functions */
-operand *geniCodeDivision (operand *, operand *, bool);
 operand *geniCodeAssign (operand *, operand *, int);
 static operand *geniCodeArray (operand *, operand *,int);
 static operand *geniCodeArray2Ptr (operand *);
@@ -1703,10 +1702,11 @@ setOperandType (operand * op, sym_link * type)
     }
 
 }
+
 /*-----------------------------------------------------------------*/
 /* Get size in byte of ptr need to access an array                 */
 /*-----------------------------------------------------------------*/
-int
+static int
 getArraySizePtr (operand * op)
 {
   sym_link *ltype = operandType(op);
@@ -1766,7 +1766,7 @@ usualUnaryConversions (operand * op)
 
 static sym_link *
 usualBinaryConversions (operand ** op1, operand ** op2,
-                        bool resultIsInt, char op)
+                        RESULT_TYPE resultType, char op)
 {
   sym_link *ctype;
   sym_link *rtype = operandType (*op2);
@@ -1804,10 +1804,10 @@ usualBinaryConversions (operand ** op1, operand ** op2,
       && (   (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
          || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
     /* one or two signed char operands: promote to int */
-    resultIsInt = TRUE;
+    resultType = RESULT_TYPE_INT;
 #endif
   
-  ctype = computeType (ltype, rtype, resultIsInt);
+  ctype = computeType (ltype, rtype, resultType, op);
 
 #ifdef OLDONEBYTEOPS
 
@@ -2069,8 +2069,8 @@ geniCodeGoto (symbol * label)
 /*-----------------------------------------------------------------*/
 /* geniCodeMultiply - gen intermediate code for multiplication     */
 /*-----------------------------------------------------------------*/
-operand *
-geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
+static operand *
+geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
 {
   iCode *ic;
   int p2 = 0;
@@ -2086,7 +2086,7 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
     p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
   }
 
-  resType = usualBinaryConversions (&left, &right, resultIsInt, '*');
+  resType = usualBinaryConversions (&left, &right, resultType, '*');
 #if 1
   rtype = operandType (right);
   retype = getSpec (rtype);
@@ -2100,12 +2100,12 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
      efficient in most cases than 2 bytes result = 2 bytes << literal
      if port has 1 byte muldiv */
   if (p2 && !IS_FLOAT (letype)
-      && !((resultIsInt) && (getSize (resType) != getSize (ltype))
+      && !((resultType != RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
            && (port->support.muldiv == 1))
       && strcmp (port->target, "pic14") != 0  /* don't shift for pic */
       && strcmp (port->target, "pic16") != 0)
     {
-      if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
+      if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
        {
          /* LEFT_OP need same size for left and result, */
          left = geniCodeCast (resType, left, TRUE);
@@ -2130,8 +2130,8 @@ geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
 /*-----------------------------------------------------------------*/
 /* geniCodeDivision - gen intermediate code for division           */
 /*-----------------------------------------------------------------*/
-operand *
-geniCodeDivision (operand * left, operand * right, bool resultIsInt)
+static operand *
+geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
 {
   iCode *ic;
   int p2 = 0;
@@ -2141,7 +2141,7 @@ geniCodeDivision (operand * left, operand * right, bool resultIsInt)
   sym_link *ltype = operandType (left);
   sym_link *letype = getSpec (ltype);
 
-  resType = usualBinaryConversions (&left, &right, resultIsInt, '/');
+  resType = usualBinaryConversions (&left, &right, resultType, '/');
 
   /* if the right is a literal & power of 2
      and left is unsigned then make it a
@@ -2168,8 +2168,8 @@ geniCodeDivision (operand * left, operand * right, bool resultIsInt)
 /*-----------------------------------------------------------------*/
 /* geniCodeModulus  - gen intermediate code for modulus            */
 /*-----------------------------------------------------------------*/
-operand *
-geniCodeModulus (operand * left, operand * right, bool resultIsInt)
+static operand *
+geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
 {
   iCode *ic;
   sym_link *resType;
@@ -2180,7 +2180,7 @@ geniCodeModulus (operand * left, operand * right, bool resultIsInt)
     return operandFromValue (valMod (left->operand.valOperand,
                                     right->operand.valOperand));
 
-  resType = usualBinaryConversions (&left, &right, resultIsInt, '%');
+  resType = usualBinaryConversions (&left, &right, resultType, '%');
 
   /* now they are the same size */
   ic = newiCode ('%', left, right);
@@ -2231,8 +2231,8 @@ subtractExit:
 /*-----------------------------------------------------------------*/
 /* geniCodeSubtract - generates code for subtraction               */
 /*-----------------------------------------------------------------*/
-operand *
-geniCodeSubtract (operand * left, operand * right)
+static operand *
+geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
 {
   iCode *ic;
   int isarray = 0;
@@ -2255,12 +2255,15 @@ geniCodeSubtract (operand * left, operand * right)
     {
       isarray = left->isaddr;
       right = geniCodeMultiply (right,
-                               operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
+                               operandFromLit (getSize (ltype->next)),
+                               (getArraySizePtr(left) >= INTSIZE) ?
+                                 RESULT_TYPE_INT :
+                                 RESULT_TYPE_CHAR);
       resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
     }
   else
     {                          /* make them the same size */
-      resType = usualBinaryConversions (&left, &right, FALSE, '-');
+      resType = usualBinaryConversions (&left, &right, resultType, '-');
     }
 
   ic = newiCode ('-', left, right);
@@ -2279,8 +2282,8 @@ geniCodeSubtract (operand * left, operand * right)
 /*-----------------------------------------------------------------*/
 /* geniCodeAdd - generates iCode for addition                      */
 /*-----------------------------------------------------------------*/
-operand *
-geniCodeAdd (operand * left, operand * right, int lvl)
+static operand *
+geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
 {
   iCode *ic;
   sym_link *resType;
@@ -2308,7 +2311,11 @@ geniCodeAdd (operand * left, operand * right, int lvl)
          size  = operandFromLit (getSize (ltype->next));
          SPEC_USIGN (getSpec (operandType (size))) = 1;
          indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-         right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+         right = geniCodeMultiply (right,
+                                   size,
+                                   (getArraySizePtr(left) >= INTSIZE) ?
+                                     RESULT_TYPE_INT :
+                                     RESULT_TYPE_CHAR);
          /* Even if right is a 'unsigned char',
             the result will be a 'signed int' due to the promotion rules.
             It doesn't make sense when accessing arrays, so let's fix it here: */
@@ -2319,7 +2326,7 @@ geniCodeAdd (operand * left, operand * right, int lvl)
     }
   else
     { // make them the same size
-      resType = usualBinaryConversions (&left, &right, FALSE, '+');
+      resType = usualBinaryConversions (&left, &right, resultType, '+');
     }
 
   /* if they are both literals then we know */
@@ -2401,12 +2408,22 @@ geniCodeArray (operand * left, operand * right, int lvl)
          left = geniCodeRValue (left, FALSE);
        }
 
-      return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
+      return geniCodeDerefPtr (geniCodeAdd (left,
+                                           right,
+                                           (getArraySizePtr(left) >= INTSIZE) ?
+                                             RESULT_TYPE_INT :
+                                             RESULT_TYPE_CHAR,
+                                           lvl),
+                              lvl);
     }
   size = operandFromLit (getSize (ltype->next));
   SPEC_USIGN (getSpec (operandType (size))) = 1;
   indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
-  right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
+  right = geniCodeMultiply (right,
+                           size,
+                           (getArraySizePtr(left) >= INTSIZE) ?
+                             RESULT_TYPE_INT :
+                             RESULT_TYPE_CHAR);
   /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
      It doesn't make sense when accessing arrays, so let's fix it here: */
   if (indexUnsigned)
@@ -2909,7 +2926,7 @@ geniCodeLogic (operand * left, operand * right, int op)
         }
     }
 
-  ctype = usualBinaryConversions (&left, &right, FALSE, ' ');
+  ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, ' ');
 
   ic = newiCode (op, left, right);
   IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
@@ -3498,7 +3515,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
   /* if the min is not zero then we no make it zero */
   if (min)
     {
-      cond = geniCodeSubtract (cond, operandFromLit (min));
+      cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
       if (!IS_LITERAL(getSpec(operandType(cond))))
         setOperandType (cond, UCHARTYPE);
     }
@@ -3866,31 +3883,34 @@ ast2iCode (ast * tree,int lvl)
     case '/':
       return geniCodeDivision (geniCodeRValue (left, FALSE),
                               geniCodeRValue (right, FALSE),
-                              IS_INT (tree->ftype));
+                              getResultTypeFromType (tree->ftype));
 
     case '%':
       return geniCodeModulus (geniCodeRValue (left, FALSE),
                              geniCodeRValue (right, FALSE),
-                             IS_INT (tree->ftype));
+                             getResultTypeFromType (tree->ftype));
     case '*':
       if (right)
        return geniCodeMultiply (geniCodeRValue (left, FALSE),
                                 geniCodeRValue (right, FALSE),
-                                IS_INT (tree->ftype));
+                                getResultTypeFromType (tree->ftype));
       else
        return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
 
     case '-':
       if (right)
        return geniCodeSubtract (geniCodeRValue (left, FALSE),
-                                geniCodeRValue (right, FALSE));
+                                geniCodeRValue (right, FALSE),
+                                getResultTypeFromType (tree->ftype));
       else
        return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
 
     case '+':
       if (right)
        return geniCodeAdd (geniCodeRValue (left, FALSE),
-                           geniCodeRValue (right, FALSE),lvl);
+                           geniCodeRValue (right, FALSE),
+                           getResultTypeFromType (tree->ftype),
+                           lvl);
       else
        return geniCodeRValue (left, FALSE);    /* unary '+' has no meaning */
 
@@ -3981,7 +4001,8 @@ ast2iCode (ast * tree,int lvl)
        geniCodeAssign (left,
                geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 geniCodeRValue (right, FALSE),FALSE), 0);
+                                 geniCodeRValue (right, FALSE), FALSE),
+                                 getResultTypeFromType (tree->ftype));
 
     case DIV_ASSIGN:
       return
@@ -3989,7 +4010,7 @@ ast2iCode (ast * tree,int lvl)
                geniCodeDivision (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
-                                 IS_INT (tree->ftype)),
+                                 getResultTypeFromType (tree->ftype)),
                        0);
     case MOD_ASSIGN:
       return
@@ -3997,7 +4018,7 @@ ast2iCode (ast * tree,int lvl)
                 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
                                  geniCodeRValue (right, FALSE),
-                                 IS_INT (tree->ftype)),
+                                 getResultTypeFromType (tree->ftype)),
                        0);
     case ADD_ASSIGN:
       {
@@ -4013,7 +4034,10 @@ ast2iCode (ast * tree,int lvl)
        return geniCodeAssign (left,
                     geniCodeAdd (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 right,lvl), 0);
+                                 right,
+                                 getResultTypeFromType (tree->ftype),
+                                 lvl),
+                              0);
       }
     case SUB_ASSIGN:
       {
@@ -4032,7 +4056,9 @@ ast2iCode (ast * tree,int lvl)
          geniCodeAssign (left,
                geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
                                                  FALSE),
-                                 right), 0);
+                                 right,
+                                 getResultTypeFromType (tree->ftype)),
+                         0);
       }
     case LEFT_ASSIGN:
       return
index c1c8a8ce72a13610cb66b86303f78fd78ca24025..4ceceaf007bd50c5a55f08ee18cb4d8d12a879cb 100644 (file)
@@ -24,6 +24,8 @@
 #include "common.h"
 #include "newalloc.h"
 
+#include "SDCCsymt.h"
+
 value *aggregateToPointer (value *val);
 void printTypeChainRaw (sym_link * start, FILE * of);
 
@@ -566,6 +568,14 @@ void checkTypeSanity(sym_link *etype, char *name) {
     SPEC_NOUN(etype)=V_INT;
   }
 
+  /* ISO/IEC 9899 J.3.9 implementation defined behaviour: */
+  /* a "plain" int bitfield is unsigned */
+  if (SPEC_NOUN(etype)==V_BIT ||
+      SPEC_NOUN(etype)==V_SBIT) {
+    if (!etype->select.s._signed)
+      SPEC_USIGN(etype) = 1;
+  }
+
   if (etype->select.s._signed && SPEC_USIGN(etype)) {
     // signed AND unsigned 
     werror (E_SIGNED_AND_UNSIGNED_INVALID, noun, name);
@@ -1578,17 +1588,85 @@ cleanUpLevel (bucket ** table, int level)
     }
 }
 
+/*------------------------------------------------------------------*/
+/* computeTypeOr - computes the resultant type from two types       */
+/*------------------------------------------------------------------*/
+static sym_link *
+computeTypeOr (sym_link * etype1, sym_link * etype2, sym_link * reType)
+{
+  /* sanity check */
+  assert (IS_CHAR (etype1) && IS_CHAR (etype2));
+
+  if (SPEC_USIGN (etype1) == SPEC_USIGN (etype2))
+    {
+      SPEC_USIGN (reType) = SPEC_USIGN (etype1);
+      return reType;
+    }
+  
+  if (SPEC_USIGN (etype1))
+    {
+      if (   IS_LITERAL (etype2)
+         && floatFromVal (valFromType (etype2)) >= 0)
+       SPEC_USIGN (reType) = 1;
+      else
+       {
+         /* promote to int */
+         SPEC_USIGN (reType) = 0;
+         SPEC_NOUN (reType) = V_INT;
+       }
+    }
+  else /* etype1 signed */
+    {
+      if (   IS_LITERAL (etype2)
+         && floatFromVal (valFromType (etype2)) <= 127)
+       SPEC_USIGN (reType) = 0;
+      else
+       {
+         /* promote to int */
+         SPEC_USIGN (reType) = 0;
+         SPEC_NOUN (reType) = V_INT;
+       }
+    }
+
+  if (SPEC_USIGN (etype2))
+    {
+      if (   IS_LITERAL (etype1)
+         && floatFromVal (valFromType (etype1)) >= 0)
+       SPEC_USIGN (reType) = 1;
+      else
+       {
+         /* promote to int */
+         SPEC_USIGN (reType) = 0;
+         SPEC_NOUN (reType) = V_INT;
+       }
+    }
+  else /* etype2 signed */
+    {
+      if (   IS_LITERAL (etype1)
+         && floatFromVal (valFromType (etype1)) <= 127)
+       SPEC_USIGN (reType) = 0;
+      else
+       {
+         /* promote to int */
+         SPEC_USIGN (reType) = 0;
+         SPEC_NOUN (reType) = V_INT;
+       }
+    }
+  return reType;
+}
+
 /*------------------------------------------------------------------*/
 /* computeType - computes the resultant type from two types         */
 /*------------------------------------------------------------------*/
 sym_link *
-computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
+computeType (sym_link * type1, sym_link * type2,
+             RESULT_TYPE resultType, char op)
 {
   sym_link *rType;
   sym_link *reType;
   sym_link *etype1 = getSpec (type1);
   sym_link *etype2;
-   
+
   etype2 = type2 ? getSpec (type2) : type1;
 
   /* if one of them is a float then result is a float */
@@ -1598,12 +1676,28 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
   if (IS_FLOAT (etype1) || IS_FLOAT (etype2))
     rType = newFloatLink ();
   else
+    /* if both are bitvars choose the larger one */
+  if (IS_BITVAR (etype1) && IS_BITVAR (etype2))
+    {
+      rType = SPEC_BLEN (etype1) >= SPEC_BLEN (etype2) ?
+               copyLinkChain (type1) : copyLinkChain (type1);
+    }
     /* if only one of them is a bit variable
        then the other one prevails */
-  if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
-    rType = copyLinkChain (type2);
+  else if (IS_BITVAR (etype1) && !IS_BITVAR (etype2))
+    {
+      rType = copyLinkChain (type2);
+      /* bitfield can have up to 16 bits */
+      if (getSize (etype1) > 1)
+        SPEC_NOUN (getSpec (rType)) = V_INT;
+    }
   else if (IS_BITVAR (etype2) && !IS_BITVAR (etype1))
-    rType = copyLinkChain (type1);
+    {
+      rType = copyLinkChain (type1);
+      /* bitfield can have up to 16 bits */
+      if (getSize (etype2) > 1)
+        SPEC_NOUN (getSpec (rType)) = V_INT;
+    }
   else
     /* if one of them is a pointer or array then that
        prevails */
@@ -1621,8 +1715,60 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
   /* avoid conflicting types */
   reType->select.s._signed = 0;
 
-  if (IS_CHAR (reType) && promoteCharToInt)
-    SPEC_NOUN (reType) = V_INT;
+  /* if result is a literal then make not so */
+  if (IS_LITERAL (reType))
+    SPEC_SCLS (reType) = S_REGISTER;
+
+  switch (resultType)
+    {
+      case RESULT_TYPE_CHAR:
+       if (IS_BITVAR (reType))
+         {
+           SPEC_NOUN (reType) = V_CHAR;
+           SPEC_SCLS (reType) = 0;
+           SPEC_USIGN (reType) = 0;
+           return rType;
+         }
+       break;
+      case RESULT_TYPE_INT:
+      case RESULT_TYPE_NONE:
+       if (IS_BIT (reType))
+         {
+           SPEC_NOUN (reType) = V_CHAR;
+           SPEC_SCLS (reType) = 0;
+           SPEC_USIGN (reType) = 0;
+           return rType;
+         }
+       else if (IS_BITFIELD (reType))
+         {
+           /* could be smarter, but it depends on the op */
+           /* this is for the worst case: a multiplication of 4 * 4 bit */
+           SPEC_NOUN (reType) = SPEC_BLEN (reType) <= 4 ? V_CHAR : V_INT;
+           SPEC_SCLS (reType) = 0;
+           SPEC_USIGN (reType) = 0;
+           return rType;
+         }
+       else if (IS_CHAR (reType))
+         {
+           if (op == '|' || op == '^')
+             return computeTypeOr (etype1, etype2, reType);
+           else if (   op == '&'
+                    && SPEC_USIGN (etype1) != SPEC_USIGN (etype2))
+             {
+               SPEC_USIGN (reType) = 1;
+               return rType;
+             }
+           else
+             {
+               SPEC_NOUN (reType) = V_INT;
+               SPEC_USIGN (reType) = 0;
+               return rType;
+             }
+         }
+       break;
+      default:
+       break;
+    }
 
   /* SDCC's sign promotion:
      - if one or both operands are unsigned, the resultant type will be unsigned
@@ -1638,7 +1784,7 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
      - if the result of an operation with two char's is promoted to a
        larger type, the result will be signed.
 
-     More sophisticated is the last one:
+     More sophisticated are these:
      - if the result of an operation with two char's is a char again,
        the result will only then be unsigned, if both operands are
        unsigned. In all other cases the result will be signed.
@@ -1653,6 +1799,8 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
        unsigned; this helps to avoid overflow:
                2 * 100 =  200;
 
+     - ToDo: document '|', '^' and '&'
+     
      Homework: - why is (200 * 200 < 0) true?
               - why is { char l = 200, r = 200; (r * l > 0) } true?
   */
@@ -1679,10 +1827,6 @@ computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt)
   else
     SPEC_USIGN (reType) = 0;
 
-  /* if result is a literal then make not so */
-  if (IS_LITERAL (reType))
-    SPEC_SCLS (reType) = S_REGISTER;
-
   return rType;
 }
 
index 49ed5eb8d743dd9be9c59f413e0ad99a3ae2e4ad..82acf79b6bab1546cf9fcf7e44a034597af80c15 100644 (file)
@@ -457,6 +457,8 @@ extern sym_link *validateLink(sym_link      *l,
 #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_BIT(x) (IS_SPEC(x) && (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))
 #define IS_AGGREGATE(x) (IS_ARRAY(x) || IS_STRUCT(x))
@@ -502,6 +504,18 @@ extern sym_link *floatType;
 
 #include "SDCCval.h"
 
+typedef enum
+{
+  RESULT_TYPE_NONE = 0,        /* operands will be promoted to int */
+  RESULT_CHECK = 0, /* TODO: replace all occurences with the appropriate type and remove me */
+  RESULT_TYPE_BIT,
+  RESULT_TYPE_CHAR,
+  RESULT_TYPE_INT,
+  RESULT_TYPE_OTHER,   /* operands will be promoted to int */
+  RESULT_TYPE_IFX,
+  RESULT_TYPE_NOPROM,  /* operands will be promoted to int */
+} RESULT_TYPE;
+
 /* forward definitions for the symbol table related functions */
 void initSymt ();
 symbol *newSymbol (char *, int);
@@ -541,7 +555,7 @@ int funcInChain (sym_link *);
 void addSymChain (symbol *);
 sym_link *structElemType (sym_link *, value *);
 symbol *getStructElement (structdef *, symbol *);
-sym_link *computeType (sym_link *, sym_link *, bool promoteCharToInt);
+sym_link *computeType (sym_link *, sym_link *, RESULT_TYPE, char);
 void processFuncArgs (symbol *);
 int isSymbolEqual (symbol *, symbol *);
 int powof2 (TYPE_UDWORD);
index c5f2556844b40d33f25b86e3421d3767784c5968..b2f8fe0e1b0cf4db8434243e7c9913409bb91067 100644 (file)
@@ -280,7 +280,7 @@ resolveIvalSym (initList * ilist, sym_link * type)
   if (ilist->type == INIT_NODE)
     {
       if (IS_PTR (type))
-        resultType = RESULT_TYPE_NONE;
+        resultType = RESULT_TYPE_INT;
       else
         resultType = getResultTypeFromType (getSpec (type));
       ilist->init.node = decorateType (resolveSymbols (ilist->init.node),
@@ -1086,7 +1086,8 @@ valMult (value * lval, value * rval)
   val = newValue ();
   val->type = val->etype = computeType (lval->etype,
                                        rval->etype,
-                                       TRUE);
+                                       RESULT_TYPE_INT,
+                                       '*');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
 
   if (IS_FLOAT (val->type))
@@ -1135,7 +1136,8 @@ valDiv (value * lval, value * rval)
   val = newValue ();
   val->type = val->etype = computeType (lval->etype,
                                        rval->etype,
-                                       TRUE);
+                                       RESULT_TYPE_INT,
+                                       '/');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
 
   if (IS_FLOAT (val->type))
@@ -1173,7 +1175,8 @@ valMod (value * lval, value * rval)
   val = newValue();
   val->type = val->etype = computeType (lval->etype,
                                        rval->etype,
-                                       TRUE);
+                                       RESULT_TYPE_INT,
+                                       '%');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
 
   if (SPEC_LONG (val->type))
@@ -1209,7 +1212,8 @@ valPlus (value * lval, value * rval)
   val = newValue();
   val->type = val->etype = computeType (lval->etype,
                                        rval->etype,
-                                       TRUE);
+                                       RESULT_TYPE_INT,
+                                       '+');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
   
   if (IS_FLOAT (val->type))
@@ -1247,7 +1251,8 @@ valMinus (value * lval, value * rval)
   val = newValue();
   val->type = val->etype = computeType (lval->etype,
                                        rval->etype,
-                                       TRUE);
+                                       RESULT_TYPE_INT,
+                                       '-');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
   
   if (IS_FLOAT (val->type))
@@ -1285,8 +1290,8 @@ valShift (value * lval, value * rval, int lr)
   val = newValue();
   val->type = val->etype = computeType (lval->etype,
                                        NULL,
-                                       /* promote left shift */
-                                       lr ? TRUE : FALSE);
+                                       RESULT_TYPE_INT,
+                                       'S');
   SPEC_SCLS (val->etype) = S_LITERAL; /* will remain literal */
 
   if (getSize (val->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) &&
@@ -1435,7 +1440,7 @@ valBitwise (value * lval, value * rval, int op)
 
   /* create a new value */
   val = newValue ();
-  val->type = computeType (lval->etype, rval->etype, FALSE);
+  val->type = computeType (lval->etype, rval->etype, RESULT_TYPE_CHAR, op);
   val->etype = getSpec (val->type);
   SPEC_SCLS (val->etype) = S_LITERAL;
 
@@ -1563,6 +1568,12 @@ valCastLiteral (sym_link * dtype, double fval)
 
   if (SPEC_NOUN (val->etype) == V_FLOAT)
       SPEC_CVAL (val->etype).v_float = fval;
+  else if (SPEC_NOUN (val->etype) == V_BIT ||
+           SPEC_NOUN (val->etype) == V_SBIT)
+    SPEC_CVAL (val->etype).v_uint = l & 1;   
+  else if (SPEC_NOUN (val->etype) == V_BITFIELD)
+    SPEC_CVAL (val->etype).v_uint = l &
+                                   (0xffffu >> (16 - SPEC_BLEN (val->etype)));
   else if (SPEC_NOUN (val->etype) == V_CHAR) {
       if (SPEC_USIGN (val->etype))
          SPEC_CVAL (val->etype).v_uint= (TYPE_UBYTE) l;
index a5fb515d3ffbebab1ae160bc0e1349476b2eb328..1dffcc0feadff7739eb2cfd6106fedc6f3d30824 100644 (file)
@@ -121,3 +121,51 @@ testMod(void)
    r16 = 0;
    cL = -128; ucR =    5; r16 =  cL % ucR; ASSERT(r16 == -3);
 }
+
+void
+testOr(void)
+{
+  {attrL}           char  cL;
+  {attrL}  unsigned char ucL;
+  {attrR}           char  cR;
+  {attrR}  unsigned char ucR;
+  volatile         short r16, r16b;
+
+   cL = 0x00;  cR = 0x80; r16 =  cL |  cR; r16b =  cR |  cL; ASSERT(r16 == (short) 0xff80); ASSERT(r16b == (short) 0xff80);
+  ucL = 0x80;  cR = 0x00; r16 = ucL |  cR; r16b =  cR | ucL; ASSERT(r16 ==           0x80); ASSERT(r16b ==           0x80);
+  ucL = 0x80; ucR = 0x80; r16 = ucL | ucR; r16b = ucR | ucL; ASSERT(r16 ==           0x80); ASSERT(r16b ==           0x80);
+}
+
+void
+testXor(void)
+{
+  {attrL}           char  cL;
+  {attrL}  unsigned char ucL;
+  {attrR}           char  cR;
+  {attrR}  unsigned char ucR;
+  volatile         short r16, r16b;
+
+   cL = 0x80;  cR = 0x80; r16 =  cL ^  cR; r16b =  cR ^  cL; ASSERT(r16 ==              0); ASSERT(r16b ==              0);
+   cL = 0x80;  cR = 0x00; r16 =  cL ^  cR; r16b =  cR ^  cL; ASSERT(r16 == (short) 0xff80); ASSERT(r16b == (short) 0xff80);
+
+  ucL = 0x80;  cR = 0x80; r16 = ucL ^  cR; r16b =  cR ^ ucL; ASSERT(r16 == (short) 0xff00); ASSERT(r16b == (short) 0xff00);
+  ucL = 0x80;  cR =    0; r16 = ucL ^  cR; r16b =  cR ^ ucL; ASSERT(r16 ==           0x80); ASSERT(r16b ==           0x80);
+  ucL =    0;  cR = 0x80; r16 = ucL ^  cR; r16b =  cR ^ ucL; ASSERT(r16 == (short) 0xff80); ASSERT(r16b == (short) 0xff80);
+
+  ucL = 0x80; ucR = 0x80; r16 = ucL ^ ucR; r16b = ucR ^ ucL; ASSERT(r16 ==      0); ASSERT(r16b ==      0);
+  ucL =    0; ucR = 0x80; r16 = ucL ^ ucR; r16b = ucR ^ ucL; ASSERT(r16 ==   0x80); ASSERT(r16b ==   0x80);
+}
+
+void
+testAnd(void)
+{
+  {attrL}           char  cL;
+  {attrL}  unsigned char ucL;
+  {attrR}           char  cR;
+  {attrR}  unsigned char ucR;
+  volatile         short r16, r16b;
+
+   cL = 0x80;  cR = 0x80; r16 =  cL &  cR; r16b =  cR &  cL; ASSERT(r16 == (short) 0xff80); ASSERT(r16b == (short) 0xff80);
+  ucL = 0x80;  cR = 0x80; r16 = ucL &  cR; r16b =  cR & ucL; ASSERT(r16 ==           0x80); ASSERT(r16b ==           0x80);
+  ucL = 0x80; ucR = 0x80; r16 = ucL & ucR; r16b = ucR & ucL; ASSERT(r16 ==           0x80); ASSERT(r16b ==           0x80);
+}