mirror of
https://github.com/corda/corda.git
synced 2025-06-21 00:23:09 +00:00
322 lines
7.9 KiB
C++
322 lines
7.9 KiB
C++
/* Copyright (c) 2008-2013, 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_COMPILER_SITE_H
|
|
#define AVIAN_CODEGEN_COMPILER_SITE_H
|
|
|
|
#include <avian/codegen/architecture.h>
|
|
|
|
#include "codegen/compiler/value.h"
|
|
#include "codegen/compiler/context.h"
|
|
|
|
namespace avian {
|
|
namespace codegen {
|
|
namespace compiler {
|
|
|
|
class Context;
|
|
|
|
const unsigned RegisterCopyCost = 1;
|
|
const unsigned AddressCopyCost = 2;
|
|
const unsigned ConstantCopyCost = 3;
|
|
const unsigned MemoryCopyCost = 4;
|
|
const unsigned CopyPenalty = 10;
|
|
|
|
class SiteMask {
|
|
public:
|
|
SiteMask(): typeMask(~0), registerMask(~0), frameIndex(AnyFrameIndex) { }
|
|
|
|
SiteMask(uint8_t typeMask, uint32_t registerMask, int frameIndex):
|
|
typeMask(typeMask), registerMask(registerMask), frameIndex(frameIndex)
|
|
{ }
|
|
|
|
SiteMask intersectionWith(const SiteMask& b);
|
|
|
|
static SiteMask fixedRegisterMask(int number) {
|
|
return SiteMask(1 << lir::RegisterOperand, 1 << number, NoFrameIndex);
|
|
}
|
|
|
|
static SiteMask lowPart(const OperandMask& mask) {
|
|
return SiteMask(mask.typeMask, mask.registerMask, AnyFrameIndex);
|
|
}
|
|
|
|
static SiteMask highPart(const OperandMask& mask) {
|
|
return SiteMask(mask.typeMask, mask.registerMask >> 32, AnyFrameIndex);
|
|
}
|
|
|
|
uint8_t typeMask;
|
|
uint32_t registerMask;
|
|
int frameIndex;
|
|
};
|
|
|
|
class Site {
|
|
public:
|
|
Site(): next(0) { }
|
|
|
|
virtual Site* readTarget(Context*, Read*) { return this; }
|
|
|
|
virtual unsigned toString(Context*, char*, unsigned) = 0;
|
|
|
|
virtual unsigned copyCost(Context*, Site*) = 0;
|
|
|
|
virtual bool match(Context*, const SiteMask&) = 0;
|
|
|
|
virtual bool loneMatch(Context*, const SiteMask&) = 0;
|
|
|
|
virtual bool matchNextWord(Context*, Site*, unsigned) = 0;
|
|
|
|
virtual void acquire(Context*, Value*) { }
|
|
|
|
virtual void release(Context*, Value*) { }
|
|
|
|
virtual void freeze(Context*, Value*) { }
|
|
|
|
virtual void thaw(Context*, Value*) { }
|
|
|
|
virtual bool frozen(Context*) { return false; }
|
|
|
|
virtual lir::OperandType type(Context*) = 0;
|
|
|
|
virtual void asAssemblerOperand(Context*, Site*, lir::Operand*) = 0;
|
|
|
|
virtual Site* copy(Context*) = 0;
|
|
|
|
virtual Site* copyLow(Context*) = 0;
|
|
|
|
virtual Site* copyHigh(Context*) = 0;
|
|
|
|
virtual Site* makeNextWord(Context*, unsigned) = 0;
|
|
|
|
virtual SiteMask mask(Context*) = 0;
|
|
|
|
virtual SiteMask nextWordMask(Context*, unsigned) = 0;
|
|
|
|
virtual unsigned registerSize(Context*);
|
|
|
|
virtual unsigned registerMask(Context*) { return 0; }
|
|
|
|
virtual bool isVolatile(Context*) { return false; }
|
|
|
|
Site* next;
|
|
};
|
|
|
|
class SiteIterator {
|
|
public:
|
|
SiteIterator(Context* c, Value* v, bool includeBuddies = true,
|
|
bool includeNextWord = true);
|
|
|
|
Site** findNext(Site** p);
|
|
bool hasMore();
|
|
Site* next();
|
|
void remove(Context* c);
|
|
|
|
Context* c;
|
|
Value* originalValue;
|
|
Value* currentValue;
|
|
bool includeBuddies;
|
|
bool includeNextWord;
|
|
uint8_t pass;
|
|
Site** next_;
|
|
Site** previous;
|
|
};
|
|
|
|
Site* constantSite(Context* c, Promise* value);
|
|
Site* constantSite(Context* c, int64_t value);
|
|
|
|
Promise* combinedPromise(Context* c, Promise* low, Promise* high);
|
|
Promise* shiftMaskPromise(Context* c, Promise* base, unsigned shift, int64_t mask);
|
|
|
|
class ConstantSite: public Site {
|
|
public:
|
|
ConstantSite(Promise* value): value(value) { }
|
|
|
|
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize) {
|
|
if (value->resolved()) {
|
|
return vm::snprintf
|
|
(buffer, bufferSize, "constant %" LLD, value->value());
|
|
} else {
|
|
return vm::snprintf(buffer, bufferSize, "constant unresolved");
|
|
}
|
|
}
|
|
|
|
virtual unsigned copyCost(Context*, Site* s) {
|
|
return (s == this ? 0 : ConstantCopyCost);
|
|
}
|
|
|
|
virtual bool match(Context*, const SiteMask& mask) {
|
|
return mask.typeMask & (1 << lir::ConstantOperand);
|
|
}
|
|
|
|
virtual bool loneMatch(Context*, const SiteMask&) {
|
|
return true;
|
|
}
|
|
|
|
virtual bool matchNextWord(Context* c, Site* s, unsigned) {
|
|
return s->type(c) == lir::ConstantOperand;
|
|
}
|
|
|
|
virtual lir::OperandType type(Context*) {
|
|
return lir::ConstantOperand;
|
|
}
|
|
|
|
virtual void asAssemblerOperand(Context* c, Site* high,
|
|
lir::Operand* result)
|
|
{
|
|
Promise* v = value;
|
|
if (high != this) {
|
|
v = combinedPromise(c, value, static_cast<ConstantSite*>(high)->value);
|
|
}
|
|
new (result) lir::Constant(v);
|
|
}
|
|
|
|
virtual Site* copy(Context* c) {
|
|
return constantSite(c, value);
|
|
}
|
|
|
|
virtual Site* copyLow(Context* c) {
|
|
return constantSite(c, shiftMaskPromise(c, value, 0, 0xFFFFFFFF));
|
|
}
|
|
|
|
virtual Site* copyHigh(Context* c) {
|
|
return constantSite(c, shiftMaskPromise(c, value, 32, 0xFFFFFFFF));
|
|
}
|
|
|
|
virtual Site* makeNextWord(Context* c, unsigned) {
|
|
abort(c);
|
|
}
|
|
|
|
virtual SiteMask mask(Context*) {
|
|
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
|
|
}
|
|
|
|
virtual SiteMask nextWordMask(Context*, unsigned) {
|
|
return SiteMask(1 << lir::ConstantOperand, 0, NoFrameIndex);
|
|
}
|
|
|
|
Promise* value;
|
|
};
|
|
|
|
Site* addressSite(Context* c, Promise* address);
|
|
|
|
class RegisterSite: public Site {
|
|
public:
|
|
RegisterSite(uint32_t mask, int number);
|
|
|
|
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize);
|
|
|
|
virtual unsigned copyCost(Context* c, Site* s);
|
|
|
|
virtual bool match(Context* c UNUSED, const SiteMask& mask);
|
|
|
|
virtual bool loneMatch(Context* c UNUSED, const SiteMask& mask);
|
|
|
|
virtual bool matchNextWord(Context* c, Site* s, unsigned);
|
|
|
|
virtual void acquire(Context* c, Value* v);
|
|
|
|
virtual void release(Context* c, Value* v);
|
|
|
|
virtual void freeze(Context* c, Value* v);
|
|
|
|
virtual void thaw(Context* c, Value* v);
|
|
|
|
virtual bool frozen(Context* c UNUSED);
|
|
|
|
virtual lir::OperandType type(Context*);
|
|
|
|
virtual void asAssemblerOperand(Context* c UNUSED, Site* high,
|
|
lir::Operand* result);
|
|
|
|
virtual Site* copy(Context* c);
|
|
|
|
virtual Site* copyLow(Context* c);
|
|
|
|
virtual Site* copyHigh(Context* c);
|
|
|
|
virtual Site* makeNextWord(Context* c, unsigned);
|
|
|
|
virtual SiteMask mask(Context* c UNUSED);
|
|
|
|
virtual SiteMask nextWordMask(Context* c, unsigned);
|
|
|
|
virtual unsigned registerSize(Context* c);
|
|
|
|
virtual unsigned registerMask(Context* c UNUSED);
|
|
|
|
uint32_t mask_;
|
|
int number;
|
|
};
|
|
|
|
Site* registerSite(Context* c, int number);
|
|
Site* freeRegisterSite(Context* c, uint32_t mask);
|
|
|
|
|
|
class MemorySite: public Site {
|
|
public:
|
|
MemorySite(int base, int offset, int index, unsigned scale);
|
|
|
|
virtual unsigned toString(Context*, char* buffer, unsigned bufferSize);
|
|
|
|
virtual unsigned copyCost(Context* c, Site* s);
|
|
|
|
bool conflicts(const SiteMask& mask);
|
|
|
|
virtual bool match(Context* c, const SiteMask& mask);
|
|
|
|
virtual bool loneMatch(Context* c, const SiteMask& mask);
|
|
|
|
virtual bool matchNextWord(Context* c, Site* s, unsigned index);
|
|
|
|
virtual void acquire(Context* c, Value* v);
|
|
|
|
virtual void release(Context* c, Value* v);
|
|
|
|
virtual void freeze(Context* c, Value* v);
|
|
|
|
virtual void thaw(Context* c, Value* v);
|
|
|
|
virtual bool frozen(Context* c);
|
|
|
|
virtual lir::OperandType type(Context*);
|
|
|
|
virtual void asAssemblerOperand(Context* c UNUSED, Site* high UNUSED,
|
|
lir::Operand* result);
|
|
|
|
virtual Site* copy(Context* c);
|
|
|
|
Site* copyHalf(Context* c, bool add);
|
|
|
|
virtual Site* copyLow(Context* c);
|
|
|
|
virtual Site* copyHigh(Context* c);
|
|
|
|
virtual Site* makeNextWord(Context* c, unsigned index);
|
|
|
|
virtual SiteMask mask(Context* c);
|
|
|
|
virtual SiteMask nextWordMask(Context* c, unsigned index);
|
|
|
|
virtual bool isVolatile(Context* c);
|
|
|
|
bool acquired;
|
|
int base;
|
|
int offset;
|
|
int index;
|
|
unsigned scale;
|
|
};
|
|
|
|
MemorySite* memorySite(Context* c, int base, int offset = 0, int index = lir::NoRegister, unsigned scale = 1);
|
|
MemorySite* frameSite(Context* c, int frameIndex);
|
|
|
|
} // namespace compiler
|
|
} // namespace codegen
|
|
} // namespace avian
|
|
|
|
#endif // AVIAN_CODEGEN_COMPILER_SITE_H
|