changeset 376:35d4213e6657

Add cycle counting to listing Add option to include instruction cycle counts to the listing. Thanks to Erik G <erik@6809.org> for the patch.
author William Astle <lost@l-w.ca>
date Mon, 13 Jul 2015 20:47:30 -0600
parents 71f507f404f1
children 67373a053c49
files Makefile lwasm/insn_gen.c lwasm/insn_indexed.c lwasm/insn_inh.c lwasm/insn_rel.c lwasm/insn_rlist.c lwasm/list.c lwasm/lwasm.c lwasm/lwasm.h lwasm/pragma.c win/lwasm.vcxproj
diffstat 11 files changed, 112 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Mon Jul 13 20:35:16 2015 -0600
+++ b/Makefile	Mon Jul 13 20:47:30 2015 -0600
@@ -52,7 +52,7 @@
 lwlink_srcs := $(addprefix lwlink/,$(lwlink_srcs))
 lwobjdump_srcs := $(addprefix lwlink/,$(lwobjdump_srcs))
 
-lwasm_srcs :=  debug.c input.c insn_bitbit.c insn_gen.c insn_indexed.c \
+lwasm_srcs := cycle.c debug.c input.c insn_bitbit.c insn_gen.c insn_indexed.c \
 	insn_inh.c insn_logicmem.c insn_rel.c insn_rlist.c insn_rtor.c insn_tfm.c \
 	instab.c list.c lwasm.c macro.c main.c os9.c output.c pass1.c pass2.c \
 	pass3.c pass4.c pass5.c pass6.c pass7.c pragma.c pseudo.c section.c \
--- a/lwasm/insn_gen.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/insn_gen.c	Mon Jul 13 20:47:30 2015 -0600
@@ -280,6 +280,8 @@
 			}
 			lwasm_emitexpr(l, e, l -> lint);
 		}
+
+		l -> cycle_adj = lwasm_cycle_calc_ind(l);
 		return;
 	}
 	
--- a/lwasm/insn_indexed.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/insn_indexed.c	Mon Jul 13 20:47:30 2015 -0600
@@ -594,6 +594,9 @@
 	
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	lwasm_emitop(l, l -> pb);
+
+	l -> cycle_adj = lwasm_cycle_calc_ind(l);
+
 	if (l -> lint > 0)
 	{
 		e = lwasm_fetch_expr(l, 0);
--- a/lwasm/insn_inh.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/insn_inh.c	Mon Jul 13 20:47:30 2015 -0600
@@ -47,4 +47,6 @@
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	if (instab[l -> insn].ops[1] >= 0)
 		lwasm_emitop(l, instab[l -> insn].ops[1]);
+
+	l -> cycle_adj = instab[l -> insn].ops[3];
 }
--- a/lwasm/insn_rel.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/insn_rel.c	Mon Jul 13 20:47:30 2015 -0600
@@ -232,14 +232,17 @@
 			lwasm_register_error(as, l, E_BYTE_OVERFLOW);
 			return;
 		}
-	
 
 		lwasm_emitop(l, instab[l -> insn].ops[2]);
 		lwasm_emit(l, offs);
+
+		l -> cycle_adj = 2;
 	}
 	else
 	{
 		lwasm_emitop(l, instab[l -> insn].ops[3]);
 		lwasm_emitexpr(l, e, 2);
+
+		l->cycle_adj = 4;
 	}
 }
--- a/lwasm/insn_rlist.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/insn_rlist.c	Mon Jul 13 20:47:30 2015 -0600
@@ -82,4 +82,6 @@
 {
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	lwasm_emit(l, l -> pb);
+
+	l -> cycle_adj = lwasm_cycle_calc_rlist(l);
 }
--- a/lwasm/list.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/list.c	Mon Jul 13 20:47:30 2015 -0600
@@ -66,7 +66,6 @@
 	for (cl = as -> line_head; cl; cl = nl)
 	{
 		char *linespec;
-		int linespec_len;
 
 		nl = cl -> next;
 		if (CURPRAGMA(cl, PRAGMA_NOLIST))
@@ -194,15 +193,67 @@
 			}
 			fprintf(of, " ");
 		}
