2012-01-01 3 views
36

Quale sarebbe il modo più semplice per creare un compilatore C per una CPU personalizzata, presumendo che io abbia già un assemblatore per questo?Come creare un compilatore C per CPU personalizzata?

Poiché un compilatore C genera un assembly, esiste un modo per definire solo bit e pezzi standard di codice assembly per i vari idiomi C, ricostruire il compilatore e quindi ottenere un cross-compilatore per l'hardware di destinazione?

Preferibilmente il compilatore stesso verrebbe scritto in C e creato come eseguibile nativo per Linux o Windows.

Si prega di notare: Sono non chiedendo come scrivere il compilatore stesso. Ho frequentato quel corso all'università, so di compilatori-compilatori generali, ecc. In questa situazione, mi piacerebbe solo configurare un quadro esistente se possibile. Non voglio modificare la lingua, voglio solo essere in grado di indirizzare un'architettura arbitraria. Se la risposta risulta essere "non funziona in questo modo", che le informazioni saranno utili a me stesso ea chiunque altro possa fare ipotesi simili.

+4

Non esiste un requisito * fondamentale * che il compilatore produca assemblatore: è solo una pratica comune e conveniente. – dmckee

+0

@dmckee - supponiamo che sia un requisito in questo caso. So che ci sono quelli in questa comunità che avrebbero una risposta per questo. Si prega di notare, la risposta per quello che sto chiedendo è * non * "andare a prendere un corso di scrittura del compilatore". – JustJeff

+1

PS: Supponendo che tu abbia questa CPU personalizzata che è così nuova di zecca non hai nemmeno un compilatore per questo. Dov'è il * OS * che verrà da ??? Cosa intendi per "eseguibile nativo"? Nativo a * COSA *?!? – paulsm4

risposta

29

Quick overview/tutorial on writing a LLVM backend.

Questo documento descrive le tecniche per la scrittura di backend per LLVM che converte la rappresentazione LLVM in codice di assemblaggio della macchina o in altre lingue.

[. . . ]

Per creare un compilatore statico (uno che emette il montaggio di testo), è necessario implementare il seguente:

  • descrivere l'insieme registro.
  • Descrivere il set di istruzioni.
  • Descrivi la macchina di destinazione.
  • Implementare la stampante di assemblaggio per l'architettura.
  • Implementare un selettore di istruzioni per l'architettura.
+0

LLVM è molto complesso e totalmente non documentato. Non toccarlo nemmeno. Ha sprecato 1 mese della mia vita. – Ehsan

+3

Sono la stessa persona che ha lasciato il commento precedente. Sto lavorando su LLVM per un anno e mezzo già. Potrei sviluppare il mio backend e assemblare. Ci vuole un anno per capire l'infrastruttura di LLVM, ma immagino ne valga la pena. – Ehsan

+1

@Ehsan Pensi di poter scrivere della documentazione? :-D – wizzwizz4

8

C'è il concetto di un cross-compiler, cioè, uno che gira su un'architettura, ma ne sceglie uno diverso. Puoi vedere come GCC lo fa (per esempio) e aggiungere una nuova architettura al set, se è il compilatore che vuoi estendere.

Edit: Ho appena notato una domanda di qualche anno fa su una mailing list GCC su come aggiungere un nuovo target e qualcuno indicò this

+0

Sì. Come si aggiunge una nuova architettura. Si prega di elaborare? – JustJeff

+1

Modificato la risposta con un collegamento. È un documento un po 'grande, ma immagino che sia la strada da percorrere ... –

+1

Hai mai * guardato * alla sorgente GCC per vedere come funziona? PS: * do * guarda il sorgente gcc, e * anche * guarda LLVM. Penso che troverai sia informativo ... – paulsm4

3

1) Risposta breve:

"No. Non c'è cosa come un 'quadro compilatore' dove si può solo aggiungere acqua (spina nel vostro kit di montaggio), mescolare, ed è fatta ".

2) Risposta più lunga: è certamente possibile. Ma impegnativo. E probabilmente costoso.

Se volessi farlo da solo, inizierei guardando Gnu CC. È già disponibile per una grande varietà di CPU e piattaforme.

3) Date un'occhiata a questo link per ulteriori idee (tra cui l'idea di "solo costruire una libreria di funzioni e macro"), che sarebbe stato il mio primo suggerimento:

