mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
Merge branch 'cross-bootimage' into ios
This commit is contained in:
commit
66bc326523
44
makefile
44
makefile
@ -165,11 +165,13 @@ rdynamic = -rdynamic
|
||||
warnings = -Wall -Wextra -Werror -Wunused-parameter -Winit-self \
|
||||
-Wno-non-virtual-dtor
|
||||
|
||||
target-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||
|
||||
common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\"
|
||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" $(target-cflags)
|
||||
|
||||
ifneq (,$(filter i386 x86_64,$(arch)))
|
||||
ifeq ($(use-frame-pointer),true)
|
||||
@ -208,6 +210,14 @@ shared = -shared
|
||||
|
||||
openjdk-extra-cflags = -fvisibility=hidden
|
||||
|
||||
bootimage-cflags = -DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||
|
||||
ifeq ($(build-arch),powerpc)
|
||||
ifneq ($(arch),$(build-arch))
|
||||
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(arch),i386)
|
||||
pointer-size = 4
|
||||
endif
|
||||
@ -215,6 +225,10 @@ ifeq ($(arch),powerpc)
|
||||
asm = powerpc
|
||||
pointer-size = 4
|
||||
|
||||
ifneq ($(arch),$(build-arch))
|
||||
bootimage-cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||
endif
|
||||
|
||||
ifneq ($(platform),darwin)
|
||||
ifneq ($(arch),$(build-arch))
|
||||
converter-cflags += -DOPPOSITE_ENDIAN
|
||||
@ -251,6 +265,11 @@ ifeq ($(arch),arm)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(platform),linux)
|
||||
bootimage-cflags += -DTARGET_PLATFORM_LINUX
|
||||
endif
|
||||
|
||||
ifeq ($(build-platform),darwin)
|
||||
build-cflags = $(common-cflags) -fPIC -fvisibility=hidden -I$(src)
|
||||
cflags += -I/System/Library/Frameworks/JavaVM.framework/Headers/
|
||||
@ -258,6 +277,8 @@ ifeq ($(build-platform),darwin)
|
||||
endif
|
||||
|
||||
ifeq ($(platform),darwin)
|
||||
bootimage-cflags += -DTARGET_PLATFORM_DARWIN
|
||||
|
||||
ifeq (${OSX_SDK_SYSROOT},)
|
||||
OSX_SDK_SYSROOT = 10.4u
|
||||
endif
|
||||
@ -332,6 +353,8 @@ ifeq ($(platform),darwin)
|
||||
endif
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
bootimage-cflags += -DTARGET_PLATFORM_WINDOWS
|
||||
|
||||
inc = "$(root)/win32/include"
|
||||
lib = "$(root)/win32/lib"
|
||||
|
||||
@ -481,7 +504,8 @@ generated-code = \
|
||||
$(build)/type-constructors.cpp \
|
||||
$(build)/type-initializations.cpp \
|
||||
$(build)/type-java-initializations.cpp \
|
||||
$(build)/type-name-initializations.cpp
|
||||
$(build)/type-name-initializations.cpp \
|
||||
$(build)/type-maps.cpp
|
||||
|
||||
vm-depends := $(generated-code) $(wildcard $(src)/*.h)
|
||||
|
||||
@ -499,10 +523,12 @@ vm-sources = \
|
||||
|
||||
vm-asm-sources = $(src)/$(asm).S
|
||||
|
||||
target-asm = $(asm)
|
||||
|
||||
ifeq ($(process),compile)
|
||||
vm-sources += \
|
||||
$(src)/compiler.cpp \
|
||||
$(src)/$(asm).cpp
|
||||
$(src)/$(target-asm).cpp
|
||||
|
||||
vm-asm-sources += $(src)/compile-$(asm).S
|
||||
endif
|
||||
@ -539,16 +565,6 @@ bootimage-bin = $(build)/bootimage.bin
|
||||
bootimage-object = $(build)/bootimage-bin.o
|
||||
|
||||
ifeq ($(bootimage),true)
|
||||
ifneq ($(build-arch),$(arch))
|
||||
$(error "bootimage cross-builds not yet supported")
|
||||
endif
|
||||
|
||||
ifeq ($(arch),x86_64)
|
||||
ifneq ($(build-platform),$(platform))
|
||||
$(error "bootimage cross-builds not yet supported")
|
||||
endif
|
||||
endif
|
||||
|
||||
vm-classpath-object = $(bootimage-object)
|
||||
cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\"
|
||||
else
|
||||
@ -891,6 +907,8 @@ $(bootimage-generator):
|
||||
openjdk-src=$(openjdk-src) \
|
||||
bootimage-generator= \
|
||||
build-bootimage-generator=$(bootimage-generator) \
|
||||
target-cflags="$(bootimage-cflags)" \
|
||||
target-asm=$(asm) \
|
||||
$(bootimage-generator)
|
||||
|
||||
$(build-bootimage-generator): \
|
||||
|
177
src/arm.cpp
177
src/arm.cpp
@ -155,11 +155,11 @@ inline int unha16(int32_t high, int32_t low) {
|
||||
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
||||
}
|
||||
|
||||
inline bool isInt8(intptr_t v) { return v == static_cast<int8_t>(v); }
|
||||
inline bool isInt16(intptr_t v) { return v == static_cast<int16_t>(v); }
|
||||
inline bool isInt24(intptr_t v) { return v == (v & 0xffffff); }
|
||||
inline bool isInt32(intptr_t v) { return v == static_cast<int32_t>(v); }
|
||||
inline int carry16(intptr_t v) { return static_cast<int16_t>(v) < 0 ? 1 : 0; }
|
||||
inline bool isInt8(target_intptr_t v) { return v == static_cast<int8_t>(v); }
|
||||
inline bool isInt16(target_intptr_t v) { return v == static_cast<int16_t>(v); }
|
||||
inline bool isInt24(target_intptr_t v) { return v == (v & 0xffffff); }
|
||||
inline bool isInt32(target_intptr_t v) { return v == static_cast<int32_t>(v); }
|
||||
inline int carry16(target_intptr_t v) { return static_cast<int16_t>(v) < 0 ? 1 : 0; }
|
||||
|
||||
inline bool isOfWidth(long long i, int size) { return static_cast<unsigned long long>(i) >> size == 0; }
|
||||
inline bool isOfWidth(int i, int size) { return static_cast<unsigned>(i) >> size == 0; }
|
||||
@ -167,7 +167,8 @@ inline bool isOfWidth(int i, int size) { return static_cast<unsigned>(i) >> size
|
||||
const unsigned FrameHeaderSize = 1;
|
||||
|
||||
const unsigned StackAlignmentInBytes = 8;
|
||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
|
||||
const unsigned StackAlignmentInWords
|
||||
= StackAlignmentInBytes / TargetBytesPerWord;
|
||||
|
||||
const int ThreadRegister = 8;
|
||||
const int StackRegister = 13;
|
||||
@ -331,7 +332,8 @@ class Offset: public Promise {
|
||||
assert(c, resolved());
|
||||
|
||||
unsigned o = offset - block->offset;
|
||||
return block->start + padding(block, forTrace ? o - BytesPerWord : o) + o;
|
||||
return block->start + padding
|
||||
(block, forTrace ? o - TargetBytesPerWord : o) + o;
|
||||
}
|
||||
|
||||
Context* c;
|
||||
@ -496,7 +498,7 @@ void shiftLeftR(Context* con, unsigned size, Assembler::Register* a, Assembler::
|
||||
|
||||
void shiftLeftC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == TargetBytesPerWord);
|
||||
emit(con, lsli(t->low, b->low, getValue(a)));
|
||||
}
|
||||
|
||||
@ -519,7 +521,7 @@ void shiftRightR(Context* con, unsigned size, Assembler::Register* a, Assembler:
|
||||
|
||||
void shiftRightC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == TargetBytesPerWord);
|
||||
emit(con, asri(t->low, b->low, getValue(a)));
|
||||
}
|
||||
|
||||
@ -541,7 +543,7 @@ void unsignedShiftRightR(Context* con, unsigned size, Assembler::Register* a, As
|
||||
|
||||
void unsignedShiftRightC(Context* con, unsigned size UNUSED, Assembler::Constant* a, Assembler::Register* b, Assembler::Register* t)
|
||||
{
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == TargetBytesPerWord);
|
||||
emit(con, lsri(t->low, b->low, getValue(a)));
|
||||
}
|
||||
|
||||
@ -556,7 +558,7 @@ class ConstantPoolEntry: public Promise {
|
||||
virtual int64_t value() {
|
||||
assert(c, resolved());
|
||||
|
||||
return reinterpret_cast<intptr_t>(address);
|
||||
return reinterpret_cast<int64_t>(address);
|
||||
}
|
||||
|
||||
virtual bool resolved() {
|
||||
@ -573,7 +575,8 @@ class ConstantPoolEntry: public Promise {
|
||||
|
||||
class ConstantPoolListener: public Promise::Listener {
|
||||
public:
|
||||
ConstantPoolListener(System* s, uintptr_t* address, uint8_t* returnAddress):
|
||||
ConstantPoolListener(System* s, target_uintptr_t* address,
|
||||
uint8_t* returnAddress):
|
||||
s(s),
|
||||
address(address),
|
||||
returnAddress(returnAddress)
|
||||
@ -588,7 +591,7 @@ class ConstantPoolListener: public Promise::Listener {
|
||||
}
|
||||
|
||||
System* s;
|
||||
uintptr_t* address;
|
||||
target_uintptr_t* address;
|
||||
uint8_t* returnAddress;
|
||||
};
|
||||
|
||||
@ -677,10 +680,10 @@ padding(MyBlock* b, unsigned offset)
|
||||
for (PoolEvent* e = b->poolEventHead; e; e = e->next) {
|
||||
if (e->offset <= offset) {
|
||||
if (needJump(b)) {
|
||||
total += BytesPerWord;
|
||||
total += TargetBytesPerWord;
|
||||
}
|
||||
for (PoolOffset* o = e->poolOffsetHead; o; o = o->next) {
|
||||
total += BytesPerWord;
|
||||
total += TargetBytesPerWord;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
@ -708,7 +711,7 @@ resolve(MyBlock* b)
|
||||
if (b->next == 0 or b->next->poolEventHead) {
|
||||
append = true;
|
||||
} else {
|
||||
int32_t v = (b->start + b->size + b->next->size + BytesPerWord - 8)
|
||||
int32_t v = (b->start + b->size + b->next->size + TargetBytesPerWord - 8)
|
||||
- (c->poolOffsetHead->offset + c->poolOffsetHead->block->start);
|
||||
|
||||
append = (v != (v & PoolOffsetMask));
|
||||
@ -751,7 +754,7 @@ resolve(MyBlock* b)
|
||||
void
|
||||
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
emit(c, bx(target->low));
|
||||
}
|
||||
|
||||
@ -763,8 +766,8 @@ void
|
||||
swapRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == BytesPerWord);
|
||||
assert(c, bSize == BytesPerWord);
|
||||
assert(c, aSize == TargetBytesPerWord);
|
||||
assert(c, bSize == TargetBytesPerWord);
|
||||
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
moveRR(c, aSize, a, bSize, &tmp);
|
||||
@ -876,7 +879,7 @@ void
|
||||
addC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
int32_t v = a->value->value();
|
||||
if (v) {
|
||||
@ -897,7 +900,7 @@ void
|
||||
subC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
int32_t v = a->value->value();
|
||||
if (v) {
|
||||
@ -958,7 +961,7 @@ normalize(Context* c, int offset, int index, unsigned scale,
|
||||
ResolvedPromise scalePromise(log(scale));
|
||||
Assembler::Constant scaleConstant(&scalePromise);
|
||||
|
||||
shiftLeftC(c, BytesPerWord, &scaleConstant,
|
||||
shiftLeftC(c, TargetBytesPerWord, &scaleConstant,
|
||||
&unscaledIndex, &normalizedIndex);
|
||||
|
||||
scaled = normalizedIndex.low;
|
||||
@ -973,8 +976,8 @@ normalize(Context* c, int offset, int index, unsigned scale,
|
||||
Assembler::Constant offsetConstant(&offsetPromise);
|
||||
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
moveCR(c, BytesPerWord, &offsetConstant, BytesPerWord, &tmp);
|
||||
addR(c, BytesPerWord, &tmp, &untranslatedIndex, &normalizedIndex);
|
||||
moveCR(c, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp);
|
||||
addR(c, TargetBytesPerWord, &tmp, &untranslatedIndex, &normalizedIndex);
|
||||
c->client->releaseTemporary(tmp.low);
|
||||
}
|
||||
|
||||
@ -1046,7 +1049,7 @@ store(Context* c, unsigned size, Assembler::Register* src,
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
ResolvedPromise offsetPromise(offset);
|
||||
Assembler::Constant offsetConstant(&offsetPromise);
|
||||
moveCR(c, BytesPerWord, &offsetConstant, BytesPerWord, &tmp);
|
||||
moveCR(c, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp);
|
||||
|
||||
store(c, size, src, base, 0, tmp.low, 1, false);
|
||||
|
||||
@ -1067,8 +1070,8 @@ void
|
||||
moveAndUpdateRM(Context* c, unsigned srcSize UNUSED, Assembler::Register* src,
|
||||
unsigned dstSize UNUSED, Assembler::Memory* dst)
|
||||
{
|
||||
assert(c, srcSize == BytesPerWord);
|
||||
assert(c, dstSize == BytesPerWord);
|
||||
assert(c, srcSize == TargetBytesPerWord);
|
||||
assert(c, dstSize == TargetBytesPerWord);
|
||||
|
||||
if (dst->index == NoRegister) {
|
||||
emit(c, stri(src->low, dst->base, dst->offset, dst->offset ? 1 : 0));
|
||||
@ -1168,7 +1171,7 @@ load(Context* c, unsigned srcSize, int base, int offset, int index,
|
||||
Assembler::Register tmp(c->client->acquireTemporary());
|
||||
ResolvedPromise offsetPromise(offset);
|
||||
Assembler::Constant offsetConstant(&offsetPromise);
|
||||
moveCR(c, BytesPerWord, &offsetConstant, BytesPerWord, &tmp);
|
||||
moveCR(c, TargetBytesPerWord, &offsetConstant, TargetBytesPerWord, &tmp);
|
||||
|
||||
load(c, srcSize, base, 0, tmp.low, 1, dstSize, dst, false, signExtend);
|
||||
|
||||
@ -1457,7 +1460,7 @@ branchRR(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Register* a, Assembler::Register* b,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1474,13 +1477,13 @@ branchCR(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Constant* a, Assembler::Register* b,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
int64_t v = a->value->value();
|
||||
|
||||
ResolvedPromise low(v & ~static_cast<uintptr_t>(0));
|
||||
ResolvedPromise low(v & ~static_cast<target_uintptr_t>(0));
|
||||
Assembler::Constant al(&low);
|
||||
|
||||
ResolvedPromise high((v >> 32) & ~static_cast<uintptr_t>(0));
|
||||
ResolvedPromise high((v >> 32) & ~static_cast<target_uintptr_t>(0));
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
Assembler::Register bh(b->high);
|
||||
@ -1498,7 +1501,7 @@ branchRM(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Register* a, Assembler::Memory* b,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size <= BytesPerWord);
|
||||
assert(c, size <= TargetBytesPerWord);
|
||||
|
||||
compareRM(c, size, a, size, b);
|
||||
branch(c, op, target);
|
||||
@ -1509,7 +1512,7 @@ branchCM(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Constant* a, Assembler::Memory* b,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size <= BytesPerWord);
|
||||
assert(c, size <= TargetBytesPerWord);
|
||||
|
||||
compareCM(c, size, a, size, b);
|
||||
branch(c, op, target);
|
||||
@ -1565,14 +1568,14 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
||||
void
|
||||
callR(Context* c, unsigned size UNUSED, Assembler::Register* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
emit(c, blx(target->low));
|
||||
}
|
||||
|
||||
void
|
||||
callC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c));
|
||||
emit(c, bl(0));
|
||||
@ -1581,27 +1584,27 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
void
|
||||
longCallC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
Assembler::Register tmp(4);
|
||||
moveCR2(c, BytesPerWord, target, BytesPerWord, &tmp, offset(c));
|
||||
callR(c, BytesPerWord, &tmp);
|
||||
moveCR2(c, TargetBytesPerWord, target, TargetBytesPerWord, &tmp, offset(c));
|
||||
callR(c, TargetBytesPerWord, &tmp);
|
||||
}
|
||||
|
||||
void
|
||||
longJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
Assembler::Register tmp(4); // a non-arg reg that we don't mind clobbering
|
||||
moveCR2(c, BytesPerWord, target, BytesPerWord, &tmp, offset(c));
|
||||
jumpR(c, BytesPerWord, &tmp);
|
||||
moveCR2(c, TargetBytesPerWord, target, TargetBytesPerWord, &tmp, offset(c));
|
||||
jumpR(c, TargetBytesPerWord, &tmp);
|
||||
}
|
||||
|
||||
void
|
||||
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
appendOffsetTask(c, target->value, offset(c));
|
||||
emit(c, b(0));
|
||||
@ -1630,7 +1633,7 @@ nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
|
||||
unsigned targetParameterFootprint UNUSED, void** ip, void** stack)
|
||||
{
|
||||
assert(c, *ip >= start);
|
||||
assert(c, *ip <= start + (size / BytesPerWord));
|
||||
assert(c, *ip <= start + (size / TargetBytesPerWord));
|
||||
|
||||
uint32_t* instruction = static_cast<uint32_t*>(*ip);
|
||||
|
||||
@ -1669,7 +1672,7 @@ nextFrame(ArchitectureContext* c, uint32_t* start, unsigned size UNUSED,
|
||||
unsigned value = *instruction & 0xff;
|
||||
unsigned rotation = (*instruction >> 8) & 0xf;
|
||||
switch (rotation) {
|
||||
case 0: offset -= value / BytesPerWord; break;
|
||||
case 0: offset -= value / TargetBytesPerWord; break;
|
||||
case 15: offset -= value; break;
|
||||
default: abort(c);
|
||||
}
|
||||
@ -1905,8 +1908,8 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
return 4;
|
||||
}
|
||||
|
||||
virtual void setConstant(void* dst, uintptr_t constant) {
|
||||
*static_cast<uintptr_t*>(dst) = constant;
|
||||
virtual void setConstant(void* dst, uint64_t constant) {
|
||||
*static_cast<target_uintptr_t*>(dst) = constant;
|
||||
}
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||
@ -2146,18 +2149,18 @@ class MyAssembler: public Assembler {
|
||||
Constant handlerConstant
|
||||
(new (c.zone->allocate(sizeof(ResolvedPromise)))
|
||||
ResolvedPromise(handler));
|
||||
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
|
||||
branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit,
|
||||
&handlerConstant);
|
||||
}
|
||||
|
||||
virtual void saveFrame(unsigned stackOffset, unsigned ipOffset) {
|
||||
Register link(LinkRegister);
|
||||
Memory linkDst(ThreadRegister, ipOffset);
|
||||
moveRM(&c, BytesPerWord, &link, BytesPerWord, &linkDst);
|
||||
moveRM(&c, TargetBytesPerWord, &link, TargetBytesPerWord, &linkDst);
|
||||
|
||||
Register stack(StackRegister);
|
||||
Memory stackDst(ThreadRegister, stackOffset);
|
||||
moveRM(&c, BytesPerWord, &stack, BytesPerWord, &stackDst);
|
||||
moveRM(&c, TargetBytesPerWord, &stack, TargetBytesPerWord, &stackDst);
|
||||
}
|
||||
|
||||
virtual void pushFrame(unsigned argumentCount, ...) {
|
||||
@ -2173,7 +2176,7 @@ class MyAssembler: public Assembler {
|
||||
arguments[i].size = va_arg(a, unsigned);
|
||||
arguments[i].type = static_cast<OperandType>(va_arg(a, int));
|
||||
arguments[i].operand = va_arg(a, Operand*);
|
||||
footprint += ceiling(arguments[i].size, BytesPerWord);
|
||||
footprint += ceiling(arguments[i].size, TargetBytesPerWord);
|
||||
}
|
||||
va_end(a);
|
||||
|
||||
@ -2186,17 +2189,18 @@ class MyAssembler: public Assembler {
|
||||
|
||||
apply(Move,
|
||||
arguments[i].size, arguments[i].type, arguments[i].operand,
|
||||
pad(arguments[i].size), RegisterOperand, &dst);
|
||||
pad(arguments[i].size, TargetBytesPerWord), RegisterOperand,
|
||||
&dst);
|
||||
|
||||
offset += ceiling(arguments[i].size, BytesPerWord);
|
||||
offset += ceiling(arguments[i].size, TargetBytesPerWord);
|
||||
} else {
|
||||
Memory dst(StackRegister, offset * BytesPerWord);
|
||||
Memory dst(StackRegister, offset * TargetBytesPerWord);
|
||||
|
||||
apply(Move,
|
||||
arguments[i].size, arguments[i].type, arguments[i].operand,
|
||||
pad(arguments[i].size), MemoryOperand, &dst);
|
||||
pad(arguments[i].size, TargetBytesPerWord), MemoryOperand, &dst);
|
||||
|
||||
offset += ceiling(arguments[i].size, BytesPerWord);
|
||||
offset += ceiling(arguments[i].size, TargetBytesPerWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2210,33 +2214,37 @@ class MyAssembler: public Assembler {
|
||||
assert(&c, footprint < 256);
|
||||
|
||||
Register stack(StackRegister);
|
||||
ResolvedPromise footprintPromise(footprint * BytesPerWord);
|
||||
ResolvedPromise footprintPromise(footprint * TargetBytesPerWord);
|
||||
Constant footprintConstant(&footprintPromise);
|
||||
subC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
|
||||
subC(&c, TargetBytesPerWord, &footprintConstant, &stack, &stack);
|
||||
|
||||
Register returnAddress(LinkRegister);
|
||||
Memory returnAddressDst(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &returnAddress, BytesPerWord, &returnAddressDst);
|
||||
Memory returnAddressDst
|
||||
(StackRegister, (footprint - 1) * TargetBytesPerWord);
|
||||
moveRM(&c, TargetBytesPerWord, &returnAddress, TargetBytesPerWord,
|
||||
&returnAddressDst);
|
||||
}
|
||||
|
||||
virtual void adjustFrame(unsigned difference) {
|
||||
Register stack(StackRegister);
|
||||
ResolvedPromise differencePromise(difference * BytesPerWord);
|
||||
ResolvedPromise differencePromise(difference * TargetBytesPerWord);
|
||||
Constant differenceConstant(&differencePromise);
|
||||
subC(&c, BytesPerWord, &differenceConstant, &stack, &stack);
|
||||
subC(&c, TargetBytesPerWord, &differenceConstant, &stack, &stack);
|
||||
}
|
||||
|
||||
virtual void popFrame(unsigned footprint) {
|
||||
footprint += FrameHeaderSize;
|
||||
|
||||
Register returnAddress(LinkRegister);
|
||||
Memory returnAddressSrc(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &returnAddress);
|
||||
Memory returnAddressSrc
|
||||
(StackRegister, (footprint - 1) * TargetBytesPerWord);
|
||||
moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord,
|
||||
&returnAddress);
|
||||
|
||||
Register stack(StackRegister);
|
||||
ResolvedPromise footprintPromise(footprint * BytesPerWord);
|
||||
ResolvedPromise footprintPromise(footprint * TargetBytesPerWord);
|
||||
Constant footprintConstant(&footprintPromise);
|
||||
addC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
|
||||
addC(&c, TargetBytesPerWord, &footprintConstant, &stack, &stack);
|
||||
}
|
||||
|
||||
virtual void popFrameForTailCall(unsigned footprint,
|
||||
@ -2252,20 +2260,22 @@ class MyAssembler: public Assembler {
|
||||
|
||||
Register link(LinkRegister);
|
||||
Memory returnAddressSrc
|
||||
(StackRegister, (footprint - 1) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &link);
|
||||
(StackRegister, (footprint - 1) * TargetBytesPerWord);
|
||||
moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord,
|
||||
&link);
|
||||
|
||||
Register stack(StackRegister);
|
||||
ResolvedPromise footprintPromise((footprint - offset) * BytesPerWord);
|
||||
ResolvedPromise footprintPromise
|
||||
((footprint - offset) * TargetBytesPerWord);
|
||||
Constant footprintConstant(&footprintPromise);
|
||||
addC(&c, BytesPerWord, &footprintConstant, &stack, &stack);
|
||||
addC(&c, TargetBytesPerWord, &footprintConstant, &stack, &stack);
|
||||
|
||||
if (returnAddressSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
Register ras(returnAddressSurrogate);
|
||||
Memory dst(StackRegister, (offset - 1) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst);
|
||||
Memory dst(StackRegister, (offset - 1) * TargetBytesPerWord);
|
||||
moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst);
|
||||
}
|
||||
} else {
|
||||
popFrame(footprint);
|
||||
@ -2288,9 +2298,9 @@ class MyAssembler: public Assembler {
|
||||
offset = argumentFootprint - StackAlignmentInWords;
|
||||
|
||||
Register stack(StackRegister);
|
||||
ResolvedPromise adjustmentPromise(offset * BytesPerWord);
|
||||
ResolvedPromise adjustmentPromise(offset * TargetBytesPerWord);
|
||||
Constant adjustment(&adjustmentPromise);
|
||||
addC(&c, BytesPerWord, &adjustment, &stack, &stack);
|
||||
addC(&c, TargetBytesPerWord, &adjustment, &stack, &stack);
|
||||
} else {
|
||||
offset = 0;
|
||||
}
|
||||
@ -2305,7 +2315,7 @@ class MyAssembler: public Assembler {
|
||||
|
||||
Register stack(StackRegister);
|
||||
Memory newStackSrc(ThreadRegister, stackOffsetFromThread);
|
||||
moveMR(&c, BytesPerWord, &newStackSrc, BytesPerWord, &stack);
|
||||
moveMR(&c, TargetBytesPerWord, &newStackSrc, TargetBytesPerWord, &stack);
|
||||
|
||||
return_(&c);
|
||||
}
|
||||
@ -2338,7 +2348,7 @@ class MyAssembler: public Assembler {
|
||||
{
|
||||
if (isBranch(op)) {
|
||||
assert(&c, aSize == bSize);
|
||||
assert(&c, cSize == BytesPerWord);
|
||||
assert(&c, cSize == TargetBytesPerWord);
|
||||
assert(&c, cType == ConstantOperand);
|
||||
|
||||
arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]
|
||||
@ -2382,7 +2392,7 @@ class MyAssembler: public Assembler {
|
||||
unsigned entry = dstOffset + poolSize;
|
||||
|
||||
if (needJump(b)) {
|
||||
entry += BytesPerWord;
|
||||
entry += TargetBytesPerWord;
|
||||
}
|
||||
|
||||
o->entry->address = dst + entry;
|
||||
@ -2396,14 +2406,15 @@ class MyAssembler: public Assembler {
|
||||
int32_t* p = reinterpret_cast<int32_t*>(dst + instruction);
|
||||
*p = (v & PoolOffsetMask) | ((~PoolOffsetMask) & *p);
|
||||
|
||||
poolSize += BytesPerWord;
|
||||
poolSize += TargetBytesPerWord;
|
||||
}
|
||||
|
||||
if (needJump(b)) {
|
||||
write4(dst + dstOffset, ::b((poolSize + BytesPerWord - 8) >> 2));
|
||||
write4
|
||||
(dst + dstOffset, ::b((poolSize + TargetBytesPerWord - 8) >> 2));
|
||||
}
|
||||
|
||||
dstOffset += poolSize + BytesPerWord;
|
||||
dstOffset += poolSize + TargetBytesPerWord;
|
||||
}
|
||||
|
||||
unsigned size = b->size - blockOffset;
|
||||
@ -2421,10 +2432,10 @@ class MyAssembler: public Assembler {
|
||||
|
||||
for (ConstantPoolEntry* e = c.constantPool; e; e = e->next) {
|
||||
if (e->constant->resolved()) {
|
||||
*static_cast<uintptr_t*>(e->address) = e->constant->value();
|
||||
*static_cast<target_uintptr_t*>(e->address) = e->constant->value();
|
||||
} else {
|
||||
new (e->constant->listen(sizeof(ConstantPoolListener)))
|
||||
ConstantPoolListener(c.s, static_cast<uintptr_t*>(e->address),
|
||||
ConstantPoolListener(c.s, static_cast<target_uintptr_t*>(e->address),
|
||||
e->callOffset
|
||||
? dst + e->callOffset->value() + 8
|
||||
: 0);
|
||||
@ -2453,7 +2464,7 @@ class MyAssembler: public Assembler {
|
||||
MyBlock* b = c.lastBlock;
|
||||
unsigned thisEventOffset = c.code.length() - b->offset;
|
||||
if (b->poolOffsetHead) {
|
||||
int32_t v = (thisEventOffset + BytesPerWord - 8)
|
||||
int32_t v = (thisEventOffset + TargetBytesPerWord - 8)
|
||||
- b->poolOffsetHead->offset;
|
||||
|
||||
if (v > 0 and v != (v & PoolOffsetMask)) {
|
||||
|
@ -343,7 +343,7 @@ class Assembler {
|
||||
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
||||
void* newTarget) = 0;
|
||||
|
||||
virtual void setConstant(void* dst, uintptr_t constant) = 0;
|
||||
virtual void setConstant(void* dst, uint64_t constant) = 0;
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
||||
|
||||
|
30
src/bootimage-template.cpp
Normal file
30
src/bootimage-template.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
const unsigned NAME(BootMask) = (~static_cast<unsigned>(0))
|
||||
/ NAME(BytesPerWord);
|
||||
|
||||
const unsigned NAME(BootShift) = 32 - log(NAME(BytesPerWord));
|
||||
|
||||
const unsigned NAME(BootFlatConstant) = 1 << NAME(BootShift);
|
||||
const unsigned NAME(BootHeapOffset) = 1 << (NAME(BootShift) + 1);
|
||||
|
||||
inline unsigned
|
||||
LABEL(codeMapSize)(unsigned codeSize)
|
||||
{
|
||||
return ceiling(codeSize, TargetBitsPerWord) * TargetBytesPerWord;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
LABEL(heapMapSize)(unsigned heapSize)
|
||||
{
|
||||
return ceiling(heapSize, TargetBitsPerWord * TargetBytesPerWord)
|
||||
* TargetBytesPerWord;
|
||||
}
|
||||
|
||||
inline object
|
||||
LABEL(bootObject)(LABEL(uintptr_t)* heap, unsigned offset)
|
||||
{
|
||||
if (offset) {
|
||||
return reinterpret_cast<object>(heap + offset - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
1312
src/bootimage.cpp
1312
src/bootimage.cpp
File diff suppressed because it is too large
Load Diff
102
src/bootimage.h
102
src/bootimage.h
@ -12,16 +12,11 @@
|
||||
#define BOOTIMAGE_H
|
||||
|
||||
#include "common.h"
|
||||
#include "target.h"
|
||||
#include "machine.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
const unsigned BootMask = (~static_cast<unsigned>(0)) / BytesPerWord;
|
||||
|
||||
const unsigned BootShift = 32 - log(BytesPerWord);
|
||||
|
||||
const unsigned BootFlatConstant = 1 << BootShift;
|
||||
const unsigned BootHeapOffset = 1 << (BootShift + 1);
|
||||
|
||||
class BootImage {
|
||||
public:
|
||||
class Thunk {
|
||||
@ -30,14 +25,14 @@ class BootImage {
|
||||
start(0), frameSavedOffset(0), length(0)
|
||||
{ }
|
||||
|
||||
Thunk(unsigned start, unsigned frameSavedOffset, unsigned length):
|
||||
Thunk(uint32_t start, uint32_t frameSavedOffset, uint32_t length):
|
||||
start(start), frameSavedOffset(frameSavedOffset), length(length)
|
||||
{ }
|
||||
|
||||
unsigned start;
|
||||
unsigned frameSavedOffset;
|
||||
unsigned length;
|
||||
};
|
||||
uint32_t start;
|
||||
uint32_t frameSavedOffset;
|
||||
uint32_t length;
|
||||
} PACKED;
|
||||
|
||||
class ThunkCollection {
|
||||
public:
|
||||
@ -47,63 +42,56 @@ class BootImage {
|
||||
Thunk aioob;
|
||||
Thunk stackOverflow;
|
||||
Thunk table;
|
||||
};
|
||||
} PACKED;
|
||||
|
||||
static const unsigned Magic = 0x22377322;
|
||||
static const uint32_t Magic = 0x22377322;
|
||||
|
||||
unsigned magic;
|
||||
uint32_t magic;
|
||||
|
||||
unsigned heapSize;
|
||||
unsigned codeSize;
|
||||
uint32_t heapSize;
|
||||
uint32_t codeSize;
|
||||
|
||||
unsigned bootClassCount;
|
||||
unsigned appClassCount;
|
||||
unsigned stringCount;
|
||||
unsigned callCount;
|
||||
uint32_t bootClassCount;
|
||||
uint32_t appClassCount;
|
||||
uint32_t stringCount;
|
||||
uint32_t callCount;
|
||||
|
||||
unsigned bootLoader;
|
||||
unsigned appLoader;
|
||||
unsigned types;
|
||||
unsigned methodTree;
|
||||
unsigned methodTreeSentinal;
|
||||
unsigned virtualThunks;
|
||||
uint32_t bootLoader;
|
||||
uint32_t appLoader;
|
||||
uint32_t types;
|
||||
uint32_t methodTree;
|
||||
uint32_t methodTreeSentinal;
|
||||
uint32_t virtualThunks;
|
||||
|
||||
uintptr_t codeBase;
|
||||
uint32_t compileMethodCall;
|
||||
uint32_t compileVirtualMethodCall;
|
||||
uint32_t invokeNativeCall;
|
||||
uint32_t throwArrayIndexOutOfBoundsCall;
|
||||
uint32_t throwStackOverflowCall;
|
||||
|
||||
ThunkCollection thunks;
|
||||
|
||||
unsigned compileMethodCall;
|
||||
unsigned compileVirtualMethodCall;
|
||||
unsigned invokeNativeCall;
|
||||
unsigned throwArrayIndexOutOfBoundsCall;
|
||||
unsigned throwStackOverflowCall;
|
||||
|
||||
#define THUNK(s) unsigned s##Call;
|
||||
#define THUNK(s) uint32_t s##Call;
|
||||
#include "thunks.cpp"
|
||||
#undef THUNK
|
||||
|
||||
ThunkCollection thunks;
|
||||
} PACKED;
|
||||
|
||||
class OffsetResolver {
|
||||
public:
|
||||
virtual unsigned fieldOffset(Thread*, object) = 0;
|
||||
};
|
||||
|
||||
inline unsigned
|
||||
codeMapSize(unsigned codeSize)
|
||||
{
|
||||
return ceiling(codeSize, BitsPerWord) * BytesPerWord;
|
||||
}
|
||||
#define NAME(x) Target##x
|
||||
#define LABEL(x) target_##x
|
||||
#include "bootimage-template.cpp"
|
||||
#undef LABEL
|
||||
#undef NAME
|
||||
|
||||
inline unsigned
|
||||
heapMapSize(unsigned heapSize)
|
||||
{
|
||||
return ceiling(heapSize, BitsPerWord * BytesPerWord) * BytesPerWord;
|
||||
}
|
||||
|
||||
inline object
|
||||
bootObject(uintptr_t* heap, unsigned offset)
|
||||
{
|
||||
if (offset) {
|
||||
return reinterpret_cast<object>(heap + offset - 1);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#define NAME(x) x
|
||||
#define LABEL(x) x
|
||||
#include "bootimage-template.cpp"
|
||||
#undef LABEL
|
||||
#undef NAME
|
||||
|
||||
} // namespace vm
|
||||
|
||||
|
@ -45,6 +45,8 @@ typedef unsigned __int64 uint64_t;
|
||||
|
||||
# define NO_RETURN __declspec(noreturn)
|
||||
|
||||
# define PACKED
|
||||
|
||||
# define PLATFORM_WINDOWS
|
||||
|
||||
# ifdef _M_IX86
|
||||
@ -76,6 +78,8 @@ typedef intptr_t intptr_alias_t;
|
||||
|
||||
# define NO_RETURN __attribute__((noreturn))
|
||||
|
||||
# define PACKED __attribute__((packed))
|
||||
|
||||
# ifdef __MINGW32__
|
||||
# define PLATFORM_WINDOWS
|
||||
# endif
|
||||
|
410
src/compile.cpp
410
src/compile.cpp
File diff suppressed because it is too large
Load Diff
214
src/compiler.cpp
214
src/compiler.cpp
@ -10,6 +10,7 @@
|
||||
|
||||
#include "compiler.h"
|
||||
#include "assembler.h"
|
||||
#include "target.h"
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -34,7 +35,7 @@ const unsigned StealRegisterReserveCount = 2;
|
||||
|
||||
// this should be equal to the largest number of registers used by a
|
||||
// compare instruction:
|
||||
const unsigned ResolveRegisterReserveCount = (BytesPerWord == 8 ? 2 : 4);
|
||||
const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4);
|
||||
|
||||
const unsigned RegisterCopyCost = 1;
|
||||
const unsigned AddressCopyCost = 2;
|
||||
@ -143,7 +144,7 @@ class Site {
|
||||
|
||||
virtual SiteMask nextWordMask(Context*, unsigned) = 0;
|
||||
|
||||
virtual unsigned registerSize(Context*) { return BytesPerWord; }
|
||||
virtual unsigned registerSize(Context*) { return TargetBytesPerWord; }
|
||||
|
||||
virtual unsigned registerMask(Context*) { return 0; }
|
||||
|
||||
@ -467,8 +468,9 @@ class PoolPromise: public Promise {
|
||||
|
||||
virtual int64_t value() {
|
||||
if (resolved()) {
|
||||
return reinterpret_cast<intptr_t>
|
||||
(c->machineCode + pad(c->machineCodeSize) + (key * BytesPerWord));
|
||||
return reinterpret_cast<int64_t>
|
||||
(c->machineCode + pad(c->machineCodeSize, TargetBytesPerWord)
|
||||
+ (key * TargetBytesPerWord));
|
||||
}
|
||||
|
||||
abort(c);
|
||||
@ -740,18 +742,18 @@ frameIndexToOffset(Context* c, unsigned frameIndex)
|
||||
{
|
||||
assert(c, frameIndex < totalFrameSize(c));
|
||||
|
||||
return (frameIndex + c->arch->frameFooterSize()) * BytesPerWord;
|
||||
return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord;
|
||||
}
|
||||
|
||||
unsigned
|
||||
offsetToFrameIndex(Context* c, unsigned offset)
|
||||
{
|
||||
assert(c, static_cast<int>
|
||||
((offset / BytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
||||
assert(c, ((offset / BytesPerWord) - c->arch->frameFooterSize())
|
||||
((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
||||
assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize())
|
||||
< totalFrameSize(c));
|
||||
|
||||
return (offset / BytesPerWord) - c->arch->frameFooterSize();
|
||||
return (offset / TargetBytesPerWord) - c->arch->frameFooterSize();
|
||||
}
|
||||
|
||||
unsigned
|
||||
@ -837,7 +839,7 @@ class SiteIterator {
|
||||
Site** findNext(Site** p) {
|
||||
while (true) {
|
||||
if (*p) {
|
||||
if (pass == 0 or (*p)->registerSize(c) > BytesPerWord) {
|
||||
if (pass == 0 or (*p)->registerSize(c) > TargetBytesPerWord) {
|
||||
return p;
|
||||
} else {
|
||||
p = &((*p)->next);
|
||||
@ -922,7 +924,7 @@ uniqueSite(Context* c, Value* v, Site* s)
|
||||
if (it.hasMore()) {
|
||||
// the site is not this word's only site, but if the site is
|
||||
// shared with the next word, it may be that word's only site
|
||||
if (v->nextWord != v and s->registerSize(c) > BytesPerWord) {
|
||||
if (v->nextWord != v and s->registerSize(c) > TargetBytesPerWord) {
|
||||
SiteIterator nit(c, v->nextWord);
|
||||
Site* p = nit.next();
|
||||
if (nit.hasMore()) {
|
||||
@ -1052,7 +1054,7 @@ deadWord(Context* c, Value* v)
|
||||
for (SiteIterator it(c, v, true, false); it.hasMore();) {
|
||||
Site* s = it.next();
|
||||
|
||||
if (s->registerSize(c) > BytesPerWord) {
|
||||
if (s->registerSize(c) > TargetBytesPerWord) {
|
||||
it.remove(c);
|
||||
addSite(c, nextWord, s);
|
||||
}
|
||||
@ -1838,7 +1840,7 @@ class RegisterSite: public Site {
|
||||
|
||||
RegisterSite* rs = static_cast<RegisterSite*>(s);
|
||||
unsigned size = rs->registerSize(c);
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
assert(c, number != NoRegister);
|
||||
return number == rs->number;
|
||||
} else {
|
||||
@ -1940,7 +1942,7 @@ class RegisterSite: public Site {
|
||||
virtual SiteMask nextWordMask(Context* c, unsigned) {
|
||||
assert(c, number != NoRegister);
|
||||
|
||||
if (registerSize(c) > BytesPerWord) {
|
||||
if (registerSize(c) > TargetBytesPerWord) {
|
||||
return SiteMask
|
||||
(1 << RegisterOperand, number, NoFrameIndex);
|
||||
} else {
|
||||
@ -1955,7 +1957,7 @@ class RegisterSite: public Site {
|
||||
if ((1 << number) & c->arch->floatRegisterMask()) {
|
||||
return c->arch->floatRegisterSize();
|
||||
} else {
|
||||
return BytesPerWord;
|
||||
return TargetBytesPerWord;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2065,9 +2067,9 @@ class MemorySite: public Site {
|
||||
MemorySite* ms = static_cast<MemorySite*>(s);
|
||||
return ms->base == this->base
|
||||
and ((index == 1 and ms->offset == static_cast<int>
|
||||
(this->offset + BytesPerWord))
|
||||
(this->offset + TargetBytesPerWord))
|
||||
or (index == 0 and this->offset == static_cast<int>
|
||||
(ms->offset + BytesPerWord)))
|
||||
(ms->offset + TargetBytesPerWord)))
|
||||
and ms->index == this->index
|
||||
and ms->scale == this->scale;
|
||||
} else {
|
||||
@ -2149,7 +2151,7 @@ class MemorySite: public Site {
|
||||
assert(c, high == this
|
||||
or (static_cast<MemorySite*>(high)->base == base
|
||||
and static_cast<MemorySite*>(high)->offset
|
||||
== static_cast<int>(offset + BytesPerWord)
|
||||
== static_cast<int>(offset + TargetBytesPerWord)
|
||||
and static_cast<MemorySite*>(high)->index == index
|
||||
and static_cast<MemorySite*>(high)->scale == scale));
|
||||
|
||||
@ -2164,7 +2166,7 @@ class MemorySite: public Site {
|
||||
|
||||
Site* copyHalf(Context* c, bool add) {
|
||||
if (add) {
|
||||
return memorySite(c, base, offset + BytesPerWord, index, scale);
|
||||
return memorySite(c, base, offset + TargetBytesPerWord, index, scale);
|
||||
} else {
|
||||
return copy(c);
|
||||
}
|
||||
@ -2181,7 +2183,7 @@ class MemorySite: public Site {
|
||||
virtual Site* makeNextWord(Context* c, unsigned index) {
|
||||
return memorySite
|
||||
(c, base, offset + ((index == 1) xor c->arch->bigEndian()
|
||||
? BytesPerWord : -BytesPerWord),
|
||||
? TargetBytesPerWord : -TargetBytesPerWord),
|
||||
this->index, scale);
|
||||
}
|
||||
|
||||
@ -2398,7 +2400,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord,
|
||||
unsigned registerReserveCount = 0)
|
||||
{
|
||||
Value* value = read->value;
|
||||
unsigned size = value == value->nextWord ? BytesPerWord : 8;
|
||||
unsigned size = value == value->nextWord ? TargetBytesPerWord : 8;
|
||||
|
||||
class MyCostCalculator: public CostCalculator {
|
||||
public:
|
||||
@ -2926,8 +2928,8 @@ move(Context* c, Value* value, Site* src, Site* dst)
|
||||
unsigned srcSize;
|
||||
unsigned dstSize;
|
||||
if (value->nextWord == value) {
|
||||
srcSize = BytesPerWord;
|
||||
dstSize = BytesPerWord;
|
||||
srcSize = TargetBytesPerWord;
|
||||
dstSize = TargetBytesPerWord;
|
||||
} else {
|
||||
srcSize = src->registerSize(c);
|
||||
dstSize = dst->registerSize(c);
|
||||
@ -2935,7 +2937,7 @@ move(Context* c, Value* value, Site* src, Site* dst)
|
||||
|
||||
if (srcSize == dstSize) {
|
||||
apply(c, Move, srcSize, src, src, dstSize, dst, dst);
|
||||
} else if (srcSize > BytesPerWord) {
|
||||
} else if (srcSize > TargetBytesPerWord) {
|
||||
Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high);
|
||||
other->freeze(c, value->nextWord);
|
||||
|
||||
@ -3065,7 +3067,7 @@ addReads(Context* c, Event* e, Value* v, unsigned size,
|
||||
{
|
||||
SingleRead* r = read(c, lowMask, lowSuccessor);
|
||||
addRead(c, e, v, r);
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
r->high_ = v->nextWord;
|
||||
addRead(c, e, v->nextWord, highMask, highSuccessor);
|
||||
}
|
||||
@ -3234,7 +3236,7 @@ class CallEvent: public Event {
|
||||
uint8_t typeMask;
|
||||
uint64_t planRegisterMask;
|
||||
c->arch->plan
|
||||
((flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord,
|
||||
((flags & Compiler::Aligned) ? AlignedCall : Call, TargetBytesPerWord,
|
||||
&typeMask, &planRegisterMask, &thunk);
|
||||
|
||||
assert(c, not thunk);
|
||||
@ -3251,10 +3253,11 @@ class CallEvent: public Event {
|
||||
Value* v = stack->value;
|
||||
stack = stack->next;
|
||||
|
||||
if ((BytesPerWord == 8 and (v == 0 or (i >= 1 and stack->value == 0)))
|
||||
or (BytesPerWord == 4 and v->nextWord != v))
|
||||
if ((TargetBytesPerWord == 8
|
||||
and (v == 0 or (i >= 1 and stack->value == 0)))
|
||||
or (TargetBytesPerWord == 4 and v->nextWord != v))
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or v->nextWord == stack->value);
|
||||
assert(c, TargetBytesPerWord == 8 or v->nextWord == stack->value);
|
||||
|
||||
RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value;
|
||||
stack = stack->next;
|
||||
@ -3405,7 +3408,7 @@ class CallEvent: public Event {
|
||||
op = Call;
|
||||
}
|
||||
|
||||
apply(c, op, BytesPerWord, address->source, address->source);
|
||||
apply(c, op, TargetBytesPerWord, address->source, address->source);
|
||||
|
||||
if (traceHandler) {
|
||||
traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)),
|
||||
@ -3436,7 +3439,7 @@ class CallEvent: public Event {
|
||||
|
||||
if (resultSize and live(c, result)) {
|
||||
addSite(c, result, registerSite(c, c->arch->returnLow()));
|
||||
if (resultSize > BytesPerWord and live(c, result->nextWord)) {
|
||||
if (resultSize > TargetBytesPerWord and live(c, result->nextWord)) {
|
||||
addSite(c, result->nextWord, registerSite(c, c->arch->returnHigh()));
|
||||
}
|
||||
}
|
||||
@ -3758,16 +3761,17 @@ class MoveEvent: public Event {
|
||||
|
||||
bool noop = srcSelectSize >= dstSize;
|
||||
|
||||
if (dstSize > BytesPerWord) {
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
grow(c, dst);
|
||||
}
|
||||
|
||||
if (srcSelectSize > BytesPerWord) {
|
||||
if (srcSelectSize > TargetBytesPerWord) {
|
||||
maybeSplit(c, src);
|
||||
}
|
||||
|
||||
addReads(c, this, src, srcSelectSize, srcLowMask, noop ? dst : 0,
|
||||
srcHighMask, noop and dstSize > BytesPerWord ? dst->nextWord : 0);
|
||||
srcHighMask,
|
||||
noop and dstSize > TargetBytesPerWord ? dst->nextWord : 0);
|
||||
}
|
||||
|
||||
virtual const char* name() {
|
||||
@ -3791,43 +3795,46 @@ class MoveEvent: public Event {
|
||||
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
|
||||
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
|
||||
|
||||
if (srcSelectSize >= BytesPerWord
|
||||
and dstSize >= BytesPerWord
|
||||
if (srcSelectSize >= TargetBytesPerWord
|
||||
and dstSize >= TargetBytesPerWord
|
||||
and srcSelectSize >= dstSize)
|
||||
{
|
||||
if (dst->target) {
|
||||
if (dstSize > BytesPerWord
|
||||
and src->source->registerSize(c) > BytesPerWord)
|
||||
if (dstSize > TargetBytesPerWord
|
||||
and src->source->registerSize(c) > TargetBytesPerWord)
|
||||
{
|
||||
apply(c, Move, srcSelectSize, src->source, src->source,
|
||||
dstSize, dst->target, dst->target);
|
||||
|
||||
if (live(c, dst) == 0) {
|
||||
removeSite(c, dst, dst->target);
|
||||
if (dstSize > BytesPerWord) {
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
removeSite(c, dst->nextWord, dst->nextWord->target);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
maybeMove(c, Move, BytesPerWord, BytesPerWord, src,
|
||||
BytesPerWord, dst, dstLowMask);
|
||||
if (dstSize > BytesPerWord) {
|
||||
maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord,
|
||||
BytesPerWord, dst->nextWord, dstHighMask);
|
||||
maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src,
|
||||
TargetBytesPerWord, dst, dstLowMask);
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
maybeMove
|
||||
(c, Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord,
|
||||
TargetBytesPerWord, dst->nextWord, dstHighMask);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
|
||||
if (dstSize > BytesPerWord) {
|
||||
if (dstSize > TargetBytesPerWord) {
|
||||
pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1);
|
||||
}
|
||||
}
|
||||
} else if (srcSelectSize <= BytesPerWord and dstSize <= BytesPerWord) {
|
||||
} else if (srcSelectSize <= TargetBytesPerWord
|
||||
and dstSize <= TargetBytesPerWord)
|
||||
{
|
||||
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||
dstLowMask);
|
||||
} else {
|
||||
assert(c, srcSize == BytesPerWord);
|
||||
assert(c, srcSelectSize == BytesPerWord);
|
||||
assert(c, srcSize == TargetBytesPerWord);
|
||||
assert(c, srcSelectSize == TargetBytesPerWord);
|
||||
|
||||
if (dst->nextWord->target or live(c, dst->nextWord)) {
|
||||
assert(c, dstLowMask.typeMask & (1 << RegisterOperand));
|
||||
@ -3847,8 +3854,8 @@ class MoveEvent: public Event {
|
||||
srcb, dstb, src);
|
||||
}
|
||||
|
||||
apply(c, Move, BytesPerWord, src->source, src->source,
|
||||
BytesPerWord, low, low);
|
||||
apply(c, Move, TargetBytesPerWord, src->source, src->source,
|
||||
TargetBytesPerWord, low, low);
|
||||
|
||||
low->thaw(c, dst);
|
||||
|
||||
@ -3871,7 +3878,7 @@ class MoveEvent: public Event {
|
||||
srcb, dstb, dst, dst->nextWord);
|
||||
}
|
||||
|
||||
apply(c, Move, BytesPerWord, low, low, dstSize, low, high);
|
||||
apply(c, Move, TargetBytesPerWord, low, low, dstSize, low, high);
|
||||
|
||||
high->thaw(c, dst->nextWord);
|
||||
|
||||
@ -3972,7 +3979,7 @@ void
|
||||
freezeSource(Context* c, unsigned size, Value* v)
|
||||
{
|
||||
v->source->freeze(c, v);
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
v->nextWord->source->freeze(c, v->nextWord);
|
||||
}
|
||||
}
|
||||
@ -3981,7 +3988,7 @@ void
|
||||
thawSource(Context* c, unsigned size, Value* v)
|
||||
{
|
||||
v->source->thaw(c, v);
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
v->nextWord->source->thaw(c, v->nextWord);
|
||||
}
|
||||
}
|
||||
@ -4002,7 +4009,7 @@ class CombineEvent: public Event {
|
||||
{
|
||||
addReads(c, this, first, firstSize, firstLowMask, firstHighMask);
|
||||
|
||||
if (resultSize > BytesPerWord) {
|
||||
if (resultSize > TargetBytesPerWord) {
|
||||
grow(c, result);
|
||||
}
|
||||
|
||||
@ -4227,7 +4234,7 @@ push(Context* c, unsigned footprint, Value* v)
|
||||
if (footprint > 1) {
|
||||
assert(c, footprint == 2);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
maybeSplit(c, low);
|
||||
high = pushWord(c, low->nextWord);
|
||||
} else {
|
||||
@ -4288,9 +4295,9 @@ pop(Context* c, unsigned footprint)
|
||||
high = low->next;
|
||||
}
|
||||
|
||||
assert(c, (BytesPerWord == 8
|
||||
assert(c, (TargetBytesPerWord == 8
|
||||
and low->value->nextWord == low->value and high->value == 0)
|
||||
or (BytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
or (TargetBytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
#endif // not NDEBUG
|
||||
|
||||
popWord(c);
|
||||
@ -4331,7 +4338,7 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy)
|
||||
highIndex = index;
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
assert(c, v->nextWord != v);
|
||||
|
||||
high = storeLocal(c, 1, v->nextWord, highIndex, false);
|
||||
@ -4423,11 +4430,11 @@ appendCombine(Context* c, TernaryOperation type,
|
||||
intptr_t handler = c->client->getThunk
|
||||
(type, firstSize, resultSize, &threadParameter);
|
||||
|
||||
unsigned stackSize = ceiling(secondSize, BytesPerWord)
|
||||
+ ceiling(firstSize, BytesPerWord);
|
||||
unsigned stackSize = ceiling(secondSize, TargetBytesPerWord)
|
||||
+ ceiling(firstSize, TargetBytesPerWord);
|
||||
|
||||
local::push(c, ceiling(secondSize, BytesPerWord), second);
|
||||
local::push(c, ceiling(firstSize, BytesPerWord), first);
|
||||
local::push(c, ceiling(secondSize, TargetBytesPerWord), second);
|
||||
local::push(c, ceiling(firstSize, TargetBytesPerWord), first);
|
||||
|
||||
if (threadParameter) {
|
||||
++ stackSize;
|
||||
@ -4467,7 +4474,7 @@ class TranslateEvent: public Event {
|
||||
{
|
||||
bool condensed = c->arch->alwaysCondensed(type);
|
||||
|
||||
if (resultSize > BytesPerWord) {
|
||||
if (resultSize > TargetBytesPerWord) {
|
||||
grow(c, result);
|
||||
}
|
||||
|
||||
@ -4549,7 +4556,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize,
|
||||
if (thunk) {
|
||||
Stack* oldStack = c->stack;
|
||||
|
||||
local::push(c, ceiling(firstSize, BytesPerWord), first);
|
||||
local::push(c, ceiling(firstSize, TargetBytesPerWord), first);
|
||||
|
||||
Stack* argumentStack = c->stack;
|
||||
c->stack = oldStack;
|
||||
@ -4559,7 +4566,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize,
|
||||
(c, ValueGeneral, constantSite
|
||||
(c, c->client->getThunk(type, firstSize, resultSize))),
|
||||
0, 0, result, resultSize, argumentStack,
|
||||
ceiling(firstSize, BytesPerWord), 0);
|
||||
ceiling(firstSize, TargetBytesPerWord), 0);
|
||||
} else {
|
||||
append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
|
||||
TranslateEvent
|
||||
@ -4632,7 +4639,7 @@ class MemoryEvent: public Event {
|
||||
|
||||
popRead(c, this, base);
|
||||
if (index) {
|
||||
if (BytesPerWord == 8 and indexRegister != NoRegister) {
|
||||
if (TargetBytesPerWord == 8 and indexRegister != NoRegister) {
|
||||
apply(c, Move, 4, index->source, index->source,
|
||||
8, index->source, index->source);
|
||||
}
|
||||
@ -4798,7 +4805,7 @@ class BranchEvent: public Event {
|
||||
|
||||
uint8_t typeMask;
|
||||
uint64_t registerMask;
|
||||
c->arch->planDestination(type, size, 0, 0, size, 0, 0, BytesPerWord,
|
||||
c->arch->planDestination(type, size, 0, 0, size, 0, 0, TargetBytesPerWord,
|
||||
&typeMask, ®isterMask);
|
||||
|
||||
addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
||||
@ -4821,7 +4828,7 @@ class BranchEvent: public Event {
|
||||
int64_t firstValue = firstConstant->value->value();
|
||||
int64_t secondValue = secondConstant->value->value();
|
||||
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
firstValue |= findConstantSite
|
||||
(c, first->nextWord)->value->value() << 32;
|
||||
secondValue |= findConstantSite
|
||||
@ -4829,18 +4836,18 @@ class BranchEvent: public Event {
|
||||
}
|
||||
|
||||
if (shouldJump(c, type, size, firstValue, secondValue)) {
|
||||
apply(c, Jump, BytesPerWord, address->source, address->source);
|
||||
apply(c, Jump, TargetBytesPerWord, address->source, address->source);
|
||||
}
|
||||
} else {
|
||||
freezeSource(c, size, first);
|
||||
freezeSource(c, size, second);
|
||||
freezeSource(c, BytesPerWord, address);
|
||||
freezeSource(c, TargetBytesPerWord, address);
|
||||
|
||||
apply(c, type, size, first->source, first->nextWord->source,
|
||||
size, second->source, second->nextWord->source,
|
||||
BytesPerWord, address->source, address->source);
|
||||
TargetBytesPerWord, address->source, address->source);
|
||||
|
||||
thawSource(c, BytesPerWord, address);
|
||||
thawSource(c, TargetBytesPerWord, address);
|
||||
thawSource(c, size, second);
|
||||
thawSource(c, size, first);
|
||||
}
|
||||
@ -4872,7 +4879,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
||||
|
||||
c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask,
|
||||
size, &secondTypeMask, &secondRegisterMask,
|
||||
BytesPerWord, &thunk);
|
||||
TargetBytesPerWord, &thunk);
|
||||
|
||||
if (thunk) {
|
||||
Stack* oldStack = c->stack;
|
||||
@ -4883,8 +4890,8 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
||||
|
||||
assert(c, not threadParameter);
|
||||
|
||||
local::push(c, ceiling(size, BytesPerWord), second);
|
||||
local::push(c, ceiling(size, BytesPerWord), first);
|
||||
local::push(c, ceiling(size, TargetBytesPerWord), second);
|
||||
local::push(c, ceiling(size, TargetBytesPerWord), first);
|
||||
|
||||
Stack* argumentStack = c->stack;
|
||||
c->stack = oldStack;
|
||||
@ -4893,7 +4900,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
||||
appendCall
|
||||
(c, value
|
||||
(c, ValueGeneral, constantSite(c, handler)), 0, 0, result, 4,
|
||||
argumentStack, ceiling(size, BytesPerWord) * 2, 0);
|
||||
argumentStack, ceiling(size, TargetBytesPerWord) * 2, 0);
|
||||
|
||||
appendBranch(c, thunkBranch(c, type), 4, value
|
||||
(c, ValueGeneral, constantSite(c, static_cast<int64_t>(0))),
|
||||
@ -4920,7 +4927,7 @@ class JumpEvent: public Event {
|
||||
bool thunk;
|
||||
uint8_t typeMask;
|
||||
uint64_t registerMask;
|
||||
c->arch->plan(type, BytesPerWord, &typeMask, ®isterMask, &thunk);
|
||||
c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk);
|
||||
|
||||
assert(c, not thunk);
|
||||
|
||||
@ -4933,7 +4940,7 @@ class JumpEvent: public Event {
|
||||
|
||||
virtual void compile(Context* c) {
|
||||
if (not unreachable(this)) {
|
||||
apply(c, type, BytesPerWord, address->source, address->source);
|
||||
apply(c, type, TargetBytesPerWord, address->source, address->source);
|
||||
}
|
||||
|
||||
for (Read* r = reads; r; r = r->eventNext) {
|
||||
@ -4992,7 +4999,7 @@ class BoundsCheckEvent: public Event {
|
||||
if (constant) {
|
||||
if (constant->value->value() < 0) {
|
||||
Assembler::Constant handlerConstant(resolved(c, handler));
|
||||
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
||||
a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant);
|
||||
}
|
||||
} else {
|
||||
outOfBoundsPromise = codePromise(c, static_cast<Promise*>(0));
|
||||
@ -5000,7 +5007,7 @@ class BoundsCheckEvent: public Event {
|
||||
ConstantSite zero(resolved(c, 0));
|
||||
ConstantSite oob(outOfBoundsPromise);
|
||||
apply(c, JumpIfLess, 4, &zero, &zero, 4, index->source, index->source,
|
||||
BytesPerWord, &oob, &oob);
|
||||
TargetBytesPerWord, &oob, &oob);
|
||||
}
|
||||
|
||||
if (constant == 0 or constant->value->value() >= 0) {
|
||||
@ -5011,20 +5018,20 @@ class BoundsCheckEvent: public Event {
|
||||
|
||||
CodePromise* nextPromise = codePromise(c, static_cast<Promise*>(0));
|
||||
|
||||
freezeSource(c, BytesPerWord, index);
|
||||
freezeSource(c, TargetBytesPerWord, index);
|
||||
|
||||
ConstantSite next(nextPromise);
|
||||
apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length,
|
||||
&length, BytesPerWord, &next, &next);
|
||||
&length, TargetBytesPerWord, &next, &next);
|
||||
|
||||
thawSource(c, BytesPerWord, index);
|
||||
thawSource(c, TargetBytesPerWord, index);
|
||||
|
||||
if (constant == 0) {
|
||||
outOfBoundsPromise->offset = a->offset();
|
||||
}
|
||||
|
||||
Assembler::Constant handlerConstant(resolved(c, handler));
|
||||
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
||||
a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant);
|
||||
|
||||
nextPromise->offset = a->offset();
|
||||
}
|
||||
@ -6268,7 +6275,7 @@ class MyCompiler: public Compiler {
|
||||
|
||||
virtual void save(unsigned footprint, Operand* value) {
|
||||
c.saved = cons(&c, static_cast<Value*>(value), c.saved);
|
||||
if (BytesPerWord == 4 and footprint > 1) {
|
||||
if (TargetBytesPerWord == 4 and footprint > 1) {
|
||||
assert(&c, footprint == 2);
|
||||
assert(&c, static_cast<Value*>(value)->nextWord);
|
||||
|
||||
@ -6329,9 +6336,10 @@ class MyCompiler: public Compiler {
|
||||
high = s->next;
|
||||
}
|
||||
|
||||
assert(&c, (BytesPerWord == 8
|
||||
assert(&c, (TargetBytesPerWord == 8
|
||||
and low->value->nextWord == low->value and high->value == 0)
|
||||
or (BytesPerWord == 4 and low->value->nextWord == high->value));
|
||||
or (TargetBytesPerWord == 4
|
||||
and low->value->nextWord == high->value));
|
||||
#endif // not NDEBUG
|
||||
|
||||
if (bigEndian) {
|
||||
@ -6355,20 +6363,20 @@ class MyCompiler: public Compiler {
|
||||
bool bigEndian = c.arch->bigEndian();
|
||||
|
||||
unsigned footprint = 0;
|
||||
unsigned size = BytesPerWord;
|
||||
unsigned size = TargetBytesPerWord;
|
||||
RUNTIME_ARRAY(Value*, arguments, argumentCount);
|
||||
int index = 0;
|
||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||
Value* o = va_arg(a, Value*);
|
||||
if (o) {
|
||||
if (bigEndian and size > BytesPerWord) {
|
||||
if (bigEndian and size > TargetBytesPerWord) {
|
||||
RUNTIME_ARRAY_BODY(arguments)[index++] = o->nextWord;
|
||||
}
|
||||
RUNTIME_ARRAY_BODY(arguments)[index] = o;
|
||||
if ((not bigEndian) and size > BytesPerWord) {
|
||||
if ((not bigEndian) and size > TargetBytesPerWord) {
|
||||
RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord;
|
||||
}
|
||||
size = BytesPerWord;
|
||||
size = TargetBytesPerWord;
|
||||
++ index;
|
||||
} else {
|
||||
size = 8;
|
||||
@ -6427,7 +6435,7 @@ class MyCompiler: public Compiler {
|
||||
highIndex = index;
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
initLocal(1, highIndex, type);
|
||||
Value* next = c.locals[highIndex].value;
|
||||
v->nextWord = next;
|
||||
@ -6499,7 +6507,7 @@ class MyCompiler: public Compiler {
|
||||
virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src,
|
||||
unsigned dstSize)
|
||||
{
|
||||
assert(&c, dstSize >= BytesPerWord);
|
||||
assert(&c, dstSize >= TargetBytesPerWord);
|
||||
|
||||
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
||||
appendMove(&c, Move, srcSize, srcSelectSize, static_cast<Value*>(src),
|
||||
@ -6510,7 +6518,7 @@ class MyCompiler: public Compiler {
|
||||
virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize,
|
||||
Operand* src, unsigned dstSize)
|
||||
{
|
||||
assert(&c, dstSize >= BytesPerWord);
|
||||
assert(&c, dstSize >= TargetBytesPerWord);
|
||||
|
||||
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
||||
appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast<Value*>(src),
|
||||
@ -6786,7 +6794,7 @@ class MyCompiler: public Compiler {
|
||||
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||
Value* result = value(&c, ValueGeneral);
|
||||
appendCombine(&c, ShiftLeft, BytesPerWord, static_cast<Value*>(a),
|
||||
appendCombine(&c, ShiftLeft, TargetBytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
@ -6794,7 +6802,7 @@ class MyCompiler: public Compiler {
|
||||
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||
Value* result = value(&c, ValueGeneral);
|
||||
appendCombine(&c, ShiftRight, BytesPerWord, static_cast<Value*>(a),
|
||||
appendCombine(&c, ShiftRight, TargetBytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
@ -6803,8 +6811,8 @@ class MyCompiler: public Compiler {
|
||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||
Value* result = value(&c, ValueGeneral);
|
||||
appendCombine
|
||||
(&c, UnsignedShiftRight, BytesPerWord, static_cast<Value*>(a), size,
|
||||
static_cast<Value*>(b), size, result);
|
||||
(&c, UnsignedShiftRight, TargetBytesPerWord, static_cast<Value*>(a),
|
||||
size, static_cast<Value*>(b), size, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -6933,7 +6941,7 @@ class MyCompiler: public Compiler {
|
||||
}
|
||||
|
||||
virtual unsigned poolSize() {
|
||||
return c.constantCount * BytesPerWord;
|
||||
return c.constantCount * TargetBytesPerWord;
|
||||
}
|
||||
|
||||
virtual void write() {
|
||||
@ -6941,15 +6949,15 @@ class MyCompiler: public Compiler {
|
||||
|
||||
int i = 0;
|
||||
for (ConstantPoolNode* n = c.firstConstant; n; n = n->next) {
|
||||
intptr_t* target = reinterpret_cast<intptr_t*>
|
||||
(c.machineCode + pad(c.machineCodeSize) + i);
|
||||
target_intptr_t* target = reinterpret_cast<target_intptr_t*>
|
||||
(c.machineCode + pad(c.machineCodeSize, TargetBytesPerWord) + i);
|
||||
|
||||
if (n->promise->resolved()) {
|
||||
*target = n->promise->value();
|
||||
} else {
|
||||
class Listener: public Promise::Listener {
|
||||
public:
|
||||
Listener(intptr_t* target): target(target){ }
|
||||
Listener(target_intptr_t* target): target(target){ }
|
||||
|
||||
virtual bool resolve(int64_t value, void** location) {
|
||||
*target = value;
|
||||
@ -6957,12 +6965,12 @@ class MyCompiler: public Compiler {
|
||||
return true;
|
||||
}
|
||||
|
||||
intptr_t* target;
|
||||
target_intptr_t* target;
|
||||
};
|
||||
new (n->promise->listen(sizeof(Listener))) Listener(target);
|
||||
}
|
||||
|
||||
i += BytesPerWord;
|
||||
i += TargetBytesPerWord;
|
||||
}
|
||||
}
|
||||
|
||||
|
13
src/heap.cpp
13
src/heap.cpp
@ -19,12 +19,6 @@ namespace {
|
||||
|
||||
namespace local {
|
||||
|
||||
// an object must survive TenureThreshold + 2 garbage collections
|
||||
// before being copied to gen2 (must be at least 1):
|
||||
const unsigned TenureThreshold = 3;
|
||||
|
||||
const unsigned FixieTenureThreshold = TenureThreshold + 2;
|
||||
|
||||
const unsigned Top = ~static_cast<unsigned>(0);
|
||||
|
||||
const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024;
|
||||
@ -535,7 +529,7 @@ class Fixie {
|
||||
}
|
||||
|
||||
static unsigned maskSize(unsigned size, bool hasMask) {
|
||||
return hasMask * ceiling(size, BytesPerWord) * BytesPerWord;
|
||||
return hasMask * ceiling(size, BitsPerWord) * BytesPerWord;
|
||||
}
|
||||
|
||||
static unsigned totalSize(unsigned size, bool hasMask) {
|
||||
@ -546,11 +540,14 @@ class Fixie {
|
||||
return totalSize(size, hasMask);
|
||||
}
|
||||
|
||||
// be sure to update e.g. TargetFixieSizeInBytes in bootimage.cpp if
|
||||
// you add/remove/change fields in this class:
|
||||
|
||||
uint8_t age;
|
||||
bool hasMask;
|
||||
bool marked;
|
||||
bool dirty;
|
||||
unsigned size;
|
||||
uint32_t size;
|
||||
Fixie* next;
|
||||
Fixie** handle;
|
||||
uintptr_t body_[0];
|
||||
|
@ -16,6 +16,12 @@
|
||||
|
||||
namespace vm {
|
||||
|
||||
// an object must survive TenureThreshold + 2 garbage collections
|
||||
// before being copied to gen2 (must be at least 1):
|
||||
const unsigned TenureThreshold = 3;
|
||||
|
||||
const unsigned FixieTenureThreshold = TenureThreshold + 2;
|
||||
|
||||
class Heap: public Allocator {
|
||||
public:
|
||||
enum CollectionType {
|
||||
|
@ -665,7 +665,7 @@ store(Thread* t, unsigned index)
|
||||
BytesPerWord * 2);
|
||||
}
|
||||
|
||||
ExceptionHandler*
|
||||
uint64_t
|
||||
findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||
{
|
||||
PROTECT(t, method);
|
||||
@ -674,7 +674,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||
|
||||
if (eht) {
|
||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||
uint64_t eh = exceptionHandlerTableBody(t, eht, i);
|
||||
|
||||
if (ip - 1 >= exceptionHandlerStart(eh)
|
||||
and ip - 1 < exceptionHandlerEnd(eh))
|
||||
@ -708,7 +708,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ExceptionHandler*
|
||||
uint64_t
|
||||
findExceptionHandler(Thread* t, int frame)
|
||||
{
|
||||
return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, frame));
|
||||
@ -2673,7 +2673,7 @@ interpret3(Thread* t, const int base)
|
||||
|
||||
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
||||
for (; frame >= base; popFrame(t)) {
|
||||
ExceptionHandler* eh = findExceptionHandler(t, frame);
|
||||
uint64_t eh = findExceptionHandler(t, frame);
|
||||
if (eh) {
|
||||
sp = frame + FrameFootprint;
|
||||
ip = exceptionHandlerIp(eh);
|
||||
@ -3067,7 +3067,7 @@ class MyProcessor: public Processor {
|
||||
}
|
||||
|
||||
virtual void compileMethod(vm::Thread*, Zone*, object*, object*,
|
||||
DelayedPromise**, object)
|
||||
DelayedPromise**, object, OffsetResolver*)
|
||||
{
|
||||
abort(s);
|
||||
}
|
||||
@ -3076,6 +3076,10 @@ class MyProcessor: public Processor {
|
||||
abort(s);
|
||||
}
|
||||
|
||||
virtual void normalizeVirtualThunks(vm::Thread*) {
|
||||
abort(s);
|
||||
}
|
||||
|
||||
virtual unsigned* makeCallTable(vm::Thread*, HeapWalker*) {
|
||||
abort(s);
|
||||
}
|
||||
|
@ -3324,11 +3324,15 @@ JNI_CreateJavaVM(Machine** m, Thread** t, void* args)
|
||||
unsigned bootClasspathBufferSize = bcppl + bcpl + bcpal + 3;
|
||||
RUNTIME_ARRAY(char, bootClasspathBuffer, bootClasspathBufferSize);
|
||||
char* bootClasspathPointer = RUNTIME_ARRAY_BODY(bootClasspathBuffer);
|
||||
local::append(&bootClasspathPointer, bootClasspathPrepend, bcppl,
|
||||
bcpl + bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspath, bcpl,
|
||||
bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspathAppend, bcpal, 0);
|
||||
if (bootClasspathBufferSize > 3) {
|
||||
local::append(&bootClasspathPointer, bootClasspathPrepend, bcppl,
|
||||
bcpl + bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspath, bcpl,
|
||||
bcpal ? PATH_SEPARATOR : 0);
|
||||
local::append(&bootClasspathPointer, bootClasspathAppend, bcpal, 0);
|
||||
} else {
|
||||
*RUNTIME_ARRAY_BODY(bootClasspathBuffer) = 0;
|
||||
}
|
||||
|
||||
Finder* bf = makeFinder
|
||||
(s, h, RUNTIME_ARRAY_BODY(bootClasspathBuffer), bootLibrary);
|
||||
|
@ -1143,11 +1143,10 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
addendum,
|
||||
class_);
|
||||
|
||||
unsigned size = fieldSize(t, code);
|
||||
if (flags & ACC_STATIC) {
|
||||
unsigned size = fieldSize(t, code);
|
||||
unsigned excess = (staticOffset % size) % BytesPerWord;
|
||||
if (excess) {
|
||||
staticOffset += BytesPerWord - excess;
|
||||
while (staticOffset % size) {
|
||||
++ staticOffset;
|
||||
}
|
||||
|
||||
fieldOffset(t, field) = staticOffset;
|
||||
@ -1162,12 +1161,13 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
||||
classVmFlags(t, class_) |= HasFinalMemberFlag;
|
||||
}
|
||||
|
||||
while (memberOffset % fieldSize(t, code)) {
|
||||
while (memberOffset % size) {
|
||||
++ memberOffset;
|
||||
}
|
||||
|
||||
fieldOffset(t, field) = memberOffset;
|
||||
memberOffset += fieldSize(t, code);
|
||||
|
||||
memberOffset += size;
|
||||
}
|
||||
|
||||
set(t, fieldTable, ArrayBody + (i * BytesPerWord), field);
|
||||
@ -1298,11 +1298,12 @@ parseCode(Thread* t, Stream& s, object pool)
|
||||
if (ehtLength) {
|
||||
object eht = makeExceptionHandlerTable(t, ehtLength);
|
||||
for (unsigned i = 0; i < ehtLength; ++i) {
|
||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
||||
exceptionHandlerStart(eh) = s.read2();
|
||||
exceptionHandlerEnd(eh) = s.read2();
|
||||
exceptionHandlerIp(eh) = s.read2();
|
||||
exceptionHandlerCatchType(eh) = s.read2();
|
||||
unsigned start = s.read2();
|
||||
unsigned end = s.read2();
|
||||
unsigned ip = s.read2();
|
||||
unsigned catchType = s.read2();
|
||||
exceptionHandlerTableBody(t, eht, i) = exceptionHandler
|
||||
(start, end, ip, catchType);
|
||||
}
|
||||
|
||||
set(t, code, CodeExceptionHandlerTable, eht);
|
||||
@ -1319,9 +1320,9 @@ parseCode(Thread* t, Stream& s, object pool)
|
||||
unsigned lntLength = s.read2();
|
||||
object lnt = makeLineNumberTable(t, lntLength);
|
||||
for (unsigned i = 0; i < lntLength; ++i) {
|
||||
LineNumber* ln = lineNumberTableBody(t, lnt, i);
|
||||
lineNumberIp(ln) = s.read2();
|
||||
lineNumberLine(ln) = s.read2();
|
||||
unsigned ip = s.read2();
|
||||
unsigned line = s.read2();
|
||||
lineNumberTableBody(t, lnt, i) = lineNumber(ip, line);
|
||||
}
|
||||
|
||||
set(t, code, CodeLineNumberTable, lnt);
|
||||
@ -1451,15 +1452,15 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
|
||||
unsigned attributeCount = s.read2();
|
||||
for (unsigned j = 0; j < attributeCount; ++j) {
|
||||
object name = singletonObject(t, pool, s.read2() - 1);
|
||||
object attributeName = singletonObject(t, pool, s.read2() - 1);
|
||||
unsigned length = s.read4();
|
||||
|
||||
if (vm::strcmp(reinterpret_cast<const int8_t*>("Code"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
&byteArrayBody(t, attributeName, 0)) == 0)
|
||||
{
|
||||
code = parseCode(t, s, pool);
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Exceptions"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
&byteArrayBody(t, attributeName, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
@ -1472,7 +1473,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
set(t, addendum, MethodAddendumExceptionTable, body);
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("AnnotationDefault"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
&byteArrayBody(t, attributeName, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
@ -1484,7 +1485,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
|
||||
set(t, addendum, MethodAddendumAnnotationDefault, body);
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>("Signature"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
&byteArrayBody(t, attributeName, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
@ -1494,7 +1495,7 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
|
||||
singletonObject(t, pool, s.read2() - 1));
|
||||
} else if (vm::strcmp(reinterpret_cast<const int8_t*>
|
||||
("RuntimeVisibleAnnotations"),
|
||||
&byteArrayBody(t, name, 0)) == 0)
|
||||
&byteArrayBody(t, attributeName, 0)) == 0)
|
||||
{
|
||||
if (addendum == 0) {
|
||||
addendum = makeMethodAddendum(t, pool, 0, 0, 0, 0);
|
||||
@ -2217,9 +2218,9 @@ boot(Thread* t)
|
||||
|
||||
#include "type-java-initializations.cpp"
|
||||
|
||||
#ifdef AVIAN_HEAPDUMP
|
||||
//#ifdef AVIAN_HEAPDUMP
|
||||
# include "type-name-initializations.cpp"
|
||||
#endif
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -3428,6 +3429,16 @@ parseClass(Thread* t, object loader, const uint8_t* data, unsigned size,
|
||||
|
||||
updateClassTables(t, real, class_);
|
||||
|
||||
if (root(t, Machine::PoolMap)) {
|
||||
object bootstrapClass = hashMapFind
|
||||
(t, root(t, Machine::BootstrapClassMap), className(t, class_),
|
||||
byteArrayHash, byteArrayEqual);
|
||||
|
||||
hashMapInsert
|
||||
(t, root(t, Machine::PoolMap), bootstrapClass ? bootstrapClass : real,
|
||||
pool, objectHash);
|
||||
}
|
||||
|
||||
return real;
|
||||
}
|
||||
|
||||
@ -4426,7 +4437,7 @@ vmAddressFromLine(Thread* t, object m, unsigned line)
|
||||
unsigned top = lineNumberTableLength(t, lnt);
|
||||
for(unsigned i = bottom; i < top; i++)
|
||||
{
|
||||
LineNumber* ln = lineNumberTableBody(t, lnt, i);
|
||||
uint64_t ln = lineNumberTableBody(t, lnt, i);
|
||||
if(lineNumberLine(ln) == line)
|
||||
return reinterpret_cast<void*>(lineNumberIp(ln));
|
||||
else if(lineNumberLine(ln) > line)
|
||||
|
@ -1253,6 +1253,7 @@ class Machine {
|
||||
MonitorMap,
|
||||
StringMap,
|
||||
ByteArrayMap,
|
||||
PoolMap,
|
||||
ClassRuntimeDataTable,
|
||||
MethodRuntimeDataTable,
|
||||
JNIMethodTable,
|
||||
@ -3283,14 +3284,20 @@ methodVirtual(Thread* t, object method)
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
singletonMaskSize(unsigned count)
|
||||
singletonMaskSize(unsigned count, unsigned bitsPerWord)
|
||||
{
|
||||
if (count) {
|
||||
return ceiling(count + 2, BitsPerWord);
|
||||
return ceiling(count + 2, bitsPerWord);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
singletonMaskSize(unsigned count)
|
||||
{
|
||||
return singletonMaskSize(count, BitsPerWord);
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
singletonMaskSize(Thread* t, object singleton)
|
||||
{
|
||||
@ -3315,11 +3322,17 @@ singletonMask(Thread* t, object singleton)
|
||||
(&singletonBody(t, singleton, singletonCount(t, singleton)));
|
||||
}
|
||||
|
||||
inline void
|
||||
singletonMarkObject(uint32_t* mask, unsigned index)
|
||||
{
|
||||
mask[(index + 2) / 32]
|
||||
|= (static_cast<uint32_t>(1) << ((index + 2) % 32));
|
||||
}
|
||||
|
||||
inline void
|
||||
singletonMarkObject(Thread* t, object singleton, unsigned index)
|
||||
{
|
||||
singletonMask(t, singleton)[(index + 2) / 32]
|
||||
|= (static_cast<uint32_t>(1) << ((index + 2) % 32));
|
||||
singletonMarkObject(singletonMask(t, singleton), index);
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -3370,10 +3383,16 @@ singletonBit(Thread* t, object singleton, unsigned start, unsigned index)
|
||||
& (static_cast<uintptr_t>(1) << (index % BitsPerWord))) != 0;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
poolMaskSize(unsigned count, unsigned bitsPerWord)
|
||||
{
|
||||
return ceiling(count, bitsPerWord);
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
poolMaskSize(unsigned count)
|
||||
{
|
||||
return ceiling(count, BitsPerWord);
|
||||
return poolMaskSize(count, BitsPerWord);
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
@ -3766,6 +3785,54 @@ methodClone(Thread* t, object method)
|
||||
methodCode(t, method));
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
exceptionHandler(uint64_t start, uint64_t end, uint64_t ip, uint64_t catchType)
|
||||
{
|
||||
return (start << 48) | (end << 32) | (ip << 16) | catchType;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
exceptionHandlerStart(uint64_t eh)
|
||||
{
|
||||
return eh >> 48;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
exceptionHandlerEnd(uint64_t eh)
|
||||
{
|
||||
return (eh >> 32) & 0xFFFF;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
exceptionHandlerIp(uint64_t eh)
|
||||
{
|
||||
return (eh >> 16) & 0xFFFF;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
exceptionHandlerCatchType(uint64_t eh)
|
||||
{
|
||||
return eh & 0xFFFF;
|
||||
}
|
||||
|
||||
inline uint64_t
|
||||
lineNumber(uint64_t ip, uint64_t line)
|
||||
{
|
||||
return (ip << 32) | line;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
lineNumberIp(uint64_t ln)
|
||||
{
|
||||
return ln >> 32;
|
||||
}
|
||||
|
||||
inline unsigned
|
||||
lineNumberLine(uint64_t ln)
|
||||
{
|
||||
return ln & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
inline FILE*
|
||||
errorLog(Thread* t)
|
||||
{
|
||||
|
@ -271,7 +271,7 @@ findLineNumber(Thread* t, object method, unsigned ip)
|
||||
unsigned top = lineNumberTableLength(t, lnt);
|
||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||
unsigned middle = bottom + (span / 2);
|
||||
LineNumber* ln = lineNumberTableBody(t, lnt, middle);
|
||||
uint64_t ln = lineNumberTableBody(t, lnt, middle);
|
||||
|
||||
if (ip >= lineNumberIp(ln)
|
||||
and (middle + 1 == lineNumberTableLength(t, lnt)
|
||||
|
@ -122,11 +122,15 @@ class Processor {
|
||||
|
||||
virtual void
|
||||
compileMethod(Thread* t, Zone* zone, object* constants, object* calls,
|
||||
DelayedPromise** addresses, object method) = 0;
|
||||
DelayedPromise** addresses, object method,
|
||||
OffsetResolver* resolver) = 0;
|
||||
|
||||
virtual void
|
||||
visitRoots(Thread* t, HeapWalker* w) = 0;
|
||||
|
||||
virtual void
|
||||
normalizeVirtualThunks(Thread* t) = 0;
|
||||
|
||||
virtual unsigned*
|
||||
makeCallTable(Thread* t, HeapWalker* w) = 0;
|
||||
|
||||
|
103
src/target.h
Normal file
103
src/target.h
Normal file
@ -0,0 +1,103 @@
|
||||
/* Copyright (c) 2011, Avian Contributors
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software
|
||||
for any purpose with or without fee is hereby granted, provided
|
||||
that the above copyright notice and this permission notice appear
|
||||
in all copies.
|
||||
|
||||
There is NO WARRANTY for this software. See license.txt for
|
||||
details. */
|
||||
|
||||
#ifndef TARGET_H
|
||||
#define TARGET_H
|
||||
|
||||
#define TARGET_V1(v) (v)
|
||||
|
||||
#ifdef TARGET_OPPOSITE_ENDIAN
|
||||
# define TARGET_V2(v) \
|
||||
((((v) >> 8) & 0xFF) | \
|
||||
(((v) << 8)))
|
||||
# define TARGET_V4(v) \
|
||||
((((v) >> 24) & 0x000000FF) | \
|
||||
(((v) >> 8) & 0x0000FF00) | \
|
||||
(((v) << 8) & 0x00FF0000) | \
|
||||
(((v) << 24)))
|
||||
# define TARGET_V8(v) \
|
||||
(((static_cast<uint64_t>(v) >> 56) & UINT64_C(0x00000000000000FF)) | \
|
||||
((static_cast<uint64_t>(v) >> 40) & UINT64_C(0x000000000000FF00)) | \
|
||||
((static_cast<uint64_t>(v) >> 24) & UINT64_C(0x0000000000FF0000)) | \
|
||||
((static_cast<uint64_t>(v) >> 8) & UINT64_C(0x00000000FF000000)) | \
|
||||
((static_cast<uint64_t>(v) << 8) & UINT64_C(0x000000FF00000000)) | \
|
||||
((static_cast<uint64_t>(v) << 24) & UINT64_C(0x0000FF0000000000)) | \
|
||||
((static_cast<uint64_t>(v) << 40) & UINT64_C(0x00FF000000000000)) | \
|
||||
((static_cast<uint64_t>(v) << 56)))
|
||||
#else
|
||||
# define TARGET_V2(v) (v)
|
||||
# define TARGET_V4(v) (v)
|
||||
# define TARGET_V8(v) (v)
|
||||
#endif
|
||||
|
||||
namespace vm {
|
||||
|
||||
#ifdef TARGET_BYTES_PER_WORD
|
||||
# if (TARGET_BYTES_PER_WORD == 8)
|
||||
# define TARGET_VW(v) TARGET_V8(v)
|
||||
|
||||
typedef uint64_t target_uintptr_t;
|
||||
typedef int64_t target_intptr_t;
|
||||
|
||||
const unsigned TargetBytesPerWord = 8;
|
||||
|
||||
const unsigned TargetThreadTailAddress = 2272;
|
||||
const unsigned TargetThreadStackLimit = 2336;
|
||||
const unsigned TargetThreadStack = 2224;
|
||||
const unsigned TargetThreadIp = 2216;
|
||||
const unsigned TargetThreadVirtualCallTarget = 2280;
|
||||
const unsigned TargetThreadVirtualCallIndex = 2288;
|
||||
|
||||
const unsigned TargetClassFixedSize = 12;
|
||||
const unsigned TargetClassArrayElementSize = 14;
|
||||
const unsigned TargetClassVtable = 128;
|
||||
|
||||
const unsigned TargetFieldOffset = 12;
|
||||
|
||||
# elif (TARGET_BYTES_PER_WORD == 4)
|
||||
# define TARGET_VW(v) TARGET_V4(v)
|
||||
|
||||
typedef uint32_t target_uintptr_t;
|
||||
typedef int32_t target_intptr_t;
|
||||
|
||||
const unsigned TargetBytesPerWord = 4;
|
||||
|
||||
const unsigned TargetThreadTailAddress = 2172;
|
||||
const unsigned TargetThreadStackLimit = 2204;
|
||||
const unsigned TargetThreadStack = 2148;
|
||||
const unsigned TargetThreadIp = 2144;
|
||||
const unsigned TargetThreadVirtualCallTarget = 2176;
|
||||
const unsigned TargetThreadVirtualCallIndex = 2180;
|
||||
|
||||
const unsigned TargetClassFixedSize = 8;
|
||||
const unsigned TargetClassArrayElementSize = 10;
|
||||
const unsigned TargetClassVtable = 68;
|
||||
|
||||
const unsigned TargetFieldOffset = 8;
|
||||
|
||||
# else
|
||||
# error
|
||||
# endif
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
const unsigned TargetBitsPerWord = TargetBytesPerWord * 8;
|
||||
|
||||
const uintptr_t TargetPointerMask
|
||||
= ((~static_cast<target_uintptr_t>(0)) / TargetBytesPerWord)
|
||||
* TargetBytesPerWord;
|
||||
|
||||
const unsigned TargetArrayLength = TargetBytesPerWord;
|
||||
const unsigned TargetArrayBody = TargetBytesPerWord * 2;
|
||||
|
||||
} // namespace vm
|
||||
|
||||
#endif//TARGET_H
|
@ -225,7 +225,6 @@ class Object {
|
||||
Scalar,
|
||||
Array,
|
||||
Method,
|
||||
Pod,
|
||||
Type,
|
||||
Pair,
|
||||
Number,
|
||||
@ -314,20 +313,18 @@ class List {
|
||||
class Scalar : public Object {
|
||||
public:
|
||||
Object* owner;
|
||||
Object* typeObject;
|
||||
const char* typeName;
|
||||
const char* name;
|
||||
unsigned elementSize;
|
||||
bool noassert;
|
||||
bool nogc;
|
||||
|
||||
static Scalar* make(Object* owner, Object* typeObject, const char* typeName,
|
||||
const char* name, unsigned size)
|
||||
static Scalar* make(Object* owner, const char* typeName, const char* name,
|
||||
unsigned size)
|
||||
{
|
||||
Scalar* o = allocate<Scalar>();
|
||||
o->type = Object::Scalar;
|
||||
o->owner = owner;
|
||||
o->typeObject = typeObject;
|
||||
o->typeName = typeName;
|
||||
o->name = name;
|
||||
o->elementSize = size;
|
||||
@ -339,13 +336,12 @@ class Scalar : public Object {
|
||||
|
||||
class Array : public Scalar {
|
||||
public:
|
||||
static Array* make(Object* owner, Object* typeObject, const char* typeName,
|
||||
const char* name, unsigned elementSize)
|
||||
static Array* make(Object* owner, const char* typeName, const char* name,
|
||||
unsigned elementSize)
|
||||
{
|
||||
Array* o = allocate<Array>();
|
||||
o->type = Object::Array;
|
||||
o->owner = owner;
|
||||
o->typeObject = typeObject;
|
||||
o->typeName = typeName;
|
||||
o->name = name;
|
||||
o->elementSize = elementSize;
|
||||
@ -380,19 +376,6 @@ memberOwner(Object* o)
|
||||
}
|
||||
}
|
||||
|
||||
Object*
|
||||
memberTypeObject(Object* o)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Scalar:
|
||||
case Object::Array:
|
||||
return static_cast<Scalar*>(o)->typeObject;
|
||||
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
memberTypeName(Object* o)
|
||||
{
|
||||
@ -406,6 +389,17 @@ memberTypeName(Object* o)
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
memberTypeEnumName(Object* o)
|
||||
{
|
||||
const char* n = memberTypeName(o);
|
||||
if (strcmp("void*", n) == 0) {
|
||||
return "word";
|
||||
} else {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
|
||||
const char*&
|
||||
memberName(Object* o)
|
||||
{
|
||||
@ -545,7 +539,7 @@ const char*
|
||||
typeName(Object* o)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Type: case Object::Pod:
|
||||
case Object::Type:
|
||||
return static_cast<Type*>(o)->name;
|
||||
|
||||
default:
|
||||
@ -557,7 +551,7 @@ const char*
|
||||
typeJavaName(Object* o)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Type: case Object::Pod:
|
||||
case Object::Type:
|
||||
return static_cast<Type*>(o)->javaName;
|
||||
|
||||
default:
|
||||
@ -569,7 +563,7 @@ Object*
|
||||
typeMembers(Object* o)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Type: case Object::Pod:
|
||||
case Object::Type:
|
||||
return static_cast<Type*>(o)->members.first;
|
||||
|
||||
default:
|
||||
@ -605,10 +599,10 @@ void
|
||||
addMember(Object* o, Object* member)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Type: case Object::Pod:
|
||||
case Object::Type:
|
||||
if (member->type == Object::Array) {
|
||||
static_cast<Type*>(o)->members.append
|
||||
(Scalar::make(o, 0, "uintptr_t", "length", BytesPerWord));
|
||||
(Scalar::make(o, "uintptr_t", "length", BytesPerWord));
|
||||
}
|
||||
static_cast<Type*>(o)->members.append(member);
|
||||
break;
|
||||
@ -822,7 +816,7 @@ declaration(const char* name, Object* declarations)
|
||||
for (Object* p = declarations; p; p = cdr(p)) {
|
||||
Object* o = car(p);
|
||||
switch (o->type) {
|
||||
case Object::Type: case Object::Pod:
|
||||
case Object::Type:
|
||||
if (equal(name, typeName(o))) return o;
|
||||
break;
|
||||
|
||||
@ -842,9 +836,6 @@ javaDeclaration(const char* name, Object* declarations)
|
||||
if (typeJavaName(o) and equal(name, typeJavaName(o))) return o;
|
||||
break;
|
||||
|
||||
case Object::Pod:
|
||||
break;
|
||||
|
||||
default: UNREACHABLE;
|
||||
}
|
||||
}
|
||||
@ -854,15 +845,11 @@ javaDeclaration(const char* name, Object* declarations)
|
||||
Object*
|
||||
derivationChain(Object* o)
|
||||
{
|
||||
if (o->type == Object::Pod) {
|
||||
return cons(o, 0);
|
||||
} else {
|
||||
Object* chain = 0;
|
||||
for (Object* p = o; p; p = typeSuper(p)) {
|
||||
chain = cons(p, chain);
|
||||
}
|
||||
return chain;
|
||||
Object* chain = 0;
|
||||
for (Object* p = o; p; p = typeSuper(p)) {
|
||||
chain = cons(p, chain);
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
class MemberIterator {
|
||||
@ -883,7 +870,7 @@ class MemberIterator {
|
||||
members(0),
|
||||
member(0),
|
||||
index_(-1),
|
||||
offset_(type->type == Object::Pod ? 0 : BytesPerWord),
|
||||
offset_(BytesPerWord),
|
||||
size_(0),
|
||||
padding_(0),
|
||||
alignment_(BytesPerWord)
|
||||
@ -972,21 +959,6 @@ class MemberIterator {
|
||||
}
|
||||
};
|
||||
|
||||
unsigned
|
||||
typeSize(Object* o)
|
||||
{
|
||||
switch (o->type) {
|
||||
case Object::Pod: {
|
||||
MemberIterator it(o);
|
||||
while (it.hasMore()) it.next();
|
||||
return pad(it.offset() + it.space());
|
||||
} break;
|
||||
|
||||
default:
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
namesPointer(const char* s)
|
||||
{
|
||||
@ -996,7 +968,7 @@ namesPointer(const char* s)
|
||||
}
|
||||
|
||||
unsigned
|
||||
sizeOf(const char* type, Object* declarations)
|
||||
sizeOf(const char* type)
|
||||
{
|
||||
if (equal(type, "object")
|
||||
or equal(type, "intptr_t") or equal(type, "uintptr_t"))
|
||||
@ -1021,33 +993,29 @@ sizeOf(const char* type, Object* declarations)
|
||||
} else if (namesPointer(type)) {
|
||||
return BytesPerWord;
|
||||
} else {
|
||||
Object* dec = declaration(type, declarations);
|
||||
if (dec) return typeSize(dec);
|
||||
|
||||
fprintf(stderr, "unexpected type: %s\n", type);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
Object*
|
||||
parseArray(Object* t, Object* p, Object* declarations)
|
||||
parseArray(Object* t, Object* p)
|
||||
{
|
||||
const char* typeName = string(car(p));
|
||||
|
||||
p = cdr(p);
|
||||
const char* name = string(car(p));
|
||||
|
||||
return Array::make(t, declaration(typeName, declarations),
|
||||
typeName, name, sizeOf(typeName, declarations));
|
||||
return Array::make(t, typeName, name, sizeOf(typeName));
|
||||
}
|
||||
|
||||
Object*
|
||||
parseMember(Object* t, Object* p, Object* declarations);
|
||||
parseMember(Object* t, Object* p);
|
||||
|
||||
Object*
|
||||
parseMember(Object* t, Object* p, Object* declarations, bool* isNew)
|
||||
parseMember(Object* t, Object* p, bool* isNew)
|
||||
{
|
||||
Object* member = parseMember(t, p, declarations);
|
||||
Object* member = parseMember(t, p);
|
||||
for (MemberIterator it(t); it.hasMore();) {
|
||||
Object* m = it.next();
|
||||
if (equal(memberName(m), memberName(member))) {
|
||||
@ -1063,34 +1031,32 @@ parseMember(Object* t, Object* p, Object* declarations, bool* isNew)
|
||||
}
|
||||
|
||||
Object*
|
||||
parseMember(Object* t, Object* p, Object* declarations)
|
||||
parseMember(Object* t, Object* p)
|
||||
{
|
||||
const char* spec = string(car(p));
|
||||
if (equal(spec, "array")) {
|
||||
return parseArray(t, cdr(p), declarations);
|
||||
return parseArray(t, cdr(p));
|
||||
} else if (equal(spec, "noassert")) {
|
||||
bool isNew;
|
||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
||||
Object* member = parseMember(t, cdr(p), &isNew);
|
||||
memberNoAssert(member) = true;
|
||||
return isNew ? member : 0;
|
||||
} else if (equal(spec, "nogc")) {
|
||||
bool isNew;
|
||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
||||
Object* member = parseMember(t, cdr(p), &isNew);
|
||||
memberNoGC(member) = true;
|
||||
return isNew ? member : 0;
|
||||
} else if (equal(spec, "require")) {
|
||||
bool isNew;
|
||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
||||
Object* member = parseMember(t, cdr(p), &isNew);
|
||||
return isNew ? member : 0;
|
||||
} else if (equal(spec, "alias")) {
|
||||
bool isNew;
|
||||
Object* member = parseMember(t, cdr(cdr(p)), declarations, &isNew);
|
||||
Object* member = parseMember(t, cdr(cdr(p)), &isNew);
|
||||
memberName(member) = string(car(cdr(p)));
|
||||
return 0;
|
||||
} else {
|
||||
return Scalar::make(t, declaration(spec, declarations), spec,
|
||||
string(car(cdr(p))),
|
||||
sizeOf(spec, declarations));
|
||||
return Scalar::make(t, spec, string(car(cdr(p))), sizeOf(spec));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1105,7 +1071,7 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations)
|
||||
assert(typeSuper(t));
|
||||
assert(typeSuper(t)->type == Object::Type);
|
||||
} else {
|
||||
Object* member = parseMember(t, p, declarations);
|
||||
Object* member = parseMember(t, p);
|
||||
if (member) {
|
||||
addMember(t, member);
|
||||
}
|
||||
@ -1297,7 +1263,7 @@ parseJavaClass(Object* type, Stream* s, Object* declarations)
|
||||
const char* memberType = fieldType(spec);
|
||||
|
||||
Object* member = Scalar::make
|
||||
(type, 0, memberType, name, sizeOf(memberType, declarations));
|
||||
(type, memberType, name, sizeOf(memberType));
|
||||
|
||||
addMember(type, member);
|
||||
}
|
||||
@ -1365,7 +1331,7 @@ parseType(Finder* finder, Object::ObjectType type, Object* p,
|
||||
if (type == Object::Type) {
|
||||
parseSubdeclaration(t, car(p), declarations);
|
||||
} else {
|
||||
Object* member = parseMember(t, car(p), declarations);
|
||||
Object* member = parseMember(t, car(p));
|
||||
if (member) {
|
||||
assert(member->type == Object::Scalar);
|
||||
addMember(t, member);
|
||||
@ -1390,8 +1356,6 @@ parseDeclaration(Finder* finder, Object* p, Object* declarations)
|
||||
const char* spec = string(car(p));
|
||||
if (equal(spec, "type")) {
|
||||
return parseType(finder, Object::Type, cdr(p), declarations);
|
||||
} else if (equal(spec, "pod")) {
|
||||
return parseType(finder, Object::Pod, cdr(p), declarations);
|
||||
} else {
|
||||
fprintf(stderr, "unexpected declaration spec: %s\n", spec);
|
||||
abort();
|
||||
@ -1473,7 +1437,6 @@ void
|
||||
writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
{
|
||||
const char* typeName = memberTypeName(member);
|
||||
if (memberTypeObject(member)) typeName = capitalize(typeName);
|
||||
|
||||
if (not unsafe) {
|
||||
out->write("const unsigned ");
|
||||
@ -1491,22 +1454,12 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
}
|
||||
out->write("&");
|
||||
}
|
||||
|
||||
out->write("\n");
|
||||
writeAccessorName(out, member, unsafe);
|
||||
if (memberOwner(member)->type == Object::Pod) {
|
||||
out->write("(");
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("(Thread* t UNUSED, object");
|
||||
}
|
||||
out->write("(Thread* t UNUSED, object");
|
||||
out->write(" o");
|
||||
if (member->type != Object::Scalar) {
|
||||
out->write(", unsigned i");
|
||||
@ -1537,41 +1490,22 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write(typeName);
|
||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
||||
out->write("*");
|
||||
} else {
|
||||
out->write("&");
|
||||
}
|
||||
out->write("&");
|
||||
}
|
||||
|
||||
out->write(">(reinterpret_cast<uint8_t*>(o)");
|
||||
if (endsWith("[0]", typeName)
|
||||
or (member->type != Object::Scalar
|
||||
and memberTypeObject(member)))
|
||||
{
|
||||
out->write(" + ");
|
||||
} else {
|
||||
out->write("[");
|
||||
}
|
||||
out->write("[");
|
||||
|
||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||
out->write(capitalize(memberName(member)));
|
||||
|
||||
if (member->type != Object::Scalar) {
|
||||
out->write(" + (i * ");
|
||||
unsigned elementSize = (memberTypeObject(member) ?
|
||||
typeSize(memberTypeObject(member)) :
|
||||
sizeOf(memberTypeName(member), 0));
|
||||
unsigned elementSize = sizeOf(memberTypeName(member));
|
||||
out->write(elementSize);
|
||||
out->write(")");
|
||||
}
|
||||
if (not endsWith("[0]", typeName)
|
||||
and (member->type == Object::Scalar
|
||||
or memberTypeObject(member) == 0))
|
||||
{
|
||||
out->write("]");
|
||||
}
|
||||
out->write(");\n}\n\n");
|
||||
out->write("]);\n}\n\n");
|
||||
}
|
||||
|
||||
Object*
|
||||
@ -1615,39 +1549,13 @@ typeOffset(Object* type)
|
||||
return typeOffset(0, type);
|
||||
}
|
||||
|
||||
void
|
||||
writePods(Output* out, Object* declarations)
|
||||
{
|
||||
for (Object* p = declarations; p; p = cdr(p)) {
|
||||
Object* o = car(p);
|
||||
switch (o->type) {
|
||||
case Object::Pod: {
|
||||
out->write("const unsigned ");
|
||||
out->write(capitalize(typeName(o)));
|
||||
out->write("Size = ");
|
||||
out->write(typeSize(o));
|
||||
out->write(";\n\n");
|
||||
|
||||
out->write("struct ");
|
||||
out->write(capitalize(typeName(o)));
|
||||
out->write(" { uint8_t body[");
|
||||
out->write(capitalize(typeName(o)));
|
||||
out->write("Size]; };\n\n");
|
||||
} break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeAccessors(Output* out, Object* declarations)
|
||||
{
|
||||
for (Object* p = declarations; p; p = cdr(p)) {
|
||||
Object* o = car(p);
|
||||
switch (o->type) {
|
||||
case Object::Type:
|
||||
case Object::Pod: {
|
||||
case Object::Type: {
|
||||
Object* offset = typeOffset
|
||||
(o, o->type == Object::Type ? typeSuper(o) : 0);
|
||||
for (MemberIterator it(o, true); it.hasMore();) {
|
||||
@ -2031,15 +1939,6 @@ typeObjectMask(Object* type)
|
||||
case Object::Array: {
|
||||
if (memberGC(m)) {
|
||||
set(&mask, offset);
|
||||
} else if (memberTypeObject(m)
|
||||
and memberTypeObject(m)->type == Object::Pod)
|
||||
{
|
||||
for (MemberIterator it(memberTypeObject(m)); it.hasMore();) {
|
||||
Object* m = it.next();
|
||||
if (memberGC(m)) {
|
||||
set(&mask, offset + (it.offset() / BytesPerWord));
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -2207,13 +2106,76 @@ writeNameInitializations(Output* out, Object* declarations)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
writeMap(Output* out, Object* type)
|
||||
{
|
||||
for (MemberIterator it(type); it.hasMore();) {
|
||||
Object* m = it.next();
|
||||
|
||||
switch (m->type) {
|
||||
case Object::Scalar: {
|
||||
out->write("Type_");
|
||||
out->write(memberTypeEnumName(m));
|
||||
if (memberNoGC(m)) {
|
||||
out->write("_nogc");
|
||||
}
|
||||
} break;
|
||||
|
||||
case Object::Array: {
|
||||
out->write("Type_array, ");
|
||||
out->write("Type_");
|
||||
out->write(memberTypeEnumName(m));
|
||||
} break;
|
||||
|
||||
default: UNREACHABLE;
|
||||
}
|
||||
|
||||
out->write(", ");
|
||||
}
|
||||
|
||||
out->write("Type_none");
|
||||
}
|
||||
|
||||
void
|
||||
writeMaps(Output* out, Object* declarations)
|
||||
{
|
||||
unsigned count = 0;
|
||||
for (Object* p = declarations; p; p = cdr(p)) {
|
||||
if (car(p)->type == Object::Type) {
|
||||
++ count;
|
||||
}
|
||||
}
|
||||
|
||||
out->write("Type types[][");
|
||||
out->write(count);
|
||||
out->write("] = {\n");
|
||||
bool wrote = false;
|
||||
for (Object* p = declarations; p; p = cdr(p)) {
|
||||
Object* o = car(p);
|
||||
if (o->type == Object::Type) {
|
||||
if (wrote) {
|
||||
out->write(",\n");
|
||||
} else {
|
||||
wrote = true;
|
||||
}
|
||||
|
||||
out->write("// ");
|
||||
out->write(typeName(o));
|
||||
out->write("\n{ ");
|
||||
writeMap(out, o);
|
||||
out->write(" }");
|
||||
}
|
||||
}
|
||||
out->write("\n};");
|
||||
}
|
||||
|
||||
void
|
||||
usageAndExit(const char* command)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s <classpath> <input file> <output file> "
|
||||
"{enums,declarations,constructors,initializations,"
|
||||
"java-initializations,name-initializations}\n",
|
||||
"java-initializations,name-initializations,maps}\n",
|
||||
command);
|
||||
exit(-1);
|
||||
}
|
||||
@ -2243,7 +2205,8 @@ main(int ac, char** av)
|
||||
or local::equal(av[4], "constructors")
|
||||
or local::equal(av[4], "initializations")
|
||||
or local::equal(av[4], "java-initializations")
|
||||
or local::equal(av[4], "name-initializations")))
|
||||
or local::equal(av[4], "name-initializations")
|
||||
or local::equal(av[4], "maps")))
|
||||
{
|
||||
local::usageAndExit(av[0]);
|
||||
}
|
||||
@ -2301,7 +2264,6 @@ main(int ac, char** av)
|
||||
out.Output::write(local::typeCount(declarations));
|
||||
out.write(";\n\n");
|
||||
|
||||
local::writePods(&out, declarations);
|
||||
local::writeAccessors(&out, declarations);
|
||||
local::writeSizes(&out, declarations);
|
||||
local::writeInitializerDeclarations(&out, declarations);
|
||||
@ -2315,6 +2277,8 @@ main(int ac, char** av)
|
||||
local::writeJavaInitializations(&out, declarations);
|
||||
} else if (local::equal(av[4], "name-initializations")) {
|
||||
local::writeNameInitializations(&out, declarations);
|
||||
} else if (local::equal(av[4], "maps")) {
|
||||
local::writeMaps(&out, declarations);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -64,23 +64,13 @@
|
||||
|
||||
(type region
|
||||
(void* region)
|
||||
(unsigned position))
|
||||
|
||||
(pod exceptionHandler
|
||||
(uint16_t start)
|
||||
(uint16_t end)
|
||||
(uint16_t ip)
|
||||
(uint16_t catchType))
|
||||
(uint32_t position))
|
||||
|
||||
(type exceptionHandlerTable
|
||||
(array exceptionHandler body))
|
||||
|
||||
(pod lineNumber
|
||||
(uint32_t ip)
|
||||
(uint32_t line))
|
||||
(array uint64_t body))
|
||||
|
||||
(type lineNumberTable
|
||||
(array lineNumber body))
|
||||
(array uint64_t body))
|
||||
|
||||
(type code
|
||||
(object pool)
|
||||
@ -126,7 +116,7 @@
|
||||
|
||||
(type traceElement
|
||||
(object method)
|
||||
(int ip))
|
||||
(int32_t ip))
|
||||
|
||||
(type treeNode
|
||||
(object value)
|
||||
@ -155,7 +145,7 @@
|
||||
(void* waitTail)
|
||||
(object acquireHead)
|
||||
(object acquireTail)
|
||||
(unsigned depth))
|
||||
(uint32_t depth))
|
||||
|
||||
(type monitorNode
|
||||
(void* value)
|
||||
|
@ -12,6 +12,7 @@
|
||||
#define VECTOR_H
|
||||
|
||||
#include "system.h"
|
||||
#include "target.h"
|
||||
|
||||
namespace vm {
|
||||
|
||||
@ -103,6 +104,10 @@ class Vector {
|
||||
append(&v, 4);
|
||||
}
|
||||
|
||||
void appendTargetAddress(target_uintptr_t v) {
|
||||
append(&v, TargetBytesPerWord);
|
||||
}
|
||||
|
||||
void appendAddress(uintptr_t v) {
|
||||
append(&v, BytesPerWord);
|
||||
}
|
||||
|
301
src/x86.cpp
301
src/x86.cpp
@ -9,6 +9,7 @@
|
||||
details. */
|
||||
|
||||
#include "assembler.h"
|
||||
#include "target.h"
|
||||
#include "vector.h"
|
||||
|
||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||
@ -60,26 +61,26 @@ enum {
|
||||
};
|
||||
|
||||
const unsigned GeneralRegisterMask
|
||||
= BytesPerWord == 4 ? 0x000000ff : 0x0000ffff;
|
||||
= TargetBytesPerWord == 4 ? 0x000000ff : 0x0000ffff;
|
||||
|
||||
const unsigned FloatRegisterMask
|
||||
= BytesPerWord == 4 ? 0x00ff0000 : 0xffff0000;
|
||||
= TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000;
|
||||
|
||||
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
|
||||
|
||||
const int LongJumpRegister = r10;
|
||||
|
||||
const unsigned StackAlignmentInBytes = 16;
|
||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
|
||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord;
|
||||
|
||||
bool
|
||||
isInt8(intptr_t v)
|
||||
isInt8(target_intptr_t v)
|
||||
{
|
||||
return v == static_cast<int8_t>(v);
|
||||
}
|
||||
|
||||
bool
|
||||
isInt32(intptr_t v)
|
||||
isInt32(target_intptr_t v)
|
||||
{
|
||||
return v == static_cast<int32_t>(v);
|
||||
}
|
||||
@ -478,7 +479,7 @@ detectFeature(unsigned ecx, unsigned edx);
|
||||
bool
|
||||
useSSE(ArchitectureContext* c)
|
||||
{
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
// amd64 implies SSE2 support
|
||||
return true;
|
||||
} else if (c->useNativeFeatures) {
|
||||
@ -502,7 +503,7 @@ useSSE(ArchitectureContext* c)
|
||||
void maybeRex(Context* c, unsigned size, int a, int index, int base,
|
||||
bool always)
|
||||
{
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
uint8_t byte;
|
||||
if (size == 8) {
|
||||
byte = REX_W;
|
||||
@ -656,7 +657,7 @@ storeLoadBarrier(Context* c)
|
||||
} else {
|
||||
// lock addq $0x0,(%rsp):
|
||||
c->code.append(0xf0);
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
c->code.append(0x48);
|
||||
}
|
||||
c->code.append(0x83);
|
||||
@ -746,7 +747,7 @@ callR(Context*, unsigned, Assembler::Register*);
|
||||
void
|
||||
callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
unconditional(c, 0xe8, a);
|
||||
}
|
||||
@ -754,9 +755,9 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||
void
|
||||
longCallC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
Assembler::Register r(LongJumpRegister);
|
||||
moveCR2(c, size, a, size, &r, 11);
|
||||
callR(c, size, &r);
|
||||
@ -768,7 +769,7 @@ longCallC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
void
|
||||
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0xff, 0xe0 + regCode(a));
|
||||
@ -777,7 +778,7 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||
void
|
||||
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
unconditional(c, 0xe9, a);
|
||||
}
|
||||
@ -785,7 +786,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||
void
|
||||
jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0xff);
|
||||
@ -795,9 +796,9 @@ jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
||||
void
|
||||
longJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
Assembler::Register r(LongJumpRegister);
|
||||
moveCR2(c, size, a, size, &r, 11);
|
||||
jumpR(c, size, &r);
|
||||
@ -809,7 +810,7 @@ longJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
void
|
||||
callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
// maybeRex.W has no meaning here so we disable it
|
||||
maybeRex(c, 4, a);
|
||||
@ -819,7 +820,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||
void
|
||||
callM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0xff);
|
||||
@ -836,9 +837,9 @@ alignedCallC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
void
|
||||
alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
new (c->zone->allocate(sizeof(AlignmentPadding)))
|
||||
AlignmentPadding(c, 2, 8);
|
||||
longCallC(c, size, a);
|
||||
@ -857,9 +858,9 @@ alignedJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
void
|
||||
alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
{
|
||||
assert(c, size == BytesPerWord);
|
||||
assert(c, size == TargetBytesPerWord);
|
||||
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
new (c->zone->allocate(sizeof(AlignmentPadding)))
|
||||
AlignmentPadding(c, 2, 8);
|
||||
longJumpC(c, size, a);
|
||||
@ -871,7 +872,7 @@ alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
||||
void
|
||||
pushR(Context* c, unsigned size, Assembler::Register* a)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
if (TargetBytesPerWord == 4 and size == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
|
||||
pushR(c, 4, &ah);
|
||||
@ -889,7 +890,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
void
|
||||
popR(Context* c, unsigned size, Assembler::Register* a)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
if (TargetBytesPerWord == 4 and size == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
|
||||
popR(c, 4, a);
|
||||
@ -897,7 +898,7 @@ popR(Context* c, unsigned size, Assembler::Register* a)
|
||||
} else {
|
||||
maybeRex(c, 4, a);
|
||||
opcode(c, 0x58 + regCode(a));
|
||||
if (BytesPerWord == 8 and size == 4) {
|
||||
if (TargetBytesPerWord == 8 and size == 4) {
|
||||
moveRR(c, 4, a, 8, a);
|
||||
}
|
||||
}
|
||||
@ -910,7 +911,7 @@ addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
|
||||
void
|
||||
negateR(Context* c, unsigned size, Assembler::Register* a)
|
||||
{
|
||||
if (BytesPerWord == 4 and size == 8) {
|
||||
if (TargetBytesPerWord == 4 and size == 8) {
|
||||
assert(c, a->low == rax and a->high == rdx);
|
||||
|
||||
ResolvedPromise zeroPromise(0);
|
||||
@ -940,7 +941,7 @@ void
|
||||
moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
||||
UNUSED unsigned bSize, Assembler::Register* b, unsigned promiseOffset)
|
||||
{
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
int64_t v = a->value->value();
|
||||
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
@ -954,14 +955,14 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
||||
moveCR(c, 4, &al, 4, b);
|
||||
moveCR(c, 4, &ah, 4, &bh);
|
||||
} else {
|
||||
maybeRex(c, BytesPerWord, b);
|
||||
maybeRex(c, TargetBytesPerWord, b);
|
||||
opcode(c, 0xb8 + regCode(b));
|
||||
if (a->value->resolved()) {
|
||||
c->code.appendAddress(a->value->value());
|
||||
c->code.appendTargetAddress(a->value->value());
|
||||
} else {
|
||||
appendImmediateTask
|
||||
(c, a->value, offset(c), BytesPerWord, promiseOffset);
|
||||
c->code.appendAddress(static_cast<uintptr_t>(0));
|
||||
(c, a->value, offset(c), TargetBytesPerWord, promiseOffset);
|
||||
c->code.appendTargetAddress(static_cast<target_uintptr_t>(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1008,7 +1009,7 @@ void
|
||||
sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize <= BytesPerWord);
|
||||
assert(c, aSize <= TargetBytesPerWord);
|
||||
Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask));
|
||||
moveCR2(c, aSize, a, aSize, &tmp, 0);
|
||||
sseMoveRR(c, aSize, &tmp, bSize, b);
|
||||
@ -1031,7 +1032,7 @@ swapRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, aSize == BytesPerWord);
|
||||
assert(c, aSize == TargetBytesPerWord);
|
||||
|
||||
alwaysRex(c, aSize, a, b);
|
||||
opcode(c, 0x87);
|
||||
@ -1047,7 +1048,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
return;
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8 and bSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1065,11 +1066,11 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
} else {
|
||||
switch (aSize) {
|
||||
case 1:
|
||||
if (BytesPerWord == 4 and a->low > rbx) {
|
||||
if (TargetBytesPerWord == 4 and a->low > rbx) {
|
||||
assert(c, b->low <= rbx);
|
||||
|
||||
moveRR(c, BytesPerWord, a, BytesPerWord, b);
|
||||
moveRR(c, 1, b, BytesPerWord, b);
|
||||
moveRR(c, TargetBytesPerWord, a, TargetBytesPerWord, b);
|
||||
moveRR(c, 1, b, TargetBytesPerWord, b);
|
||||
} else {
|
||||
alwaysRex(c, aSize, b, a);
|
||||
opcode(c, 0x0f, 0xbe);
|
||||
@ -1085,7 +1086,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
|
||||
case 4:
|
||||
if (bSize == 8) {
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
alwaysRex(c, bSize, b, a);
|
||||
opcode(c, 0x63);
|
||||
modrm(c, 0xc0, a, b);
|
||||
@ -1125,7 +1126,7 @@ sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
||||
{
|
||||
assert(c, aSize >= 4);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
opcode(c, 0xf3);
|
||||
opcode(c, 0x0f, 0x7e);
|
||||
modrmSibImm(c, b, a);
|
||||
@ -1160,7 +1161,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
maybeRex(c, bSize, b, a);
|
||||
opcode(c, 0x63);
|
||||
modrmSibImm(c, b, a);
|
||||
@ -1179,7 +1180,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1203,7 +1204,7 @@ sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
assert(c, aSize >= 4);
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
opcode(c, 0x66);
|
||||
opcode(c, 0x0f, 0xd6);
|
||||
modrmSibImm(c, a, b);
|
||||
@ -1241,7 +1242,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
maybeRex(c, bSize, a, b);
|
||||
opcode(c, 0x89);
|
||||
modrmSibImm(c, a, b);
|
||||
@ -1253,7 +1254,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
maybeRex(c, bSize, a, b);
|
||||
opcode(c, 0x89);
|
||||
modrmSibImm(c, a, b);
|
||||
@ -1274,7 +1275,7 @@ void
|
||||
moveAR(Context* c, unsigned aSize, Assembler::Address* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or (aSize == 4 and bSize == 4));
|
||||
assert(c, TargetBytesPerWord == 8 or (aSize == 4 and bSize == 4));
|
||||
|
||||
Assembler::Constant constant(a->address);
|
||||
Assembler::Memory memory(b->low, 0, -1, 0);
|
||||
@ -1323,7 +1324,7 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a,
|
||||
break;
|
||||
|
||||
case 8: {
|
||||
if (BytesPerWord == 8) {
|
||||
if (TargetBytesPerWord == 8) {
|
||||
if (a->value->resolved() and isInt32(a->value->value())) {
|
||||
maybeRex(c, bSize, b);
|
||||
opcode(c, 0xc7);
|
||||
@ -1370,7 +1371,7 @@ void
|
||||
moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
{
|
||||
assert(c, bSize == BytesPerWord);
|
||||
assert(c, bSize == TargetBytesPerWord);
|
||||
assert(c, aSize == 2);
|
||||
|
||||
maybeRex(c, bSize, b, a);
|
||||
@ -1382,7 +1383,7 @@ void
|
||||
addCarryRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
maybeRex(c, size, a, b);
|
||||
opcode(c, 0x11);
|
||||
@ -1395,7 +1396,7 @@ addRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1432,7 +1433,7 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (v) {
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
@ -1468,7 +1469,7 @@ void
|
||||
subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (isInt8(v)) {
|
||||
@ -1491,7 +1492,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (v) {
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
@ -1527,7 +1528,7 @@ void
|
||||
subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b)
|
||||
{
|
||||
assert(c, BytesPerWord == 8 or size == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||
|
||||
maybeRex(c, size, a, b);
|
||||
opcode(c, 0x19);
|
||||
@ -1540,7 +1541,7 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1560,7 +1561,7 @@ andRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1581,7 +1582,7 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
|
||||
int64_t v = a->value->value();
|
||||
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
@ -1618,7 +1619,7 @@ orRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1639,7 +1640,7 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (v) {
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
@ -1675,7 +1676,7 @@ void
|
||||
xorRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
{
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -1696,7 +1697,7 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
|
||||
int64_t v = a->value->value();
|
||||
if (v) {
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
@ -1735,7 +1736,7 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
assert(c, b->high == rdx);
|
||||
assert(c, b->low != rax);
|
||||
assert(c, a->low != rax);
|
||||
@ -1870,7 +1871,7 @@ compareRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, aSize <= BytesPerWord);
|
||||
assert(c, aSize <= TargetBytesPerWord);
|
||||
|
||||
maybeRex(c, aSize, a, b);
|
||||
opcode(c, 0x39);
|
||||
@ -1882,7 +1883,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
if (a->value->resolved() and isInt32(a->value->value())) {
|
||||
int64_t v = a->value->value();
|
||||
@ -1907,9 +1908,9 @@ compareRM(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize UNUSED, Assembler::Memory* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
if (BytesPerWord == 8 and aSize == 4) {
|
||||
if (TargetBytesPerWord == 8 and aSize == 4) {
|
||||
moveRR(c, 4, a, 8, a);
|
||||
}
|
||||
maybeRex(c, bSize, a, b);
|
||||
@ -1922,7 +1923,7 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
unsigned bSize, Assembler::Memory* b)
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
||||
assert(c, TargetBytesPerWord == 8 or aSize == 4);
|
||||
|
||||
if (a->value->resolved()) {
|
||||
int64_t v = a->value->value();
|
||||
@ -2048,7 +2049,7 @@ branchRR(Context* c, TernaryOperation op, unsigned size,
|
||||
if (isFloatBranch(op)) {
|
||||
compareFloatRR(c, size, a, size, b);
|
||||
branchFloat(c, op, target);
|
||||
} else if (size > BytesPerWord) {
|
||||
} else if (size > TargetBytesPerWord) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
|
||||
@ -2066,7 +2067,7 @@ branchCR(Context* c, TernaryOperation op, unsigned size,
|
||||
{
|
||||
assert(c, not isFloatBranch(op));
|
||||
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
int64_t v = a->value->value();
|
||||
|
||||
ResolvedPromise low(v & ~static_cast<uintptr_t>(0));
|
||||
@ -2090,7 +2091,7 @@ branchRM(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
assert(c, not isFloatBranch(op));
|
||||
assert(c, size <= BytesPerWord);
|
||||
assert(c, size <= TargetBytesPerWord);
|
||||
|
||||
compareRM(c, size, a, size, b);
|
||||
branch(c, op, target);
|
||||
@ -2102,7 +2103,7 @@ branchCM(Context* c, TernaryOperation op, unsigned size,
|
||||
Assembler::Constant* target)
|
||||
{
|
||||
assert(c, not isFloatBranch(op));
|
||||
assert(c, size <= BytesPerWord);
|
||||
assert(c, size <= TargetBytesPerWord);
|
||||
|
||||
compareCM(c, size, a, size, b);
|
||||
branch(c, op, target);
|
||||
@ -2114,7 +2115,7 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||
{
|
||||
assert(c, aSize == bSize);
|
||||
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx));
|
||||
Assembler::Register tmp(c->client->acquireTemporary(mask),
|
||||
c->client->acquireTemporary(mask));
|
||||
@ -2182,7 +2183,7 @@ remainderRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||
opcode(c, 0xf7, 0xf8 + regCode(a));
|
||||
|
||||
Assembler::Register dx(rdx);
|
||||
moveRR(c, BytesPerWord, &dx, BytesPerWord, b);
|
||||
moveRR(c, TargetBytesPerWord, &dx, TargetBytesPerWord, b);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2194,7 +2195,7 @@ doShift(Context* c, UNUSED void (*shift)
|
||||
{
|
||||
int64_t v = a->value->value();
|
||||
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
c->client->save(rcx);
|
||||
|
||||
Assembler::Register cx(rcx);
|
||||
@ -2219,7 +2220,7 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a,
|
||||
{
|
||||
assert(c, a->low == rcx);
|
||||
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
// shld
|
||||
opcode(c, 0x0f, 0xa5);
|
||||
modrm(c, 0xc0, b->high, b->low);
|
||||
@ -2255,7 +2256,7 @@ shiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a,
|
||||
unsigned bSize, Assembler::Register* b)
|
||||
{
|
||||
assert(c, a->low == rcx);
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
// shrd
|
||||
opcode(c, 0x0f, 0xad);
|
||||
modrm(c, 0xc0, b->low, b->high);
|
||||
@ -2295,7 +2296,7 @@ unsignedShiftRightRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a,
|
||||
{
|
||||
assert(c, a->low == rcx);
|
||||
|
||||
if (BytesPerWord == 4 and bSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||
// shrd
|
||||
opcode(c, 0x0f, 0xad);
|
||||
modrm(c, 0xc0, b->low, b->high);
|
||||
@ -2556,7 +2557,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
||||
uint8_t* instruction = static_cast<uint8_t*>(*ip);
|
||||
|
||||
// skip stack overflow check, if present:
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
if (*start == 0x39) {
|
||||
start += 11;
|
||||
}
|
||||
@ -2571,7 +2572,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
||||
|
||||
if (UseFramePointer) {
|
||||
// skip preamble
|
||||
start += (BytesPerWord == 4 ? 3 : 4);
|
||||
start += (TargetBytesPerWord == 4 ? 3 : 4);
|
||||
|
||||
if (instruction <= start or *instruction == 0x5d) {
|
||||
*ip = static_cast<void**>(*stack)[1];
|
||||
@ -2596,13 +2597,13 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
||||
|
||||
// check for post-non-tail-call stack adjustment of the form "add
|
||||
// $offset,%rsp":
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
if ((*instruction == 0x83 or *instruction == 0x81)
|
||||
and instruction[1] == 0xec)
|
||||
{
|
||||
offset
|
||||
-= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2))
|
||||
/ BytesPerWord;
|
||||
/ TargetBytesPerWord;
|
||||
}
|
||||
} else if (*instruction == 0x48
|
||||
and (instruction[1] == 0x83 or instruction[1] == 0x81)
|
||||
@ -2610,7 +2611,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
||||
{
|
||||
offset
|
||||
-= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3))
|
||||
/ BytesPerWord;
|
||||
/ TargetBytesPerWord;
|
||||
}
|
||||
|
||||
// todo: check for and handle tail calls
|
||||
@ -2773,7 +2774,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual int returnHigh() {
|
||||
return (BytesPerWord == 4 ? rdx : NoRegister);
|
||||
return (TargetBytesPerWord == 4 ? rdx : NoRegister);
|
||||
}
|
||||
|
||||
virtual int virtualCallTarget() {
|
||||
@ -2807,7 +2808,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned frameFootprint(unsigned footprint) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
#ifdef TARGET_PLATFORM_WINDOWS
|
||||
return max(footprint, StackAlignmentInWords);
|
||||
#else
|
||||
return max(footprint > argumentRegisterCount() ?
|
||||
@ -2829,18 +2830,18 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned argumentRegisterCount() {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
if (BytesPerWord == 8) return 4; else
|
||||
#ifdef TARGET_PLATFORM_WINDOWS
|
||||
if (TargetBytesPerWord == 8) return 4; else
|
||||
#else
|
||||
if (BytesPerWord == 8) return 6; else
|
||||
if (TargetBytesPerWord == 8) return 6; else
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int argumentRegister(unsigned index) {
|
||||
assert(&c, BytesPerWord == 8);
|
||||
assert(&c, TargetBytesPerWord == 8);
|
||||
switch (index) {
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
#ifdef TARGET_PLATFORM_WINDOWS
|
||||
case 0:
|
||||
return rcx;
|
||||
case 1:
|
||||
@ -2913,7 +2914,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
assertAlignment = false;
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4 or op == Call or op == Jump) {
|
||||
if (TargetBytesPerWord == 4 or op == Call or op == Jump) {
|
||||
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||
|
||||
assert(&c, ((op == Call or op == LongCall) and *instruction == 0xE8)
|
||||
@ -2945,8 +2946,9 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void setConstant(void* dst, uintptr_t constant) {
|
||||
memcpy(dst, &constant, BytesPerWord);
|
||||
virtual void setConstant(void* dst, uint64_t constant) {
|
||||
target_uintptr_t v = TARGET_VW(constant);
|
||||
memcpy(dst, &v, TargetBytesPerWord);
|
||||
}
|
||||
|
||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||
@ -3040,7 +3042,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Absolute:
|
||||
if (aSize <= BytesPerWord) {
|
||||
if (aSize <= TargetBytesPerWord) {
|
||||
*aTypeMask = (1 << RegisterOperand);
|
||||
*aRegisterMask = (static_cast<uint64_t>(1) << rax);
|
||||
} else {
|
||||
@ -3089,7 +3091,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Float2Int:
|
||||
if (useSSE(&c) and bSize <= BytesPerWord) {
|
||||
if (useSSE(&c) and bSize <= TargetBytesPerWord) {
|
||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
|
||||
| FloatRegisterMask;
|
||||
@ -3099,7 +3101,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Int2Float:
|
||||
if (useSSE(&c) and aSize <= BytesPerWord) {
|
||||
if (useSSE(&c) and aSize <= TargetBytesPerWord) {
|
||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||
*aRegisterMask = GeneralRegisterMask
|
||||
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
||||
@ -3112,7 +3114,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
*aTypeMask = ~0;
|
||||
*aRegisterMask = ~static_cast<uint64_t>(0);
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
if (aSize == 4 and bSize == 8) {
|
||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||
const uint32_t mask
|
||||
@ -3188,7 +3190,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
*bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||
}
|
||||
|
||||
if (BytesPerWord == 4) {
|
||||
if (TargetBytesPerWord == 4) {
|
||||
if (aSize == 4 and bSize == 8) {
|
||||
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32))
|
||||
| (static_cast<uint64_t>(1) << rax);
|
||||
@ -3223,7 +3225,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
*tmpRegisterMask = GeneralRegisterMask
|
||||
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
||||
} else if (dstTypeMask & (1 << RegisterOperand)) {
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
// can't move directly from FPR to GPR or vice-versa for
|
||||
// values larger than the GPR size
|
||||
if (dstRegisterMask & FloatRegisterMask) {
|
||||
@ -3239,7 +3241,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
if (dstRegisterMask & FloatRegisterMask) {
|
||||
// can't move directly from constant to FPR
|
||||
*srcTypeMask &= ~(1 << ConstantOperand);
|
||||
if (size > BytesPerWord) {
|
||||
if (size > TargetBytesPerWord) {
|
||||
*tmpTypeMask = 1 << MemoryOperand;
|
||||
} else {
|
||||
*tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||
@ -3290,7 +3292,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Multiply:
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx));
|
||||
*aRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;
|
||||
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32)) | mask;
|
||||
@ -3301,7 +3303,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Divide:
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
*thunk = true;
|
||||
} else {
|
||||
*aTypeMask = (1 << RegisterOperand);
|
||||
@ -3311,7 +3313,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Remainder:
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||
*thunk = true;
|
||||
} else {
|
||||
*aTypeMask = (1 << RegisterOperand);
|
||||
@ -3404,15 +3406,15 @@ class MyAssembler: public Assembler {
|
||||
Register stack(rsp);
|
||||
Memory stackLimit(rbx, stackLimitOffsetFromThread);
|
||||
Constant handlerConstant(resolved(&c, handler));
|
||||
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
|
||||
branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit,
|
||||
&handlerConstant);
|
||||
}
|
||||
|
||||
virtual void saveFrame(unsigned stackOffset, unsigned) {
|
||||
Register stack(rsp);
|
||||
Memory stackDst(rbx, stackOffset);
|
||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, MemoryOperand, &stackDst);
|
||||
apply(Move, TargetBytesPerWord, RegisterOperand, &stack,
|
||||
TargetBytesPerWord, MemoryOperand, &stackDst);
|
||||
}
|
||||
|
||||
virtual void pushFrame(unsigned argumentCount, ...) {
|
||||
@ -3430,7 +3432,7 @@ class MyAssembler: public Assembler {
|
||||
= static_cast<OperandType>(va_arg(a, int));
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*);
|
||||
footprint += ceiling
|
||||
(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord);
|
||||
(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||
}
|
||||
va_end(a);
|
||||
|
||||
@ -3444,19 +3446,20 @@ class MyAssembler: public Assembler {
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord),
|
||||
RegisterOperand,
|
||||
&dst);
|
||||
} else {
|
||||
Memory dst(rsp, offset * BytesPerWord);
|
||||
Memory dst(rsp, offset * TargetBytesPerWord);
|
||||
apply(Move,
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||
RUNTIME_ARRAY_BODY(arguments)[i].operand,
|
||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord),
|
||||
MemoryOperand,
|
||||
&dst);
|
||||
offset += ceiling(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord);
|
||||
offset += ceiling
|
||||
(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3466,40 +3469,40 @@ class MyAssembler: public Assembler {
|
||||
|
||||
if (UseFramePointer) {
|
||||
Register base(rbp);
|
||||
pushR(&c, BytesPerWord, &base);
|
||||
pushR(&c, TargetBytesPerWord, &base);
|
||||
|
||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &base);
|
||||
apply(Move, TargetBytesPerWord, RegisterOperand, &stack,
|
||||
TargetBytesPerWord, RegisterOperand, &base);
|
||||
}
|
||||
|
||||
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
|
||||
apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord));
|
||||
apply(Subtract, TargetBytesPerWord, ConstantOperand, &footprintConstant,
|
||||
TargetBytesPerWord, RegisterOperand, &stack,
|
||||
TargetBytesPerWord, RegisterOperand, &stack);
|
||||
}
|
||||
|
||||
virtual void adjustFrame(unsigned difference) {
|
||||
Register stack(rsp);
|
||||
Constant differenceConstant(resolved(&c, difference * BytesPerWord));
|
||||
apply(Subtract, BytesPerWord, ConstantOperand, &differenceConstant,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord));
|
||||
apply(Subtract, TargetBytesPerWord, ConstantOperand, &differenceConstant,
|
||||
TargetBytesPerWord, RegisterOperand, &stack,
|
||||
TargetBytesPerWord, RegisterOperand, &stack);
|
||||
}
|
||||
|
||||
virtual void popFrame(unsigned frameFootprint) {
|
||||
if (UseFramePointer) {
|
||||
Register base(rbp);
|
||||
Register stack(rsp);
|
||||
apply(Move, BytesPerWord, RegisterOperand, &base,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
apply(Move, TargetBytesPerWord, RegisterOperand, &base,
|
||||
TargetBytesPerWord, RegisterOperand, &stack);
|
||||
|
||||
popR(&c, BytesPerWord, &base);
|
||||
popR(&c, TargetBytesPerWord, &base);
|
||||
} else {
|
||||
Register stack(rsp);
|
||||
Constant footprint(resolved(&c, frameFootprint * BytesPerWord));
|
||||
apply(Add, BytesPerWord, ConstantOperand, &footprint,
|
||||
BytesPerWord, RegisterOperand, &stack,
|
||||
BytesPerWord, RegisterOperand, &stack);
|
||||
Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord));
|
||||
apply(Add, TargetBytesPerWord, ConstantOperand, &footprint,
|
||||
TargetBytesPerWord, RegisterOperand, &stack,
|
||||
TargetBytesPerWord, RegisterOperand, &stack);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3515,40 +3518,44 @@ class MyAssembler: public Assembler {
|
||||
unsigned baseSize = UseFramePointer ? 1 : 0;
|
||||
|
||||
Memory returnAddressSrc
|
||||
(rsp, (frameFootprint + baseSize) * BytesPerWord);
|
||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
||||
(rsp, (frameFootprint + baseSize) * TargetBytesPerWord);
|
||||
moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord,
|
||||
&tmp);
|
||||
|
||||
Memory returnAddressDst
|
||||
(rsp, (frameFootprint - offset + baseSize) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &tmp, BytesPerWord, &returnAddressDst);
|
||||
(rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord);
|
||||
moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord,
|
||||
&returnAddressDst);
|
||||
|
||||
c.client->releaseTemporary(tmp.low);
|
||||
|
||||
if (UseFramePointer) {
|
||||
Memory baseSrc(rsp, frameFootprint * BytesPerWord);
|
||||
Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord);
|
||||
Register base(rbp);
|
||||
moveMR(&c, BytesPerWord, &baseSrc, BytesPerWord, &base);
|
||||
moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base);
|
||||
}
|
||||
|
||||
Register stack(rsp);
|
||||
Constant footprint
|
||||
(resolved(&c, (frameFootprint - offset + baseSize) * BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &footprint, BytesPerWord, &stack);
|
||||
(resolved
|
||||
(&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord));
|
||||
|
||||
addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack);
|
||||
|
||||
if (returnAddressSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
Register ras(returnAddressSurrogate);
|
||||
Memory dst(rsp, offset * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst);
|
||||
Memory dst(rsp, offset * TargetBytesPerWord);
|
||||
moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst);
|
||||
}
|
||||
|
||||
if (framePointerSurrogate != NoRegister) {
|
||||
assert(&c, offset > 0);
|
||||
|
||||
Register fps(framePointerSurrogate);
|
||||
Memory dst(rsp, (offset - 1) * BytesPerWord);
|
||||
moveRM(&c, BytesPerWord, &fps, BytesPerWord, &dst);
|
||||
Memory dst(rsp, (offset - 1) * TargetBytesPerWord);
|
||||
moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst);
|
||||
}
|
||||
} else {
|
||||
popFrame(frameFootprint);
|
||||
@ -3568,15 +3575,15 @@ class MyAssembler: public Assembler {
|
||||
|
||||
if (TailCalls and argumentFootprint > StackAlignmentInWords) {
|
||||
Register returnAddress(rcx);
|
||||
popR(&c, BytesPerWord, &returnAddress);
|
||||
popR(&c, TargetBytesPerWord, &returnAddress);
|
||||
|
||||
Register stack(rsp);
|
||||
Constant adjustment
|
||||
(resolved(&c, (argumentFootprint - StackAlignmentInWords)
|
||||
* BytesPerWord));
|
||||
addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack);
|
||||
* TargetBytesPerWord));
|
||||
addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack);
|
||||
|
||||
jumpR(&c, BytesPerWord, &returnAddress);
|
||||
jumpR(&c, TargetBytesPerWord, &returnAddress);
|
||||
} else {
|
||||
return_(&c);
|
||||
}
|
||||
@ -3588,13 +3595,13 @@ class MyAssembler: public Assembler {
|
||||
popFrame(frameFootprint);
|
||||
|
||||
Register returnAddress(rcx);
|
||||
popR(&c, BytesPerWord, &returnAddress);
|
||||
popR(&c, TargetBytesPerWord, &returnAddress);
|
||||
|
||||
Register stack(rsp);
|
||||
Memory stackSrc(rbx, stackOffsetFromThread);
|
||||
moveMR(&c, BytesPerWord, &stackSrc, BytesPerWord, &stack);
|
||||
moveMR(&c, TargetBytesPerWord, &stackSrc, TargetBytesPerWord, &stack);
|
||||
|
||||
jumpR(&c, BytesPerWord, &returnAddress);
|
||||
jumpR(&c, TargetBytesPerWord, &returnAddress);
|
||||
}
|
||||
|
||||
virtual void apply(Operation op) {
|
||||
@ -3624,7 +3631,7 @@ class MyAssembler: public Assembler {
|
||||
{
|
||||
if (isBranch(op)) {
|
||||
assert(&c, aSize == bSize);
|
||||
assert(&c, cSize == BytesPerWord);
|
||||
assert(&c, cSize == TargetBytesPerWord);
|
||||
assert(&c, cType == ConstantOperand);
|
||||
|
||||
arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]
|
||||
|
Loading…
Reference in New Issue
Block a user