-		/* the 32.32 below is deliberately chosen so that the start of the line text is at
-		   a multiple of 8 from the start of the list line */
-		linespec = cl -> linespec;
-		linespec_len = strlen(linespec);
-		if (linespec_len > 32)
+
+		/* the format specifier below is deliberately chosen so that the start of the line text is at
+		a multiple of 8 from the start of the list line */
+
+		#define max_linespec_len 17
+
+		// trim "include:" if it appears
+		linespec = cl -> linespec;
+		if ((strlen(linespec) > 8) && (linespec[7] == ':')) linespec += 8;
+		while (*linespec == ' ') linespec++;
+
+		fprintf(of, "(%*.*s):%05d ", max_linespec_len, max_linespec_len, linespec, cl->lineno);
+
+		if (CURPRAGMA(cl, PRAGMA_CC))
+		{
+			as->cycle_total = 0;
+		}
+
+		/* display cycle counts */
+		char s[64] = "";
+		if (CURPRAGMA(cl, PRAGMA_C) || CURPRAGMA(cl, PRAGMA_CD))
 		{
-			linespec += linespec_len - 32;
+			if (cl->cycle_base != 0)
+			{
+				char ch = '(';
+				if (CURPRAGMA(cl, PRAGMA_6809)) ch = '[';
+
+				if (CURPRAGMA(cl, PRAGMA_CD) && cl->cycle_flags & CYCLE_ADJ)
+				{
+					sprintf(s, "%c%d+%d", ch, cl->cycle_base, cl->cycle_adj);	/* detailed cycle count */
+				}
+				else
+				{
+					sprintf(s, "%c%d", ch, cl->cycle_base + cl->cycle_adj);   /* normal cycle count*/
+				}
+
+				if (cl->cycle_flags & CYCLE_ESTIMATED)
+					strcat(s, "+?");
+
+				as->cycle_total += cl->cycle_base + cl->cycle_adj;
+
+				ch = ')';
+				if (CURPRAGMA(cl, PRAGMA_6809)) ch = ']';
+				sprintf(s, "%s%c", s, ch);
+			}
 		}
-		fprintf(of, "(%32.32s):%05d ", linespec, cl -> lineno);
+
+		fprintf(of, "%-8s", s);
+
+		if (CURPRAGMA(cl, PRAGMA_CT)) 
+		{
+			if (cl->cycle_base != 0)
+			{
+				fprintf(of, "%-8d", as->cycle_total);
+			}
+			else
+			{
+				fprintf(of, "        ");
+			}
+		}
+
 		i = 0;
 		for (tc = cl -> ltext; *tc; tc++)
 		{
--- a/lwasm/lwasm.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/lwasm.c	Mon Jul 13 20:47:30 2015 -0600
@@ -456,6 +456,9 @@
 
 void lwasm_emitop(line_t *cl, int opc)
 {
+	if (cl->cycle_base == 0)
+		lwasm_cycle_update_count(cl, opc);	/* only call first time, never on postbyte */
+
 	if (opc > 0x100)
 		lwasm_emit(cl, opc >> 8);
 	lwasm_emit(cl, opc);
--- a/lwasm/lwasm.h	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/lwasm.h	Mon Jul 13 20:47:30 2015 -0600
@@ -93,7 +93,11 @@
 	PRAGMA_6800COMPAT			= 1 << 12,	// enable 6800 compatibility opcodes
 	PRAGMA_FORWARDREFMAX		= 1 << 13,	// force incomplete references on pass 1 to maximum mode
 	PRAGMA_6809					= 1 << 14,	// 6809/6309 assembly mode
-	PRAGMA_TESTMODE				= 1 << 15	// enable test mode (for internal unit testing)
+	PRAGMA_TESTMODE				= 1 << 15,	// enable test mode (for internal unit testing)
+	PRAGMA_C					= 1 << 16,	// enable cycle counts
+	PRAGMA_CD					= 1 << 17,	// enable detailed cycle count
+	PRAGMA_CT					= 1 << 18,	// enable cycle count running total
+	PRAGMA_CC					= 1 << 19	// clear cycle count running total
 };
 
 enum
@@ -232,6 +236,12 @@
 	importlist_t *next;					// next in the import list
 };
 
