diff --git a/src/cc65.vcxproj b/src/cc65.vcxproj
index 7e2e8ea8c..556c616b0 100644
--- a/src/cc65.vcxproj
+++ b/src/cc65.vcxproj
@@ -110,6 +110,7 @@
+
@@ -190,6 +191,7 @@
+
diff --git a/src/cc65/expr.c b/src/cc65/expr.c
index 37af494b5..61a24329f 100644
--- a/src/cc65/expr.c
+++ b/src/cc65/expr.c
@@ -31,6 +31,7 @@
#include "macrotab.h"
#include "preproc.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "shiftexpr.h"
#include "stackptr.h"
#include "standard.h"
@@ -677,6 +678,7 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr)
int I;
unsigned Size = 0;
int Count = GetDeferredOpCount ();
+ unsigned StmtFlags = GetSQPFlags ();
/* Nothing to be done */
if (Count <= 0) {
@@ -684,26 +686,38 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr)
}
/* Backup some regs/processor flags around the inc/dec */
- if ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr)) {
+ if ((StmtFlags & SQP_KEEP_TEST) != 0 ||
+ ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr))) {
/* Sufficient to add a pair of PHP/PLP for all cases */
AddCodeLine ("php");
}
- /* Backup the content of EAX around the inc/dec */
- if ((Flags & SQP_KEEP_EAX) != 0 && ED_NeedsPrimary (Expr)) {
- /* Get the size */
- Size = CheckedSizeOf (Expr->Type);
+ if ((Flags & SQP_MASK_EAX) != 0 && ED_NeedsPrimary (Expr)) {
+ Size = SizeOf (Expr->Type);
+ }
- if (Size < 2) {
- AddCodeLine ("pha");
- } else if (Size < 3) {
- AddCodeLine ("sta regsave");
- AddCodeLine ("stx regsave+1");
- } else {
- AddCodeLine ("jsr saveeax");
+ /* Get the size of the backup */
+ if ((StmtFlags & SQP_MASK_EAX) != 0) {
+ switch (StmtFlags & SQP_MASK_EAX) {
+ case SQP_KEEP_A: if (Size < 1) Size = 1; break;
+ case SQP_KEEP_AX: if (Size < 2) Size = 2; break;
+ case SQP_KEEP_EAX: if (Size < 4) Size = 4; break;
+ default: ;
}
}
+ /* Backup the content of EAX around the inc/dec */
+ if (Size == 1) {
+ AddCodeLine ("pha");
+ } else if (Size == 2) {
+ AddCodeLine ("sta regsave");
+ AddCodeLine ("stx regsave+1");
+ } else if (Size == 3 || Size == 4) {
+ AddCodeLine("jsr saveeax");
+ } else if (Size > 4) {
+ Error ("Unsupported deferred operand size: %u", Size);
+ }
+
for (I = 0; I < Count; ++I) {
DeferredOp* Op = CollAtUnchecked (&DeferredOps, I);
switch (Op->OpType) {
@@ -721,19 +735,18 @@ void DoDeferred (unsigned Flags, ExprDesc* Expr)
CollDeleteAll (&DeferredOps);
/* Restore the content of EAX around the inc/dec */
- if ((Flags & SQP_KEEP_EAX) != 0 && ED_NeedsPrimary (Expr)) {
- if (Size < 2) {
- AddCodeLine ("pla");
- } else if (Size < 3) {
- AddCodeLine ("lda regsave");
- AddCodeLine ("ldx regsave+1");
- } else {
- AddCodeLine ("jsr resteax");
- }
+ if (Size == 1) {
+ AddCodeLine ("pla");
+ } else if (Size == 2) {
+ AddCodeLine ("lda regsave");
+ AddCodeLine ("ldx regsave+1");
+ } else if (Size == 3 || Size == 4) {
+ AddCodeLine ("jsr resteax");
}
/* Restore the regs/processor flags around the inc/dec */
- if ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr)) {
+ if ((StmtFlags & SQP_KEEP_TEST) != 0 ||
+ ((Flags & SQP_KEEP_TEST) != 0 && ED_NeedsTest (Expr))) {
/* Sufficient to pop the processor flags */
AddCodeLine ("plp");
}
@@ -1362,6 +1375,7 @@ static void Primary (ExprDesc* E)
case TOK_A:
/* Register pseudo variable */
+ SetSQPFlags (SQP_KEEP_A);
E->Type = type_uchar;
E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
NextToken ();
@@ -1369,6 +1383,7 @@ static void Primary (ExprDesc* E)
case TOK_AX:
/* Register pseudo variable */
+ SetSQPFlags (SQP_KEEP_AX);
E->Type = type_uint;
E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
NextToken ();
@@ -1376,6 +1391,7 @@ static void Primary (ExprDesc* E)
case TOK_EAX:
/* Register pseudo variable */
+ SetSQPFlags (SQP_KEEP_EAX);
E->Type = type_ulong;
E->Flags = E_LOC_PRIMARY | E_RTYPE_LVAL;
NextToken ();
diff --git a/src/cc65/expr.h b/src/cc65/expr.h
index 5644fb82d..8bf7c00b5 100644
--- a/src/cc65/expr.h
+++ b/src/cc65/expr.h
@@ -23,11 +23,6 @@
-#define SQP_KEEP_NONE 0x00
-#define SQP_KEEP_TEST 0x01U
-#define SQP_KEEP_EAX 0x02U
-#define SQP_KEEP_EXPR 0x03U /* SQP_KEEP_TEST | SQP_KEEP_EAX */
-
/* Generator attributes */
#define GEN_NOPUSH 0x01 /* Don't push lhs */
#define GEN_COMM 0x02 /* Operator is commutative */
diff --git a/src/cc65/goto.c b/src/cc65/goto.c
index 7d3ff1a6a..44ae0595e 100644
--- a/src/cc65/goto.c
+++ b/src/cc65/goto.c
@@ -43,6 +43,7 @@
#include "expr.h"
#include "loadexpr.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "standard.h"
#include "symtab.h"
#include "goto.h"
diff --git a/src/cc65/initdata.c b/src/cc65/initdata.c
index f63e9e95c..f576c0255 100644
--- a/src/cc65/initdata.c
+++ b/src/cc65/initdata.c
@@ -58,6 +58,7 @@
#include "litpool.h"
#include "pragma.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "shift.h"
#include "standard.h"
#include "symtab.h"
diff --git a/src/cc65/locals.c b/src/cc65/locals.c
index 68ac00e62..7bc5697ff 100644
--- a/src/cc65/locals.c
+++ b/src/cc65/locals.c
@@ -49,6 +49,7 @@
#include "initdata.h"
#include "loadexpr.h"
#include "locals.h"
+#include "seqpoint.h"
#include "stackptr.h"
#include "standard.h"
#include "staticassert.h"
diff --git a/src/cc65/seqpoint.c b/src/cc65/seqpoint.c
new file mode 100644
index 000000000..a6d992113
--- /dev/null
+++ b/src/cc65/seqpoint.c
@@ -0,0 +1,67 @@
+/*****************************************************************************/
+/* */
+/* seqpoint.h */
+/* */
+/* Stuff involved in sequence points */
+/* */
+/* */
+/* */
+/* Copyright 2022 The cc65 Authors */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* cc65 */
+#include "seqpoint.h"
+
+
+
+/*****************************************************************************/
+/* data */
+/*****************************************************************************/
+
+
+
+/* Remeber if __A__, __AX__ and __EAX__ are being used */
+unsigned PendingSqpFlags = SQP_KEEP_NONE;
+
+
+
+/*****************************************************************************/
+/* code */
+/*****************************************************************************/
+
+
+
+void SetSQPFlags (unsigned Flags)
+/* Set the SQP_KEEP_* flags for the deferred operations in the statement */
+{
+ PendingSqpFlags = Flags;
+}
+
+
+
+unsigned GetSQPFlags (void)
+/* Get the SQP_KEEP_* flags for the deferred operations in the statement */
+{
+ return PendingSqpFlags;
+}
diff --git a/src/cc65/seqpoint.h b/src/cc65/seqpoint.h
new file mode 100644
index 000000000..07ff0d315
--- /dev/null
+++ b/src/cc65/seqpoint.h
@@ -0,0 +1,70 @@
+/*****************************************************************************/
+/* */
+/* seqpoint.h */
+/* */
+/* Stuff involved in sequence points */
+/* */
+/* */
+/* */
+/* Copyright 2022 The cc65 Authors */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef SEQPOINT_H
+#define SEQPOINT_H
+
+
+
+/*****************************************************************************/
+/* data */
+/*****************************************************************************/
+
+
+
+#define SQP_KEEP_NONE 0x00U
+#define SQP_KEEP_A 0x01U
+#define SQP_KEEP_AX 0x03U
+#define SQP_KEEP_EAX 0x07U
+#define SQP_MASK_EAX 0x07U
+#define SQP_KEEP_TEST 0x10U
+#define SQP_KEEP_EXPR 0x17U /* SQP_KEEP_TEST | SQP_KEEP_EAX */
+
+
+
+/*****************************************************************************/
+/* code */
+/*****************************************************************************/
+
+
+
+void SetSQPFlags (unsigned Flags);
+/* Set the SQP_KEEP_* flags for the deferred operations in the statement */
+
+unsigned GetSQPFlags (void);
+/* Get the SQP_KEEP_* flags for the deferred operations in the statement */
+
+
+
+/* End of seqpoint.h */
+
+#endif
diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c
index d22c73dcf..e968aaf1f 100644
--- a/src/cc65/stdfunc.c
+++ b/src/cc65/stdfunc.c
@@ -50,6 +50,7 @@
#include "litpool.h"
#include "loadexpr.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "stackptr.h"
#include "stdfunc.h"
#include "stdnames.h"
diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c
index 7355e88a8..613129e1b 100644
--- a/src/cc65/stmt.c
+++ b/src/cc65/stmt.c
@@ -56,6 +56,7 @@
#include "loop.h"
#include "pragma.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "stackptr.h"
#include "stmt.h"
#include "swstmt.h"
@@ -674,6 +675,8 @@ int AnyStatement (int* PendingToken)
** NULL, the function will skip the token.
*/
{
+ int GotBreak = 0;
+
/* Assume no pending token */
if (PendingToken) {
*PendingToken = 0;
@@ -689,7 +692,8 @@ int AnyStatement (int* PendingToken)
switch (CurTok.Tok) {
case TOK_IF:
- return IfStatement ();
+ GotBreak = IfStatement ();
+ break;
case TOK_SWITCH:
SwitchStatement ();
@@ -710,22 +714,26 @@ int AnyStatement (int* PendingToken)
case TOK_GOTO:
GotoStatement ();
CheckSemi (PendingToken);
- return 1;
+ GotBreak = 1;
+ break;
case TOK_RETURN:
ReturnStatement ();
CheckSemi (PendingToken);
- return 1;
+ GotBreak = 1;
+ break;
case TOK_BREAK:
BreakStatement ();
CheckSemi (PendingToken);
- return 1;
+ GotBreak = 1;
+ break;
case TOK_CONTINUE:
ContinueStatement ();
CheckSemi (PendingToken);
- return 1;
+ GotBreak = 1;
+ break;
case TOK_PRAGMA:
DoPragma ();
@@ -737,12 +745,17 @@ int AnyStatement (int* PendingToken)
break;
case TOK_LCURLY:
- return CompoundStatement (PendingToken);
+ GotBreak = CompoundStatement (PendingToken);
+ break;
default:
/* Simple statement */
Statement (PendingToken);
break;
}
- return 0;
+
+ /* Reset SQP flags */
+ SetSQPFlags (SQP_KEEP_NONE);
+
+ return GotBreak;
}
diff --git a/src/cc65/testexpr.c b/src/cc65/testexpr.c
index bad8b95f1..14160f13f 100644
--- a/src/cc65/testexpr.c
+++ b/src/cc65/testexpr.c
@@ -39,6 +39,7 @@
#include "expr.h"
#include "loadexpr.h"
#include "scanner.h"
+#include "seqpoint.h"
#include "testexpr.h"
diff --git a/test/todo/inline-asm-1489.c b/test/val/inline-asm-1489.c
similarity index 83%
rename from test/todo/inline-asm-1489.c
rename to test/val/inline-asm-1489.c
index 57699ab0a..a531c7405 100644
--- a/test/todo/inline-asm-1489.c
+++ b/test/val/inline-asm-1489.c
@@ -1,9 +1,11 @@
+#include
#include
#include
#include
#include
+#ifdef __CC65__
#define testasm1(C) (__AX__ = (C), \
asm("and #$3f"),\
__AX__)
@@ -11,6 +13,22 @@
#define testasm2(C) (__A__ = (C), \
asm("and #$3f"),\
__A__)
+#else
+/* Non-cc65 compiler. Just make the code compile and work. */
+uint16_t testasm1(uint16_t C)
+{
+ uint16_t AX = C;
+ AX &= 0x3f;
+ return AX;
+}
+
+uint8_t testasm2(uint8_t C)
+{
+ uint8_t A = C;
+ A &= 0x3f;
+ return A;
+}
+#endif
uint8_t src[32] = { 0x10, 0x41, 0x62, 0x83, 0xb4, 0xf5, 0xe6, 0xc7, 0, 0 };
uint8_t src2[32] = { 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0, 0 };
@@ -46,7 +64,7 @@ void dotest1b(uint8_t *s, uint8_t *d)
void dotest2a (void)
{
char *p = &src2[0];
- uint16_t scaddr=&dest[0]; //output to line 11 on the screen
+ uintptr_t scaddr=&dest[0]; //output to line 11 on the screen
printf("dotest2a\n");
while (*p != 0) {
@@ -58,7 +76,7 @@ void dotest2a (void)
void dotest2b (void)
{
char *p = &src2[0];
- uint16_t scaddr=&dest[0]; //output to line 11 on the screen
+ uintptr_t scaddr=&dest[0]; //output to line 11 on the screen
printf("dotest2b\n");
while (*p != 0) {