diff --git a/src/cc65/expr.c b/src/cc65/expr.c index 34cf550a2..e87b02ffc 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -1534,26 +1534,35 @@ static void PostInc (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Push the address if needed */ - PushAddr (Expr); + /* Emit smaller code if a char variable is at a constant location */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + LoadExpr (CF_NONE, Expr); + AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0)); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Push the address if needed */ + PushAddr (Expr); + + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_inc (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_inc (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); } - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); - /* The result is always an expression, no reference */ ED_MakeRValExpr (Expr); } @@ -1581,26 +1590,35 @@ static void PostDec (ExprDesc* Expr) /* Get the data type */ Flags = TypeOf (Expr->Type); - /* Push the address if needed */ - PushAddr (Expr); + /* Emit smaller code if a char variable is at a constant location */ + if ((Flags & CF_CHAR) == CF_CHAR && ED_IsLocConst(Expr)) { - /* Fetch the value and save it (since it's the result of the expression) */ - LoadExpr (CF_NONE, Expr); - g_save (Flags | CF_FORCECHAR); + LoadExpr (CF_NONE, Expr); + AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0)); - /* If we have a pointer expression, increment by the size of the type */ - if (IsTypePtr (Expr->Type)) { - g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); } else { - g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + + /* Push the address if needed */ + PushAddr (Expr); + + /* Fetch the value and save it (since it's the result of the expression) */ + LoadExpr (CF_NONE, Expr); + g_save (Flags | CF_FORCECHAR); + + /* If we have a pointer expression, increment by the size of the type */ + if (IsTypePtr (Expr->Type)) { + g_dec (Flags | CF_CONST | CF_FORCECHAR, CheckedSizeOf (Expr->Type + 1)); + } else { + g_dec (Flags | CF_CONST | CF_FORCECHAR, 1); + } + + /* Store the result back */ + Store (Expr, 0); + + /* Restore the original value in the primary register */ + g_restore (Flags | CF_FORCECHAR); } - /* Store the result back */ - Store (Expr, 0); - - /* Restore the original value in the primary register */ - g_restore (Flags | CF_FORCECHAR); - /* The result is always an expression, no reference */ ED_MakeRValExpr (Expr); } diff --git a/test/val/postincdec.c b/test/val/postincdec.c new file mode 100644 index 000000000..6d3e9593c --- /dev/null +++ b/test/val/postincdec.c @@ -0,0 +1,23 @@ +/* + !!DESCRIPTION!! char-sized post-increment and -decrement + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + + +static unsigned char val, array[2]; + +int main() { + + val = 0; + array[0] = array[1] = 10; + + array[val++] = 2; + array[val++] = 2; + --val; + array[val--] = 0; + array[val--] = 0; + + return (array[0] == array[1] && array[0] == 0 && val == 0xff) ? 0 : 1; +}