XCASM Optimising Code Generator

The code generator converts C like expressions to executable assembler

operators and precedence (binding) table

using the code generator inside interrupt service routines (you need to
redefine xacc_0, wacc_0 etc using .set - see below). This is because of
re-entrentcy problems and sharing static variables. In particular
watchout for multiply, divide, mod, and shift (using variable shift RHS

explain about optimisation making use of destination RAM location. This
could have side effects where the destination is a memory mapped port or
mailbox used between the main line code and the interrupt service
e.g.	A = B >> 3   this causes A to be modified multiple times during
the shifting becaue building the result in A is more efficent than
building the result in an alternate RAM location and then moving it to
A (shifts cannot be done efficiently in the accumulator in the PIC MCU)

using variables (see .set statement) to change the RAM locations used
as temporary storage during computation.
xfred_0	.ds	2
xfred_1	.ds	2
xfred_2	.ds	2
	.org	$-6
wfred_0	.dw	0
wfred_1	.dw	0
wfred_2	.dw	0

xacc_0	.set	xfred_0
xacc_1	.set	xfred_1
xacc_2	.set	xfred_2
wacc_0	.set	wfred_0
wacc_1	.set	wfred_1
wacc_2	.set	wfred_2

calculating a value and leaving it in the accumulator

calculating an address and leaving it in the index register

.let statement

xif, xthen statement

8 bit
16 bit

restrictions on table size (only first 256 words of code space
accessable via arrays and address derefernces using 8 bit only code

array indexing, in RAM and in ROM

address arithmetic and derefernces
e.g. *(&a + 1)

efficent address calculation when accessing RAM (MSB of the address is
discarded early on in the calculation and any redundent instructions
which only affect the MSB are eliminated)

when storeing results to byte sized RAM locations, any instructions that
would affect the MSB only are eliminated. This produces much more
compact code than simply comuting a 16 bit result and discarding the

Highly efficient 8 and 16 bit mixed value computation.

Optimised accumulator usage. minimises RAM accesses keeping results
in the accumulator. Keeps LSB of 16 bit value in accumulator where
possible further optimising 8 and 16 bit mixed value computation.

Optimised index register usage. keep address refernces in the index
register and tracks its use so that multiple refernces to the same
location make use previous address calculations
e.g. a[j] = b - a[j] only calculates the address of a[j] and uses
it twice.

Early out && and || operators. complex logical expressions using
early out operators cause execution if the expression to be terminated
as soon the result is known
e.g.  (a > 1  &&  b > 1)  fails immediately if a <= 1 without
bothering to evaluate b > 1
e.g.  (a > 1  ||  b > 1)  succeads immediately if a > 1 without
bothering to evaluate b > 1

(.byte) coersion operator
prevents computation of MSB of word, (.byte)(a + b) is different to
and much more efficent than ((b + B) & 0xFF)

(.word) coersion operator
ensures MSB of computation is not lost when operands are only byte
wide e.g. (a + b) != (.word)(a + b)

.dw defines word quantities