bugfixes, mainly concerning 32-bit machines

This commit is contained in:
Joel Dice 2008-04-28 16:08:31 -06:00
parent 90ae9a70ee
commit 8738bddcb9
4 changed files with 348 additions and 120 deletions

View File

@ -134,7 +134,7 @@ class Assembler {
public: public:
virtual ~Client() { } virtual ~Client() { }
virtual int acquireTemporary(int r = NoRegister) = 0; virtual int acquireTemporary() = 0;
virtual void releaseTemporary(int r) = 0; virtual void releaseTemporary(int r) = 0;
virtual void save(int r) = 0; virtual void save(int r) = 0;
@ -156,11 +156,8 @@ class Assembler {
virtual unsigned argumentRegisterCount() = 0; virtual unsigned argumentRegisterCount() = 0;
virtual int argumentRegister(unsigned index) = 0; virtual int argumentRegister(unsigned index) = 0;
virtual void getTargets(UnaryOperation op, unsigned size,
Register* a) = 0;
virtual void getTargets(BinaryOperation op, unsigned size, virtual void getTargets(BinaryOperation op, unsigned size,
Register* a, Register* b) = 0; Register* a, Register* b, bool* syncStack) = 0;
virtual void apply(Operation op) = 0; virtual void apply(Operation op) = 0;

View File

@ -3875,11 +3875,11 @@ finish(MyThread* t, Context* context)
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)), (&byteArrayBody(t, className(t, methodClass(t, context->method)), 0)),
"java/nio/ByteBuffer") == 0 and "java/lang/Class") == 0 and
strcmp strcmp
(reinterpret_cast<const char*> (reinterpret_cast<const char*>
(&byteArrayBody(t, methodName(t, context->method), 0)), (&byteArrayBody(t, methodName(t, context->method), 0)),
"checkPut") == 0) "replace") == 0)
{ {
asm("int3"); asm("int3");
} }

View File

