ref: 8865ed9510427f9af64eeeaa18f8209c91aeb456
dir: /8/regalloc.c/
#include <stdlib.h> #include <stdio.h> #include <stdint.h> #include <stdarg.h> #include <ctype.h> #include <string.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "parse.h" #include "asm.h" const Mode regmodes[] = { #define Reg(r, name, mode) mode, #include "regs.def" #undef Reg }; const char *regnames[] = { #define Reg(r, name, mode) name, #include "regs.def" #undef Reg }; const Reg reginterferes[Nreg][Nmode + 1] = { /* byte */ [Ral] = {Ral, Rax, Reax}, [Rcl] = {Rcl, Rcx, Recx}, [Rdl] = {Rdl, Rdx, Redx}, [Rbl] = {Rbl, Rbx, Rebx}, /* word */ [Rax] = {Ral, Rax, Reax}, [Rcx] = {Rcl, Rcx, Recx}, [Rdx] = {Rdl, Rdx, Redx}, [Rbx] = {Rbl, Rbx, Rebx}, [Rsi] = {Rsi, Resi}, [Rdi] = {Rdi, Redi}, /* dword */ [Reax] = {Ral, Rax, Reax}, [Recx] = {Rcl, Rcx, Recx}, [Redx] = {Rdl, Rdx, Redx}, [Rebx] = {Rbl, Rbx, Rebx}, [Resi] = {Rsi, Resi}, [Redi] = {Rdi, Redi}, [Resp] = {Resp}, [Rebp] = {Rebp}, }; Loc *locstrlbl(Loc *l, char *lbl) { l->type = Loclbl; l->mode = ModeL; l->lbl = strdup(lbl); return l; } Loc *loclbl(Loc *l, Node *lbl) { assert(lbl->type = Nlbl); return locstrlbl(l, lbl->lbl.name); } Loc *locreg(Loc *l, Reg r) { l->type = Locreg; l->mode = regmodes[r]; l->reg = r; return l; } Loc *locmem(Loc *l, long disp, Reg base, Reg idx, Mode mode) { l->type = Locmem; l->mode = mode; l->mem.constdisp = disp; l->mem.base = base; l->mem.idx = idx; l->mem.scale = 0; return l; } Loc *locmems(Loc *l, long disp, Reg base, Reg idx, int scale, Mode mode) { locmem(l, disp, base, idx, mode); l->mem.scale = scale; return l; } Loc *locmeml(Loc *l, char *disp, Reg base, Reg idx, Mode mode) { l->type = Locmem; l->mode = mode; l->mem.lbldisp = strdup(disp); l->mem.base = base; l->mem.idx = idx; l->mem.scale = 0; return l; } Loc *locmemls(Loc *l, char *disp, Reg base, Reg idx, int scale, Mode mode) { locmeml(l, disp, base, idx, mode); l->mem.scale = scale; return l; } Loc *loclit(Loc *l, long val) { l->type = Loclit; l->mode = ModeL; /* FIXME: what do we do for mode? */ l->lit = val; return l; } Loc getreg(Isel *s, Mode m) { Loc l; int i; assert(m != ModeNone); l.reg = Rnone; for (i = 0; i < Nreg; i++) { if (!s->rtaken[i] && regmodes[i] == m) { locreg(&l, i); break; } } if (l.reg == Rnone) die("Not enough registers. Please split your expression and try again (FIXME: implement spilling)"); for (i = 0; i < Nmode; i++) s->rtaken[reginterferes[l.reg][i]] = 1; return l; } Loc claimreg(Isel *s, Reg r) { Loc l; int i; if (s->rtaken[r]) die("Reg %s is already taken", regnames[r]); for (i = 0; i < Nmode; i++) s->rtaken[reginterferes[r][i]] = 1; locreg(&l, r); return l; } void freereg(Isel *s, Reg r) { int i; for (i = 0; i < Nmode; i++) s->rtaken[reginterferes[r][i]] = 0; } void freeloc(Isel *s, Loc l) { if (l.type == Locreg) freereg(s, l.reg); }