mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +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 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 };
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
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