+ reType->select.s.b_signed = 0;
+
+ /* 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:
+ case RESULT_TYPE_OTHER:
+ 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 if (op == '*')
+ {
+ SPEC_NOUN (reType) = V_INT;
+ SPEC_USIGN (reType) = 0;
+ return rType;
+ }
+ /* TODO: should be in SDCCast.c */
+ else if ( op == '/'
+ && ( !SPEC_USIGN (etype1)
+ || !SPEC_USIGN (etype2)))
+ {
+ 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
+ (except char, see below)
+ - if an operand is promoted to a larger type (char -> int, int -> long),
+ the larger type will be signed
+
+ SDCC tries hard to avoid promotion to int and does 8 bit calculation as
+ much as possible. We're leaving ISO IEC 9899 here and have to extrapolate
+ the standard. The standard demands, that the result has to be the same
+ "as if" the promotion would have been performed:
+
+ - if the result of an operation with two char's is promoted to a
+ larger type, the result will be signed.
+
+ 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.
+
+ This seems to be contradictionary to the first two rules, but it makes
+ real sense (all types are char's):