mirror of
https://github.com/corda/corda.git
synced 2025-01-09 06:23:04 +00:00
support 64-bit multiplies on 32-bit systems
This commit is contained in:
parent
4c2d44099b
commit
59f92b6208
116
src/x86.cpp
116
src/x86.cpp
@ -35,6 +35,12 @@ enum {
|
|||||||
r15 = 15,
|
r15 = 15,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int64_t FORCE_ALIGN
|
||||||
|
multiplyLong(int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t FORCE_ALIGN
|
int64_t FORCE_ALIGN
|
||||||
divideLong(int64_t a, int64_t b)
|
divideLong(int64_t a, int64_t b)
|
||||||
{
|
{
|
||||||
@ -438,9 +444,9 @@ pushR(Context*, unsigned, Assembler::Register*);
|
|||||||
void
|
void
|
||||||
pushC(Context* c, unsigned size, Assembler::Constant* a)
|
pushC(Context* c, unsigned size, Assembler::Constant* a)
|
||||||
{
|
{
|
||||||
int64_t v = a->value->value();
|
|
||||||
|
|
||||||
if (BytesPerWord == 4 and size == 8) {
|
if (BytesPerWord == 4 and size == 8) {
|
||||||
|
int64_t v = a->value->value();
|
||||||
|
|
||||||
ResolvedPromise low(v & 0xFFFFFFFF);
|
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||||
Assembler::Constant al(&low);
|
Assembler::Constant al(&low);
|
||||||
|
|
||||||
@ -450,17 +456,26 @@ pushC(Context* c, unsigned size, Assembler::Constant* a)
|
|||||||
pushC(c, 4, &ah);
|
pushC(c, 4, &ah);
|
||||||
pushC(c, 4, &al);
|
pushC(c, 4, &al);
|
||||||
} else {
|
} else {
|
||||||
if (isInt8(v)) {
|
if (a->value->resolved()) {
|
||||||
c->code.append(0x6a);
|
int64_t v = a->value->value();
|
||||||
c->code.append(v);
|
if (isInt8(v)) {
|
||||||
} else if (isInt32(v)) {
|
c->code.append(0x6a);
|
||||||
c->code.append(0x68);
|
c->code.append(v);
|
||||||
c->code.append4(v);
|
} else if (isInt32(v)) {
|
||||||
|
c->code.append(0x68);
|
||||||
|
c->code.append4(v);
|
||||||
|
} else {
|
||||||
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
|
moveCR(c, size, a, &tmp);
|
||||||
|
pushR(c, size, &tmp);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Assembler::Register tmp(c->client->acquireTemporary());
|
assert(c, BytesPerWord == 4);
|
||||||
moveCR(c, size, a, &tmp);
|
|
||||||
pushR(c, size, &tmp);
|
c->code.append(0x68);
|
||||||
c->client->releaseTemporary(tmp.low);
|
appendImmediateTask(c, a->value, c->code.length());
|
||||||
|
c->code.appendAddress(static_cast<uintptr_t>(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1174,41 +1189,71 @@ addRM(Context* c, unsigned size UNUSED, Assembler::Register* a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
multiplyRR(Context* c, unsigned size UNUSED, Assembler::Register* a,
|
multiplyRR(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) {
|
||||||
|
pushR(c, size, a);
|
||||||
|
pushR(c, size, b);
|
||||||
|
|
||||||
rex(c);
|
Assembler::Constant address
|
||||||
c->code.append(0x0f);
|
(resolved(c, reinterpret_cast<intptr_t>(multiplyLong)));
|
||||||
c->code.append(0xaf);
|
callC(c, BytesPerWord, &address);
|
||||||
c->code.append(0xc0 | (b->low << 3) | a->low);
|
|
||||||
|
Assembler::Register axdx(rax, rdx);
|
||||||
|
moveRR(c, 4, &axdx, b);
|
||||||
|
|
||||||
|
ResolvedPromise offsetPromise(16);
|
||||||
|
Assembler::Constant offset(&offsetPromise);
|
||||||
|
Assembler::Register stack(rsp);
|
||||||
|
addCR(c, BytesPerWord, &offset, &stack);
|
||||||
|
} else {
|
||||||
|
rex(c);
|
||||||
|
c->code.append(0x0f);
|
||||||
|
c->code.append(0xaf);
|
||||||
|
c->code.append(0xc0 | (b->low << 3) | a->low);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
multiplyCR(Context* c, unsigned size, Assembler::Constant* a,
|
multiplyCR(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) {
|
||||||
|
pushC(c, size, a);
|
||||||
|
pushR(c, size, b);
|
||||||
|
|
||||||
int64_t v = a->value->value();
|
Assembler::Constant address
|
||||||
if (v) {
|
(resolved(c, reinterpret_cast<intptr_t>(multiplyLong)));
|
||||||
if (isInt32(v)) {
|
callC(c, BytesPerWord, &address);
|
||||||
rex(c);
|
|
||||||
if (isInt8(v)) {
|
Assembler::Register axdx(rax, rdx);
|
||||||
c->code.append(0x6b);
|
moveRR(c, 4, &axdx, b);
|
||||||
c->code.append(0xc0 | (b->low << 3) | b->low);
|
|
||||||
c->code.append(v);
|
ResolvedPromise offsetPromise(16);
|
||||||
|
Assembler::Constant offset(&offsetPromise);
|
||||||
|
Assembler::Register stack(rsp);
|
||||||
|
addCR(c, BytesPerWord, &offset, &stack);
|
||||||
|
} else {
|
||||||
|
int64_t v = a->value->value();
|
||||||
|
if (v) {
|
||||||
|
if (isInt32(v)) {
|
||||||
|
rex(c);
|
||||||
|
if (isInt8(v)) {
|
||||||
|
c->code.append(0x6b);
|
||||||
|
c->code.append(0xc0 | (b->low << 3) | b->low);
|
||||||
|
c->code.append(v);
|
||||||
|
} else {
|
||||||
|
c->code.append(0x69);
|
||||||
|
c->code.append(0xc0 | (b->low << 3) | b->low);
|
||||||
|
c->code.append4(v);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
c->code.append(0x69);
|
Assembler::Register tmp(c->client->acquireTemporary());
|
||||||
c->code.append(0xc0 | (b->low << 3) | b->low);
|
moveCR(c, size, a, &tmp);
|
||||||
c->code.append4(v);
|
multiplyRR(c, size, &tmp, b);
|
||||||
|
c->client->releaseTemporary(tmp.low);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
Assembler::Register tmp(c->client->acquireTemporary());
|
|
||||||
moveCR(c, size, a, &tmp);
|
|
||||||
multiplyRR(c, size, &tmp, b);
|
|
||||||
c->client->releaseTemporary(tmp.low);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1996,6 +2041,7 @@ class MyAssembler: public Assembler {
|
|||||||
*syncStack = false;
|
*syncStack = false;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
case Multiply:
|
||||||
case Divide:
|
case Divide:
|
||||||
case Remainder:
|
case Remainder:
|
||||||
if (BytesPerWord == 4 and size == 8) {
|
if (BytesPerWord == 4 and size == 8) {
|
||||||
|
Loading…
Reference in New Issue
Block a user