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

📄 dynamicarmcode.cpp

📁 鼎鼎有名的手机mpeg4播放器smart movie-智能影院 解码内核
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 *
 * This program is free software ; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * The Core Pocket Media Player
 * Copyright (c) 2004-2005 Gabor Kovacs
 *
 ****************************************************************************/


#if defined __SYMBIAN32__
#include <e32base.h>
#elif defined _WIN32_WCE
#include <Windows.h>
#endif

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

#include "DynamicArmCode.h"
#include "Util.h"
#include "C_buffer.h"

//mode
//1: I2 rd:16,rn:12
//2: I2C rd:16,rn:12,imm[3]:0
//4: I3 rd:0,rnlo:12,rnhi:16
//6: I2 rd:12,rn:16
//7: I3 rd:12,rn:16,rm:0
//8: I3C rd:12,rn:16,rm:0,imm[3]:20
//9: I2C rd:12,rn:16,imm[8]:0|20
//F: I2C,I1P rd:12,rn:16,imm[8]:0 (w or q *4)
//----------------------------

void *CodeAlloc(int size){
#if defined __SYMBIAN32__ || defined __PALMOS__
                              //Symbian
   return new(true) byte[size];
#elif defined _WIN32_WCE
   return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READ);
#else
#error
#endif
}

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

void CodeFree(void *code, int size){
#if defined __SYMBIAN32__ || defined __PALMOS__
                              //Symbian
   delete[] (byte*)code;
#elif defined _WIN32_WCE
	VirtualFree(code, size, MEM_DECOMMIT);
	VirtualFree(code, 0, MEM_RELEASE);
#else
#error
#endif
}

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

void CodeLock(void *code, int size){
#if defined _WIN32_WCE
   DWORD protect;
	VirtualProtect(code, size, PAGE_READWRITE | PAGE_NOCACHE, &protect);
#endif
}

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

void CodeUnlock(void *code, int size){

                              //flush cache
#ifdef __SYMBIAN32__
   User::IMB_Range(code, (byte*)code+size);
#elif defined _WIN32_WCE
	DWORD protect;
	VirtualProtect(code, size, PAGE_EXECUTE_READ, &protect);

   static void (WINAPI *FuncCacheSync)(DWORD);
   static HMODULE CoreDLL;

   if(!FuncCacheSync && !CoreDLL){
      CoreDLL = LoadLibrary(L"coredll.dll");
      if(CoreDLL)
         *(FARPROC*)&FuncCacheSync = GetProcAddress(CoreDLL, L"CacheSync");
   }
   if(FuncCacheSync)
      FuncCacheSync(2);
#elif defined __PALMOS__
   byte *mem = new byte[65536];
   if(mem){
      MemCpy(mem, mem, 65536);
      delete[] mem;
   }
#else
#error
#endif
}

//----------------------------
                              //detect caps
dword C_dyn_code::GetCpuCaps(){

   dword caps = 0;

#if defined _WIN32_WCE
   HINSTANCE hi = LoadLibrary(L"Coredll.dll");
   if(hi){
      typedef BOOL (t_IsProcessorFeaturePresent)(DWORD);
      t_IsProcessorFeaturePresent *fp = (t_IsProcessorFeaturePresent*)GetProcAddress(hi, L"IsProcessorFeaturePresent");
      if(fp){
         const dword _PF_ARM_INTEL_WMMX = 0x80010003;
         if((*fp)(_PF_ARM_INTEL_WMMX) != 0)
            caps |= CPU_WIRELESS_MMX;
      }
      FreeLibrary(hi);
   }
#endif
   return caps;
}

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

class C_dyn_code_imp: public C_dyn_code{

   struct S_instruction{
      S_instruction *next, *prev;
      int tag;
      int read_flags;
      int write_flags;
      dword read_regs;
      dword write_regs;
      S_instruction *realloc;
      bool branch;            //branch label
      bool is_function;
      dword code_small;
      byte *code_large;
      int code_size;
      byte *address;

      S_instruction():
         tag(0),
         next(NULL),
         prev(NULL),
         read_flags(0),
         write_flags(0),
         read_regs(0),
         write_regs(0),
         realloc(NULL),
         branch(false),
         is_function(false),
         code_small(0),
         code_large(NULL),
         address(NULL)
      {}
   };

   E_CONDITION next_cond;
   bool next_set,
      next_byte,
      next_half,
      next_sign;
   dword max_align;

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

