Re: [cc65] Macros in inline assembler

From: Ullrich von Bassewitz <uz1musoftware.de>
Date: 2012-01-19 15:38:57
Hi!

On Thu, Jan 19, 2012 at 02:37:55PM +0100, "Andreas Rückert" wrote:
> So I'd like to unroll this loop:
> =========
> 	/* Unpack the block into 64 32-bit words */
> 	for(t = 0; t < 16; ++t)	{
> 	  datap = &data[t<<2];
> 		W[t] = (((uint32)*datap) << 24) |
> 		       (((uint32)*++datap) << 16) |
> 		       (((uint32)*++datap) <<  8) |
> 		       ((uint32)*++datap);
> =========

Just as a side note, because this is not your actual question: Above code
triggers undefined behaviour. If you're lucky, it works with a specific
compiler (-version). Otherwise it won't work. For most compilers it won't.

Reason: The '|' operator doesn't introduce a sequence point, which means that
the compiler is free to delay the evaluation of side effects (the ++
operators) until the end of the statement. This has nothing to do with cc65
but with writing proper C code.

> and defined me a macro:
>
> =========
> #define swapCopyULong(INDEX) \
>   __asm__( "lda _data+(" ## #INDEX ## "*16+3)\n" \
> 		 "sta _W+(" ## #INDEX ## "q*4)\n"               \
> 		 "lda _data+(" ## #INDEX ## "*16+2)\n"		\
> 		 "sta _W+"( ## #INDEX ## "*4+1)\n"		\
> 		 "lda _data+(" ## #INDEX ## "*16+1)\n"		\
> 		 "sta _W+( " ## #INDEX ## "*4+2)\n"		\
> 		 "lda _data+(" ## #INDEX ## "*16)\n"		\
> 		 "sta _W+(" ## #INDEX ## "*4+3)\n" )
> =========

Just as a side note, because this is not your actual question: You should
never generate the names of variables yourself by prepending an underscore.
Please read this:

        http://www.cc65.org/snapshot-doc/cc65-9.html

Reading that chapter may also give some clues how your problem can be solved
easily: Just use %w for the offset.

Apart from that, above lines have several other errors: There's something
named "q" in the second line which leads to an error. And, using the token
pasting operator (##) is wrong, because pasting two strings together gives an
invalid token. Strings do not need an operator to have them concatenated.

> , but this doesn't work so far, because the macro parameter is
> not expanded and the linker complains about unresolved externals
> _data and _W .

I would first fix the problems then try again. There are some problems with
cc65 macros, but as far as I can say, your code doesn't trigger any of them.

> I also tried to write a ca65 macro in the inline assembly, but
> I got complains, that it's not supported at this place?

You should really read the documentation. From the chapter already mentioned:

  For this reason, the compiler does only allow regular 6502 opcodes to be
  used with the inline assembler. Pseudo instructions (like .import, .byte and
  so on) are not allowed, even if the ca65 assembler (which is used to
  translate the generated assembler code) would accept them. The builtin
  inline assembler is not a replacement for the full blown macro assembler
  which comes with the compiler.

> Or is there a way to expand macro parameters within a string, so
> I get something like sta _W+(3*4+3), which could be used as an
> absolute address? (_W is a local var, but static as I understand it).

There's an old saying among us engineers: If nothing else helps, read the
documentation:-) Hint: It does also describe how to access a static local
variable from inline assembly.

Regards


        Uz


-- 
Ullrich von Bassewitz                                  uz@musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo@musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Thu Jan 19 15:39:07 2012

This archive was generated by hypermail 2.1.8 : 2012-01-19 15:39:10 CET