mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
progress towards cross-architecture bootimage builds
This monster commit is the first step towards supporting cross-architecture bootimage builds. The challenge is to build a heap and code image for the target platform where the word size and endianess may differ from those of the build architecture. That means the memory layout of objects may differ due to alignment and size differences, so we can't just copy objects into the heap image unchanged; we must copy field by field, resizing values, reversing endianess and shifting offsets as necessary. This commit also removes POD (plain old data) type support from the type generator because it added a lot of complication and little value.
This commit is contained in:
parent
b4661d2ccd
commit
5b4f17997f
34
makefile
34
makefile
@ -169,7 +169,8 @@ common-cflags = $(warnings) -fno-rtti -fno-exceptions \
|
|||||||
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
"-I$(JAVA_HOME)/include" -idirafter $(src) -I$(build) $(classpath-cflags) \
|
||||||
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
-D__STDC_LIMIT_MACROS -D_JNI_IMPLEMENTATION_ -DAVIAN_VERSION=\"$(version)\" \
|
||||||
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
-DUSE_ATOMIC_OPERATIONS -DAVIAN_JAVA_HOME=\"$(javahome)\" \
|
||||||
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\"
|
-DAVIAN_EMBED_PREFIX=\"$(embed-prefix)\" \
|
||||||
|
-DTARGET_BYTES_PER_WORD=$(pointer-size)
|
||||||
|
|
||||||
ifneq (,$(filter i386 x86_64,$(arch)))
|
ifneq (,$(filter i386 x86_64,$(arch)))
|
||||||
ifeq ($(use-frame-pointer),true)
|
ifeq ($(use-frame-pointer),true)
|
||||||
@ -208,6 +209,12 @@ shared = -shared
|
|||||||
|
|
||||||
openjdk-extra-cflags = -fvisibility=hidden
|
openjdk-extra-cflags = -fvisibility=hidden
|
||||||
|
|
||||||
|
ifeq ($(build-arch),powerpc)
|
||||||
|
ifneq ($(arch),$(build-arch))
|
||||||
|
cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(arch),i386)
|
ifeq ($(arch),i386)
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
endif
|
endif
|
||||||
@ -215,6 +222,10 @@ ifeq ($(arch),powerpc)
|
|||||||
asm = powerpc
|
asm = powerpc
|
||||||
pointer-size = 4
|
pointer-size = 4
|
||||||
|
|
||||||
|
ifneq ($(arch),$(build-arch))
|
||||||
|
cflags += -DTARGET_OPPOSITE_ENDIAN
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(platform),darwin)
|
ifneq ($(platform),darwin)
|
||||||
ifneq ($(arch),$(build-arch))
|
ifneq ($(arch),$(build-arch))
|
||||||
converter-cflags += -DOPPOSITE_ENDIAN
|
converter-cflags += -DOPPOSITE_ENDIAN
|
||||||
@ -251,7 +262,13 @@ ifeq ($(arch),arm)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(platform),linux)
|
||||||
|
cflags += -DTARGET_PLATFORM_LINUX
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),darwin)
|
ifeq ($(platform),darwin)
|
||||||
|
cflags += -DTARGET_PLATFORM_DARWIN
|
||||||
|
|
||||||
ifeq (${OSX_SDK_SYSROOT},)
|
ifeq (${OSX_SDK_SYSROOT},)
|
||||||
OSX_SDK_SYSROOT = 10.4u
|
OSX_SDK_SYSROOT = 10.4u
|
||||||
endif
|
endif
|
||||||
@ -330,6 +347,8 @@ ifeq ($(platform),darwin)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(platform),windows)
|
ifeq ($(platform),windows)
|
||||||
|
cflags += -DTARGET_PLATFORM_WINDOWS
|
||||||
|
|
||||||
inc = "$(root)/win32/include"
|
inc = "$(root)/win32/include"
|
||||||
lib = "$(root)/win32/lib"
|
lib = "$(root)/win32/lib"
|
||||||
|
|
||||||
@ -479,7 +498,8 @@ generated-code = \
|
|||||||
$(build)/type-constructors.cpp \
|
$(build)/type-constructors.cpp \
|
||||||
$(build)/type-initializations.cpp \
|
$(build)/type-initializations.cpp \
|
||||||
$(build)/type-java-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)
|
vm-depends := $(generated-code) $(wildcard $(src)/*.h)
|
||||||
|
|
||||||
@ -537,16 +557,6 @@ bootimage-bin = $(build)/bootimage.bin
|
|||||||
bootimage-object = $(build)/bootimage-bin.o
|
bootimage-object = $(build)/bootimage-bin.o
|
||||||
|
|
||||||
ifeq ($(bootimage),true)
|
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)
|
vm-classpath-object = $(bootimage-object)
|
||||||
cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\"
|
cflags += -DBOOT_IMAGE=\"bootimageBin\" -DAVIAN_CLASSPATH=\"\"
|
||||||
else
|
else
|
||||||
|
@ -343,7 +343,7 @@ class Assembler {
|
|||||||
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
||||||
void* newTarget) = 0;
|
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;
|
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
216
src/compile.cpp
216
src/compile.cpp
@ -13,6 +13,7 @@
|
|||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
#include "process.h"
|
#include "process.h"
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
|
#include "target.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "arch.h"
|
#include "arch.h"
|
||||||
|
|
||||||
@ -52,7 +53,7 @@ const bool Continuations = true;
|
|||||||
const bool Continuations = false;
|
const bool Continuations = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const unsigned MaxNativeCallFootprint = BytesPerWord == 8 ? 4 : 5;
|
const unsigned MaxNativeCallFootprint = TargetBytesPerWord == 8 ? 4 : 5;
|
||||||
|
|
||||||
const unsigned InitialZoneCapacityInBytes = 64 * 1024;
|
const unsigned InitialZoneCapacityInBytes = 64 * 1024;
|
||||||
|
|
||||||
@ -3164,7 +3165,7 @@ resultSize(MyThread* t, unsigned code)
|
|||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
case ObjectField:
|
case ObjectField:
|
||||||
return BytesPerWord;
|
return TargetBytesPerWord;
|
||||||
|
|
||||||
case LongField:
|
case LongField:
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
@ -3305,8 +3306,8 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
|
|||||||
methodParameterFootprint(t, target));
|
methodParameterFootprint(t, target));
|
||||||
|
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, frame->addressOperand(returnAddressPromise),
|
(TargetBytesPerWord, frame->addressOperand(returnAddressPromise),
|
||||||
BytesPerWord, c->memory
|
TargetBytesPerWord, c->memory
|
||||||
(c->register_(t->arch->thread()), Compiler::AddressType,
|
(c->register_(t->arch->thread()), Compiler::AddressType,
|
||||||
difference(&(t->tailAddress), t)));
|
difference(&(t->tailAddress), t)));
|
||||||
|
|
||||||
@ -3455,7 +3456,7 @@ compileDirectReferenceInvoke(MyThread* t, Frame* frame, Thunk thunk,
|
|||||||
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::AddressType,
|
Compiler::AddressType,
|
||||||
2, c->register_(t->arch->thread()), frame->append(pair)),
|
2, c->register_(t->arch->thread()), frame->append(pair)),
|
||||||
reference, isStatic, tailCall);
|
reference, isStatic, tailCall);
|
||||||
@ -3497,7 +3498,7 @@ compileDirectAbstractInvoke(MyThread* t, Frame* frame, Thunk thunk,
|
|||||||
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::AddressType,
|
Compiler::AddressType,
|
||||||
2, c->register_(t->arch->thread()), frame->append(target)),
|
2, c->register_(t->arch->thread()), frame->append(target)),
|
||||||
target, tailCall);
|
target, tailCall);
|
||||||
@ -3560,7 +3561,7 @@ inTryBlock(MyThread* t, object code, unsigned ip)
|
|||||||
if (table) {
|
if (table) {
|
||||||
unsigned length = exceptionHandlerTableLength(t, table);
|
unsigned length = exceptionHandlerTableLength(t, table);
|
||||||
for (unsigned i = 0; i < length; ++i) {
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, table, i);
|
uint64_t eh = exceptionHandlerTableBody(t, table, i);
|
||||||
if (ip >= exceptionHandlerStart(eh)
|
if (ip >= exceptionHandlerStart(eh)
|
||||||
and ip < exceptionHandlerEnd(eh))
|
and ip < exceptionHandlerEnd(eh))
|
||||||
{
|
{
|
||||||
@ -3867,16 +3868,18 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case aaload:
|
case aaload:
|
||||||
frame->pushObject
|
frame->pushObject
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, BytesPerWord, c->memory
|
(TargetBytesPerWord, TargetBytesPerWord, c->memory
|
||||||
(array, Compiler::ObjectType, ArrayBody, index, BytesPerWord),
|
(array, Compiler::ObjectType, ArrayBody, index,
|
||||||
BytesPerWord));
|
TargetBytesPerWord),
|
||||||
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case faload:
|
case faload:
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 4), BytesPerWord));
|
(array, Compiler::FloatType, ArrayBody, index, 4),
|
||||||
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iaload:
|
case iaload:
|
||||||
@ -3884,7 +3887,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 4),
|
(array, Compiler::IntegerType, ArrayBody, index, 4),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case baload:
|
case baload:
|
||||||
@ -3892,7 +3895,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(1, 1, c->memory
|
(1, 1, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 1),
|
(array, Compiler::IntegerType, ArrayBody, index, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case caload:
|
case caload:
|
||||||
@ -3900,7 +3903,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->loadz
|
(c->loadz
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case daload:
|
case daload:
|
||||||
@ -3922,7 +3925,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
(array, Compiler::IntegerType, ArrayBody, index, 2),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -3968,32 +3971,33 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
c->add
|
c->add
|
||||||
(4, c->constant(ArrayBody, Compiler::IntegerType),
|
(4, c->constant(ArrayBody, Compiler::IntegerType),
|
||||||
c->shl
|
c->shl
|
||||||
(4, c->constant(log(BytesPerWord), Compiler::IntegerType), index)),
|
(4, c->constant(log(TargetBytesPerWord), Compiler::IntegerType),
|
||||||
|
index)),
|
||||||
value);
|
value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case fastore:
|
case fastore:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(array, Compiler::FloatType, ArrayBody, index, 4));
|
(array, Compiler::FloatType, ArrayBody, index, 4));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case iastore:
|
case iastore:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 4));
|
(array, Compiler::IntegerType, ArrayBody, index, 4));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case bastore:
|
case bastore:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 1, c->memory
|
(TargetBytesPerWord, value, 1, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 1));
|
(array, Compiler::IntegerType, ArrayBody, index, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case castore:
|
case castore:
|
||||||
case sastore:
|
case sastore:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 2, c->memory
|
(TargetBytesPerWord, value, 2, c->memory
|
||||||
(array, Compiler::IntegerType, ArrayBody, index, 2));
|
(array, Compiler::IntegerType, ArrayBody, index, 2));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4062,7 +4066,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
3, c->register_(t->arch->thread()), frame->append(argument),
|
3, c->register_(t->arch->thread()), frame->append(argument),
|
||||||
length));
|
length));
|
||||||
@ -4070,16 +4074,16 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
case areturn: {
|
case areturn: {
|
||||||
handleExit(t, frame);
|
handleExit(t, frame);
|
||||||
c->return_(BytesPerWord, frame->popObject());
|
c->return_(TargetBytesPerWord, frame->popObject());
|
||||||
} return;
|
} return;
|
||||||
|
|
||||||
case arraylength: {
|
case arraylength: {
|
||||||
frame->pushInt
|
frame->pushInt
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, BytesPerWord,
|
(TargetBytesPerWord, TargetBytesPerWord,
|
||||||
c->memory
|
c->memory
|
||||||
(frame->popObject(), Compiler::IntegerType, ArrayLength, 0, 1),
|
(frame->popObject(), Compiler::IntegerType, ArrayLength, 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case astore:
|
case astore:
|
||||||
@ -4367,7 +4371,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
if (LIKELY(field)) {
|
if (LIKELY(field)) {
|
||||||
if ((fieldFlags(t, field) & ACC_VOLATILE)
|
if ((fieldFlags(t, field) & ACC_VOLATILE)
|
||||||
and BytesPerWord == 4
|
and TargetBytesPerWord == 4
|
||||||
and (fieldCode(t, field) == DoubleField
|
and (fieldCode(t, field) == DoubleField
|
||||||
or fieldCode(t, field) == LongField))
|
or fieldCode(t, field) == LongField))
|
||||||
{
|
{
|
||||||
@ -4375,7 +4379,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
c->call
|
c->call
|
||||||
(c->constant
|
(c->constant
|
||||||
(getThunk(t, acquireMonitorForObjectThunk), Compiler::AddressType),
|
(getThunk(t, acquireMonitorForObjectThunk),
|
||||||
|
Compiler::AddressType),
|
||||||
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
0, frame->trace(0, 0), 0, Compiler::VoidType, 2,
|
||||||
c->register_(t->arch->thread()),
|
c->register_(t->arch->thread()),
|
||||||
frame->append(field));
|
frame->append(field));
|
||||||
@ -4421,7 +4426,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(1, 1, c->memory
|
(1, 1, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
@ -4429,7 +4434,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->loadz
|
(c->loadz
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ShortField:
|
case ShortField:
|
||||||
@ -4437,7 +4442,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(2, 2, c->memory
|
(2, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
@ -4445,7 +4450,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntField:
|
case IntField:
|
||||||
@ -4453,7 +4458,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->load
|
(c->load
|
||||||
(4, 4, c->memory
|
(4, 4, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DoubleField:
|
case DoubleField:
|
||||||
@ -4473,10 +4478,10 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case ObjectField:
|
case ObjectField:
|
||||||
frame->pushObject
|
frame->pushObject
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, BytesPerWord,
|
(TargetBytesPerWord, TargetBytesPerWord,
|
||||||
c->memory
|
c->memory
|
||||||
(table, Compiler::ObjectType, fieldOffset(t, field), 0, 1),
|
(table, Compiler::ObjectType, fieldOffset(t, field), 0, 1),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -4484,7 +4489,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||||
if (BytesPerWord == 4
|
if (TargetBytesPerWord == 4
|
||||||
and (fieldCode(t, field) == DoubleField
|
and (fieldCode(t, field) == DoubleField
|
||||||
or fieldCode(t, field) == LongField))
|
or fieldCode(t, field) == LongField))
|
||||||
{
|
{
|
||||||
@ -4551,11 +4556,13 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2b: {
|
case i2b: {
|
||||||
frame->pushInt(c->load(BytesPerWord, 1, frame->popInt(), BytesPerWord));
|
frame->pushInt
|
||||||
|
(c->load(TargetBytesPerWord, 1, frame->popInt(), TargetBytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2c: {
|
case i2c: {
|
||||||
frame->pushInt(c->loadz(BytesPerWord, 2, frame->popInt(), BytesPerWord));
|
frame->pushInt
|
||||||
|
(c->loadz(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2d: {
|
case i2d: {
|
||||||
@ -4567,11 +4574,12 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case i2l:
|
case i2l:
|
||||||
frame->pushLong(c->load(BytesPerWord, 4, frame->popInt(), 8));
|
frame->pushLong(c->load(TargetBytesPerWord, 4, frame->popInt(), 8));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case i2s: {
|
case i2s: {
|
||||||
frame->pushInt(c->load(BytesPerWord, 2, frame->popInt(), BytesPerWord));
|
frame->pushInt
|
||||||
|
(c->load(TargetBytesPerWord, 2, frame->popInt(), TargetBytesPerWord));
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case iadd: {
|
case iadd: {
|
||||||
@ -4637,9 +4645,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* target = frame->machineIp(newIp);
|
Compiler::Operand* target = frame->machineIp(newIp);
|
||||||
|
|
||||||
if (instruction == if_acmpeq) {
|
if (instruction == if_acmpeq) {
|
||||||
c->jumpIfEqual(BytesPerWord, a, b, target);
|
c->jumpIfEqual(TargetBytesPerWord, a, b, target);
|
||||||
} else {
|
} else {
|
||||||
c->jumpIfNotEqual(BytesPerWord, a, b, target);
|
c->jumpIfNotEqual(TargetBytesPerWord, a, b, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveStateAndCompile(t, frame, newIp);
|
saveStateAndCompile(t, frame, newIp);
|
||||||
@ -4737,9 +4745,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* target = frame->machineIp(newIp);
|
Compiler::Operand* target = frame->machineIp(newIp);
|
||||||
|
|
||||||
if (instruction == ifnull) {
|
if (instruction == ifnull) {
|
||||||
c->jumpIfEqual(BytesPerWord, a, b, target);
|
c->jumpIfEqual(TargetBytesPerWord, a, b, target);
|
||||||
} else {
|
} else {
|
||||||
c->jumpIfNotEqual(BytesPerWord, a, b, target);
|
c->jumpIfNotEqual(TargetBytesPerWord, a, b, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveStateAndCompile(t, frame, newIp);
|
saveStateAndCompile(t, frame, newIp);
|
||||||
@ -4868,7 +4876,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::AddressType,
|
Compiler::AddressType,
|
||||||
3, c->register_(t->arch->thread()), frame->append(argument),
|
3, c->register_(t->arch->thread()), frame->append(argument),
|
||||||
c->peek(1, parameterFootprint - 1)),
|
c->peek(1, parameterFootprint - 1)),
|
||||||
@ -4976,7 +4984,8 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::Operand* result = c->stackCall
|
Compiler::Operand* result = c->stackCall
|
||||||
(c->memory
|
(c->memory
|
||||||
(c->and_
|
(c->and_
|
||||||
(BytesPerWord, c->constant(PointerMask, Compiler::IntegerType),
|
(TargetBytesPerWord, c->constant
|
||||||
|
(PointerMask, Compiler::IntegerType),
|
||||||
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
c->memory(instance, Compiler::ObjectType, 0, 0, 1)),
|
||||||
Compiler::ObjectType, offset, 0, 1),
|
Compiler::ObjectType, offset, 0, 1),
|
||||||
tailCall ? Compiler::TailJump : 0,
|
tailCall ? Compiler::TailJump : 0,
|
||||||
@ -5008,7 +5017,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::AddressType),
|
Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::AddressType,
|
Compiler::AddressType,
|
||||||
3, c->register_(t->arch->thread()), frame->append(pair),
|
3, c->register_(t->arch->thread()), frame->append(pair),
|
||||||
c->peek(1, methodReferenceParameterFootprint
|
c->peek(1, methodReferenceParameterFootprint
|
||||||
@ -5132,7 +5141,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case l2i:
|
case l2i:
|
||||||
frame->pushInt(c->load(8, 8, frame->popLong(), BytesPerWord));
|
frame->pushInt(c->load(8, 8, frame->popLong(), TargetBytesPerWord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ladd: {
|
case ladd: {
|
||||||
@ -5201,7 +5210,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
Compiler::AddressType),
|
Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
2, c->register_(t->arch->thread()),
|
2, c->register_(t->arch->thread()),
|
||||||
frame->append(makePair(t, context->method, reference))));
|
frame->append(makePair(t, context->method, reference))));
|
||||||
@ -5216,7 +5225,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(getThunk(t, getJClass64Thunk), Compiler::AddressType),
|
(getThunk(t, getJClass64Thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
2, c->register_(t->arch->thread()), frame->append(v)));
|
2, c->register_(t->arch->thread()), frame->append(v)));
|
||||||
} else {
|
} else {
|
||||||
@ -5330,7 +5339,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->call
|
(c->call
|
||||||
(c->constant
|
(c->constant
|
||||||
(getThunk(t, lookUpAddressThunk), Compiler::AddressType),
|
(getThunk(t, lookUpAddressThunk), Compiler::AddressType),
|
||||||
0, 0, BytesPerWord, Compiler::AddressType,
|
0, 0, TargetBytesPerWord, Compiler::AddressType,
|
||||||
4, key, start, c->constant(pairCount, Compiler::IntegerType),
|
4, key, start, c->constant(pairCount, Compiler::IntegerType),
|
||||||
default_));
|
default_));
|
||||||
|
|
||||||
@ -5477,7 +5486,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(getThunk(t, thunk), Compiler::AddressType),
|
(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
4, c->register_(t->arch->thread()), frame->append(argument),
|
4, c->register_(t->arch->thread()), frame->append(argument),
|
||||||
c->constant(dimensions, Compiler::IntegerType),
|
c->constant(dimensions, Compiler::IntegerType),
|
||||||
@ -5516,7 +5525,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
(c->constant(getThunk(t, thunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
2, c->register_(t->arch->thread()), frame->append(argument)));
|
2, c->register_(t->arch->thread()), frame->append(argument)));
|
||||||
} break;
|
} break;
|
||||||
@ -5531,7 +5540,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
(c->constant(getThunk(t, makeBlankArrayThunk), Compiler::AddressType),
|
(c->constant(getThunk(t, makeBlankArrayThunk), Compiler::AddressType),
|
||||||
0,
|
0,
|
||||||
frame->trace(0, 0),
|
frame->trace(0, 0),
|
||||||
BytesPerWord,
|
TargetBytesPerWord,
|
||||||
Compiler::ObjectType,
|
Compiler::ObjectType,
|
||||||
3, c->register_(t->arch->thread()),
|
3, c->register_(t->arch->thread()),
|
||||||
c->constant(type, Compiler::IntegerType), length));
|
c->constant(type, Compiler::IntegerType), length));
|
||||||
@ -5593,7 +5602,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||||
if (BytesPerWord == 4
|
if (TargetBytesPerWord == 4
|
||||||
and (fieldCode == DoubleField or fieldCode == LongField))
|
and (fieldCode == DoubleField or fieldCode == LongField))
|
||||||
{
|
{
|
||||||
PROTECT(t, field);
|
PROTECT(t, field);
|
||||||
@ -5625,26 +5634,26 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
case ByteField:
|
case ByteField:
|
||||||
case BooleanField:
|
case BooleanField:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 1, c->memory
|
(TargetBytesPerWord, value, 1, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CharField:
|
case CharField:
|
||||||
case ShortField:
|
case ShortField:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 2, c->memory
|
(TargetBytesPerWord, value, 2, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FloatField:
|
case FloatField:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::FloatType, fieldOffset(t, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IntField:
|
case IntField:
|
||||||
c->store
|
c->store
|
||||||
(BytesPerWord, value, 4, c->memory
|
(TargetBytesPerWord, value, 4, c->memory
|
||||||
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
(table, Compiler::IntegerType, fieldOffset(t, field), 0, 1));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -5686,7 +5695,7 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
if (fieldFlags(t, field) & ACC_VOLATILE) {
|
||||||
if (BytesPerWord == 4
|
if (TargetBytesPerWord == 4
|
||||||
and (fieldCode == DoubleField or fieldCode == LongField))
|
and (fieldCode == DoubleField or fieldCode == LongField))
|
||||||
{
|
{
|
||||||
c->call
|
c->call
|
||||||
@ -5862,9 +5871,9 @@ compile(MyThread* t, Frame* initialFrame, unsigned ip,
|
|||||||
|
|
||||||
c->jmp
|
c->jmp
|
||||||
(c->load
|
(c->load
|
||||||
(BytesPerWord, BytesPerWord, c->memory
|
(TargetBytesPerWord, TargetBytesPerWord, c->memory
|
||||||
(start, Compiler::AddressType, 0, normalizedKey, BytesPerWord),
|
(start, Compiler::AddressType, 0, normalizedKey, TargetBytesPerWord),
|
||||||
BytesPerWord));
|
TargetBytesPerWord));
|
||||||
|
|
||||||
Compiler::State* state = c->saveState();
|
Compiler::State* state = c->saveState();
|
||||||
|
|
||||||
@ -6018,9 +6027,9 @@ truncateLineNumberTable(Thread* t, object table, unsigned length)
|
|||||||
PROTECT(t, table);
|
PROTECT(t, table);
|
||||||
|
|
||||||
object newTable = makeLineNumberTable(t, length);
|
object newTable = makeLineNumberTable(t, length);
|
||||||
memcpy(lineNumberTableBody(t, newTable, 0),
|
memcpy(&lineNumberTableBody(t, newTable, 0),
|
||||||
lineNumberTableBody(t, table, 0),
|
&lineNumberTableBody(t, table, 0),
|
||||||
length * sizeof(LineNumber));
|
length * sizeof(uint64_t));
|
||||||
|
|
||||||
return newTable;
|
return newTable;
|
||||||
}
|
}
|
||||||
@ -6046,7 +6055,7 @@ translateExceptionHandlerTable(MyThread* t, Context* context, intptr_t start)
|
|||||||
|
|
||||||
unsigned ni = 0;
|
unsigned ni = 0;
|
||||||
for (unsigned oi = 0; oi < length; ++ oi) {
|
for (unsigned oi = 0; oi < length; ++ oi) {
|
||||||
ExceptionHandler* oldHandler = exceptionHandlerTableBody
|
uint64_t oldHandler = exceptionHandlerTableBody
|
||||||
(t, oldTable, oi);
|
(t, oldTable, oi);
|
||||||
|
|
||||||
int handlerStart = resolveIpForwards
|
int handlerStart = resolveIpForwards
|
||||||
@ -6107,8 +6116,7 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start)
|
|||||||
object newTable = makeLineNumberTable(t, length);
|
object newTable = makeLineNumberTable(t, length);
|
||||||
unsigned ni = 0;
|
unsigned ni = 0;
|
||||||
for (unsigned oi = 0; oi < length; ++oi) {
|
for (unsigned oi = 0; oi < length; ++oi) {
|
||||||
LineNumber* oldLine = lineNumberTableBody(t, oldTable, oi);
|
uint64_t oldLine = lineNumberTableBody(t, oldTable, oi);
|
||||||
LineNumber* newLine = lineNumberTableBody(t, newTable, ni);
|
|
||||||
|
|
||||||
int ip = resolveIpForwards
|
int ip = resolveIpForwards
|
||||||
(context, lineNumberIp(oldLine), oi + 1 < length
|
(context, lineNumberIp(oldLine), oi + 1 < length
|
||||||
@ -6116,12 +6124,9 @@ translateLineNumberTable(MyThread* t, Context* context, intptr_t start)
|
|||||||
: lineNumberIp(oldLine) + 1);
|
: lineNumberIp(oldLine) + 1);
|
||||||
|
|
||||||
if (LIKELY(ip >= 0)) {
|
if (LIKELY(ip >= 0)) {
|
||||||
lineNumberIp(newLine)
|
lineNumberTableBody(t, newTable, ni++) = lineNumber
|
||||||
= context->compiler->machineIp(ip)->value() - start;
|
(context->compiler->machineIp(ip)->value() - start,
|
||||||
|
lineNumberLine(oldLine));
|
||||||
lineNumberLine(newLine) = lineNumberLine(oldLine);
|
|
||||||
|
|
||||||
++ ni;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6675,7 +6680,9 @@ makeGeneralFrameMapTable(MyThread* t, Context* context, uint8_t* start,
|
|||||||
|
|
||||||
pathIndex = subroutine->tableIndex;
|
pathIndex = subroutine->tableIndex;
|
||||||
|
|
||||||
THREAD_RUNTIME_ARRAY(t, SubroutineTrace*, traces, p->subroutineTraceCount);
|
THREAD_RUNTIME_ARRAY
|
||||||
|
(t, SubroutineTrace*, traces, p->subroutineTraceCount);
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
for (SubroutineTrace* trace = p->subroutineTrace;
|
for (SubroutineTrace* trace = p->subroutineTrace;
|
||||||
trace; trace = trace->next)
|
trace; trace = trace->next)
|
||||||
@ -6795,9 +6802,9 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
// we must acquire the class lock here at the latest
|
// we must acquire the class lock here at the latest
|
||||||
|
|
||||||
unsigned codeSize = c->resolve
|
unsigned codeSize = c->resolve
|
||||||
(allocator->base + allocator->offset + BytesPerWord);
|
(allocator->base + allocator->offset + TargetBytesPerWord);
|
||||||
|
|
||||||
unsigned total = pad(codeSize) + pad(c->poolSize()) + BytesPerWord;
|
unsigned total = pad(codeSize) + pad(c->poolSize()) + TargetBytesPerWord;
|
||||||
|
|
||||||
uintptr_t* code = static_cast<uintptr_t*>(allocator->allocate(total));
|
uintptr_t* code = static_cast<uintptr_t*>(allocator->allocate(total));
|
||||||
code[0] = codeSize;
|
code[0] = codeSize;
|
||||||
@ -6810,7 +6817,8 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
if (context->objectPool) {
|
if (context->objectPool) {
|
||||||
object pool = allocate3
|
object pool = allocate3
|
||||||
(t, allocator, Machine::ImmortalAllocation,
|
(t, allocator, Machine::ImmortalAllocation,
|
||||||
FixedSizeOfArray + ((context->objectPoolCount + 1) * BytesPerWord),
|
FixedSizeOfArray
|
||||||
|
+ ((context->objectPoolCount + 1) * TargetBytesPerWord),
|
||||||
true);
|
true);
|
||||||
|
|
||||||
initArray(t, pool, context->objectPoolCount + 1);
|
initArray(t, pool, context->objectPoolCount + 1);
|
||||||
@ -6821,7 +6829,7 @@ finish(MyThread* t, FixedAllocator* allocator, Context* context)
|
|||||||
|
|
||||||
unsigned i = 1;
|
unsigned i = 1;
|
||||||
for (PoolElement* p = context->objectPool; p; p = p->next) {
|
for (PoolElement* p = context->objectPool; p; p = p->next) {
|
||||||
unsigned offset = ArrayBody + ((i++) * BytesPerWord);
|
unsigned offset = ArrayBody + ((i++) * TargetBytesPerWord);
|
||||||
|
|
||||||
p->address = reinterpret_cast<uintptr_t>(pool) + offset;
|
p->address = reinterpret_cast<uintptr_t>(pool) + offset;
|
||||||
|
|
||||||
@ -7023,7 +7031,7 @@ compile(MyThread* t, Context* context)
|
|||||||
progress = false;
|
progress = false;
|
||||||
|
|
||||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
||||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
uint64_t eh = exceptionHandlerTableBody(t, eht, i);
|
||||||
int start = resolveIpForwards
|
int start = resolveIpForwards
|
||||||
(context, exceptionHandlerStart(eh), exceptionHandlerEnd(eh));
|
(context, exceptionHandlerStart(eh), exceptionHandlerEnd(eh));
|
||||||
|
|
||||||
@ -7042,7 +7050,7 @@ compile(MyThread* t, Context* context)
|
|||||||
Frame frame2(&frame, RUNTIME_ARRAY_BODY(stackMap));
|
Frame frame2(&frame, RUNTIME_ARRAY_BODY(stackMap));
|
||||||
|
|
||||||
unsigned end = exceptionHandlerEnd(eh);
|
unsigned end = exceptionHandlerEnd(eh);
|
||||||
if (exceptionHandlerIp(eh) >= start
|
if (exceptionHandlerIp(eh) >= static_cast<unsigned>(start)
|
||||||
and exceptionHandlerIp(eh) < end)
|
and exceptionHandlerIp(eh) < end)
|
||||||
{
|
{
|
||||||
end = exceptionHandlerIp(eh);
|
end = exceptionHandlerIp(eh);
|
||||||
@ -9334,15 +9342,15 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
p->thunks.default_.frameSavedOffset = a->length();
|
p->thunks.default_.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Register thread(t->arch->thread());
|
Assembler::Register thread(t->arch->thread());
|
||||||
a->pushFrame(1, BytesPerWord, RegisterOperand, &thread);
|
a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread);
|
||||||
|
|
||||||
Assembler::Constant proc(&(defaultContext.promise));
|
Assembler::Constant proc(&(defaultContext.promise));
|
||||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
a->popFrame(t->arch->alignFrameSize(1));
|
a->popFrame(t->arch->alignFrameSize(1));
|
||||||
|
|
||||||
Assembler::Register result(t->arch->returnLow());
|
Assembler::Register result(t->arch->returnLow());
|
||||||
a->apply(Jump, BytesPerWord, RegisterOperand, &result);
|
a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result);
|
||||||
|
|
||||||
p->thunks.default_.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.default_.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9355,38 +9363,38 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
Assembler::Memory virtualCallTargetSrc
|
Assembler::Memory virtualCallTargetSrc
|
||||||
(t->arch->stack(),
|
(t->arch->stack(),
|
||||||
(t->arch->frameFooterSize() + t->arch->frameReturnAddressSize())
|
(t->arch->frameFooterSize() + t->arch->frameReturnAddressSize())
|
||||||
* BytesPerWord);
|
* TargetBytesPerWord);
|
||||||
|
|
||||||
a->apply(Move, BytesPerWord, MemoryOperand, &virtualCallTargetSrc,
|
a->apply(Move, TargetBytesPerWord, MemoryOperand, &virtualCallTargetSrc,
|
||||||
BytesPerWord, RegisterOperand, &class_);
|
TargetBytesPerWord, RegisterOperand, &class_);
|
||||||
|
|
||||||
Assembler::Memory virtualCallTargetDst
|
Assembler::Memory virtualCallTargetDst
|
||||||
(t->arch->thread(), difference(&(t->virtualCallTarget), t));
|
(t->arch->thread(), difference(&(t->virtualCallTarget), t));
|
||||||
|
|
||||||
a->apply(Move, BytesPerWord, RegisterOperand, &class_,
|
a->apply(Move, TargetBytesPerWord, RegisterOperand, &class_,
|
||||||
BytesPerWord, MemoryOperand, &virtualCallTargetDst);
|
TargetBytesPerWord, MemoryOperand, &virtualCallTargetDst);
|
||||||
|
|
||||||
Assembler::Register index(t->arch->virtualCallIndex());
|
Assembler::Register index(t->arch->virtualCallIndex());
|
||||||
Assembler::Memory virtualCallIndex
|
Assembler::Memory virtualCallIndex
|
||||||
(t->arch->thread(), difference(&(t->virtualCallIndex), t));
|
(t->arch->thread(), difference(&(t->virtualCallIndex), t));
|
||||||
|
|
||||||
a->apply(Move, BytesPerWord, RegisterOperand, &index,
|
a->apply(Move, TargetBytesPerWord, RegisterOperand, &index,
|
||||||
BytesPerWord, MemoryOperand, &virtualCallIndex);
|
TargetBytesPerWord, MemoryOperand, &virtualCallIndex);
|
||||||
|
|
||||||
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
a->saveFrame(difference(&(t->stack), t), difference(&(t->ip), t));
|
||||||
|
|
||||||
p->thunks.defaultVirtual.frameSavedOffset = a->length();
|
p->thunks.defaultVirtual.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Register thread(t->arch->thread());
|
Assembler::Register thread(t->arch->thread());
|
||||||
a->pushFrame(1, BytesPerWord, RegisterOperand, &thread);
|
a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread);
|
||||||
|
|
||||||
Assembler::Constant proc(&(defaultVirtualContext.promise));
|
Assembler::Constant proc(&(defaultVirtualContext.promise));
|
||||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
a->popFrame(t->arch->alignFrameSize(1));
|
a->popFrame(t->arch->alignFrameSize(1));
|
||||||
|
|
||||||
Assembler::Register result(t->arch->returnLow());
|
Assembler::Register result(t->arch->returnLow());
|
||||||
a->apply(Jump, BytesPerWord, RegisterOperand, &result);
|
a->apply(Jump, TargetBytesPerWord, RegisterOperand, &result);
|
||||||
|
|
||||||
p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.defaultVirtual.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9400,10 +9408,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
p->thunks.native.frameSavedOffset = a->length();
|
p->thunks.native.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Register thread(t->arch->thread());
|
Assembler::Register thread(t->arch->thread());
|
||||||
a->pushFrame(1, BytesPerWord, RegisterOperand, &thread);
|
a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread);
|
||||||
|
|
||||||
Assembler::Constant proc(&(nativeContext.promise));
|
Assembler::Constant proc(&(nativeContext.promise));
|
||||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
a->popFrameAndUpdateStackAndReturn
|
a->popFrameAndUpdateStackAndReturn
|
||||||
(t->arch->alignFrameSize(1), difference(&(t->stack), t));
|
(t->arch->alignFrameSize(1), difference(&(t->stack), t));
|
||||||
@ -9420,10 +9428,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
p->thunks.aioob.frameSavedOffset = a->length();
|
p->thunks.aioob.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Register thread(t->arch->thread());
|
Assembler::Register thread(t->arch->thread());
|
||||||
a->pushFrame(1, BytesPerWord, RegisterOperand, &thread);
|
a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread);
|
||||||
|
|
||||||
Assembler::Constant proc(&(aioobContext.promise));
|
Assembler::Constant proc(&(aioobContext.promise));
|
||||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
p->thunks.aioob.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.aioob.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9437,10 +9445,10 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
p->thunks.stackOverflow.frameSavedOffset = a->length();
|
p->thunks.stackOverflow.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Register thread(t->arch->thread());
|
Assembler::Register thread(t->arch->thread());
|
||||||
a->pushFrame(1, BytesPerWord, RegisterOperand, &thread);
|
a->pushFrame(1, TargetBytesPerWord, RegisterOperand, &thread);
|
||||||
|
|
||||||
Assembler::Constant proc(&(stackOverflowContext.promise));
|
Assembler::Constant proc(&(stackOverflowContext.promise));
|
||||||
a->apply(LongCall, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongCall, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
p->thunks.stackOverflow.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.stackOverflow.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9454,7 +9462,7 @@ compileThunks(MyThread* t, Allocator* allocator, MyProcessor* p)
|
|||||||
p->thunks.table.frameSavedOffset = a->length();
|
p->thunks.table.frameSavedOffset = a->length();
|
||||||
|
|
||||||
Assembler::Constant proc(&(tableContext.promise));
|
Assembler::Constant proc(&(tableContext.promise));
|
||||||
a->apply(LongJump, BytesPerWord, ConstantOperand, &proc);
|
a->apply(LongJump, TargetBytesPerWord, ConstantOperand, &proc);
|
||||||
|
|
||||||
p->thunks.table.length = a->endBlock(false)->resolve(0, 0);
|
p->thunks.table.length = a->endBlock(false)->resolve(0, 0);
|
||||||
}
|
}
|
||||||
@ -9633,12 +9641,12 @@ compileVirtualThunk(MyThread* t, unsigned index, unsigned* size)
|
|||||||
ResolvedPromise indexPromise(index);
|
ResolvedPromise indexPromise(index);
|
||||||
Assembler::Constant indexConstant(&indexPromise);
|
Assembler::Constant indexConstant(&indexPromise);
|
||||||
Assembler::Register indexRegister(t->arch->virtualCallIndex());
|
Assembler::Register indexRegister(t->arch->virtualCallIndex());
|
||||||
a->apply(Move, BytesPerWord, ConstantOperand, &indexConstant,
|
a->apply(Move, TargetBytesPerWord, ConstantOperand, &indexConstant,
|
||||||
BytesPerWord, RegisterOperand, &indexRegister);
|
TargetBytesPerWord, RegisterOperand, &indexRegister);
|
||||||
|
|
||||||
ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t));
|
ResolvedPromise defaultVirtualThunkPromise(defaultVirtualThunk(t));
|
||||||
Assembler::Constant thunk(&defaultVirtualThunkPromise);
|
Assembler::Constant thunk(&defaultVirtualThunkPromise);
|
||||||
a->apply(Jump, BytesPerWord, ConstantOperand, &thunk);
|
a->apply(Jump, TargetBytesPerWord, ConstantOperand, &thunk);
|
||||||
|
|
||||||
*size = a->endBlock(false)->resolve(0, 0);
|
*size = a->endBlock(false)->resolve(0, 0);
|
||||||
|
|
||||||
@ -9723,7 +9731,7 @@ compile(MyThread* t, FixedAllocator* allocator, BootContext* bootContext,
|
|||||||
// resolve all exception handler catch types before we acquire
|
// resolve all exception handler catch types before we acquire
|
||||||
// the class lock:
|
// the class lock:
|
||||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, ehTable); ++i) {
|
for (unsigned i = 0; i < exceptionHandlerTableLength(t, ehTable); ++i) {
|
||||||
ExceptionHandler* handler = exceptionHandlerTableBody(t, ehTable, i);
|
uint64_t handler = exceptionHandlerTableBody(t, ehTable, i);
|
||||||
if (exceptionHandlerCatchType(handler)) {
|
if (exceptionHandlerCatchType(handler)) {
|
||||||
resolveClassInPool
|
resolveClassInPool
|
||||||
(t, clone, exceptionHandlerCatchType(handler) - 1);
|
(t, clone, exceptionHandlerCatchType(handler) - 1);
|
||||||
|
206
src/compiler.cpp
206
src/compiler.cpp
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
using namespace vm;
|
using namespace vm;
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ const unsigned StealRegisterReserveCount = 2;
|
|||||||
|
|
||||||
// this should be equal to the largest number of registers used by a
|
// this should be equal to the largest number of registers used by a
|
||||||
// compare instruction:
|
// compare instruction:
|
||||||
const unsigned ResolveRegisterReserveCount = (BytesPerWord == 8 ? 2 : 4);
|
const unsigned ResolveRegisterReserveCount = (TargetBytesPerWord == 8 ? 2 : 4);
|
||||||
|
|
||||||
const unsigned RegisterCopyCost = 1;
|
const unsigned RegisterCopyCost = 1;
|
||||||
const unsigned AddressCopyCost = 2;
|
const unsigned AddressCopyCost = 2;
|
||||||
@ -143,7 +144,7 @@ class Site {
|
|||||||
|
|
||||||
virtual SiteMask nextWordMask(Context*, unsigned) = 0;
|
virtual SiteMask nextWordMask(Context*, unsigned) = 0;
|
||||||
|
|
||||||
virtual unsigned registerSize(Context*) { return BytesPerWord; }
|
virtual unsigned registerSize(Context*) { return TargetBytesPerWord; }
|
||||||
|
|
||||||
virtual unsigned registerMask(Context*) { return 0; }
|
virtual unsigned registerMask(Context*) { return 0; }
|
||||||
|
|
||||||
@ -467,8 +468,9 @@ class PoolPromise: public Promise {
|
|||||||
|
|
||||||
virtual int64_t value() {
|
virtual int64_t value() {
|
||||||
if (resolved()) {
|
if (resolved()) {
|
||||||
return reinterpret_cast<intptr_t>
|
return reinterpret_cast<int64_t>
|
||||||
(c->machineCode + pad(c->machineCodeSize) + (key * BytesPerWord));
|
(c->machineCode + pad(c->machineCodeSize)
|
||||||
|
+ (key * TargetBytesPerWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
abort(c);
|
abort(c);
|
||||||
@ -740,18 +742,18 @@ frameIndexToOffset(Context* c, unsigned frameIndex)
|
|||||||
{
|
{
|
||||||
assert(c, frameIndex < totalFrameSize(c));
|
assert(c, frameIndex < totalFrameSize(c));
|
||||||
|
|
||||||
return (frameIndex + c->arch->frameFooterSize()) * BytesPerWord;
|
return (frameIndex + c->arch->frameFooterSize()) * TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
offsetToFrameIndex(Context* c, unsigned offset)
|
offsetToFrameIndex(Context* c, unsigned offset)
|
||||||
{
|
{
|
||||||
assert(c, static_cast<int>
|
assert(c, static_cast<int>
|
||||||
((offset / BytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
((offset / TargetBytesPerWord) - c->arch->frameFooterSize()) >= 0);
|
||||||
assert(c, ((offset / BytesPerWord) - c->arch->frameFooterSize())
|
assert(c, ((offset / TargetBytesPerWord) - c->arch->frameFooterSize())
|
||||||
< totalFrameSize(c));
|
< totalFrameSize(c));
|
||||||
|
|
||||||
return (offset / BytesPerWord) - c->arch->frameFooterSize();
|
return (offset / TargetBytesPerWord) - c->arch->frameFooterSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
@ -837,7 +839,7 @@ class SiteIterator {
|
|||||||
Site** findNext(Site** p) {
|
Site** findNext(Site** p) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (*p) {
|
if (*p) {
|
||||||
if (pass == 0 or (*p)->registerSize(c) > BytesPerWord) {
|
if (pass == 0 or (*p)->registerSize(c) > TargetBytesPerWord) {
|
||||||
return p;
|
return p;
|
||||||
} else {
|
} else {
|
||||||
p = &((*p)->next);
|
p = &((*p)->next);
|
||||||
@ -922,7 +924,7 @@ uniqueSite(Context* c, Value* v, Site* s)
|
|||||||
if (it.hasMore()) {
|
if (it.hasMore()) {
|
||||||
// the site is not this word's only site, but if the site is
|
// 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
|
// 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);
|
SiteIterator nit(c, v->nextWord);
|
||||||
Site* p = nit.next();
|
Site* p = nit.next();
|
||||||
if (nit.hasMore()) {
|
if (nit.hasMore()) {
|
||||||
@ -1052,7 +1054,7 @@ deadWord(Context* c, Value* v)
|
|||||||
for (SiteIterator it(c, v, true, false); it.hasMore();) {
|
for (SiteIterator it(c, v, true, false); it.hasMore();) {
|
||||||
Site* s = it.next();
|
Site* s = it.next();
|
||||||
|
|
||||||
if (s->registerSize(c) > BytesPerWord) {
|
if (s->registerSize(c) > TargetBytesPerWord) {
|
||||||
it.remove(c);
|
it.remove(c);
|
||||||
addSite(c, nextWord, s);
|
addSite(c, nextWord, s);
|
||||||
}
|
}
|
||||||
@ -1838,7 +1840,7 @@ class RegisterSite: public Site {
|
|||||||
|
|
||||||
RegisterSite* rs = static_cast<RegisterSite*>(s);
|
RegisterSite* rs = static_cast<RegisterSite*>(s);
|
||||||
unsigned size = rs->registerSize(c);
|
unsigned size = rs->registerSize(c);
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
assert(c, number != NoRegister);
|
assert(c, number != NoRegister);
|
||||||
return number == rs->number;
|
return number == rs->number;
|
||||||
} else {
|
} else {
|
||||||
@ -1940,7 +1942,7 @@ class RegisterSite: public Site {
|
|||||||
virtual SiteMask nextWordMask(Context* c, unsigned) {
|
virtual SiteMask nextWordMask(Context* c, unsigned) {
|
||||||
assert(c, number != NoRegister);
|
assert(c, number != NoRegister);
|
||||||
|
|
||||||
if (registerSize(c) > BytesPerWord) {
|
if (registerSize(c) > TargetBytesPerWord) {
|
||||||
return SiteMask
|
return SiteMask
|
||||||
(1 << RegisterOperand, number, NoFrameIndex);
|
(1 << RegisterOperand, number, NoFrameIndex);
|
||||||
} else {
|
} else {
|
||||||
@ -1955,7 +1957,7 @@ class RegisterSite: public Site {
|
|||||||
if ((1 << number) & c->arch->floatRegisterMask()) {
|
if ((1 << number) & c->arch->floatRegisterMask()) {
|
||||||
return c->arch->floatRegisterSize();
|
return c->arch->floatRegisterSize();
|
||||||
} else {
|
} else {
|
||||||
return BytesPerWord;
|
return TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2065,9 +2067,9 @@ class MemorySite: public Site {
|
|||||||
MemorySite* ms = static_cast<MemorySite*>(s);
|
MemorySite* ms = static_cast<MemorySite*>(s);
|
||||||
return ms->base == this->base
|
return ms->base == this->base
|
||||||
and ((index == 1 and ms->offset == static_cast<int>
|
and ((index == 1 and ms->offset == static_cast<int>
|
||||||
(this->offset + BytesPerWord))
|
(this->offset + TargetBytesPerWord))
|
||||||
or (index == 0 and this->offset == static_cast<int>
|
or (index == 0 and this->offset == static_cast<int>
|
||||||
(ms->offset + BytesPerWord)))
|
(ms->offset + TargetBytesPerWord)))
|
||||||
and ms->index == this->index
|
and ms->index == this->index
|
||||||
and ms->scale == this->scale;
|
and ms->scale == this->scale;
|
||||||
} else {
|
} else {
|
||||||
@ -2149,7 +2151,7 @@ class MemorySite: public Site {
|
|||||||
assert(c, high == this
|
assert(c, high == this
|
||||||
or (static_cast<MemorySite*>(high)->base == base
|
or (static_cast<MemorySite*>(high)->base == base
|
||||||
and static_cast<MemorySite*>(high)->offset
|
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)->index == index
|
||||||
and static_cast<MemorySite*>(high)->scale == scale));
|
and static_cast<MemorySite*>(high)->scale == scale));
|
||||||
|
|
||||||
@ -2164,7 +2166,7 @@ class MemorySite: public Site {
|
|||||||
|
|
||||||
Site* copyHalf(Context* c, bool add) {
|
Site* copyHalf(Context* c, bool add) {
|
||||||
if (add) {
|
if (add) {
|
||||||
return memorySite(c, base, offset + BytesPerWord, index, scale);
|
return memorySite(c, base, offset + TargetBytesPerWord, index, scale);
|
||||||
} else {
|
} else {
|
||||||
return copy(c);
|
return copy(c);
|
||||||
}
|
}
|
||||||
@ -2181,7 +2183,7 @@ class MemorySite: public Site {
|
|||||||
virtual Site* makeNextWord(Context* c, unsigned index) {
|
virtual Site* makeNextWord(Context* c, unsigned index) {
|
||||||
return memorySite
|
return memorySite
|
||||||
(c, base, offset + ((index == 1) xor c->arch->bigEndian()
|
(c, base, offset + ((index == 1) xor c->arch->bigEndian()
|
||||||
? BytesPerWord : -BytesPerWord),
|
? TargetBytesPerWord : -TargetBytesPerWord),
|
||||||
this->index, scale);
|
this->index, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2398,7 +2400,7 @@ maybeMove(Context* c, Read* read, bool intersectRead, bool includeNextWord,
|
|||||||
unsigned registerReserveCount = 0)
|
unsigned registerReserveCount = 0)
|
||||||
{
|
{
|
||||||
Value* value = read->value;
|
Value* value = read->value;
|
||||||
unsigned size = value == value->nextWord ? BytesPerWord : 8;
|
unsigned size = value == value->nextWord ? TargetBytesPerWord : 8;
|
||||||
|
|
||||||
class MyCostCalculator: public CostCalculator {
|
class MyCostCalculator: public CostCalculator {
|
||||||
public:
|
public:
|
||||||
@ -2926,8 +2928,8 @@ move(Context* c, Value* value, Site* src, Site* dst)
|
|||||||
unsigned srcSize;
|
unsigned srcSize;
|
||||||
unsigned dstSize;
|
unsigned dstSize;
|
||||||
if (value->nextWord == value) {
|
if (value->nextWord == value) {
|
||||||
srcSize = BytesPerWord;
|
srcSize = TargetBytesPerWord;
|
||||||
dstSize = BytesPerWord;
|
dstSize = TargetBytesPerWord;
|
||||||
} else {
|
} else {
|
||||||
srcSize = src->registerSize(c);
|
srcSize = src->registerSize(c);
|
||||||
dstSize = dst->registerSize(c);
|
dstSize = dst->registerSize(c);
|
||||||
@ -2935,7 +2937,7 @@ move(Context* c, Value* value, Site* src, Site* dst)
|
|||||||
|
|
||||||
if (srcSize == dstSize) {
|
if (srcSize == dstSize) {
|
||||||
apply(c, Move, srcSize, src, src, dstSize, dst, dst);
|
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);
|
Site* low, *high, *other = pickSiteOrGrow(c, value, dst, &low, &high);
|
||||||
other->freeze(c, value->nextWord);
|
other->freeze(c, value->nextWord);
|
||||||
|
|
||||||
@ -3065,7 +3067,7 @@ addReads(Context* c, Event* e, Value* v, unsigned size,
|
|||||||
{
|
{
|
||||||
SingleRead* r = read(c, lowMask, lowSuccessor);
|
SingleRead* r = read(c, lowMask, lowSuccessor);
|
||||||
addRead(c, e, v, r);
|
addRead(c, e, v, r);
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
r->high_ = v->nextWord;
|
r->high_ = v->nextWord;
|
||||||
addRead(c, e, v->nextWord, highMask, highSuccessor);
|
addRead(c, e, v->nextWord, highMask, highSuccessor);
|
||||||
}
|
}
|
||||||
@ -3234,7 +3236,7 @@ class CallEvent: public Event {
|
|||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
uint64_t planRegisterMask;
|
uint64_t planRegisterMask;
|
||||||
c->arch->plan
|
c->arch->plan
|
||||||
((flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord,
|
((flags & Compiler::Aligned) ? AlignedCall : Call, TargetBytesPerWord,
|
||||||
&typeMask, &planRegisterMask, &thunk);
|
&typeMask, &planRegisterMask, &thunk);
|
||||||
|
|
||||||
assert(c, not thunk);
|
assert(c, not thunk);
|
||||||
@ -3251,10 +3253,11 @@ class CallEvent: public Event {
|
|||||||
Value* v = stack->value;
|
Value* v = stack->value;
|
||||||
stack = stack->next;
|
stack = stack->next;
|
||||||
|
|
||||||
if ((BytesPerWord == 8 and (v == 0 or (i >= 1 and stack->value == 0)))
|
if ((TargetBytesPerWord == 8
|
||||||
or (BytesPerWord == 4 and v->nextWord != v))
|
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;
|
RUNTIME_ARRAY_BODY(arguments)[i--] = stack->value;
|
||||||
stack = stack->next;
|
stack = stack->next;
|
||||||
@ -3405,7 +3408,7 @@ class CallEvent: public Event {
|
|||||||
op = Call;
|
op = Call;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(c, op, BytesPerWord, address->source, address->source);
|
apply(c, op, TargetBytesPerWord, address->source, address->source);
|
||||||
|
|
||||||
if (traceHandler) {
|
if (traceHandler) {
|
||||||
traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)),
|
traceHandler->handleTrace(codePromise(c, c->assembler->offset(true)),
|
||||||
@ -3436,7 +3439,7 @@ class CallEvent: public Event {
|
|||||||
|
|
||||||
if (resultSize and live(c, result)) {
|
if (resultSize and live(c, result)) {
|
||||||
addSite(c, result, registerSite(c, c->arch->returnLow()));
|
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()));
|
addSite(c, result->nextWord, registerSite(c, c->arch->returnHigh()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3758,16 +3761,17 @@ class MoveEvent: public Event {
|
|||||||
|
|
||||||
bool noop = srcSelectSize >= dstSize;
|
bool noop = srcSelectSize >= dstSize;
|
||||||
|
|
||||||
if (dstSize > BytesPerWord) {
|
if (dstSize > TargetBytesPerWord) {
|
||||||
grow(c, dst);
|
grow(c, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srcSelectSize > BytesPerWord) {
|
if (srcSelectSize > TargetBytesPerWord) {
|
||||||
maybeSplit(c, src);
|
maybeSplit(c, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
addReads(c, this, src, srcSelectSize, srcLowMask, noop ? dst : 0,
|
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() {
|
virtual const char* name() {
|
||||||
@ -3791,43 +3795,46 @@ class MoveEvent: public Event {
|
|||||||
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
|
SiteMask dstLowMask(dstTypeMask, dstRegisterMask, AnyFrameIndex);
|
||||||
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
|
SiteMask dstHighMask(dstTypeMask, dstRegisterMask >> 32, AnyFrameIndex);
|
||||||
|
|
||||||
if (srcSelectSize >= BytesPerWord
|
if (srcSelectSize >= TargetBytesPerWord
|
||||||
and dstSize >= BytesPerWord
|
and dstSize >= TargetBytesPerWord
|
||||||
and srcSelectSize >= dstSize)
|
and srcSelectSize >= dstSize)
|
||||||
{
|
{
|
||||||
if (dst->target) {
|
if (dst->target) {
|
||||||
if (dstSize > BytesPerWord
|
if (dstSize > TargetBytesPerWord
|
||||||
and src->source->registerSize(c) > BytesPerWord)
|
and src->source->registerSize(c) > TargetBytesPerWord)
|
||||||
{
|
{
|
||||||
apply(c, Move, srcSelectSize, src->source, src->source,
|
apply(c, Move, srcSelectSize, src->source, src->source,
|
||||||
dstSize, dst->target, dst->target);
|
dstSize, dst->target, dst->target);
|
||||||
|
|
||||||
if (live(c, dst) == 0) {
|
if (live(c, dst) == 0) {
|
||||||
removeSite(c, dst, dst->target);
|
removeSite(c, dst, dst->target);
|
||||||
if (dstSize > BytesPerWord) {
|
if (dstSize > TargetBytesPerWord) {
|
||||||
removeSite(c, dst->nextWord, dst->nextWord->target);
|
removeSite(c, dst->nextWord, dst->nextWord->target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
maybeMove(c, Move, BytesPerWord, BytesPerWord, src,
|
maybeMove(c, Move, TargetBytesPerWord, TargetBytesPerWord, src,
|
||||||
BytesPerWord, dst, dstLowMask);
|
TargetBytesPerWord, dst, dstLowMask);
|
||||||
if (dstSize > BytesPerWord) {
|
if (dstSize > TargetBytesPerWord) {
|
||||||
maybeMove(c, Move, BytesPerWord, BytesPerWord, src->nextWord,
|
maybeMove
|
||||||
BytesPerWord, dst->nextWord, dstHighMask);
|
(c, Move, TargetBytesPerWord, TargetBytesPerWord, src->nextWord,
|
||||||
|
TargetBytesPerWord, dst->nextWord, dstHighMask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
|
Site* low = pickSiteOrMove(c, src, dst, 0, 0);
|
||||||
if (dstSize > BytesPerWord) {
|
if (dstSize > TargetBytesPerWord) {
|
||||||
pickSiteOrMove(c, src->nextWord, dst->nextWord, low, 1);
|
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,
|
maybeMove(c, type, srcSize, srcSelectSize, src, dstSize, dst,
|
||||||
dstLowMask);
|
dstLowMask);
|
||||||
} else {
|
} else {
|
||||||
assert(c, srcSize == BytesPerWord);
|
assert(c, srcSize == TargetBytesPerWord);
|
||||||
assert(c, srcSelectSize == BytesPerWord);
|
assert(c, srcSelectSize == TargetBytesPerWord);
|
||||||
|
|
||||||
if (dst->nextWord->target or live(c, dst->nextWord)) {
|
if (dst->nextWord->target or live(c, dst->nextWord)) {
|
||||||
assert(c, dstLowMask.typeMask & (1 << RegisterOperand));
|
assert(c, dstLowMask.typeMask & (1 << RegisterOperand));
|
||||||
@ -3847,8 +3854,8 @@ class MoveEvent: public Event {
|
|||||||
srcb, dstb, src);
|
srcb, dstb, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
apply(c, Move, BytesPerWord, src->source, src->source,
|
apply(c, Move, TargetBytesPerWord, src->source, src->source,
|
||||||
BytesPerWord, low, low);
|
TargetBytesPerWord, low, low);
|
||||||
|
|
||||||
low->thaw(c, dst);
|
low->thaw(c, dst);
|
||||||
|
|
||||||
@ -3871,7 +3878,7 @@ class MoveEvent: public Event {
|
|||||||
srcb, dstb, dst, dst->nextWord);
|
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);
|
high->thaw(c, dst->nextWord);
|
||||||
|
|
||||||
@ -3972,7 +3979,7 @@ void
|
|||||||
freezeSource(Context* c, unsigned size, Value* v)
|
freezeSource(Context* c, unsigned size, Value* v)
|
||||||
{
|
{
|
||||||
v->source->freeze(c, v);
|
v->source->freeze(c, v);
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
v->nextWord->source->freeze(c, v->nextWord);
|
v->nextWord->source->freeze(c, v->nextWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3981,7 +3988,7 @@ void
|
|||||||
thawSource(Context* c, unsigned size, Value* v)
|
thawSource(Context* c, unsigned size, Value* v)
|
||||||
{
|
{
|
||||||
v->source->thaw(c, v);
|
v->source->thaw(c, v);
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
v->nextWord->source->thaw(c, v->nextWord);
|
v->nextWord->source->thaw(c, v->nextWord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4002,7 +4009,7 @@ class CombineEvent: public Event {
|
|||||||
{
|
{
|
||||||
addReads(c, this, first, firstSize, firstLowMask, firstHighMask);
|
addReads(c, this, first, firstSize, firstLowMask, firstHighMask);
|
||||||
|
|
||||||
if (resultSize > BytesPerWord) {
|
if (resultSize > TargetBytesPerWord) {
|
||||||
grow(c, result);
|
grow(c, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4227,7 +4234,7 @@ push(Context* c, unsigned footprint, Value* v)
|
|||||||
if (footprint > 1) {
|
if (footprint > 1) {
|
||||||
assert(c, footprint == 2);
|
assert(c, footprint == 2);
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
maybeSplit(c, low);
|
maybeSplit(c, low);
|
||||||
high = pushWord(c, low->nextWord);
|
high = pushWord(c, low->nextWord);
|
||||||
} else {
|
} else {
|
||||||
@ -4288,9 +4295,9 @@ pop(Context* c, unsigned footprint)
|
|||||||
high = low->next;
|
high = low->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(c, (BytesPerWord == 8
|
assert(c, (TargetBytesPerWord == 8
|
||||||
and low->value->nextWord == low->value and high->value == 0)
|
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
|
#endif // not NDEBUG
|
||||||
|
|
||||||
popWord(c);
|
popWord(c);
|
||||||
@ -4331,7 +4338,7 @@ storeLocal(Context* c, unsigned footprint, Value* v, unsigned index, bool copy)
|
|||||||
highIndex = index;
|
highIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
assert(c, v->nextWord != v);
|
assert(c, v->nextWord != v);
|
||||||
|
|
||||||
high = storeLocal(c, 1, v->nextWord, highIndex, false);
|
high = storeLocal(c, 1, v->nextWord, highIndex, false);
|
||||||
@ -4423,11 +4430,11 @@ appendCombine(Context* c, TernaryOperation type,
|
|||||||
intptr_t handler = c->client->getThunk
|
intptr_t handler = c->client->getThunk
|
||||||
(type, firstSize, resultSize, &threadParameter);
|
(type, firstSize, resultSize, &threadParameter);
|
||||||
|
|
||||||
unsigned stackSize = ceiling(secondSize, BytesPerWord)
|
unsigned stackSize = ceiling(secondSize, TargetBytesPerWord)
|
||||||
+ ceiling(firstSize, BytesPerWord);
|
+ ceiling(firstSize, TargetBytesPerWord);
|
||||||
|
|
||||||
local::push(c, ceiling(secondSize, BytesPerWord), second);
|
local::push(c, ceiling(secondSize, TargetBytesPerWord), second);
|
||||||
local::push(c, ceiling(firstSize, BytesPerWord), first);
|
local::push(c, ceiling(firstSize, TargetBytesPerWord), first);
|
||||||
|
|
||||||
if (threadParameter) {
|
if (threadParameter) {
|
||||||
++ stackSize;
|
++ stackSize;
|
||||||
@ -4467,7 +4474,7 @@ class TranslateEvent: public Event {
|
|||||||
{
|
{
|
||||||
bool condensed = c->arch->alwaysCondensed(type);
|
bool condensed = c->arch->alwaysCondensed(type);
|
||||||
|
|
||||||
if (resultSize > BytesPerWord) {
|
if (resultSize > TargetBytesPerWord) {
|
||||||
grow(c, result);
|
grow(c, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4549,7 +4556,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize,
|
|||||||
if (thunk) {
|
if (thunk) {
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
|
|
||||||
local::push(c, ceiling(firstSize, BytesPerWord), first);
|
local::push(c, ceiling(firstSize, TargetBytesPerWord), first);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -4559,7 +4566,7 @@ appendTranslate(Context* c, BinaryOperation type, unsigned firstSize,
|
|||||||
(c, ValueGeneral, constantSite
|
(c, ValueGeneral, constantSite
|
||||||
(c, c->client->getThunk(type, firstSize, resultSize))),
|
(c, c->client->getThunk(type, firstSize, resultSize))),
|
||||||
0, 0, result, resultSize, argumentStack,
|
0, 0, result, resultSize, argumentStack,
|
||||||
ceiling(firstSize, BytesPerWord), 0);
|
ceiling(firstSize, TargetBytesPerWord), 0);
|
||||||
} else {
|
} else {
|
||||||
append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
|
append(c, new (c->zone->allocate(sizeof(TranslateEvent)))
|
||||||
TranslateEvent
|
TranslateEvent
|
||||||
@ -4632,7 +4639,7 @@ class MemoryEvent: public Event {
|
|||||||
|
|
||||||
popRead(c, this, base);
|
popRead(c, this, base);
|
||||||
if (index) {
|
if (index) {
|
||||||
if (BytesPerWord == 8 and indexRegister != NoRegister) {
|
if (TargetBytesPerWord == 8 and indexRegister != NoRegister) {
|
||||||
apply(c, Move, 4, index->source, index->source,
|
apply(c, Move, 4, index->source, index->source,
|
||||||
8, index->source, index->source);
|
8, index->source, index->source);
|
||||||
}
|
}
|
||||||
@ -4798,7 +4805,7 @@ class BranchEvent: public Event {
|
|||||||
|
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
uint64_t registerMask;
|
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);
|
&typeMask, ®isterMask);
|
||||||
|
|
||||||
addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
addRead(c, this, address, SiteMask(typeMask, registerMask, AnyFrameIndex));
|
||||||
@ -4821,7 +4828,7 @@ class BranchEvent: public Event {
|
|||||||
int64_t firstValue = firstConstant->value->value();
|
int64_t firstValue = firstConstant->value->value();
|
||||||
int64_t secondValue = secondConstant->value->value();
|
int64_t secondValue = secondConstant->value->value();
|
||||||
|
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
firstValue |= findConstantSite
|
firstValue |= findConstantSite
|
||||||
(c, first->nextWord)->value->value() << 32;
|
(c, first->nextWord)->value->value() << 32;
|
||||||
secondValue |= findConstantSite
|
secondValue |= findConstantSite
|
||||||
@ -4829,18 +4836,18 @@ class BranchEvent: public Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldJump(c, type, size, firstValue, secondValue)) {
|
if (shouldJump(c, type, size, firstValue, secondValue)) {
|
||||||
apply(c, Jump, BytesPerWord, address->source, address->source);
|
apply(c, Jump, TargetBytesPerWord, address->source, address->source);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
freezeSource(c, size, first);
|
freezeSource(c, size, first);
|
||||||
freezeSource(c, size, second);
|
freezeSource(c, size, second);
|
||||||
freezeSource(c, BytesPerWord, address);
|
freezeSource(c, TargetBytesPerWord, address);
|
||||||
|
|
||||||
apply(c, type, size, first->source, first->nextWord->source,
|
apply(c, type, size, first->source, first->nextWord->source,
|
||||||
size, second->source, second->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, second);
|
||||||
thawSource(c, size, first);
|
thawSource(c, size, first);
|
||||||
}
|
}
|
||||||
@ -4872,7 +4879,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
|||||||
|
|
||||||
c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask,
|
c->arch->planSource(type, size, &firstTypeMask, &firstRegisterMask,
|
||||||
size, &secondTypeMask, &secondRegisterMask,
|
size, &secondTypeMask, &secondRegisterMask,
|
||||||
BytesPerWord, &thunk);
|
TargetBytesPerWord, &thunk);
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
@ -4883,8 +4890,8 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
|||||||
|
|
||||||
assert(c, not threadParameter);
|
assert(c, not threadParameter);
|
||||||
|
|
||||||
local::push(c, ceiling(size, BytesPerWord), second);
|
local::push(c, ceiling(size, TargetBytesPerWord), second);
|
||||||
local::push(c, ceiling(size, BytesPerWord), first);
|
local::push(c, ceiling(size, TargetBytesPerWord), first);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -4893,7 +4900,7 @@ appendBranch(Context* c, TernaryOperation type, unsigned size, Value* first,
|
|||||||
appendCall
|
appendCall
|
||||||
(c, value
|
(c, value
|
||||||
(c, ValueGeneral, constantSite(c, handler)), 0, 0, result, 4,
|
(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
|
appendBranch(c, thunkBranch(c, type), 4, value
|
||||||
(c, ValueGeneral, constantSite(c, static_cast<int64_t>(0))),
|
(c, ValueGeneral, constantSite(c, static_cast<int64_t>(0))),
|
||||||
@ -4920,7 +4927,7 @@ class JumpEvent: public Event {
|
|||||||
bool thunk;
|
bool thunk;
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
uint64_t registerMask;
|
uint64_t registerMask;
|
||||||
c->arch->plan(type, BytesPerWord, &typeMask, ®isterMask, &thunk);
|
c->arch->plan(type, TargetBytesPerWord, &typeMask, ®isterMask, &thunk);
|
||||||
|
|
||||||
assert(c, not thunk);
|
assert(c, not thunk);
|
||||||
|
|
||||||
@ -4933,7 +4940,7 @@ class JumpEvent: public Event {
|
|||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
if (not unreachable(this)) {
|
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) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
@ -4992,7 +4999,7 @@ class BoundsCheckEvent: public Event {
|
|||||||
if (constant) {
|
if (constant) {
|
||||||
if (constant->value->value() < 0) {
|
if (constant->value->value() < 0) {
|
||||||
Assembler::Constant handlerConstant(resolved(c, handler));
|
Assembler::Constant handlerConstant(resolved(c, handler));
|
||||||
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
outOfBoundsPromise = codePromise(c, static_cast<Promise*>(0));
|
outOfBoundsPromise = codePromise(c, static_cast<Promise*>(0));
|
||||||
@ -5000,7 +5007,7 @@ class BoundsCheckEvent: public Event {
|
|||||||
ConstantSite zero(resolved(c, 0));
|
ConstantSite zero(resolved(c, 0));
|
||||||
ConstantSite oob(outOfBoundsPromise);
|
ConstantSite oob(outOfBoundsPromise);
|
||||||
apply(c, JumpIfLess, 4, &zero, &zero, 4, index->source, index->source,
|
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) {
|
if (constant == 0 or constant->value->value() >= 0) {
|
||||||
@ -5011,20 +5018,20 @@ class BoundsCheckEvent: public Event {
|
|||||||
|
|
||||||
CodePromise* nextPromise = codePromise(c, static_cast<Promise*>(0));
|
CodePromise* nextPromise = codePromise(c, static_cast<Promise*>(0));
|
||||||
|
|
||||||
freezeSource(c, BytesPerWord, index);
|
freezeSource(c, TargetBytesPerWord, index);
|
||||||
|
|
||||||
ConstantSite next(nextPromise);
|
ConstantSite next(nextPromise);
|
||||||
apply(c, JumpIfGreater, 4, index->source, index->source, 4, &length,
|
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) {
|
if (constant == 0) {
|
||||||
outOfBoundsPromise->offset = a->offset();
|
outOfBoundsPromise->offset = a->offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Assembler::Constant handlerConstant(resolved(c, handler));
|
Assembler::Constant handlerConstant(resolved(c, handler));
|
||||||
a->apply(Call, BytesPerWord, ConstantOperand, &handlerConstant);
|
a->apply(Call, TargetBytesPerWord, ConstantOperand, &handlerConstant);
|
||||||
|
|
||||||
nextPromise->offset = a->offset();
|
nextPromise->offset = a->offset();
|
||||||
}
|
}
|
||||||
@ -6268,7 +6275,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
virtual void save(unsigned footprint, Operand* value) {
|
virtual void save(unsigned footprint, Operand* value) {
|
||||||
c.saved = cons(&c, static_cast<Value*>(value), c.saved);
|
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, footprint == 2);
|
||||||
assert(&c, static_cast<Value*>(value)->nextWord);
|
assert(&c, static_cast<Value*>(value)->nextWord);
|
||||||
|
|
||||||
@ -6329,9 +6336,10 @@ class MyCompiler: public Compiler {
|
|||||||
high = s->next;
|
high = s->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(&c, (BytesPerWord == 8
|
assert(&c, (TargetBytesPerWord == 8
|
||||||
and low->value->nextWord == low->value and high->value == 0)
|
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
|
#endif // not NDEBUG
|
||||||
|
|
||||||
if (bigEndian) {
|
if (bigEndian) {
|
||||||
@ -6355,20 +6363,20 @@ class MyCompiler: public Compiler {
|
|||||||
bool bigEndian = c.arch->bigEndian();
|
bool bigEndian = c.arch->bigEndian();
|
||||||
|
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
unsigned size = BytesPerWord;
|
unsigned size = TargetBytesPerWord;
|
||||||
RUNTIME_ARRAY(Value*, arguments, argumentCount);
|
RUNTIME_ARRAY(Value*, arguments, argumentCount);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
Value* o = va_arg(a, Value*);
|
Value* o = va_arg(a, Value*);
|
||||||
if (o) {
|
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->nextWord;
|
||||||
}
|
}
|
||||||
RUNTIME_ARRAY_BODY(arguments)[index] = o;
|
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;
|
RUNTIME_ARRAY_BODY(arguments)[++index] = o->nextWord;
|
||||||
}
|
}
|
||||||
size = BytesPerWord;
|
size = TargetBytesPerWord;
|
||||||
++ index;
|
++ index;
|
||||||
} else {
|
} else {
|
||||||
size = 8;
|
size = 8;
|
||||||
@ -6427,7 +6435,7 @@ class MyCompiler: public Compiler {
|
|||||||
highIndex = index;
|
highIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
initLocal(1, highIndex, type);
|
initLocal(1, highIndex, type);
|
||||||
Value* next = c.locals[highIndex].value;
|
Value* next = c.locals[highIndex].value;
|
||||||
v->nextWord = next;
|
v->nextWord = next;
|
||||||
@ -6499,7 +6507,7 @@ class MyCompiler: public Compiler {
|
|||||||
virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src,
|
virtual Operand* load(unsigned srcSize, unsigned srcSelectSize, Operand* src,
|
||||||
unsigned dstSize)
|
unsigned dstSize)
|
||||||
{
|
{
|
||||||
assert(&c, dstSize >= BytesPerWord);
|
assert(&c, dstSize >= TargetBytesPerWord);
|
||||||
|
|
||||||
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
||||||
appendMove(&c, Move, srcSize, srcSelectSize, static_cast<Value*>(src),
|
appendMove(&c, Move, srcSize, srcSelectSize, static_cast<Value*>(src),
|
||||||
@ -6510,7 +6518,7 @@ class MyCompiler: public Compiler {
|
|||||||
virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize,
|
virtual Operand* loadz(unsigned srcSize, unsigned srcSelectSize,
|
||||||
Operand* src, unsigned dstSize)
|
Operand* src, unsigned dstSize)
|
||||||
{
|
{
|
||||||
assert(&c, dstSize >= BytesPerWord);
|
assert(&c, dstSize >= TargetBytesPerWord);
|
||||||
|
|
||||||
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
Value* dst = value(&c, static_cast<Value*>(src)->type);
|
||||||
appendMove(&c, MoveZ, srcSize, srcSelectSize, static_cast<Value*>(src),
|
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) {
|
virtual Operand* shl(unsigned size, Operand* a, Operand* b) {
|
||||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||||
Value* result = value(&c, 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);
|
size, static_cast<Value*>(b), size, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -6794,7 +6802,7 @@ class MyCompiler: public Compiler {
|
|||||||
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
|
virtual Operand* shr(unsigned size, Operand* a, Operand* b) {
|
||||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||||
Value* result = value(&c, 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);
|
size, static_cast<Value*>(b), size, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -6803,8 +6811,8 @@ class MyCompiler: public Compiler {
|
|||||||
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
assert(&c, static_cast<Value*>(a)->type == ValueGeneral);
|
||||||
Value* result = value(&c, ValueGeneral);
|
Value* result = value(&c, ValueGeneral);
|
||||||
appendCombine
|
appendCombine
|
||||||
(&c, UnsignedShiftRight, BytesPerWord, static_cast<Value*>(a), size,
|
(&c, UnsignedShiftRight, TargetBytesPerWord, static_cast<Value*>(a),
|
||||||
static_cast<Value*>(b), size, result);
|
size, static_cast<Value*>(b), size, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6933,7 +6941,7 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned poolSize() {
|
virtual unsigned poolSize() {
|
||||||
return c.constantCount * BytesPerWord;
|
return c.constantCount * TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void write() {
|
virtual void write() {
|
||||||
@ -6962,7 +6970,7 @@ class MyCompiler: public Compiler {
|
|||||||
new (n->promise->listen(sizeof(Listener))) Listener(target);
|
new (n->promise->listen(sizeof(Listener))) Listener(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
i += BytesPerWord;
|
i += TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/heap.cpp
11
src/heap.cpp
@ -19,12 +19,6 @@ namespace {
|
|||||||
|
|
||||||
namespace local {
|
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 Top = ~static_cast<unsigned>(0);
|
||||||
|
|
||||||
const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024;
|
const unsigned InitialGen2CapacityInBytes = 4 * 1024 * 1024;
|
||||||
@ -546,11 +540,14 @@ class Fixie {
|
|||||||
return totalSize(size, hasMask);
|
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;
|
uint8_t age;
|
||||||
bool hasMask;
|
bool hasMask;
|
||||||
bool marked;
|
bool marked;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
unsigned size;
|
uint32_t size;
|
||||||
Fixie* next;
|
Fixie* next;
|
||||||
Fixie** handle;
|
Fixie** handle;
|
||||||
uintptr_t body_[0];
|
uintptr_t body_[0];
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
|
|
||||||
namespace vm {
|
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 {
|
class Heap: public Allocator {
|
||||||
public:
|
public:
|
||||||
enum CollectionType {
|
enum CollectionType {
|
||||||
|
@ -665,7 +665,7 @@ store(Thread* t, unsigned index)
|
|||||||
BytesPerWord * 2);
|
BytesPerWord * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExceptionHandler*
|
uint64_t
|
||||||
findExceptionHandler(Thread* t, object method, unsigned ip)
|
findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||||
{
|
{
|
||||||
PROTECT(t, method);
|
PROTECT(t, method);
|
||||||
@ -674,7 +674,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip)
|
|||||||
|
|
||||||
if (eht) {
|
if (eht) {
|
||||||
for (unsigned i = 0; i < exceptionHandlerTableLength(t, eht); ++i) {
|
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)
|
if (ip - 1 >= exceptionHandlerStart(eh)
|
||||||
and ip - 1 < exceptionHandlerEnd(eh))
|
and ip - 1 < exceptionHandlerEnd(eh))
|
||||||
@ -708,7 +708,7 @@ findExceptionHandler(Thread* t, object method, unsigned ip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExceptionHandler*
|
uint64_t
|
||||||
findExceptionHandler(Thread* t, int frame)
|
findExceptionHandler(Thread* t, int frame)
|
||||||
{
|
{
|
||||||
return findExceptionHandler(t, frameMethod(t, frame), frameIp(t, 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);
|
pokeInt(t, t->frame + FrameIpOffset, t->ip);
|
||||||
for (; frame >= base; popFrame(t)) {
|
for (; frame >= base; popFrame(t)) {
|
||||||
ExceptionHandler* eh = findExceptionHandler(t, frame);
|
uint64_t eh = findExceptionHandler(t, frame);
|
||||||
if (eh) {
|
if (eh) {
|
||||||
sp = frame + FrameFootprint;
|
sp = frame + FrameFootprint;
|
||||||
ip = exceptionHandlerIp(eh);
|
ip = exceptionHandlerIp(eh);
|
||||||
|
@ -1143,11 +1143,10 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
addendum,
|
addendum,
|
||||||
class_);
|
class_);
|
||||||
|
|
||||||
|
unsigned size = fieldSize(t, code);
|
||||||
if (flags & ACC_STATIC) {
|
if (flags & ACC_STATIC) {
|
||||||
unsigned size = fieldSize(t, code);
|
while (staticOffset % size) {
|
||||||
unsigned excess = (staticOffset % size) % BytesPerWord;
|
++ staticOffset;
|
||||||
if (excess) {
|
|
||||||
staticOffset += BytesPerWord - excess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldOffset(t, field) = staticOffset;
|
fieldOffset(t, field) = staticOffset;
|
||||||
@ -1162,12 +1161,13 @@ parseFieldTable(Thread* t, Stream& s, object class_, object pool)
|
|||||||
classVmFlags(t, class_) |= HasFinalMemberFlag;
|
classVmFlags(t, class_) |= HasFinalMemberFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (memberOffset % fieldSize(t, code)) {
|
while (memberOffset % size) {
|
||||||
++ memberOffset;
|
++ memberOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldOffset(t, field) = memberOffset;
|
fieldOffset(t, field) = memberOffset;
|
||||||
memberOffset += fieldSize(t, code);
|
|
||||||
|
memberOffset += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, fieldTable, ArrayBody + (i * BytesPerWord), field);
|
set(t, fieldTable, ArrayBody + (i * BytesPerWord), field);
|
||||||
@ -1298,11 +1298,12 @@ parseCode(Thread* t, Stream& s, object pool)
|
|||||||
if (ehtLength) {
|
if (ehtLength) {
|
||||||
object eht = makeExceptionHandlerTable(t, ehtLength);
|
object eht = makeExceptionHandlerTable(t, ehtLength);
|
||||||
for (unsigned i = 0; i < ehtLength; ++i) {
|
for (unsigned i = 0; i < ehtLength; ++i) {
|
||||||
ExceptionHandler* eh = exceptionHandlerTableBody(t, eht, i);
|
unsigned start = s.read2();
|
||||||
exceptionHandlerStart(eh) = s.read2();
|
unsigned end = s.read2();
|
||||||
exceptionHandlerEnd(eh) = s.read2();
|
unsigned ip = s.read2();
|
||||||
exceptionHandlerIp(eh) = s.read2();
|
unsigned catchType = s.read2();
|
||||||
exceptionHandlerCatchType(eh) = s.read2();
|
exceptionHandlerTableBody(t, eht, i) = exceptionHandler
|
||||||
|
(start, end, ip, catchType);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, code, CodeExceptionHandlerTable, eht);
|
set(t, code, CodeExceptionHandlerTable, eht);
|
||||||
@ -1319,9 +1320,9 @@ parseCode(Thread* t, Stream& s, object pool)
|
|||||||
unsigned lntLength = s.read2();
|
unsigned lntLength = s.read2();
|
||||||
object lnt = makeLineNumberTable(t, lntLength);
|
object lnt = makeLineNumberTable(t, lntLength);
|
||||||
for (unsigned i = 0; i < lntLength; ++i) {
|
for (unsigned i = 0; i < lntLength; ++i) {
|
||||||
LineNumber* ln = lineNumberTableBody(t, lnt, i);
|
unsigned ip = s.read2();
|
||||||
lineNumberIp(ln) = s.read2();
|
unsigned line = s.read2();
|
||||||
lineNumberLine(ln) = s.read2();
|
lineNumberTableBody(t, lnt, i) = lineNumber(ip, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
set(t, code, CodeLineNumberTable, lnt);
|
set(t, code, CodeLineNumberTable, lnt);
|
||||||
@ -2217,9 +2218,9 @@ boot(Thread* t)
|
|||||||
|
|
||||||
#include "type-java-initializations.cpp"
|
#include "type-java-initializations.cpp"
|
||||||
|
|
||||||
#ifdef AVIAN_HEAPDUMP
|
//#ifdef AVIAN_HEAPDUMP
|
||||||
# include "type-name-initializations.cpp"
|
# 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_);
|
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;
|
return real;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4426,7 +4437,7 @@ vmAddressFromLine(Thread* t, object m, unsigned line)
|
|||||||
unsigned top = lineNumberTableLength(t, lnt);
|
unsigned top = lineNumberTableLength(t, lnt);
|
||||||
for(unsigned i = bottom; i < top; i++)
|
for(unsigned i = bottom; i < top; i++)
|
||||||
{
|
{
|
||||||
LineNumber* ln = lineNumberTableBody(t, lnt, i);
|
uint64_t ln = lineNumberTableBody(t, lnt, i);
|
||||||
if(lineNumberLine(ln) == line)
|
if(lineNumberLine(ln) == line)
|
||||||
return reinterpret_cast<void*>(lineNumberIp(ln));
|
return reinterpret_cast<void*>(lineNumberIp(ln));
|
||||||
else if(lineNumberLine(ln) > line)
|
else if(lineNumberLine(ln) > line)
|
||||||
|
@ -1253,6 +1253,7 @@ class Machine {
|
|||||||
MonitorMap,
|
MonitorMap,
|
||||||
StringMap,
|
StringMap,
|
||||||
ByteArrayMap,
|
ByteArrayMap,
|
||||||
|
PoolMap,
|
||||||
ClassRuntimeDataTable,
|
ClassRuntimeDataTable,
|
||||||
MethodRuntimeDataTable,
|
MethodRuntimeDataTable,
|
||||||
JNIMethodTable,
|
JNIMethodTable,
|
||||||
@ -3283,14 +3284,20 @@ methodVirtual(Thread* t, object method)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
singletonMaskSize(unsigned count)
|
singletonMaskSize(unsigned count, unsigned bitsPerWord)
|
||||||
{
|
{
|
||||||
if (count) {
|
if (count) {
|
||||||
return ceiling(count + 2, BitsPerWord);
|
return ceiling(count + 2, bitsPerWord);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
singletonMaskSize(unsigned count)
|
||||||
|
{
|
||||||
|
return singletonMaskSize(count, BitsPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
singletonMaskSize(Thread* t, object singleton)
|
singletonMaskSize(Thread* t, object singleton)
|
||||||
{
|
{
|
||||||
@ -3315,11 +3322,17 @@ singletonMask(Thread* t, object singleton)
|
|||||||
(&singletonBody(t, singleton, singletonCount(t, 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
|
inline void
|
||||||
singletonMarkObject(Thread* t, object singleton, unsigned index)
|
singletonMarkObject(Thread* t, object singleton, unsigned index)
|
||||||
{
|
{
|
||||||
singletonMask(t, singleton)[(index + 2) / 32]
|
singletonMarkObject(singletonMask(t, singleton), index);
|
||||||
|= (static_cast<uint32_t>(1) << ((index + 2) % 32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -3370,10 +3383,16 @@ singletonBit(Thread* t, object singleton, unsigned start, unsigned index)
|
|||||||
& (static_cast<uintptr_t>(1) << (index % BitsPerWord))) != 0;
|
& (static_cast<uintptr_t>(1) << (index % BitsPerWord))) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned
|
||||||
|
poolMaskSize(unsigned count, unsigned bitsPerWord)
|
||||||
|
{
|
||||||
|
return ceiling(count, bitsPerWord);
|
||||||
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
poolMaskSize(unsigned count)
|
poolMaskSize(unsigned count)
|
||||||
{
|
{
|
||||||
return ceiling(count, BitsPerWord);
|
return poolMaskSize(count, BitsPerWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned
|
inline unsigned
|
||||||
@ -3766,6 +3785,54 @@ methodClone(Thread* t, object method)
|
|||||||
methodCode(t, 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*
|
inline FILE*
|
||||||
errorLog(Thread* t)
|
errorLog(Thread* t)
|
||||||
{
|
{
|
||||||
|
@ -271,7 +271,7 @@ findLineNumber(Thread* t, object method, unsigned ip)
|
|||||||
unsigned top = lineNumberTableLength(t, lnt);
|
unsigned top = lineNumberTableLength(t, lnt);
|
||||||
for (unsigned span = top - bottom; span; span = top - bottom) {
|
for (unsigned span = top - bottom; span; span = top - bottom) {
|
||||||
unsigned middle = bottom + (span / 2);
|
unsigned middle = bottom + (span / 2);
|
||||||
LineNumber* ln = lineNumberTableBody(t, lnt, middle);
|
uint64_t ln = lineNumberTableBody(t, lnt, middle);
|
||||||
|
|
||||||
if (ip >= lineNumberIp(ln)
|
if (ip >= lineNumberIp(ln)
|
||||||
and (middle + 1 == lineNumberTableLength(t, lnt)
|
and (middle + 1 == lineNumberTableLength(t, lnt)
|
||||||
|
66
src/target.h
Normal file
66
src/target.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* 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;
|
||||||
|
# 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;
|
||||||
|
# else
|
||||||
|
# error
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
typedef uintptr_t target_uintptr_t;
|
||||||
|
typedef intptr_t target_intptr_t;
|
||||||
|
const unsigned TargetBytesPerWord = BytesPerWord;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const unsigned TargetBitsPerWord = TargetBytesPerWord * 8;
|
||||||
|
|
||||||
|
} // namespace vm
|
||||||
|
|
||||||
|
#endif//TARGET_H
|
@ -225,7 +225,6 @@ class Object {
|
|||||||
Scalar,
|
Scalar,
|
||||||
Array,
|
Array,
|
||||||
Method,
|
Method,
|
||||||
Pod,
|
|
||||||
Type,
|
Type,
|
||||||
Pair,
|
Pair,
|
||||||
Number,
|
Number,
|
||||||
@ -314,20 +313,18 @@ class List {
|
|||||||
class Scalar : public Object {
|
class Scalar : public Object {
|
||||||
public:
|
public:
|
||||||
Object* owner;
|
Object* owner;
|
||||||
Object* typeObject;
|
|
||||||
const char* typeName;
|
const char* typeName;
|
||||||
const char* name;
|
const char* name;
|
||||||
unsigned elementSize;
|
unsigned elementSize;
|
||||||
bool noassert;
|
bool noassert;
|
||||||
bool nogc;
|
bool nogc;
|
||||||
|
|
||||||
static Scalar* make(Object* owner, Object* typeObject, const char* typeName,
|
static Scalar* make(Object* owner, const char* typeName, const char* name,
|
||||||
const char* name, unsigned size)
|
unsigned size)
|
||||||
{
|
{
|
||||||
Scalar* o = allocate<Scalar>();
|
Scalar* o = allocate<Scalar>();
|
||||||
o->type = Object::Scalar;
|
o->type = Object::Scalar;
|
||||||
o->owner = owner;
|
o->owner = owner;
|
||||||
o->typeObject = typeObject;
|
|
||||||
o->typeName = typeName;
|
o->typeName = typeName;
|
||||||
o->name = name;
|
o->name = name;
|
||||||
o->elementSize = size;
|
o->elementSize = size;
|
||||||
@ -339,13 +336,12 @@ class Scalar : public Object {
|
|||||||
|
|
||||||
class Array : public Scalar {
|
class Array : public Scalar {
|
||||||
public:
|
public:
|
||||||
static Array* make(Object* owner, Object* typeObject, const char* typeName,
|
static Array* make(Object* owner, const char* typeName, const char* name,
|
||||||
const char* name, unsigned elementSize)
|
unsigned elementSize)
|
||||||
{
|
{
|
||||||
Array* o = allocate<Array>();
|
Array* o = allocate<Array>();
|
||||||
o->type = Object::Array;
|
o->type = Object::Array;
|
||||||
o->owner = owner;
|
o->owner = owner;
|
||||||
o->typeObject = typeObject;
|
|
||||||
o->typeName = typeName;
|
o->typeName = typeName;
|
||||||
o->name = name;
|
o->name = name;
|
||||||
o->elementSize = elementSize;
|
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*
|
const char*
|
||||||
memberTypeName(Object* o)
|
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*&
|
const char*&
|
||||||
memberName(Object* o)
|
memberName(Object* o)
|
||||||
{
|
{
|
||||||
@ -545,7 +539,7 @@ const char*
|
|||||||
typeName(Object* o)
|
typeName(Object* o)
|
||||||
{
|
{
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: case Object::Pod:
|
case Object::Type:
|
||||||
return static_cast<Type*>(o)->name;
|
return static_cast<Type*>(o)->name;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -557,7 +551,7 @@ const char*
|
|||||||
typeJavaName(Object* o)
|
typeJavaName(Object* o)
|
||||||
{
|
{
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: case Object::Pod:
|
case Object::Type:
|
||||||
return static_cast<Type*>(o)->javaName;
|
return static_cast<Type*>(o)->javaName;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -569,7 +563,7 @@ Object*
|
|||||||
typeMembers(Object* o)
|
typeMembers(Object* o)
|
||||||
{
|
{
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: case Object::Pod:
|
case Object::Type:
|
||||||
return static_cast<Type*>(o)->members.first;
|
return static_cast<Type*>(o)->members.first;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -605,10 +599,10 @@ void
|
|||||||
addMember(Object* o, Object* member)
|
addMember(Object* o, Object* member)
|
||||||
{
|
{
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: case Object::Pod:
|
case Object::Type:
|
||||||
if (member->type == Object::Array) {
|
if (member->type == Object::Array) {
|
||||||
static_cast<Type*>(o)->members.append
|
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);
|
static_cast<Type*>(o)->members.append(member);
|
||||||
break;
|
break;
|
||||||
@ -822,7 +816,7 @@ declaration(const char* name, Object* declarations)
|
|||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type: case Object::Pod:
|
case Object::Type:
|
||||||
if (equal(name, typeName(o))) return o;
|
if (equal(name, typeName(o))) return o;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -842,9 +836,6 @@ javaDeclaration(const char* name, Object* declarations)
|
|||||||
if (typeJavaName(o) and equal(name, typeJavaName(o))) return o;
|
if (typeJavaName(o) and equal(name, typeJavaName(o))) return o;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Object::Pod:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: UNREACHABLE;
|
default: UNREACHABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -854,15 +845,11 @@ javaDeclaration(const char* name, Object* declarations)
|
|||||||
Object*
|
Object*
|
||||||
derivationChain(Object* o)
|
derivationChain(Object* o)
|
||||||
{
|
{
|
||||||
if (o->type == Object::Pod) {
|
Object* chain = 0;
|
||||||
return cons(o, 0);
|
for (Object* p = o; p; p = typeSuper(p)) {
|
||||||
} else {
|
chain = cons(p, chain);
|
||||||
Object* chain = 0;
|
|
||||||
for (Object* p = o; p; p = typeSuper(p)) {
|
|
||||||
chain = cons(p, chain);
|
|
||||||
}
|
|
||||||
return chain;
|
|
||||||
}
|
}
|
||||||
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemberIterator {
|
class MemberIterator {
|
||||||
@ -883,7 +870,7 @@ class MemberIterator {
|
|||||||
members(0),
|
members(0),
|
||||||
member(0),
|
member(0),
|
||||||
index_(-1),
|
index_(-1),
|
||||||
offset_(type->type == Object::Pod ? 0 : BytesPerWord),
|
offset_(BytesPerWord),
|
||||||
size_(0),
|
size_(0),
|
||||||
padding_(0),
|
padding_(0),
|
||||||
alignment_(BytesPerWord)
|
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
|
bool
|
||||||
namesPointer(const char* s)
|
namesPointer(const char* s)
|
||||||
{
|
{
|
||||||
@ -996,7 +968,7 @@ namesPointer(const char* s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
sizeOf(const char* type, Object* declarations)
|
sizeOf(const char* type)
|
||||||
{
|
{
|
||||||
if (equal(type, "object")
|
if (equal(type, "object")
|
||||||
or equal(type, "intptr_t") or equal(type, "uintptr_t"))
|
or equal(type, "intptr_t") or equal(type, "uintptr_t"))
|
||||||
@ -1021,33 +993,29 @@ sizeOf(const char* type, Object* declarations)
|
|||||||
} else if (namesPointer(type)) {
|
} else if (namesPointer(type)) {
|
||||||
return BytesPerWord;
|
return BytesPerWord;
|
||||||
} else {
|
} else {
|
||||||
Object* dec = declaration(type, declarations);
|
|
||||||
if (dec) return typeSize(dec);
|
|
||||||
|
|
||||||
fprintf(stderr, "unexpected type: %s\n", type);
|
fprintf(stderr, "unexpected type: %s\n", type);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object*
|
Object*
|
||||||
parseArray(Object* t, Object* p, Object* declarations)
|
parseArray(Object* t, Object* p)
|
||||||
{
|
{
|
||||||
const char* typeName = string(car(p));
|
const char* typeName = string(car(p));
|
||||||
|
|
||||||
p = cdr(p);
|
p = cdr(p);
|
||||||
const char* name = string(car(p));
|
const char* name = string(car(p));
|
||||||
|
|
||||||
return Array::make(t, declaration(typeName, declarations),
|
return Array::make(t, typeName, name, sizeOf(typeName));
|
||||||
typeName, name, sizeOf(typeName, declarations));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object*
|
Object*
|
||||||
parseMember(Object* t, Object* p, Object* declarations);
|
parseMember(Object* t, Object* p);
|
||||||
|
|
||||||
Object*
|
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();) {
|
for (MemberIterator it(t); it.hasMore();) {
|
||||||
Object* m = it.next();
|
Object* m = it.next();
|
||||||
if (equal(memberName(m), memberName(member))) {
|
if (equal(memberName(m), memberName(member))) {
|
||||||
@ -1063,34 +1031,32 @@ parseMember(Object* t, Object* p, Object* declarations, bool* isNew)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object*
|
Object*
|
||||||
parseMember(Object* t, Object* p, Object* declarations)
|
parseMember(Object* t, Object* p)
|
||||||
{
|
{
|
||||||
const char* spec = string(car(p));
|
const char* spec = string(car(p));
|
||||||
if (equal(spec, "array")) {
|
if (equal(spec, "array")) {
|
||||||
return parseArray(t, cdr(p), declarations);
|
return parseArray(t, cdr(p));
|
||||||
} else if (equal(spec, "noassert")) {
|
} else if (equal(spec, "noassert")) {
|
||||||
bool isNew;
|
bool isNew;
|
||||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
Object* member = parseMember(t, cdr(p), &isNew);
|
||||||
memberNoAssert(member) = true;
|
memberNoAssert(member) = true;
|
||||||
return isNew ? member : 0;
|
return isNew ? member : 0;
|
||||||
} else if (equal(spec, "nogc")) {
|
} else if (equal(spec, "nogc")) {
|
||||||
bool isNew;
|
bool isNew;
|
||||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
Object* member = parseMember(t, cdr(p), &isNew);
|
||||||
memberNoGC(member) = true;
|
memberNoGC(member) = true;
|
||||||
return isNew ? member : 0;
|
return isNew ? member : 0;
|
||||||
} else if (equal(spec, "require")) {
|
} else if (equal(spec, "require")) {
|
||||||
bool isNew;
|
bool isNew;
|
||||||
Object* member = parseMember(t, cdr(p), declarations, &isNew);
|
Object* member = parseMember(t, cdr(p), &isNew);
|
||||||
return isNew ? member : 0;
|
return isNew ? member : 0;
|
||||||
} else if (equal(spec, "alias")) {
|
} else if (equal(spec, "alias")) {
|
||||||
bool isNew;
|
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)));
|
memberName(member) = string(car(cdr(p)));
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return Scalar::make(t, declaration(spec, declarations), spec,
|
return Scalar::make(t, spec, string(car(cdr(p))), sizeOf(spec));
|
||||||
string(car(cdr(p))),
|
|
||||||
sizeOf(spec, declarations));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1105,7 +1071,7 @@ parseSubdeclaration(Object* t, Object* p, Object* declarations)
|
|||||||
assert(typeSuper(t));
|
assert(typeSuper(t));
|
||||||
assert(typeSuper(t)->type == Object::Type);
|
assert(typeSuper(t)->type == Object::Type);
|
||||||
} else {
|
} else {
|
||||||
Object* member = parseMember(t, p, declarations);
|
Object* member = parseMember(t, p);
|
||||||
if (member) {
|
if (member) {
|
||||||
addMember(t, member);
|
addMember(t, member);
|
||||||
}
|
}
|
||||||
@ -1297,7 +1263,7 @@ parseJavaClass(Object* type, Stream* s, Object* declarations)
|
|||||||
const char* memberType = fieldType(spec);
|
const char* memberType = fieldType(spec);
|
||||||
|
|
||||||
Object* member = Scalar::make
|
Object* member = Scalar::make
|
||||||
(type, 0, memberType, name, sizeOf(memberType, declarations));
|
(type, memberType, name, sizeOf(memberType));
|
||||||
|
|
||||||
addMember(type, member);
|
addMember(type, member);
|
||||||
}
|
}
|
||||||
@ -1365,7 +1331,7 @@ parseType(Finder* finder, Object::ObjectType type, Object* p,
|
|||||||
if (type == Object::Type) {
|
if (type == Object::Type) {
|
||||||
parseSubdeclaration(t, car(p), declarations);
|
parseSubdeclaration(t, car(p), declarations);
|
||||||
} else {
|
} else {
|
||||||
Object* member = parseMember(t, car(p), declarations);
|
Object* member = parseMember(t, car(p));
|
||||||
if (member) {
|
if (member) {
|
||||||
assert(member->type == Object::Scalar);
|
assert(member->type == Object::Scalar);
|
||||||
addMember(t, member);
|
addMember(t, member);
|
||||||
@ -1390,8 +1356,6 @@ parseDeclaration(Finder* finder, Object* p, Object* declarations)
|
|||||||
const char* spec = string(car(p));
|
const char* spec = string(car(p));
|
||||||
if (equal(spec, "type")) {
|
if (equal(spec, "type")) {
|
||||||
return parseType(finder, Object::Type, cdr(p), declarations);
|
return parseType(finder, Object::Type, cdr(p), declarations);
|
||||||
} else if (equal(spec, "pod")) {
|
|
||||||
return parseType(finder, Object::Pod, cdr(p), declarations);
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "unexpected declaration spec: %s\n", spec);
|
fprintf(stderr, "unexpected declaration spec: %s\n", spec);
|
||||||
abort();
|
abort();
|
||||||
@ -1473,7 +1437,6 @@ void
|
|||||||
writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
||||||
{
|
{
|
||||||
const char* typeName = memberTypeName(member);
|
const char* typeName = memberTypeName(member);
|
||||||
if (memberTypeObject(member)) typeName = capitalize(typeName);
|
|
||||||
|
|
||||||
if (not unsafe) {
|
if (not unsafe) {
|
||||||
out->write("const unsigned ");
|
out->write("const unsigned ");
|
||||||
@ -1491,22 +1454,12 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
out->write("*");
|
out->write("*");
|
||||||
} else {
|
} else {
|
||||||
out->write(typeName);
|
out->write(typeName);
|
||||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
out->write("&");
|
||||||
out->write("*");
|
|
||||||
} else {
|
|
||||||
out->write("&");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out->write("\n");
|
out->write("\n");
|
||||||
writeAccessorName(out, member, unsafe);
|
writeAccessorName(out, member, unsafe);
|
||||||
if (memberOwner(member)->type == Object::Pod) {
|
out->write("(Thread* t UNUSED, object");
|
||||||
out->write("(");
|
|
||||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
|
||||||
out->write("*");
|
|
||||||
} else {
|
|
||||||
out->write("(Thread* t UNUSED, object");
|
|
||||||
}
|
|
||||||
out->write(" o");
|
out->write(" o");
|
||||||
if (member->type != Object::Scalar) {
|
if (member->type != Object::Scalar) {
|
||||||
out->write(", unsigned i");
|
out->write(", unsigned i");
|
||||||
@ -1537,41 +1490,22 @@ writeAccessor(Output* out, Object* member, Object* offset, bool unsafe = false)
|
|||||||
out->write("*");
|
out->write("*");
|
||||||
} else {
|
} else {
|
||||||
out->write(typeName);
|
out->write(typeName);
|
||||||
if (member->type != Object::Scalar and memberTypeObject(member)) {
|
out->write("&");
|
||||||
out->write("*");
|
|
||||||
} else {
|
|
||||||
out->write("&");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out->write(">(reinterpret_cast<uint8_t*>(o)");
|
out->write(">(reinterpret_cast<uint8_t*>(o)");
|
||||||
if (endsWith("[0]", typeName)
|
out->write("[");
|
||||||
or (member->type != Object::Scalar
|
|
||||||
and memberTypeObject(member)))
|
|
||||||
{
|
|
||||||
out->write(" + ");
|
|
||||||
} else {
|
|
||||||
out->write("[");
|
|
||||||
}
|
|
||||||
|
|
||||||
out->write(capitalize(local::typeName(memberOwner(member))));
|
out->write(capitalize(local::typeName(memberOwner(member))));
|
||||||
out->write(capitalize(memberName(member)));
|
out->write(capitalize(memberName(member)));
|
||||||
|
|
||||||
if (member->type != Object::Scalar) {
|
if (member->type != Object::Scalar) {
|
||||||
out->write(" + (i * ");
|
out->write(" + (i * ");
|
||||||
unsigned elementSize = (memberTypeObject(member) ?
|
unsigned elementSize = sizeOf(memberTypeName(member));
|
||||||
typeSize(memberTypeObject(member)) :
|
|
||||||
sizeOf(memberTypeName(member), 0));
|
|
||||||
out->write(elementSize);
|
out->write(elementSize);
|
||||||
out->write(")");
|
out->write(")");
|
||||||
}
|
}
|
||||||
if (not endsWith("[0]", typeName)
|
out->write("]);\n}\n\n");
|
||||||
and (member->type == Object::Scalar
|
|
||||||
or memberTypeObject(member) == 0))
|
|
||||||
{
|
|
||||||
out->write("]");
|
|
||||||
}
|
|
||||||
out->write(");\n}\n\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object*
|
Object*
|
||||||
@ -1615,39 +1549,13 @@ typeOffset(Object* type)
|
|||||||
return typeOffset(0, 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
|
void
|
||||||
writeAccessors(Output* out, Object* declarations)
|
writeAccessors(Output* out, Object* declarations)
|
||||||
{
|
{
|
||||||
for (Object* p = declarations; p; p = cdr(p)) {
|
for (Object* p = declarations; p; p = cdr(p)) {
|
||||||
Object* o = car(p);
|
Object* o = car(p);
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
case Object::Type:
|
case Object::Type: {
|
||||||
case Object::Pod: {
|
|
||||||
Object* offset = typeOffset
|
Object* offset = typeOffset
|
||||||
(o, o->type == Object::Type ? typeSuper(o) : 0);
|
(o, o->type == Object::Type ? typeSuper(o) : 0);
|
||||||
for (MemberIterator it(o, true); it.hasMore();) {
|
for (MemberIterator it(o, true); it.hasMore();) {
|
||||||
@ -2031,15 +1939,6 @@ typeObjectMask(Object* type)
|
|||||||
case Object::Array: {
|
case Object::Array: {
|
||||||
if (memberGC(m)) {
|
if (memberGC(m)) {
|
||||||
set(&mask, offset);
|
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;
|
} break;
|
||||||
|
|
||||||
@ -2207,13 +2106,73 @@ 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));
|
||||||
|
} 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
|
void
|
||||||
usageAndExit(const char* command)
|
usageAndExit(const char* command)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s <classpath> <input file> <output file> "
|
"usage: %s <classpath> <input file> <output file> "
|
||||||
"{enums,declarations,constructors,initializations,"
|
"{enums,declarations,constructors,initializations,"
|
||||||
"java-initializations,name-initializations}\n",
|
"java-initializations,name-initializations,maps}\n",
|
||||||
command);
|
command);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@ -2243,7 +2202,8 @@ main(int ac, char** av)
|
|||||||
or local::equal(av[4], "constructors")
|
or local::equal(av[4], "constructors")
|
||||||
or local::equal(av[4], "initializations")
|
or local::equal(av[4], "initializations")
|
||||||
or local::equal(av[4], "java-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]);
|
local::usageAndExit(av[0]);
|
||||||
}
|
}
|
||||||
@ -2301,7 +2261,6 @@ main(int ac, char** av)
|
|||||||
out.Output::write(local::typeCount(declarations));
|
out.Output::write(local::typeCount(declarations));
|
||||||
out.write(";\n\n");
|
out.write(";\n\n");
|
||||||
|
|
||||||
local::writePods(&out, declarations);
|
|
||||||
local::writeAccessors(&out, declarations);
|
local::writeAccessors(&out, declarations);
|
||||||
local::writeSizes(&out, declarations);
|
local::writeSizes(&out, declarations);
|
||||||
local::writeInitializerDeclarations(&out, declarations);
|
local::writeInitializerDeclarations(&out, declarations);
|
||||||
@ -2315,6 +2274,8 @@ main(int ac, char** av)
|
|||||||
local::writeJavaInitializations(&out, declarations);
|
local::writeJavaInitializations(&out, declarations);
|
||||||
} else if (local::equal(av[4], "name-initializations")) {
|
} else if (local::equal(av[4], "name-initializations")) {
|
||||||
local::writeNameInitializations(&out, declarations);
|
local::writeNameInitializations(&out, declarations);
|
||||||
|
} else if (local::equal(av[4], "maps")) {
|
||||||
|
local::writeMaps(&out, declarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -64,23 +64,13 @@
|
|||||||
|
|
||||||
(type region
|
(type region
|
||||||
(void* region)
|
(void* region)
|
||||||
(unsigned position))
|
(uint32_t position))
|
||||||
|
|
||||||
(pod exceptionHandler
|
|
||||||
(uint16_t start)
|
|
||||||
(uint16_t end)
|
|
||||||
(uint16_t ip)
|
|
||||||
(uint16_t catchType))
|
|
||||||
|
|
||||||
(type exceptionHandlerTable
|
(type exceptionHandlerTable
|
||||||
(array exceptionHandler body))
|
(array uint64_t body))
|
||||||
|
|
||||||
(pod lineNumber
|
|
||||||
(uint32_t ip)
|
|
||||||
(uint32_t line))
|
|
||||||
|
|
||||||
(type lineNumberTable
|
(type lineNumberTable
|
||||||
(array lineNumber body))
|
(array uint64_t body))
|
||||||
|
|
||||||
(type code
|
(type code
|
||||||
(object pool)
|
(object pool)
|
||||||
@ -126,7 +116,7 @@
|
|||||||
|
|
||||||
(type traceElement
|
(type traceElement
|
||||||
(object method)
|
(object method)
|
||||||
(int ip))
|
(int32_t ip))
|
||||||
|
|
||||||
(type treeNode
|
(type treeNode
|
||||||
(object value)
|
(object value)
|
||||||
@ -155,7 +145,7 @@
|
|||||||
(void* waitTail)
|
(void* waitTail)
|
||||||
(object acquireHead)
|
(object acquireHead)
|
||||||
(object acquireTail)
|
(object acquireTail)
|
||||||
(unsigned depth))
|
(uint32_t depth))
|
||||||
|
|
||||||
(type monitorNode
|
(type monitorNode
|
||||||
(void* value)
|
(void* value)
|
||||||
|
289
src/x86.cpp
289
src/x86.cpp
@ -9,6 +9,7 @@
|
|||||||
details. */
|
details. */
|
||||||
|
|
||||||
#include "assembler.h"
|
#include "assembler.h"
|
||||||
|
#include "target.h"
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
|
||||||
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
#define CAST1(x) reinterpret_cast<UnaryOperationType>(x)
|
||||||
@ -60,17 +61,17 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const unsigned GeneralRegisterMask
|
const unsigned GeneralRegisterMask
|
||||||
= BytesPerWord == 4 ? 0x000000ff : 0x0000ffff;
|
= TargetBytesPerWord == 4 ? 0x000000ff : 0x0000ffff;
|
||||||
|
|
||||||
const unsigned FloatRegisterMask
|
const unsigned FloatRegisterMask
|
||||||
= BytesPerWord == 4 ? 0x00ff0000 : 0xffff0000;
|
= TargetBytesPerWord == 4 ? 0x00ff0000 : 0xffff0000;
|
||||||
|
|
||||||
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
|
const unsigned FrameHeaderSize = (UseFramePointer ? 2 : 1);
|
||||||
|
|
||||||
const int LongJumpRegister = r10;
|
const int LongJumpRegister = r10;
|
||||||
|
|
||||||
const unsigned StackAlignmentInBytes = 16;
|
const unsigned StackAlignmentInBytes = 16;
|
||||||
const unsigned StackAlignmentInWords = StackAlignmentInBytes / BytesPerWord;
|
const unsigned StackAlignmentInWords = StackAlignmentInBytes / TargetBytesPerWord;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
isInt8(intptr_t v)
|
isInt8(intptr_t v)
|
||||||
@ -478,7 +479,7 @@ detectFeature(unsigned ecx, unsigned edx);
|
|||||||
bool
|
bool
|
||||||
useSSE(ArchitectureContext* c)
|
useSSE(ArchitectureContext* c)
|
||||||
{
|
{
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
// amd64 implies SSE2 support
|
// amd64 implies SSE2 support
|
||||||
return true;
|
return true;
|
||||||
} else if (c->useNativeFeatures) {
|
} else if (c->useNativeFeatures) {
|
||||||
@ -502,7 +503,7 @@ useSSE(ArchitectureContext* c)
|
|||||||
void maybeRex(Context* c, unsigned size, int a, int index, int base,
|
void maybeRex(Context* c, unsigned size, int a, int index, int base,
|
||||||
bool always)
|
bool always)
|
||||||
{
|
{
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
uint8_t byte;
|
uint8_t byte;
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
byte = REX_W;
|
byte = REX_W;
|
||||||
@ -656,7 +657,7 @@ storeLoadBarrier(Context* c)
|
|||||||
} else {
|
} else {
|
||||||
// lock addq $0x0,(%rsp):
|
// lock addq $0x0,(%rsp):
|
||||||
c->code.append(0xf0);
|
c->code.append(0xf0);
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
c->code.append(0x48);
|
c->code.append(0x48);
|
||||||
}
|
}
|
||||||
c->code.append(0x83);
|
c->code.append(0x83);
|
||||||
@ -746,7 +747,7 @@ callR(Context*, unsigned, Assembler::Register*);
|
|||||||
void
|
void
|
||||||
callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
unconditional(c, 0xe8, a);
|
unconditional(c, 0xe8, a);
|
||||||
}
|
}
|
||||||
@ -754,9 +755,9 @@ callC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
longCallC(Context* c, unsigned size, Assembler::Constant* a)
|
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);
|
Assembler::Register r(LongJumpRegister);
|
||||||
moveCR2(c, size, a, size, &r, 11);
|
moveCR2(c, size, a, size, &r, 11);
|
||||||
callR(c, size, &r);
|
callR(c, size, &r);
|
||||||
@ -768,7 +769,7 @@ longCallC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
maybeRex(c, 4, a);
|
maybeRex(c, 4, a);
|
||||||
opcode(c, 0xff, 0xe0 + regCode(a));
|
opcode(c, 0xff, 0xe0 + regCode(a));
|
||||||
@ -777,7 +778,7 @@ jumpR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
|||||||
void
|
void
|
||||||
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
unconditional(c, 0xe9, a);
|
unconditional(c, 0xe9, a);
|
||||||
}
|
}
|
||||||
@ -785,7 +786,7 @@ jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
maybeRex(c, 4, a);
|
maybeRex(c, 4, a);
|
||||||
opcode(c, 0xff);
|
opcode(c, 0xff);
|
||||||
@ -795,9 +796,9 @@ jumpM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
|||||||
void
|
void
|
||||||
longJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
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);
|
Assembler::Register r(LongJumpRegister);
|
||||||
moveCR2(c, size, a, size, &r, 11);
|
moveCR2(c, size, a, size, &r, 11);
|
||||||
jumpR(c, size, &r);
|
jumpR(c, size, &r);
|
||||||
@ -809,7 +810,7 @@ longJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
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.W has no meaning here so we disable it
|
||||||
maybeRex(c, 4, a);
|
maybeRex(c, 4, a);
|
||||||
@ -819,7 +820,7 @@ callR(Context* c, unsigned size UNUSED, Assembler::Register* a)
|
|||||||
void
|
void
|
||||||
callM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
callM(Context* c, unsigned size UNUSED, Assembler::Memory* a)
|
||||||
{
|
{
|
||||||
assert(c, size == BytesPerWord);
|
assert(c, size == TargetBytesPerWord);
|
||||||
|
|
||||||
maybeRex(c, 4, a);
|
maybeRex(c, 4, a);
|
||||||
opcode(c, 0xff);
|
opcode(c, 0xff);
|
||||||
@ -836,9 +837,9 @@ alignedCallC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
alignedLongCallC(Context* c, unsigned size, Assembler::Constant* a)
|
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)))
|
new (c->zone->allocate(sizeof(AlignmentPadding)))
|
||||||
AlignmentPadding(c, 2, 8);
|
AlignmentPadding(c, 2, 8);
|
||||||
longCallC(c, size, a);
|
longCallC(c, size, a);
|
||||||
@ -857,9 +858,9 @@ alignedJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
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)))
|
new (c->zone->allocate(sizeof(AlignmentPadding)))
|
||||||
AlignmentPadding(c, 2, 8);
|
AlignmentPadding(c, 2, 8);
|
||||||
longJumpC(c, size, a);
|
longJumpC(c, size, a);
|
||||||
@ -871,7 +872,7 @@ alignedLongJumpC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
void
|
void
|
||||||
pushR(Context* c, unsigned size, Assembler::Register* a)
|
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);
|
Assembler::Register ah(a->high);
|
||||||
|
|
||||||
pushR(c, 4, &ah);
|
pushR(c, 4, &ah);
|
||||||
@ -889,7 +890,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
void
|
void
|
||||||
popR(Context* c, unsigned size, Assembler::Register* a)
|
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);
|
Assembler::Register ah(a->high);
|
||||||
|
|
||||||
popR(c, 4, a);
|
popR(c, 4, a);
|
||||||
@ -897,7 +898,7 @@ popR(Context* c, unsigned size, Assembler::Register* a)
|
|||||||
} else {
|
} else {
|
||||||
maybeRex(c, 4, a);
|
maybeRex(c, 4, a);
|
||||||
opcode(c, 0x58 + regCode(a));
|
opcode(c, 0x58 + regCode(a));
|
||||||
if (BytesPerWord == 8 and size == 4) {
|
if (TargetBytesPerWord == 8 and size == 4) {
|
||||||
moveRR(c, 4, a, 8, a);
|
moveRR(c, 4, a, 8, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -910,7 +911,7 @@ addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
void
|
void
|
||||||
negateR(Context* c, unsigned size, Assembler::Register* a)
|
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);
|
assert(c, a->low == rax and a->high == rdx);
|
||||||
|
|
||||||
ResolvedPromise zeroPromise(0);
|
ResolvedPromise zeroPromise(0);
|
||||||
@ -940,7 +941,7 @@ void
|
|||||||
moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
||||||
UNUSED unsigned bSize, Assembler::Register* b, unsigned promiseOffset)
|
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();
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
@ -954,13 +955,13 @@ moveCR2(Context* c, UNUSED unsigned aSize, Assembler::Constant* a,
|
|||||||
moveCR(c, 4, &al, 4, b);
|
moveCR(c, 4, &al, 4, b);
|
||||||
moveCR(c, 4, &ah, 4, &bh);
|
moveCR(c, 4, &ah, 4, &bh);
|
||||||
} else {
|
} else {
|
||||||
maybeRex(c, BytesPerWord, b);
|
maybeRex(c, TargetBytesPerWord, b);
|
||||||
opcode(c, 0xb8 + regCode(b));
|
opcode(c, 0xb8 + regCode(b));
|
||||||
if (a->value->resolved()) {
|
if (a->value->resolved()) {
|
||||||
c->code.appendAddress(a->value->value());
|
c->code.appendAddress(a->value->value());
|
||||||
} else {
|
} else {
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, a->value, offset(c), BytesPerWord, promiseOffset);
|
(c, a->value, offset(c), TargetBytesPerWord, promiseOffset);
|
||||||
c->code.appendAddress(static_cast<uintptr_t>(0));
|
c->code.appendAddress(static_cast<uintptr_t>(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1008,7 +1009,7 @@ void
|
|||||||
sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
sseMoveCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
||||||
unsigned bSize, Assembler::Register* b)
|
unsigned bSize, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize <= BytesPerWord);
|
assert(c, aSize <= TargetBytesPerWord);
|
||||||
Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask));
|
Assembler::Register tmp(c->client->acquireTemporary(GeneralRegisterMask));
|
||||||
moveCR2(c, aSize, a, aSize, &tmp, 0);
|
moveCR2(c, aSize, a, aSize, &tmp, 0);
|
||||||
sseMoveRR(c, aSize, &tmp, bSize, b);
|
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)
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
assert(c, aSize == BytesPerWord);
|
assert(c, aSize == TargetBytesPerWord);
|
||||||
|
|
||||||
alwaysRex(c, aSize, a, b);
|
alwaysRex(c, aSize, a, b);
|
||||||
opcode(c, 0x87);
|
opcode(c, 0x87);
|
||||||
@ -1047,7 +1048,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
return;
|
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 ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1065,11 +1066,11 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
} else {
|
} else {
|
||||||
switch (aSize) {
|
switch (aSize) {
|
||||||
case 1:
|
case 1:
|
||||||
if (BytesPerWord == 4 and a->low > rbx) {
|
if (TargetBytesPerWord == 4 and a->low > rbx) {
|
||||||
assert(c, b->low <= rbx);
|
assert(c, b->low <= rbx);
|
||||||
|
|
||||||
moveRR(c, BytesPerWord, a, BytesPerWord, b);
|
moveRR(c, TargetBytesPerWord, a, TargetBytesPerWord, b);
|
||||||
moveRR(c, 1, b, BytesPerWord, b);
|
moveRR(c, 1, b, TargetBytesPerWord, b);
|
||||||
} else {
|
} else {
|
||||||
alwaysRex(c, aSize, b, a);
|
alwaysRex(c, aSize, b, a);
|
||||||
opcode(c, 0x0f, 0xbe);
|
opcode(c, 0x0f, 0xbe);
|
||||||
@ -1085,7 +1086,7 @@ moveRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (bSize == 8) {
|
if (bSize == 8) {
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
alwaysRex(c, bSize, b, a);
|
alwaysRex(c, bSize, b, a);
|
||||||
opcode(c, 0x63);
|
opcode(c, 0x63);
|
||||||
modrm(c, 0xc0, a, b);
|
modrm(c, 0xc0, a, b);
|
||||||
@ -1125,7 +1126,7 @@ sseMoveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize >= 4);
|
assert(c, aSize >= 4);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
opcode(c, 0xf3);
|
opcode(c, 0xf3);
|
||||||
opcode(c, 0x0f, 0x7e);
|
opcode(c, 0x0f, 0x7e);
|
||||||
modrmSibImm(c, b, a);
|
modrmSibImm(c, b, a);
|
||||||
@ -1160,7 +1161,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
maybeRex(c, bSize, b, a);
|
maybeRex(c, bSize, b, a);
|
||||||
opcode(c, 0x63);
|
opcode(c, 0x63);
|
||||||
modrmSibImm(c, b, a);
|
modrmSibImm(c, b, a);
|
||||||
@ -1179,7 +1180,7 @@ moveMR(Context* c, unsigned aSize, Assembler::Memory* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
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::Memory ah(a->base, a->offset + 4, a->index, a->scale);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1203,7 +1204,7 @@ sseMoveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
assert(c, aSize >= 4);
|
assert(c, aSize >= 4);
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
opcode(c, 0x66);
|
opcode(c, 0x66);
|
||||||
opcode(c, 0x0f, 0xd6);
|
opcode(c, 0x0f, 0xd6);
|
||||||
modrmSibImm(c, a, b);
|
modrmSibImm(c, a, b);
|
||||||
@ -1241,7 +1242,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
maybeRex(c, bSize, a, b);
|
maybeRex(c, bSize, a, b);
|
||||||
opcode(c, 0x89);
|
opcode(c, 0x89);
|
||||||
modrmSibImm(c, a, b);
|
modrmSibImm(c, a, b);
|
||||||
@ -1253,7 +1254,7 @@ moveRM(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
maybeRex(c, bSize, a, b);
|
maybeRex(c, bSize, a, b);
|
||||||
opcode(c, 0x89);
|
opcode(c, 0x89);
|
||||||
modrmSibImm(c, a, b);
|
modrmSibImm(c, a, b);
|
||||||
@ -1274,7 +1275,7 @@ void
|
|||||||
moveAR(Context* c, unsigned aSize, Assembler::Address* a,
|
moveAR(Context* c, unsigned aSize, Assembler::Address* a,
|
||||||
unsigned bSize, Assembler::Register* b)
|
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::Constant constant(a->address);
|
||||||
Assembler::Memory memory(b->low, 0, -1, 0);
|
Assembler::Memory memory(b->low, 0, -1, 0);
|
||||||
@ -1323,7 +1324,7 @@ moveCM(Context* c, unsigned aSize UNUSED, Assembler::Constant* a,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 8: {
|
case 8: {
|
||||||
if (BytesPerWord == 8) {
|
if (TargetBytesPerWord == 8) {
|
||||||
if (a->value->resolved() and isInt32(a->value->value())) {
|
if (a->value->resolved() and isInt32(a->value->value())) {
|
||||||
maybeRex(c, bSize, b);
|
maybeRex(c, bSize, b);
|
||||||
opcode(c, 0xc7);
|
opcode(c, 0xc7);
|
||||||
@ -1370,7 +1371,7 @@ void
|
|||||||
moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a,
|
moveZMR(Context* c, unsigned aSize UNUSED, Assembler::Memory* a,
|
||||||
unsigned bSize UNUSED, Assembler::Register* b)
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, bSize == BytesPerWord);
|
assert(c, bSize == TargetBytesPerWord);
|
||||||
assert(c, aSize == 2);
|
assert(c, aSize == 2);
|
||||||
|
|
||||||
maybeRex(c, bSize, b, a);
|
maybeRex(c, bSize, b, a);
|
||||||
@ -1382,7 +1383,7 @@ void
|
|||||||
addCarryRR(Context* c, unsigned size, Assembler::Register* a,
|
addCarryRR(Context* c, unsigned size, Assembler::Register* a,
|
||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, BytesPerWord == 8 or size == 4);
|
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
maybeRex(c, size, a, b);
|
maybeRex(c, size, a, b);
|
||||||
opcode(c, 0x11);
|
opcode(c, 0x11);
|
||||||
@ -1395,7 +1396,7 @@ addRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
Assembler::Register ah(a->high);
|
Assembler::Register ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1432,7 +1433,7 @@ addCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
if (v) {
|
if (v) {
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
Assembler::Constant ah(&high);
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
@ -1468,7 +1469,7 @@ void
|
|||||||
subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
subtractBorrowCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
|
||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, BytesPerWord == 8 or size == 4);
|
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
if (isInt8(v)) {
|
if (isInt8(v)) {
|
||||||
@ -1491,7 +1492,7 @@ subtractCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
if (v) {
|
if (v) {
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
Assembler::Constant ah(&high);
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
@ -1527,7 +1528,7 @@ void
|
|||||||
subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a,
|
subtractBorrowRR(Context* c, unsigned size, Assembler::Register* a,
|
||||||
Assembler::Register* b)
|
Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, BytesPerWord == 8 or size == 4);
|
assert(c, TargetBytesPerWord == 8 or size == 4);
|
||||||
|
|
||||||
maybeRex(c, size, a, b);
|
maybeRex(c, size, a, b);
|
||||||
opcode(c, 0x19);
|
opcode(c, 0x19);
|
||||||
@ -1540,7 +1541,7 @@ subtractRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
Assembler::Register ah(a->high);
|
Assembler::Register ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1560,7 +1561,7 @@ andRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
Assembler::Register ah(a->high);
|
Assembler::Register ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1581,7 +1582,7 @@ andCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
Assembler::Constant ah(&high);
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
@ -1618,7 +1619,7 @@ orRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
Assembler::Register ah(a->high);
|
Assembler::Register ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1639,7 +1640,7 @@ orCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
if (v) {
|
if (v) {
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
Assembler::Constant ah(&high);
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
@ -1675,7 +1676,7 @@ void
|
|||||||
xorRR(Context* c, unsigned aSize, Assembler::Register* a,
|
xorRR(Context* c, unsigned aSize, Assembler::Register* a,
|
||||||
unsigned bSize UNUSED, Assembler::Register* b)
|
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 ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -1696,7 +1697,7 @@ xorCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
|
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
if (v) {
|
if (v) {
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||||
Assembler::Constant ah(&high);
|
Assembler::Constant ah(&high);
|
||||||
|
|
||||||
@ -1735,7 +1736,7 @@ multiplyRR(Context* c, unsigned aSize, Assembler::Register* a,
|
|||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
|
|
||||||
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
assert(c, b->high == rdx);
|
assert(c, b->high == rdx);
|
||||||
assert(c, b->low != rax);
|
assert(c, b->low != rax);
|
||||||
assert(c, a->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)
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
assert(c, aSize <= BytesPerWord);
|
assert(c, aSize <= TargetBytesPerWord);
|
||||||
|
|
||||||
maybeRex(c, aSize, a, b);
|
maybeRex(c, aSize, a, b);
|
||||||
opcode(c, 0x39);
|
opcode(c, 0x39);
|
||||||
@ -1882,7 +1883,7 @@ compareCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
unsigned bSize, Assembler::Register* b)
|
unsigned bSize, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
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())) {
|
if (a->value->resolved() and isInt32(a->value->value())) {
|
||||||
int64_t v = 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)
|
unsigned bSize UNUSED, Assembler::Memory* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
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);
|
moveRR(c, 4, a, 8, a);
|
||||||
}
|
}
|
||||||
maybeRex(c, bSize, a, b);
|
maybeRex(c, bSize, a, b);
|
||||||
@ -1922,7 +1923,7 @@ compareCM(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
unsigned bSize, Assembler::Memory* b)
|
unsigned bSize, Assembler::Memory* b)
|
||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
assert(c, aSize == bSize);
|
||||||
assert(c, BytesPerWord == 8 or aSize == 4);
|
assert(c, TargetBytesPerWord == 8 or aSize == 4);
|
||||||
|
|
||||||
if (a->value->resolved()) {
|
if (a->value->resolved()) {
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
@ -2048,7 +2049,7 @@ branchRR(Context* c, TernaryOperation op, unsigned size,
|
|||||||
if (isFloatBranch(op)) {
|
if (isFloatBranch(op)) {
|
||||||
compareFloatRR(c, size, a, size, b);
|
compareFloatRR(c, size, a, size, b);
|
||||||
branchFloat(c, op, target);
|
branchFloat(c, op, target);
|
||||||
} else if (size > BytesPerWord) {
|
} else if (size > TargetBytesPerWord) {
|
||||||
Assembler::Register ah(a->high);
|
Assembler::Register ah(a->high);
|
||||||
Assembler::Register bh(b->high);
|
Assembler::Register bh(b->high);
|
||||||
|
|
||||||
@ -2066,7 +2067,7 @@ branchCR(Context* c, TernaryOperation op, unsigned size,
|
|||||||
{
|
{
|
||||||
assert(c, not isFloatBranch(op));
|
assert(c, not isFloatBranch(op));
|
||||||
|
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
ResolvedPromise low(v & ~static_cast<uintptr_t>(0));
|
ResolvedPromise low(v & ~static_cast<uintptr_t>(0));
|
||||||
@ -2090,7 +2091,7 @@ branchRM(Context* c, TernaryOperation op, unsigned size,
|
|||||||
Assembler::Constant* target)
|
Assembler::Constant* target)
|
||||||
{
|
{
|
||||||
assert(c, not isFloatBranch(op));
|
assert(c, not isFloatBranch(op));
|
||||||
assert(c, size <= BytesPerWord);
|
assert(c, size <= TargetBytesPerWord);
|
||||||
|
|
||||||
compareRM(c, size, a, size, b);
|
compareRM(c, size, a, size, b);
|
||||||
branch(c, op, target);
|
branch(c, op, target);
|
||||||
@ -2102,7 +2103,7 @@ branchCM(Context* c, TernaryOperation op, unsigned size,
|
|||||||
Assembler::Constant* target)
|
Assembler::Constant* target)
|
||||||
{
|
{
|
||||||
assert(c, not isFloatBranch(op));
|
assert(c, not isFloatBranch(op));
|
||||||
assert(c, size <= BytesPerWord);
|
assert(c, size <= TargetBytesPerWord);
|
||||||
|
|
||||||
compareCM(c, size, a, size, b);
|
compareCM(c, size, a, size, b);
|
||||||
branch(c, op, target);
|
branch(c, op, target);
|
||||||
@ -2114,7 +2115,7 @@ multiplyCR(Context* c, unsigned aSize, Assembler::Constant* a,
|
|||||||
{
|
{
|
||||||
assert(c, aSize == bSize);
|
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));
|
const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx));
|
||||||
Assembler::Register tmp(c->client->acquireTemporary(mask),
|
Assembler::Register tmp(c->client->acquireTemporary(mask),
|
||||||
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));
|
opcode(c, 0xf7, 0xf8 + regCode(a));
|
||||||
|
|
||||||
Assembler::Register dx(rdx);
|
Assembler::Register dx(rdx);
|
||||||
moveRR(c, BytesPerWord, &dx, BytesPerWord, b);
|
moveRR(c, TargetBytesPerWord, &dx, TargetBytesPerWord, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2194,7 +2195,7 @@ doShift(Context* c, UNUSED void (*shift)
|
|||||||
{
|
{
|
||||||
int64_t v = a->value->value();
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
c->client->save(rcx);
|
c->client->save(rcx);
|
||||||
|
|
||||||
Assembler::Register cx(rcx);
|
Assembler::Register cx(rcx);
|
||||||
@ -2219,7 +2220,7 @@ shiftLeftRR(Context* c, UNUSED unsigned aSize, Assembler::Register* a,
|
|||||||
{
|
{
|
||||||
assert(c, a->low == rcx);
|
assert(c, a->low == rcx);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
// shld
|
// shld
|
||||||
opcode(c, 0x0f, 0xa5);
|
opcode(c, 0x0f, 0xa5);
|
||||||
modrm(c, 0xc0, b->high, b->low);
|
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)
|
unsigned bSize, Assembler::Register* b)
|
||||||
{
|
{
|
||||||
assert(c, a->low == rcx);
|
assert(c, a->low == rcx);
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
// shrd
|
// shrd
|
||||||
opcode(c, 0x0f, 0xad);
|
opcode(c, 0x0f, 0xad);
|
||||||
modrm(c, 0xc0, b->low, b->high);
|
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);
|
assert(c, a->low == rcx);
|
||||||
|
|
||||||
if (BytesPerWord == 4 and bSize == 8) {
|
if (TargetBytesPerWord == 4 and bSize == 8) {
|
||||||
// shrd
|
// shrd
|
||||||
opcode(c, 0x0f, 0xad);
|
opcode(c, 0x0f, 0xad);
|
||||||
modrm(c, 0xc0, b->low, b->high);
|
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);
|
uint8_t* instruction = static_cast<uint8_t*>(*ip);
|
||||||
|
|
||||||
// skip stack overflow check, if present:
|
// skip stack overflow check, if present:
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
if (*start == 0x39) {
|
if (*start == 0x39) {
|
||||||
start += 11;
|
start += 11;
|
||||||
}
|
}
|
||||||
@ -2571,7 +2572,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
|||||||
|
|
||||||
if (UseFramePointer) {
|
if (UseFramePointer) {
|
||||||
// skip preamble
|
// skip preamble
|
||||||
start += (BytesPerWord == 4 ? 3 : 4);
|
start += (TargetBytesPerWord == 4 ? 3 : 4);
|
||||||
|
|
||||||
if (instruction <= start or *instruction == 0x5d) {
|
if (instruction <= start or *instruction == 0x5d) {
|
||||||
*ip = static_cast<void**>(*stack)[1];
|
*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
|
// check for post-non-tail-call stack adjustment of the form "add
|
||||||
// $offset,%rsp":
|
// $offset,%rsp":
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
if ((*instruction == 0x83 or *instruction == 0x81)
|
if ((*instruction == 0x83 or *instruction == 0x81)
|
||||||
and instruction[1] == 0xec)
|
and instruction[1] == 0xec)
|
||||||
{
|
{
|
||||||
offset
|
offset
|
||||||
-= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2))
|
-= (*instruction == 0x83 ? instruction[2] : read4(instruction + 2))
|
||||||
/ BytesPerWord;
|
/ TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
} else if (*instruction == 0x48
|
} else if (*instruction == 0x48
|
||||||
and (instruction[1] == 0x83 or instruction[1] == 0x81)
|
and (instruction[1] == 0x83 or instruction[1] == 0x81)
|
||||||
@ -2610,7 +2611,7 @@ nextFrame(ArchitectureContext* c UNUSED, uint8_t* start, unsigned size UNUSED,
|
|||||||
{
|
{
|
||||||
offset
|
offset
|
||||||
-= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3))
|
-= (instruction[1] == 0x83 ? instruction[3] : read4(instruction + 3))
|
||||||
/ BytesPerWord;
|
/ TargetBytesPerWord;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: check for and handle tail calls
|
// todo: check for and handle tail calls
|
||||||
@ -2773,7 +2774,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual int returnHigh() {
|
virtual int returnHigh() {
|
||||||
return (BytesPerWord == 4 ? rdx : NoRegister);
|
return (TargetBytesPerWord == 4 ? rdx : NoRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int virtualCallTarget() {
|
virtual int virtualCallTarget() {
|
||||||
@ -2807,7 +2808,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned frameFootprint(unsigned footprint) {
|
virtual unsigned frameFootprint(unsigned footprint) {
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef TARGET_PLATFORM_WINDOWS
|
||||||
return max(footprint, StackAlignmentInWords);
|
return max(footprint, StackAlignmentInWords);
|
||||||
#else
|
#else
|
||||||
return max(footprint > argumentRegisterCount() ?
|
return max(footprint > argumentRegisterCount() ?
|
||||||
@ -2829,18 +2830,18 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned argumentRegisterCount() {
|
virtual unsigned argumentRegisterCount() {
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef TARGET_PLATFORM_WINDOWS
|
||||||
if (BytesPerWord == 8) return 4; else
|
if (TargetBytesPerWord == 8) return 4; else
|
||||||
#else
|
#else
|
||||||
if (BytesPerWord == 8) return 6; else
|
if (TargetBytesPerWord == 8) return 6; else
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int argumentRegister(unsigned index) {
|
virtual int argumentRegister(unsigned index) {
|
||||||
assert(&c, BytesPerWord == 8);
|
assert(&c, TargetBytesPerWord == 8);
|
||||||
switch (index) {
|
switch (index) {
|
||||||
#ifdef PLATFORM_WINDOWS
|
#ifdef TARGET_PLATFORM_WINDOWS
|
||||||
case 0:
|
case 0:
|
||||||
return rcx;
|
return rcx;
|
||||||
case 1:
|
case 1:
|
||||||
@ -2913,7 +2914,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
assertAlignment = false;
|
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;
|
uint8_t* instruction = static_cast<uint8_t*>(returnAddress) - 5;
|
||||||
|
|
||||||
assert(&c, ((op == Call or op == LongCall) and *instruction == 0xE8)
|
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) {
|
virtual void setConstant(void* dst, uint64_t constant) {
|
||||||
memcpy(dst, &constant, BytesPerWord);
|
target_uintptr_t v = TARGET_VW(constant);
|
||||||
|
memcpy(dst, &v, TargetBytesPerWord);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||||
@ -3040,7 +3042,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Absolute:
|
case Absolute:
|
||||||
if (aSize <= BytesPerWord) {
|
if (aSize <= TargetBytesPerWord) {
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
*aRegisterMask = (static_cast<uint64_t>(1) << rax);
|
*aRegisterMask = (static_cast<uint64_t>(1) << rax);
|
||||||
} else {
|
} else {
|
||||||
@ -3089,7 +3091,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Float2Int:
|
case Float2Int:
|
||||||
if (useSSE(&c) and bSize <= BytesPerWord) {
|
if (useSSE(&c) and bSize <= TargetBytesPerWord) {
|
||||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
|
*aRegisterMask = (static_cast<uint64_t>(FloatRegisterMask) << 32)
|
||||||
| FloatRegisterMask;
|
| FloatRegisterMask;
|
||||||
@ -3099,7 +3101,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Int2Float:
|
case Int2Float:
|
||||||
if (useSSE(&c) and aSize <= BytesPerWord) {
|
if (useSSE(&c) and aSize <= TargetBytesPerWord) {
|
||||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
*aRegisterMask = GeneralRegisterMask
|
*aRegisterMask = GeneralRegisterMask
|
||||||
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
||||||
@ -3112,7 +3114,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
*aTypeMask = ~0;
|
*aTypeMask = ~0;
|
||||||
*aRegisterMask = ~static_cast<uint64_t>(0);
|
*aRegisterMask = ~static_cast<uint64_t>(0);
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
if (aSize == 4 and bSize == 8) {
|
if (aSize == 4 and bSize == 8) {
|
||||||
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
*aTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
const uint32_t mask
|
const uint32_t mask
|
||||||
@ -3188,7 +3190,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
*bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
*bTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (BytesPerWord == 4) {
|
if (TargetBytesPerWord == 4) {
|
||||||
if (aSize == 4 and bSize == 8) {
|
if (aSize == 4 and bSize == 8) {
|
||||||
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32))
|
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32))
|
||||||
| (static_cast<uint64_t>(1) << rax);
|
| (static_cast<uint64_t>(1) << rax);
|
||||||
@ -3223,7 +3225,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
*tmpRegisterMask = GeneralRegisterMask
|
*tmpRegisterMask = GeneralRegisterMask
|
||||||
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
| (static_cast<uint64_t>(GeneralRegisterMask) << 32);
|
||||||
} else if (dstTypeMask & (1 << RegisterOperand)) {
|
} else if (dstTypeMask & (1 << RegisterOperand)) {
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
// can't move directly from FPR to GPR or vice-versa for
|
// can't move directly from FPR to GPR or vice-versa for
|
||||||
// values larger than the GPR size
|
// values larger than the GPR size
|
||||||
if (dstRegisterMask & FloatRegisterMask) {
|
if (dstRegisterMask & FloatRegisterMask) {
|
||||||
@ -3239,7 +3241,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
if (dstRegisterMask & FloatRegisterMask) {
|
if (dstRegisterMask & FloatRegisterMask) {
|
||||||
// can't move directly from constant to FPR
|
// can't move directly from constant to FPR
|
||||||
*srcTypeMask &= ~(1 << ConstantOperand);
|
*srcTypeMask &= ~(1 << ConstantOperand);
|
||||||
if (size > BytesPerWord) {
|
if (size > TargetBytesPerWord) {
|
||||||
*tmpTypeMask = 1 << MemoryOperand;
|
*tmpTypeMask = 1 << MemoryOperand;
|
||||||
} else {
|
} else {
|
||||||
*tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
*tmpTypeMask = (1 << RegisterOperand) | (1 << MemoryOperand);
|
||||||
@ -3290,7 +3292,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Multiply:
|
case Multiply:
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx));
|
const uint32_t mask = GeneralRegisterMask & ~((1 << rax) | (1 << rdx));
|
||||||
*aRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;
|
*aRegisterMask = (static_cast<uint64_t>(mask) << 32) | mask;
|
||||||
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32)) | mask;
|
*bRegisterMask = (static_cast<uint64_t>(1) << (rdx + 32)) | mask;
|
||||||
@ -3301,7 +3303,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Divide:
|
case Divide:
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
*thunk = true;
|
*thunk = true;
|
||||||
} else {
|
} else {
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
@ -3311,7 +3313,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Remainder:
|
case Remainder:
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (TargetBytesPerWord == 4 and aSize == 8) {
|
||||||
*thunk = true;
|
*thunk = true;
|
||||||
} else {
|
} else {
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
@ -3404,15 +3406,15 @@ class MyAssembler: public Assembler {
|
|||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Memory stackLimit(rbx, stackLimitOffsetFromThread);
|
Memory stackLimit(rbx, stackLimitOffsetFromThread);
|
||||||
Constant handlerConstant(resolved(&c, handler));
|
Constant handlerConstant(resolved(&c, handler));
|
||||||
branchRM(&c, JumpIfGreaterOrEqual, BytesPerWord, &stack, &stackLimit,
|
branchRM(&c, JumpIfGreaterOrEqual, TargetBytesPerWord, &stack, &stackLimit,
|
||||||
&handlerConstant);
|
&handlerConstant);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void saveFrame(unsigned stackOffset, unsigned) {
|
virtual void saveFrame(unsigned stackOffset, unsigned) {
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Memory stackDst(rbx, stackOffset);
|
Memory stackDst(rbx, stackOffset);
|
||||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
apply(Move, TargetBytesPerWord, RegisterOperand, &stack,
|
||||||
BytesPerWord, MemoryOperand, &stackDst);
|
TargetBytesPerWord, MemoryOperand, &stackDst);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void pushFrame(unsigned argumentCount, ...) {
|
virtual void pushFrame(unsigned argumentCount, ...) {
|
||||||
@ -3430,7 +3432,7 @@ class MyAssembler: public Assembler {
|
|||||||
= static_cast<OperandType>(va_arg(a, int));
|
= static_cast<OperandType>(va_arg(a, int));
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*);
|
RUNTIME_ARRAY_BODY(arguments)[i].operand = va_arg(a, Operand*);
|
||||||
footprint += ceiling
|
footprint += ceiling
|
||||||
(RUNTIME_ARRAY_BODY(arguments)[i].size, BytesPerWord);
|
(RUNTIME_ARRAY_BODY(arguments)[i].size, TargetBytesPerWord);
|
||||||
}
|
}
|
||||||
va_end(a);
|
va_end(a);
|
||||||
|
|
||||||
@ -3448,7 +3450,7 @@ class MyAssembler: public Assembler {
|
|||||||
RegisterOperand,
|
RegisterOperand,
|
||||||
&dst);
|
&dst);
|
||||||
} else {
|
} else {
|
||||||
Memory dst(rsp, offset * BytesPerWord);
|
Memory dst(rsp, offset * TargetBytesPerWord);
|
||||||
apply(Move,
|
apply(Move,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
RUNTIME_ARRAY_BODY(arguments)[i].size,
|
||||||
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
RUNTIME_ARRAY_BODY(arguments)[i].type,
|
||||||
@ -3456,7 +3458,8 @@ class MyAssembler: public Assembler {
|
|||||||
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
pad(RUNTIME_ARRAY_BODY(arguments)[i].size),
|
||||||
MemoryOperand,
|
MemoryOperand,
|
||||||
&dst);
|
&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) {
|
if (UseFramePointer) {
|
||||||
Register base(rbp);
|
Register base(rbp);
|
||||||
pushR(&c, BytesPerWord, &base);
|
pushR(&c, TargetBytesPerWord, &base);
|
||||||
|
|
||||||
apply(Move, BytesPerWord, RegisterOperand, &stack,
|
apply(Move, TargetBytesPerWord, RegisterOperand, &stack,
|
||||||
BytesPerWord, RegisterOperand, &base);
|
TargetBytesPerWord, RegisterOperand, &base);
|
||||||
}
|
}
|
||||||
|
|
||||||
Constant footprintConstant(resolved(&c, footprint * BytesPerWord));
|
Constant footprintConstant(resolved(&c, footprint * TargetBytesPerWord));
|
||||||
apply(Subtract, BytesPerWord, ConstantOperand, &footprintConstant,
|
apply(Subtract, TargetBytesPerWord, ConstantOperand, &footprintConstant,
|
||||||
BytesPerWord, RegisterOperand, &stack,
|
TargetBytesPerWord, RegisterOperand, &stack,
|
||||||
BytesPerWord, RegisterOperand, &stack);
|
TargetBytesPerWord, RegisterOperand, &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void adjustFrame(unsigned difference) {
|
virtual void adjustFrame(unsigned difference) {
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Constant differenceConstant(resolved(&c, difference * BytesPerWord));
|
Constant differenceConstant(resolved(&c, difference * TargetBytesPerWord));
|
||||||
apply(Subtract, BytesPerWord, ConstantOperand, &differenceConstant,
|
apply(Subtract, TargetBytesPerWord, ConstantOperand, &differenceConstant,
|
||||||
BytesPerWord, RegisterOperand, &stack,
|
TargetBytesPerWord, RegisterOperand, &stack,
|
||||||
BytesPerWord, RegisterOperand, &stack);
|
TargetBytesPerWord, RegisterOperand, &stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void popFrame(unsigned frameFootprint) {
|
virtual void popFrame(unsigned frameFootprint) {
|
||||||
if (UseFramePointer) {
|
if (UseFramePointer) {
|
||||||
Register base(rbp);
|
Register base(rbp);
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
apply(Move, BytesPerWord, RegisterOperand, &base,
|
apply(Move, TargetBytesPerWord, RegisterOperand, &base,
|
||||||
BytesPerWord, RegisterOperand, &stack);
|
TargetBytesPerWord, RegisterOperand, &stack);
|
||||||
|
|
||||||
popR(&c, BytesPerWord, &base);
|
popR(&c, TargetBytesPerWord, &base);
|
||||||
} else {
|
} else {
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Constant footprint(resolved(&c, frameFootprint * BytesPerWord));
|
Constant footprint(resolved(&c, frameFootprint * TargetBytesPerWord));
|
||||||
apply(Add, BytesPerWord, ConstantOperand, &footprint,
|
apply(Add, TargetBytesPerWord, ConstantOperand, &footprint,
|
||||||
BytesPerWord, RegisterOperand, &stack,
|
TargetBytesPerWord, RegisterOperand, &stack,
|
||||||
BytesPerWord, RegisterOperand, &stack);
|
TargetBytesPerWord, RegisterOperand, &stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3515,40 +3518,44 @@ class MyAssembler: public Assembler {
|
|||||||
unsigned baseSize = UseFramePointer ? 1 : 0;
|
unsigned baseSize = UseFramePointer ? 1 : 0;
|
||||||
|
|
||||||
Memory returnAddressSrc
|
Memory returnAddressSrc
|
||||||
(rsp, (frameFootprint + baseSize) * BytesPerWord);
|
(rsp, (frameFootprint + baseSize) * TargetBytesPerWord);
|
||||||
moveMR(&c, BytesPerWord, &returnAddressSrc, BytesPerWord, &tmp);
|
moveMR(&c, TargetBytesPerWord, &returnAddressSrc, TargetBytesPerWord,
|
||||||
|
&tmp);
|
||||||
|
|
||||||
Memory returnAddressDst
|
Memory returnAddressDst
|
||||||
(rsp, (frameFootprint - offset + baseSize) * BytesPerWord);
|
(rsp, (frameFootprint - offset + baseSize) * TargetBytesPerWord);
|
||||||
moveRM(&c, BytesPerWord, &tmp, BytesPerWord, &returnAddressDst);
|
moveRM(&c, TargetBytesPerWord, &tmp, TargetBytesPerWord,
|
||||||
|
&returnAddressDst);
|
||||||
|
|
||||||
c.client->releaseTemporary(tmp.low);
|
c.client->releaseTemporary(tmp.low);
|
||||||
|
|
||||||
if (UseFramePointer) {
|
if (UseFramePointer) {
|
||||||
Memory baseSrc(rsp, frameFootprint * BytesPerWord);
|
Memory baseSrc(rsp, frameFootprint * TargetBytesPerWord);
|
||||||
Register base(rbp);
|
Register base(rbp);
|
||||||
moveMR(&c, BytesPerWord, &baseSrc, BytesPerWord, &base);
|
moveMR(&c, TargetBytesPerWord, &baseSrc, TargetBytesPerWord, &base);
|
||||||
}
|
}
|
||||||
|
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Constant footprint
|
Constant footprint
|
||||||
(resolved(&c, (frameFootprint - offset + baseSize) * BytesPerWord));
|
(resolved
|
||||||
addCR(&c, BytesPerWord, &footprint, BytesPerWord, &stack);
|
(&c, (frameFootprint - offset + baseSize) * TargetBytesPerWord));
|
||||||
|
|
||||||
|
addCR(&c, TargetBytesPerWord, &footprint, TargetBytesPerWord, &stack);
|
||||||
|
|
||||||
if (returnAddressSurrogate != NoRegister) {
|
if (returnAddressSurrogate != NoRegister) {
|
||||||
assert(&c, offset > 0);
|
assert(&c, offset > 0);
|
||||||
|
|
||||||
Register ras(returnAddressSurrogate);
|
Register ras(returnAddressSurrogate);
|
||||||
Memory dst(rsp, offset * BytesPerWord);
|
Memory dst(rsp, offset * TargetBytesPerWord);
|
||||||
moveRM(&c, BytesPerWord, &ras, BytesPerWord, &dst);
|
moveRM(&c, TargetBytesPerWord, &ras, TargetBytesPerWord, &dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framePointerSurrogate != NoRegister) {
|
if (framePointerSurrogate != NoRegister) {
|
||||||
assert(&c, offset > 0);
|
assert(&c, offset > 0);
|
||||||
|
|
||||||
Register fps(framePointerSurrogate);
|
Register fps(framePointerSurrogate);
|
||||||
Memory dst(rsp, (offset - 1) * BytesPerWord);
|
Memory dst(rsp, (offset - 1) * TargetBytesPerWord);
|
||||||
moveRM(&c, BytesPerWord, &fps, BytesPerWord, &dst);
|
moveRM(&c, TargetBytesPerWord, &fps, TargetBytesPerWord, &dst);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
popFrame(frameFootprint);
|
popFrame(frameFootprint);
|
||||||
@ -3568,15 +3575,15 @@ class MyAssembler: public Assembler {
|
|||||||
|
|
||||||
if (TailCalls and argumentFootprint > StackAlignmentInWords) {
|
if (TailCalls and argumentFootprint > StackAlignmentInWords) {
|
||||||
Register returnAddress(rcx);
|
Register returnAddress(rcx);
|
||||||
popR(&c, BytesPerWord, &returnAddress);
|
popR(&c, TargetBytesPerWord, &returnAddress);
|
||||||
|
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Constant adjustment
|
Constant adjustment
|
||||||
(resolved(&c, (argumentFootprint - StackAlignmentInWords)
|
(resolved(&c, (argumentFootprint - StackAlignmentInWords)
|
||||||
* BytesPerWord));
|
* TargetBytesPerWord));
|
||||||
addCR(&c, BytesPerWord, &adjustment, BytesPerWord, &stack);
|
addCR(&c, TargetBytesPerWord, &adjustment, TargetBytesPerWord, &stack);
|
||||||
|
|
||||||
jumpR(&c, BytesPerWord, &returnAddress);
|
jumpR(&c, TargetBytesPerWord, &returnAddress);
|
||||||
} else {
|
} else {
|
||||||
return_(&c);
|
return_(&c);
|
||||||
}
|
}
|
||||||
@ -3588,13 +3595,13 @@ class MyAssembler: public Assembler {
|
|||||||
popFrame(frameFootprint);
|
popFrame(frameFootprint);
|
||||||
|
|
||||||
Register returnAddress(rcx);
|
Register returnAddress(rcx);
|
||||||
popR(&c, BytesPerWord, &returnAddress);
|
popR(&c, TargetBytesPerWord, &returnAddress);
|
||||||
|
|
||||||
Register stack(rsp);
|
Register stack(rsp);
|
||||||
Memory stackSrc(rbx, stackOffsetFromThread);
|
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) {
|
virtual void apply(Operation op) {
|
||||||
@ -3624,7 +3631,7 @@ class MyAssembler: public Assembler {
|
|||||||
{
|
{
|
||||||
if (isBranch(op)) {
|
if (isBranch(op)) {
|
||||||
assert(&c, aSize == bSize);
|
assert(&c, aSize == bSize);
|
||||||
assert(&c, cSize == BytesPerWord);
|
assert(&c, cSize == TargetBytesPerWord);
|
||||||
assert(&c, cType == ConstantOperand);
|
assert(&c, cType == ConstantOperand);
|
||||||
|
|
||||||
arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]
|
arch_->c.branchOperations[branchIndex(&(arch_->c), aType, bType)]
|
||||||
|
Loading…
Reference in New Issue
Block a user