Sto scrivendo un targeting per compilatore giocattolo su x86-64
di macchine. Ma mi trovo di fronte a diversi problemi nell'implementare l'allocazione dei registri con la rappresentazione intermedia lineare. Uso NASM e GCC per generare file eseguibili.
Nella rappresentazione intermedia del codice di origine, assumiamo che ci siano registri infiniti (la memoria è considerata una sorta di registro virtuale). Li ho divisi in due tipi:
-
Registri singoli: questo tipo di registro virtuale rappresenta una variabile tipica.
-
Registri di offset: questo tipo di registro virtuale viene utilizzato per rappresentare l'accesso a un elemento di una matrice o di un membro di una struttura. Ad esempio, quando si traducono istruzioni come
a.x = 3
eb[i] = 3
in rappresentazione intermedia, possiamo rappresentarlo comemov [$a + 0], 3
emov [$b + $i * 4], 3
(4
è la dimensione di un intero), dove$a
,$b
e$i
sono registri singoli e[$a + 0]
e[$b + $i * 4]
sono registri di offset.
Tuttavia, in x86-64
macchina, l'accesso alla memoria può essere rappresentato solo come [$reg1 + $reg2 * imm1 + imm2]
, dove $reg1
e $reg2
sono registri fisici e imm1
e imm2
sono numeri immediati. Non riesco a capire come gli algoritmi di allocazione del registro si occupino del caso in cui l'algoritmo segni $va
e $vb
come nodo spillato con istruzione mov [$va + $vb * 4], 3
. In altre parole, $va
e $vb
devono essere un registro fisico piuttosto che un accesso alla memoria, ma se un registro virtuale è contrassegnato come nodo spillato, sarà considerato come accesso alla memoria allo stack frame.
Ad esempio, ottengo il seguente codice simile a C di origine:
int main() {
int [] a = new int[10];
int i = 3;
a[i] = 4;
}
E lo traduco nella seguente rappresentazione intermedia:
call malloc, 10
mov $a, $retval ; $retval is the return value of malloc
mov $i, 3
mov [$a + $i * 4], 4
Tuttavia, dopo aver assegnato i registri, trovo che il codice finale diventa:
push rbp
mov rbp, rsp
sub rsp, 16
mov rdi, 10
call malloc
mov qword [rbp-8], rax
mov qword [rbp-16], 3
mov [qword [rbp-8] + qword [rbp-16] * 4], 3 <- Compliation error occurs here
Mi chiedo se esiste una buona implementazione per risolvere questo problema. Grazie in anticipo.
UPD: Basile-Starynkevitch mi ha fornito un documento che mostra come GCC risolve questo problema. E sto cercando alcuni (probabilmente) metodi più semplici.