+typedef enum
+{
+	CYCLE_ADJ = 1,
+	CYCLE_ESTIMATED = 2
+} cycle_flags;
+
 struct line_s
 {
 	lw_expr_t addr;						// assembly address of the line
@@ -247,6 +257,9 @@
 	int outputl;						// size of output
 	int outputbl;						// size of output buffer
 	int dpval;							// direct page value
+	int cycle_base;						// base instruction cycle count
+	int cycle_adj;						// cycle adjustment
+	int	cycle_flags;					// cycle flags
 	lwasm_error_t *err;					// list of errors
 	lwasm_error_t *warn;				// list of errors
 	lwasm_errorcode_t err_testmode;		// error code in testmode
@@ -360,6 +373,7 @@
 	int undefzero;						// used for handling "condundefzero"
 	int pretendmax;						// set if we need to pretend the instruction is max length
 	unsigned char crc[3];				// crc accumulator
+	int cycle_total;					// cycle count accumulator
 	int badsymerr;						// throw error on undef sym if set
 
 	line_t *line_head;					// start of lines list
@@ -399,6 +413,10 @@
 struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags);
 struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym);
 
+int lwasm_cycle_calc_ind(line_t *cl);
+int lwasm_cycle_calc_rlist(line_t *cl);
+void lwasm_cycle_update_count(line_t *cl, int opc);
+
 void lwasm_parse_testmode_comment(line_t *cl, lwasm_testflags_t *flags, lwasm_errorcode_t *err, int *len, char **buf);
 void lwasm_error_testmode(line_t *cl, const char* msg, int fatal);
 
--- a/lwasm/pragma.c	Mon Jul 13 20:35:16 2015 -0600
+++ b/lwasm/pragma.c	Mon Jul 13 20:47:30 2015 -0600
@@ -64,7 +64,11 @@
 	{ "6800compat", "no6800compat", PRAGMA_6800COMPAT },
 	{ "forwardrefmax", "noforwardrefmax", PRAGMA_FORWARDREFMAX },
 	{ "testmode", "notestmode", PRAGMA_TESTMODE },
-	{ 0, 0, 0}
+	{ "c", "noc", PRAGMA_C },
+	{ "cc", "nocc", PRAGMA_CC },
+	{ "cd", "nocd", PRAGMA_CD },
+	{ "ct", "noct", PRAGMA_CT },
+	{ 0, 0, 0 }
 };
 
 int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr)
@@ -141,6 +145,11 @@
 	parse_pragma_string(as, ps, 1);
 	if (as -> pragmas & PRAGMA_NOLIST)
 		l -> pragmas |= PRAGMA_NOLIST;
+	if (as->pragmas & PRAGMA_CC)
+	{
+		l->pragmas |= PRAGMA_CC;
+		as->pragmas &= ~PRAGMA_CC;
+	}
 	lw_free(ps);
 }
 
--- a/win/lwasm.vcxproj	Mon Jul 13 20:35:16 2015 -0600
+++ b/win/lwasm.vcxproj	Mon Jul 13 20:47:30 2015 -0600
@@ -8,12 +8,13 @@
     <ProjectConfiguration Include="Release|Win32">
       <Configuration>Release</Configuration>
       <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\lwasm\debug.c" />
-    <ClCompile Include="..\lwasm\input.c" />
-    <ClCompile Include="..\lwasm\insn_bitbit.c" />
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwasm\cycle.c" />
+    <ClCompile Include="..\lwasm\debug.c" />
+    <ClCompile Include="..\lwasm\input.c" />
+    <ClCompile Include="..\lwasm\insn_bitbit.c" />
     <ClCompile Include="..\lwasm\insn_gen.c" />
     <ClCompile Include="..\lwasm\insn_indexed.c" />
     <ClCompile Include="..\lwasm\insn_inh.c" />