Merge pull request #425 from clbr/arrayaccess
Add fast paths for char postinc/dec
This commit is contained in:
@@ -1534,26 +1534,35 @@ static void PostInc (ExprDesc* Expr)
|
|||||||
/* Get the data type */
|
/* Get the data type */
|
||||||
Flags = TypeOf (Expr->Type);
|
Flags = TypeOf (Expr->Type);
|
||||||
|
|
||||||
/* Push the address if needed */
|
/* Emit smaller code if a char variable is at a constant location */
|
||||||
PushAddr (Expr);
|
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);
|
||||||
LoadExpr (CF_NONE, Expr);
|
AddCodeLine ("inc %s", ED_GetLabelName(Expr, 0));
|
||||||
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 {
|
} 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 */
|
/* The result is always an expression, no reference */
|
||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
}
|
}
|
||||||
@@ -1581,26 +1590,35 @@ static void PostDec (ExprDesc* Expr)
|
|||||||
/* Get the data type */
|
/* Get the data type */
|
||||||
Flags = TypeOf (Expr->Type);
|
Flags = TypeOf (Expr->Type);
|
||||||
|
|
||||||
/* Push the address if needed */
|
/* Emit smaller code if a char variable is at a constant location */
|
||||||
PushAddr (Expr);
|
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);
|
||||||
LoadExpr (CF_NONE, Expr);
|
AddCodeLine ("dec %s", ED_GetLabelName(Expr, 0));
|
||||||
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 {
|
} 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 */
|
/* The result is always an expression, no reference */
|
||||||
ED_MakeRValExpr (Expr);
|
ED_MakeRValExpr (Expr);
|
||||||
}
|
}
|
||||||
|
|||||||
23
test/val/postincdec.c
Normal file
23
test/val/postincdec.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user