mirror of
https://github.com/corda/corda.git
synced 2025-01-08 14:03:06 +00:00
sketch some 64-bit-arithmetic-on-32-bit-system instructions
This commit is contained in:
parent
be42c325d8
commit
640d1d0654
151
src/compiler.cpp
151
src/compiler.cpp
@ -52,6 +52,18 @@ class CodePromise;
|
|||||||
class MyPromise;
|
class MyPromise;
|
||||||
class RegisterReference;
|
class RegisterReference;
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
divideLong(int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t
|
||||||
|
moduloLong(int64_t a, int64_t b)
|
||||||
|
{
|
||||||
|
return a % b;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
isInt8(intptr_t v)
|
isInt8(intptr_t v)
|
||||||
{
|
{
|
||||||
@ -330,7 +342,9 @@ class MyOperand: public Operand {
|
|||||||
jne,
|
jne,
|
||||||
jmp,
|
jmp,
|
||||||
add,
|
add,
|
||||||
|
addc,
|
||||||
sub,
|
sub,
|
||||||
|
subb,
|
||||||
mul,
|
mul,
|
||||||
div,
|
div,
|
||||||
rem,
|
rem,
|
||||||
@ -1244,10 +1258,19 @@ RegisterOperand::accept(Context* c, Operation operation,
|
|||||||
} else {
|
} else {
|
||||||
abort(c);
|
abort(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case addc:
|
||||||
|
if (isInt8(operand->value)) {
|
||||||
|
c->code.append(0x83);
|
||||||
|
c->code.append(0xd0 | value(c));
|
||||||
|
c->code.append(operand->value);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case and_: {
|
case and_: {
|
||||||
rex(c);
|
rex(c);
|
||||||
if (isInt8(operand->value)) {
|
if (isInt8(operand->value)) {
|
||||||
@ -1636,12 +1659,7 @@ MemoryOperand::apply(Context* c, Operation operation)
|
|||||||
dx->accept(c, mov, high);
|
dx->accept(c, mov, high);
|
||||||
|
|
||||||
ax->apply(c, neg);
|
ax->apply(c, neg);
|
||||||
|
dx->accept(c, addc, immediate(c, 0), dx);
|
||||||
// adc 0,%rdx
|
|
||||||
c->code.append(0x83);
|
|
||||||
c->code.append(0xd0 | rdx);
|
|
||||||
c->code.append(0);
|
|
||||||
|
|
||||||
dx->apply(c, neg);
|
dx->apply(c, neg);
|
||||||
|
|
||||||
low->accept(c, mov, ax);
|
low->accept(c, mov, ax);
|
||||||
@ -1682,9 +1700,34 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case add: {
|
case add: {
|
||||||
encode(c, 0x01, operand->value(c), this, true);
|
if (selection == DefaultSelection) {
|
||||||
|
encode(c, 0x01, operand->value(c), this, true);
|
||||||
|
} else {
|
||||||
|
assert(c, selection == S8Selection);
|
||||||
|
|
||||||
|
RegisterOperand* ax = temporary(c, rax);
|
||||||
|
RegisterOperand* dx = temporary(c, rdx);
|
||||||
|
|
||||||
|
ax->accept(c, mov, register_(c, operand->value(c)));
|
||||||
|
dx->accept(c, mov, register_(c, operand->high(c)));
|
||||||
|
|
||||||
|
memory(c, base, displacement, index, scale)->accept(c, add, ax);
|
||||||
|
memory(c, base, displacement + BytesPerWord, index, scale)->accept
|
||||||
|
(c, addc, dx);
|
||||||
|
|
||||||
|
ax->release(c);
|
||||||
|
dx->release(c);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case addc:
|
||||||
|
if (operand->selection == DefaultSelection) {
|
||||||
|
encode(c, 0x11, operand->value(c), this, true);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case div: {
|
case div: {
|
||||||
if (selection == DefaultSelection) {
|
if (selection == DefaultSelection) {
|
||||||
RegisterOperand* ax = temporary(c, rax);
|
RegisterOperand* ax = temporary(c, rax);
|
||||||
@ -1702,7 +1745,12 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
ax->release(c);
|
ax->release(c);
|
||||||
dx->release(c);
|
dx->release(c);
|
||||||
} else {
|
} else {
|
||||||
abort(c);
|
assert(c, selection == S8Selection);
|
||||||
|
|
||||||
|
operand->apply(c, push);
|
||||||
|
apply(c, push);
|
||||||
|
immediate_(c, reinterpret_cast<intptr_t>(divideLong))->apply(c, call);
|
||||||
|
accept(c, mov, register_(c, rax, rdx, S8Selection));
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1753,7 +1801,32 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
|
|
||||||
tmp->release(c);
|
tmp->release(c);
|
||||||
} else {
|
} else {
|
||||||
abort(c);
|
RegisterOperand* tmp = temporary(c);
|
||||||
|
RegisterOperand* ax = temporary(c, rax);
|
||||||
|
RegisterOperand* dx = temporary(c, rdx);
|
||||||
|
|
||||||
|
RegisterOperand* lowSrc = register_(c, operand->value(c));
|
||||||
|
RegisterOperand* highSrc = register_(c, operand->high(c));
|
||||||
|
|
||||||
|
MemoryOperand* lowDst = memory(c, base, displacement, index, scale);
|
||||||
|
MemoryOperand* highDst = memory
|
||||||
|
(c, base, displacement + BytesPerWord, index, scale);
|
||||||
|
|
||||||
|
tmp->accept(c, mov, highSrc);
|
||||||
|
tmp->accept(c, mul, lowDst);
|
||||||
|
ax->accept(c, mov, highDst);
|
||||||
|
ax->accept(c, mul, lowSrc);
|
||||||
|
tmp->accept(c, add, ax);
|
||||||
|
ax->accept(c, mov, lowDst);
|
||||||
|
ax->accept(c, mul, lowSrc);
|
||||||
|
dx->accept(c, add, tmp);
|
||||||
|
|
||||||
|
lowDst->accept(c, mov, rax);
|
||||||
|
highDst->accept(c, mov, rdx);
|
||||||
|
|
||||||
|
tmp->release(c);
|
||||||
|
ax->release(c);
|
||||||
|
dx->release(c);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@ -1762,20 +1835,29 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case rem: {
|
case rem: {
|
||||||
RegisterOperand* ax = temporary(c, rax);
|
if (selection == DefaultSelection) {
|
||||||
RegisterOperand* dx = temporary(c, rdx);
|
RegisterOperand* ax = temporary(c, rax);
|
||||||
ax->accept(c, mov, this);
|
RegisterOperand* dx = temporary(c, rdx);
|
||||||
|
ax->accept(c, mov, this);
|
||||||
|
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0x99);
|
c->code.append(0x99);
|
||||||
rex(c);
|
rex(c);
|
||||||
c->code.append(0xf7);
|
c->code.append(0xf7);
|
||||||
c->code.append(0xf8 | operand->value(c));
|
c->code.append(0xf8 | operand->value(c));
|
||||||
|
|
||||||
accept(c, mov, dx);
|
accept(c, mov, dx);
|
||||||
|
|
||||||
ax->release(c);
|
ax->release(c);
|
||||||
dx->release(c);
|
dx->release(c);
|
||||||
|
} else {
|
||||||
|
assert(c, selection == S8Selection);
|
||||||
|
|
||||||
|
operand->apply(c, push);
|
||||||
|
apply(c, push);
|
||||||
|
immediate_(c, reinterpret_cast<intptr_t>(moduloLong))->apply(c, call);
|
||||||
|
accept(c, mov, register_(c, rax, rdx, S8Selection));
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case shl: {
|
case shl: {
|
||||||
@ -1800,9 +1882,34 @@ MemoryOperand::accept(Context* c, Operation operation,
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case sub: {
|
case sub: {
|
||||||
encode(c, 0x29, operand->value(c), this, true);
|
if (selection == DefaultSelection) {
|
||||||
|
encode(c, 0x29, operand->value(c), this, true);
|
||||||
|
} else {
|
||||||
|
assert(c, selection == S8Selection);
|
||||||
|
|
||||||
|
RegisterOperand* ax = temporary(c, rax);
|
||||||
|
RegisterOperand* dx = temporary(c, rdx);
|
||||||
|
|
||||||
|
ax->accept(c, mov, register_(c, operand->value(c)));
|
||||||
|
dx->accept(c, mov, register_(c, operand->high(c)));
|
||||||
|
|
||||||
|
memory(c, base, displacement, index, scale)->accept(c, sub, ax);
|
||||||
|
memory(c, base, displacement + BytesPerWord, index, scale)->accept
|
||||||
|
(c, subb, dx);
|
||||||
|
|
||||||
|
ax->release(c);
|
||||||
|
dx->release(c);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case subb:
|
||||||
|
if (operand->selection == DefaultSelection) {
|
||||||
|
encode(c, 0x19, operand->value(c), this, true);
|
||||||
|
} else {
|
||||||
|
abort(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case xor_: {
|
case xor_: {
|
||||||
encode(c, 0x31, operand->value(c), this, true);
|
encode(c, 0x31, operand->value(c), this, true);
|
||||||
} break;
|
} break;
|
||||||
|
Loading…
Reference in New Issue
Block a user