@ -1195,13 +1195,15 @@ class MoveEvent: public Event {
nextRead(c, src); nextRead(c, src);
if (dst->reads) {
addSite(c, stack, size, dst, target);
}
if (cost) { if (cost) {
apply(c, type, size, src->source, target); apply(c, type, size, src->source, target);
} }
if (dst->reads) { if (dst->reads == 0) {
addSite(c, stack, size, dst, target);
} else {
removeSite(c, dst, target); removeSite(c, dst, target);
} }
} }
@ -1263,22 +1265,20 @@ appendCompare(Context* c, unsigned size, Value* first, Value* second)
class CombineEvent: public Event { class CombineEvent: public Event {
public: public:
CombineEvent(Context* c, BinaryOperation type, unsigned size, Value* first, CombineEvent(Context* c, BinaryOperation type, unsigned size, Value* first,
Value* second, Value* result): Value* second, Value* result, Assembler::Register* r1,
Assembler::Register* r2):
Event(c), type(type), size(size), first(first), second(second), Event(c), type(type), size(size), first(first), second(second),
result(result) result(result)
{ {
Assembler::Register r1(NoRegister);
Assembler::Register r2(NoRegister);
c->assembler->getTargets(type, size, &r1, &r2);
addRead(c, first, size, addRead(c, first, size,
r1.low == NoRegister ? r1->low == NoRegister ?
constantOrRegisterSite(c) : constantOrRegisterSite(c) :
static_cast<Site*>(registerSite(c, r1.low, r1.high))); static_cast<Site*>(registerSite(c, r1->low, r1->high)));
addRead(c, second, size, addRead(c, second, size,
r2.low == NoRegister ? r2->low == NoRegister ?
valueSite(c, result) : valueSite(c, result) :
static_cast<Site*>(registerSite(c, r2.low, r2.high))); static_cast<Site*>(registerSite(c, r2->low, r2->high)));
} }
virtual void compile(Context* c) { virtual void compile(Context* c) {
@ -1304,16 +1304,28 @@ class CombineEvent: public Event {
Value* result; Value* result;
}; };
void
appendStackSync(Context* c);
void void
appendCombine(Context* c, BinaryOperation type, unsigned size, Value* first, appendCombine(Context* c, BinaryOperation type, unsigned size, Value* first,
Value* second, Value* result) Value* second, Value* result)
{ {
Assembler::Register r1(NoRegister);
Assembler::Register r2(NoRegister);
bool syncStack;
c->assembler->getTargets(type, size, &r1, &r2, &syncStack);
if (syncStack) {
appendStackSync(c);
}
if (DebugAppend) { if (DebugAppend) {
fprintf(stderr, "appendCombine\n"); fprintf(stderr, "appendCombine\n");
} }
new (c->zone->allocate(sizeof(CombineEvent))) new (c->zone->allocate(sizeof(CombineEvent)))
CombineEvent(c, type, size, first, second, result); CombineEvent(c, type, size, first, second, result, &r1, &r2);
} }
class TranslateEvent: public Event { class TranslateEvent: public Event {
@ -1949,14 +1961,8 @@ class Client: public Assembler::Client {
public: public:
Client(Context* c): c(c) { } Client(Context* c): c(c) { }
virtual int acquireTemporary(int r) { virtual int acquireTemporary() {
if (r == NoRegister) { int r = freeRegisterExcept(c, NoRegister, false);
r = freeRegisterExcept(c, NoRegister, false);
} else {
expect(c, (c->registers[r].refCount == 0
and c->registers[r].value == 0)
or c->registers[r].pushed);
}
increment(c, r); increment(c, r);
return r; return r;
} }

View File

@ -95,6 +95,13 @@ expect(Context* c, bool v)
expect(c->s, v); expect(c->s, v);
} }
ResolvedPromise*
resolved(Context* c, int64_t value)
{
return new (c->zone->allocate(sizeof(ResolvedPromise)))
ResolvedPromise(value);
}
class CodePromise: public Promise { class CodePromise: public Promise {
public: public:
CodePromise(Context* c, unsigned offset): c(c), offset(offset) { } CodePromise(Context* c, unsigned offset): c(c), offset(offset) { }
@ -434,12 +441,12 @@ pushC(Context* c, unsigned size, Assembler::Constant* a)
int64_t v = a->value->value(); int64_t v = a->value->value();
if (BytesPerWord == 4 and size == 8) { if (BytesPerWord == 4 and size == 8) {
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant ah(&high);
ResolvedPromise low(v & 0xFFFFFFFF); ResolvedPromise low(v & 0xFFFFFFFF);
Assembler::Constant al(&low); Assembler::Constant al(&low);
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant ah(&high);
pushC(c, 4, &ah); pushC(c, 4, &ah);
pushC(c, 4, &al); pushC(c, 4, &al);
} else { } else {
@ -536,14 +543,66 @@ popM(Context* c, unsigned size, Assembler::Memory* a)
} }
void void
negateR(Context* c, unsigned size UNUSED, Assembler::Register* a) addCarryCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo assert(c, BytesPerWord == 8 or size == 4);
int64_t v = a->value->value();
if (isInt8(v)) {
c->code.append(0x83);
c->code.append(0xd0 | b->low);
c->code.append(v);
} else {
abort(c);
}
}
void
moveRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b);
void
negateR(Context* c, unsigned size, Assembler::Register* a)
{
if (BytesPerWord == 4 and size == 8) {
Assembler::Register ax(rax);
Assembler::Register dx(rdx);
Assembler::Register ah(a->high);
ResolvedPromise zeroPromise(0);
Assembler::Constant zero(&zeroPromise);
if (a->low != rax) {
c->client->save(rax);
moveRR(c, BytesPerWord, a, &ax);
}
if (a->high != rdx) {
c->client->save(rdx);
moveRR(c, BytesPerWord, &ah, &dx);
}
negateR(c, 4, &ax);
addCarryCR(c, 4, &zero, &dx);
negateR(c, 4, &dx);
if (a->high != rdx) {
moveRR(c, BytesPerWord, &dx, a);
c->client->restore(rdx);
}
if (a->low != rax) {
moveRR(c, BytesPerWord, &ax, a);
c->client->restore(rax);
}
} else {
rex(c); rex(c);
c->code.append(0xf7); c->code.append(0xf7);
c->code.append(0xd8 | a->low); c->code.append(0xd8 | a->low);
} }
}
void void
@ -559,11 +618,23 @@ leaMR(Context* c, unsigned size, Assembler::Memory* b, Assembler::Register* a)
} }
void void
moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, moveCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b) Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
int64_t v = a->value->value();
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant ah(&high);
ResolvedPromise low(v & 0xFFFFFFFF);
Assembler::Constant al(&low);
Assembler::Register bh(b->high);
moveCR(c, 4, &al, b);
moveCR(c, 4, &ah, &bh);
} else {
rex(c, 0x48, b->low); rex(c, 0x48, b->low);
c->code.append(0xb8 | b->low); c->code.append(0xb8 | b->low);
if (a->value->resolved()) { if (a->value->resolved()) {
@ -573,6 +644,7 @@ moveCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
c->code.appendAddress(static_cast<uintptr_t>(0)); c->code.appendAddress(static_cast<uintptr_t>(0));
} }
} }
}
void void
moveCM(Context* c, unsigned size, Assembler::Constant* a, moveCM(Context* c, unsigned size, Assembler::Constant* a,
@ -629,10 +701,25 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
} else { } else {
switch (size) { switch (size) {
case 1: case 1:
if (BytesPerWord == 4 and a->low > rbx) {
if (b->low > rbx) {
c->client->save(rax);
Assembler::Register ax(rax);
moveRR(c, BytesPerWord, a, &ax);
moveRR(c, 1, &ax, b);
c->client->restore(rax);
} else {
moveRR(c, BytesPerWord, a, b);
moveRR(c, 1, b, b);
}
} else {
rex(c); rex(c);
c->code.append(0x0f); c->code.append(0x0f);
c->code.append(0xbe); c->code.append(0xbe);
c->code.append(0xc0 | (b->low << 3) | a->low); c->code.append(0xc0 | (b->low << 3) | a->low);
}
break; break;
case 2: case 2:
@ -674,10 +761,13 @@ moveRM(Context* c, unsigned size, Assembler::Register* a, Assembler::Memory* b)
} }
} else { } else {
if (a->low > rbx) { if (a->low > rbx) {
Assembler::Register ax(c->client->acquireTemporary(rax)); c->client->save(rax);
Assembler::Register ax(rax);
moveRR(c, BytesPerWord, a, &ax); moveRR(c, BytesPerWord, a, &ax);
moveRM(c, 1, &ax, b); moveRM(c, 1, &ax, b);
c->client->releaseTemporary(ax.low);
c->client->restore(rax);
} else { } else {
encode(c, 0x88, a->low, b, false); encode(c, 0x88, a->low, b, false);
} }
@ -709,15 +799,32 @@ move4To8RR(Context* c, unsigned size UNUSED, Assembler::Register* a,
if (a->low == rax and b->low == rax and b->high == rdx) { if (a->low == rax and b->low == rax and b->high == rdx) {
c->code.append(0x99); // cdq c->code.append(0x99); // cdq
} else { } else {
Assembler::Register axdx(c->client->acquireTemporary(rax), Assembler::Register axdx(rax, rdx);
c->client->acquireTemporary(rdx)); Assembler::Register dx(rdx);
Assembler::Register bh(b->high);
bool saveAX = a->low != rax and b->low != rax and b->high != rax;
bool saveDX = b->low != rdx and b->high != rdx;
if (saveDX) c->client->save(rdx);
if (saveAX) c->client->save(rax);
if (a->low != rax) {
moveRR(c, 4, a, &axdx); moveRR(c, 4, a, &axdx);
move4To8RR(c, 0, &axdx, &axdx); }
moveRR(c, 8, &axdx, b);
c->client->releaseTemporary(axdx.low); move4To8RR(c, 0, &axdx, &axdx);
c->client->releaseTemporary(axdx.high);
if (b->low != rax) {
moveRR(c, 4, &axdx, b);
}
if (b->high != rdx) {
moveRR(c, 4, &dx, &bh);
}
if (saveAX) c->client->restore(rax);
if (saveDX) c->client->restore(rdx);
} }
} }
} }
@ -803,15 +910,29 @@ move4To8MR(Context* c, unsigned, Assembler::Memory* a, Assembler::Register* b)
if (BytesPerWord == 8) { if (BytesPerWord == 8) {
encode(c, 0x63, b->low, a, true); encode(c, 0x63, b->low, a, true);
} else { } else {
Assembler::Register axdx(c->client->acquireTemporary(rax), Assembler::Register axdx(rax, rdx);
c->client->acquireTemporary(rdx)); Assembler::Register dx(rdx);
Assembler::Register bh(b->high);
bool saveAX = b->low != rax and b->high != rax;
bool saveDX = b->low != rdx and b->high != rdx;
if (saveDX) c->client->save(rdx);
if (saveAX) c->client->save(rax);
moveMR(c, 4, a, &axdx); moveMR(c, 4, a, &axdx);
move4To8RR(c, 0, &axdx, &axdx); move4To8RR(c, 0, &axdx, &axdx);
moveRR(c, 8, &axdx, b);
c->client->releaseTemporary(axdx.low); if (b->low != rax) {
c->client->releaseTemporary(axdx.high); moveRR(c, 4, &axdx, b);
}
if (b->high != rdx) {
moveRR(c, 4, &dx, &bh);
}
if (saveAX) c->client->restore(rax);
if (saveDX) c->client->restore(rdx);
} }
} }
@ -867,14 +988,40 @@ addCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
} }
} }
void
subtractBorrowCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register* b)
{
assert(c, BytesPerWord == 8 or size == 4);
int64_t v = a->value->value();
if (isInt8(v)) {
c->code.append(0x83);
c->code.append(0xd8 | b->low);
c->code.append(v);
} else {
abort(c);
}
}
void void
subtractCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, subtractCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
Assembler::Register* b) Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo
int64_t v = a->value->value(); int64_t v = a->value->value();
if (v) { if (v) {
if (BytesPerWord == 4 and size == 8) {
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant ah(&high);
ResolvedPromise low(v & 0xFFFFFFFF);
Assembler::Constant al(&low);
Assembler::Register bh(b->high);
subtractCR(c, 4, &al, b);
subtractBorrowCR(c, 4, &ah, &bh);
} else {
rex(c); rex(c);
if (isInt8(v)) { if (isInt8(v)) {
c->code.append(0x83); c->code.append(0x83);
@ -889,6 +1036,7 @@ subtractCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
} }
} }
} }
}
void void
subtractRR(Context* c, unsigned size UNUSED, Assembler::Register* a, subtractRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
@ -902,15 +1050,32 @@ subtractRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
} }
void void
addRR(Context* c, unsigned size UNUSED, Assembler::Register* a, addCarryRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo assert(c, BytesPerWord == 8 or size == 4);
rex(c);
c->code.append(0x11);
c->code.append(0xc0 | (a->low << 3) | b->low);
}
void
addRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b)
{
if (BytesPerWord == 4 and size == 8) {
Assembler::Register ah(a->high);
Assembler::Register bh(b->high);
addRR(c, 4, a, b);
addCarryRR(c, 4, &ah, &bh);
} else {
rex(c); rex(c);
c->code.append(0x01); c->code.append(0x01);
c->code.append(0xc0 | (a->low << 3) | b->low); c->code.append(0xc0 | (a->low << 3) | b->low);
} }
}
void void
addRM(Context* c, unsigned size UNUSED, Assembler::Register* a, addRM(Context* c, unsigned size UNUSED, Assembler::Register* a,
@ -966,16 +1131,21 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
{ {
if (BytesPerWord == 4 and size == 8) { if (BytesPerWord == 4 and size == 8) {
abort(c); // todo: sync stack first Assembler::Register axdx(rax, rdx);
Assembler::Register dx(rdx);
Assembler::Register bh(b->high);
Assembler::Register axdx(c->client->acquireTemporary(rax), bool saveAX = b->low != rax and b->high != rax;
c->client->acquireTemporary(rdx)); bool saveDX = b->low != rdx and b->high != rdx;
if (saveDX) c->client->save(rdx);
if (saveAX) c->client->save(rax);
pushR(c, size, a); pushR(c, size, a);
pushR(c, size, b); pushR(c, size, b);
ResolvedPromise addressPromise(reinterpret_cast<intptr_t>(divideLong)); Assembler::Constant address
Assembler::Constant address(&addressPromise); (resolved(c, reinterpret_cast<intptr_t>(divideLong)));
callC(c, BytesPerWord, &address); callC(c, BytesPerWord, &address);
ResolvedPromise offsetPromise(16); ResolvedPromise offsetPromise(16);
@ -983,10 +1153,16 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register stack(rsp); Assembler::Register stack(rsp);
addCR(c, BytesPerWord, &offset, &stack); addCR(c, BytesPerWord, &offset, &stack);
moveRR(c, size, &axdx, b); if (b->low != rax) {
moveRR(c, 4, &axdx, b);
}
c->client->releaseTemporary(axdx.low); if (b->high != rdx) {
c->client->releaseTemporary(axdx.high); moveRR(c, 4, &dx, &bh);
}
if (saveAX) c->client->restore(rax);
if (saveDX) c->client->restore(rdx);
} else { } else {
Assembler::Register ax(rax); Assembler::Register ax(rax);
Assembler::Register divisor(a->low); Assembler::Register divisor(a->low);
@ -1000,7 +1176,6 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
if (b->low != rax) { if (b->low != rax) {
c->client->save(rax); c->client->save(rax);
c->client->acquireTemporary(rax);
moveRR(c, BytesPerWord, b, &ax); moveRR(c, BytesPerWord, b, &ax);
} }
@ -1012,7 +1187,6 @@ divideRR(Context* c, unsigned size, Assembler::Register* a,
if (b->low != rax) { if (b->low != rax) {
moveRR(c, BytesPerWord, &ax, b); moveRR(c, BytesPerWord, &ax, b);
c->client->releaseTemporary(rax);
c->client->restore(rax); c->client->restore(rax);
} }
@ -1042,16 +1216,21 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
{ {
if (BytesPerWord == 4 and size == 8) { if (BytesPerWord == 4 and size == 8) {
abort(c); // todo: sync stack first Assembler::Register axdx(rax, rdx);
Assembler::Register dx(rdx);
Assembler::Register bh(b->high);
Assembler::Register axdx(c->client->acquireTemporary(rax), bool saveAX = b->low != rax and b->high != rax;
c->client->acquireTemporary(rdx)); bool saveDX = b->low != rdx and b->high != rdx;
if (saveDX) c->client->save(rdx);
if (saveAX) c->client->save(rax);
pushR(c, size, a); pushR(c, size, a);
pushR(c, size, b); pushR(c, size, b);
ResolvedPromise addressPromise(reinterpret_cast<intptr_t>(moduloLong)); Assembler::Constant address
Assembler::Constant address(&addressPromise); (resolved(c, reinterpret_cast<intptr_t>(moduloLong)));
callC(c, BytesPerWord, &address); callC(c, BytesPerWord, &address);
ResolvedPromise offsetPromise(16); ResolvedPromise offsetPromise(16);
@ -1059,10 +1238,16 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register stack(rsp); Assembler::Register stack(rsp);
addCR(c, BytesPerWord, &offset, &stack); addCR(c, BytesPerWord, &offset, &stack);
moveRR(c, size, &axdx, b); if (b->low != rax) {
moveRR(c, 4, &axdx, b);
}
c->client->releaseTemporary(axdx.low); if (b->high != rdx) {
c->client->releaseTemporary(axdx.high); moveRR(c, 4, &dx, &bh);
}
if (saveAX) c->client->restore(rax);
if (saveDX) c->client->restore(rdx);
} else { } else {
Assembler::Register ax(rax); Assembler::Register ax(rax);
Assembler::Register dx(rdx); Assembler::Register dx(rdx);
@ -1077,7 +1262,6 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
if (b->low != rax) { if (b->low != rax) {
c->client->save(rax); c->client->save(rax);
c->client->acquireTemporary(rax);
moveRR(c, BytesPerWord, b, &ax); moveRR(c, BytesPerWord, b, &ax);
} }
@ -1089,7 +1273,9 @@ remainderRR(Context* c, unsigned size, Assembler::Register* a,
if (b->low != rdx) { if (b->low != rdx) {
moveRR(c, BytesPerWord, &dx, b); moveRR(c, BytesPerWord, &dx, b);
c->client->releaseTemporary(rax); }
if (b->low != rax) {
c->client->restore(rax); c->client->restore(rax);
} }
@ -1215,10 +1401,25 @@ shift(Context* c, int type, Assembler::Register* a, Assembler::Register* b) {
c->code.append(0xd3); c->code.append(0xd3);
c->code.append(type | b->low); c->code.append(type | b->low);
} else { } else {
Assembler::Register cx(c->client->acquireTemporary(rcx)); Assembler::Register target(b->low);
if (b->low == rcx) {
target.low = c->client->acquireTemporary();
moveRR(c, BytesPerWord, b, &target);
} else {
c->client->save(rcx);
}
Assembler::Register cx(rcx);
moveRR(c, BytesPerWord, a, &cx); moveRR(c, BytesPerWord, a, &cx);
shift(c, type, &cx, b); shift(c, type, &cx, b);
c->client->releaseTemporary(cx.low);
if (b->low == rcx) {
moveRR(c, BytesPerWord, &target, b);
c->client->releaseTemporary(target.low);
} else {
c->client->restore(rcx);
}
} }
} }
@ -1346,21 +1547,41 @@ compareCR(Context* c, unsigned size UNUSED, Assembler::Constant* a,
} }
void void
compareCM(Context* c, unsigned size UNUSED, Assembler::Constant* a, compareCM(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Memory* b) Assembler::Memory* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); int64_t v = a->value->value();
encode(c, isInt8(a->value->value()) ? 0x83 : 0x81, 7, b, true); if (BytesPerWord == 4 and size == 8) {
ResolvedPromise low(v & 0xFFFFFFFF);
Assembler::Constant al(&low);
if (isInt8(a->value->value())) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
c->code.append(a->value->value()); Assembler::Constant ah(&high);
} else if (isInt32(a->value->value())) {
c->code.append4(a->value->value()); Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale);
compareCM(c, 4, &ah, &bh);
// if the high order bits are equal, we compare the low order
// bits; otherwise, we jump past that comparison
c->code.append(0x0f);
c->code.append(0x85); // jne
c->code.append4(2);
compareCM(c, 4, &al, b);
} else {
encode(c, isInt8(v) ? 0x83 : 0x81, 7, b, true);
if (isInt8(v)) {
c->code.append(v);
} else if (isInt32(v)) {
c->code.append4(v);
} else { } else {
abort(c); abort(c);
} }
} }
}
void void
compareRM(Context* c, unsigned size UNUSED, Assembler::Register* a, compareRM(Context* c, unsigned size UNUSED, Assembler::Register* a,
@ -1557,22 +1778,26 @@ class MyAssembler: public Assembler {
} }
} }
virtual void getTargets(UnaryOperation /*op*/, unsigned /*size*/, virtual void getTargets(BinaryOperation op, unsigned size,
Register* r) Register* a, Register* b, bool* syncStack)
{ {
// todo
r->low = NoRegister;
r->high = NoRegister;
}
virtual void getTargets(BinaryOperation /*op*/, unsigned /*size*/,
Register* a, Register* b)
{
// todo
a->low = NoRegister; a->low = NoRegister;
a->high = NoRegister; a->high = NoRegister;
b->low = NoRegister; b->low = NoRegister;
b->high = NoRegister; b->high = NoRegister;
*syncStack = false;
switch (op) {
case Divide:
case Remainder:
if (BytesPerWord == 4 and size == 8) {
*syncStack = true;
}
break;
default:
break;
}
} }
virtual void apply(Operation op) { virtual void apply(Operation op) {