Go Down

Topic: Another optimization question - can I speed up this 32 bit multiply? (Read 2812 times) previous topic - next topic

scswift

What the hell is going on here?

Code: [Select]

#define MultiU16X16to32(longRes, intIn1, intIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %A2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %B1, %B2 \n\t" \
"movw %C0, r0 \n\t" \
"mul %B2, %A1 \n\t" \
"add %B0, r0 \n\t" \
"adc %C0, r1 \n\t" \
"adc %D0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add %B0, r0 \n\t" \
"adc %C0, r1 \n\t" \
"adc %D0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (longRes) \
: \
"a" (intIn1), \
"a" (intIn2) \
: \
"r26" \
)



#define MultiU8X16to24(longRes, charIn1, intIn2) \
asm volatile ( \
"clr r16 \n\t" \       
"mul %A1, %A2 \n\t" \   
"movw %A0, r0 \n\t" \   
"mov %C0, r16 \n\t" \   
"mov %D0, r16 \n\t" \   
"mul %A1, %B2 \n\t" \ 
"add %B0, r0 \n\t" \   
"adc %C0, r1 \n\t" \   
"adc %D0, r16 \n\t" \ 
"clr r1 \n\t" \
: \                 
"=&r" (longRes) \ 
: \               
"a" (charIn1), \
"a" (intIn2) \
: \               
"r16" \           
)



I was getting an error in the second define, "expected ) before : token", so I copied another example assembly function which is nearly identical, pasted that before the one that's broken, and I get no errors on that one, but of course the second one still errors. 

scswift

Now I'm getting "expected unqualified ID before string constant" on:
"mul %A1, %A2 \n\t" \

Code: [Select]

#define MultiU8X16to24(longRes, charIn1, intIn2) \
asm volatile ( \
"clr r16 \n\t" \     
"mul %A1, %A2 \n\t" \ 
"movw %A0, r0 \n\t" \ 
"mov %C0, r16 \n\t" \ 
"mov %D0, r16 \n\t" \   
"mul %A1, %B2 \n\t" \
"add %B0, r0 \n\t" \   
"adc %C0, r1 \n\t" \   
"adc %D0, r16 \n\t" \
"clr r1 \n\t" \       
: \                 
"=&r" (longRes) \ 
: \               
"a" (charIn1), \
"a" (intIn2) \
: \               
"r16" \           
)

scswift

I removed the first backslash which seems to have fixed that error, but I'm back to to getting an error about expecitng ) before : ...

Code: [Select]

"clr r1 \n\t" \       
: \ 


Right there, on the : \ line.

scswift

What the hell!

I'm still getting that stupid error no matter what I do!

I copied example code from here:
http://www.nongnu.org/avr-libc/user-manual/inline_asm.html

Code: [Select]

asm volatile("mov __tmp_reg__, %A0" "\n\t"
             "mov %A0, %B0"         "\n\t"
             "mov %B0, __tmp_reg__" "\n\t"
             : "=r" (value)
             : "0" (value)
            );



And I get THE SAME ERROR!

scswift

I've been copying examples from everywhere into new sketches and NONE of them are working.  Is there some kind of bug in the IDE?

Code: [Select]

uint8_t n=10;
__asm(" inc #0\n"::"r");


scswift

THIS one works.  Why does THIS one work?

Code: [Select]

#define MultiU16X16toH16(intRes, intIn1, intIn2) \
asm volatile ( \
"clr r26 \n\t" \
"mul %A1, %A2 \n\t" \
"mov r27, r1 \n\t" \
"mul %B1, %B2 \n\t" \
"movw %A0, r0 \n\t" \
"mul %B2, %A1 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"mul %B1, %A2 \n\t" \
"add r27, r0 \n\t" \
"adc %A0, r1 \n\t" \
"adc %B0, r26 \n\t" \
"clr r1 \n\t" \
: \
"=&r" (intRes) \
: \
"a" (intIn1), \
"a" (intIn2) \
: \
"r26" , "r27" \
)

scswift

You have GOT to be kidding me.

The problem was a warning I saw a few times and ignored: "blackslash and newline seperatedby space".  I didn't know what that meant and it looked like the newlines in my assembly code were all fine, and it was just a warning so I looked elsewhere for the problem.

But apparently that was the problem.  This damn thing cares if there are INVISIBLE SPACES after that frigging backslash.

So apparently all the code examples I pasted that weren't working had some of these invisible spaces in there, and even though what I could SEE looked virtually identical, it wouldn't compiled because of those damn spaces.

Nick Gammon

A backslash at the end of a line has a special meaning (line folding). But a backslash elsewhere has another meaning, eg.

Code: [Select]
Serial.print ("foo\n");


http://en.wikipedia.org/wiki/Backslash

Quote
In the context of line-oriented text, especially source code for some programming languages, it is often used at the end of a line to indicate that the trailing newline character should be ignored, so that the following line is treated as if it were part of the current line. In this context it may be called a "continuation". The GNU make manual says, "We split each long line into two lines using backslash-newline; this is like using one long line, but is easier to read."


So backslash+newline has a special meaning. Not backslash+space+newline. Sorry.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

If it helps, a lot of us have fallen for that. Plus it's another reason not to use defines, especially ones that go over multiple lines. Those trailing spaces can be hard to see.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

scswift

I understand, but I don't think there could be ANY good reason the compiler does not ignore spaces after that trailing backslash.

I mean "blackslash followed by spces and then a linefeed" doesn't seem like a more complicated rule than just looking for an immediate linefeed, nor can I think of any good examples where such a rule would trip things up.

scswift

Quote
Plus it's another reason not to use defines


What do you mean by that anyway?  I shouldn't be using defines?  How else can I use inline assembly?

Nick Gammon

What do you mean? Without using defines? Defines are just a text pre-preprocessing thing. An example from optiboot.c:

Code: [Select]

  __asm__ __volatile__ (
    "   com %[ch]\n" // ones complement, carry set
    "   sec\n"
    "1: brcc 2f\n"
    "   cbi %[uartPort],%[uartBit]\n"
    "   rjmp 3f\n"
    "2: sbi %[uartPort],%[uartBit]\n"
    "   nop\n"
    "3: rcall uartDelay\n"
    "   rcall uartDelay\n"
    "   lsr %[ch]\n"
    "   dec %[bitcnt]\n"
    "   brne 1b\n"
    :
    :
      [bitcnt] "d" (10),
      [ch] "r" (ch),
      [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
      [uartBit] "I" (UART_TX_BIT)
    :
      "r25"
  );


No define there. No backslashes (apart from the \n inside the assembler string).
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Coding Badly

I shouldn't be using defines?  How else can I use inline assembly?


Inline functions are a good choice...
http://code.google.com/p/arduino-tiny/source/browse/trunk/hardware/tiny/cores/tiny/TinyDebugSerial.h#54

scswift

Does that mean the \t isn't needed?  Some seem to use it some don't.  The code I'm using had them already.

As for defines, I know what they do, but what I'm saying is without them I'd have to drop that assembly in everywhere I want to use it.  I can't use it like a function, but without the overhead of a function call.  Unless I can use an inline function and the compiler knows not to do all kinds of crazy stuff with the function parameters.

Go Up