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

📄 dynamicarmcode.cpp

📁 鼎鼎有名的手机mpeg4播放器smart movie-智能影院 解码内核
💻 CPP
📖 第 1 页 / 共 3 页
字号:

   if (code == LDR || code == STR || 
      code == LDR_PRE || code == STR_PRE || 
      code == LDR_POST|| code == STR_POST ||
      code == LDR_PRESUB || code == STR_PRESUB || 
      code == LDR_POSTSUB || code == STR_POSTSUB)
   {
      bool pre = (code != LDR_POST) && (code != STR_POST) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
      bool pre_write = (code == LDR_PRE) || (code == STR_PRE) || (code == LDR_PRESUB) || (code == STR_PRESUB);
      bool load = (code == LDR) || (code == LDR_PRE) || (code == LDR_POST) || (code == LDR_PRESUB) || (code == LDR_POSTSUB);
      bool un_signed = (code != LDR_PRESUB) && (code != STR_PRESUB) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);

      if(next_half || next_sign){
         if(Shift==0 && (next_half || next_byte)){
            p = InstCreate32((next_cond << 28) | 
               ((pre ? 1 : 0)<<24) | (un_signed<<23) | 
               ((pre_write ? 1 : 0)<<21) | (load<<20) | (next_sign << 6) | (next_half << 5) |
               (op_1 << 16) | (Dest << 12) | (9 << 4) | Op2,
               NONE, op_1, Op2, (next_cond != AL)?1:0, 0);
         }
      }else{
         p = InstCreate32((next_cond << 28) | (3 << 25) |
            ((pre ? 1 : 0)<<24) | (un_signed<<23) | (next_byte<<22) |
            ((pre_write ? 1 : 0)<<21) | (load<<20) |
            (op_1 << 16) | (Dest << 12) | (Shift << 7) | (ShiftType << 5) | Op2,
            NONE, op_1, Op2, (next_cond != AL)?1:0, 0);
      }
      if(p){
         if(load)
            p->write_regs |= 1 << Dest;
         else
            p->read_regs |= 1 << Dest;
         if(!pre || pre_write)
            p->write_regs |= 1 << op_1;
      }
   }
   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::I4(int code, byte Dest, byte op_1, byte Op2, byte Op3){

   S_instruction *p = NULL;
   if (code == MLA){
      p = InstCreate32((next_cond << 28) | (1 << 21) | ((next_set?1:0)<<20) |
         (Dest << 16) | (Op3 << 12) | (Op2 << 8) | 0x90 | (op_1),
         Dest, op_1, Op2, (next_cond != AL)?1:0, next_set?1:0);

      p->read_regs |= 1 << Op3;
   }
   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::MulC(E_REGISTER dst, E_REGISTER src, int constant){

   if(dst == src){
      assert(0);
      InstPost(NULL);
   }
   switch(constant){
   case  0: Mov(dst, 0); break;
   case  1: Mov(dst, src); break;
   case  2: Mov(dst, src, LSL, 1); break;
   case  3: Add(dst, src, src, LSL, 1); break;
   case  4: Mov(dst, src, LSL, 2); break;
   case  5: Add(dst, src, src, LSL, 2); break;
   case  6: Mov(dst, src, LSL, 1); Add(dst, dst, dst, LSL, 1); break; //2*3
   case  7: Rsb(dst, src, src, LSL, 3); break;
   case  8: Mov(dst, src, LSL, 3); break;
   case  9: Add(dst, src, src, LSL, 3); break;
   case 10: Mov(dst, src, LSL, 1); Add(dst, dst, dst, LSL, 2); break; //2*5
   case 11: Rsb(dst, src, src, LSL, 3); Add(dst, dst, src, LSL, 2); break;  //7+4
   case 12: Add(dst, src, src, LSL, 1); Mov(dst, dst, LSL, 2); break; //3*4
   case 13: Add(dst, src, src, LSL, 3); Add(dst, dst, src, LSL, 2); break;  //9+4
   case 14: Rsb(dst, src, src, LSL, 3); Add(dst, dst, dst); break;  //7*2
   case 15: Rsb(dst, src, src, LSL, 4); break;
   case 16: Mov(dst, src, LSL, 4); break;
   case 17: Add(dst, src, src, LSL, 4); break;
   default: Mov(dst, constant); Mul(dst, src, dst); break;
   }
}

//----------------------------

void C_dyn_code_imp::IConst(byte Dest, int constant){

   S_instruction *p = NULL;
   int Shift,code;

   if(constant < 0){
      code = MVN;
      constant = -constant-1;
   }else
      code = MOV;

   constant = (constant << 8) | ((constant >> 24) & 255);
   for(Shift=8;Shift<=32;Shift+=2){
      if(constant & 0xC0)
         break;
      constant = (constant << 2) | ((constant >> 30) & 3);
   }
   Shift &= 31;
   constant &= 255;

   p = InstCreate32((next_cond << 28) | (1<<25) | (code << 21) | ((next_set?1:0)<<20) |
      (Dest << 12) | (Shift << 7) | constant, Dest, NONE, NONE, (next_cond != AL)?1:0, next_set?1:0);

   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::I2(int code, byte Dest, byte op_1){
   if (MODE(code) == 1){
      S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 16) | ((op_1 & 15) << 12),
            Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
      InstPost(p);
   }
   else
   if (MODE(code) == 6){
      S_instruction *p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16),
            Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
      InstPost(p);
   }else
      I2C(code,Dest,op_1,0);
}

//----------------------------

void C_dyn_code_imp::I2C(int code, byte Dest, byte op_1, int constant){

   S_instruction *p = NULL;

   if(MODE(code) == 2 && constant>=0 && constant<8){
      p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 16) | ((op_1 & 15) << 12) | (constant << 0),
            Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
   }

   if(MODE(code) == 9 && constant>=0 && constant<256){
      p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | ((constant & 15) << 0) | ((constant & 0xF0) << 16),
            Dest, op_1, NONE, (next_cond != AL)?1:0, 0);
   }

   if(MODE(code) == 15){
      if(constant<0){
         code ^= (1<<23);
         constant = -constant;
      }
      if(code & 256){ // dword or qword
         if(constant & 3)
            constant = -1;
         else
            constant >>= 2;
      }
      if(constant>=0 && constant<256){
         p = InstCreate32((next_cond << 28) | (code & MODEMASK) | ((Dest & 15) << 12) | ((op_1 & 15) << 16) | (constant << 0),
               NONE, op_1, NONE, (next_cond != AL)?1:0, 0);

         if(code & (1<<20))
            p->write_regs |= 1 << Dest;
         else
            p->read_regs |= 1 << Dest;

         if(!(code & (1<<24)) || (code & (1<<21)))
            p->write_regs |= 1 << op_1;
      }
   }

   if(code >= 0 && code < 16){
      if(code==MOV && constant<0){
         code = MVN;
         constant = -constant-1;
      }else
      if(code==ADD && constant<0){
         code = SUB;
         constant = -constant;
      }
      else
      if(code==SUB && constant<0){
         code = ADD;
         constant = -constant;
      }

      if(code == CMP || code == TST || code == CMN || code == TEQ) 
         next_set = 1;

      int shift;
      for(shift = 0; shift<32; shift+=2){
         if(constant>=0 && constant<=255)
            break;
         constant = (constant << 2) | ((constant >> 30) & 3);
      }
      if(constant >= 0 && constant <= 255){
         p = InstCreate32((next_cond << 28) | (1<<25) | (code << 21) | ((next_set?1:0)<<20) |
            ((op_1==NONE ? r0 : op_1) << 16) | ((Dest==NONE ? r0 : Dest) << 12) | (shift << 7) | constant,
            Dest, op_1, NONE, (next_cond != AL)?1:0, next_set?1:0);
      }
   }
   
   IPLD(&code,&Dest);

   if(code == LDR || code == STR || 
      code == LDR_PRE || code == STR_PRE || 
      code == LDR_POST|| code == STR_POST ||
      code == LDR_PRESUB || code == STR_PRESUB || 
      code == LDR_POSTSUB || code == STR_POSTSUB){

      bool pre = (code != LDR_POST) && (code != STR_POST) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);
      bool pre_write = (code == LDR_PRE) || (code == STR_PRE) || (code == LDR_PRESUB) || (code == STR_PRESUB);
      bool load = (code == LDR) || (code == LDR_PRE) || (code == LDR_POST) || (code == LDR_PRESUB) || (code == LDR_POSTSUB);
      bool un_signed = (code != LDR_PRESUB) && (code != STR_PRESUB) && (code != LDR_POSTSUB) && (code != STR_POSTSUB);

      if(constant == 0){
         pre = true;
         pre_write = false;
      }
      if(constant < 0){
         constant = -constant;
         un_signed = !un_signed;
      }

      if(next_half || next_sign){
         if (constant >= 0 && constant < 256 && (next_half || next_byte))
            p = InstCreate32((next_cond << 28) | 
               ((pre ? 1 : 0)<<24) | (un_signed<<23) | (1 << 22) |
               ((pre_write ? 1 : 0)<<21) | (load<<20) | (next_sign << 6) | (next_half << 5) |
               (op_1 << 16) | (Dest << 12) | ((constant >> 4) << 8) | (9 << 4) | (constant & 15),
               NONE, op_1, NONE, (next_cond != AL)?1:0, 0);
      }else
      if(constant >= 0 && constant < 4096){
         p = InstCreate32((next_cond << 28) | (1 << 26) |
            ((pre ? 1 : 0)<<24) | (un_signed<<23) | (next_byte<<22) |
            ((pre_write ? 1 : 0)<<21) | (load<<20) |
            (op_1 << 16) | (Dest << 12) | constant,
            NONE, op_1, NONE, (next_cond != AL)?1:0, 0);
      }
      if(p){
         if(load)
            p->write_regs |= 1 << Dest;
         else
            p->read_regs |= 1 << Dest;
         if(!pre || pre_write)
            p->write_regs |= 1 << op_1;
      }
   }
   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::I1P(int code, byte Dest, void *block, int Ofs){

   S_instruction *p = NULL;

   if(MODE(code)==15){
      p = InstCreate32((next_cond << 28) | (code & MODEMASK) | (pc << 16) | ((Dest & 15) << 12), Dest, pc, NONE, (next_cond != AL)?1:0, 0);

      p->tag = Ofs;
      p->realloc = (S_instruction*)block;
   }

   if(code == LDR || code == STR){
      int load = (code == LDR);

      p = InstCreate32((next_cond << 28) | (1 << 26) | (1<<24) | (next_byte<<22) | (load<<20) | (pc << 16) | (Dest << 12),
         Dest, pc, NONE, (next_cond != AL)?1:0, 0);

      p->tag = Ofs;
      p->realloc = (S_instruction*)block;
   }else
   if(code == MOV){ // ADD|SUB,Dst,R15,Ofs
      p = InstCreate32((next_cond << 28) | (1<<25) | (pc << 16) | (Dest << 12), Dest, pc, NONE, (next_cond != AL)?1:0, 0);

      p->tag = Ofs;
      p->realloc = (S_instruction*)block;
   }
   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::I0P(int code, int Cond, void *target){

   S_instruction *p = NULL;
   if(code == B || code == BL){
      p = InstCreate32((Cond << 28) | (5 << 25) | ((code == BL?1:0)<<24), pc, NONE, NONE, (Cond != AL)?1:0, 0);
      
      if(code == BL)
         p->write_regs |= 1 << lr;
      p->realloc = (S_instruction*)target;
      p->branch = true;
   }
   InstPost(p);
}

//----------------------------

void C_dyn_code_imp::CodeBuild(){

                              //determine code size
   int code_size = 0;
   int num_functions = 0;
   for(S_instruction *p=inst_begin; p; p=p->next){
      code_size += InstructionSize(p, code_size);
      if(p->is_function)
         ++num_functions;
   }
   dynamic_code.functions.Resize(num_functions);
                              //allocate code
   //if(code_size > dynamic_code.allocated){
      dynamic_code.Free();
      dynamic_code.alloc_size = code_size;
      if(max_align)
         dynamic_code.alloc_size += max_align-1;
      dynamic_code.alloc_base = (byte*)CodeAlloc(dynamic_code.alloc_size);
      if(!dynamic_code.alloc_base)
         return;
      dynamic_code.code = dynamic_code.alloc_base;
      if(max_align)
         dynamic_code.code = (byte*)((dword(dynamic_code.alloc_base)+max_align-1) & -max_align);
   //}
   //dynamic_code.size = code_size;
   //if(dynamic_code.code)
   {
      int fnc_index = 0;
      CodeLock(dynamic_code.alloc_base, dynamic_code.alloc_size);

      byte *addr = dynamic_code.code;
      S_instruction *p;
      for(p=inst_begin; p; p=p->next){
         p->address = addr;
         if(p->is_function)
            dynamic_code.functions[fnc_index++] = addr;
         addr += InstructionSize(p, addr - dynamic_code.code);
      }
      for(p=inst_begin; p; p=p->next){
         if(p->realloc && (!p->realloc->address || !InstReAlloc(p, p->realloc))){
            //dynamic_code.size = 0;
            assert(0);
            break;
         }
         if(p->code_large)
            MemCpy(p->address, p->code_large, p->code_size);
         else
         if(p->code_size>0){
            if(p->code_size == sizeof(dword))
               *(dword*)p->address = p->code_small;
            else{
               assert(0);
            }
         }
      }
      CodeUnlock(dynamic_code.alloc_base, dynamic_code.alloc_size);
   }//else
      //dynamic_code.size = 0;
   FreeInstructions();
}

//----------------------------

C_dyn_code *C_dyn_code::Create(){
   return new(true) C_dyn_code_imp;
}

//----------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -