fix up creation of ir::Type

This commit is contained in:
Joshua Warner 2014-06-01 14:22:14 -06:00
parent 68b725900e
commit 1fb6a0bceb
4 changed files with 999 additions and 876 deletions

View File

@ -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 };

View File

@ -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,

View File

@ -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,

File diff suppressed because it is too large Load Diff