mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wiw nutze ich den Multiplizierer des ARMs ?


Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
unsigned long x, y;
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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn dir das nötige Vertrauen fehlt:
static inline long long smull (int x, int y)
{
    long long r;
    asm ("smull %Q0, %R0, %1, %2" : "=&r"(r) : "r"(x), "r"(y) : "cc");
    return r;
}

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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" ?!

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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 ...

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> 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).

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TheMason wrote:

> (wenn dahinter nicht auch wieder ein asm-makro steht).
# define cli()  __asm__ __volatile__ ("cli" ::)

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> (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 ? :-)

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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).

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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 :-))

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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)

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
static inline long long smlal (long long r, int x, int y)
{
    asm ("smlal %Q0, %R0, %1, %2" : "+r"(r) : "r"(x), "r"(y) : "cc");
    return r;
}

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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 ?

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ps. danke noch für das smlal beispiel.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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" ?

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Empfehlenswert: Such mal bei ARM nach einen Dokument mit dem überaus 
sprechenden Namen DDI0100E. Das ist die komplette ARM Referenz.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: TheMason (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: gerhard (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Sepp (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.