Hier im Forum treten immer wieder Fragen zu sdcc auf, oft von Leuten,
die gerade anfangen, sdcc zu verwenden, oder die im Betracht ziehen,
sdcc zu verwenden. Da ich mich etwas mit sdcc auskenne, aber wohl nicht
dauerhaft im Forum aktiv sein werden, möchte ich etwas dazu schreiben,
was den sdcc nutzenden C-Programmierer zu Zeit (sdcc 3.4.0) so erwartet.
Vieles davon hängt vom Port ab, aber zuerst das allgemeine:
sdcc ist ein C-Compiler, der versucht, sich weitgehend an die Standards
(ISO C90, ISO C99, ISO C11) zu halten. Innerhalb der Spielräume, die der
Standard läßt, wird gelegentlich anders als bei gcc vorgegangen.
Üblicherweise dürfte man im C99-Modus (Kommandozeilenoption --std-c99)
arbeiten wollen. sdcc ist auf 8-Bit-Architekturen ausgelegt, und kann
oft halbwegs effizienten Code für diese erzeugen. Mittels
--opt-code-size bzw. --opt-code-speed läßt sich das Optimierungsziel
wählen. Leider fehlen noch ein paar Features aus den Standards,
allerdings hauptsächlich solche, die auf 8-Bit Microcontrollern eher
selten verwednet werden. Details siehe:
http://sdcc.sourceforge.net/mediawiki/index.php/Standard_compliance
sdcc ist ausgereifte Software, es gibt selten schwere Bugs. Nächtlich
laufen regression tests auf verschiedenen Plattformen, d.h. es werden
kleine C-Programme mit sdcc auf verschiedenen Architekturen und
Betriebssystemen für verschiedene Zielarchitekturen kompiliert, und dann
im Simulator ausgeführt, um zu testen, ob sie sich korrekt verhalten.
Ein paar der tests wurden bei der Implementierung von Features in sdcc
geschrieben. Aber die meisten stammen aus Bug reports: Wenn ein Bug in
sdcc behoben wird, wird ein regression test geschrieben, um
sicherzustellen, das dieser Bug nicht wieder auftreten kann. Außerdem
ahben wir viele regression tests von gcc übernommen.
mcs51 und ds390 sind relativ alte Ports. Soweit ich weiß, sind sie recht
stabil, aber es gibt hie und da ein paar fehlende Features, die in
anderen Ports drin sind. An manchen Ecken wurde zugunsten von
Speicherplatzeffizienz gegen Standardkompatiblität entschieden (bool als
bit impementiert).
Auch hc08 und s08 sind etablierte, stabile ports. Da der s08 port aus
dem hc08 port entwickelt wurde, mag es hie und da noch ungenutzes
Optimierungspotential geben. Wie auch beim mcs51 und ds390, sind
Funktionen nicht reeentrant, falls nicht explizit anders angegeben (per
Schlüsselwort oder Kommandozeilenoption). Der erzeugte Code ist recht
gut, aber üblicheweise etwas größer als bei den nichtfreien Compilern.
Diese Ports verwenden den neuen Registerallokator (dazu später mehr).
Philipp
Kommen wir zum z80-Port und den verwandten (z180, gbz80, r2k, r3ka,
tlcs90). Der Z80-Port ist recht alt, hat aber im Laufe der Zeit
bedeutende Verbesserungen erfahren. Die anderen Ports sind daraus
entwickelt worden. Der tlcs90-Port hat keinen Simulator, und wird daher
von den regression tests nicht erfasst. Recht effizienter Code wird
generiert für z80, z180, r2k. Bei den anderen gibt es noch etwas mehr
ungenutzes Potential.
Im Vergleich zu den nicht-freien Compilern erzeugt sdcc üblicherweise
besseren Code als CROSS-C und HITECH-C, aber etwas schlechteren als IAR.
Manche dieser Prozessoren haben ein paar komplexe Instruktionen, wie
z.B. ldir. Für einen Compiler ist es nicht einfach, zu erkennen, wann
z.B. eine Schleife mit Hilfe ldir effizienter implementiert werden
könnte. Die Befehle werden aber in den Bibliotheksfunktionen (z.B.
memmove()) genutzt. Und für manche Bibliotheksfunktionen (memcpy(),
strcpy(), strncpy(), strchr(), memset()) wird, wo möglich, auch kein
Funktionsaufruf erzeugt, sondern direkt Code generiert.
Da der Z80 nur ein Prozessor, kein ganzes System ist, gibt es ein paar
Dinge, die der Programmierer erledigen muß (z.B.
Speicherinitialisierung), die ihm bei anderen Ports von sdcc abgenommen
werden. Dazu dient die crt0.
Auch diese Ports verwenden den neuen Registerallokator.
Philipp
Die pic-ports hinken den anderen Ports weit hinterher. Etwas die Hälfte
der offenen Bugreports in sdcc bezieht sich auf pics.
Es gibt den pic14-port für die pics mit 14-bit Instruktionen (z.B.
16Fxxx, 12Fxxx) und den pic16 für die pics mit 16-bit Instruktionen
(z.B. PIC18Fxxx).
Wobei der pic16-port sich deutlich besser schlägt als der pci14 port.
Der pic16 port ist kurz davor, in die nächtlichen regression tests
aufgenommen zu werden. Der pic14-port ist weit davon entfernt. In beide
ports müßte noch viel Arbeit reingesteckt werden.
Philipp
Ich habe die bisherigen Beiträge jetzt 'mal nach
http://www.colecovision.eu/sdcc.shtml
kopiert, und werde sie dort im Laufe des Tages vervollständigen (z.B.
stm8 port) und überarbeiten.
Falls es Fragen zu sdcc gibt, hoffe ich, diese beantworten zu können,
und würe je nachdem, die Antworten auch dort einarbeiten.
Philipp
--
link repariert
-rufus
Danke für die Infos. Ich habe vor kurzem angefangen den cc1111 mit dem
sdcc zu programmieren und habe mich gewundert dass Funktionen
Standardmäßig nicht reentrant sind. Wenn man das aber per
compilerschalter aktiviert, funktionieren die Standard libs nicht mehr
richtig.
Ansonsten lief das ganze echt problemlos. Da ich von der avr und stm32
Seite kam habe ich erst nicht so ganz durchgeblickt bei den
verschiedenen Speichermodellen, aber das scheint generell eine 8051
Sache zu sein.
Hi, ich schätze die Frage passt hier ganz gut rein. Ich versuche mit dem
sdcc FUZIX zu kompilieren (https://github.com/EtchedPixels/FUZIX) doch
mit der 3.4.0er Version funktioniert das nicht. Unter anderem wegen dem
long long bug. In der Readme für den FUZIX-Kernel steht, ich solle den
3.4.2 benutzen, aber ich finde den auf sf nicht. Nur den 3.4.0 oder den
3.4.4 im trunk. Ich habe den im trunk zwar mal ausprobiert, aber wie zu
erwarten hat der natürlich nicht wirklich funktioniert. Ist auch nicht
weiter verwunderlich ;)
Aber offensichtlich gibt es noch 3 Versionen nach dem 3.4.0 von dem sdcc
im Umlauf, die scheinbar stable sind? Wo kann man sich den Code dazu
runterladen?
MfG
Tobias
In dem Readme steht eine explizite Version von dem sdcc ab wann sich die
Quellen kompilieren lassen, weil die vorherigen Versionen eben den long
long Bug besitzen.
Diese Version (3.4.2) ist jedoch wohl keine offizielle Releaseversion
(die letzte Releaseversion ist 3.4.0), daher finde ich sie dort auch
nicht.
Eine bestimmte Revision auschecken ist auch eine Möglichkeit, jedoch
müsste ich dazu wissen, welche Revision denn nun eine stabile Version
ist ;)
MfG
Tobias
tobias schrieb:> Eine bestimmte Revision auschecken ist auch eine Möglichkeit, jedoch> müsste ich dazu wissen, welche Revision denn nun eine stabile Version> ist ;)
Ab welcher SVN-Revision die Versionsnr. 3.4.2 vergeben wurde, ist mit
"svn log .version" leicht herauszufinden.
(Und dann "svn update --revision 9143")