enable 64-bit various operations on 32-bit systems

This commit is contained in:
Joel Dice 2008-04-29 10:56:29 -06:00
parent 9dafe37ff3
commit 4652b7aea0

View File

@ -1042,24 +1042,35 @@ moveZRR(Context* c, unsigned size, Assembler::Register* a,
} }
void void
addCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, addCR(Context* c, unsigned size, 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) {
rex(c); if (BytesPerWord == 4 and size == 8) {
if (isInt8(v)) { ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
c->code.append(0x83); Assembler::Constant ah(&high);
c->code.append(0xc0 | b->low);
c->code.append(v); ResolvedPromise low(v & 0xFFFFFFFF);
} else if (isInt32(v)) { Assembler::Constant al(&low);
c->code.append(0x81);
c->code.append(0xc0 | b->low); Assembler::Register bh(b->high);
c->code.append4(v);
addCR(c, 4, &al, b);
addCarryCR(c, 4, &ah, &bh);
} else { } else {
abort(c); rex(c);
if (isInt8(v)) {
c->code.append(0x83);
c->code.append(0xc0 | b->low);
c->code.append(v);
} else if (isInt32(v)) {
c->code.append(0x81);
c->code.append(0xc0 | b->low);
c->code.append4(v);
} else {
abort(c);
}
} }
} }
} }
@ -1340,29 +1351,40 @@ andRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
} }
void void
andCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, andCR(Context* c, unsigned size, 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 (isInt32(v)) { if (BytesPerWord == 4 and size == 8) {
rex(c); ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
if (isInt8(v)) { Assembler::Constant ah(&high);
c->code.append(0x83);
c->code.append(0xe0 | b->low); ResolvedPromise low(v & 0xFFFFFFFF);
c->code.append(v); Assembler::Constant al(&low);
} else {
c->code.append(0x81); Assembler::Register bh(b->high);
c->code.append(0xe0 | b->low);
c->code.append4(v); andCR(c, 4, &al, b);
} andCR(c, 4, &ah, &bh);
} else { } else {
Assembler::Register tmp(c->client->acquireTemporary()); if (isInt32(v)) {
moveCR(c, size, a, &tmp); rex(c);
andRR(c, size, &tmp, b); if (isInt8(v)) {
c->client->releaseTemporary(tmp.low); c->code.append(0x83);
c->code.append(0xe0 | b->low);
c->code.append(v);
} else {
c->code.append(0x81);
c->code.append(0xe0 | b->low);
c->code.append4(v);
}
} else {
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, a, &tmp);
andRR(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
} }
} }
@ -1396,40 +1418,57 @@ orRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
} }
void void
xorRR(Context* c, unsigned size UNUSED, Assembler::Register* a, xorRR(Context* c, unsigned size, Assembler::Register* a,
Assembler::Register* b) Assembler::Register* b)
{ {
assert(c, BytesPerWord == 8 or size == 4); // todo if (BytesPerWord == 4 and size == 8) {
Assembler::Register ah(a->high);
Assembler::Register bh(b->high);
rex(c); xorRR(c, 4, a, b);
c->code.append(0x31); xorRR(c, 4, &ah, &bh);
c->code.append(0xc0 | (a->low << 3) | b->low); } else {
rex(c);
c->code.append(0x31);
c->code.append(0xc0 | (a->low << 3) | b->low);
}
} }
void void
xorCR(Context* c, unsigned size UNUSED, Assembler::Constant* a, xorCR(Context* c, unsigned size, 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 (isInt32(v)) { if (BytesPerWord == 4 and size == 8) {
rex(c); ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
if (isInt8(v)) { Assembler::Constant ah(&high);
c->code.append(0x83);
c->code.append(0xf0 | b->low); ResolvedPromise low(v & 0xFFFFFFFF);
c->code.append(v); Assembler::Constant al(&low);
} else {
c->code.append(0x81); Assembler::Register bh(b->high);
c->code.append(0xf0 | b->low);
c->code.append4(v); xorCR(c, 4, &al, b);
} xorCR(c, 4, &ah, &bh);
} else { } else {
Assembler::Register tmp(c->client->acquireTemporary()); if (isInt32(v)) {
moveCR(c, size, a, &tmp); rex(c);
xorRR(c, size, &tmp, b); if (isInt8(v)) {
c->client->releaseTemporary(tmp.low); c->code.append(0x83);
c->code.append(0xf0 | b->low);
c->code.append(v);
} else {
c->code.append(0x81);
c->code.append(0xf0 | b->low);
c->code.append4(v);
}
} else {
Assembler::Register tmp(c->client->acquireTemporary());
moveCR(c, size, a, &tmp);
xorRR(c, size, &tmp, b);
c->client->releaseTemporary(tmp.low);
}
} }
} }
} }