mirror of
https://github.com/corda/corda.git
synced 2025-06-13 20:58:19 +00:00
pair up stack for NativeCallingConvention
This commit is contained in:
@ -115,6 +115,8 @@ class Types {
|
|||||||
|
|
||||||
enum SignExtendMode { SignExtend, ZeroExtend };
|
enum SignExtendMode { SignExtend, ZeroExtend };
|
||||||
|
|
||||||
|
enum CallingConvention { NativeCallingConvention, AvianCallingConvention };
|
||||||
|
|
||||||
class Value {
|
class Value {
|
||||||
public:
|
public:
|
||||||
ir::Type type;
|
ir::Type type;
|
||||||
|
@ -2460,7 +2460,7 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
unsigned footprint = 0;
|
unsigned footprint = 0;
|
||||||
unsigned size = TargetBytesPerWord;
|
unsigned size = TargetBytesPerWord;
|
||||||
RUNTIME_ARRAY(Value*, arguments, argumentCount);
|
RUNTIME_ARRAY(ir::Value*, arguments, argumentCount);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (unsigned i = 0; i < argumentCount; ++i) {
|
for (unsigned i = 0; i < argumentCount; ++i) {
|
||||||
Value* o = va_arg(a, Value*);
|
Value* o = va_arg(a, Value*);
|
||||||
@ -2484,20 +2484,23 @@ class MyCompiler: public Compiler {
|
|||||||
|
|
||||||
Stack* argumentStack = c.stack;
|
Stack* argumentStack = c.stack;
|
||||||
for (int i = index - 1; i >= 0; --i) {
|
for (int i = index - 1; i >= 0; --i) {
|
||||||
argumentStack = compiler::stack
|
argumentStack = compiler::stack(
|
||||||
(&c, RUNTIME_ARRAY_BODY(arguments)[i], argumentStack);
|
&c,
|
||||||
|
static_cast<Value*>(RUNTIME_ARRAY_BODY(arguments)[i]),
|
||||||
|
argumentStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value* result = value(&c, resultType);
|
Value* result = value(&c, resultType);
|
||||||
appendCall(&c,
|
appendCall(&c,
|
||||||
static_cast<Value*>(address),
|
static_cast<Value*>(address),
|
||||||
|
ir::NativeCallingConvention,
|
||||||
flags,
|
flags,
|
||||||
traceHandler,
|
traceHandler,
|
||||||
result,
|
result,
|
||||||
resultType.size(),
|
resultType.size(),
|
||||||
argumentStack,
|
argumentStack,
|
||||||
index,
|
index,
|
||||||
util::Slice<ir::Value*>(0, 0));
|
util::Slice<ir::Value*>(RUNTIME_ARRAY_BODY(arguments), index));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -2511,6 +2514,7 @@ class MyCompiler: public Compiler {
|
|||||||
Value* result = value(&c, resultType);
|
Value* result = value(&c, resultType);
|
||||||
appendCall(&c,
|
appendCall(&c,
|
||||||
static_cast<Value*>(address),
|
static_cast<Value*>(address),
|
||||||
|
ir::AvianCallingConvention,
|
||||||
flags,
|
flags,
|
||||||
traceHandler,
|
traceHandler,
|
||||||
result,
|
result,
|
||||||
|
@ -184,11 +184,110 @@ Link* link(Context* c, Event* predecessor, Link* nextPredecessor, Event* success
|
|||||||
(predecessor, nextPredecessor, successor, nextSuccessor, forkState);
|
(predecessor, nextPredecessor, successor, nextSuccessor, forkState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value* maybeBuddySlice(Context* c, Value* v)
|
||||||
|
{
|
||||||
|
if (v->home >= 0) {
|
||||||
|
Value* n = value(c, v->type);
|
||||||
|
appendBuddy(c, v, n);
|
||||||
|
return n;
|
||||||
|
} else {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
struct SliceStack : public Slice<T> {
|
||||||
|
size_t capacity;
|
||||||
|
|
||||||
|
SliceStack(T* items, size_t capacity)
|
||||||
|
: Slice<T>(items + capacity, 0), capacity(capacity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(const T& item)
|
||||||
|
{
|
||||||
|
--Slice<T>::items;
|
||||||
|
++Slice<T>::count;
|
||||||
|
*Slice<T>::items = item;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T, size_t Capacity>
|
||||||
|
struct FixedSliceStack : public SliceStack<T> {
|
||||||
|
T itemArray[Capacity];
|
||||||
|
|
||||||
|
FixedSliceStack() : SliceStack<T>(&itemArray[0], Capacity)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Value* pushWordSlice(Context* c, Value* v, SliceStack<ir::Value*>& slice)
|
||||||
|
{
|
||||||
|
if (v) {
|
||||||
|
v = maybeBuddySlice(c, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
Stack* s = stack(c, v, c->stack);
|
||||||
|
assert(c, index > 0);
|
||||||
|
slice.push(v);
|
||||||
|
|
||||||
|
// if (DebugFrame) {
|
||||||
|
// fprintf(stderr, "push %p\n", v);
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (v) {
|
||||||
|
v->home = frameIndex(c, s->index + c->localFootprint);
|
||||||
|
}
|
||||||
|
c->stack = s;
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushSlice(Context* c,
|
||||||
|
unsigned footprint,
|
||||||
|
Value* v,
|
||||||
|
SliceStack<ir::Value*>& slice)
|
||||||
|
{
|
||||||
|
assert(c, footprint);
|
||||||
|
|
||||||
|
bool bigEndian = c->arch->bigEndian();
|
||||||
|
|
||||||
|
Value* low = v;
|
||||||
|
|
||||||
|
if (bigEndian) {
|
||||||
|
v = pushWordSlice(c, v, slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* high;
|
||||||
|
if (footprint > 1) {
|
||||||
|
assert(c, footprint == 2);
|
||||||
|
|
||||||
|
if (vm::TargetBytesPerWord == 4) {
|
||||||
|
low->maybeSplit(c);
|
||||||
|
high = pushWordSlice(c, low->nextWord, slice);
|
||||||
|
} else {
|
||||||
|
high = pushWordSlice(c, 0, slice);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
high = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not bigEndian) {
|
||||||
|
v = pushWordSlice(c, v, slice);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (high) {
|
||||||
|
v->nextWord = high;
|
||||||
|
high->nextWord = v;
|
||||||
|
high->wordIndex = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CallEvent: public Event {
|
class CallEvent: public Event {
|
||||||
public:
|
public:
|
||||||
CallEvent(Context* c,
|
CallEvent(Context* c,
|
||||||
Value* address,
|
Value* address,
|
||||||
|
ir::CallingConvention callingConvention UNUSED,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
Value* result,
|
Value* result,
|
||||||
@ -206,13 +305,19 @@ class CallEvent: public Event {
|
|||||||
stackArgumentIndex(0),
|
stackArgumentIndex(0),
|
||||||
flags(flags),
|
flags(flags),
|
||||||
resultSize(resultSize),
|
resultSize(resultSize),
|
||||||
stackArgumentFootprint(arguments.count)
|
stackArgumentFootprint(callingConvention == ir::AvianCallingConvention
|
||||||
|
? arguments.count
|
||||||
|
: 0)
|
||||||
{
|
{
|
||||||
uint32_t registerMask = c->regFile->generalRegisters.mask;
|
uint32_t registerMask = c->regFile->generalRegisters.mask;
|
||||||
|
|
||||||
|
assert(c,
|
||||||
|
callingConvention == ir::AvianCallingConvention
|
||||||
|
|| argumentCount == arguments.count);
|
||||||
|
|
||||||
if (argumentCount) {
|
if (argumentCount) {
|
||||||
assert(c, (flags & Compiler::TailJump) == 0);
|
assert(c, (flags & Compiler::TailJump) == 0);
|
||||||
assert(c, arguments.count == 0);
|
assert(c, stackArgumentFootprint == 0);
|
||||||
|
|
||||||
Stack* s = argumentStack;
|
Stack* s = argumentStack;
|
||||||
unsigned index = 0;
|
unsigned index = 0;
|
||||||
@ -501,6 +606,7 @@ class CallEvent: public Event {
|
|||||||
|
|
||||||
void appendCall(Context* c,
|
void appendCall(Context* c,
|
||||||
Value* address,
|
Value* address,
|
||||||
|
ir::CallingConvention callingConvention,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
Value* result,
|
Value* result,
|
||||||
@ -512,6 +618,7 @@ void appendCall(Context* c,
|
|||||||
append(c,
|
append(c,
|
||||||
new (c->zone) CallEvent(c,
|
new (c->zone) CallEvent(c,
|
||||||
address,
|
address,
|
||||||
|
callingConvention,
|
||||||
flags,
|
flags,
|
||||||
traceHandler,
|
traceHandler,
|
||||||
result,
|
result,
|
||||||
@ -929,6 +1036,7 @@ appendCombine(Context* c, lir::TernaryOperation type,
|
|||||||
&thunk);
|
&thunk);
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
|
FixedSliceStack<ir::Value*, 6> slice;
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
|
|
||||||
bool threadParameter;
|
bool threadParameter;
|
||||||
@ -938,13 +1046,17 @@ appendCombine(Context* c, lir::TernaryOperation type,
|
|||||||
unsigned stackSize = ceilingDivide(secondSize, vm::TargetBytesPerWord)
|
unsigned stackSize = ceilingDivide(secondSize, vm::TargetBytesPerWord)
|
||||||
+ ceilingDivide(firstSize, vm::TargetBytesPerWord);
|
+ ceilingDivide(firstSize, vm::TargetBytesPerWord);
|
||||||
|
|
||||||
compiler::push(c, ceilingDivide(secondSize, vm::TargetBytesPerWord), secondValue);
|
pushSlice(c,
|
||||||
compiler::push(c, ceilingDivide(firstSize, vm::TargetBytesPerWord), firstValue);
|
ceilingDivide(secondSize, vm::TargetBytesPerWord),
|
||||||
|
secondValue,
|
||||||
|
slice);
|
||||||
|
pushSlice(
|
||||||
|
c, ceilingDivide(firstSize, vm::TargetBytesPerWord), firstValue, slice);
|
||||||
|
|
||||||
if (threadParameter) {
|
if (threadParameter) {
|
||||||
++ stackSize;
|
++ stackSize;
|
||||||
|
|
||||||
compiler::push(c, 1, threadRegister(c));
|
pushSlice(c, 1, threadRegister(c), slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
@ -954,13 +1066,14 @@ appendCombine(Context* c, lir::TernaryOperation type,
|
|||||||
value(c,
|
value(c,
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
||||||
constantSite(c, handler)),
|
constantSite(c, handler)),
|
||||||
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
resultValue,
|
resultValue,
|
||||||
resultSize,
|
resultSize,
|
||||||
argumentStack,
|
argumentStack,
|
||||||
stackSize,
|
stackSize,
|
||||||
util::Slice<ir::Value*>(0, 0));
|
slice);
|
||||||
} else {
|
} else {
|
||||||
append
|
append
|
||||||
(c, new(c->zone)
|
(c, new(c->zone)
|
||||||
@ -1066,8 +1179,10 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize,
|
|||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
|
FixedSliceStack<ir::Value*, 2> slice;
|
||||||
|
|
||||||
compiler::push(c, ceilingDivide(firstSize, vm::TargetBytesPerWord), firstValue);
|
pushSlice(
|
||||||
|
c, ceilingDivide(firstSize, vm::TargetBytesPerWord), firstValue, slice);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -1077,13 +1192,14 @@ appendTranslate(Context* c, lir::BinaryOperation type, unsigned firstSize,
|
|||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
||||||
constantSite(
|
constantSite(
|
||||||
c, c->client->getThunk(type, firstSize, resultSize))),
|
c, c->client->getThunk(type, firstSize, resultSize))),
|
||||||
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
resultValue,
|
resultValue,
|
||||||
resultSize,
|
resultSize,
|
||||||
argumentStack,
|
argumentStack,
|
||||||
ceilingDivide(firstSize, vm::TargetBytesPerWord),
|
ceilingDivide(firstSize, vm::TargetBytesPerWord),
|
||||||
util::Slice<ir::Value*>(0, 0));
|
slice);
|
||||||
} else {
|
} else {
|
||||||
append(c, new(c->zone)
|
append(c, new(c->zone)
|
||||||
TranslateEvent
|
TranslateEvent
|
||||||
@ -1422,6 +1538,7 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first
|
|||||||
vm::TargetBytesPerWord, &thunk);
|
vm::TargetBytesPerWord, &thunk);
|
||||||
|
|
||||||
if (thunk) {
|
if (thunk) {
|
||||||
|
FixedSliceStack<ir::Value*, 4> slice;
|
||||||
Stack* oldStack = c->stack;
|
Stack* oldStack = c->stack;
|
||||||
|
|
||||||
bool threadParameter;
|
bool threadParameter;
|
||||||
@ -1430,8 +1547,10 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first
|
|||||||
|
|
||||||
assert(c, not threadParameter);
|
assert(c, not threadParameter);
|
||||||
|
|
||||||
compiler::push(c, ceilingDivide(size, vm::TargetBytesPerWord), secondValue);
|
pushSlice(
|
||||||
compiler::push(c, ceilingDivide(size, vm::TargetBytesPerWord), firstValue);
|
c, ceilingDivide(size, vm::TargetBytesPerWord), secondValue, slice);
|
||||||
|
pushSlice(
|
||||||
|
c, ceilingDivide(size, vm::TargetBytesPerWord), firstValue, slice);
|
||||||
|
|
||||||
Stack* argumentStack = c->stack;
|
Stack* argumentStack = c->stack;
|
||||||
c->stack = oldStack;
|
c->stack = oldStack;
|
||||||
@ -1442,13 +1561,14 @@ appendBranch(Context* c, lir::TernaryOperation type, unsigned size, Value* first
|
|||||||
value(c,
|
value(c,
|
||||||
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
ir::Type(ir::Type::Address, vm::TargetBytesPerWord),
|
||||||
constantSite(c, handler)),
|
constantSite(c, handler)),
|
||||||
|
ir::NativeCallingConvention,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
result,
|
result,
|
||||||
4,
|
4,
|
||||||
argumentStack,
|
argumentStack,
|
||||||
ceilingDivide(size, vm::TargetBytesPerWord) * 2,
|
ceilingDivide(size, vm::TargetBytesPerWord) * 2,
|
||||||
util::Slice<ir::Value*>(0, 0));
|
slice);
|
||||||
|
|
||||||
appendBranch(c,
|
appendBranch(c,
|
||||||
thunkBranch(c, type),
|
thunkBranch(c, type),
|
||||||
|
@ -115,6 +115,7 @@ link(Context* c, Event* predecessor, Link* nextPredecessor, Event* successor,
|
|||||||
|
|
||||||
void appendCall(Context* c,
|
void appendCall(Context* c,
|
||||||
Value* address,
|
Value* address,
|
||||||
|
ir::CallingConvention callingConvention,
|
||||||
unsigned flags,
|
unsigned flags,
|
||||||
TraceHandler* traceHandler,
|
TraceHandler* traceHandler,
|
||||||
Value* result,
|
Value* result,
|
||||||
@ -168,6 +169,8 @@ appendSaveLocals(Context* c);
|
|||||||
void
|
void
|
||||||
appendDummy(Context* c);
|
appendDummy(Context* c);
|
||||||
|
|
||||||
|
void appendBuddy(Context* c, Value* original, Value* buddy);
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace codegen
|
} // namespace codegen
|
||||||
} // namespace avian
|
} // namespace avian
|
||||||
|
Reference in New Issue
Block a user