Hallo Forum,
zur Zeit beschäftige ich mich gezwungenermaßen mit dem LPC824. Die
gesamte Serie von NXP besitzt sogenannte ROM-APIs. Hauptsächlich dienen
diese zur Hardware-Ansteuerung.
Speziell dieses Modell hat aber auch "Performance-optimized
signed/unsigned integer division" Funktionen. Folgende Funktionen sind
im ROM implementiert:
1
int32_tsdiv(int32_tnum,int32_tdenom);
2
uint32_tudiv(uint32_tnum,uint32_tdenom);
3
sdiv_tsdivmod(int32_tnum,int32_tdenom);
4
udiv_tudivmod(uint32_tnum,uint32_tdenom);
Diese liegen an der Adresse 0x1FFF_1FF8 + 0x10 und den darauffolgenden
Adressen.
Aus der ARM EBAI Beschreibung*) entnehme ich, dass (da es keine
Divisions-Instruktionen gibt) die folgenden Funktionen aus der libgcc
aufgerufen werden:
Soweit zu den Gegebenheiten:
Meine Frage ist jetzt, wie ich den GCC dazu bewegen kann, statt den
Funktionen der libgcc die ROMAPI aufzurufen.
Mein naiver Ansatz wäre so:
Allerdings werden so ja extra Funktionen, samt extra push/pop-Sequenz,
generiert, die dann weitere Funktionen anspringen. Diesen extra Sprung
und das push/pop**) würde ich gerne, wenn es geht, abstellen.
Kann ich dem GCC mitteilen, dass die __aeabi_[ui]div(mod) an speziellen
Adressen liegen und nicht nochmal dazugelinkt werden müssen? (mglw. mit
-Wl,--defsym=name=...?)
Mit freundlichen Grüßen,
N.G.
PS:
1. ich weiß nicht, ob die Performance der ROM-API besser ist, ich will
es aber einfach mal ausprobieren.
2. Ich habe weder ein Performance-, noch ein Speicher-Problem,
allerdings will ich die Funktion schon mal nutzen, wenn sie angeboten
wird.
*)
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0043d/IHI0043D_rtabi.pdf
**) https://godbolt.org/g/zskz1x
Also ähnlich wie bei arm: gcc erzeugt einen lib-Aufruf, hier __divmodhi4
aus libgcc. Um stattdessen nach 0x1234 zu springen (wo hier kein
sinnvoller Code steht) bein Linken:
D.h. ld löst das Symbol nicht durch Linken gegen libgcc.a auf, sonder
gemäß der Definition des Symbols von der Kommandozeile.
Symbole können auch im Linker-Skript festgelegt werden, falls das besser
in den Build-Prozess passt.
Ob das gut mit Symbolreferenzen funktioniert, die sich in anderen
Bibliotheken oder der libgcc selbst befinden, weiß ich nicht konkret.
Evtl. hilft es dann, ein anderes Symbol zu verwenden, das nicht in der
Bibliothek auftaucht:
Hallo Johann,
danke für deine Antwort.
Dann lag ich ja mit meiner defsym-Idee gar nicht so falsch :-)
Das werde ich probieren, sobald ich die Hardware wieder habe. Dann teste
ich auch mal die Performance.
Johann L. schrieb:> Symbole können auch im Linker-Skript festgelegt werden, falls das besser> in den Build-Prozess passt.
Ja, das wäre mir lieb, da ich (ARM-typisch) sowieso ein eigenes
ld-Skript nutze. Wie müsste ich so etwas machen (ich tippe auf
PROVIDE())?
Johann L. schrieb:> Ob das gut mit Symbolreferenzen funktioniert, die sich in anderen> Bibliotheken oder der libgcc selbst befinden, weiß ich nicht konkret.> Evtl. hilft es dann, ein anderes Symbol zu verwenden, das nicht in der> Bibliothek auftaucht
Inwiefern könnte es da Probleme geben, und wie würden die sich äußern?
Link-time-errors oder ein nicht-funktionierendes Programm?
Mit freundlichen Grüßen,
N.G.
N. G. schrieb:> Johann L. schrieb:>> Ob das gut mit Symbolreferenzen funktioniert, die sich in anderen>> Bibliotheken oder der libgcc selbst befinden, weiß ich nicht konkret.>> Evtl. hilft es dann, ein anderes Symbol zu verwenden, das nicht in der>> Bibliothek auftaucht>> Inwiefern könnte es da Probleme geben, und wie würden die sich äußern?> Link-time-errors oder ein nicht-funktionierendes Programm?
Okay, scheinbar geht es sowohl mit (war zu erwarten), als auch ohne
--wrap.
.../ld: warning: cannot find entry symbol _start; defaulting to 0000000000008000
(Warning, weil ich kein eigenes ld-skript angegeben habe. Kann hier
ignoriert werden)
1
$ arm-none-eabi-objdump -d -S a.out
2
3
a.out: file format elf32-littlearm
4
5
6
Disassembly of section .text:
7
8
00008000 <main>:
9
8000: 2305 movs r3, #5
10
8002: b507 push {r0, r1, r2, lr}
11
8004: 9300 str r3, [sp, #0]
12
8006: 3b03 subs r3, #3
13
8008: 9301 str r3, [sp, #4]
14
800a: 9800 ldr r0, [sp, #0]
15
800c: 9901 ldr r1, [sp, #4]
16
800e: f7f9 f911 bl 1234 <__aeabi_uidiv>
17
8012: bd0e pop {r1, r2, r3, pc}
Funktioniert also.
Die Performance habe ich mangels Hardware noch nicht testen können.
Die Frage nach der Angabe im Linker-Skript bleibt aber noch bestehen ;-)
Mit freundlichen Grüßen,
N.G.