begin moving register allocator out of compiler.cpp

This commit is contained in:
Joshua Warner 2013-02-11 21:31:19 -07:00
parent 34471e5d60
commit ef5e534e1e
11 changed files with 225 additions and 109 deletions

View File

@ -953,6 +953,8 @@ embed-objects = $(call cpp-objects,$(embed-sources),$(src),$(build-embed))
ifeq ($(process),compile) ifeq ($(process),compile)
vm-sources += \ vm-sources += \
$(src)/codegen/compiler.cpp \ $(src)/codegen/compiler.cpp \
$(src)/codegen/regalloc.cpp \
$(src)/codegen/registers.cpp \
$(src)/codegen/targets.cpp $(src)/codegen/targets.cpp
ifeq ($(codegen-targets),native) ifeq ($(codegen-targets),native)

View File

@ -8,11 +8,12 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
#include "codegen/assembler.h"
#include "codegen/registers.h"
#include "alloc-vector.h" #include "alloc-vector.h"
#include "util/abort.h" #include "util/abort.h"
#include "codegen/assembler.h"
#include "util/runtime-array.h" #include "util/runtime-array.h"
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x) #define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
@ -210,6 +211,9 @@ const uint64_t GPR_MASK64 = GPR_MASK | (uint64_t)GPR_MASK << 32;
// making the following const somehow breaks debug symbol output in GDB // making the following const somehow breaks debug symbol output in GDB
/* const */ uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32; /* const */ uint64_t FPR_MASK64 = FPR_MASK | (uint64_t)FPR_MASK << 32;
const RegisterFile MyRegisterFileWithoutFloats(GPR_MASK, 0);
const RegisterFile MyRegisterFileWithFloats(GPR_MASK, FPR_MASK);
inline bool isFpr(lir::Register* reg) { inline bool isFpr(lir::Register* reg) {
return reg->low >= N_GPRS; return reg->low >= N_GPRS;
} }
@ -2057,12 +2061,8 @@ class MyArchitecture: public Assembler::Architecture {
return vfpSupported() ? 8 : 0; return vfpSupported() ? 8 : 0;
} }
virtual uint32_t generalRegisterMask() { virtual const RegisterFile* registerFile() {
return GPR_MASK; return vfpSupported() ? &MyRegisterFileWithFloats : &MyRegisterFileWithoutFloats;
}
virtual uint32_t floatRegisterMask() {
return vfpSupported() ? FPR_MASK : 0;
} }
virtual int scratch() { virtual int scratch() {

View File

@ -20,6 +20,8 @@
namespace avian { namespace avian {
namespace codegen { namespace codegen {
class RegisterFile;
class OperandInfo { class OperandInfo {
public: public:
const unsigned size; const unsigned size;
@ -66,8 +68,7 @@ class Assembler {
public: public:
virtual unsigned floatRegisterSize() = 0; virtual unsigned floatRegisterSize() = 0;
virtual uint32_t generalRegisterMask() = 0; virtual const RegisterFile* registerFile() = 0;
virtual uint32_t floatRegisterMask() = 0;
virtual int scratch() = 0; virtual int scratch() = 0;
virtual int stack() = 0; virtual int stack() = 0;

View File

@ -8,12 +8,14 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
#include "compiler.h"
#include "assembler.h"
#include "target.h" #include "target.h"
#include "util/runtime-array.h" #include "util/runtime-array.h"
#include "codegen/compiler.h"
#include "codegen/assembler.h"
#include "codegen/regalloc.h"
using namespace vm; using namespace vm;
using namespace avian::codegen; using namespace avian::codegen;
@ -338,30 +340,6 @@ class Value: public Compiler::Operand {
uint8_t wordIndex; uint8_t wordIndex;
}; };
uint32_t
registerMask(Assembler::Architecture* arch)
{
return arch->generalRegisterMask() | arch->floatRegisterMask();
}
unsigned
maskStart(uint32_t mask)
{
for (int i = 0; i <= 31; ++i) {
if (mask & (1 << i)) return i;
}
return 32;
}
unsigned
maskLimit(uint32_t mask)
{
for (int i = 31; i >= 0; --i) {
if (mask & (1 << i)) return i + 1;
}
return 0;
}
class Context { class Context {
public: public:
Context(System* system, Assembler* assembler, Zone* zone, Context(System* system, Assembler* assembler, Zone* zone,
@ -376,15 +354,11 @@ class Context {
saved(0), saved(0),
predecessor(0), predecessor(0),
logicalCode(0), logicalCode(0),
registerStart(maskStart(registerMask(arch))), regFile(arch->registerFile()),
registerLimit(maskLimit(registerMask(arch))), regAlloc(system, arch->registerFile()),
generalRegisterStart(maskStart(arch->generalRegisterMask())),
generalRegisterLimit(maskLimit(arch->generalRegisterMask())),
floatRegisterStart(maskStart(arch->floatRegisterMask())),
floatRegisterLimit(maskLimit(arch->floatRegisterMask())),
registerResources registerResources
(static_cast<RegisterResource*> (static_cast<RegisterResource*>
(zone->allocate(sizeof(RegisterResource) * registerLimit))), (zone->allocate(sizeof(RegisterResource) * regFile->allRegisters.limit))),
frameResources(0), frameResources(0),
acquiredResources(0), acquiredResources(0),
firstConstant(0), firstConstant(0),
@ -402,16 +376,16 @@ class Context {
localFootprint(0), localFootprint(0),
machineCodeSize(0), machineCodeSize(0),
alignedFrameSize(0), alignedFrameSize(0),
availableGeneralRegisterCount(generalRegisterLimit - generalRegisterStart) availableGeneralRegisterCount(regFile->generalRegisters.limit - regFile->generalRegisters.start)
{ {
for (unsigned i = generalRegisterStart; i < generalRegisterLimit; ++i) { for (unsigned i = regFile->generalRegisters.start; i < regFile->generalRegisters.limit; ++i) {
new (registerResources + i) RegisterResource(arch->reserved(i)); new (registerResources + i) RegisterResource(arch->reserved(i));
if (registerResources[i].reserved) { if (registerResources[i].reserved) {
-- availableGeneralRegisterCount; -- availableGeneralRegisterCount;
} }
} }
for (unsigned i = floatRegisterStart; i < floatRegisterLimit; ++i) { for (unsigned i = regFile->floatRegisters.start; i < regFile->floatRegisters.limit; ++i) {
new (registerResources + i) RegisterResource(arch->reserved(i)); new (registerResources + i) RegisterResource(arch->reserved(i));
} }
} }
@ -426,12 +400,8 @@ class Context {
Cell* saved; Cell* saved;
Event* predecessor; Event* predecessor;
LogicalInstruction** logicalCode; LogicalInstruction** logicalCode;
uint8_t registerStart; const RegisterFile* regFile;
uint8_t registerLimit; regalloc::RegisterAllocator regAlloc;
uint8_t generalRegisterStart;
uint8_t generalRegisterLimit;
uint8_t floatRegisterStart;
uint8_t floatRegisterLimit;
RegisterResource* registerResources; RegisterResource* registerResources;
FrameResource* frameResources; FrameResource* frameResources;
Resource* acquiredResources; Resource* acquiredResources;
@ -1158,7 +1128,7 @@ increment(Context* c, RegisterResource* r)
++ r->referenceCount; ++ r->referenceCount;
if (r->referenceCount == 1 if (r->referenceCount == 1
and ((1 << r->index(c)) & c->arch->generalRegisterMask())) and ((1 << r->index(c)) & c->regFile->generalRegisters.mask))
{ {
decrementAvailableGeneralRegisterCount(c); decrementAvailableGeneralRegisterCount(c);
} }
@ -1179,7 +1149,7 @@ decrement(Context* c, RegisterResource* r)
-- r->referenceCount; -- r->referenceCount;
if (r->referenceCount == 0 if (r->referenceCount == 0
and ((1 << r->index(c)) & c->arch->generalRegisterMask())) and ((1 << r->index(c)) & c->regFile->generalRegisters.mask))
{ {
incrementAvailableGeneralRegisterCount(c); incrementAvailableGeneralRegisterCount(c);
} }
@ -1204,7 +1174,7 @@ RegisterResource::freeze(Context* c, Value* v)
freezeResource(c, this, v); freezeResource(c, this, v);
if (freezeCount == 1 if (freezeCount == 1
and ((1 << index(c)) & c->arch->generalRegisterMask())) and ((1 << index(c)) & c->regFile->generalRegisters.mask))
{ {
decrementAvailableGeneralRegisterCount(c); decrementAvailableGeneralRegisterCount(c);
} }
@ -1239,7 +1209,7 @@ RegisterResource::thaw(Context* c, Value* v)
thawResource(c, this, v); thawResource(c, this, v);
if (freezeCount == 0 if (freezeCount == 0
and ((1 << index(c)) & c->arch->generalRegisterMask())) and ((1 << index(c)) & c->regFile->generalRegisters.mask))
{ {
incrementAvailableGeneralRegisterCount(c); incrementAvailableGeneralRegisterCount(c);
} }
@ -1291,20 +1261,18 @@ valueType(Context* c, Compiler::OperandType type)
class CostCalculator { class CostCalculator {
public: public:
virtual unsigned cost(Context* c, uint8_t typeMask, uint32_t registerMask, virtual unsigned cost(Context* c, SiteMask mask) = 0;
int frameIndex) = 0;
}; };
unsigned unsigned
resourceCost(Context* c, Value* v, Resource* r, uint8_t typeMask, resourceCost(Context* c, Value* v, Resource* r, SiteMask mask,
uint32_t registerMask, int frameIndex,
CostCalculator* costCalculator) CostCalculator* costCalculator)
{ {
if (r->reserved or r->freezeCount or r->referenceCount) { if (r->reserved or r->freezeCount or r->referenceCount) {
return Target::Impossible; return Target::Impossible;
} else { } else {
unsigned baseCost = costCalculator ? costCalculator->cost unsigned baseCost =
(c, typeMask, registerMask, frameIndex) : 0; costCalculator ? costCalculator->cost(c, mask) : 0;
if (r->value) { if (r->value) {
assert(c, findSite(c, r->value, r->site)); assert(c, findSite(c, r->value, r->site));
@ -1329,7 +1297,7 @@ pickRegisterTarget(Context* c, int i, Value* v, uint32_t mask, int* target,
if ((1 << i) & mask) { if ((1 << i) & mask) {
RegisterResource* r = c->registerResources + i; RegisterResource* r = c->registerResources + i;
unsigned myCost = resourceCost unsigned myCost = resourceCost
(c, v, r, 1 << lir::RegisterOperand, 1 << i, NoFrameIndex, costCalculator) (c, v, r, SiteMask(1 << lir::RegisterOperand, 1 << i, NoFrameIndex), costCalculator)
+ Target::MinimumRegisterCost; + Target::MinimumRegisterCost;
if ((static_cast<uint32_t>(1) << i) == mask) { if ((static_cast<uint32_t>(1) << i) == mask) {
@ -1350,9 +1318,9 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
int target = lir::NoRegister; int target = lir::NoRegister;
*cost = Target::Impossible; *cost = Target::Impossible;
if (mask & c->arch->generalRegisterMask()) { if (mask & c->regFile->generalRegisters.mask) {
for (int i = c->generalRegisterLimit - 1; for (int i = c->regFile->generalRegisters.limit - 1;
i >= c->generalRegisterStart; --i) i >= c->regFile->generalRegisters.start; --i)
{ {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i; return i;
@ -1360,9 +1328,9 @@ pickRegisterTarget(Context* c, Value* v, uint32_t mask, unsigned* cost,
} }
} }
if (mask & c->arch->floatRegisterMask()) { if (mask & c->regFile->floatRegisters.mask) {
for (int i = c->floatRegisterStart; for (int i = c->regFile->floatRegisters.start;
i < static_cast<int>(c->floatRegisterLimit); ++i) i < static_cast<int>(c->regFile->floatRegisters.limit); ++i)
{ {
if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) { if (pickRegisterTarget(c, i, v, mask, &target, cost, costCalculator)) {
return i; return i;
@ -1386,7 +1354,7 @@ unsigned
frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator) frameCost(Context* c, Value* v, int frameIndex, CostCalculator* costCalculator)
{ {
return resourceCost return resourceCost
(c, v, c->frameResources + frameIndex, 1 << lir::MemoryOperand, 0, frameIndex, (c, v, c->frameResources + frameIndex, SiteMask(1 << lir::MemoryOperand, 0, frameIndex),
costCalculator) costCalculator)
+ Target::MinimumFrameCost; + Target::MinimumFrameCost;
} }
@ -1482,13 +1450,13 @@ pickTarget(Context* c, Read* read, bool intersectRead,
Value* value = read->value; Value* value = read->value;
uint32_t registerMask uint32_t registerMask
= (value->type == lir::ValueFloat ? ~0 : c->arch->generalRegisterMask()); = (value->type == lir::ValueFloat ? ~0 : c->regFile->generalRegisters.mask);
SiteMask mask(~0, registerMask, AnyFrameIndex); SiteMask mask(~0, registerMask, AnyFrameIndex);
read->intersect(&mask); read->intersect(&mask);
if (value->type == lir::ValueFloat) { if (value->type == lir::ValueFloat) {
uint32_t floatMask = mask.registerMask & c->arch->floatRegisterMask(); uint32_t floatMask = mask.registerMask & c->regFile->floatRegisters.mask;
if (floatMask) { if (floatMask) {
mask.registerMask = floatMask; mask.registerMask = floatMask;
} }
@ -1813,7 +1781,7 @@ class RegisterSite: public Site {
assert(c, number != lir::NoRegister); assert(c, number != lir::NoRegister);
return number == rs->number; return number == rs->number;
} else { } else {
uint32_t mask = c->arch->generalRegisterMask(); uint32_t mask = c->regFile->generalRegisters.mask;
return ((1 << number) & mask) and ((1 << rs->number) & mask); return ((1 << number) & mask) and ((1 << rs->number) & mask);
} }
} }
@ -1899,9 +1867,9 @@ class RegisterSite: public Site {
virtual Site* makeNextWord(Context* c, unsigned) { virtual Site* makeNextWord(Context* c, unsigned) {
assert(c, number != lir::NoRegister); assert(c, number != lir::NoRegister);
assert(c, ((1 << number) & c->arch->generalRegisterMask())); assert(c, ((1 << number) & c->regFile->generalRegisters.mask));
return freeRegisterSite(c, c->arch->generalRegisterMask()); return freeRegisterSite(c, c->regFile->generalRegisters.mask);
} }
virtual SiteMask mask(Context* c UNUSED) { virtual SiteMask mask(Context* c UNUSED) {
@ -1916,14 +1884,14 @@ class RegisterSite: public Site {
(1 << lir::RegisterOperand, number, NoFrameIndex); (1 << lir::RegisterOperand, number, NoFrameIndex);
} else { } else {
return SiteMask return SiteMask
(1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex);
} }
} }
virtual unsigned registerSize(Context* c) { virtual unsigned registerSize(Context* c) {
assert(c, number != lir::NoRegister); assert(c, number != lir::NoRegister);
if ((1 << number) & c->arch->floatRegisterMask()) { if ((1 << number) & c->regFile->floatRegisters.mask) {
return c->arch->floatRegisterSize(); return c->arch->floatRegisterSize();
} else { } else {
return TargetBytesPerWord; return TargetBytesPerWord;
@ -1944,8 +1912,8 @@ RegisterSite*
registerSite(Context* c, int number) registerSite(Context* c, int number)
{ {
assert(c, number >= 0); assert(c, number >= 0);
assert(c, (1 << number) & (c->arch->generalRegisterMask() assert(c, (1 << number) & (c->regFile->generalRegisters.mask
| c->arch->floatRegisterMask())); | c->regFile->floatRegisters.mask));
return new(c->zone) RegisterSite(1 << number, number); return new(c->zone) RegisterSite(1 << number, number);
} }
@ -2382,8 +2350,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord,
includeNextWord(includeNextWord) includeNextWord(includeNextWord)
{ } { }
virtual unsigned cost(Context* c, uint8_t typeMask, uint32_t registerMask, virtual unsigned cost(Context* c, SiteMask dstMask)
int frameIndex)
{ {
uint8_t srcTypeMask; uint8_t srcTypeMask;
uint64_t srcRegisterMask; uint64_t srcRegisterMask;
@ -2392,10 +2359,9 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord,
c->arch->planMove c->arch->planMove
(size, &srcTypeMask, &srcRegisterMask, (size, &srcTypeMask, &srcRegisterMask,
&tmpTypeMask, &tmpRegisterMask, &tmpTypeMask, &tmpRegisterMask,
typeMask, registerMask); dstMask.typeMask, dstMask.registerMask);
SiteMask srcMask(srcTypeMask, srcRegisterMask, AnyFrameIndex); SiteMask srcMask(srcTypeMask, srcRegisterMask, AnyFrameIndex);
SiteMask dstMask(typeMask, registerMask, frameIndex);
for (SiteIterator it(c, value, true, includeNextWord); it.hasMore();) { for (SiteIterator it(c, value, true, includeNextWord); it.hasMore();) {
Site* s = it.next(); Site* s = it.next();
if (s->match(c, srcMask) or s->match(c, dstMask)) { if (s->match(c, srcMask) or s->match(c, dstMask)) {
@ -2615,7 +2581,7 @@ SiteMask
generalRegisterMask(Context* c) generalRegisterMask(Context* c)
{ {
return SiteMask return SiteMask
(1 << lir::RegisterOperand, c->arch->generalRegisterMask(), NoFrameIndex); (1 << lir::RegisterOperand, c->regFile->generalRegisters.mask, NoFrameIndex);
} }
SiteMask SiteMask
@ -2623,7 +2589,7 @@ generalRegisterOrConstantMask(Context* c)
{ {
return SiteMask return SiteMask
((1 << lir::RegisterOperand) | (1 << lir::ConstantOperand), ((1 << lir::RegisterOperand) | (1 << lir::ConstantOperand),
c->arch->generalRegisterMask(), NoFrameIndex); c->regFile->generalRegisters.mask, NoFrameIndex);
} }
SiteMask SiteMask
@ -3143,7 +3109,7 @@ class CallEvent: public Event {
resultSize(resultSize), resultSize(resultSize),
stackArgumentFootprint(stackArgumentFootprint) stackArgumentFootprint(stackArgumentFootprint)
{ {
uint32_t registerMask = c->arch->generalRegisterMask(); uint32_t registerMask = c->regFile->generalRegisters.mask;
if (argumentCount) { if (argumentCount) {
assert(c, (flags & Compiler::TailJump) == 0); assert(c, (flags & Compiler::TailJump) == 0);
@ -3564,7 +3530,7 @@ maybeMove(Context* c, lir::BinaryOperation type, unsigned srcSize,
dstSize, &thunk); dstSize, &thunk);
if (src->type == lir::ValueGeneral) { if (src->type == lir::ValueGeneral) {
srcRegisterMask &= c->arch->generalRegisterMask(); srcRegisterMask &= c->regFile->generalRegisters.mask;
} }
assert(c, thunk == 0); assert(c, thunk == 0);
@ -4374,11 +4340,11 @@ loadLocal(Context* c, unsigned footprint, unsigned index)
Value* Value*
register_(Context* c, int number) register_(Context* c, int number)
{ {
assert(c, (1 << number) & (c->arch->generalRegisterMask() assert(c, (1 << number) & (c->regFile->generalRegisters.mask
| c->arch->floatRegisterMask())); | c->regFile->floatRegisters.mask));
Site* s = registerSite(c, number); Site* s = registerSite(c, number);
lir::ValueType type = ((1 << number) & c->arch->floatRegisterMask()) lir::ValueType type = ((1 << number) & c->regFile->floatRegisters.mask)
? lir::ValueFloat: lir::ValueGeneral; ? lir::ValueFloat: lir::ValueGeneral;
return value(c, type, s, s); return value(c, type, s, s);
@ -5415,7 +5381,7 @@ resolveSourceSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (r and sites[el.localIndex] == 0) { if (r and sites[el.localIndex] == 0) {
SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand),
c->arch->generalRegisterMask(), AnyFrameIndex); c->regFile->generalRegisters.mask, AnyFrameIndex);
Site* s = pickSourceSite Site* s = pickSourceSite
(c, r, 0, 0, &mask, true, false, true, acceptForResolve); (c, r, 0, 0, &mask, true, false, true, acceptForResolve);
@ -5449,7 +5415,7 @@ resolveTargetSites(Context* c, Event* e, SiteRecordList* frozen, Site** sites)
if (r and sites[el.localIndex] == 0) { if (r and sites[el.localIndex] == 0) {
SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand), SiteMask mask((1 << lir::RegisterOperand) | (1 << lir::MemoryOperand),
c->arch->generalRegisterMask(), AnyFrameIndex); c->regFile->generalRegisters.mask, AnyFrameIndex);
Site* s = pickSourceSite Site* s = pickSourceSite
(c, r, 0, 0, &mask, false, true, true, acceptForResolve); (c, r, 0, 0, &mask, false, true, true, acceptForResolve);

View File

@ -8,8 +8,8 @@
There is NO WARRANTY for this software. See license.txt for There is NO WARRANTY for this software. See license.txt for
details. */ details. */
#ifndef COMPILER_H #ifndef AVIAN_CODEGEN_COMPILER_H
#define COMPILER_H #define AVIAN_CODEGEN_COMPILER_H
#include "system.h" #include "system.h"
#include "zone.h" #include "zone.h"
@ -207,4 +207,4 @@ makeCompiler(vm::System* system, Assembler* assembler, vm::Zone* zone,
} // namespace codegen } // namespace codegen
} // namespace avian } // namespace avian
#endif//COMPILER_H #endif // AVIAN_CODEGEN_COMPILER_H

View File

@ -9,6 +9,8 @@
details. */ details. */
#include "codegen/assembler.h" #include "codegen/assembler.h"
#include "codegen/registers.h"
#include "alloc-vector.h" #include "alloc-vector.h"
#include "util/abort.h" #include "util/abort.h"
@ -153,6 +155,8 @@ inline int unha16(int32_t high, int32_t low) {
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low; return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
} }
const RegisterFile MyRegisterFile(0xFFFFFFFF, 0);
inline bool inline bool
isInt16(target_intptr_t v) isInt16(target_intptr_t v)
{ {
@ -2061,12 +2065,8 @@ class MyArchitecture: public Assembler::Architecture {
return 0; return 0;
} }
virtual uint32_t generalRegisterMask() { virtual const RegisterFile* registerFile() {
return 0xFFFFFFFF; return &MyRegisterFile;
}
virtual uint32_t floatRegisterMask() {
return 0;
} }
virtual int scratch() { virtual int scratch() {

24
src/codegen/regalloc.cpp Normal file
View File

@ -0,0 +1,24 @@
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#include "codegen/regalloc.h"
namespace avian {
namespace codegen {
namespace regalloc {
RegisterAllocator::RegisterAllocator(Aborter* a, const RegisterFile* registerFile):
a(a),
registerFile(registerFile)
{ }
} // namespace regalloc
} // namespace codegen
} // namespace avian

37
src/codegen/regalloc.h Normal file
View File

@ -0,0 +1,37 @@
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_CODEGEN_REGALLOC_H
#define AVIAN_CODEGEN_REGALLOC_H
#include "common.h"
#include "codegen/registers.h"
class Aborter;
namespace avian {
namespace codegen {
namespace regalloc {
class RegisterAllocator {
public:
Aborter* a;
const RegisterFile* registerFile;
RegisterAllocator(Aborter* a, const RegisterFile* registerFile);
};
} // namespace regalloc
} // namespace codegen
} // namespace avian
#endif // AVIAN_CODEGEN_REGALLOC_H

35
src/codegen/registers.cpp Normal file
View File

@ -0,0 +1,35 @@
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#include "codegen/registers.h"
namespace avian {
namespace codegen {
unsigned
RegisterMask::maskStart(uint32_t mask)
{
for (int i = 0; i <= 31; ++i) {
if (mask & (1 << i)) return i;
}
return 32;
}
unsigned
RegisterMask::maskLimit(uint32_t mask)
{
for (int i = 31; i >= 0; --i) {
if (mask & (1 << i)) return i + 1;
}
return 0;
}
} // namespace codegen
} // namespace avian

51
src/codegen/registers.h Normal file
View File

@ -0,0 +1,51 @@
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_CODEGEN_REGISTERS_H
#define AVIAN_CODEGEN_REGISTERS_H
#include "common.h"
namespace avian {
namespace codegen {
class RegisterMask {
public:
uint32_t mask;
uint8_t start;
uint8_t limit;
static unsigned maskStart(uint32_t mask);
static unsigned maskLimit(uint32_t mask);
inline RegisterMask(uint32_t mask):
mask(mask),
start(maskStart(mask)),
limit(maskLimit(mask))
{ }
};
class RegisterFile {
public:
RegisterMask allRegisters;
RegisterMask generalRegisters;
RegisterMask floatRegisters;
inline RegisterFile(uint32_t generalRegisterMask, uint32_t floatRegisterMask):
allRegisters(generalRegisterMask | floatRegisterMask),
generalRegisters(generalRegisterMask),
floatRegisters(floatRegisterMask)
{ }
};
} // namespace codegen
} // namespace avian
#endif // AVIAN_CODEGEN_REGISTERS_H

View File

@ -13,6 +13,7 @@
#include "alloc-vector.h" #include "alloc-vector.h"
#include "codegen/assembler.h" #include "codegen/assembler.h"
#include "codegen/registers.h"
#include "util/runtime-array.h" #include "util/runtime-array.h"
#include "util/abort.h" #include "util/abort.h"
@ -72,6 +73,8 @@ const unsigned GeneralRegisterMask
const unsigned FloatRegisterMask const unsigned FloatRegisterMask
= TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000; = TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000;
const RegisterFile MyRegisterFile(GeneralRegisterMask, FloatRegisterMask);
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1); const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
const int LongJumpRegister = r10; const int LongJumpRegister = r10;
@ -2714,7 +2717,8 @@ populateTables(ArchitectureContext* c)
class MyArchitecture: public Assembler::Architecture { class MyArchitecture: public Assembler::Architecture {
public: public:
MyArchitecture(System* system, bool useNativeFeatures): MyArchitecture(System* system, bool useNativeFeatures):
c(system, useNativeFeatures), referenceCount(0) c(system, useNativeFeatures),
referenceCount(0)
{ {
populateTables(&c); populateTables(&c);
} }
@ -2726,13 +2730,9 @@ class MyArchitecture: public Assembler::Architecture {
return 0; return 0;
} }
} }
virtual uint32_t generalRegisterMask() { virtual const RegisterFile* registerFile() {
return GeneralRegisterMask; return &MyRegisterFile;
}
virtual uint32_t floatRegisterMask() {
return useSSE(&c) ? FloatRegisterMask : 0;
} }
virtual int scratch() { virtual int scratch() {