Forum: Mikrocontroller und Digitale Elektronik 16bit x16bit =32bit inline assembler


von kaffeetas (Gast)


Lesenswert?

Hallo

ich verwende erfolgreich die 16x16 multiplikation aus
Beitrag "16Bit x 16Bit = 32Bit schnelle Multiplikation für 8Bit AVR in C"

nun habe ich versucht damit und aus der AVR201 das ganze auf signed 
umzustellen:
1
inline int32_t multi16s(int16_t zahl_a, int16_t zahl_b)
2
{
3
  int32_t result;
4
  char hilf;
5
  asm(
6
    "clr hilf"   "\n\t"
7
    "muls %B1,%B2"   "\n\t"      
8
    "mov %D0,R1"   "\n\t"
9
    "mov %C0,R0"   "\n\t"
10
    "mul %A1,%A2"  "\n\t"    
11
    "mov %B0,R1"   "\n\t"
12
    "mov %A0,R0"   "\n\t"
13
    "mulsu %B1,%A2""\n\t"    
14
    "sbc %D0,hilf"  "\n\t"
15
    "add %B0,R0"  "\n\t"
16
    "adc %C0,R1"  "\n\t"
17
    "adc %D0,hilf"  "\n\t"
18
    "mulsu %B2,%A1" "\n\t"    
19
    "sbc %D0,hilf"  "\n\t"
20
    "add %B0,R0"    "\n\t"
21
    "adc %C0,R1"  "\n\t"
22
    "adc %D0,hilf"  "\n\t"
23
    "clr R1"   "\n\t"
24
    : "=&r" (result)
25
    :"r" (zahl_a), "r" (zahl_b));
26
27
  return result;
28
}
Es kompiliert nicht und erzeugt eine ganze Latte Fehlermeldungen
1
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s: Assembler messages:
2
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:517: Error: register r16-r23 required
3
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:518: Error: constant value required
4
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:521: Error: constant value required
5
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:522: Error: unknown opcode `mulu'
6
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:523: Error: constant value required
7
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:526: Error: constant value required
8
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:548: Error: register r16-r23 required
9
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:548: Error: register r16-r23 required
10
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:549: Error: constant value required
11
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:552: Error: constant value required
12
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:553: Error: unknown opcode `mulu'
13
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:554: Error: constant value required
14
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:557: Error: constant value required
15
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:572: Error: register number above 15 required
16
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:578: Error: register r16-r23 required
17
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:578: Error: register r16-r23 required
18
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:579: Error: constant value required
19
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:582: Error: constant value required
20
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:583: Error: unknown opcode `mulu'
21
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:584: Error: constant value required
22
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:587: Error: constant value required
23
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:610: Error: register number above 15 required
24
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:616: Error: register r16-r23 required
25
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:616: Error: register r16-r23 required
26
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:617: Error: constant value required
27
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:620: Error: constant value required
28
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:621: Error: unknown opcode `mulu'
29
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:622: Error: constant value required
30
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:625: Error: constant value required
31
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:639: Error: register number above 15 required
32
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:645: Error: register r16-r23 required
33
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:645: Error: register r16-r23 required
34
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:646: Error: constant value required
35
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:649: Error: constant value required
36
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:650: Error: unknown opcode `mulu'
37
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:651: Error: constant value required
38
C:\DOKUME~1\ADMINI~1\LOKALE~1\Temp/ccFi0i31.s:654: Error: constant value required

soviel kann doch eigentlich nicht falsch sein oder?
Bitte helft mir ich komm sonst noch in die Klapse :-)

Grüße
 kaffeetas

von Benedikt K. (benedikt)


Lesenswert?

Ersetz mal das r durch ein a, dann sollten die ganzen r16-r23 required 
Fehler weg sein.
Desweiteren kannst du hilf nicht so einfach ansprechen, das musst du der 
inline asm Funktion genauso übergeben wie die anderen Variablen. Les dir 
am besten mal das Inline Assembler Cookbook das beim gcc dabei ist 
durch. Der Abschnitt Clobbers könnte auch für dich auch interessant 
sein.

von kaffeetas (Gast)


Lesenswert?

ACK
obwohl ichs nicht verstehe hatte die "r" aus dem obigen code kopiert und 
ob "any register" oder "simple upper register" sollte doch keine Roller 
spielen (wenn kein unteres mehr frei ist soll er halt ein oberes nehmen)

die "constant value required" bleiben das "mulu" hab ich wieder nach 
"mulsu" gefixt.

danke für die schnelle Antwort

von Benedikt K. (benedikt)


Lesenswert?

kaffeetas schrieb:

> obwohl ichs nicht verstehe hatte die "r" aus dem obigen code kopiert und
> ob "any register" oder "simple upper register" sollte doch keine Roller
> spielen (wenn kein unteres mehr frei ist soll er halt ein oberes nehmen)

Doch: mulsu funktioniert nur mit r16-r23. Und a zwingt den Compiler eben 
diese Register zu verwenden.

von Z8 (Gast)


Lesenswert?

... nur gut das es asm gibt. :)

von kaffeetas (Gast)


Lesenswert?

ich kann die angezeigte tempdatei nicht finden! Da muss ich doch 
bestimmt noch was einstellen dass diese erhalten bleibt die Frage ist 
nur wieder wo!!

das hilf hab ich durch _tmp_reg ersetzt, dann brauch ich "hilf" nicht 
clobbern?

achso vor ichs vergesse es läuft, ich werd verückt es läuft!

und das beste es rechnet anscheinend auch noch richtig.

danke Benedikt!

P.S. asm ist super da kann man mit ner "simplen" multiplikation den 
halben abend verbringen!

von Benedikt K. (benedikt)


Lesenswert?

kaffeetas schrieb:
> ich kann die angezeigte tempdatei nicht finden! Da muss ich doch
> bestimmt noch was einstellen dass diese erhalten bleibt die Frage ist
> nur wieder wo!!

Such mal im gcc Forum, da gabs irgendeinen Befehl mit dem man das 
einstellen kann.

> das hilf hab ich durch _tmp_reg ersetzt, dann brauch ich "hilf" nicht
> clobbern?

Ja.

> P.S. asm ist super da kann man mit ner "simplen" multiplikation den
> halben abend verbringen!

Versuch das ganze jetzt mal für einen AVR ohne mul Befehl zu 
programmieren. Da kommt Freude auf...

von kaffeetas (Gast)


Lesenswert?

-save-temps bei den Compiler Optionen im Makefile -das ich da nicht 
selbst drauf gekommen bin.

Den Spaß hebe ich mir für die Divisionen auf. Die Routinen gibts ja 
schon, man muss Sie ja nicht neuerfinden nur selbst mal nachvolziehen ob 
das "Rad" auch rund ist und dann auch zum laufen bringen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.