mirror of
https://github.com/RPCSX/xbyak.git
synced 2025-02-25 13:10:43 +00:00
add Pack ; change api to access reg for StackFrame
This commit is contained in:
parent
1dfa77c290
commit
f58fec9196
139
test/sf_test.cpp
139
test/sf_test.cpp
@ -11,37 +11,37 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
void gen1()
|
||||
{
|
||||
StackFrame sf(this, 1);
|
||||
mov(rax, sf.p(0));
|
||||
mov(rax, sf.p[0]);
|
||||
}
|
||||
void gen2()
|
||||
{
|
||||
StackFrame sf(this, 2);
|
||||
lea(rax, ptr [sf.p(0) + sf.p(1)]);
|
||||
lea(rax, ptr [sf.p[0] + sf.p[1]]);
|
||||
}
|
||||
void gen3()
|
||||
{
|
||||
StackFrame sf(this, 3);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
void gen4()
|
||||
{
|
||||
StackFrame sf(this, 4);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
add(rax, sf.p(3));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen5()
|
||||
{
|
||||
StackFrame sf(this, 4, UseRCX);
|
||||
xor_(rcx, rcx);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
add(rax, sf.p(3));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen6()
|
||||
@ -49,10 +49,10 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
StackFrame sf(this, 4, UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
add(rax, sf.p(3));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
|
||||
void gen7()
|
||||
@ -60,9 +60,9 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
StackFrame sf(this, 3, UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
|
||||
void gen8()
|
||||
@ -70,12 +70,12 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
StackFrame sf(this, 3, 3 | UseRCX | UseRDX);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(sf.t(0), 1);
|
||||
mov(sf.t(1), 2);
|
||||
mov(sf.t(2), 3);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
mov(sf.t[0], 1);
|
||||
mov(sf.t[1], 2);
|
||||
mov(sf.t[2], 3);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
}
|
||||
|
||||
void gen9()
|
||||
@ -83,12 +83,12 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
StackFrame sf(this, 3, 3 | UseRCX | UseRDX, 32);
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
mov(sf.t(0), 1);
|
||||
mov(sf.t(1), 2);
|
||||
mov(sf.t(2), 3);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
mov(sf.t[0], 1);
|
||||
mov(sf.t[1], 2);
|
||||
mov(sf.t[2], 3);
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
mov(ptr [rsp + 8 * 0], rax);
|
||||
mov(ptr [rsp + 8 * 1], rax);
|
||||
mov(ptr [rsp + 8 * 2], rax);
|
||||
@ -101,12 +101,12 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
xor_(rcx, rcx);
|
||||
xor_(rdx, rdx);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
mov(sf.t(i), i);
|
||||
mov(sf.t[i], i);
|
||||
}
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
add(rax, sf.p(3));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
mov(ptr [rsp + 8 * 0], rax);
|
||||
mov(ptr [rsp + 8 * 1], rax);
|
||||
mov(ptr [rsp + 8 * 2], rax);
|
||||
@ -124,10 +124,10 @@ struct Code : public Xbyak::CodeGenerator {
|
||||
{
|
||||
StackFrame sf(this, 4, UseRDX);
|
||||
xor_(rdx, rdx);
|
||||
mov(rax, sf.p(0));
|
||||
add(rax, sf.p(1));
|
||||
add(rax, sf.p(2));
|
||||
add(rax, sf.p(3));
|
||||
mov(rax, sf.p[0]);
|
||||
add(rax, sf.p[1]);
|
||||
add(rax, sf.p[2]);
|
||||
add(rax, sf.p[3]);
|
||||
}
|
||||
};
|
||||
|
||||
@ -142,14 +142,14 @@ struct Code2 : Xbyak::CodeGenerator {
|
||||
if (tNum & UseRCX) xor_(rcx, rcx);
|
||||
if (tNum & UseRDX) xor_(rdx, rdx);
|
||||
for (int i = 0, n = tNum & ~(UseRCX | UseRDX); i < n; i++) {
|
||||
mov(sf.t(i), 5);
|
||||
mov(sf.t[i], 5);
|
||||
}
|
||||
for (int i = 0; i < stackSizeByte; i++) {
|
||||
mov(byte [rsp + i], 0);
|
||||
}
|
||||
mov(rax, 1);
|
||||
for (int i = 0; i < pNum; i++) {
|
||||
add(rax, sf.p(i));
|
||||
add(rax, sf.p[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -208,7 +208,7 @@ void testAll()
|
||||
opt = UseRCX | UseRDX;
|
||||
}
|
||||
for (int tNum = 0; tNum < maxNum; tNum++) {
|
||||
printf("pNum=%d, tNum=%d, stackSize=%d\n", pNum, tNum | opt, stackSize);
|
||||
// printf("pNum=%d, tNum=%d, stackSize=%d\n", pNum, tNum | opt, stackSize);
|
||||
const Xbyak::uint8 *f = code.getCurr();
|
||||
code.gen(pNum, tNum | opt, stackSize);
|
||||
verify(f, pNum);
|
||||
@ -270,12 +270,63 @@ void testPartial()
|
||||
check(24, f12(3, 5, 7, 9));
|
||||
}
|
||||
|
||||
void put(const Xbyak::util::Pack& p)
|
||||
{
|
||||
for (size_t i = 0, n = p.size(); i < n; i++) {
|
||||
printf("%s ", p[i].toString());
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void verifyPack(const Xbyak::util::Pack& p, const int *tbl, size_t tblNum)
|
||||
{
|
||||
for (size_t i = 0; i < tblNum; i++) {
|
||||
check(p[i].getIdx(), tbl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void testPack()
|
||||
{
|
||||
const int N = 10;
|
||||
Xbyak::Reg64 regTbl[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
regTbl[i] = Xbyak::Reg64(i);
|
||||
}
|
||||
Xbyak::util::Pack p(regTbl, N);
|
||||
const struct {
|
||||
int pos;
|
||||
int num;
|
||||
int tbl[10];
|
||||
} tbl[] = {
|
||||
{ 0, 10, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 1, 9, { 1, 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 2, 8, { 2, 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 3, 7, { 3, 4, 5, 6, 7, 8, 9 } },
|
||||
{ 4, 6, { 4, 5, 6, 7, 8, 9 } },
|
||||
{ 5, 5, { 5, 6, 7, 8, 9 } },
|
||||
{ 6, 4, { 6, 7, 8, 9 } },
|
||||
{ 7, 3, { 7, 8, 9 } },
|
||||
{ 8, 2, { 8, 9 } },
|
||||
{ 9, 1, { 9 } },
|
||||
{ 3, 5, { 3, 4, 5, 6, 7 } },
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(tbl) / sizeof(*tbl); i++) {
|
||||
const int pos = tbl[i].pos;
|
||||
const int num = tbl[i].num;
|
||||
verifyPack(p.sub(pos, num), tbl[i].tbl, num);
|
||||
if (pos + num == N) {
|
||||
verifyPack(p.sub(pos), tbl[i].tbl, num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
try
|
||||
{
|
||||
testAll();
|
||||
|
||||
testPartial();
|
||||
testPack();
|
||||
printf("errNum=%d\n", errNum);
|
||||
} catch (const Xbyak::Error& e) {
|
||||
printf("err %s\n", Xbyak::ConvertErrorToString(e));
|
||||
|
@ -237,6 +237,77 @@ private:
|
||||
const int UseRCX = 1 << 6;
|
||||
const int UseRDX = 1 << 7;
|
||||
|
||||
class Pack {
|
||||
static const size_t maxTblNum = 10;
|
||||
const Xbyak::Reg64 *tbl_[maxTblNum];
|
||||
size_t n_;
|
||||
public:
|
||||
Pack() : n_(0) {}
|
||||
Pack(const Xbyak::Reg64 *tbl, size_t n) { init(tbl, n); }
|
||||
Pack(const Pack& rhs)
|
||||
: n_(rhs.n_)
|
||||
{
|
||||
for (size_t i = 0; i < n_; i++) tbl_[i] = rhs.tbl_[i];
|
||||
}
|
||||
Pack(const Xbyak::Reg64& t0)
|
||||
{ n_ = 1; tbl_[0] = &t0; }
|
||||
Pack(const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 2; tbl_[0] = &t0; tbl_[1] = &t1; }
|
||||
Pack(const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 3; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; }
|
||||
Pack(const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 4; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; }
|
||||
Pack(const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 5; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; }
|
||||
Pack(const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 6; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; }
|
||||
Pack(const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 7; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; }
|
||||
Pack(const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 8; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; }
|
||||
Pack(const Xbyak::Reg64& t8, const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 9; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; tbl_[8] = &t8; }
|
||||
Pack(const Xbyak::Reg64& t9, const Xbyak::Reg64& t8, const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
|
||||
{ n_ = 10; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; tbl_[8] = &t8; tbl_[9] = &t9; }
|
||||
void init(const Xbyak::Reg64 *tbl, size_t n)
|
||||
{
|
||||
if (n > maxTblNum) {
|
||||
fprintf(stderr, "ERR Pack::init bad n=%d\n", (int)n);
|
||||
throw ERR_BAD_PARAMETER;
|
||||
}
|
||||
n_ = n;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
tbl_[i] = &tbl[i];
|
||||
}
|
||||
}
|
||||
const Xbyak::Reg64& operator[](size_t n) const
|
||||
{
|
||||
if (n >= n_) {
|
||||
fprintf(stderr, "ERR Pack bad n=%d\n", (int)n);
|
||||
throw ERR_BAD_PARAMETER;
|
||||
}
|
||||
return *tbl_[n];
|
||||
}
|
||||
size_t size() const { return n_; }
|
||||
/*
|
||||
get tbl[pos, pos + num)
|
||||
*/
|
||||
Pack sub(size_t pos, size_t num = size_t(-1)) const
|
||||
{
|
||||
if (num == size_t(-1)) num = n_ - pos;
|
||||
if (pos + num > n_) {
|
||||
fprintf(stderr, "ERR Pack::sub bad pos=%d, num=%d\n", (int)pos, (int)num);
|
||||
throw ERR_BAD_PARAMETER;
|
||||
}
|
||||
Pack pack;
|
||||
pack.n_ = num;
|
||||
for (size_t i = 0; i < num; i++) {
|
||||
pack.tbl_[i] = tbl_[pos + i];
|
||||
}
|
||||
return pack;
|
||||
}
|
||||
};
|
||||
|
||||
class StackFrame {
|
||||
#ifdef XBYAK64_WIN
|
||||
static const int noSaveNum = 6;
|
||||
@ -257,17 +328,13 @@ class StackFrame {
|
||||
bool makeEpilog_;
|
||||
Xbyak::Reg64 pTbl_[4];
|
||||
Xbyak::Reg64 tTbl_[10];
|
||||
Pack p_;
|
||||
Pack t_;
|
||||
StackFrame(const StackFrame&);
|
||||
void operator=(const StackFrame&);
|
||||
public:
|
||||
const Xbyak::Reg64& p(int pos) const
|
||||
{
|
||||
if (pos < 0 || pos >= pNum_) throw ERR_BAD_PARAMETER;
|
||||
return pTbl_[pos];
|
||||
}
|
||||
const Xbyak::Reg64& t(int pos) const
|
||||
{
|
||||
if (pos < 0 || pos >= tNum_) throw ERR_BAD_PARAMETER;
|
||||
return tTbl_[pos];
|
||||
}
|
||||
const Pack& p;
|
||||
const Pack& t;
|
||||
/*
|
||||
make stack frame
|
||||
@param sf [in] this
|
||||
@ -293,6 +360,8 @@ public:
|
||||
, saveNum_(0)
|
||||
, P_(0)
|
||||
, makeEpilog_(makeEpilog)
|
||||
, p(p_)
|
||||
, t(t_)
|
||||
{
|
||||
using namespace Xbyak;
|
||||
if (pNum < 0 || pNum > 4) throw ERR_BAD_PNUM;
|
||||
@ -327,6 +396,8 @@ public:
|
||||
}
|
||||
if (useRcx_ && rcxPos < pNum) code_->mov(code_->r10, code_->rcx);
|
||||
if (useRdx_ && rdxPos < pNum) code_->mov(code_->r11, code_->rdx);
|
||||
p_.init(pTbl_, pNum);
|
||||
t_.init(tTbl_, tNum_);
|
||||
}
|
||||
/*
|
||||
make epilog manually
|
||||
|
Loading…
x
Reference in New Issue
Block a user