Go Down

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

#### scswift

#15
##### Nov 06, 2012, 06:23 am
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

#16
##### Nov 06, 2012, 06:33 am
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

#17
##### Nov 06, 2012, 06:42 am
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

#18
##### Nov 06, 2012, 07:13 am
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

#19
##### Nov 06, 2012, 07:26 am
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

#20
##### Nov 06, 2012, 07:28 am
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

#21
##### Nov 06, 2012, 07:38 am
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.

#### nickgammon

#22
##### Nov 06, 2012, 07:46 am
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!

#### nickgammon

#23
##### Nov 06, 2012, 07:48 am
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!

#### scswift

#24
##### Nov 06, 2012, 08:03 am
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

#25
##### Nov 06, 2012, 08:05 am
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?

#### nickgammon

#26
##### Nov 06, 2012, 08:11 am
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!

#### nickgammon

#27
##### Nov 06, 2012, 08:12 am
Note that there is no \t in optiboot.c.
Please post technical questions on the forum, not by personal message. Thanks!

#28
##### Nov 06, 2012, 08:15 am
I shouldn't be using defines?  How else can I use inline assembly?

Inline functions are a good choice...