WIP: Register allocator

This commit is contained in:
Tristan B. Kildaire 2021-11-02 17:03:38 +02:00
parent 0352f96c16
commit 09233633a0
3 changed files with 181 additions and 6 deletions

View File

@ -6,8 +6,9 @@ import std.container.slist : SList;
import compiler.codegen.instruction;
import std.stdio;
import std.file;
import std.conv : to;
import std.string : cmp;
import compiler.codegen.emit.dgenregs;
public final class DCodeEmitter : CodeEmitter
{
@ -56,6 +57,76 @@ public final class DCodeEmitter : CodeEmitter
`);
}
private SList!(Register) registers;
private void initRegisterFile()
{
/* R's registers */
for(ulong i = 0; i <= 6; i++)
{
/* Generate R-prefix */
string prefix = "R";
/* Tack on number */
prefix = prefix~to!(string)(i+8);
RichardRegister register = new RichardRegister(prefix);
registers.insert(register);
}
/* TODO: Add othe registers (and in dgenregs.d) */
}
private Register getRegister(ubyte size)
{
foreach(Register register; registers)
{
if(!register.isInUse())
{
foreach(ubyte sizeC; register.getSupportedSizes())
{
if(sizeC == size)
{
register.allocate(size);
return register;
}
}
}
}
return null;
}
public string emitAndProcessExpression(Instruction instr)
{
string registerToCheck;
/**
* Literal case
*/
if(cast(LiteralValue)instr)
{
LiteralValue litValInstr = cast(LiteralValue)instr;
Register valReg = getRegister(litValInstr.len);
}
return registerToCheck;
}
public override void emit()
{
/* Emit initial struccture */
@ -129,7 +200,15 @@ public final class DCodeEmitter : CodeEmitter
{
VariableAssignmentInstr varAssInstr = cast(compiler.codegen.instruction.VariableAssignmentInstr)instruction;
/* Value Instruction */
Instruction valInstr = varAssInstr.data;
/**
* Process the expression (emitting code along the way)
* and return the register the value will be placed in
*/
string valueRegister = emitAndProcessExpression(valInstr);
/* Recursively descend soon */

View File

@ -0,0 +1,99 @@
module compiler.codegen.emit.dgenregs;
import compiler.codegen.emit.core : CodeEmitter;
import compiler.typecheck.core;
import std.container.slist : SList;
import compiler.codegen.instruction;
import std.stdio;
import std.file;
import std.conv : to;
import std.string : cmp;
public class Register
{
public abstract bool isInUse();
public string getUsableName();
public void allocate(ubyte size);
public ubyte[] getSupportedSizes();
public void deallocate();
public void free();
}
/**
* Support for x86_64's R8-R14 (R15 excluded for now)
*
* Example: R14B, R14W
*/
public final class RichardRegister : Register
{
/* Which of the Richards? */
private string richardBase;
/* Current allocated size and name */
private ubyte curSize;
private string curName;
/* State of usage */
private bool inUse;
/**
* Construct a new RichardRegister with base
* RX prefix
*/
this(string XPrefix)
{
richardBase = "R"~XPrefix;
}
public override ubyte[] getSupportedSizes()
{
return [1,2,4,8];
}
public override void free()
{
inUse = false;
}
public override void allocate(ubyte size)
{
curSize = size;
inUse = true;
if(size == 1)
{
curName = richardBase~"B";
}
else if(size == 2)
{
curName = richardBase~"W";
}
else if(size == 4)
{
curName = richardBase~"D";
}
else if(size == 8)
{
curName = richardBase~"";
}
}
public override bool isInUse()
{
return inUse;
}
}

3
test.d
View File

@ -10,19 +10,16 @@ void main()
asm
{
sub RSP, 4;
mov dword ptr [RSP], 69;
}
asm
{
sub RSP, 4;
mov dword ptr [RSP], 69;
}
asm
{
sub RSP, 4;
mov dword ptr [RSP], 69;
}