http://www.instructables.com/answers/Custom-C-Compiler-for-homemade-instruction-set/

+1

Al giorno d'oggi LLVM è una struttura "basta aggiungere acqua"? –

3

Il corto la risposta è che non funziona in questo modo.

La risposta più lunga è che richiede un certo sforzo scrivere un compilatore per un nuovo tipo di CPU. Non è necessario creare un compilatore da zero, tuttavia. La maggior parte dei compilatori sono strutturati in diversi passaggi; Ecco un'architettura tipica (sono possibili molte variazioni):

  1. Analisi sintattica (lexer e parser) e per la preelaborazione C, che conduce a un albero di sintassi astratto.
  2. Controllo tipo, che porta a un albero di sintassi astratto annotato.
  3. Generazione di codice intermedio, che conduce a un codice intermedio indipendente dall'architettura. Alcune ottimizzazioni vengono eseguite in questa fase.
  4. Generazione codice macchina, che porta all'assemblaggio o direttamente al codice macchina. Altre ottimizzazioni vengono eseguite in questa fase.

In questa descrizione, solo il passaggio 4 dipende dalla macchina. Quindi puoi prendere un compilatore in cui il passaggio 4 è chiaramente separato e collegare il tuo passaggio 4. Ciò richiede una profonda comprensione della CPU e una certa comprensione degli interni del compilatore, ma non devi preoccuparti di ciò che accade prima.

Quasi tutte le CPU che non sono molto piccole, molto rare o molto vecchie hanno un backend (passaggio 4) per GCC. La documentazione principale per scrivere un backend GCC è la GCC internals manual, in particolare i capitoli su machine descriptions e target descriptions. GCC è un software gratuito, quindi non ci sono costi di licenza per utilizzarlo.

1

È possibile modificare i compilatori open source esistenti come GCC o Clang. Altre risposte ti hanno fornito link su dove saperne di più. Ma questi compilatori non sono progettati per facilmente reindirizzato; sono "più facili" da reimpostare rispetto ai compilatori rispetto ad altri compilatori cablati per obiettivi specifici.

Ma se si desidera un compilatore relativamente facile da retarget, si desidera uno in cui è possibile specificare l'architettura della macchina in termini espliciti e alcuni strumenti generano il resto del compilatore (GCC fa un po 'di questo; non credo che Clang/LLVM faccia molto ma potrei sbagliarmi qui).

C'è molto di questo in letteratura, google "compilatore-compilatore".

Ma per una soluzione concreta per C, è necessario verificare ACE, un fornitore di compilatore che genera compilatori su richiesta per i clienti. Non libero, ma ho sentito che producono molto buoni compilatori molto velocemente. Penso che produca binari di stile standard (ELF?) Così salta la fase di assemblaggio. (Non ho esperienza o relazione con ACE.)

Se non ti interessa la qualità del codice, è probabile che tu possa scrivere una traduzione diretta di sintassi di C sull'assemblatore utilizzando un C AST. È possibile ottenere C AST da GCC, Clang, forse ANTLR e dal nostro DMS Software Reengineering Toolkit.

1

vbcc (all'indirizzo www.compilers.de) è un semplice e semplice compilatore C retargetable scritto in C. È molto più semplice di GCC/LLVM.È così semplice che sono riuscito a reimpostare il compilatore sulla mia CPU con poche settimane di lavoro senza avere alcuna conoscenza preliminare dei compilatori.

+0

Opzione interessante. Di solito le persone non pensano nemmeno ai compilatori gratuiti al di fuori della famiglia gcc/clang/llvm. Puoi approfondire un po 'l'OP su come è stato fatto il processo di retargeting? (ad esempio, esiste una fase intermedia definita "codice macchina generico" da cui si scrive semplicemente un traduttore più o meno diretto nel set di istruzioni CPU reale?) – dodgethesteamroller

+0

Sì, il front-end del compilatore VBCC emette un codice macchina generico di ordinamenti . Sta chiamando la funzione di back-end (quelle che devi scrivere) per tradurre queste istruzioni nelle istruzioni dell'assemblea di destinazione. Il compilatore è abbastanza potente e offre una buona ottimizzazione. Ci vuole pochissimo tempo per ottenere un backend funzionante (anche se non molto ottimizzante). Se il tuo obiettivo è raggiungere il miglior codice possibile, allora diventa un po 'più difficile. – dsula