unify parameter tNum and useRCX, useRDX
This commit is contained in:
parent
3639843e27
commit
b51d70c495
3 changed files with 53 additions and 37 deletions
|
@ -8,19 +8,21 @@
|
||||||
struct Code : public Xbyak::CodeGenerator {
|
struct Code : public Xbyak::CodeGenerator {
|
||||||
Code()
|
Code()
|
||||||
{
|
{
|
||||||
Xbyak::util::StackFrame sf(this, 4);
|
Xbyak::util::StackFrame sf(this, 3);
|
||||||
mov(rax, sf.p(0));
|
mov(rax, sf.p(0));
|
||||||
add(rax, sf.p(1));
|
add(rax, sf.p(1));
|
||||||
add(rax, sf.p(2));
|
add(rax, sf.p(2));
|
||||||
add(rax, sf.p(3));
|
|
||||||
ret();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
Code c;
|
Code c;
|
||||||
int (*f)(int, int, int, int) = c.getCode<int(*) (int, int, int, int)>();
|
int (*f)(int, int, int) = c.getCode<int(*) (int, int, int)>();
|
||||||
printf("%d\n", f(3, 5, 2, 9));
|
int ret = f(3, 5, 2);
|
||||||
puts("ok");
|
if (ret == 3 + 5 + 2) {
|
||||||
|
puts("ok");
|
||||||
|
} else {
|
||||||
|
puts("ng");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen5()
|
void gen5()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 4, 0, UseRCX);
|
StackFrame sf(this, 4, UseRCX);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
mov(rax, sf.p(0));
|
mov(rax, sf.p(0));
|
||||||
add(rax, sf.p(1));
|
add(rax, sf.p(1));
|
||||||
|
@ -47,7 +47,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen6()
|
void gen6()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 4, 0, UseRCX | UseRDX);
|
StackFrame sf(this, 4, UseRCX | UseRDX);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
xor_(rdx, rdx);
|
xor_(rdx, rdx);
|
||||||
mov(rax, sf.p(0));
|
mov(rax, sf.p(0));
|
||||||
|
@ -58,7 +58,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen7()
|
void gen7()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 3, 0, UseRCX | UseRDX);
|
StackFrame sf(this, 3, UseRCX | UseRDX);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
xor_(rdx, rdx);
|
xor_(rdx, rdx);
|
||||||
mov(rax, sf.p(0));
|
mov(rax, sf.p(0));
|
||||||
|
@ -68,7 +68,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen8()
|
void gen8()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 4, 3, UseRCX | UseRDX);
|
StackFrame sf(this, 4, 3 | UseRCX | UseRDX);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
xor_(rdx, rdx);
|
xor_(rdx, rdx);
|
||||||
mov(sf.t(0), 1);
|
mov(sf.t(0), 1);
|
||||||
|
@ -81,7 +81,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen9()
|
void gen9()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 4, 3, UseRCX | UseRDX, 4);
|
StackFrame sf(this, 4, 3 | UseRCX | UseRDX, 4);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
xor_(rdx, rdx);
|
xor_(rdx, rdx);
|
||||||
mov(sf.t(0), 1);
|
mov(sf.t(0), 1);
|
||||||
|
@ -98,7 +98,7 @@ struct Code : public Xbyak::CodeGenerator {
|
||||||
|
|
||||||
void gen10()
|
void gen10()
|
||||||
{
|
{
|
||||||
StackFrame sf(this, 4, 8, UseRCX | UseRDX, 4);
|
StackFrame sf(this, 4, 8 | UseRCX | UseRDX, 4);
|
||||||
xor_(rcx, rcx);
|
xor_(rcx, rcx);
|
||||||
xor_(rdx, rdx);
|
xor_(rdx, rdx);
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
|
|
|
@ -234,8 +234,10 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64
|
||||||
struct StackFrame {
|
const int UseRCX = 1 << 6;
|
||||||
enum { UseRCX = 1, UseRDX = 2 };
|
const int UseRDX = 1 << 7;
|
||||||
|
|
||||||
|
class StackFrame {
|
||||||
#ifdef XBYAK64_WIN
|
#ifdef XBYAK64_WIN
|
||||||
static const int noSaveNum = 6;
|
static const int noSaveNum = 6;
|
||||||
#else
|
#else
|
||||||
|
@ -244,12 +246,14 @@ struct StackFrame {
|
||||||
Xbyak::CodeGenerator *code_;
|
Xbyak::CodeGenerator *code_;
|
||||||
int pNum_;
|
int pNum_;
|
||||||
int tNum_;
|
int tNum_;
|
||||||
int useReg_;
|
bool useRcx_;
|
||||||
|
bool useRdx_;
|
||||||
int saveNum_;
|
int saveNum_;
|
||||||
int P_;
|
int P_;
|
||||||
bool makeEpilog_;
|
bool makeEpilog_;
|
||||||
Xbyak::Reg64 pTbl_[4];
|
Xbyak::Reg64 pTbl_[4];
|
||||||
Xbyak::Reg64 tTbl_[10];
|
Xbyak::Reg64 tTbl_[10];
|
||||||
|
public:
|
||||||
const Xbyak::Reg64& p(int pos) const
|
const Xbyak::Reg64& p(int pos) const
|
||||||
{
|
{
|
||||||
if (pos < 0 || pos >= pNum_) throw ERR_BAD_PARAMETER;
|
if (pos < 0 || pos >= pNum_) throw ERR_BAD_PARAMETER;
|
||||||
|
@ -273,27 +277,30 @@ struct StackFrame {
|
||||||
gt0, ..., gt(tNum-1)
|
gt0, ..., gt(tNum-1)
|
||||||
rsp[0..8 * numQrod - 1]
|
rsp[0..8 * numQrod - 1]
|
||||||
*/
|
*/
|
||||||
StackFrame(Xbyak::CodeGenerator *code, int pNum, int tNum = 0, int numQword = 0, int useReg = 0)
|
StackFrame(Xbyak::CodeGenerator *code, int pNum, int tNum = 0, int numQword = 0)
|
||||||
: code_(code)
|
: code_(code)
|
||||||
, pNum_(pNum)
|
, pNum_(pNum)
|
||||||
, tNum_(tNum)
|
, tNum_(tNum & ~(UseRCX | UseRDX))
|
||||||
, useReg_(useReg)
|
, useRcx_((tNum & UseRCX) != 0)
|
||||||
|
, useRdx_((tNum & UseRDX) != 0)
|
||||||
, saveNum_(0)
|
, saveNum_(0)
|
||||||
, P_(0)
|
, P_(0)
|
||||||
, makeEpilog_(true)
|
, makeEpilog_(true)
|
||||||
{
|
{
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
if (pNum > 4) throw ERR_BAD_PNUM;
|
if (pNum < 0 || pNum > 4) throw ERR_BAD_PNUM;
|
||||||
const int allRegNum = pNum + tNum + (useReg & UseRCX) + (useReg & UseRDX);
|
const int allRegNum = pNum + tNum_ + (useRcx_ ? 1 : 0) + (useRdx_ ? 1 : 0);
|
||||||
if (allRegNum > 14) throw ERR_BAD_TNUM;
|
if (allRegNum < pNum || allRegNum > 14) throw ERR_BAD_TNUM;
|
||||||
const Reg64& rsp = code->rsp;
|
const Reg64& rsp = code->rsp;
|
||||||
const AddressFrame& ptr = code->ptr;
|
const AddressFrame& ptr = code->ptr;
|
||||||
saveNum_ = std::max(0, allRegNum - noSaveNum);
|
saveNum_ = (std::max)(0, allRegNum - noSaveNum);
|
||||||
const int *tbl = getOrderTbl() + noSaveNum;
|
const int *tbl = getOrderTbl() + noSaveNum;
|
||||||
P_ = 8 * (saveNum_ + numQword);
|
P_ = saveNum_ + numQword;
|
||||||
|
if (P_ > 0 && (P_ & 1) == 0) P_++; // ensure (rsp % 16) == 0
|
||||||
|
P_ *= 8;
|
||||||
if (P_ > 0) code->sub(rsp, P_);
|
if (P_ > 0) code->sub(rsp, P_);
|
||||||
#ifdef XBYAK64
|
#ifdef XBYAK64_WIN
|
||||||
for (int i = 0; i < std::min(saveNum_, 4); i++) {
|
for (int i = 0; i < (std::min)(saveNum_, 4); i++) {
|
||||||
code->mov(ptr [rsp + P_ + (i + 1) * 8], Reg64(tbl[i]));
|
code->mov(ptr [rsp + P_ + (i + 1) * 8], Reg64(tbl[i]));
|
||||||
}
|
}
|
||||||
for (int i = 4; i < saveNum_; i++) {
|
for (int i = 4; i < saveNum_; i++) {
|
||||||
|
@ -308,7 +315,7 @@ struct StackFrame {
|
||||||
for (int i = 0; i < pNum; i++) {
|
for (int i = 0; i < pNum; i++) {
|
||||||
pTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
|
pTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
|
||||||
}
|
}
|
||||||
for (int i = 0; i < tNum; i++) {
|
for (int i = 0; i < tNum_; i++) {
|
||||||
tTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
|
tTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,14 +327,14 @@ struct StackFrame {
|
||||||
const AddressFrame& ptr = code_->ptr;
|
const AddressFrame& ptr = code_->ptr;
|
||||||
const int *tbl = getOrderTbl() + noSaveNum;
|
const int *tbl = getOrderTbl() + noSaveNum;
|
||||||
#ifdef XBYAK64_WIN
|
#ifdef XBYAK64_WIN
|
||||||
for (int i = 0; i < std::min(saveNum_, 4); i++) {
|
for (int i = 0; i < (std::min)(saveNum_, 4); i++) {
|
||||||
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ + (i + 1) * 8]);
|
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ + (i + 1) * 8]);
|
||||||
}
|
}
|
||||||
for (int i = 4; i < saveNum_; i++) {
|
for (int i = 4; i < saveNum_; i++) {
|
||||||
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ - 8 * (saveNum_ - i)]);
|
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ - 8 * (saveNum_ - i)]);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i <=saveNum_; i++) {
|
for (int i = 0; i < saveNum_; i++) {
|
||||||
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ - 8 * (saveNum_ - i)]);
|
code_->mov(Reg64(tbl[i]), ptr [rsp + P_ - 8 * (saveNum_ - i)]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -335,6 +342,11 @@ struct StackFrame {
|
||||||
|
|
||||||
if (callRet) code_->ret();
|
if (callRet) code_->ret();
|
||||||
}
|
}
|
||||||
|
~StackFrame()
|
||||||
|
{
|
||||||
|
if (makeEpilog_) close();
|
||||||
|
}
|
||||||
|
private:
|
||||||
const int *getOrderTbl() const
|
const int *getOrderTbl() const
|
||||||
{
|
{
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
|
@ -354,20 +366,22 @@ struct StackFrame {
|
||||||
using namespace Xbyak;
|
using namespace Xbyak;
|
||||||
const int *tbl = getOrderTbl();
|
const int *tbl = getOrderTbl();
|
||||||
int r = tbl[pos++];
|
int r = tbl[pos++];
|
||||||
if (useReg_ & UseRCX) {
|
if (useRcx_) {
|
||||||
if (r == Operand::RCX) { return Operand::R10; }
|
if (r == Operand::RCX) {
|
||||||
if (r == Operand::R10) { return tbl[pos++]; }
|
code_->mov(code_->r10, code_->rcx);
|
||||||
|
return Operand::R10;
|
||||||
|
}
|
||||||
|
if (r == Operand::R10) { r = tbl[pos++]; }
|
||||||
}
|
}
|
||||||
if (useReg_ & UseRDX) {
|
if (useRdx_) {
|
||||||
if (r == Operand::RDX) { return Operand::R11; }
|
if (r == Operand::RDX) {
|
||||||
|
code_->mov(code_->r11, code_->rdx);
|
||||||
|
return Operand::R11;
|
||||||
|
}
|
||||||
if (r == Operand::R11) { return tbl[pos++]; }
|
if (r == Operand::R11) { return tbl[pos++]; }
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
~StackFrame()
|
|
||||||
{
|
|
||||||
if (makeEpilog_) close();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue