diff options
-rw-r--r-- | test/sf_test.cpp | 139 | ||||
-rw-r--r-- | xbyak/xbyak_util.h | 91 |
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 |