⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcomp.cpp

📁 鼎鼎有名的手机mpeg4播放器smart movie-智能影院 解码内核
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#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 + -