📄 mcomp.cpp
字号:
#endif
CopyBlock16x16Row(dc);
dc.Set(); dc.Sub(dc.r11, dc.r11, 1);
dc.Branch(dc.NE, loop);
}
//unroll last (no preload needed)
CopyBlock16x16Row(dc);
dc.FunctionEnd();
}
//----------------------------
static void BuildCopyFunction(C_dyn_code &dc, t_BuldFunc Func, bool round, bool add, bool fast = true, bool ARM5 = false){
dc.Align(16);
dc.FunctionBegin();
#ifdef USE_PLD
if(ARM5){
dc.Add(dc.r12, dc.r2, 7);
dc.Pld(dc.r0, dc.r2);
dc.Pld(dc.r0, 7);
dc.Pld(dc.r0, dc.r12);
dc.Pld(dc.r0, 0);
}
#endif
if(fast){
void *L00 = dc.Label(false);
void *L10 = dc.Label(false);
void *L11 = dc.Label(false);
dc.Set(); dc.Mov(dc.r4, dc.r0, dc.LSL, 30);
dc.Branch(dc.EQ, L00);
dc.Bic(dc.r0, dc.r0, 3);
dc.Set(); dc.Cmp(dc.r4, 0x80000000);
dc.Branch(dc.EQ, L10);
dc.Branch(dc.HI, L11);
Func(dc, 8, round, add, ARM5);
dc.PutLabel(L10);
Func(dc, 16, round, add, ARM5);
dc.PutLabel(L11);
Func(dc, 24, round, add, ARM5);
dc.PutLabel(L00);
Func(dc, 0, round, add, ARM5);
}else{
Func(dc, -1, round, add, ARM5);
}
}
//----------------------------
#ifdef USE_IDCT_WMMX
//----------------------------
static void BuildWMMXCopyBegin(C_dyn_code &dc){
dc.FunctionBegin();
dc.Add(dc.r12, dc.r2, 7);
dc.Pld(dc.r0, dc.r2);
dc.Pld(dc.r0, 7);
dc.Pld(dc.r0, dc.r12);
dc.Pld(dc.r0, 0);
}
//----------------------------
static void BuildWMMXPreLoad(C_dyn_code &dc){
dc.Pld(dc.r0, dc.r2, dc.LSL, 1);
}
//----------------------------
static void BuildWMMXPreLoad2Init(C_dyn_code &dc){
dc.Add(dc.r12, dc.r2, 4);
}
//----------------------------
static void BuildWMMXPreLoad2(C_dyn_code &dc){
dc.Pld(dc.r0, dc.r2, dc.LSL, 1); //2*pitch
dc.Pld(dc.r0, dc.r12, dc.LSL, 1); //2*pitch+8
}
//----------------------------
static void BuildWMMXPrepareAlignVer(C_dyn_code &dc, void *label_aligned){
dc.Set(); dc.And(dc.r14, dc.r0, 7);
dc.Tmcr(dc.wcgr1, dc.r14);
dc.Mov(dc.r14, 8);
dc.Branch(dc.EQ, label_aligned);
dc.Bic(dc.r0, dc.r0, 7);
}
//----------------------------
static void BuildWMMXPrepareAlignHor(C_dyn_code &dc, void *label_wrap){
dc.And(dc.r14, dc.r0, 7);
dc.Tmcr(dc.wcgr1, dc.r14);
dc.Add(dc.r14, dc.r14, 1);
dc.Bic(dc.r0, dc.r0, 7);
dc.Cmp(dc.r14, 8);
dc.Branch(dc.EQ, label_wrap);
dc.Tmcr(dc.wcgr2, dc.r14);
dc.Mov(dc.r14, 8);
}
//----------------------------
static void BuildWMMXCopyBlock(C_dyn_code &dc){
void *label_aligned = dc.Label(false);
dc.Align(16);
BuildWMMXCopyBegin(dc);
dc.Sub(dc.r1, dc.r1, dc.r3);
BuildWMMXPrepareAlignVer(dc, label_aligned);
BuildWMMXPreLoad2Init(dc);
{
void *loop = dc.Label();
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Add(dc.r1, dc.r1, dc.r3);
dc.Walignr(1, dc.wr0, dc.wr0, dc.wr1);
dc.Wstrd(dc.wr0, dc.r1, 0);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, loop);
}
dc.FunctionEnd();
dc.PutLabel(label_aligned);
{
BuildWMMXPreLoad(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Add(dc.r1, dc.r1, dc.r3);
dc.Wstrd(dc.wr0, dc.r1, 0);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, label_aligned);
}
dc.FunctionEnd();
}
//----------------------------
static void BuildWMMXAddBlock(C_dyn_code &dc){
void *label_aligned = dc.Label(false);
dc.Align(16);
BuildWMMXCopyBegin(dc);
BuildWMMXPrepareAlignVer(dc, label_aligned);
BuildWMMXPreLoad2Init(dc);
{
void *loop = dc.Label();
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Wldrd(dc.wr5, dc.r1, 0);
dc.Walignr(1, dc.wr0, dc.wr0, dc.wr1);
dc.Wavg2b(true, dc.wr0, dc.wr0, dc.wr5);
dc.WstrdAdvance(dc.wr0, dc.r1, 8);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, loop);
}
dc.FunctionEnd();
dc.PutLabel(label_aligned);
{
BuildWMMXPreLoad(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Wldrd(dc.wr5, dc.r1, 0);
dc.Wavg2b(true, dc.wr0, dc.wr0, dc.wr5);
dc.WstrdAdvance(dc.wr0, dc.r1, 8);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, label_aligned);
}
dc.FunctionEnd();
}
//----------------------------
static void BuildWMMXCopyHorRow(C_dyn_code &dc, bool round, bool add, bool wrap){
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
if(add){
dc.Wldrd(dc.wr5, dc.r1, 0);
}else{
dc.Add(dc.r1, dc.r1, dc.r3);
}
dc.Walignr(1, dc.wr2, dc.wr0, dc.wr1);
if(!wrap){
dc.Walignr(2, dc.wr1, dc.wr0, dc.wr1);
}
if(round){
dc.Wavg2b(false, dc.wr0, dc.wr1, dc.wr2);
}else{
dc.Wavg2b(true, dc.wr0, dc.wr1, dc.wr2);
}
if(add){
dc.Wavg2b(true, dc.wr0, dc.wr0, dc.wr5);
dc.WstrdAdvance(dc.wr0, dc.r1, 8);
}else{
dc.Wstrd(dc.wr0, dc.r1, 0);
}
}
//----------------------------
static void BuildWMMXCopyBlockHor(C_dyn_code &dc, bool round, bool add){
void *label_wrap = dc.Label(false);
dc.Align(16);
BuildWMMXCopyBegin(dc);
if(!add){
dc.Sub(dc.r1, dc.r1, dc.r3);
}
BuildWMMXPreLoad2Init(dc);
BuildWMMXPrepareAlignHor(dc, label_wrap);
{
void *loop = dc.Label();
BuildWMMXCopyHorRow(dc, round, add, false);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, loop);
}
dc.FunctionEnd();
dc.PutLabel(label_wrap);
{
BuildWMMXCopyHorRow(dc, round, add, true);
dc.Set(); dc.Sub(dc.r14, dc.r14, 1);
dc.Branch(dc.NE, label_wrap);
}
dc.FunctionEnd();
}
//----------------------------
static void BuildWMMXSetVerRow(C_dyn_code &dc, bool round, bool add){
if(add){
dc.Wldrd(dc.wr5, dc.r1, 0);
}else{
dc.Add(dc.r1, dc.r1, dc.r3);
}
if(round){
dc.Wavg2b(false, dc.wr1, dc.wr0, dc.wr2);
}else{
dc.Wavg2b(true, dc.wr1, dc.wr0, dc.wr2);
}
if(add){
dc.Wavg2b(true, dc.wr1, dc.wr1, dc.wr5);
dc.WstrdAdvance(dc.wr1, dc.r1, 8);
}else{
dc.Wstrd(dc.wr1, dc.r1, 0);
}
}
//----------------------------
static void BuildWMMXCopyBlockVer(C_dyn_code &dc, bool round, bool add){
void *label_aligned = dc.Label(false);
dc.Align(16);
BuildWMMXCopyBegin(dc);
if(!add){
dc.Sub(dc.r1, dc.r1, dc.r3);
}
BuildWMMXPrepareAlignVer(dc, label_aligned);
BuildWMMXPreLoad2Init(dc);
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Walignr(1, dc.wr0, dc.wr0, dc.wr1);
{
void *loop = dc.Label();
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr2, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Walignr(1, dc.wr2, dc.wr2, dc.wr1);
BuildWMMXSetVerRow(dc, round, add);
BuildWMMXPreLoad2(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Walignr(1, dc.wr0, dc.wr0, dc.wr1);
BuildWMMXSetVerRow(dc, round, add);
dc.Set(); dc.Sub(dc.r14, dc.r14, 2);
dc.Branch(dc.NE, loop);
}
dc.FunctionEnd();
dc.PutLabel(label_aligned);
BuildWMMXPreLoad(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Add(dc.r0, dc.r0, dc.r2);
{
void *loop = dc.Label();
BuildWMMXPreLoad(dc);
dc.Wldrd(dc.wr2, dc.r0, 0);
dc.Add(dc.r0, dc.r0, dc.r2);
BuildWMMXSetVerRow(dc, round, add);
BuildWMMXPreLoad(dc);
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Add(dc.r0, dc.r0, dc.r2);
BuildWMMXSetVerRow(dc, round, add);
dc.Set(); dc.Sub(dc.r14, dc.r14, 2);
dc.Branch(dc.NE, loop);
}
dc.FunctionEnd();
}
//----------------------------
// wr6 0x03
// wr7 ~0x03
static void BuildWMMXLoadHorVerRow(C_dyn_code &dc, bool parity, bool wrap){
BuildWMMXPreLoad2(dc);
if(parity){
dc.Wldrd(dc.wr0, dc.r0, 0);
dc.Wldrd(dc.wr1, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Walignr(1, dc.wr2, dc.wr0, dc.wr1);
if(!wrap){
dc.Walignr(2, dc.wr1, dc.wr0, dc.wr1);
}
dc.Wand(dc.wr0, dc.wr2, dc.wr6);
dc.Wand(dc.wr3, dc.wr1, dc.wr6);
dc.Wand(dc.wr2, dc.wr2, dc.wr7);
dc.Wand(dc.wr1, dc.wr1, dc.wr7);
dc.Wsrldg(dc.wr2, dc.wr2, dc.wcgr0);
dc.Wsrldg(dc.wr1, dc.wr1, dc.wcgr0);
dc.Waddb(dc.wr2, dc.wr2, dc.wr1);
dc.Waddb(dc.wr1, dc.wr3, dc.wr0);
}else{
dc.Wldrd(dc.wr3, dc.r0, 0);
dc.Wldrd(dc.wr4, dc.r0, 8);
dc.Add(dc.r0, dc.r0, dc.r2);
dc.Walignr(1, dc.wr5, dc.wr3, dc.wr4);
if(!wrap){
dc.Walignr(2, dc.wr4, dc.wr3, dc.wr4);
}
dc.Wand(dc.wr0, dc.wr5, dc.wr6);
dc.Wand(dc.wr3, dc.wr4, dc.wr6);
dc.Wand(dc.wr5, dc.wr5, dc.wr7);
dc.Wand(dc.wr4, dc.wr4, dc.wr7);
dc.Wsrldg(dc.wr5, dc.wr5, dc.wcgr0);
dc.Wsrldg(dc.wr4, dc.wr4, dc.wcgr0);
dc.Waddb(dc.wr5, dc.wr5, dc.wr4);
dc.Waddb(dc.wr4, dc.wr3, dc.wr0);
}
}
//----------------------------
static void BuildWMMXSetHorVerRow(C_dyn_code &dc, bool add){
if(add){
dc.Wldrd(dc.wr9, dc.r1, 0);
}else{
dc.Add(dc.r1, dc.r1, dc.r3);
}
dc.Waddb(dc.wr0, dc.wr1, dc.wr4);
dc.Waddb(dc.wr0, dc.wr0, dc.wr8); //rounding
dc.Wand(dc.wr0, dc.wr0, dc.wr7);
dc.Waddb(dc.wr3, dc.wr2, dc.wr5);
dc.Wsrldg(dc.wr0, dc.wr0, dc.wcgr0);
dc.Waddb(dc.wr0, dc.wr0, dc.wr3);
if(add){
dc.Wavg2b(true, dc.wr0, dc.wr0, dc.wr9);
dc.WstrdAdvance(dc.wr0, dc.r1, 8);
}else{
dc.Wstrd(dc.wr0, dc.r1, 0);
}
}
//----------------------------
static void BuildWMMXCopyBlockHorVer(C_dyn_code &dc, bool round, bool add){
void *label_wrap = dc.Label(false);
dc.Align(16);
BuildWMMXCopyBegin(dc);
if(!add){
dc.Sub(dc.r1, dc.r1, dc.r3);
}
if(round){
dc.Mov(dc.r14, 1);
}else{
dc.Mov(dc.r14, 2);
}
dc.Tbcstb(dc.wr8, dc.r14);
dc.Mov(dc.r14, 3);
dc.Tbcstb(dc.wr6, dc.r14);
dc.Mvn(dc.r14, 3);
dc.Tbcstb(dc.wr7, dc.r14);
dc.Mov(dc.r14, 2);
dc.Tmcr(dc.wcgr0, dc.r14);
BuildWMMXPreLoad2Init(dc);
BuildWMMXPrepareAlignHor(dc, label_wrap);
BuildWMMXLoadHorVerRow(dc, true, false);
{
void *loop = dc.Label();
BuildWMMXLoadHorVerRow(dc, false, false);
BuildWMMXSetHorVerRow(dc, add);
BuildWMMXLoadHorVerRow(dc, true, false);
BuildWMMXSetHorVerRow(dc, add);
dc.Set(); dc.Sub(dc.r14, dc.r14, 2);
dc.Branch(dc.NE, loop);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -