mirror of
https://github.com/corda/corda.git
synced 2025-01-21 03:55:00 +00:00
fix powerpc bootimage build
This commit is contained in:
parent
984f3106fd
commit
c044781807
@ -333,7 +333,6 @@ class Assembler {
|
|||||||
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
virtual void updateCall(UnaryOperation op, void* returnAddress,
|
||||||
void* newTarget) = 0;
|
void* newTarget) = 0;
|
||||||
|
|
||||||
virtual uintptr_t getConstant(const void* src) = 0;
|
|
||||||
virtual void setConstant(void* dst, uintptr_t constant) = 0;
|
virtual void setConstant(void* dst, uintptr_t constant) = 0;
|
||||||
|
|
||||||
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
virtual unsigned alignFrameSize(unsigned sizeInWords) = 0;
|
||||||
@ -422,6 +421,8 @@ class Assembler {
|
|||||||
|
|
||||||
virtual unsigned length() = 0;
|
virtual unsigned length() = 0;
|
||||||
|
|
||||||
|
virtual unsigned scratchSize() = 0;
|
||||||
|
|
||||||
virtual void dispose() = 0;
|
virtual void dispose() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -5383,6 +5383,7 @@ makeSimpleFrameMapTable(MyThread* t, Context* context, uint8_t* start,
|
|||||||
|
|
||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t*
|
uint8_t*
|
||||||
finish(MyThread* t, Allocator* allocator, Context* context)
|
finish(MyThread* t, Allocator* allocator, Context* context)
|
||||||
{
|
{
|
||||||
|
@ -5397,7 +5397,7 @@ compile(Context* c)
|
|||||||
block = next;
|
block = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return block->assemblerBlock->resolve(block->start, 0);
|
return block->assemblerBlock->resolve(block->start, 0) + a->scratchSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
|
162
src/powerpc.cpp
162
src/powerpc.cpp
@ -32,6 +32,15 @@ inline int lo16(int64_t i) { return (int)(i & MASK_LO16); }
|
|||||||
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
inline int hi16(int64_t i) { return lo16(i >> 16); }
|
||||||
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
inline int lo8(int64_t i) { return (int)(i & MASK_LO8); }
|
||||||
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
inline int hi8(int64_t i) { return lo8(i >> 8); }
|
||||||
|
|
||||||
|
inline int ha16(int32_t i) {
|
||||||
|
return ((i >> 16) + ((i & 0x8000) ? 1 : 0)) & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int unha16(int32_t high, int32_t low) {
|
||||||
|
return ((high - ((low & 0x8000) ? 1 : 0)) << 16) | low;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace isa {
|
namespace isa {
|
||||||
@ -186,13 +195,14 @@ class MyBlock: public Assembler::Block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Task;
|
class Task;
|
||||||
|
class ConstantPoolEntry;
|
||||||
|
|
||||||
class Context {
|
class Context {
|
||||||
public:
|
public:
|
||||||
Context(System* s, Allocator* a, Zone* zone):
|
Context(System* s, Allocator* a, Zone* zone):
|
||||||
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0),
|
||||||
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(0)),
|
firstBlock(new (zone->allocate(sizeof(MyBlock))) MyBlock(0)),
|
||||||
lastBlock(firstBlock)
|
lastBlock(firstBlock), constantPool(0), constantPoolCount(0)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
System* s;
|
System* s;
|
||||||
@ -203,6 +213,8 @@ class Context {
|
|||||||
uint8_t* result;
|
uint8_t* result;
|
||||||
MyBlock* firstBlock;
|
MyBlock* firstBlock;
|
||||||
MyBlock* lastBlock;
|
MyBlock* lastBlock;
|
||||||
|
ConstantPoolEntry* constantPool;
|
||||||
|
unsigned constantPoolCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Task {
|
class Task {
|
||||||
@ -556,15 +568,20 @@ void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
updateImmediate(System* s, void* dst, int64_t src, unsigned size)
|
updateImmediate(System* s, void* dst, int32_t src, unsigned size, bool address)
|
||||||
{
|
{
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 4: {
|
case 4: {
|
||||||
int32_t* p = static_cast<int32_t*>(dst);
|
int32_t* p = static_cast<int32_t*>(dst);
|
||||||
int r = (p[1] >> 21) & 31;
|
int r = (p[1] >> 21) & 31;
|
||||||
|
|
||||||
p[0] = lis(r, src >> 16);
|
if (address) {
|
||||||
p[1] = ori(r, r, src);
|
p[0] = lis(r, ha16(src));
|
||||||
|
p[1] |= (src & 0xFFFF);
|
||||||
|
} else {
|
||||||
|
p[0] = lis(r, src >> 16);
|
||||||
|
p[1] = ori(r, r, src);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(s);
|
default: abort(s);
|
||||||
@ -573,12 +590,13 @@ updateImmediate(System* s, void* dst, int64_t src, unsigned size)
|
|||||||
|
|
||||||
class ImmediateListener: public Promise::Listener {
|
class ImmediateListener: public Promise::Listener {
|
||||||
public:
|
public:
|
||||||
ImmediateListener(System* s, void* dst, unsigned size, unsigned offset):
|
ImmediateListener(System* s, void* dst, unsigned size, unsigned offset,
|
||||||
s(s), dst(dst), size(size), offset(offset)
|
bool address):
|
||||||
|
s(s), dst(dst), size(size), offset(offset), address(address)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual bool resolve(int64_t value, void** location) {
|
virtual bool resolve(int64_t value, void** location) {
|
||||||
updateImmediate(s, dst, value, size);
|
updateImmediate(s, dst, value, size, address);
|
||||||
if (location) *location = static_cast<uint8_t*>(dst) + offset;
|
if (location) *location = static_cast<uint8_t*>(dst) + offset;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -587,26 +605,28 @@ class ImmediateListener: public Promise::Listener {
|
|||||||
void* dst;
|
void* dst;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
bool address;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ImmediateTask: public Task {
|
class ImmediateTask: public Task {
|
||||||
public:
|
public:
|
||||||
ImmediateTask(Task* next, Promise* promise, Promise* offset, unsigned size,
|
ImmediateTask(Task* next, Promise* promise, Promise* offset, unsigned size,
|
||||||
unsigned promiseOffset):
|
unsigned promiseOffset, bool address):
|
||||||
Task(next),
|
Task(next),
|
||||||
promise(promise),
|
promise(promise),
|
||||||
offset(offset),
|
offset(offset),
|
||||||
size(size),
|
size(size),
|
||||||
promiseOffset(promiseOffset)
|
promiseOffset(promiseOffset),
|
||||||
|
address(address)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
virtual void run(Context* c) {
|
virtual void run(Context* c) {
|
||||||
if (promise->resolved()) {
|
if (promise->resolved()) {
|
||||||
updateImmediate
|
updateImmediate
|
||||||
(c->s, c->result + offset->value(), promise->value(), size);
|
(c->s, c->result + offset->value(), promise->value(), size, address);
|
||||||
} else {
|
} else {
|
||||||
new (promise->listen(sizeof(ImmediateListener))) ImmediateListener
|
new (promise->listen(sizeof(ImmediateListener))) ImmediateListener
|
||||||
(c->s, c->result + offset->value(), size, promiseOffset);
|
(c->s, c->result + offset->value(), size, promiseOffset, address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,14 +634,48 @@ class ImmediateTask: public Task {
|
|||||||
Promise* offset;
|
Promise* offset;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
unsigned promiseOffset;
|
unsigned promiseOffset;
|
||||||
|
bool address;
|
||||||
};
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
appendImmediateTask(Context* c, Promise* promise, Promise* offset,
|
appendImmediateTask(Context* c, Promise* promise, Promise* offset,
|
||||||
unsigned size, unsigned promiseOffset = 0)
|
unsigned size, unsigned promiseOffset, bool address)
|
||||||
{
|
{
|
||||||
c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask
|
c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask
|
||||||
(c->tasks, promise, offset, size, promiseOffset);
|
(c->tasks, promise, offset, size, promiseOffset, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConstantPoolEntry: public Promise {
|
||||||
|
public:
|
||||||
|
ConstantPoolEntry(Context* c, Promise* constant):
|
||||||
|
c(c), constant(constant), next(c->constantPool), address(0)
|
||||||
|
{
|
||||||
|
c->constantPool = this;
|
||||||
|
++ c->constantPoolCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int64_t value() {
|
||||||
|
assert(c, resolved());
|
||||||
|
|
||||||
|
return reinterpret_cast<intptr_t>(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool resolved() {
|
||||||
|
return address != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Context* c;
|
||||||
|
Promise* constant;
|
||||||
|
ConstantPoolEntry* next;
|
||||||
|
void* address;
|
||||||
|
unsigned constantPoolCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
ConstantPoolEntry*
|
||||||
|
appendConstantPoolEntry(Context* c, Promise* constant)
|
||||||
|
{
|
||||||
|
return new (c->zone->allocate(sizeof(ConstantPoolEntry)))
|
||||||
|
ConstantPoolEntry(c, constant);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -717,7 +771,7 @@ moveCR2(Context* c, unsigned, Assembler::Constant* src,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
appendImmediateTask
|
appendImmediateTask
|
||||||
(c, src->value, offset(c), BytesPerWord, promiseOffset);
|
(c, src->value, offset(c), BytesPerWord, promiseOffset, false);
|
||||||
issue(c, lis(dst->low, 0));
|
issue(c, lis(dst->low, 0));
|
||||||
issue(c, ori(dst->low, dst->low, 0));
|
issue(c, ori(dst->low, dst->low, 0));
|
||||||
}
|
}
|
||||||
@ -1252,18 +1306,27 @@ xorC(Context* c, unsigned size, Assembler::Constant* a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
moveAR(Context* c, unsigned srcSize, Assembler::Address* src,
|
moveAR2(Context* c, unsigned srcSize, Assembler::Address* src,
|
||||||
unsigned dstSize, Assembler::Register* dst)
|
unsigned dstSize, Assembler::Register* dst, unsigned promiseOffset)
|
||||||
{
|
{
|
||||||
assert(c, srcSize == 4 and dstSize == 4);
|
assert(c, srcSize == 4 and dstSize == 4);
|
||||||
|
|
||||||
Assembler::Constant constant(src->address);
|
|
||||||
Assembler::Memory memory(dst->low, 0, -1, 0);
|
Assembler::Memory memory(dst->low, 0, -1, 0);
|
||||||
|
|
||||||
moveCR(c, srcSize, &constant, dstSize, dst);
|
appendImmediateTask
|
||||||
|
(c, src->address, offset(c), BytesPerWord, promiseOffset, true);
|
||||||
|
|
||||||
|
issue(c, lis(dst->low, 0));
|
||||||
moveMR(c, dstSize, &memory, dstSize, dst);
|
moveMR(c, dstSize, &memory, dstSize, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
moveAR(Context* c, unsigned srcSize, Assembler::Address* src,
|
||||||
|
unsigned dstSize, Assembler::Register* dst)
|
||||||
|
{
|
||||||
|
moveAR2(c, srcSize, src, dstSize, dst, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
compareRR(Context* c, unsigned aSize UNUSED, Assembler::Register* a,
|
||||||
unsigned bSize UNUSED, Assembler::Register* b)
|
unsigned bSize UNUSED, Assembler::Register* b)
|
||||||
@ -1596,6 +1659,18 @@ longCallC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
callR(c, BytesPerWord, &tmp);
|
callR(c, BytesPerWord, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
alignedLongCallC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
|
Assembler::Address address(appendConstantPoolEntry(c, target->value));
|
||||||
|
moveAR2(c, BytesPerWord, &address, BytesPerWord, &tmp, 12);
|
||||||
|
callR(c, BytesPerWord, &tmp);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
longJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
longJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||||
{
|
{
|
||||||
@ -1606,6 +1681,18 @@ longJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
|||||||
jumpR(c, BytesPerWord, &tmp);
|
jumpR(c, BytesPerWord, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
alignedLongJumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||||
|
{
|
||||||
|
assert(c, size == BytesPerWord);
|
||||||
|
|
||||||
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
|
Assembler::Address address(appendConstantPoolEntry(c, target->value));
|
||||||
|
moveAR2(c, BytesPerWord, &address, BytesPerWord, &tmp, 12);
|
||||||
|
jumpR(c, BytesPerWord, &tmp);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
jumpC(Context* c, unsigned size UNUSED, Assembler::Constant* target)
|
||||||
{
|
{
|
||||||
@ -1707,8 +1794,12 @@ populateTables(ArchitectureContext* c)
|
|||||||
|
|
||||||
uo[index(c, LongCall, C)] = CAST1(longCallC);
|
uo[index(c, LongCall, C)] = CAST1(longCallC);
|
||||||
|
|
||||||
|
uo[index(c, AlignedLongCall, C)] = CAST1(alignedLongCallC);
|
||||||
|
|
||||||
uo[index(c, LongJump, C)] = CAST1(longJumpC);
|
uo[index(c, LongJump, C)] = CAST1(longJumpC);
|
||||||
|
|
||||||
|
uo[index(c, AlignedLongJump, C)] = CAST1(alignedLongJumpC);
|
||||||
|
|
||||||
uo[index(c, Jump, R)] = CAST1(jumpR);
|
uo[index(c, Jump, R)] = CAST1(jumpR);
|
||||||
uo[index(c, Jump, C)] = CAST1(jumpC);
|
uo[index(c, Jump, C)] = CAST1(jumpC);
|
||||||
|
|
||||||
@ -1878,7 +1969,15 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
case LongCall:
|
case LongCall:
|
||||||
case LongJump: {
|
case LongJump: {
|
||||||
updateImmediate(c.s, static_cast<uint8_t*>(returnAddress) - 12,
|
updateImmediate(c.s, static_cast<uint8_t*>(returnAddress) - 12,
|
||||||
reinterpret_cast<intptr_t>(newTarget), BytesPerWord);
|
reinterpret_cast<intptr_t>(newTarget), BytesPerWord,
|
||||||
|
false);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case AlignedLongCall:
|
||||||
|
case AlignedLongJump: {
|
||||||
|
uint32_t* p = static_cast<uint32_t*>(returnAddress) - 4;
|
||||||
|
*reinterpret_cast<void**>(unha16(p[0] & 0xFFFF, p[1] & 0xFFFF))
|
||||||
|
= newTarget;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: abort(&c);
|
default: abort(&c);
|
||||||
@ -1889,13 +1988,8 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uintptr_t getConstant(const void* src) {
|
|
||||||
const int32_t* p = static_cast<const int32_t*>(src);
|
|
||||||
return (p[0] << 16) | (p[1] & 0xFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setConstant(void* dst, uintptr_t constant) {
|
virtual void setConstant(void* dst, uintptr_t constant) {
|
||||||
updateImmediate(c.s, dst, constant, BytesPerWord);
|
updateImmediate(c.s, dst, constant, BytesPerWord, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
virtual unsigned alignFrameSize(unsigned sizeInWords) {
|
||||||
@ -2337,9 +2431,21 @@ class MyAssembler: public Assembler {
|
|||||||
memcpy(dst + b->start, c.code.data + b->offset, b->size);
|
memcpy(dst + b->start, c.code.data + b->offset, b->size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned index = c.code.length();
|
||||||
|
assert(&c, index % BytesPerWord == 0);
|
||||||
|
for (ConstantPoolEntry* e = c.constantPool; e; e = e->next) {
|
||||||
|
e->address = dst + index;
|
||||||
|
index += BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
for (Task* t = c.tasks; t; t = t->next) {
|
for (Task* t = c.tasks; t; t = t->next) {
|
||||||
t->run(&c);
|
t->run(&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (ConstantPoolEntry* e = c.constantPool; e; e = e->next) {
|
||||||
|
*static_cast<uint32_t*>(e->address) = e->constant->value();
|
||||||
|
fprintf(stderr, "constant %p at %p\n", reinterpret_cast<void*>(e->constant->value()), e->address);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Promise* offset() {
|
virtual Promise* offset() {
|
||||||
@ -2362,6 +2468,10 @@ class MyAssembler: public Assembler {
|
|||||||
return c.code.length();
|
return c.code.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual unsigned scratchSize() {
|
||||||
|
return c.constantPoolCount * BytesPerWord;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
c.code.dispose();
|
c.code.dispose();
|
||||||
}
|
}
|
||||||
|
10
src/x86.cpp
10
src/x86.cpp
@ -2791,12 +2791,6 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uintptr_t getConstant(const void* src) {
|
|
||||||
uintptr_t v;
|
|
||||||
memcpy(&v, src, BytesPerWord);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setConstant(void* dst, uintptr_t constant) {
|
virtual void setConstant(void* dst, uintptr_t constant) {
|
||||||
memcpy(dst, &constant, BytesPerWord);
|
memcpy(dst, &constant, BytesPerWord);
|
||||||
}
|
}
|
||||||
@ -3493,6 +3487,10 @@ class MyAssembler: public Assembler {
|
|||||||
return c.code.length();
|
return c.code.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual unsigned scratchSize() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void dispose() {
|
virtual void dispose() {
|
||||||
c.code.dispose();
|
c.code.dispose();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user