aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--test/sf_test.cpp139
-rw-r--r--xbyak/xbyak_util.h91
2 files changed, 176 insertions, 54 deletions
diff --git a/test/sf_test.cpp b/test/sf_test.cpp
index 7fa5e54..6541b02 100644
--- a/test/sf_test.cpp
+++ b/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));
diff --git a/xbyak/xbyak_util.h b/xbyak/xbyak_util.h
index 7e3bbf4..578dbe3 100644
--- a/xbyak/xbyak_util.h
+++ b/xbyak/xbyak_util.h
@@ -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