+ /* Determine the type of the operation. */
+ if (IsTypeChar (Expr->Type) && rconst) {
+
+ /* Left side is unsigned char, right side is constant.
+ * Determine the minimum and maximum values
+ */
+ int LeftMin, LeftMax;
+ if (LeftSigned) {
+ LeftMin = -128;
+ LeftMax = 127;
+ } else {
+ LeftMin = 0;
+ LeftMax = 255;
+ }
+ /* An integer value is always represented as a signed in the
+ * ExprDesc structure. This may lead to false results below,
+ * if it is actually unsigned, but interpreted as signed
+ * because of the representation. Fortunately, in this case,
+ * the actual value doesn't matter, since it's always greater
+ * than what can be represented in a char. So correct the
+ * value accordingly.
+ */
+ if (!RightSigned && Expr2.IVal < 0) {
+ /* Correct the value so it is an unsigned. It will then
+ * anyway match one of the cases below.
+ */
+ Expr2.IVal = LeftMax + 1;
+ }
+
+ /* Comparing a char against a constant may have a constant
+ * result.
+ */
+ switch (Tok) {
+
+ case TOK_EQ:
+ if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) {
+ ED_MakeConstAbsInt (Expr, 0);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ case TOK_NE:
+ if (Expr2.IVal < LeftMin || Expr2.IVal > LeftMax) {
+ ED_MakeConstAbsInt (Expr, 1);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ case TOK_LT:
+ if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) {
+ ED_MakeConstAbsInt (Expr, Expr2.IVal > LeftMax);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ case TOK_LE:
+ if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) {
+ ED_MakeConstAbsInt (Expr, Expr2.IVal >= LeftMax);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ case TOK_GE:
+ if (Expr2.IVal <= LeftMin || Expr2.IVal > LeftMax) {
+ ED_MakeConstAbsInt (Expr, Expr2.IVal <= LeftMin);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ case TOK_GT:
+ if (Expr2.IVal < LeftMin || Expr2.IVal >= LeftMax) {
+ ED_MakeConstAbsInt (Expr, Expr2.IVal < LeftMin);
+ WarnConstCompareResult ();
+ RemoveCode (&Mark0);
+ goto Done;
+ }
+ break;
+
+ default:
+ Internal ("hie_compare: got token 0x%X\n", Tok);
+ }
+
+ /* If the result is not already constant (as evaluated in the
+ * switch above), we can execute the operation as a char op,
+ * since the right side constant is in a valid range.
+ */
+ flags |= (CF_CHAR | CF_FORCECHAR);
+ if (!LeftSigned) {
+ flags |= CF_UNSIGNED;
+ }
+
+ } else if (IsTypeChar (Expr->Type) && IsTypeChar (Expr2.Type) &&
+ GetSignedness (Expr->Type) == GetSignedness (Expr2.Type)) {
+
+ /* Both are chars with the same signedness. We can encode the
+ * operation as a char operation.
+ */
+ flags |= CF_CHAR;
+ if (rconst) {
+ flags |= CF_FORCECHAR;
+ }
+ if (!LeftSigned) {
+ flags |= CF_UNSIGNED;
+ }