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 ir {
class TargetInfo {
public:
unsigned pointerSize;
TargetInfo(unsigned pointerSize) : pointerSize(pointerSize)
{
}
};
class Type {
public:
enum Flavor {
@ -36,30 +45,90 @@ class Type {
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:
uint8_t flavor_;
uint8_t size_;
TypeDesc desc;
friend class Types;
public:
Type(uint8_t flavor_, uint8_t size_) : flavor_(flavor_), size_(size_)
// TODO: once we move to c++11, declare this 'constexpr', to allow
// compile-time constants of this type.
/* constexpr */ Type(TypeDesc desc) : desc(desc)
{
}
public:
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
{
return flavor_ == other.flavor_ && size_ == other.size_;
return desc == other.desc;
}
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 CallingConvention { NativeCallingConvention, AvianCallingConvention };

View File

@ -1220,7 +1220,7 @@ unsigned typeFootprint(Context* c, ir::Type type)
switch (type.flavor()) {
case ir::Type::Float:
case ir::Type::Integer:
return type.size() / 4;
return type.rawSize() / 4;
case ir::Type::Object:
case ir::Type::Address:
case ir::Type::Half:
@ -1258,7 +1258,7 @@ Value* loadLocal(Context* c, ir::Type type, unsigned index)
Value* threadRegister(Context* c)
{
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
@ -1518,7 +1518,7 @@ resolveOriginalSites(Context* c, Event* e, SiteRecordList* frozen,
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.removeSite(c, s);
freeze(c, frozen, s, 0);
@ -2281,7 +2281,7 @@ class MyCompiler: public Compiler {
static_cast<Value*>(base),
displacement,
static_cast<Value*>(index),
index == 0 ? 1 : type.size(),
index == 0 ? 1 : type.size(TargetBytesPerWord),
result);
return result;
@ -2315,8 +2315,7 @@ class MyCompiler: public Compiler {
assert(&c, footprint == 2);
assert(&c, static_cast<Value*>(value)->nextWord);
save(ir::Type(ir::Type::Integer, 4),
static_cast<Value*>(value)->nextWord);
save(ir::Type::i4(), static_cast<Value*>(value)->nextWord);
}
}
@ -2582,14 +2581,14 @@ class MyCompiler: public Compiler {
{
assert(&c, src->type.flavor() == type.flavor());
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);
appendMove(&c,
lir::Move,
src->type.size(),
src->type.size(),
src->type.size(TargetBytesPerWord),
src->type.size(TargetBytesPerWord),
static_cast<Value*>(src),
type.size(),
type.size(TargetBytesPerWord),
dst);
return dst;
}
@ -2603,10 +2602,11 @@ class MyCompiler: public Compiler {
appendMove(&c,
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
TargetBytesPerWord,
truncateType.size(),
truncateType.size(TargetBytesPerWord),
static_cast<Value*>(src),
extendType.size() < TargetBytesPerWord ? TargetBytesPerWord
: extendType.size(),
extendType.size(TargetBytesPerWord) < TargetBytesPerWord
? TargetBytesPerWord
: extendType.size(TargetBytesPerWord),
dst);
return dst;
}
@ -2617,10 +2617,10 @@ class MyCompiler: public Compiler {
appendMove(&c,
lir::Move,
src->type.size(),
src->type.size(),
src->type.size(TargetBytesPerWord),
src->type.size(TargetBytesPerWord),
static_cast<Value*>(src),
dst->type.size(),
dst->type.size(TargetBytesPerWord),
static_cast<Value*>(dst));
}
@ -2633,11 +2633,12 @@ class MyCompiler: public Compiler {
Value* dst = value(&c, dstType);
appendMove(&c,
signExtend == ir::SignExtend ? lir::Move : lir::MoveZ,
src->type.size(),
src->type.size(),
src->type.size(TargetBytesPerWord),
src->type.size(TargetBytesPerWord),
static_cast<Value*>(src),
dstType.size() < TargetBytesPerWord ? TargetBytesPerWord
: dstType.size(),
dstType.size(TargetBytesPerWord) < TargetBytesPerWord
? TargetBytesPerWord
: dstType.size(TargetBytesPerWord),
dst);
return dst;
}
@ -2645,31 +2646,30 @@ class MyCompiler: public Compiler {
virtual void condJump(lir::TernaryOperation op,
ir::Value* a,
ir::Value* b,
ir::Value* address)
ir::Value* addr)
{
assert(&c,
(isGeneralBranch(op) and isGeneralValue(a) and isGeneralValue(b))or(
isFloatBranch(op) and isFloatValue(a) and isFloatValue(b)));
assert(&c, a->type == b->type);
assert(&c,
address->type == ir::Type(ir::Type::Integer, TargetBytesPerWord));
assert(&c, addr->type == ir::Type::iptr());
appendBranch(&c,
op,
static_cast<Value*>(a),
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,

View File

@ -576,9 +576,10 @@ class CallEvent: public Event {
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()));
if (resultValue->type.size()
if (resultValue->type.size(vm::TargetBytesPerWord)
> vm::TargetBytesPerWord and live(c, resultValue->nextWord)) {
resultValue->nextWord->addSite(c,
registerSite(c, c->arch->returnHigh()));
@ -627,7 +628,7 @@ class ReturnEvent: public Event {
if (value) {
this->addReads(c,
value,
value->type.size(),
value->type.size(vm::TargetBytesPerWord),
SiteMask::fixedRegisterMask(c->arch->returnLow()),
SiteMask::fixedRegisterMask(c->arch->returnHigh()));
}
@ -945,17 +946,26 @@ class CombineEvent: public Event {
secondValue(secondValue),
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);
}
bool condensed = c->arch->alwaysCondensed(op);
this->addReads(c, secondValue, secondValue->type.size(),
secondLowMask, condensed ? resultValue : 0,
secondHighMask, condensed ? resultValue->nextWord : 0);
this->addReads(c,
secondValue,
secondValue->type.size(vm::TargetBytesPerWord),
secondLowMask,
condensed ? resultValue : 0,
secondHighMask,
condensed ? resultValue->nextWord : 0);
}
virtual const char* name() {
@ -973,28 +983,28 @@ class CombineEvent: public Event {
// }
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;
c->arch->planDestination(
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
OperandMask(
1 << firstValue->source->type(c),
(static_cast<uint64_t>(
firstValue->nextWord->source->registerMask(c))
<< 32)
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
secondValue->type.size(),
secondValue->type.size(vm::TargetBytesPerWord),
OperandMask(
1 << secondValue->source->type(c),
(static_cast<uint64_t>(
secondValue->nextWord->source->registerMask(c))
<< 32)
| static_cast<uint64_t>(secondValue->source->registerMask(c))),
resultValue->type.size(),
resultValue->type.size(vm::TargetBytesPerWord),
cMask);
SiteMask resultLowMask = SiteMask::lowPart(cMask);
@ -1002,10 +1012,12 @@ class CombineEvent: public Event {
Site* low = getTarget(c, secondValue, resultValue, resultLowMask);
unsigned lowSize = low->registerSize(c);
Site* high
= (resultValue->type.size() > lowSize
? getTarget(c, secondValue->nextWord, resultValue->nextWord, resultHighMask)
: low);
Site* high = (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
? getTarget(c,
secondValue->nextWord,
resultValue->nextWord,
resultHighMask)
: low);
// fprintf(stderr, "combine %p:%p and %p:%p into %p:%p\n",
// firstValue, firstValue->nextWord,
@ -1014,30 +1026,31 @@ class CombineEvent: public Event {
apply(c,
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstValue->source,
firstValue->nextWord->source,
secondValue->type.size(),
secondValue->type.size(vm::TargetBytesPerWord),
secondValue->source,
secondValue->nextWord->source,
resultValue->type.size(),
resultValue->type.size(vm::TargetBytesPerWord),
low,
high);
thawSource(c, firstValue->type.size(), firstValue);
thawSource(c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
for (Read* r = reads; r; r = r->eventNext) {
popRead(c, this, r->value);
}
low->thaw(c, secondValue);
if (resultValue->type.size() > lowSize) {
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize) {
high->thaw(c, secondValue->nextWord);
}
if (live(c, resultValue)) {
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);
}
}
@ -1059,11 +1072,11 @@ void appendCombine(Context* c,
OperandMask firstMask;
OperandMask secondMask;
c->arch->planSource(op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstMask,
secondValue->type.size(),
secondValue->type.size(vm::TargetBytesPerWord),
secondMask,
resultValue->type.size(),
resultValue->type.size(vm::TargetBytesPerWord),
&thunk);
if (thunk) {
@ -1072,21 +1085,27 @@ void appendCombine(Context* c,
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
bool threadParameter;
intptr_t handler = c->client->getThunk(op,
firstValue->type.size(),
resultValue->type.size(),
&threadParameter);
intptr_t handler
= c->client->getThunk(op,
firstValue->type.size(vm::TargetBytesPerWord),
resultValue->type.size(vm::TargetBytesPerWord),
&threadParameter);
unsigned stackSize = ceilingDivide(secondValue->type.size(), vm::TargetBytesPerWord)
+ ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord);
unsigned stackSize
= ceilingDivide(secondValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord)
+ ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord);
slicePush(c,
ceilingDivide(secondValue->type.size(), vm::TargetBytesPerWord),
ceilingDivide(secondValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord),
secondValue,
stackBase,
slice);
slicePush(c,
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord),
firstValue,
stackBase,
slice);
@ -1098,9 +1117,7 @@ void appendCombine(Context* c,
}
appendCall(c,
value(c,
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
constantSite(c, handler)),
value(c, ir::Type::addr(), constantSite(c, handler)),
ir::NativeCallingConvention,
0,
0,
@ -1132,12 +1149,18 @@ class TranslateEvent: public Event {
{
bool condensed = c->arch->alwaysCondensed(op);
if (resultValue->type.size() > vm::TargetBytesPerWord) {
if (resultValue->type.size(vm::TargetBytesPerWord)
> vm::TargetBytesPerWord) {
resultValue->grow(c);
}
this->addReads(c, firstValue, firstValue->type.size(), valueLowMask, condensed ? resultValue : 0,
valueHighMask, condensed ? resultValue->nextWord : 0);
this->addReads(c,
firstValue,
firstValue->type.size(vm::TargetBytesPerWord),
valueLowMask,
condensed ? resultValue : 0,
valueHighMask,
condensed ? resultValue->nextWord : 0);
}
virtual const char* name() {
@ -1151,14 +1174,14 @@ class TranslateEvent: public Event {
c->arch->planDestination(
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
OperandMask(
1 << firstValue->source->type(c),
(static_cast<uint64_t>(
firstValue->nextWord->source->registerMask(c))
<< 32)
| static_cast<uint64_t>(firstValue->source->registerMask(c))),
resultValue->type.size(),
resultValue->type.size(vm::TargetBytesPerWord),
bMask);
SiteMask resultLowMask = SiteMask::lowPart(bMask);
@ -1166,17 +1189,19 @@ class TranslateEvent: public Event {
Site* low = getTarget(c, firstValue, resultValue, resultLowMask);
unsigned lowSize = low->registerSize(c);
Site* high
= (resultValue->type.size() > lowSize
? getTarget(c, firstValue->nextWord, resultValue->nextWord, resultHighMask)
: low);
Site* high = (resultValue->type.size(vm::TargetBytesPerWord) > lowSize
? getTarget(c,
firstValue->nextWord,
resultValue->nextWord,
resultHighMask)
: low);
apply(c,
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstValue->source,
firstValue->nextWord->source,
resultValue->type.size(),
resultValue->type.size(vm::TargetBytesPerWord),
low,
high);
@ -1185,13 +1210,14 @@ class TranslateEvent: public Event {
}
low->thaw(c, firstValue);
if (resultValue->type.size() > lowSize) {
if (resultValue->type.size(vm::TargetBytesPerWord) > lowSize) {
high->thaw(c, firstValue->nextWord);
}
if (live(c, resultValue)) {
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);
}
}
@ -1210,38 +1236,47 @@ void appendTranslate(Context* c,
Value* firstValue,
Value* resultValue)
{
assert(c, firstValue->type.size() == firstValue->type.size());
assert(c, resultValue->type.size() == resultValue->type.size());
assert(c,
firstValue->type.size(vm::TargetBytesPerWord)
== firstValue->type.size(vm::TargetBytesPerWord));
assert(c,
resultValue->type.size(vm::TargetBytesPerWord)
== resultValue->type.size(vm::TargetBytesPerWord));
bool thunk;
OperandMask first;
c->arch->planSource(
op, firstValue->type.size(), first, resultValue->type.size(), &thunk);
c->arch->planSource(op,
firstValue->type.size(vm::TargetBytesPerWord),
first,
resultValue->type.size(vm::TargetBytesPerWord),
&thunk);
if (thunk) {
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
FixedSliceStack<ir::Value*, 2> slice;
slicePush(c,
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord),
firstValue,
stackBase,
slice);
appendCall(
c,
value(c,
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
constantSite(
c,
c->client->getThunk(
op, firstValue->type.size(), resultValue->type.size()))),
ir::NativeCallingConvention,
0,
0,
resultValue,
slice);
appendCall(c,
value(c,
ir::Type::addr(),
constantSite(
c,
c->client->getThunk(
op,
firstValue->type.size(vm::TargetBytesPerWord),
resultValue->type.size(vm::TargetBytesPerWord)))),
ir::NativeCallingConvention,
0,
0,
resultValue,
slice);
} else {
append(c,
new (c->zone) TranslateEvent(c,
@ -1507,16 +1542,22 @@ class BranchEvent: public Event {
secondValue(secondValue),
addressValue(addressValue)
{
this->addReads(
c, firstValue, firstValue->type.size(), firstLowMask, firstHighMask);
this->addReads(
c, secondValue, firstValue->type.size(), secondLowMask, secondHighMask);
this->addReads(c,
firstValue,
firstValue->type.size(vm::TargetBytesPerWord),
firstLowMask,
firstHighMask);
this->addReads(c,
secondValue,
firstValue->type.size(vm::TargetBytesPerWord),
secondLowMask,
secondHighMask);
OperandMask dstMask;
c->arch->planDestination(op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
OperandMask(0, 0),
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
OperandMask(0, 0),
vm::TargetBytesPerWord,
dstMask);
@ -1541,7 +1582,8 @@ class BranchEvent: public Event {
int64_t firstConstVal = firstConstant->value->value();
int64_t secondConstVal = secondConstant->value->value();
if (firstValue->type.size() > vm::TargetBytesPerWord) {
if (firstValue->type.size(vm::TargetBytesPerWord)
> vm::TargetBytesPerWord) {
firstConstVal |= findConstantSite
(c, firstValue->nextWord)->value->value() << 32;
secondConstVal |= findConstantSite
@ -1550,22 +1592,24 @@ class BranchEvent: public Event {
if (shouldJump(c,
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstConstVal,
secondConstVal)) {
apply(c, lir::Jump, vm::TargetBytesPerWord, addressValue->source, addressValue->source);
}
} else {
freezeSource(c, firstValue->type.size(), firstValue);
freezeSource(c, firstValue->type.size(), secondValue);
freezeSource(
c, firstValue->type.size(vm::TargetBytesPerWord), firstValue);
freezeSource(
c, firstValue->type.size(vm::TargetBytesPerWord), secondValue);
freezeSource(c, vm::TargetBytesPerWord, addressValue);
apply(c,
op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstValue->source,
firstValue->nextWord->source,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
secondValue->source,
secondValue->nextWord->source,
vm::TargetBytesPerWord,
@ -1573,8 +1617,10 @@ class BranchEvent: public Event {
addressValue->source);
thawSource(c, vm::TargetBytesPerWord, addressValue);
thawSource(c, firstValue->type.size(), secondValue);
thawSource(c, firstValue->type.size(), firstValue);
thawSource(
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;
c->arch->planSource(op,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
firstMask,
firstValue->type.size(),
firstValue->type.size(vm::TargetBytesPerWord),
secondMask,
vm::TargetBytesPerWord,
&thunk);
@ -1615,41 +1661,42 @@ void appendBranch(Context* c,
size_t stackBase = c->stack ? c->stack->index + 1 : 0;
bool threadParameter;
intptr_t handler = c->client->getThunk(
op, firstValue->type.size(), firstValue->type.size(), &threadParameter);
intptr_t handler
= c->client->getThunk(op,
firstValue->type.size(vm::TargetBytesPerWord),
firstValue->type.size(vm::TargetBytesPerWord),
&threadParameter);
assert(c, not threadParameter);
slicePush(c,
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord),
secondValue,
stackBase,
slice);
slicePush(c,
ceilingDivide(firstValue->type.size(), vm::TargetBytesPerWord),
ceilingDivide(firstValue->type.size(vm::TargetBytesPerWord),
vm::TargetBytesPerWord),
firstValue,
stackBase,
slice);
Value* result
= value(c, ir::Type(ir::Type::Address, vm::TargetBytesPerWord));
Value* result = value(c, ir::Type::addr());
appendCall(c,
value(c,
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
constantSite(c, handler)),
value(c, ir::Type::addr(), constantSite(c, handler)),
ir::NativeCallingConvention,
0,
0,
result,
slice);
appendBranch(c,
thunkBranch(c, op),
value(c,
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
constantSite(c, static_cast<int64_t>(0))),
result,
addressValue);
appendBranch(
c,
thunkBranch(c, op),
value(c, ir::Type::addr(), constantSite(c, static_cast<int64_t>(0))),
result,
addressValue);
} else {
append(c,
new (c->zone) BranchEvent(c,

File diff suppressed because it is too large Load Diff