Fixed-Point-Mathematik mit ARM Cortex-M4 und GCC-Compiler

8

Ich verwende Freescale Kinetis K60 und benutze die CodeWarrior IDE (von der ich glaube, dass sie GCC für den Compiler verwendet).

Ich möchte zwei 32-Bit-Zahlen multiplizieren (was zu einer 64-Bit-Zahl führt) und nur die oberen 32 Bit beibehalten.

Ich denke, die richtige Montageanleitung für den ARM Cortex-M4 ist der SMMUL-Befehl. Ich würde lieber auf diese Anweisung aus C-Code als Assembly zugreifen. Wie mache ich das?

Ich stelle mir vor, der Code wäre im Idealfall etwa so:

%Vor%

Wenn ich dies in CodeWarrior versuche, bekomme ich das korrekte Ergebnis für c (536870912 = 0.25 als D0 FP Nummer). Ich sehe den SMMUL-Befehl nirgendwo und das Multiplizieren ist 3 Anweisungen (UMULL, MLA und MLA - ich verstehe nicht, warum es eine vorzeichenlose Multiplikation verwendet, aber das ist eine andere Frage). Ich habe auch eine Rechtsverschiebung von 32 versucht, da dies für den SMMUL-Befehl mehr Sinn ergeben könnte, aber das macht nichts anderes.

    
EpicAdv 03.12.2011, 00:32
quelle

2 Antworten

6

Das Problem mit der Optimierung dieses Codes ist:

%Vor%

Ihr Code tut nichts Runtime, so dass der Optimierer nur die endgültige Antwort berechnen kann.

das:

%Vor%

wird damit aufgerufen:

%Vor%

gibt 0x10000000

UMULL gibt das gleiche Ergebnis, weil Sie positive Zahlen verwenden, die Operanden und Ergebnisse sind alle positiv, so dass es nicht in die Unterschiede zwischen Vorzeichen und Vorzeichen gerät.

Hmm, naja, du hast mich hier erwischt. Ich würde Ihren Code lesen, wenn der Compiler den Multiplikator auf 64 Bit hochstufen soll. smull ist zwei 32-Bit-Operanden, die ein 64-Bit-Ergebnis ergeben, das ist nicht das, wonach Ihr Code fragt .... aber sowohl gcc als auch clang haben die smull trotzdem benutzt, auch wenn ich es als uncalled-Funktion zurückgelassen habe Kompilierzeit, dass die Operanden keine signifikanten Ziffern über 32 hatten, verwendeten sie immer noch smull.

Vielleicht war die Verschiebung der Grund.

Yup, das war es ..

%Vor%

gibt

sowohl gcc als auch clang (well clang rezykliert r0 und r1 anstelle von r2 und r3)

%Vor%

aber das

%Vor%

gibt dies

gcc:

%Vor%

klingeln:

%Vor%

Mit der Bitverschiebung erkennen die Compiler, dass Sie nur am oberen Teil des Ergebnisses interessiert sind, so dass sie den oberen Teil der Operanden verwerfen können, was bedeutet, dass smull verwendet werden kann.

Wenn Sie das jetzt tun:

%Vor%

beide Compiler werden noch schlauer, insbesondere clang:

%Vor%

gcc:

%Vor%

Ich kann sehen, dass 0x40000000 als Float betrachtet wird, wo Sie die Nachkommastellen verfolgen, und dieser Ort ist ein fester Ort. 0x20000000 würde als Antwort Sinn machen. Ich kann noch nicht entscheiden, ob diese 31-Bit-Verschiebung universell oder nur für diesen einen Fall funktioniert.

Ein vollständiges Beispiel für das obige ist hier

Ссылка

und ich habe es auf einem stm32f4 ausgeführt, um zu überprüfen, ob es funktioniert und die Ergebnisse.

BEARBEITEN:

Wenn Sie die Parameter an die Funktion übergeben, anstatt sie in der Funktion fest zu codieren:

%Vor%

Der Compiler wird gezwungen, Laufzeitcode zu erstellen, anstatt die Antwort zur Kompilierzeit zu optimieren.

Wenn Sie diese Funktion jetzt von einer anderen Funktion mit hartcodierten Zahlen aufrufen:

%Vor%

In dieser aufrufenden Funktion kann der Compiler wählen, die Antwort zu berechnen und sie einfach zur Kompilierzeit dort zu platzieren. Wenn die Funktion myfun () global ist (nicht als statisch deklariert), weiß der Compiler nicht, ob ein anderer später zu verknüpfender Code ihn auch in der Nähe des Aufrufpunktes in dieser Datei verwendet, um eine Antwort zu optimieren und lassen Sie es in dem Objekt für anderen Code in anderen Dateien aufrufen, damit Sie noch überprüfen können, was der Compiler / Optimierer mit diesem C-Code macht. Wenn Sie zum Beispiel nicht llvm verwenden, wo Sie das gesamte Projekt (über Dateien hinweg) optimieren können, wird externer Code, der diese Funktion aufruft, die reelle Funktion und nicht eine compile-time-berechnete Antwort verwenden.

Sowohl gcc als auch clang haben das gemacht, was ich gerade beschrieben habe, den Laufzeitcode für die Funktion als globale Funktion, aber innerhalb der Datei berechnete sie die Antwort zur Kompilierzeit und platzierte die hartcodierte Antwort im Code, anstatt die Funktion aufzurufen:

%Vor%

in einer anderen Funktion in der gleichen Datei:

%Vor%

Die Funktion selbst ist im Code implementiert:

%Vor%

aber wo es heißt, haben sie die Antwort hart geschrieben, weil sie alle notwendigen Informationen dafür hatten:

%Vor%

Wenn Sie die hardcoded Antwort nicht wollen, müssen Sie eine Funktion verwenden, die nicht im selben Optimierungspass ist.

Die Bearbeitung des Compilers und des Optimierers ist sehr praxiserprobend und es ist keine exakte Wissenschaft, da sich die Compiler und Optimierer ständig weiterentwickeln (zum Guten oder zum Schlechten).
Durch das Isolieren eines kleinen Codes in einer Funktion verursachen Sie auf andere Weise Probleme. Größere Funktionen benötigen eher einen Stack - Frame und entfernen Variablen aus den Registern in den Stack, kleinere Funktionen müssen dies möglicherweise nicht tun Optimierer können ändern, wie der Code als Ergebnis implementiert wird. Sie testen das Codefragment auf eine Art und Weise, um zu sehen, was der Compiler macht, dann verwenden Sie es in einer größeren Funktion und erhalten nicht das gewünschte Ergebnis. Wenn es eine genaue Anweisung oder Folge von Anweisungen gibt, die Sie implementieren möchten .... Implementieren Sie sie in Assembler. Wenn Sie eine bestimmte Gruppe von Anweisungen in einem bestimmten Befehlssatz / Prozessor anvisieren, dann meiden Sie das Spiel, vermeiden Sie, dass sich Ihr Code ändert, wenn Sie Computer / Compiler / etc ändern und verwenden Sie einfach Assembler für dieses Ziel. Wenn nötig, verwenden Sie ifdef oder verwenden Sie bedingte Kompilierungsoptionen, um für verschiedene Ziele ohne den Assembler zu erstellen.

    
old_timer 03.12.2011, 05:26
quelle
-1

GCC unterstützt tatsächliche Festkommatypen: Ссылка

Ich bin mir nicht sicher, welche Anweisung es verwenden wird, aber es könnte Ihnen das Leben leichter machen.

    
ams 03.12.2011 20:47
quelle

Tags und Links