Hallo, ich möchte den Hardware-Multiplizierer des ARMs effektiv unter C nutzen. Ich habe 2 32 Bit Zahlen und möchte diese zu einer 64 Bit Zahl multiplizieren. Der ARM hat in seinem Opcode Instruction dazu den MULL bzw. SMULL Befehl. Wie kann ich diesen von C aus (GCC) nutzen ohne direkt Assembler Anweisungen im C Code einzuhacken ? Hintergrund ist der das ich ein IIR Filter für den ARM implementieren möchte. Allerdings möchte ich das ganze wegen des Komforts in C machen. Das Problem an einer 32x32 Bit Multiplikation ist das C mir immer nur das Low-Wort liefert und eben nicht beide. Wenn ich beide haben möchte muß ich beide Zahlen erst auf 64 Bit bringen und dann Multiplizieren. Das macht die Multiplikation allerdings umständlich und deutlich länger. Wie kann ich es dem GCC beibringen den MULL bzw. SMULL Befehl zu nutzen ? Gruß Rene
1 | unsigned long x, y; |
2 | unsigned long long result = (unsigned long long)x * (unsigned long long)y; |
und auf die Intelligenz des Compilers vertrauen. Der merkt das nämlich und erzeugt genau den gewünschten UMULL Befehl.
Wenn dir das nötige Vertrauen fehlt:
1 | static inline long long smull (int x, int y) |
2 | {
|
3 | long long r; |
4 | asm ("smull %Q0, %R0, %1, %2" : "=&r"(r) : "r"(x), "r"(y) : "cc"); |
5 | return r; |
6 | }
|
>und auf die Intelligenz des Compilers vertrauen. Der merkt das nämlich >und erzeugt genau den gewünschten UMULL Befehl. ich hoffe es ... hatte beim msp430 das selbe. wollte eine 16x16 bit multi machen und nachdem ich es auf 32x32 umgestellt hatte (weil 16x16 eben nur das low-wort lieferte) begann der overkill ... er merkte nichts mehr ... und brauchte statt 1 takt etwa 100 bzw. mehr da er nicht den HW multiplizierer nutze :-(( vllt. klappts ja beim arm. gibts eigentlich für sowas keine makros ? wie kommt es das das in c so definiert wurde ? liegt das an der bedingung "ausgangstyp = eingangstyp" ?!
@andreas danke fürs vertrauen aufbauen :-)) ich hatte zwar mal mitbekommen (und auch in manuals gelesen) das das unter gcc geht direkt assembler befehle einzubauen, bin aber immer am verständnis der parameterübergabe gescheitert (reihenfolge, definition, redefinition, mapping usw) ... danke vielmals ...
TheMason wrote: > gibts eigentlich für sowas keine makros ? Was sollte eine Textersetzung bei einer Multiplikation bringen??? > wie kommt es das das in c so definiert wurde ? Sämtliche Artithmetik ist in C und vielen anderen Sprachen so definiert. Als Ausnahme habe ich grad nur PL/I parat, da ist das Ergebnis entsprechend breiter - aber da sind auch die Operanden selbst Datentypen mit explizit definierter Genauigkeit bin(31), keine obskuren "integer".
>> gibts eigentlich für sowas keine makros ? >Was sollte eine Textersetzung bei einer Multiplikation bringen??? makros vllt. nicht. aber spezielle befehle wie es (beim avr) der "sei" ist (wenn dahinter nicht auch wieder ein asm-makro steht).
TheMason wrote: > unter gcc geht direkt assembler befehle einzubauen, bin aber immer am > verständnis der parameterübergabe gescheitert (reihenfolge, definition, > redefinition, mapping usw) ... Nachvollziehbar. Den Trick mit %Q0/%R0 musste ich dem Quellcode des Compilers abschauen, in der Doku steht das m.W. nicht drin.
TheMason wrote:
> (wenn dahinter nicht auch wieder ein asm-makro steht).
1 | # define cli() __asm__ __volatile__ ("cli" ::)
|
>Nachvollziehbar. Den Trick mit %Q0/%R0 musste ich dem Quellcode des >Compilers abschauen, in der Doku steht das m.W. nicht drin. ui ... somit hat sich die frage nach dem %Q0/%R0 und deren bedeutung erübrigt ... :-( na ja. vllt. klappts damit ja die implementierung meines iir-filters. werde davon berichten :-) danke nochmals
>> (wenn dahinter nicht auch wieder ein asm-makro steht).
hatte mir sowas schon gedacht ...
na ja. ein paar spezial befehle in der c syntax um auf die
prozessor-spezialitäten einzugehen wäre dennoch echt wünschenswert,
zumal man für viele features recht umständlich die asm-gcc-syntax (mit
eben jener etwas unverständlichen parameterübergabe) bemühen muß.
wär ja mal was für künftige gcc-implementationen, oder ? :-)
TheMason wrote: > ui ... somit hat sich die frage nach dem %Q0/%R0 und deren bedeutung > erübrigt ... :-( Es ist übrigens nicht sinnvoll, die asm statements direkt in die Anwendung einzubauen. Die von mir gezeigte Funktion ist exakt die GCC Umschreibung für den SMULL Befehl und wird als ... smull(v1,v2) + smull(v3,v4) ... das gewünschte Ergebnis bringen. Inlinen und optimieren tut es der Compiler dann schon selber, das genau ist der Charme von asm in GCC (und drum auch etwas komplex). Die Präfixe Q und R sind bei Variablen nötig, die 2 Register belegen. Irgendwie muss man ja klar machen, welches man davon grad meint.
TheMason wrote:
> wär ja mal was für künftige gcc-implementationen, oder ? :-)
Dem Compiler ist das wurscht, das wäre eher eine Library bzw. ein
Include-File. Könnte man zwar auch als builtin machen, aber wozu? Geht
ja auch so.
Und die DSP Befehle gibt's schon fertig als builtins (=> Doku).
>das genau ist der Charme von asm in GCC habe damit (den asm-konstrukten) noch nicht viel gemacht. beschränkt sich meist auf asm-befehle ohne parameter :-)) >Die Präfixe Q und R sind bei Variablen nötig, die 2 Register belegen. >Irgendwie muss man ja klar machen, welches man davon grad meint. sowas hatte ich mir schon gedacht (mit der aufteilung). nur ist die bezeichnung q und r nicht gerade aussagekräftig ob nun high oder low wort des long long's. das verwirrt etwas. da geht wohl nur : probieren und studieren (vor allem das gcc-manual section : mixing c and asm) und wenns nicht drin steht : hier im forum nachfragen :-) bei soviel geballter kompetenz :-))
>Dem Compiler ist das wurscht, das wäre eher eine Library bzw. ein >Include-File. Könnte man zwar auch als builtin machen, aber wozu? Geht >ja auch so. stümmt auch wieder ... >Und die DSP Befehle gibt's schon fertig als builtins (=> Doku). ich glaub ich habe da noch einige lücken .... das war mir bisher nicht bekannt. muß mir das mal genauer anschauen. danke für die hinweise.
TheMason wrote: > das war mir bisher nicht bekannt. muß mir das mal genauer anschauen. > danke für die hinweise. Sachte. Die hat nicht jeder ARM implementiert.
für mich sind die dsp-funktionen die multiply and accumulate funktionen. sind die denn nicht in jedem arm vorhanden ? der multiplizierer ist doch eigentlich teil des arm-cores oder nicht ?! oder gibt es noch weitere ? (hatte mir die arm-opcode übersicht von atmel geladen, vielleicht das da nur die multiply und mac-operanden implementiert sind)
TheMason wrote: > für mich sind die dsp-funktionen die multiply and accumulate funktionen. > sind die denn nicht in jedem arm vorhanden ? Doch, faktisch schon. Aber unter DSP Befehlen versteht ARM einen separaten optionalen Befehlssatz, ungefähr im Sinn von Intels MMX Befehlen. SMLAL wäre dann
1 | static inline long long smlal (long long r, int x, int y) |
2 | {
|
3 | asm ("smlal %Q0, %R0, %1, %2" : "+r"(r) : "r"(x), "r"(y) : "cc"); |
4 | return r; |
5 | }
|
>Ja. Aber unter DSP Befehlen versteht ARM einen separaten optionalen >Befehlssatz, ungefähr im Sinn von Intels MMX Befehlen. sind das dann die im arm-technical-manual schon erwähnten co-prozessoren oder sind diese dsp-befehle noch ein sub-set des std-arm-cores das je nach halbleiterhersteller mitimplementiert wird oder eben nicht ?
TheMason wrote: > sind das dann die im arm-technical-manual schon erwähnten co-prozessoren > oder sind diese dsp-befehle noch ein sub-set des std-arm-cores das je > nach halbleiterhersteller mitimplementiert wird oder eben nicht ? Hängt davon ab welchen Core der Hersteller gekauft hat. Die meisten ARM7 benutzen den ARM7TDMI Core, was die eingebaute Funktionalität umschreibt, hier T=Thumb, M=Multiplier (d.h. kann UMULL/...). Ist da noch ein "E" drin, kann er DSP. Allerdings gibt's das m.W. nur für ARMv5 aufwärts, also nicht vor ARM9.
>TDMI
ach ja ... diese ominöse abk. da war ja was.
jedenfalls reichen mir denke ich erstmal die normalen multiply befehle
um den iir zu implementieren. habe "nur" einen at91sam7s256 (also
arm7tdmi wenn ichs richtig habe) und möchte mit dem erstmal was spielen
:-)
später wird sicherlich ein größerer arm fällig, obwohl mir die arm7
schon echt gut gefallen (auch von der lötbarkeit her, also kein
bga-zeugs und so) und eigentlich auch für viele sachen ausreichend sind.
nochmal eben eine frage zum multiplier : die accumulate funktionen sind
aber auch in den M-versionen (also mit multiplier) drin oder ist das
schon "E" ?
Empfehlenswert: Such mal bei ARM nach einen Dokument mit dem überaus sprechenden Namen DDI0100E. Das ist die komplette ARM Referenz.
Die Quick Reference hast du ja wohl schon gefunden. Da steht in der § Spalte drin, welcher Befehl in welcher Variante existiert. UMULL ist "M" und ARM7TDMI hat "M". SMULBB hingegen ist "5E", also ARMv5 Architektur und "E" Option.
wenn das die technical reference ist dann hab ich die schon (ich meine dieser überaus anmutende name hat sich in meinem kopf geprägt, allerdings kann es auch ein zahlen/buchstabendreher sein :-), muß nochmal nachschauen). daher bin ich ja auch auf den multiply befehl gestossen. in einem weiteren dokument (hab den namen nicht im kopf) standen dann die opcodes nochmal schön erklärt.
Such weiter. Ich meine das ARM ARM = ARM Architecture Reference Manual. Die ARM Bibel und genauso dick. Sollte man haben (und gelesen haben, jedefalls die vordere Hälfte). Die Technical Reference beschreibt hingegen die konkrete Implementierung, also beispielsweise ARM7TDMI.
danke erstmal für die bibel hinweise :-) werd da morgen mal die suchmaschinen anwerfen. und natürlich deine asm-gcc-hinweise ausprobieren (kanns erst morgen abend ausprobieren, aber mir brennts schon ganz doll in den fingern :-))) gruß rene
halllo, hier noch eine verweis auf eine "bibel" die jeder arm programmierer kennen sollte: ARM System Developer's Guide (ISBN-10: 1558608745) wenn es effiziente Programmierung, ob in C oder Assembler, geht dann ist diese "bibel" das optimum. gruss gerhard
>wenn es effiziente Programmierung, ob in C oder Assembler, geht dann ist >diese "bibel" das optimum. Was das Alter angeht, ist das in der Tat eine Bibel. Neuere Befehlssätze wie ARMv7-M werden da nicht behandelt. Dabei ist gerade das interessant, wo doch diese Architektur bald den Markt im Low-Performance-16/32Bit-Bereich dominieren dürfte.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.