mirror of
https://github.com/corda/corda.git
synced 2025-01-08 14:03:06 +00:00
Merge commit 'origin/powerpc' into powerpc
This commit is contained in:
commit
46a6744050
151
src/powerpc.cpp
Normal file → Executable file
151
src/powerpc.cpp
Normal file → Executable file
@ -73,6 +73,7 @@ inline int addis(int rt, int ra, int i) { return D(15, rt, ra, i); }
|
||||
inline int subf(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 40, 0); }
|
||||
inline int subfc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 8, 0); }
|
||||
inline int subfe(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 136, 0); }
|
||||
inline int subfic(int rt, int ra, int i) { return D(8, rt, ra, ri); }
|
||||
inline int mullw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 235, 0); }
|
||||
inline int mulhw(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 75, 0); }
|
||||
inline int mulhwu(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 11, 0); }
|
||||
@ -395,7 +396,14 @@ inline int H(Reg* r) { return r->high; }
|
||||
void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||
{
|
||||
if(size == 8) {
|
||||
abort(con); // todo
|
||||
issue(con, subfic(31, R(a), 32));
|
||||
issue(con, slw(R(b), R(b), R(a)));
|
||||
issue(con, srw(0, H(b), 31));
|
||||
issue(con, or_(R(b), R(b), 0));
|
||||
issue(con, addi(31, R(a), -32));
|
||||
issue(con, slw(0, H(b), 31));
|
||||
issue(con, or_(R(b), R(b), 0));
|
||||
issue(con, slw(H(b), H(b), R(a)));
|
||||
} else
|
||||
issue(con, slw(R(t), R(b), R(a)));
|
||||
}
|
||||
@ -587,7 +595,7 @@ void addR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
}
|
||||
|
||||
void addC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == 4);
|
||||
|
||||
int32_t i = getVal(a);
|
||||
if(i) {
|
||||
@ -607,7 +615,7 @@ void subR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
}
|
||||
|
||||
void subC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == 4);
|
||||
|
||||
int64_t i = getVal(a);
|
||||
if(i) {
|
||||
@ -619,26 +627,28 @@ void subC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
|
||||
void multiplyR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
if(size == 8) {
|
||||
if(BytesPerWord == 8) {
|
||||
// issue(con, mulld(R(t), R(a), R(b)));
|
||||
abort(con);
|
||||
} else {
|
||||
abort(con); // todo
|
||||
}
|
||||
Reg tmp(getTemp(con));
|
||||
issue(con, mullw(H(t), H(a), R(b)));
|
||||
issue(con, mullw(R(tmp), R(a), H(b)));
|
||||
issue(con, add(H(t), H(t), R(tmp)));
|
||||
issue(con, mulhw(R(tmp), R(a), R(b)));
|
||||
issue(con, add(H(t), H(t), R(tmp)));
|
||||
freeTemp(con, R(tmp));
|
||||
} else {
|
||||
issue(con, mullw(R(t), R(a), R(b)));
|
||||
}
|
||||
}
|
||||
|
||||
void multiplyC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
||||
assert(con, size == BytesPerWord);
|
||||
assert(con, size == 4);
|
||||
int64_t i = getVal(a);
|
||||
issue(con, mulli(R(t), R(b), i));
|
||||
}
|
||||
|
||||
void divideR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
if(size == 8 && BytesPerWord == 8) {
|
||||
issue(con, divd(R(t), R(b), R(a)));
|
||||
if(size == 8) {
|
||||
issue(con, 0);
|
||||
issue(con, 0);
|
||||
} else {
|
||||
issue(con, divw(R(t), R(b), R(a)));
|
||||
}
|
||||
@ -650,6 +660,33 @@ void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||
subR(con, size, t, a, t);
|
||||
}
|
||||
|
||||
void andC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
{
|
||||
abort(c); // todo
|
||||
|
||||
int64_t v = a->value->value();
|
||||
|
||||
if(size == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||
Assembler::Constant al(&low);
|
||||
|
||||
Assembler::Register bh(b->high);
|
||||
Assembler::Register dh(dst->high);
|
||||
|
||||
andC(c, 4, &al, b, dst);
|
||||
andC(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, andi(dst->low, b->low, v));
|
||||
if (v >> 16) {
|
||||
issue(c, andis(dst->low, b->low, v >> 16));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
normalize(Context* c, int offset, int index, unsigned scale,
|
||||
bool* preserveIndex)
|
||||
@ -884,90 +921,6 @@ moveCR(Context* c, unsigned srcSize, Assembler::Constant* src,
|
||||
// issue(con, ori(R(t), R(t), lo16(i)));
|
||||
// }
|
||||
|
||||
void
|
||||
andR(Context* c, unsigned size, Assembler::Register* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
{
|
||||
if (size == 8) {
|
||||
Assembler::Register ah(a->high);
|
||||
Assembler::Register bh(b->high);
|
||||
Assembler::Register dh(dst->high);
|
||||
|
||||
andR(c, 4, a, b, dst);
|
||||
andR(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
issue(c, and_(dst->low, a->low, b->low));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
andC(Context* c, unsigned size, Assembler::Constant* a,
|
||||
Assembler::Register* b, Assembler::Register* dst)
|
||||
{
|
||||
int64_t v = a->value->value();
|
||||
|
||||
if (size == 8) {
|
||||
ResolvedPromise high((v >> 32) & 0xFFFFFFFF);
|
||||
Assembler::Constant ah(&high);
|
||||
|
||||
ResolvedPromise low(v & 0xFFFFFFFF);
|
||||
Assembler::Constant al(&low);
|
||||
|
||||
Assembler::Register bh(b->high);
|
||||
Assembler::Register dh(dst->high);
|
||||
|
||||
andC(c, 4, &al, b, dst);
|
||||
andC(c, 4, &ah, &bh, &dh);
|
||||
} else {
|
||||
// bitmasks of the form regex 0*1*0* can be handled in a single
|
||||
// rlwinm instruction, hence the following:
|
||||
|
||||
uint32_t v32 = static_cast<uint32_t>(v);
|
||||
unsigned state = 0;
|
||||
unsigned start;
|
||||
unsigned end = 31;
|
||||
for (unsigned i = 0; i < 32; ++i) {
|
||||
unsigned bit = (v32 >> i) & 1;
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (bit) {
|
||||
start = i;
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (bit == 0) {
|
||||
end = i - 1;
|
||||
state = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (bit) {
|
||||
// not in 0*1*0* form. We can only use andi(s) if either
|
||||
// the topmost or bottommost 16 bits are zero.
|
||||
|
||||
if ((v32 >> 16) == 0) {
|
||||
issue(c, andi(dst->low, b->low, v32));
|
||||
} else if ((v32 & 0xFFFF) == 0) {
|
||||
issue(c, andis(dst->low, b->low, v32 >> 16));
|
||||
} else {
|
||||
moveCR(c, 4, a, 4, dst);
|
||||
andR(c, 4, b, dst, dst);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (state) {
|
||||
issue(c, rlwinm(dst->low, b->low, 0, 31 - end, 31 - start));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
moveAR(Context* c, unsigned srcSize, Assembler::Address* src,
|
||||
unsigned dstSize, Assembler::Register* dst)
|
||||
@ -1289,7 +1242,6 @@ populateTables(ArchitectureContext* c)
|
||||
to[index(Subtract, C)] = CAST3(subC);
|
||||
|
||||
to[index(And, C)] = CAST3(andC);
|
||||
to[index(And, R)] = CAST3(andR);
|
||||
|
||||
to[index(LongCompare, R)] = CAST3(longCompareR);
|
||||
}
|
||||
@ -1378,7 +1330,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
}
|
||||
|
||||
virtual unsigned frameReturnAddressSize() {
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
virtual unsigned frameFooterSize() {
|
||||
@ -1449,6 +1401,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
switch (op) {
|
||||
case Add:
|
||||
case Subtract:
|
||||
case Multiply:
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
*aTypeMask = *bTypeMask = (1 << RegisterOperand);
|
||||
}
|
||||
@ -1459,6 +1412,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Divide:
|
||||
*aTypeMask = (1 << RegisterOperand);
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
*bTypeMask = ~0;
|
||||
*thunk = true;
|
||||
@ -1466,6 +1420,7 @@ class MyArchitecture: public Assembler::Architecture {
|
||||
break;
|
||||
|
||||
case Remainder:
|
||||
*aTypeMask = (1 << RegisterOperand);
|
||||
if (BytesPerWord == 4 and aSize == 8) {
|
||||
*bTypeMask = ~0;
|
||||
*thunk = true;
|
||||
|
Loading…
Reference in New Issue
Block a user