   struct S_dynamic_code{
      byte *alloc_base;
      dword alloc_size;
      byte *code;
      //dword size;
      S_dynamic_code():
         alloc_base(NULL),
         code(NULL),
         //size(0),
         alloc_size(0)
      {}
      ~S_dynamic_code(){
         Free();
      }

      void Free(){
         if(alloc_base)
            CodeFree(alloc_base, alloc_size);
         alloc_base = NULL;
         code = NULL;
         //size = 
         alloc_size = 0;
      }
      C_buffer<void*> functions;
   } dynamic_code;

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

   S_instruction *inst_begin, *inst_end;
   bool move_back;
   //bool delay_slot;
   dword local_vars_size;

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

   void InstInit();

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

   inline void StoreReg(dword &regs, dword reg){

      if(reg != NONE){
         if(reg<32)
            regs |= 1 << reg;
         else
            regs |= 256 << (reg-32); 
      }
   }

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

   S_instruction *InstCreate(const void *code, int code_size, byte write_reg, byte read_reg_1, byte read_reg_2, int read_flags, int write_flags);

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

   static bool InstReadWrite(const S_instruction *a, const S_instruction *b){
      return ((a->read_flags&b->write_flags) || (a->read_regs&b->write_regs));
   }

   static bool InstBothWrite(const S_instruction *a, const S_instruction *b){
      return ((a->write_flags&b->write_flags) || (a->write_regs&b->write_regs));
   }

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

   static int InstructionSize(const S_instruction *p, int pos){

      if(p->code_size >= 0)
         return p->code_size;
      pos = pos % -p->code_size;
      if(pos)
         pos = -p->code_size - pos;
      return pos;
   }

   static byte *InstCode(S_instruction *p){
      return p->code_large ? p->code_large : (byte*)&p->code_small;
   }


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

   void InstAdd(S_instruction *ins){

      assert(ins);

      S_instruction *p = inst_end; //insert after p
      /*
      if(delay_slot){
         assert(p && !p->branch && !InstReadWrite(p, ins) && !InstReadWrite(ins, p) && !InstBothWrite(p, ins));
         p->branch = true;
         p = p->prev;
         delay_slot = false;
      }
      */
      if(move_back){
         while(p && !p->branch && !p->is_function && !InstReadWrite(p, ins) && !InstReadWrite(ins, p) && !InstBothWrite(p, ins))
            p = p->prev;
         move_back = false;
      }
      
      if(p){
         if(p->next) 
            p->next->prev = ins;
         else
            inst_end = ins;
         ins->next = p->next;
         ins->prev = p;
         p->next = ins;
      }else{
         if(inst_begin)
            inst_begin->prev = ins;
         else
            inst_end = ins;
         ins->next = inst_begin;
         ins->prev = NULL;
         inst_begin = ins;
      }
   }

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

   S_instruction *InstCreate32(int Code32, byte write_reg = NONE, byte read_reg_1 = NONE, byte read_reg_2 = NONE, int read_flags = 0, int write_flags = 0){
      return InstCreate(&Code32, 4, write_reg, read_reg_1, read_reg_2, read_flags, write_flags);
   }

   /*
   S_instruction *InstCreate16(int Code16, byte write_reg, byte read_reg_1, byte read_reg_2, int read_flags, int write_flags){
      return InstCreate(&Code16, 2, write_reg, read_reg_1, read_reg_2, read_flags, write_flags);
   }
   */

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

   void FreeInstructions();

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

   bool InstReAlloc(S_instruction *p, const S_instruction *realloc);

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

   void IPLD(int *code, byte *dest);

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

public:
   C_dyn_code_imp():
      move_back(false),
      local_vars_size(0),
      inst_begin(NULL),
      inst_end(NULL),
      max_align(0)
   {
      InstInit();
   }
   ~C_dyn_code_imp(){
      Close();
   }

   void Close(){
      FreeInstructions();
      dynamic_code.Free();
   }

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

   virtual void Byte(){
      next_byte = true;
      next_sign = false;
   }

   virtual void Half(){
      next_half = true;
      next_sign = false;
   }

   virtual void SByte(){
      next_byte = true;
      next_sign = true;
   }

   virtual void SHalf(){
      next_half = true;
      next_sign = true;
   }

   virtual void Cond(E_CONDITION c){
      next_cond = c;
   }

   virtual void Set(){

⌨️ 快捷键说明

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