Suggestion to improve readability

Juergen Buchmueller pullmoll at
Sun Jun 3 22:08:35 PDT 2007

According to the docs section 3.4, page 30, the multiplexer and 16 way
dispatcher for IR is instrumented like this (with my comments in

  if     IR[0] = 1     then 3-IR[8-9]	complement of SH field of IR
  elseif IR[1-2] = 0   then IR[3-4]	JMP, JSR, ISZ, DSZ
  elseif IR[1-2] = 1   then 4		LDA
  elseif IR[1-2] = 2   then 5		STA
  elseif IR[4-7] = 0   then 1		(this is CYCLE)
  elseif IR[4-7] = 1   then 0		(this is JSRII)
  elseif IR[4-7] = 6   then 16B		CONVERT (buggy comment!)
  elseif IR[4-7] = 16B then 6		(_this_ is CONVERT)
  else			    IR[4-7]	(remaining opcodes & TRAPS)

Note that IR[4-7] = x just means ((x & 017) << 010), so we'd have:
  0 << 010 = 0	   which is the CYCLE opcode (0060000)
 01 << 010 = 00400 which is the JSRII opcode (0064400)
 06 << 010 = 03000 which seems to be unused masks (TRAPS)
016 << 010 = 07000 which is the CONVERT opcode (067000)

I'd suggest to translate all this confusing stuff to C with the help of some
simplifying macros:

#define IR_MASK(from,to) \
	(ir & ((1<<(to+1-from))-1)<<(15-to))
#define	IR_EQU(from,to,val) \
	((ir & ((1<<(to+1-from))-1)<<(15-to)) == (val<<(15-to)))
#define	IR_GET(from,to) \
	((ir & ((1<<(to+1-from))-1))>>(15-to))

You'd of course have to add some more parenthesis around from, to, and
val, if they could be computed values. Here I assumed they are just
plain numbers.

Then you could, for a function like f2_fn_idisp_late(), have really nice
looking code, closely matching what the docs say:

  if (IR_MASK(0,0))
    bval = 3 - IR_GET(8,9);	/* complement of SH */
  else if (IR_EQU(1,2,0)) {
    bval = IR_GET(3,4);		/* jump group: JMP, JSR, ISZ, DSZ */
  else if (IR_EQU(1,2,1))
    bval = 4;			/* LDA */
  else if (IR_EQU(1,2,2))
    bval = 5;			/* STA */
  else if (IR_EQU(4,7,0))
    bval = 1;			/* CYCLE */
  else if (IR_EQU(4,7,1))
    bval = 0;			/* JSRII */
  else if (IR_EQU(4,7,6))
    bval = 016;			/* TRAPS */
  else if (IR_EQU(4,7,016))
    bval = 6;			/* CONVERT */
    bval = IR_GET(4,7);		/* others and TRAPS */

It might even make sense to use this type of macros all over the place to
mask, compare, and extract bit fields from the general "reverse" notation
that the Alto docs have. It seems to be just too easy to introduce bugs
when counting and flipping the bits manually. This is a re-appearing
problem ;-P

We could have some generalized macros ALTO_MASK(reg,from,to),
ALTO_EQU(reg,from,to,val), and ALTO_GET(reg,from,to).

And we could even define the standard "reg,from,to" fields as macros:
#define	IR_ARITHGRP	ir,0,0
#define	IR_SRCAC	ir,1,2
#define	IR_DSTAC	ir,3,4
#define	IR_ARITHOP	ir,5,7
#define	IR_SH		ir,8,9
#define	IR_CY		ir,10,11
#define	IR_NL		ir,12,12
#define	IR_SKIP		ir,13,15
and then just write ALTO_GET(IR_SH) to extract SH, or ALTO_EQU(IR_SH,1) to
compare it against 1 etc.

Hmm.. and a macro ALTO_PUT(reg,from,to,val) to write into a bit field could
prove just as useful.

Just my thoughts, since I was myself about to report a non-bug as a bug,
because I counted some bits wrong in this very function.


More information about the Altogether-devel mailing list