various 32-bit fixes

This commit is contained in:
Joel Dice 2008-05-22 11:15:18 -06:00
parent 21cb1c3c8f
commit 3326aafdac
3 changed files with 102 additions and 66 deletions

View File

@ -768,9 +768,14 @@ matchRegister(Context* c UNUSED, Site* s, uint64_t mask)
assert(c, s->type(c) == RegisterOperand); assert(c, s->type(c) == RegisterOperand);
RegisterSite* r = static_cast<RegisterSite*>(s); RegisterSite* r = static_cast<RegisterSite*>(s);
return ((static_cast<uint64_t>(1) << r->register_.low) & mask) if (r->low) {
and (r->register_.high == NoRegister r->sync(c);
or ((static_cast<uint64_t>(1) << (r->register_.high + 32)) & mask)); return ((static_cast<uint64_t>(1) << r->register_.low) & mask)
and (r->register_.high == NoRegister
or ((static_cast<uint64_t>(1) << (r->register_.high + 32)) & mask));
} else {
return false;
}
} }
bool bool

View File

@ -697,12 +697,17 @@ moveRR(Context* c, unsigned size, Assembler::Register* a,
} else { } else {
switch (size) { switch (size) {
case 1: case 1:
assert(c, BytesPerWord == 8 or (a->low <= rbx and b->low <= rbx)); if (BytesPerWord == 4 and a->low > rbx) {
assert(c, b->low <= rbx);
rex(c); moveRR(c, BytesPerWord, a, b);
c->code.append(0x0f); moveRR(c, 1, b, b);
c->code.append(0xbe); } else {
c->code.append(0xc0 | (b->low << 3) | a->low); rex(c);
c->code.append(0x0f);
c->code.append(0xbe);
c->code.append(0xc0 | (b->low << 3) | a->low);
}
break; break;
case 2: case 2:
@ -1575,6 +1580,27 @@ unsignedShiftRightCR(Context* c, unsigned size, Assembler::Constant* a,
doShift(c, unsignedShiftRightRR, 0xe8, size, a, b); doShift(c, unsignedShiftRightRR, 0xe8, size, a, b);
} }
void
multiwordCompare(Context* c, Assembler::Operand* al, Assembler::Operand* ah,
Assembler::Operand* bl, Assembler::Operand* bh,
BinaryOperationType op)
{
op(c, BytesPerWord, 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
unsigned comparisonOffset = c->code.length();
c->code.append4(0);
op(c, BytesPerWord, al, bl);
int32_t comparisonSize = c->code.length() - comparisonOffset - 4;
c->code.set(comparisonOffset, &comparisonSize, 4);
}
void void
compareRR(Context* c, unsigned size, Assembler::Register* a, compareRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
@ -1583,15 +1609,7 @@ compareRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register ah(a->high); Assembler::Register ah(a->high);
Assembler::Register bh(b->high); Assembler::Register bh(b->high);
compareRR(c, 4, &ah, &bh); multiwordCompare(c, a, &ah, b, &bh, CAST2(compareRR));
// 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);
compareRR(c, 4, a, b);
} else { } else {
if (size == 8) rex(c); if (size == 8) rex(c);
c->code.append(0x39); c->code.append(0x39);
@ -1626,20 +1644,7 @@ compareCR(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Register bh(b->high); Assembler::Register bh(b->high);
compareCR(c, 4, &ah, &bh); multiwordCompare(c, &al, &ah, b, &bh, CAST2(compareCR));
// 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
unsigned comparisonOffset = c->code.length();
c->code.append4(0);
compareCR(c, 4, &al, b);
int32_t comparisonSize = c->code.length() - comparisonOffset - 4;
c->code.set(comparisonOffset, &comparisonSize, 4);
} else { } else {
if (isInt32(v)) { if (isInt32(v)) {
if (size == 8) rex(c); if (size == 8) rex(c);
@ -1676,20 +1681,7 @@ compareCM(Context* c, unsigned size, Assembler::Constant* a,
Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale); Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale);
compareCM(c, 4, &ah, &bh); multiwordCompare(c, &al, &ah, b, &bh, CAST2(compareCM));
// 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
unsigned comparisonOffset = c->code.length();
c->code.append4(0);
compareCM(c, 4, &al, b);
int32_t comparisonSize = c->code.length() - comparisonOffset - 4;
c->code.set(comparisonOffset, &comparisonSize, 4);
} else { } else {
encode(c, isInt8(v) ? 0x83 : 0x81, 7, b, true); encode(c, isInt8(v) ? 0x83 : 0x81, 7, b, true);
@ -1707,48 +1699,75 @@ void
compareRM(Context* c, unsigned size, Assembler::Register* a, compareRM(Context* c, unsigned size, Assembler::Register* a,
Assembler::Memory* b) Assembler::Memory* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
Assembler::Register ah(a->high);
Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale);
if (BytesPerWord == 8 and size == 4) { multiwordCompare(c, a, &ah, b, &bh, CAST2(compareRM));
move4To8RR(c, size, a, a); } else {
if (BytesPerWord == 8 and size == 4) {
move4To8RR(c, size, a, a);
}
encode(c, 0x39, a->low, b, true);
} }
encode(c, 0x39, a->low, b, true);
} }
void void
compareMR(Context* c, unsigned size UNUSED, Assembler::Memory* a, compareMR(Context* c, unsigned size, Assembler::Memory* a,
Assembler::Register* b) Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
Assembler::Register bh(b->high);
if (BytesPerWord == 8 and size == 4) { multiwordCompare(c, a, &ah, b, &bh, CAST2(compareMR));
move4To8RR(c, size, b, b); } else {
if (BytesPerWord == 8 and size == 4) {
move4To8RR(c, size, b, b);
}
encode(c, 0x3b, b->low, a, true);
} }
encode(c, 0x3b, b->low, a, true);
} }
void void
compareMM(Context* c, unsigned size UNUSED, Assembler::Memory* a, compareMM(Context* c, unsigned size, Assembler::Memory* a,
Assembler::Memory* b) Assembler::Memory* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
Assembler::Memory ah(a->base, a->offset + 4, a->index, a->scale);
Assembler::Memory bh(b->base, b->offset + 4, b->index, b->scale);
Assembler::Register tmp(c->client->acquireTemporary()); multiwordCompare(c, a, &ah, b, &bh, CAST2(compareMM));
moveMR(c, size, a, &tmp); } else {
compareRM(c, size, &tmp, b); Assembler::Register tmp(c->client->acquireTemporary());
c->client->releaseTemporary(tmp.low); moveMR(c, size, a, &tmp);
compareRM(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
} }
void void
compareRC(Context* c, unsigned size UNUSED, Assembler::Register* a, compareRC(Context* c, unsigned size, Assembler::Register* a,
Assembler::Constant* b) Assembler::Constant* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
Assembler::Register ah(a->high);
Assembler::Register tmp(c->client->acquireTemporary()); int64_t v = b->value->value();
moveCR(c, size, b, &tmp);
compareRR(c, size, a, &tmp); ResolvedPromise low(v & 0xFFFFFFFF);
c->client->releaseTemporary(tmp.low); Assembler::Constant bl(&low);
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
Assembler::Constant bh(&high);
multiwordCompare(c, a, &ah, &bl, &bh, CAST2(compareRC));
} else {
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, b, &tmp);
compareRR(c, size, a, &tmp);
c->client->releaseTemporary(tmp.low);
}
} }
void void

View File

@ -312,5 +312,17 @@ public class Misc {
foo.array = new int[3]; foo.array = new int[3];
foo.a = (foo.a + 1) % foo.array.length; foo.a = (foo.a + 1) % foo.array.length;
} }
{ int j = 0;
byte[] decodeTable = new byte[256];
for (int i = 'A'; i <= 'Z'; ++i) decodeTable[i] = (byte) j++;
for (int i = 'a'; i <= 'z'; ++i) decodeTable[i] = (byte) j++;
for (int i = '0'; i <= '9'; ++i) decodeTable[i] = (byte) j++;
decodeTable['+'] = (byte) j++;
decodeTable['/'] = (byte) j++;
decodeTable['='] = 0;
expect(decodeTable['a'] != 0);
}
} }
} }