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