mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
progress towards refactored JIT compiler to support PowerPC and data flow analysis across control flow boundaries
This commit is contained in:
parent
9908bbcf50
commit
a062d8c975
@ -173,7 +173,9 @@ class Assembler {
|
|||||||
virtual int stack() = 0;
|
virtual int stack() = 0;
|
||||||
virtual int thread() = 0;
|
virtual int thread() = 0;
|
||||||
virtual int returnLow() = 0;
|
virtual int returnLow() = 0;
|
||||||
virtual int returnHigh() = 0;
|
virtual int returnHigh() = 0;
|
||||||
|
|
||||||
|
virtual bool reserved(int register_) = 0;
|
||||||
|
|
||||||
virtual unsigned argumentRegisterCount() = 0;
|
virtual unsigned argumentRegisterCount() = 0;
|
||||||
virtual int argumentRegister(unsigned index) = 0;
|
virtual int argumentRegister(unsigned index) = 0;
|
||||||
@ -214,6 +216,8 @@ class Assembler {
|
|||||||
|
|
||||||
virtual void setClient(Client* client) = 0;
|
virtual void setClient(Client* client) = 0;
|
||||||
|
|
||||||
|
virtual Architecture* arch() = 0;
|
||||||
|
|
||||||
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset);
|
virtual void saveFrame(unsigned stackOffset, unsigned baseOffset);
|
||||||
virtual void pushFrame(unsigned argumentCount, ...);
|
virtual void pushFrame(unsigned argumentCount, ...);
|
||||||
virtual void popFrame();
|
virtual void popFrame();
|
||||||
|
@ -350,8 +350,6 @@ alignedFrameSizeWithParameters(MyThread* t, object method)
|
|||||||
int
|
int
|
||||||
localOffset(MyThread* t, int v, object method)
|
localOffset(MyThread* t, int v, object method)
|
||||||
{
|
{
|
||||||
return alignedFrameSize(t, method) - t->arch->frameHeaderSize() - v;
|
|
||||||
|
|
||||||
int parameterFootprint = methodParameterFootprint(t, method) * BytesPerWord;
|
int parameterFootprint = methodParameterFootprint(t, method) * BytesPerWord;
|
||||||
|
|
||||||
v *= BytesPerWord;
|
v *= BytesPerWord;
|
||||||
@ -3858,7 +3856,8 @@ compile(MyThread* t, Context* context)
|
|||||||
|
|
||||||
unsigned footprint = methodParameterFootprint(t, context->method);
|
unsigned footprint = methodParameterFootprint(t, context->method);
|
||||||
unsigned locals = localSize(t, context->method);
|
unsigned locals = localSize(t, context->method);
|
||||||
c->init(codeLength(t, methodCode(t, context->method)), footprint, locals);
|
c->init(codeLength(t, methodCode(t, context->method)), footprint, locals,
|
||||||
|
codeMaxStack(t, methodCode(t, context->method)));
|
||||||
|
|
||||||
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
|
uint8_t stackMap[codeMaxStack(t, methodCode(t, context->method))];
|
||||||
Frame frame(context, stackMap);
|
Frame frame(context, stackMap);
|
||||||
|
414
src/compiler.cpp
414
src/compiler.cpp
@ -20,6 +20,9 @@ const bool DebugCompile = false;
|
|||||||
const bool DebugStack = false;
|
const bool DebugStack = false;
|
||||||
const bool DebugRegisters = false;
|
const bool DebugRegisters = false;
|
||||||
|
|
||||||
|
const int AnyFrameIndex = -2;
|
||||||
|
const int NoFrameIndex = -1;
|
||||||
|
|
||||||
class Context;
|
class Context;
|
||||||
class Value;
|
class Value;
|
||||||
class Stack;
|
class Stack;
|
||||||
@ -53,6 +56,14 @@ enum ConstantCompare {
|
|||||||
CompareEqual
|
CompareEqual
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Cell {
|
||||||
|
public:
|
||||||
|
Cell(Cell* next, void* value): next(next), value(value) { }
|
||||||
|
|
||||||
|
Cell* next;
|
||||||
|
void* value;
|
||||||
|
};
|
||||||
|
|
||||||
class Site {
|
class Site {
|
||||||
public:
|
public:
|
||||||
Site(): next(0) { }
|
Site(): next(0) { }
|
||||||
@ -62,6 +73,8 @@ class Site {
|
|||||||
virtual Site* readTarget(Context*, Read*) { return this; }
|
virtual Site* readTarget(Context*, Read*) { return this; }
|
||||||
|
|
||||||
virtual unsigned copyCost(Context*, Site*) = 0;
|
virtual unsigned copyCost(Context*, Site*) = 0;
|
||||||
|
|
||||||
|
virtual bool match(Context*, uint8_t, uint64_t, int) = 0;
|
||||||
|
|
||||||
virtual void acquire(Context*, Stack*, Value**, unsigned, Value*) { }
|
virtual void acquire(Context*, Stack*, Value**, unsigned, Value*) { }
|
||||||
|
|
||||||
@ -78,7 +91,7 @@ class Site {
|
|||||||
Site* next;
|
Site* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Stack: public StackElement {
|
class Stack: public Compiler::StackElement {
|
||||||
public:
|
public:
|
||||||
Stack(unsigned index, Value* value, Stack* next):
|
Stack(unsigned index, Value* value, Stack* next):
|
||||||
index(index), value(value), next(next)
|
index(index), value(value), next(next)
|
||||||
@ -109,7 +122,7 @@ class LogicalInstruction {
|
|||||||
LogicalInstruction* immediatePredecessor;
|
LogicalInstruction* immediatePredecessor;
|
||||||
Stack* stack;
|
Stack* stack;
|
||||||
Value** locals;
|
Value** locals;
|
||||||
unsigned machineOffset;
|
Promise* machineOffset;
|
||||||
bool stackSaved;
|
bool stackSaved;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -193,17 +206,18 @@ class Context {
|
|||||||
Compiler::Client* client):
|
Compiler::Client* client):
|
||||||
system(system),
|
system(system),
|
||||||
assembler(assembler),
|
assembler(assembler),
|
||||||
|
arch(assembler->arch()),
|
||||||
zone(zone),
|
zone(zone),
|
||||||
client(client),
|
client(client),
|
||||||
logicalIp(-1),
|
logicalIp(-1),
|
||||||
state(new (zone->allocate(sizeof(State))) State(0, 0)),
|
state(new (zone->allocate(sizeof(State))) State(0, 0, 0)),
|
||||||
logicalCode(0),
|
logicalCode(0),
|
||||||
logicalCodeLength(0),
|
logicalCodeLength(0),
|
||||||
parameterFootprint(0),
|
parameterFootprint(0),
|
||||||
localFootprint(0),
|
localFootprint(0),
|
||||||
registers
|
registers
|
||||||
(static_cast<Register**>
|
(static_cast<Register**>
|
||||||
(zone->allocate(sizeof(Register*) * assembler->registerCount()))),
|
(zone->allocate(sizeof(Register*) * arch->registerCount()))),
|
||||||
firstConstant(0),
|
firstConstant(0),
|
||||||
lastConstant(0),
|
lastConstant(0),
|
||||||
constantCount(0),
|
constantCount(0),
|
||||||
@ -215,17 +229,15 @@ class Context {
|
|||||||
pass(ScanPass),
|
pass(ScanPass),
|
||||||
stackPadding(0)
|
stackPadding(0)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < assembler->registerCount(); ++i) {
|
for (unsigned i = 0; i < arch->registerCount(); ++i) {
|
||||||
registers[i] = new (zone->allocate(sizeof(Register))) Register(i);
|
registers[i] = new (zone->allocate(sizeof(Register))) Register(i);
|
||||||
|
registers[i]->reserved = arch->reserved(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
registers[assembler->base()]->reserved = true;
|
|
||||||
registers[assembler->stack()]->reserved = true;
|
|
||||||
registers[assembler->thread()]->reserved = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
System* system;
|
System* system;
|
||||||
Assembler* assembler;
|
Assembler* assembler;
|
||||||
|
Assembler::Architecture* arch;
|
||||||
Zone* zone;
|
Zone* zone;
|
||||||
Compiler::Client* client;
|
Compiler::Client* client;
|
||||||
int logicalIp;
|
int logicalIp;
|
||||||
@ -234,6 +246,7 @@ class Context {
|
|||||||
unsigned logicalCodeLength;
|
unsigned logicalCodeLength;
|
||||||
unsigned parameterFootprint;
|
unsigned parameterFootprint;
|
||||||
unsigned localFootprint;
|
unsigned localFootprint;
|
||||||
|
unsigned maxStackFootprint;
|
||||||
Register** registers;
|
Register** registers;
|
||||||
ConstantPoolNode* firstConstant;
|
ConstantPoolNode* firstConstant;
|
||||||
ConstantPoolNode* lastConstant;
|
ConstantPoolNode* lastConstant;
|
||||||
@ -338,8 +351,9 @@ expect(Context* c, bool v)
|
|||||||
class Event {
|
class Event {
|
||||||
public:
|
public:
|
||||||
Event(Context* c):
|
Event(Context* c):
|
||||||
next(0), stack(c->state->stack), locals(c->locals), promises(0), reads(0),
|
next(0), stack(c->state->stack), locals(c->state->locals), promises(0),
|
||||||
readCount(0), sequence(c->nextSequence++), stackReset(c->stackReset)
|
reads(0), readCount(0), sequence(c->nextSequence++),
|
||||||
|
stackReset(c->stackReset)
|
||||||
{
|
{
|
||||||
assert(c, c->logicalIp >= 0);
|
assert(c, c->logicalIp >= 0);
|
||||||
|
|
||||||
@ -357,7 +371,7 @@ class Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Event(Context*, unsigned sequence, Stack* stack, Local* locals):
|
Event(Context*, unsigned sequence, Stack* stack, Value** locals):
|
||||||
next(0), stack(stack), locals(locals), promises(0), reads(0), readCount(0),
|
next(0), stack(stack), locals(locals), promises(0), reads(0), readCount(0),
|
||||||
sequence(sequence), stackReset(false)
|
sequence(sequence), stackReset(false)
|
||||||
{ }
|
{ }
|
||||||
@ -376,16 +390,30 @@ class Event {
|
|||||||
bool stackReset;
|
bool stackReset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
alignedFrameSize(Context* c)
|
||||||
|
{
|
||||||
|
return c->arch->alignFrameSize
|
||||||
|
(c->localFootprint
|
||||||
|
- c->parameterFootprint
|
||||||
|
+ c->maxStackFootprint);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
localOffset(Context* c, int v)
|
localOffset(Context* c, int v)
|
||||||
{
|
{
|
||||||
int parameterFootprint = c->parameterFootprint * BytesPerWord;
|
int parameterFootprint = c->parameterFootprint * BytesPerWord;
|
||||||
|
int frameSize = alignedFrameSize(c) * BytesPerWord;
|
||||||
|
|
||||||
v *= BytesPerWord;
|
v *= BytesPerWord;
|
||||||
if (v < parameterFootprint) {
|
if (v < parameterFootprint) {
|
||||||
return (parameterFootprint - v - BytesPerWord) + (BytesPerWord * 2);
|
return frameSize
|
||||||
|
+ parameterFootprint
|
||||||
|
+ c->arch->frameFooterSize()
|
||||||
|
+ c->arch->frameHeaderSize()
|
||||||
|
- v;
|
||||||
} else {
|
} else {
|
||||||
return -(v + BytesPerWord - parameterFootprint);
|
return frameSize - c->arch->frameHeaderSize() - v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -480,6 +508,10 @@ class ConstantSite: public Site {
|
|||||||
return (s == this ? 0 : 1);
|
return (s == this ? 0 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool match(Context*, uint8_t typeMask, uint64_t, int) {
|
||||||
|
return typeMask & (1 << ConstantOperand);
|
||||||
|
}
|
||||||
|
|
||||||
virtual OperandType type(Context*) {
|
virtual OperandType type(Context*) {
|
||||||
return ConstantOperand;
|
return ConstantOperand;
|
||||||
}
|
}
|
||||||
@ -518,6 +550,10 @@ class AddressSite: public Site {
|
|||||||
return (s == this ? 0 : 3);
|
return (s == this ? 0 : 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool match(Context*, uint8_t typeMask, uint64_t, int) {
|
||||||
|
return typeMask & (1 << AddressOperand);
|
||||||
|
}
|
||||||
|
|
||||||
virtual OperandType type(Context*) {
|
virtual OperandType type(Context*) {
|
||||||
return AddressOperand;
|
return AddressOperand;
|
||||||
}
|
}
|
||||||
@ -563,8 +599,8 @@ void
|
|||||||
release(Context* c, Register* r);
|
release(Context* c, Register* r);
|
||||||
|
|
||||||
Register*
|
Register*
|
||||||
validate(Context* c, uint32_t mask, Stack* stack, unsigned size,
|
validate(Context* c, uint32_t mask, Stack* stack, Value** locals,
|
||||||
Value* value, RegisterSite* site, Register* current);
|
unsigned size, Value* value, RegisterSite* site, Register* current);
|
||||||
|
|
||||||
class RegisterSite: public Site {
|
class RegisterSite: public Site {
|
||||||
public:
|
public:
|
||||||
@ -597,6 +633,19 @@ class RegisterSite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool match(Context* c, uint8_t typeMask, uint64_t registerMask, int)
|
||||||
|
{
|
||||||
|
if ((typeMask & (1 << RegisterOperand)) and low) {
|
||||||
|
sync(c);
|
||||||
|
return ((static_cast<uint64_t>(1) << register_.low) & registerMask)
|
||||||
|
and (register_.high == NoRegister
|
||||||
|
or ((static_cast<uint64_t>(1) << (register_.high + 32))
|
||||||
|
& registerMask));
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void acquire(Context* c, Stack* stack, Value** locals, unsigned size,
|
virtual void acquire(Context* c, Stack* stack, Value** locals, unsigned size,
|
||||||
Value* v)
|
Value* v)
|
||||||
{
|
{
|
||||||
@ -654,9 +703,9 @@ RegisterSite*
|
|||||||
registerSite(Context* c, int low, int high = NoRegister)
|
registerSite(Context* c, int low, int high = NoRegister)
|
||||||
{
|
{
|
||||||
assert(c, low != NoRegister);
|
assert(c, low != NoRegister);
|
||||||
assert(c, low < static_cast<int>(c->assembler->registerCount()));
|
assert(c, low < static_cast<int>(c->arch->registerCount()));
|
||||||
assert(c, high == NoRegister
|
assert(c, high == NoRegister
|
||||||
or high < static_cast<int>(c->assembler->registerCount()));
|
or high < static_cast<int>(c->arch->registerCount()));
|
||||||
|
|
||||||
Register* hr;
|
Register* hr;
|
||||||
if (high == NoRegister) {
|
if (high == NoRegister) {
|
||||||
@ -720,7 +769,7 @@ decrement(Context* c UNUSED, Register* r)
|
|||||||
class MemorySite: public Site {
|
class MemorySite: public Site {
|
||||||
public:
|
public:
|
||||||
MemorySite(int base, int offset, int index, unsigned scale):
|
MemorySite(int base, int offset, int index, unsigned scale):
|
||||||
base(0), index(0), offsetPromise(0), value(base, offset, index, scale)
|
base(0), index(0), value(base, offset, index, scale)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void sync(Context* c UNUSED) {
|
void sync(Context* c UNUSED) {
|
||||||
@ -747,6 +796,22 @@ class MemorySite: public Site {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool match(Context* c, uint8_t typeMask, uint64_t, int frameIndex) {
|
||||||
|
if (typeMask & (1 << MemoryOperand)) {
|
||||||
|
sync(c);
|
||||||
|
if (value.base == c->arch->stack()) {
|
||||||
|
assert(c, value.index == NoRegister);
|
||||||
|
return frameIndex == AnyFrameIndex
|
||||||
|
|| (frameIndex != NoFrameIndex
|
||||||
|
&& localOffset(c, frameIndex) == value.offset);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual void acquire(Context* c, Stack*, Value**, unsigned, Value*) {
|
virtual void acquire(Context* c, Stack*, Value**, unsigned, Value*) {
|
||||||
base = increment(c, value.base);
|
base = increment(c, value.base);
|
||||||
if (value.index != NoRegister) {
|
if (value.index != NoRegister) {
|
||||||
@ -783,6 +848,13 @@ memorySite(Context* c, int base, int offset = 0, int index = NoRegister,
|
|||||||
MemorySite(base, offset, index, scale);
|
MemorySite(base, offset, index, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemorySite*
|
||||||
|
frameSite(Context* c, int frameIndex)
|
||||||
|
{
|
||||||
|
assert(c, frameIndex >= 0);
|
||||||
|
return memorySite(c, c->arch->stack(), localOffset(c, frameIndex));
|
||||||
|
}
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
targetOrNull(Context* c, Value* v, Read* r)
|
targetOrNull(Context* c, Value* v, Read* r)
|
||||||
{
|
{
|
||||||
@ -801,6 +873,7 @@ targetOrNull(Context* c, Value* v)
|
|||||||
if (v->target) {
|
if (v->target) {
|
||||||
return v->target;
|
return v->target;
|
||||||
} else if (live(v)) {
|
} else if (live(v)) {
|
||||||
|
Read* r = v->reads;
|
||||||
Site* s = r->pickSite(c, v);
|
Site* s = r->pickSite(c, v);
|
||||||
if (s) return s;
|
if (s) return s;
|
||||||
return r->allocateSite(c);
|
return r->allocateSite(c);
|
||||||
@ -839,70 +912,13 @@ allocateSite(Context* c, uint8_t typeMask, uint64_t registerMask,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TargetRead: public Read {
|
|
||||||
public:
|
|
||||||
TargetRead(Value* target, uint8_t typeMask, uint64_t registerMask,
|
|
||||||
int frameIndex):
|
|
||||||
target(target), registerMask(registerMask), typeMask(typeMask),
|
|
||||||
frameIndex(frameIndex)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual Site* pickSite(Context* c, Value* value) {
|
|
||||||
return ::pickSite(c, value, typeMask, registerMask, frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Site* allocateSite(Context* c) {
|
|
||||||
if (target) {
|
|
||||||
Site* s = targetOrNull(c, target);
|
|
||||||
if (s and s->match(c, typeMask, registerMask, frameIndex)) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ::allocateSite(c, typeMask, registerMask, frameIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void intersect(uint8_t* typeMask, uint64_t* registerMask,
|
|
||||||
int* frameIndex)
|
|
||||||
{
|
|
||||||
*typeMask &= this->typeMask;
|
|
||||||
*registerMask &= this->registerMask;
|
|
||||||
|
|
||||||
if (*frameIndex == AnyFrameIndex) {
|
|
||||||
*frameIndex = this->frameIndex;
|
|
||||||
} else if (this->frameIndex != AnyFrameIndex
|
|
||||||
and *frameIndex != this->frameIndex)
|
|
||||||
{
|
|
||||||
*frameIndex = NoFrameIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool valid() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* target;
|
|
||||||
uint64_t registerMask;
|
|
||||||
uint8_t typeMask;
|
|
||||||
int frameIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
TargetRead*
|
|
||||||
targetRead(Context* c, Value* target = 0,
|
|
||||||
uint8_t typeMask = ~static_cast<uint8_t>(0),
|
|
||||||
uint64_t registerMask = ~static_cast<uint64_t>(0),
|
|
||||||
int frameIndex = NoFrameIndex)
|
|
||||||
{
|
|
||||||
return new (c->zone->allocate(sizeof(TargetRead)))
|
|
||||||
TargetRead(target, typeMask, registerMask);
|
|
||||||
}
|
|
||||||
|
|
||||||
class MultiRead: public Read {
|
class MultiRead: public Read {
|
||||||
public:
|
public:
|
||||||
MultiRead():
|
MultiRead():
|
||||||
reads(0)
|
reads(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual Site* pickSite(Context* c) {
|
virtual Site* pickSite(Context* c, Value* value) {
|
||||||
uint8_t typeMask = ~static_cast<uint8_t>(0);
|
uint8_t typeMask = ~static_cast<uint8_t>(0);
|
||||||
uint64_t registerMask = ~static_cast<uint64_t>(0);
|
uint64_t registerMask = ~static_cast<uint64_t>(0);
|
||||||
int frameIndex = AnyFrameIndex;
|
int frameIndex = AnyFrameIndex;
|
||||||
@ -925,7 +941,7 @@ class MultiRead: public Read {
|
|||||||
{
|
{
|
||||||
for (Cell* cell = reads; cell; cell = cell->next) {
|
for (Cell* cell = reads; cell; cell = cell->next) {
|
||||||
Read* r = static_cast<Read*>(cell->value);
|
Read* r = static_cast<Read*>(cell->value);
|
||||||
r->intersect(&typeMask, ®isterMask, &frameIndex);
|
r->intersect(typeMask, registerMask, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -948,19 +964,6 @@ multiRead(Context* c)
|
|||||||
return new (c->zone->allocate(sizeof(MultiRead))) MultiRead;
|
return new (c->zone->allocate(sizeof(MultiRead))) MultiRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualSite*
|
|
||||||
anyRegisterSite(Context* c)
|
|
||||||
{
|
|
||||||
return virtualSite(c, 0, 1 << RegisterOperand, ~static_cast<uint64_t>(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualSite*
|
|
||||||
registerOrConstantSite(Context* c)
|
|
||||||
{
|
|
||||||
return virtualSite(c, 0, (1 << RegisterOperand) | (1 << ConstantOperand),
|
|
||||||
~static_cast<uint64_t>(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
Site*
|
Site*
|
||||||
targetOrRegister(Context* c, Value* v)
|
targetOrRegister(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
@ -1004,7 +1007,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
|
|||||||
|
|
||||||
if (v->sites->next == 0) {
|
if (v->sites->next == 0) {
|
||||||
Site* saveSite = 0;
|
Site* saveSite = 0;
|
||||||
for (unsigned i = 0; i < localFootprint; ++i) {
|
for (unsigned i = 0; i < c->localFootprint; ++i) {
|
||||||
if (locals[i] == v) {
|
if (locals[i] == v) {
|
||||||
saveSite = frameSite(c, i);
|
saveSite = frameSite(c, i);
|
||||||
break;
|
break;
|
||||||
@ -1012,7 +1015,7 @@ trySteal(Context* c, Register* r, Stack* stack, Value** locals)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (saveSite == 0) {
|
if (saveSite == 0) {
|
||||||
for (Stack* s = stack; s and (not s->pushed); s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
if (s->value == v) {
|
if (s->value == v) {
|
||||||
uint8_t typeMask;
|
uint8_t typeMask;
|
||||||
uint64_t registerMask;
|
uint64_t registerMask;
|
||||||
@ -1086,7 +1089,7 @@ pickRegister(Context* c, uint32_t mask)
|
|||||||
{
|
{
|
||||||
Register* register_ = 0;
|
Register* register_ = 0;
|
||||||
unsigned cost = 5;
|
unsigned cost = 5;
|
||||||
for (int i = c->assembler->registerCount() - 1; i >= 0; --i) {
|
for (int i = c->arch->registerCount() - 1; i >= 0; --i) {
|
||||||
if ((1 << i) & mask) {
|
if ((1 << i) & mask) {
|
||||||
Register* r = c->registers[i];
|
Register* r = c->registers[i];
|
||||||
if ((static_cast<uint32_t>(1) << i) == mask) {
|
if ((static_cast<uint32_t>(1) << i) == mask) {
|
||||||
@ -1307,105 +1310,28 @@ addRead(Context* c, Value* v, Read* r)
|
|||||||
insertRead(c, c->logicalCode[c->logicalIp]->lastEvent, -1, v, r);
|
insertRead(c, c->logicalCode[c->logicalIp]->lastEvent, -1, v, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
Site*
|
|
||||||
pushSite(Context*, PushEvent*);
|
|
||||||
|
|
||||||
class PushEvent: public Event {
|
|
||||||
public:
|
|
||||||
PushEvent(Context* c, Stack* s):
|
|
||||||
Event(c), s(s), active(false)
|
|
||||||
{
|
|
||||||
assert(c, s->pushEvent == 0);
|
|
||||||
|
|
||||||
s->pushEvent = this;
|
|
||||||
addRead(c, s->value, s->geometry->size * BytesPerWord, pushSite(c, this));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
if (DebugCompile) {
|
|
||||||
fprintf(stderr, "PushEvent.compile active: %d\n", active);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
pushNow(c, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
nextRead(c, s->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool skipMove(unsigned size) {
|
|
||||||
return active and size >= BytesPerWord;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack* s;
|
|
||||||
bool active;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
void
|
||||||
appendPush(Context* c, Stack* s)
|
clean(Context* c, Value* v)
|
||||||
{
|
{
|
||||||
if (DebugAppend) {
|
for (Site** s = &(v->sites); *s;) {
|
||||||
fprintf(stderr, "appendPush\n");
|
if ((*s)->match(c, 1 << MemoryOperand, 0, AnyFrameIndex)) {
|
||||||
|
s = &((*s)->next);
|
||||||
|
} else {
|
||||||
|
(*s)->release(c);
|
||||||
|
*s = (*s)->next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(PushEvent))) PushEvent(c, s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
appendPush(Context* c)
|
clean(Context* c, Stack* stack, Value** locals, Read* reads)
|
||||||
{
|
{
|
||||||
appendPush(c, c->state->stack);
|
for (unsigned i = 0; i < c->localCount; ++i) {
|
||||||
}
|
clean(c, locals[i]);
|
||||||
|
|
||||||
class PushedEvent: public Event {
|
|
||||||
public:
|
|
||||||
PushedEvent(Context* c, Stack* s):
|
|
||||||
Event(c), s(s)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
|
||||||
if (DebugCompile) {
|
|
||||||
fprintf(stderr, "PushedEvent.compile\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c, c->stackPadding == 0);
|
|
||||||
assert(c, s->geometry->padding == 0);
|
|
||||||
|
|
||||||
s->pushSite = s->value->sites = pushSite(&c, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack* s;
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
appendPushed(Context* c, Stack* s)
|
|
||||||
{
|
|
||||||
if (DebugAppend) {
|
|
||||||
fprintf(stderr, "appendPushed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
new (c->zone->allocate(sizeof(PushedEvent))) PushedEvent(c, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
push(Context* c, unsigned size, Value* v);
|
|
||||||
|
|
||||||
void
|
|
||||||
cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
|
||||||
{
|
|
||||||
for (Local* l = locals; l; l = l->next) {
|
|
||||||
l->reuse = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
clearSites(c, s->value);
|
clean(c, s->value);
|
||||||
}
|
|
||||||
|
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
|
||||||
if (s->pushSite) {
|
|
||||||
addSite(c, 0, 0, s->geometry->size * BytesPerWord, s->value,
|
|
||||||
s->pushSite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Read* r = reads; r; r = r->eventNext) {
|
for (Read* r = reads; r; r = r->eventNext) {
|
||||||
@ -1413,15 +1339,6 @@ cleanStack(Context* c, Stack* stack, Local* locals, Read* reads)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
resetLocals(Context* c)
|
|
||||||
{
|
|
||||||
for (Local* l = c->locals; l; l = l->next) {
|
|
||||||
c->localTable[l->index] = 0;
|
|
||||||
}
|
|
||||||
c->locals = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CodePromise*
|
CodePromise*
|
||||||
codePromise(Context* c, Event* e)
|
codePromise(Context* c, Event* e)
|
||||||
{
|
{
|
||||||
@ -1439,64 +1356,71 @@ class CallEvent: public Event {
|
|||||||
public:
|
public:
|
||||||
CallEvent(Context* c, Value* address, unsigned flags,
|
CallEvent(Context* c, Value* address, unsigned flags,
|
||||||
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
||||||
Stack* argumentStack, unsigned argumentCount, unsigned padding):
|
Stack* argumentStack, unsigned argumentCount,
|
||||||
|
unsigned stackArgumentFootprint):
|
||||||
Event(c),
|
Event(c),
|
||||||
address(address),
|
address(address),
|
||||||
traceHandler(traceHandler),
|
traceHandler(traceHandler),
|
||||||
result(result),
|
result(result),
|
||||||
flags(flags),
|
flags(flags),
|
||||||
resultSize(resultSize),
|
resultSize(resultSize)
|
||||||
argumentFootprint(0),
|
|
||||||
paddding(padding)
|
|
||||||
{
|
{
|
||||||
uint32_t mask = ~0;
|
uint32_t mask = ~0;
|
||||||
Stack* s = argumentStack;
|
Stack* s = argumentStack;
|
||||||
unsigned index = 0;
|
unsigned index = 0;
|
||||||
|
unsigned frameIndex = alignedFrameSize(c) + c->parameterFootprint;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
Site* target;
|
Read* target;
|
||||||
if (index < c->assembler->argumentRegisterCount()) {
|
if (index < c->assembler->argumentRegisterCount()) {
|
||||||
int r = c->assembler->argumentRegister(index);
|
int r = c->assembler->argumentRegister(index);
|
||||||
target = fixedRegisterSite(c, r);
|
target = fixedRegisterRead(c, r);
|
||||||
mask &= ~(1 << r);
|
mask &= ~(1 << r);
|
||||||
} else {
|
} else {
|
||||||
target = 0;
|
frameIndex -= s->geometry->size;
|
||||||
|
target = read(c, 1 << MemoryOperand, 0, frameIndex);
|
||||||
s->pushEvent->active = true;
|
s->pushEvent->active = true;
|
||||||
argumentFootprint += s->geometry->size;
|
|
||||||
}
|
}
|
||||||
addRead(c, s->value, s->geometry->size * BytesPerWord, target);
|
addRead(c, s->value, s->geometry->size * BytesPerWord, target);
|
||||||
index += s->geometry->size;
|
index += s->geometry->size;
|
||||||
s = s->next;
|
s = s->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
addRead(c, address, BytesPerWord, virtualSite
|
addRead(c, address, BytesPerWord, read
|
||||||
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
(c, ~0, (static_cast<uint64_t>(mask) << 32) | mask,
|
||||||
|
AnyFrameIndex));
|
||||||
|
|
||||||
|
int footprint = stackArgumentFootprint;
|
||||||
for (Stack* s = stack; s; s = s->next) {
|
for (Stack* s = stack; s; s = s->next) {
|
||||||
s->pushEvent->active = true;
|
if (footprint) {
|
||||||
addRead(c, s->value, s->geometry->size * BytesPerWord, virtualSite
|
addRead(c, s->value, s->geometry->size * BytesPerWord, read
|
||||||
(c, 0, ~0, (static_cast<uint64_t>(mask) << 32) | mask));
|
(c, 1 << MemoryOperand, 0, frameIndex));
|
||||||
|
} else {
|
||||||
|
unsigned index = s->geometry->index + c->localFootprint;
|
||||||
|
if (footprint == 0) {
|
||||||
|
assert(c, index <= frameIndex);
|
||||||
|
s->geometry->padding = frameIndex - index;
|
||||||
|
}
|
||||||
|
addRead(c, s->value, s->geometry->size * BytesPerWord, read
|
||||||
|
(c, 1 << MemoryOperand, 0, index));
|
||||||
|
}
|
||||||
|
frameIndex -= s->geometry->size;
|
||||||
|
footprint -= s->geometry->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
resetLocals(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void compile(Context* c) {
|
virtual void compile(Context* c) {
|
||||||
if (DebugCompile) {
|
if (DebugCompile) {
|
||||||
fprintf(stderr, "CallEvent.compile\n");
|
fprintf(stderr, "CallEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
pushNow(c, stack);
|
|
||||||
|
|
||||||
pad(c, padding);
|
|
||||||
|
|
||||||
UnaryOperation type = ((flags & Compiler::Aligned) ? AlignedCall : Call);
|
apply(c, (flags & Compiler::Aligned) ? AlignedCall : Call, BytesPerWord,
|
||||||
apply(c, type, BytesPerWord, address->source);
|
address->source);
|
||||||
|
|
||||||
if (traceHandler) {
|
if (traceHandler) {
|
||||||
traceHandler->handleTrace(codePromise(c, c->assembler->length()));
|
traceHandler->handleTrace(codePromise(c, c->assembler->length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanStack(c, stack, locals, reads);
|
clean(c, stack, locals, reads);
|
||||||
|
|
||||||
if (resultSize and live(result)) {
|
if (resultSize and live(result)) {
|
||||||
addSite(c, 0, 0, resultSize, result, registerSite
|
addSite(c, 0, 0, resultSize, result, registerSite
|
||||||
@ -1504,10 +1428,6 @@ class CallEvent: public Event {
|
|||||||
resultSize > BytesPerWord ?
|
resultSize > BytesPerWord ?
|
||||||
c->assembler->returnHigh() : NoRegister));
|
c->assembler->returnHigh() : NoRegister));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argumentFootprint and ((flags & Compiler::NoReturn) == 0)) {
|
|
||||||
ignore(c, argumentFootprint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Value* address;
|
Value* address;
|
||||||
@ -1515,14 +1435,13 @@ class CallEvent: public Event {
|
|||||||
Value* result;
|
Value* result;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
unsigned resultSize;
|
unsigned resultSize;
|
||||||
unsigned argumentFootprint;
|
|
||||||
unsigned padding;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendCall(Context* c, Value* address, unsigned flags,
|
appendCall(Context* c, Value* address, unsigned flags,
|
||||||
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
TraceHandler* traceHandler, Value* result, unsigned resultSize,
|
||||||
Stack* argumentStack, unsigned argumentCount, unsigned padding)
|
Stack* argumentStack, unsigned argumentCount,
|
||||||
|
unsigned stackArgumentFootprint)
|
||||||
{
|
{
|
||||||
if (DebugAppend) {
|
if (DebugAppend) {
|
||||||
fprintf(stderr, "appendCall\n");
|
fprintf(stderr, "appendCall\n");
|
||||||
@ -1530,7 +1449,8 @@ appendCall(Context* c, Value* address, unsigned flags,
|
|||||||
|
|
||||||
new (c->zone->allocate(sizeof(CallEvent)))
|
new (c->zone->allocate(sizeof(CallEvent)))
|
||||||
CallEvent(c, address, flags, traceHandler, result,
|
CallEvent(c, address, flags, traceHandler, result,
|
||||||
resultSize, argumentStack, argumentCount, unsigned padding);
|
resultSize, argumentStack, argumentCount,
|
||||||
|
stackArgumentFootprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ReturnEvent: public Event {
|
class ReturnEvent: public Event {
|
||||||
@ -1996,31 +1916,6 @@ stack(Context* c, Value* value, unsigned size, unsigned index, Stack* next)
|
|||||||
StackGeometry(size, index), next);
|
StackGeometry(size, index), next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
resetStack(Context* c)
|
|
||||||
{
|
|
||||||
unsigned i = 0;
|
|
||||||
Stack* p = 0;
|
|
||||||
for (Stack* s = c->state->stack; s; s = s->next) {
|
|
||||||
Stack* n = stack(c, value(c), s->geometry, 0);
|
|
||||||
n->value->sites = n->pushSite = pushSite(c, s);
|
|
||||||
n->pushed = true;
|
|
||||||
|
|
||||||
if (p) {
|
|
||||||
p->next = n;
|
|
||||||
} else {
|
|
||||||
c->state->stack = n;
|
|
||||||
}
|
|
||||||
p = n;
|
|
||||||
|
|
||||||
i += s->geometry->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
resetLocals(c);
|
|
||||||
|
|
||||||
c->stackReset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
class StackSyncEvent: public Event {
|
class StackSyncEvent: public Event {
|
||||||
public:
|
public:
|
||||||
StackSyncEvent(Context* c):
|
StackSyncEvent(Context* c):
|
||||||
@ -2047,7 +1942,7 @@ class StackSyncEvent: public Event {
|
|||||||
fprintf(stderr, "StackSyncEvent.compile\n");
|
fprintf(stderr, "StackSyncEvent.compile\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanStack(c, stack, locals, reads);
|
clean(c, stack, locals, reads);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2738,11 +2633,12 @@ class MyCompiler: public Compiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
|
virtual void init(unsigned logicalCodeLength, unsigned parameterFootprint,
|
||||||
unsigned localFootprint)
|
unsigned localFootprint, unsigned maxStackFootprint)
|
||||||
{
|
{
|
||||||
c.logicalCodeLength = logicalCodeLength;
|
c.logicalCodeLength = logicalCodeLength;
|
||||||
c.parameterFootprint = parameterFootprint;
|
c.parameterFootprint = parameterFootprint;
|
||||||
c.localFootprint = localFootprint;
|
c.localFootprint = localFootprint;
|
||||||
|
c.maxStackFootprint = maxStackFootprint;
|
||||||
|
|
||||||
c.logicalCode = static_cast<LogicalInstruction**>
|
c.logicalCode = static_cast<LogicalInstruction**>
|
||||||
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
|
(c.zone->allocate(sizeof(LogicalInstruction*) * logicalCodeLength));
|
||||||
@ -2971,7 +2867,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
Value* result = value(&c);
|
Value* result = value(&c);
|
||||||
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
|
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
|
||||||
resultSize, argumentStack, index, argumentCount ? 0 : padding);
|
resultSize, argumentStack, index, 0);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2982,25 +2878,9 @@ class MyCompiler: public Compiler {
|
|||||||
unsigned resultSize,
|
unsigned resultSize,
|
||||||
unsigned argumentFootprint)
|
unsigned argumentFootprint)
|
||||||
{
|
{
|
||||||
unsigned padding = c->assembler->stackPadding
|
|
||||||
(c.state->stack->geometry->index + c.state->stack->geometry->size);
|
|
||||||
|
|
||||||
int footprint = argumentFootprint;
|
|
||||||
for (Stack* s = c.state->stack; s; s = s->next) {
|
|
||||||
footprint -= s->geometry->size;
|
|
||||||
if (footprint == 0) {
|
|
||||||
s->geometry->padding = padding;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->pushEvent == 0) {
|
|
||||||
appendPush(&c, s);
|
|
||||||
}
|
|
||||||
s->pushEvent->active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Value* result = value(&c);
|
Value* result = value(&c);
|
||||||
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
|
appendCall(&c, static_cast<Value*>(address), flags, traceHandler, result,
|
||||||
resultSize, c.state->stack, 0, argumentFootprint ? 0 : padding);
|
resultSize, c.state->stack, 0, argumentFootprint);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ class Compiler {
|
|||||||
virtual void resetStack() = 0;
|
virtual void resetStack() = 0;
|
||||||
|
|
||||||
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
virtual void init(unsigned logicalCodeSize, unsigned parameterFootprint,
|
||||||
unsigned localFootprint) = 0;
|
unsigned localFootprint, unsigned maxStackFootprint) = 0;
|
||||||
|
|
||||||
virtual void visitLogicalIp(unsigned logicalIp) = 0;
|
virtual void visitLogicalIp(unsigned logicalIp) = 0;
|
||||||
virtual void startLogicalIp(unsigned logicalIp) = 0;
|
virtual void startLogicalIp(unsigned logicalIp) = 0;
|
||||||
|
32
src/x86.cpp
32
src/x86.cpp
@ -385,6 +385,18 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return rax;
|
return rax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool reserved(int register_) {
|
||||||
|
switch (register_) {
|
||||||
|
case rbp:
|
||||||
|
case rsp:
|
||||||
|
case rbx:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
virtual int returnHigh() {
|
virtual int returnHigh() {
|
||||||
return (BytesPerWord == 4 ? rdx : NoRegister);
|
return (BytesPerWord == 4 ? rdx : NoRegister);
|
||||||
}
|
}
|
||||||
@ -540,8 +552,8 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
|
|
||||||
class MyAssembler: public Assembler {
|
class MyAssembler: public Assembler {
|
||||||
public:
|
public:
|
||||||
MyAssembler(System* s, Allocator* a, Zone* zone, ArchitectureContext* ac):
|
MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch):
|
||||||
c(s, a, zone), ac(ac)
|
c(s, a, zone), arch_(arch)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void setClient(Client* client) {
|
virtual void setClient(Client* client) {
|
||||||
@ -549,21 +561,25 @@ class MyAssembler: public Assembler {
|
|||||||
c.client = client;
|
c.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual Architecture* arch() {
|
||||||
|
return arch_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void apply(Operation op) {
|
virtual void apply(Operation op) {
|
||||||
ac->operations[op](&c);
|
arch_->c.operations[op](&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(UnaryOperation op,
|
virtual void apply(UnaryOperation op,
|
||||||
unsigned aSize, OperandType aType, Operand* aOperand)
|
unsigned aSize, OperandType aType, Operand* aOperand)
|
||||||
{
|
{
|
||||||
ac->unaryOperations[index(op, aType)](&c, aSize, aOperand);
|
arch_->c.unaryOperations[index(op, aType)](&c, aSize, aOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void apply(BinaryOperation op,
|
virtual void apply(BinaryOperation op,
|
||||||
unsigned aSize, OperandType aType, Operand* aOperand,
|
unsigned aSize, OperandType aType, Operand* aOperand,
|
||||||
unsigned bSize, OperandType bType, Operand* bOperand)
|
unsigned bSize, OperandType bType, Operand* bOperand)
|
||||||
{
|
{
|
||||||
ac->binaryOperations[index(op, aType, bType)]
|
arch_->c.binaryOperations[index(op, aType, bType)]
|
||||||
(&c, aSize, aOperand, bSize, bOperand);
|
(&c, aSize, aOperand, bSize, bOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,7 +588,7 @@ class MyAssembler: public Assembler {
|
|||||||
unsigned bSize, OperandType bType, Operand* bOperand,
|
unsigned bSize, OperandType bType, Operand* bOperand,
|
||||||
unsigned cSize, OperandType cType, Operand* cOperand)
|
unsigned cSize, OperandType cType, Operand* cOperand)
|
||||||
{
|
{
|
||||||
ac->ternaryOperations[index(op, aType, bType, cType)]
|
arch_->c.ternaryOperations[index(op, aType, bType, cType)]
|
||||||
(&c, aSize, aOperand, bSize, bOperand, cSize, cOperand);
|
(&c, aSize, aOperand, bSize, bOperand, cSize, cOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,7 +610,7 @@ class MyAssembler: public Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Context c;
|
Context c;
|
||||||
ArchitectureContext* ac;
|
MyArchitecture* arch_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -613,7 +629,7 @@ makeAssembler(System* system, Allocator* allocator, Zone* zone,
|
|||||||
{
|
{
|
||||||
return new (zone->allocate(sizeof(MyAssembler)))
|
return new (zone->allocate(sizeof(MyAssembler)))
|
||||||
MyAssembler(system, allocator, zone,
|
MyAssembler(system, allocator, zone,
|
||||||
&(static_cast<MyArchitecture*>(architecture)->c));
|
static_cast<MyArchitecture*>(architecture));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user