add Pack ; change api to access reg for StackFrame
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 @@
 	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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 	{
 		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 @@
 		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 @@
 					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 @@
 	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 @@
 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 @@
 	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 @@
 		, 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 @@
 		}
 		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