handle unresolved constants in moveCM

This commit is contained in:
Joel Dice 2008-11-27 21:58:32 -07:00
parent 6dc181fad5
commit 02afbd1fa1

View File

@ -202,50 +202,68 @@ appendOffsetTask(Context* c, Promise* promise, int instructionOffset,
} }
void void
copyWord(void* dst, int64_t src) copy(System* s, void* dst, int64_t src, unsigned size)
{ {
intptr_t v = src; switch (size) {
memcpy(dst, &v, BytesPerWord); case 4: {
int32_t v = src;
memcpy(dst, &v, 4);
} break;
case 8: {
int64_t v = src;
memcpy(dst, &v, 8);
} break;
default: abort(s);
}
} }
class ImmediateListener: public Promise::Listener { class ImmediateListener: public Promise::Listener {
public: public:
ImmediateListener(void* dst): dst(dst) { } ImmediateListener(System* s, void* dst, unsigned size):
s(s), dst(dst), size(size)
{ }
virtual void* resolve(int64_t value) { virtual void* resolve(int64_t value) {
copyWord(dst, value); copy(s, dst, value, size);
return 0; return dst;
} }
System* s;
void* dst; void* dst;
unsigned size;
}; };
class ImmediateTask: public Task { class ImmediateTask: public Task {
public: public:
ImmediateTask(Task* next, Promise* promise, unsigned offset): ImmediateTask(Task* next, Promise* promise, unsigned offset, unsigned size):
Task(next), Task(next),
promise(promise), promise(promise),
offset(offset) offset(offset),
size(size)
{ } { }
virtual void run(Context* c) { virtual void run(Context* c) {
if (promise->resolved()) { if (promise->resolved()) {
copyWord(c->result + offset, promise->value()); copy(c->s, c->result + offset, promise->value(), size);
} else { } else {
new (promise->listen(sizeof(ImmediateListener))) new (promise->listen(sizeof(ImmediateListener)))
ImmediateListener(c->result + offset); ImmediateListener(c->s, c->result + offset, size);
} }
} }
Promise* promise; Promise* promise;
unsigned offset; unsigned offset;
unsigned size;
}; };
void void
appendImmediateTask(Context* c, Promise* promise, unsigned offset) appendImmediateTask(Context* c, Promise* promise, unsigned offset,
unsigned size)
{ {
c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask c->tasks = new (c->zone->allocate(sizeof(ImmediateTask))) ImmediateTask
(c->tasks, promise, offset); (c->tasks, promise, offset, size);
} }
void void
@ -535,7 +553,7 @@ pushC(Context* c, unsigned size, Assembler::Constant* a)
} else { } else {
if (BytesPerWord == 4) { if (BytesPerWord == 4) {
c->code.append(0x68); c->code.append(0x68);
appendImmediateTask(c, a->value, c->code.length()); appendImmediateTask(c, a->value, c->code.length(), BytesPerWord);
c->code.appendAddress(static_cast<uintptr_t>(0)); c->code.appendAddress(static_cast<uintptr_t>(0));
} else { } else {
Assembler::Register tmp(c->client->acquireTemporary()); Assembler::Register tmp(c->client->acquireTemporary());
@ -704,7 +722,7 @@ moveCR(Context* c, unsigned size, Assembler::Constant* a,
if (a->value->resolved()) { if (a->value->resolved()) {
c->code.appendAddress(a->value->value()); c->code.appendAddress(a->value->value());
} else { } else {
appendImmediateTask(c, a->value, c->code.length()); appendImmediateTask(c, a->value, c->code.length(), BytesPerWord);
c->code.appendAddress(static_cast<uintptr_t>(0)); c->code.appendAddress(static_cast<uintptr_t>(0));
} }
} }
@ -714,8 +732,6 @@ void
moveCM(Context* c, unsigned size, Assembler::Constant* a, moveCM(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Memory* b) Assembler::Memory* b)
{ {
int64_t v = a->value->value();
switch (size) { switch (size) {
case 1: case 1:
encode(c, 0xc6, 0, b, false); encode(c, 0xc6, 0, b, false);
@ -729,10 +745,17 @@ moveCM(Context* c, unsigned size, Assembler::Constant* a,
case 4: case 4:
encode(c, 0xc7, 0, b, false); encode(c, 0xc7, 0, b, false);
if (a->value->resolved()) {
c->code.append4(a->value->value()); c->code.append4(a->value->value());
} else {
appendImmediateTask(c, a->value, c->code.length(), 4);
c->code.append4(0);
}
break; break;
case 8: { case 8: {
int64_t v = a->value->value();
ResolvedPromise high((v >> 32) & 0xFFFFFFFF); ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant ah(&high); Assembler::Constant ah(&high);