mirror of
https://github.com/corda/corda.git
synced 2025-01-07 13:38:47 +00:00
added 64-bit shifts and mul/div
This commit is contained in:
parent
6e6035505c
commit
dbcd42e70c
@ -68,9 +68,9 @@ inline int stwu(int rs, int ra, int i) { return D(37, rs, ra, i); }
|
|||||||
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
|
inline int stwx(int rs, int ra, int rb) { return X(31, rs, ra, rb, 151, 0); }
|
||||||
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
|
inline int add(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 266, 0); }
|
||||||
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
|
inline int addc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 10, 0); }
|
||||||
inline int addci(int rt, int ra, int i) { return D(12, rt, ra, i); }
|
|
||||||
inline int adde(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 138, 0); }
|
inline int adde(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 138, 0); }
|
||||||
inline int addi(int rt, int ra, int i) { return D(14, rt, ra, i); }
|
inline int addi(int rt, int ra, int i) { return D(14, rt, ra, i); }
|
||||||
|
inline int addic(int rt, int ra, int i) { return D(12, rt, ra, i); }
|
||||||
inline int addis(int rt, int ra, int i) { return D(15, rt, ra, i); }
|
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 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 subfc(int rt, int ra, int rb) { return XO(31, rt, ra, rb, 0, 8, 0); }
|
||||||
@ -408,59 +408,88 @@ inline int H(Reg* r) { return r->high; }
|
|||||||
void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void shiftLeftR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
issue(con, subfic(31, R(a), 32));
|
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||||
issue(con, slw(R(b), R(b), R(a)));
|
issue(con, subfic(H(tmp), R(a), 32));
|
||||||
issue(con, srw(0, H(b), 31));
|
issue(con, slw(H(t), H(b), R(a)));
|
||||||
issue(con, or_(R(b), R(b), 0));
|
issue(con, srw(R(tmp), R(b), H(tmp)));
|
||||||
issue(con, addi(31, R(a), -32));
|
issue(con, or_(H(t), H(t), R(tmp)));
|
||||||
issue(con, slw(0, H(b), 31));
|
issue(con, addi(H(tmp), R(a), -32));
|
||||||
issue(con, or_(R(b), R(b), 0));
|
issue(con, slw(R(tmp), R(b), H(tmp)));
|
||||||
issue(con, slw(H(b), H(b), R(a)));
|
issue(con, or_(H(t), H(t), R(tmp)));
|
||||||
} else
|
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||||
issue(con, slw(R(t), R(b), R(a)));
|
}
|
||||||
|
issue(con, slw(R(t), R(b), R(a)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftLeftC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void shiftLeftC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getVal(a);
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
abort(con); // todo
|
issue(con, rlwinm(H(t),H(b),sh,0,31-sh));
|
||||||
} else
|
issue(con, rlwimi(H(t),R(b),sh,32-sh,31));
|
||||||
issue(con, slwi(R(t), R(b), sh));
|
}
|
||||||
|
issue(con, slwi(R(t), R(b), sh));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void jumpIfLessOrEqualC(Context* c, unsigned size UNUSED, Assembler::Constant* target);
|
||||||
|
|
||||||
void shiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void shiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
abort(con); // todo
|
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||||
} else
|
issue(con, subfic(H(tmp), R(a), 32));
|
||||||
|
issue(con, srw(R(t), R(b), R(a)));
|
||||||
|
issue(con, slw(R(tmp), H(b), H(tmp)));
|
||||||
|
issue(con, or_(R(t), R(t), R(tmp)));
|
||||||
|
issue(con, addic(H(tmp), R(a), -32));
|
||||||
|
issue(con, sraw(R(tmp), H(b), H(tmp)));
|
||||||
|
ResolvedPromise prom(8);
|
||||||
|
Const offset(&prom);
|
||||||
|
jumpIfLessOrEqualC(con, 0, &offset);
|
||||||
|
issue(con, ori(R(t), R(tmp), 0));
|
||||||
|
issue(con, sraw(H(t), H(b), R(a)));
|
||||||
|
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||||
|
} else {
|
||||||
issue(con, sraw(R(t), R(b), R(a)));
|
issue(con, sraw(R(t), R(b), R(a)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void shiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getVal(a);
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
abort(con); // todo
|
issue(con, rlwinm(R(t),R(b),32-sh,sh,31));
|
||||||
} else
|
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
||||||
|
issue(con, srawi(H(t),H(b),sh));
|
||||||
|
} else {
|
||||||
issue(con, srawi(R(t), R(b), sh));
|
issue(con, srawi(R(t), R(b), sh));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsignedShiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
void unsignedShiftRightR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
|
issue(con, srw(R(t), R(b), R(a)));
|
||||||
if(size == 8) {
|
if(size == 8) {
|
||||||
abort(con); // todo
|
Reg Tmp(getTemp(con), getTemp(con)); Reg* tmp = &Tmp;
|
||||||
} else
|
issue(con, subfic(H(tmp), R(a), 32));
|
||||||
issue(con, srw(R(t), R(b), R(a)));
|
issue(con, slw(R(tmp), H(b), H(tmp)));
|
||||||
|
issue(con, or_(R(t), R(t), R(tmp)));
|
||||||
|
issue(con, addi(H(tmp), R(a), -32));
|
||||||
|
issue(con, srw(R(tmp), H(b), H(tmp)));
|
||||||
|
issue(con, or_(R(t), R(t), R(tmp)));
|
||||||
|
issue(con, srw(H(t), H(b), R(a)));
|
||||||
|
freeTemp(con, H(tmp)); freeTemp(con, R(tmp));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
void unsignedShiftRightC(Context* con, unsigned size, Const* a, Reg* b, Reg* t)
|
||||||
{
|
{
|
||||||
int sh = getVal(a);
|
int sh = getVal(a);
|
||||||
|
issue(con, srwi(R(t), R(b), sh));
|
||||||
if (size == 8) {
|
if (size == 8) {
|
||||||
abort(con); // todo
|
issue(con, rlwimi(R(t),H(b),32-sh,0,sh-1));
|
||||||
} else
|
issue(con, rlwinm(H(t),H(b),32-sh,sh,31));
|
||||||
issue(con, srwi(R(t), R(b), sh));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -674,12 +703,8 @@ void multiplyC(Context* con, unsigned size, Const* a, Reg* b, Reg* t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void divideR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void divideR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||||
if(size == 8) {
|
assert(con, size == 4);
|
||||||
issue(con, 0);
|
issue(con, divw(R(t), R(b), R(a)));
|
||||||
issue(con, 0);
|
|
||||||
} else {
|
|
||||||
issue(con, divw(R(t), R(b), R(a)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
void remainderR(Context* con, unsigned size, Reg* a, Reg* b, Reg* t) {
|
||||||
@ -1355,7 +1380,7 @@ negateRR(Context* c, unsigned srcSize, Assembler::Register* src,
|
|||||||
Assembler::Register dstHigh(dst->high);
|
Assembler::Register dstHigh(dst->high);
|
||||||
|
|
||||||
negateRR(c, 4, src, 4, dst);
|
negateRR(c, 4, src, 4, dst);
|
||||||
issue(c, addci(dst->high, dst->high, 0));
|
issue(c, addic(dst->high, dst->high, 0));
|
||||||
negateRR(c, 4, &dstHigh, 4, &dstHigh);
|
negateRR(c, 4, &dstHigh, 4, &dstHigh);
|
||||||
} else {
|
} else {
|
||||||
issue(c, neg(dst->low, src->low));
|
issue(c, neg(dst->low, src->low));
|
||||||
@ -1724,7 +1749,7 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
case Add:
|
case Add:
|
||||||
case Subtract:
|
case Subtract:
|
||||||
case Multiply:
|
case Multiply:
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (aSize == 8) {
|
||||||
*aTypeMask = *bTypeMask = (1 << RegisterOperand);
|
*aTypeMask = *bTypeMask = (1 << RegisterOperand);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1734,18 +1759,20 @@ class MyArchitecture: public Assembler::Architecture {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Divide:
|
case Divide:
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
*bTypeMask = ~0;
|
*bTypeMask = ~0;
|
||||||
*thunk = true;
|
*thunk = true;
|
||||||
|
} else {
|
||||||
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Remainder:
|
case Remainder:
|
||||||
*aTypeMask = (1 << RegisterOperand);
|
|
||||||
if (BytesPerWord == 4 and aSize == 8) {
|
if (BytesPerWord == 4 and aSize == 8) {
|
||||||
*bTypeMask = ~0;
|
*bTypeMask = ~0;
|
||||||
*thunk = true;
|
*thunk = true;
|
||||||
|
} else {
|
||||||
|
*aTypeMask = (1 << RegisterOperand);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user