mirror of
https://github.com/corda/corda.git
synced 2025-01-06 05:04:20 +00:00
fix up creation of ir::Type
This commit is contained in:
parent
68b725900e
commit
1fb6a0bceb
@ -15,6 +15,15 @@ namespace avian {
|
|||||||
namespace codegen {
|
namespace codegen {
|
||||||
namespace ir {
|
namespace ir {
|
||||||
|
|
||||||
|
class TargetInfo {
|
||||||
|
public:
|
||||||
|
unsigned pointerSize;
|
||||||
|
|
||||||
|
TargetInfo(unsigned pointerSize) : pointerSize(pointerSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
enum Flavor {
|
enum Flavor {
|
||||||
@ -36,30 +45,90 @@ class Type {
|
|||||||
Void,
|
Void,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef int16_t TypeDesc;
|
||||||
|
|
||||||
|
#define TY_DESC(flavor, size) ((flavor & 0xff) | ((size & 0xff) << 8))
|
||||||
|
// TODO: once we upgrade to c++11, these should become plain constants (rather
|
||||||
|
// than function calls).
|
||||||
|
// The constructor will need to be declared 'constexpr'.
|
||||||
|
static inline Type void_()
|
||||||
|
{
|
||||||
|
return TY_DESC(Void, 0);
|
||||||
|
}
|
||||||
|
static inline Type object()
|
||||||
|
{
|
||||||
|
return TY_DESC(Object, -1);
|
||||||
|
}
|
||||||
|
static inline Type iptr()
|
||||||
|
{
|
||||||
|
return TY_DESC(Integer, -1);
|
||||||
|
}
|
||||||
|
static inline Type i1()
|
||||||
|
{
|
||||||
|
return TY_DESC(Integer, 1);
|
||||||
|
}
|
||||||
|
static inline Type i2()
|
||||||
|
{
|
||||||
|
return TY_DESC(Integer, 2);
|
||||||
|
}
|
||||||
|
static inline Type i4()
|
||||||
|
{
|
||||||
|
return TY_DESC(Integer, 4);
|
||||||
|
}
|
||||||
|
static inline Type i8()
|
||||||
|
{
|
||||||
|
return TY_DESC(Integer, 8);
|
||||||
|
}
|
||||||
|
static inline Type f4()
|
||||||
|
{
|
||||||
|
return TY_DESC(Float, 4);
|
||||||
|
}
|
||||||
|
static inline Type f8()
|
||||||
|
{
|
||||||
|
return TY_DESC(Float, 8);
|
||||||
|
}
|
||||||
|
static inline Type addr()
|
||||||
|
{
|
||||||
|
return TY_DESC(Address, -1);
|
||||||
|
}
|
||||||
|
#undef TY_DESC
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t flavor_;
|
TypeDesc desc;
|
||||||
uint8_t size_;
|
|
||||||
|
|
||||||
friend class Types;
|
friend class Types;
|
||||||
|
|
||||||
public:
|
// TODO: once we move to c++11, declare this 'constexpr', to allow
|
||||||
Type(uint8_t flavor_, uint8_t size_) : flavor_(flavor_), size_(size_)
|
// compile-time constants of this type.
|
||||||
|
/* constexpr */ Type(TypeDesc desc) : desc(desc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
inline Flavor flavor() const
|
inline Flavor flavor() const
|
||||||
{
|
{
|
||||||
return (Flavor)flavor_;
|
return (Flavor)(desc & 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned size() const
|
// If the size isn't known without inspecting the TargetInfo, returns -1.
|
||||||
|
// Otherwise, matches size(TargetInfo).
|
||||||
|
inline int rawSize() const
|
||||||
{
|
{
|
||||||
return size_;
|
return desc >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned size(const TargetInfo& t) const
|
||||||
|
{
|
||||||
|
int s = rawSize();
|
||||||
|
if (s < 0) {
|
||||||
|
return t.pointerSize;
|
||||||
|
}
|
||||||
|
return (unsigned)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator==(const Type& other) const
|
inline bool operator==(const Type& other) const
|
||||||
{
|
{
|
||||||
return flavor_ == other.flavor_ && size_ == other.size_;
|
return desc == other.desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator!=(const Type& other) const
|
inline bool operator!=(const Type& other) const
|
||||||
@ -68,51 +137,6 @@ class Type {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Types {
|
|
||||||
public:
|
|
||||||
// An object reference type, which will be treated as a GC root
|
|
||||||
Type object;
|
|
||||||
|
|
||||||
// A pointer-sized integer type (neither/both signed or unsigned)
|
|
||||||
// Note that these are just integers from the GC's perspective.
|
|
||||||
Type address;
|
|
||||||
|
|
||||||
// A 1-byte integer type (neither/both signed or unsigned)
|
|
||||||
Type i1;
|
|
||||||
|
|
||||||
// A 2-byte integer type (neither/both signed or unsigned)
|
|
||||||
Type i2;
|
|
||||||
|
|
||||||
// A 4-byte integer type (neither/both signed or unsigned)
|
|
||||||
Type i4;
|
|
||||||
|
|
||||||
// A 8-byte integer type (neither/both signed or unsigned)
|
|
||||||
Type i8;
|
|
||||||
|
|
||||||
// A 4-byte floating point type
|
|
||||||
Type f4;
|
|
||||||
|
|
||||||
// A 8-byte floating point type
|
|
||||||
Type f8;
|
|
||||||
|
|
||||||
// A type representing the lack of a return value
|
|
||||||
// TODO: remove when possible
|
|
||||||
Type void_;
|
|
||||||
|
|
||||||
Types(unsigned bytesPerWord)
|
|
||||||
: object(Type::Object, bytesPerWord),
|
|
||||||
address(Type::Integer, bytesPerWord),
|
|
||||||
i1(Type::Integer, 1),
|
|
||||||
i2(Type::Integer, 2),
|
|
||||||
i4(Type::Integer, 4),
|
|
||||||
i8(Type::Integer, 8),
|
|
||||||
f4(Type::Float, 4),
|
|
||||||
f8(Type::Float, 8),
|
|
||||||
void_(Type::Void, 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SignExtendMode { SignExtend, ZeroExtend };
|
enum SignExtendMode { SignExtend, ZeroExtend };
|
||||||
|
|
||||||
enum CallingConvention { NativeCallingConvention, AvianCallingConvention };
|
enum CallingConvention { NativeCallingConvention, AvianCallingConvention };
|
||||||
|
@ -1220,7 +1220,7 @@ unsigned typeFootprint(Context* c, ir::Type type)
|
|||||||
switch (type.flavor()) {
|
switch (type.flavor()) {
|
||||||
case ir::Type::Float:
|
case ir::Type::Float:
|
||||||
case ir::Type::Integer:
|
case ir::Type::Integer:
|
||||||
return type.size() / 4;
|
return type.rawSize() / 4;
|
||||||
case ir::Type::Object:
|
case ir::Type::Object:
|
||||||
case ir::Type::Address:
|
case ir::Type::Address:
|
||||||
case ir::Type::Half:
|
case ir::Type::Half:
|
||||||
@ -1258,7 +1258,7 @@ Value* loadLocal(Context* c, ir::Type type, unsigned index)
|
|||||||
Value* threadRegister(Context* c)
|
Value* threadRegister(Context* c)
|
||||||
{
|
{
|
||||||
Site* s = registerSite(c, c->arch->thread());
|
Site* s = registerSite(c, c->arch->thread());
|
||||||
return value(c, ir::Type(ir::Type::Address, TargetBytesPerWord), s, s);
|
return value(c, ir::Type::addr(), s, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -1518,7 +1518,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
|
|||||||
buffer, v, el.localIndex, el.frameIndex(c));
|
buffer, v, el.localIndex, el.frameIndex(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
Value dummy(0, 0, ir::Type(ir::Type::Integer, TargetBytesPerWord));
|
Value dummy(0, 0, ir::Type::addr());
|
||||||
dummy.addSite(c, s);
|
dummy.addSite(c, s);
|
||||||
dummy.removeSite(c, s);
|
dummy.removeSite(c, s);
|
||||||
freeze(c, frozen, s, 0);
|
freeze(c, frozen, s, 0);
|
||||||
@ -2281,7 +2281,7 @@ class MyCompiler: public Compiler {
|
|||||||
static_cast<Value*>(base),
|
static_cast<Value*>(base),
|
||||||
displacement,
|
displacement,
|
||||||
static_cast<Value*>(index),
|
static_cast<Value*>(index),
|
||||||
index == 0 ? 1 : type.size(),
|
index == 0 ? 1 : type.size(TargetBytesPerWord),
|
||||||
result);
|
result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -2315,8 +2315,7 @@ class MyCompiler: public Compiler {
|
|||||||
assert(&c, footprint == 2);
|
assert(&c, footprint == 2);
|
||||||
assert(&c, static_cast<Value*>(value)->nextWord);
|
assert(&c, static_cast<Value*>(value)->nextWord);
|
||||||
|
|
||||||
save(ir::Type(ir::Type::Integer, 4),
|
save(ir::Type::i4(), static_cast<Value*>(value)->nextWord);
|
||||||
static_cast<Value*>(value)->nextWord);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2582,14 +2581,14 @@ class MyCompiler: public Compiler {
|
|||||||
{
|
{
|
||||||
assert(&c, src->type.flavor() == type.flavor());
|
assert(&c, src->type.flavor() == type.flavor());
|
||||||
assert(&c, type.flavor() != ir::Type::Float);
|
assert(&c, type.flavor() != ir::Type::Float);
|
||||||
assert(&c, type.size() < src->type.size());
|
assert(&c, type.rawSize() < src->type.rawSize());
|
||||||
Value* dst = value(&c, type);
|
Value* dst = value(&c, type);
|
||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
lir::Move,
|
lir::Move,
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
type.size(),
|
type.size(TargetBytesPerWord),
|
||||||
dst);
|
dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@ -2603,10 +2602,11 @@ class MyCompiler: public Compiler {
|
|||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
||||||
TargetBytesPerWord,
|
TargetBytesPerWord,
|
||||||
truncateType.size(),
|
truncateType.size(TargetBytesPerWord),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
extendType.size() < TargetBytesPerWord ? TargetBytesPerWord
|
extendType.size(TargetBytesPerWord) < TargetBytesPerWord
|
||||||
: extendType.size(),
|
? TargetBytesPerWord
|
||||||
|
: extendType.size(TargetBytesPerWord),
|
||||||
dst);
|
dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@ -2617,10 +2617,10 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
lir::Move,
|
lir::Move,
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
dst->type.size(),
|
dst->type.size(TargetBytesPerWord),
|
||||||
static_cast<Value*>(dst));
|
static_cast<Value*>(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2633,11 +2633,12 @@ class MyCompiler: public Compiler {
|
|||||||
Value* dst = value(&c, dstType);
|
Value* dst = value(&c, dstType);
|
||||||
appendMove(&c,
|
appendMove(&c,
|
||||||
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
src->type.size(),
|
src->type.size(TargetBytesPerWord),
|
||||||
static_cast<Value*>(src),
|
static_cast<Value*>(src),
|
||||||
dstType.size() < TargetBytesPerWord ? TargetBytesPerWord
|
dstType.size(TargetBytesPerWord) < TargetBytesPerWord
|
||||||
: dstType.size(),
|
? TargetBytesPerWord
|
||||||
|
: dstType.size(TargetBytesPerWord),
|
||||||
dst);
|
dst);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
@ -2645,31 +2646,30 @@ class MyCompiler: public Compiler {
|
|||||||
virtual void condJump(lir::TernaryOperation op,
|
virtual void condJump(lir::TernaryOperation op,
|
||||||
ir::Value* a,
|
ir::Value* a,
|
||||||
ir::Value* b,
|
ir::Value* b,
|
||||||
ir::Value* address)
|
ir::Value* addr)
|
||||||
{
|
{
|
||||||
assert(&c,
|
assert(&c,
|
||||||
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))or(
|
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))or(
|
||||||
isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
|
isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
|
||||||
|
|
||||||
assert(&c, a->type == b->type);
|
assert(&c, a->type == b->type);
|
||||||
assert(&c,
|
assert(&c, addr->type == ir::Type::iptr());
|
||||||
address->type == ir::Type(ir::Type::Integer, TargetBytesPerWord));
|
|
||||||
|
|
||||||
appendBranch(&c,
|
appendBranch(&c,
|
||||||
op,
|
op,
|
||||||
static_cast<Value*>(a),
|
static_cast<Value*>(a),
|
||||||
static_cast<Value*>(b),
|
static_cast<Value*>(b),
|
||||||
static_cast<Value*>(address));
|
static_cast<Value*>(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void jmp(ir::Value* address)
|
virtual void jmp(ir::Value* addr)
|
||||||
{
|
{
|
||||||
appendJump(&c, lir::Jump, static_cast<Value*>(address));
|
appendJump(&c, lir::Jump, static_cast<Value*>(addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void exit(ir::Value* address)
|
virtual void exit(ir::Value* addr)
|
||||||
{
|
{
|
||||||
appendJump(&c, lir::Jump, static_cast<Value*>(address), true);
|
appendJump(&c, lir::Jump, static_cast<Value*>(addr), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ir::Value* binaryOp(lir::TernaryOperation op,
|
virtual ir::Value* binaryOp(lir::TernaryOperation op,
|
||||||
|
@ -576,9 +576,10 @@ class CallEvent: public Event {
|
|||||||
|
|
||||||
clean(c, this, stackBefore, localsBefore, reads, popIndex);
|
clean(c, this, stackBefore, localsBefore, reads, popIndex);
|
||||||
|
|
||||||
if (resultValue->type.size() and live(c, resultValue)) {
|
if (resultValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
and live(c, resultValue)) {
|
||||||
resultValue->addSite(c, registerSite(c, c->arch->returnLow()));
|
resultValue->addSite(c, registerSite(c, c->arch->returnLow()));
|
||||||
if (resultValue->type.size()
|
if (resultValue->type.size(vm::TargetBytesPerWord)
|
||||||
> vm::TargetBytesPerWord and live(c, resultValue->nextWord)) {
|
> vm::TargetBytesPerWord and live(c, resultValue->nextWord)) {
|
||||||
resultValue->nextWord->addSite(c,
|
resultValue->nextWord->addSite(c,
|
||||||
registerSite(c, c->arch->returnHigh()));
|
registerSite(c, c->arch->returnHigh()));
|
||||||
@ -627,7 +628,7 @@ class ReturnEvent: public Event {
|
|||||||
if (value) {
|
if (value) {
|
||||||
this->addReads(c,
|
this->addReads(c,
|
||||||
value,
|
value,
|
||||||
value->type.size(),
|
value->type.size(vm::TargetBytesPerWord),
|
||||||
SiteMask::fixedRegisterMask(c->arch->returnLow()),
|
SiteMask::fixedRegisterMask(c->arch->returnLow()),
|
||||||
SiteMask::fixedRegisterMask(c->arch->returnHigh()));
|
SiteMask::fixedRegisterMask(c->arch->returnHigh()));
|
||||||
}
|
}
|
||||||
@ -945,17 +946,26 @@ class CombineEvent: public Event {
|
|||||||
secondValue(secondValue),
|
secondValue(secondValue),
|
||||||
resultValue(resultValue)
|
resultValue(resultValue)
|
||||||
{
|
{
|
||||||
this->addReads(c, firstValue, firstValue->type.size(), firstLowMask, firstHighMask);
|
this->addReads(c,
|
||||||
|
firstValue,
|
||||||
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
firstLowMask,
|
||||||
|
firstHighMask);
|
||||||
|
|
||||||
if (resultValue->type.size() > vm::TargetBytesPerWord) {
|
if (resultValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
> vm::TargetBytesPerWord) {
|
||||||
resultValue->grow(c);
|
resultValue->grow(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool condensed = c->arch->alwaysCondensed(op);
|
bool condensed = c->arch->alwaysCondensed(op);
|
||||||
|
|
||||||
this->addReads(c, secondValue, secondValue->type.size(),
|
this->addReads(c,
|
||||||
secondLowMask, condensed ? resultValue : 0,
|
secondValue,
|
||||||
secondHighMask, condensed ? resultValue->nextWord : 0);
|
secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
secondLowMask,
|
||||||
|
condensed ? resultValue : 0,
|
||||||
|
secondHighMask,
|
||||||
|
condensed ? resultValue->nextWord : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() {
|
virtual const char* name() {
|
||||||
@ -973,28 +983,28 @@ class CombineEvent: public Event {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
assert(c, secondValue->source->type(c) == secondValue->nextWord->source->type(c));
|
assert(c, secondValue->source->type(c) == secondValue->nextWord->source->type(c));
|
||||||
|
|
||||||
freezeSource(c, firstValue->type.size(), firstValue);
|
freezeSource(c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
|
||||||
|
|
||||||
OperandMask cMask;
|
OperandMask cMask;
|
||||||
|
|
||||||
c->arch->planDestination(
|
c->arch->planDestination(
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
OperandMask(
|
OperandMask(
|
||||||
1 << firstValue->source->type(c),
|
1 << firstValue->source->type(c),
|
||||||
(static_cast<uint64_t>(
|
(static_cast<uint64_t>(
|
||||||
firstValue->nextWord->source->registerMask(c))
|
firstValue->nextWord->source->registerMask(c))
|
||||||
<< 32)
|
<< 32)
|
||||||
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
|
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
|
||||||
secondValue->type.size(),
|
secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
OperandMask(
|
OperandMask(
|
||||||
1 << secondValue->source->type(c),
|
1 << secondValue->source->type(c),
|
||||||
(static_cast<uint64_t>(
|
(static_cast<uint64_t>(
|
||||||
secondValue->nextWord->source->registerMask(c))
|
secondValue->nextWord->source->registerMask(c))
|
||||||
<< 32)
|
<< 32)
|
||||||
| static_cast<uint64_t>(secondValue->source->registerMask(c))),
|
| static_cast<uint64_t>(secondValue->source->registerMask(c))),
|
||||||
resultValue->type.size(),
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
cMask);
|
cMask);
|
||||||
|
|
||||||
SiteMask resultLowMask = SiteMask::lowPart(cMask);
|
SiteMask resultLowMask = SiteMask::lowPart(cMask);
|
||||||
@ -1002,10 +1012,12 @@ class CombineEvent: public Event {
|
|||||||
|
|
||||||
Site* low = getTarget(c, secondValue, resultValue, resultLowMask);
|
Site* low = getTarget(c, secondValue, resultValue, resultLowMask);
|
||||||
unsigned lowSize = low->registerSize(c);
|
unsigned lowSize = low->registerSize(c);
|
||||||
Site* high
|
Site* high = (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
|
||||||
= (resultValue->type.size() > lowSize
|
? getTarget(c,
|
||||||
? getTarget(c, secondValue->nextWord, resultValue->nextWord, resultHighMask)
|
secondValue->nextWord,
|
||||||
: low);
|
resultValue->nextWord,
|
||||||
|
resultHighMask)
|
||||||
|
: low);
|
||||||
|
|
||||||
// fprintf(stderr, "combine %p:%p and %p:%p into %p:%p\n",
|
// fprintf(stderr, "combine %p:%p and %p:%p into %p:%p\n",
|
||||||
// firstValue, firstValue->nextWord,
|
// firstValue, firstValue->nextWord,
|
||||||
@ -1014,30 +1026,31 @@ class CombineEvent: public Event {
|
|||||||
|
|
||||||
apply(c,
|
apply(c,
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstValue->source,
|
firstValue->source,
|
||||||
firstValue->nextWord->source,
|
firstValue->nextWord->source,
|
||||||
secondValue->type.size(),
|
secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
secondValue->source,
|
secondValue->source,
|
||||||
secondValue->nextWord->source,
|
secondValue->nextWord->source,
|
||||||
resultValue->type.size(),
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
low,
|
low,
|
||||||
high);
|
high);
|
||||||
|
|
||||||
thawSource(c, firstValue->type.size(), firstValue);
|
thawSource(c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
popRead(c, this, r->value);
|
popRead(c, this, r->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
low->thaw(c, secondValue);
|
low->thaw(c, secondValue);
|
||||||
if (resultValue->type.size() > lowSize) {
|
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize) {
|
||||||
high->thaw(c, secondValue->nextWord);
|
high->thaw(c, secondValue->nextWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (live(c, resultValue)) {
|
if (live(c, resultValue)) {
|
||||||
resultValue->addSite(c, low);
|
resultValue->addSite(c, low);
|
||||||
if (resultValue->type.size() > lowSize and live(c, resultValue->nextWord)) {
|
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
|
||||||
|
and live(c, resultValue->nextWord)) {
|
||||||
resultValue->nextWord->addSite(c, high);
|
resultValue->nextWord->addSite(c, high);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1059,11 +1072,11 @@ void appendCombine(Context* c,
|
|||||||
OperandMask firstMask;
|
OperandMask firstMask;
|
||||||
OperandMask secondMask;
|
OperandMask secondMask;
|
||||||
c->arch->planSource(op,
|
c->arch->planSource(op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstMask,
|
firstMask,
|
||||||
secondValue->type.size(),
|
secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
secondMask,
|
secondMask,
|
||||||
resultValue->type.size(),
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
&thunk);
|
&thunk);
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
@ -1072,21 +1085,27 @@ void appendCombine(Context* c,
|
|||||||
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
||||||
|
|
||||||
bool threadParameter;
|
bool threadParameter;
|
||||||
intptr_t handler = c->client->getThunk(op,
|
intptr_t handler
|
||||||
firstValue->type.size(),
|
= c->client->getThunk(op,
|
||||||
resultValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
&threadParameter);
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
&threadParameter);
|
||||||
|
|
||||||
unsigned stackSize = ceilingDivide(secondValue->type.size(), vm::TargetBytesPerWord)
|
unsigned stackSize
|
||||||
+ ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord);
|
= ceilingDivide(secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord)
|
||||||
|
+ ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord);
|
||||||
|
|
||||||
slicePush(c,
|
slicePush(c,
|
||||||
ceilingDivide(secondValue->type.size(), vm::TargetBytesPerWord),
|
ceilingDivide(secondValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord),
|
||||||
secondValue,
|
secondValue,
|
||||||
stackBase,
|
stackBase,
|
||||||
slice);
|
slice);
|
||||||
slicePush(c,
|
slicePush(c,
|
||||||
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
|
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord),
|
||||||
firstValue,
|
firstValue,
|
||||||
stackBase,
|
stackBase,
|
||||||
slice);
|
slice);
|
||||||
@ -1098,9 +1117,7 @@ void appendCombine(Context* c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
appendCall(c,
|
appendCall(c,
|
||||||
value(c,
|
value(c, ir::Type::addr(), constantSite(c, handler)),
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
|
||||||
constantSite(c, handler)),
|
|
||||||
ir::NativeCallingConvention,
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -1132,12 +1149,18 @@ class TranslateEvent: public Event {
|
|||||||
{
|
{
|
||||||
bool condensed = c->arch->alwaysCondensed(op);
|
bool condensed = c->arch->alwaysCondensed(op);
|
||||||
|
|
||||||
if (resultValue->type.size() > vm::TargetBytesPerWord) {
|
if (resultValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
> vm::TargetBytesPerWord) {
|
||||||
resultValue->grow(c);
|
resultValue->grow(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->addReads(c, firstValue, firstValue->type.size(), valueLowMask, condensed ? resultValue : 0,
|
this->addReads(c,
|
||||||
valueHighMask, condensed ? resultValue->nextWord : 0);
|
firstValue,
|
||||||
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
valueLowMask,
|
||||||
|
condensed ? resultValue : 0,
|
||||||
|
valueHighMask,
|
||||||
|
condensed ? resultValue->nextWord : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char* name() {
|
virtual const char* name() {
|
||||||
@ -1151,14 +1174,14 @@ class TranslateEvent: public Event {
|
|||||||
|
|
||||||
c->arch->planDestination(
|
c->arch->planDestination(
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
OperandMask(
|
OperandMask(
|
||||||
1 << firstValue->source->type(c),
|
1 << firstValue->source->type(c),
|
||||||
(static_cast<uint64_t>(
|
(static_cast<uint64_t>(
|
||||||
firstValue->nextWord->source->registerMask(c))
|
firstValue->nextWord->source->registerMask(c))
|
||||||
<< 32)
|
<< 32)
|
||||||
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
|
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
|
||||||
resultValue->type.size(),
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
bMask);
|
bMask);
|
||||||
|
|
||||||
SiteMask resultLowMask = SiteMask::lowPart(bMask);
|
SiteMask resultLowMask = SiteMask::lowPart(bMask);
|
||||||
@ -1166,17 +1189,19 @@ class TranslateEvent: public Event {
|
|||||||
|
|
||||||
Site* low = getTarget(c, firstValue, resultValue, resultLowMask);
|
Site* low = getTarget(c, firstValue, resultValue, resultLowMask);
|
||||||
unsigned lowSize = low->registerSize(c);
|
unsigned lowSize = low->registerSize(c);
|
||||||
Site* high
|
Site* high = (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
|
||||||
= (resultValue->type.size() > lowSize
|
? getTarget(c,
|
||||||
? getTarget(c, firstValue->nextWord, resultValue->nextWord, resultHighMask)
|
firstValue->nextWord,
|
||||||
: low);
|
resultValue->nextWord,
|
||||||
|
resultHighMask)
|
||||||
|
: low);
|
||||||
|
|
||||||
apply(c,
|
apply(c,
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstValue->source,
|
firstValue->source,
|
||||||
firstValue->nextWord->source,
|
firstValue->nextWord->source,
|
||||||
resultValue->type.size(),
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
low,
|
low,
|
||||||
high);
|
high);
|
||||||
|
|
||||||
@ -1185,13 +1210,14 @@ class TranslateEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
low->thaw(c, firstValue);
|
low->thaw(c, firstValue);
|
||||||
if (resultValue->type.size() > lowSize) {
|
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize) {
|
||||||
high->thaw(c, firstValue->nextWord);
|
high->thaw(c, firstValue->nextWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (live(c, resultValue)) {
|
if (live(c, resultValue)) {
|
||||||
resultValue->addSite(c, low);
|
resultValue->addSite(c, low);
|
||||||
if (resultValue->type.size() > lowSize and live(c, resultValue->nextWord)) {
|
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
|
||||||
|
and live(c, resultValue->nextWord)) {
|
||||||
resultValue->nextWord->addSite(c, high);
|
resultValue->nextWord->addSite(c, high);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1210,38 +1236,47 @@ void appendTranslate(Context* c,
|
|||||||
Value* firstValue,
|
Value* firstValue,
|
||||||
Value* resultValue)
|
Value* resultValue)
|
||||||
{
|
{
|
||||||
assert(c, firstValue->type.size() == firstValue->type.size());
|
assert(c,
|
||||||
assert(c, resultValue->type.size() == resultValue->type.size());
|
firstValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
== firstValue->type.size(vm::TargetBytesPerWord));
|
||||||
|
assert(c,
|
||||||
|
resultValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
== resultValue->type.size(vm::TargetBytesPerWord));
|
||||||
|
|
||||||
bool thunk;
|
bool thunk;
|
||||||
OperandMask first;
|
OperandMask first;
|
||||||
|
|
||||||
c->arch->planSource(
|
c->arch->planSource(op,
|
||||||
op, firstValue->type.size(), first, resultValue->type.size(), &thunk);
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
first,
|
||||||
|
resultValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
&thunk);
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
||||||
FixedSliceStack<ir::Value*, 2> slice;
|
FixedSliceStack<ir::Value*, 2> slice;
|
||||||
|
|
||||||
slicePush(c,
|
slicePush(c,
|
||||||
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
|
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord),
|
||||||
firstValue,
|
firstValue,
|
||||||
stackBase,
|
stackBase,
|
||||||
slice);
|
slice);
|
||||||
|
|
||||||
appendCall(
|
appendCall(c,
|
||||||
c,
|
value(c,
|
||||||
value(c,
|
ir::Type::addr(),
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
constantSite(
|
||||||
constantSite(
|
c,
|
||||||
c,
|
c->client->getThunk(
|
||||||
c->client->getThunk(
|
op,
|
||||||
op, firstValue->type.size(), resultValue->type.size()))),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
ir::NativeCallingConvention,
|
resultValue->type.size(vm::TargetBytesPerWord)))),
|
||||||
0,
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
resultValue,
|
0,
|
||||||
slice);
|
resultValue,
|
||||||
|
slice);
|
||||||
} else {
|
} else {
|
||||||
append(c,
|
append(c,
|
||||||
new (c->zone) TranslateEvent(c,
|
new (c->zone) TranslateEvent(c,
|
||||||
@ -1507,16 +1542,22 @@ class BranchEvent: public Event {
|
|||||||
secondValue(secondValue),
|
secondValue(secondValue),
|
||||||
addressValue(addressValue)
|
addressValue(addressValue)
|
||||||
{
|
{
|
||||||
this->addReads(
|
this->addReads(c,
|
||||||
c, firstValue, firstValue->type.size(), firstLowMask, firstHighMask);
|
firstValue,
|
||||||
this->addReads(
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
c, secondValue, firstValue->type.size(), secondLowMask, secondHighMask);
|
firstLowMask,
|
||||||
|
firstHighMask);
|
||||||
|
this->addReads(c,
|
||||||
|
secondValue,
|
||||||
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
secondLowMask,
|
||||||
|
secondHighMask);
|
||||||
|
|
||||||
OperandMask dstMask;
|
OperandMask dstMask;
|
||||||
c->arch->planDestination(op,
|
c->arch->planDestination(op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
OperandMask(0, 0),
|
OperandMask(0, 0),
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
OperandMask(0, 0),
|
OperandMask(0, 0),
|
||||||
vm::TargetBytesPerWord,
|
vm::TargetBytesPerWord,
|
||||||
dstMask);
|
dstMask);
|
||||||
@ -1541,7 +1582,8 @@ class BranchEvent: public Event {
|
|||||||
int64_t firstConstVal = firstConstant->value->value();
|
int64_t firstConstVal = firstConstant->value->value();
|
||||||
int64_t secondConstVal = secondConstant->value->value();
|
int64_t secondConstVal = secondConstant->value->value();
|
||||||
|
|
||||||
if (firstValue->type.size() > vm::TargetBytesPerWord) {
|
if (firstValue->type.size(vm::TargetBytesPerWord)
|
||||||
|
> vm::TargetBytesPerWord) {
|
||||||
firstConstVal |= findConstantSite
|
firstConstVal |= findConstantSite
|
||||||
(c, firstValue->nextWord)->value->value() << 32;
|
(c, firstValue->nextWord)->value->value() << 32;
|
||||||
secondConstVal |= findConstantSite
|
secondConstVal |= findConstantSite
|
||||||
@ -1550,22 +1592,24 @@ class BranchEvent: public Event {
|
|||||||
|
|
||||||
if (shouldJump(c,
|
if (shouldJump(c,
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstConstVal,
|
firstConstVal,
|
||||||
secondConstVal)) {
|
secondConstVal)) {
|
||||||
apply(c, lir::Jump, vm::TargetBytesPerWord, addressValue->source, addressValue->source);
|
apply(c, lir::Jump, vm::TargetBytesPerWord, addressValue->source, addressValue->source);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
freezeSource(c, firstValue->type.size(), firstValue);
|
freezeSource(
|
||||||
freezeSource(c, firstValue->type.size(), secondValue);
|
c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
|
||||||
|
freezeSource(
|
||||||
|
c, firstValue->type.size(vm::TargetBytesPerWord), secondValue);
|
||||||
freezeSource(c, vm::TargetBytesPerWord, addressValue);
|
freezeSource(c, vm::TargetBytesPerWord, addressValue);
|
||||||
|
|
||||||
apply(c,
|
apply(c,
|
||||||
op,
|
op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstValue->source,
|
firstValue->source,
|
||||||
firstValue->nextWord->source,
|
firstValue->nextWord->source,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
secondValue->source,
|
secondValue->source,
|
||||||
secondValue->nextWord->source,
|
secondValue->nextWord->source,
|
||||||
vm::TargetBytesPerWord,
|
vm::TargetBytesPerWord,
|
||||||
@ -1573,8 +1617,10 @@ class BranchEvent: public Event {
|
|||||||
addressValue->source);
|
addressValue->source);
|
||||||
|
|
||||||
thawSource(c, vm::TargetBytesPerWord, addressValue);
|
thawSource(c, vm::TargetBytesPerWord, addressValue);
|
||||||
thawSource(c, firstValue->type.size(), secondValue);
|
thawSource(
|
||||||
thawSource(c, firstValue->type.size(), firstValue);
|
c, firstValue->type.size(vm::TargetBytesPerWord), secondValue);
|
||||||
|
thawSource(
|
||||||
|
c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1602,9 +1648,9 @@ void appendBranch(Context* c,
|
|||||||
OperandMask secondMask;
|
OperandMask secondMask;
|
||||||
|
|
||||||
c->arch->planSource(op,
|
c->arch->planSource(op,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
firstMask,
|
firstMask,
|
||||||
firstValue->type.size(),
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
secondMask,
|
secondMask,
|
||||||
vm::TargetBytesPerWord,
|
vm::TargetBytesPerWord,
|
||||||
&thunk);
|
&thunk);
|
||||||
@ -1615,41 +1661,42 @@ void appendBranch(Context* c,
|
|||||||
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
|
||||||
|
|
||||||
bool threadParameter;
|
bool threadParameter;
|
||||||
intptr_t handler = c->client->getThunk(
|
intptr_t handler
|
||||||
op, firstValue->type.size(), firstValue->type.size(), &threadParameter);
|
= c->client->getThunk(op,
|
||||||
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
&threadParameter);
|
||||||
|
|
||||||
assert(c, not threadParameter);
|
assert(c, not threadParameter);
|
||||||
|
|
||||||
slicePush(c,
|
slicePush(c,
|
||||||
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
|
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord),
|
||||||
secondValue,
|
secondValue,
|
||||||
stackBase,
|
stackBase,
|
||||||
slice);
|
slice);
|
||||||
slicePush(c,
|
slicePush(c,
|
||||||
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
|
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
|
||||||
|
vm::TargetBytesPerWord),
|
||||||
firstValue,
|
firstValue,
|
||||||
stackBase,
|
stackBase,
|
||||||
slice);
|
slice);
|
||||||
|
|
||||||
Value* result
|
Value* result = value(c, ir::Type::addr());
|
||||||
= value(c, ir::Type(ir::Type::Address, vm::TargetBytesPerWord));
|
|
||||||
appendCall(c,
|
appendCall(c,
|
||||||
value(c,
|
value(c, ir::Type::addr(), constantSite(c, handler)),
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
|
||||||
constantSite(c, handler)),
|
|
||||||
ir::NativeCallingConvention,
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
result,
|
result,
|
||||||
slice);
|
slice);
|
||||||
|
|
||||||
appendBranch(c,
|
appendBranch(
|
||||||
thunkBranch(c, op),
|
c,
|
||||||
value(c,
|
thunkBranch(c, op),
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
value(c, ir::Type::addr(), constantSite(c, static_cast<int64_t>(0))),
|
||||||
constantSite(c, static_cast<int64_t>(0))),
|
result,
|
||||||
result,
|
addressValue);
|
||||||
addressValue);
|
|
||||||
} else {
|
} else {
|
||||||
append(c,
|
append(c,
|
||||||
new (c->zone) BranchEvent(c,
|
new (c->zone) BranchEvent(c,
|
||||||
|
1440
src/compile.cpp
1440
src/compile.cpp
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user