精华内容
下载资源
问答
  • 二进制翻译

    千次阅读 2015-10-10 21:37:00
    开始以二进制翻译为方向的硕士研究生生活已经一年多了,对于该技术的实用性仍然持怀疑态度,呵呵,记录自己想记录的,也是受博客园里一位前辈文章的影响,写作是更好的思考 。 二进制翻译就是把一种指令集架构的二...

    开始以二进制翻译为方向的硕士研究生生活已经一年多了,对于该技术的实用性仍然持怀疑态度,呵呵,记录自己想记录的,也是受博客园里一位前辈文章的影响,写作是更好的思考 。

    二进制翻译就是把一种指令集架构的二进制文件转换成用另一种指令集架构中的指令描述的逻辑等价的二进制文件的过程或者技术。比如说把ARM平台的可执行程序利用二进制翻译程序翻译到x86平台。学校启动这个项目的研究最初的目的是为了满足特定单位的特定用途,现在为了更好的推广国产化一体化平台,使国产平台可以直接运行现有的软件,减小国产平台推广的难度。

    转载于:https://www.cnblogs.com/laohu/p/4842780.html

    展开全文
  • 二进制翻译是在不同硬件平台之间实现软件迁移的重要手段.在二进制翻译系统中,如何在没有标志位寄存器的目标平台上模拟实现源平台上标志位寄存器的功能,是影响系统性能的关键.现有的标志位分析技术通过对标志位的定值...
  • 如何处理库函数调用问题直接关系到二进制翻译系统的性能。提出了一种系统库函数的分类处理方法,成功地解决了二进制翻译系统中的库函数调用处理问题。
  • 二进制翻译是实现系统迁移的主要方法,但基于通用平台的仅靠软件实现的二进制翻译性能不高。该文以龙芯2F处理器为实现平台,提出一种QEMU二进制翻译器并进行优化,其中包括编译环境的优化以及二进制翻译器本身的优化...
  • MIPS安卓平台上ARM二进制翻译系统.pdf
  • 摘 要:二进制翻译技术是代码移植技术中的一种重要技术。针对二进制翻译的应用,提出在ARM嵌入式平台下实现X86 t0 ARM二进制翻译系统。通过对ARM嵌入式平台的研究,介绍二进制翻译模块的功能,着重论述SOC架构的设计...
  • CrossBit是一个多元多目标的动态二进制翻译系统,通过对CrossBit二进制翻译器的性能进行的研究,分析动态二进制翻译器性能提升中所必须解决的若干问题,并通过定量的分析总结了一些二进制翻译系统的在不同的配置和...
  • 软件移植、二进制翻译和国产处理器发展.pdf
  • 作者介绍了正在研究的动态二进制翻译系统中使用的跳转优化的技术,分别是直接跳转优化和间接跳转优化.实验结果证明,由于直接跳转优化回避了一般二进制翻译系统中每个基本块之间必要的切换判断,因而取得了明显的性能...
  • 动态优化是动态二进制翻译研究中一个十分重要的课题,数据预取优化能提高现代处理器体系结构应用程序性能。基于超级块(Superblock)的动态数据预取优化采用软件插桩方式收集应用程序的load访存延迟信息并构造...
  • 面向ARM平台的二进制翻译系统标志位优化.pdf
  • 行业分类-设备装置-动态二进制翻译中代码Cache管理方法.zip
  • 体系结构的不断发展给软件开发者带来了巨大的风险,造成了新体系结构推广的困难,而二进制翻译技术使得可执行代码可自动迁移到新的体系结构。介绍了在开发一个静态二进制翻译系统(I2A翻译系统)中的库函数识别技术...
  • 二进制翻译也是一种编译技术 ,它与传统编译的差别在于其编译处理对象不同。 传统编译处理的对象是某一种高级语言,经过编译处理生成某种机器的目标代码;二进制翻译处理的对象是某种机器的二进制代码,该二进制...

    二进制翻译也是一种编译技术 ,它与传统编译的差别在于其编译处理对象不同。

    传统编译处理的对象是某一种高级语言,经过编译处理生成某种机器的目标代码;二进制翻译处理的对象是某种机器的二进制代码,该二进制代码是经过传统编译生成的,经过二进制翻译处理后生成另一种机器的二进制代码。

    按照传统编译程序前端、中端和后端的划分,我们可以理解为二进制翻译是拥有特殊前端的编译器。

     

     1 package Com.TableTest;
     2 
     3     class Cat{
     4         int size;
     5 
     6         void bark(){
     7             
     8         
     9             if(size>60){
    10         
    11             System.out.println("yet!");
    12             
    13         
    14             }else if(size>14){
    15         
    16             System.out.println("Hi!");
    17             
    18         
    19             }else{
    20         
    21             System.out.println("Hello!");
    22             
    23         
    24             }
    25 
    26         }
    27     }
    28     public class TableText_12 {
    29         public static void main(String[] args){
    30     
    31         Cat one = new Cat();
    32         one.size = 70;
    33         Cat two = new Cat();
    34         two.size = 8;
    35         Cat three =  new Cat();
    36         three.size = 35;
    37 
    38         one.bark();
    39         two.bark();
    40         three.bark();
    41     }
    42 }
    43     
    44 
    45 
    46 
    47  

     

    转载于:https://www.cnblogs.com/borter/p/9388483.html

    展开全文
  • 动态二进制翻译中数据预取优化研究,罗琼程,吴强,动态优化是动态二进制翻译研究中一个十分重要的课题,数据预取优化能提高现代处理器体系结构应用程序性能。基于超级块(SuperBlock)的
  • 二进制翻译器Ascii 从二进制转换为文本和文本到二进制很容易。您只需选择要转换的文本,然后在上下文菜单中出现转换文本的选项。 支持语言:español (Latinoamérica)
  • 该论文是是初步了解qemu的一篇极好的文章,文章对qemu的性能做了分析,并介绍了动态二进制翻译技术。
  • 在跨平台系统虚拟机原型ARCH-BRIDGE的基础上,提出了一种基本块级的动态二进制翻译优化方法,通过两阶段翻译、基于虚拟寄存器的优化翻译及延迟机器状态提交等技术,可在不采用中间表示及确保精确异常的情况下,有效...
  • 这里给出了一种具有X86到ARM二进制翻译和执行功能的SoC系统。利用Multi-layer bus SWitch(BusMatrix)模块实现Multi-layer。总线结构,在多个核不访问同一个Slave时,可以同时执行各自功能,有效提高系统的性能,且该...
  • 提出一种二进制翻译中代码Cache管理的LRC(LevelRegionChunk)策略。其兼具全清空策略、FIFO策略和多级Cache的优点,并且考虑了程序的时间空间局部性、执行特性和替换开销,具有较好的性能,实现了代码Cache的...
  • 通过二进制翻译手段将CUDA程序移植到其他异构众核处理器平台特别是国产处理器平台,对扩展CUDA程序应用范围,发挥目标平台的众核优势以及支持民族产业都具有现实意义。设计了CUDA程序的二进制翻译框架,从CUDA程序可...
  • 行业分类-设备装置-多处理器平台下的动态二进制翻译方法.zip
  • 静态二进制翻译的入口点通常为main函数,所以main函数执行之前的动态地址解析部分就无法在目标机上恢复。通过分析基于ELF文件的动态地址解析机制,提出了在目标代码中插入代码模拟动态地址解析的方法来解决该问题。...
  • 这里给出了一种具有X86到ARM二进制翻译和执行功能的SoC系统。利用Multi-layer bus SWitch(BusMatrix)模块实现Multi-layer。总线结构,在多个核不访问同一个Slave时,可以同时执行各自功能,有效提高系统的性能,且该...
  • 提出一种二进制翻译中代码Cache管理的LRC(Level-Region-Chunk)策略。其兼具全清空策略、FIFO策略和多级Cache的优点,并且考虑了程序的时间空间局部性、执行特性和替换开销,具有较好的性能,实现了代码Cache的高效...
  • qemu源码分析--qemu是开源的二进制翻译器,支持多种平台,具有很好的移植性。
  • qemu的源码,主要应用在二进制翻译中,希望对大家有帮助
  • qemu 二进制翻译 执行流程分析

    千次阅读 2014-04-26 15:25:05
     qemu是使用动态二进制翻译的cpu模拟器,它支持两种运行模式:全系统模拟和用户态模拟。在全系统模拟下,qemu可以模拟处理器和各种外设,可以运行操作系统。用户态可以运行为另外一种cpu编译的进程,前提是两者运行...

    一.qemu简介

             qemu是使用动态二进制翻译的cpu模拟器,它支持两种运行模式:全系统模拟和用户态模拟。在全系统模拟下,qemu可以模拟处理器和各种外设,可以运行操作系统。用户态可以运行为另外一种cpu编译的进程,前提是两者运行的os要一致。qemu使用了动态二进制翻译将targetinstruction翻译成hostinstruction,完成这个工作的是tcg模块。为了移植性和通用性方面的考虑,qemu定义了mirco-op,首先qemu会将targetinstruction翻译成mirco-op,然后tcgmirco-op翻译成host instruction

    Qemu代码翻译流程:target instruction ->micro-op->tcg->host instruction

    2.qemu代码执行流程:

        1. 这部分主要是创建了一个为执行tcg翻译和执行的线程,它的函数是qemu_tcg_cpu_thread_fn,这个函数会调用tcg_exec_all,最后cpu_exec.   

    main
    cpu_init
    qemu_init_vcpu
    qemu_tcg_init_vcpu

    qemu_tcg_cpu_thread_fn

         2.执行主函数(cpu_exec)

                    主要是处理中断异常, 找到代码翻译块,然后执行.

    [cpp]  view plain copy
    1. for(;;) {  
    2. process interruptrequest;  
    3.   
    4. tb_find_fast();  
    5.   
    6. tcg_qemu_tb_exec(tc_ptr);  
    7. }  

            qemu会将翻译好到代码块暂存起来,因此首先会去查看该pc对应的代码是否已经翻译,如果已经存在直接返回,否则就进入tb_find_slow,进行翻译。

    [cpp]  view plain copy
    1. 139 static inline TranslationBlock *tb_find_fast(CPUArchState *env)  
    2. 140 {  
    3. 141     TranslationBlock *tb;  
    4. 142     target_ulong cs_base, pc;  
    5. 143     int flags;  
    6. 144   
    7. 145     /* we record a subset of the CPU state. It will 
    8. 146        always be the same before a given translated block 
    9. 147        is executed. */  
    10. 148     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);  
    11. 149     tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];  
    12. 150     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||  
    13. 151                  tb->flags != flags)) {  
    14. 152         tb = tb_find_slow(env, pc, cs_base, flags);  
    15. 153     }  
    16. 154     return tb;  
    17. 155 }  

           进入tb_find_slow后会调用tb_gen_code,首先分配TranslationBlock描述符,将要翻译的pc等信息记录下来,然后调用cpu_gen_code,这个函数完成代码翻译工作。qemu将翻译好的代码存在一个缓冲区里面。

    [cpp]  view plain copy
    1. 1029 TranslationBlock *tb_gen_code(CPUArchState *env,  
    2. 1030                               target_ulong pc, target_ulong cs_base,  
    3. 1031                               int flags, int cflags)  
    4. 1032 {            
    5. 1033     TranslationBlock *tb;  
    6. 1034     uint8_t *tc_ptr;  
    7. 1035     tb_page_addr_t phys_pc, phys_page2;  
    8. 1036     target_ulong virt_page2;  
    9. 1037     int code_gen_size;  
    10. 1038      
    11. 1039     phys_pc = get_page_addr_code(env, pc);  
    12. 1040     tb = tb_alloc(pc);  
    13. 1041     if (!tb) {  
    14. 1042         /* flush must be done */  
    15. 1043         tb_flush(env);  
    16. 1044         /* cannot fail at this point */  
    [cpp]  view plain copy
    1. 1045         tb = tb_alloc(pc);  
    2. 1046         /* Don't forget to invalidate previous TB info.  */  
    3. 1047         tb_invalidated_flag = 1;  
    4. 1048     }  
    5. 1049     tc_ptr = code_gen_ptr;  
    6. 1050     tb->tc_ptr = tc_ptr;  
    7. 1051     tb->cs_base = cs_base;  
    8. 1052     tb->flags = flags;  
    9. 1053     tb->cflags = cflags;  
    10. 1054     cpu_gen_code(env, tb, &code_gen_size);  
    11. 1055     code_gen_ptr = (void *)(((uintptr_t)code_gen_ptr + code_gen_size +  
    12. 1056                              CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));  
    13. 1057   
    14. 1058     /* check next page if needed */  
    15. 1059     virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;  
    16. 1060     phys_page2 = -1;  
    17. 1061     if ((pc & TARGET_PAGE_MASK) != virt_page2) {  
    18. 1062         phys_page2 = get_page_addr_code(env, virt_page2);  
    19. 1063     }  
    20. 1064     tb_link_page(tb, phys_pc, phys_page2);  
    21. 1065     return tb;  
    22. 1066 }  

          在cpu_gen_code里面首先是将targetinstruction翻译成micro-op,然后将mirco-op翻译成host机器码。

    [cpp]  view plain copy
    1. 54 int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)  
    2.  55 {  
    3.  56     TCGContext *s = &tcg_ctx;  
    4.  57     uint8_t *gen_code_buf;  
    5.  58     int gen_code_size;  
    6.  59 #ifdef CONFIG_PROFILER  
    7.  60     int64_t ti;  
    8.  61 #endif  
    9.  62   
    10.  63 #ifdef CONFIG_PROFILER  
    11.  64     s->tb_count1++; /* includes aborted translations because of 
    12.  65                        exceptions */  
    13.  66     ti = profile_getclock();  
    14.  67 #endif  
    15.  68     tcg_func_start(s);  
    16.  69   
    17.  70     gen_intermediate_code(env, tb);  
    18.  71   
    19.  72     /* generate machine code */  
    20.  73     gen_code_buf = tb->tc_ptr;  
    21.  74     tb->tb_next_offset[0] = 0xffff;  
    22.  75     tb->tb_next_offset[1] = 0xffff;  
    23.  76     s->tb_next_offset = tb->tb_next_offset;  
    24.  77 #ifdef USE_DIRECT_JUMP  
    25.  78     s->tb_jmp_offset = tb->tb_jmp_offset;  
    26.  79     s->tb_next = NULL;  
    27.  80 #else  
    28.  81     s->tb_jmp_offset = NULL;  
    29.  82     s->tb_next = tb->tb_next;  
    30.  83 #endif  
    31.  84   
    32.  85 #ifdef CONFIG_PROFILER  
    33.  86     s->tb_count++;  
    34.  87     s->interm_time += profile_getclock() - ti;  
    35.  88     s->code_time -= profile_getclock();  
    36.  89 #endif  
    37.  90     gen_code_size = tcg_gen_code(s, gen_code_buf);  
    38.  91     *gen_code_size_ptr = gen_code_size;  
    39.  92 #ifdef CONFIG_PROFILER  
    40.  93     s->code_time += profile_getclock();  
    41.  94     s->code_in_len += tb->size;  
    42.  95     s->code_out_len += gen_code_size;  
    43.  96 #endif  
    44.  97   
    45.  98 #ifdef DEBUG_DISAS  
    46.  99     if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM)) {  
    47. 100         qemu_log("OUT: [size=%d]\n", *gen_code_size_ptr);  
    48. 101         log_disas(tb->tc_ptr, *gen_code_size_ptr);  
    49. 102         qemu_log("\n");  
    50. 103         qemu_log_flush();  
    51. 104     }  
    52. 105 #endif  
    53. 106     return 0;  
    54. 107 }  

           qemutarget翻译成中间码时,将操作码和操作数分开存储,分别存在gen_opc_bufgen_opparam_buf中。翻译的过程就是不断向gen_opc_bufgen_opparam_buf中填充操作码和操作数。接下来就是tcg_gen_code.

    [cpp]  view plain copy
    1. 2175 int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)  
    2. 2176 {  
    3. 2177 #ifdef CONFIG_PROFILER  
    4. 2178     {  
    5. 2179         int n;  
    6. 2180         n = (gen_opc_ptr - gen_opc_buf);  
    7. 2181         s->op_count += n;  
    8. 2182         if (n > s->op_count_max)  
    9. 2183             s->op_count_max = n;  
    10. 2184   
    11. 2185         s->temp_count += s->nb_temps;  
    12. 2186         if (s->nb_temps > s->temp_count_max)  
    13. 2187             s->temp_count_max = s->nb_temps;  
    14. 2188     }  
    15. 2189 #endif  
    16. 2190   
    17. 2191     tcg_gen_code_common(s, gen_code_buf, -1);  
    18. 2192   
    19. 2193     /* flush instruction cache */  
    20. 2194     flush_icache_range((tcg_target_ulong)gen_code_buf,  
    21. 2195                        (tcg_target_ulong)s->code_ptr);  
    22. 2196   
    23. 2197     return s->code_ptr -  gen_code_buf;  
    24. 2198 }  

          tcg_gen_code的工作是将中间码翻译成host机器码,它的主要函数是tcg_gen_code_common.

    [cpp]  view plain copy
    1. 2045 static inline int tcg_gen_code_common(TCGContext *s, uint8_t *gen_code_buf,  
    2. 2046                                       long search_pc)  
    3. 2047 {  
    4. 2048     TCGOpcode opc;  
    5. 2049     int op_index;  
    6. 2050     const TCGOpDef *def;  
    7. 2051     unsigned int dead_args;  
    8. 2052     const TCGArg *args;  
    9. 2053   
    10. 2054 #ifdef DEBUG_DISAS  
    11. 2055     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {  
    12. 2056         qemu_log("OP:\n");  
    13. 2057         tcg_dump_ops(s);  
    14. 2058         qemu_log("\n");  
    15. 2059     }  
    16. 2060 #endif  
    17. 2061   
    18. 2062 #ifdef USE_TCG_OPTIMIZATIONS  
    19. 2063     gen_opparam_ptr =  
    20. 2064         tcg_optimize(s, gen_opc_ptr, gen_opparam_buf, tcg_op_defs);  
    21. 2065 #endif  
    22. 2066   
    23. 2067 #ifdef CONFIG_PROFILER  
    24. 2068     s->la_time -= profile_getclock();  
    25. 2069 #endif  
    26. 2070     tcg_liveness_analysis(s);  
    27. 2071 #ifdef CONFIG_PROFILER  
    28. 2072     s->la_time += profile_getclock();  
    29. 2073 #endif  
    30. 2074   
    31. 2075 #ifdef DEBUG_DISAS  
    32. 2076     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP_OPT))) {  
    33. 2077         qemu_log("OP after liveness analysis:\n");  
    34. 2078         tcg_dump_ops(s);  
    35. 2079         qemu_log("\n");  
    36. 2080     }  
    37. 2081 #endif  
    38. 2082   
    39. 2083     tcg_reg_alloc_start(s);  
    40. 2084   
    41. 2085     s->code_buf = gen_code_buf;  
    42. 2086     s->code_ptr = gen_code_buf;  
    43. 2087   
    44. 2088     args = gen_opparam_buf;  
    45.  2089     op_index = 0;  
    46. 2090   
    47. 2091     for(;;) {  
    48. 2092         opc = gen_opc_buf[op_index];  
    49. 2093 #ifdef CONFIG_PROFILER  
    50. 2094         tcg_table_op_count[opc]++;  
    51. 2095 #endif  
    52. 2096         def = &tcg_op_defs[opc];  
    53. 2097 #if 0  
    54. 2098         printf("%s: %d %d %d\n", def->name,  
    55. 2099                def->nb_oargs, def->nb_iargs, def->nb_cargs);  
    56. 2100         //        dump_regs(s);  
    57. 2101 #endif  
    58. 2102         switch(opc) {  
    59. 2103         case INDEX_op_mov_i32:  
    60. 2104 #if TCG_TARGET_REG_BITS == 64  
    61. 2105         case INDEX_op_mov_i64:  
    62. 2106 #endif  
    63. 2107             dead_args = s->op_dead_args[op_index];  
    64. 2108             tcg_reg_alloc_mov(s, def, args, dead_args);  
    65. 2109             break;  
    66. 2110         case INDEX_op_movi_i32:  
    67. 2111 #if TCG_TARGET_REG_BITS == 64  
    68. 2112         case INDEX_op_movi_i64:  
    69. 2113 #endif  
    70. 2114             tcg_reg_alloc_movi(s, args);  
    71. 2115             break;  
    72. 2116         case INDEX_op_debug_insn_start:  
    73. 2117             /* debug instruction */  
    74. 2118             break;  
    75. 2119         case INDEX_op_nop:  
    76. 2120         case INDEX_op_nop1:  
    77. 2121         case INDEX_op_nop2:  
    78. 2122         case INDEX_op_nop3:  
    79. 2123             break;  
    80. 2124         case INDEX_op_nopn:  
    81. 2125             args += args[0];  
    82. 2126             goto next;  
    83. 2127         case INDEX_op_discard:  
    84. 2128             {  
    85.  2129                 TCGTemp *ts;  
    86. 2130                 ts = &s->temps[args[0]];  
    87. 2131                 /* mark the temporary as dead */  
    88. 2132                 if (!ts->fixed_reg) {  
    89. 2133                     if (ts->val_type == TEMP_VAL_REG)  
    90. 2134                         s->reg_to_temp[ts->reg] = -1;  
    91. 2135                     ts->val_type = TEMP_VAL_DEAD;  
    92. 2136                 }  
    93. 2137             }  
    94. 2138             break;  
    95. 2139         case INDEX_op_set_label:  
    96. 2140             tcg_reg_alloc_bb_end(s, s->reserved_regs);  
    97. 2141             tcg_out_label(s, args[0], s->code_ptr);  
    98. 2142             break;  
    99. 2143         case INDEX_op_call:  
    100. 2144             dead_args = s->op_dead_args[op_index];  
    101. 2145             args += tcg_reg_alloc_call(s, def, opc, args, dead_args);  
    102. 2146             goto next;  
    103. 2147         case INDEX_op_end:  
    104. 2148             goto the_end;  
    105. 2149         default:  
    106. 2150             /* Sanity check that we've not introduced any unhandled opcodes. */  
    107. 2151             if (def->flags & TCG_OPF_NOT_PRESENT) {  
    108. 2152                 tcg_abort();  
    109. 2153             }  
    110. 2154             /* Note: in order to speed up the code, it would be much 
    111. 2155                faster to have specialized register allocator functions for 
    112. 2156                some common argument patterns */  
    113. 2157             dead_args = s->op_dead_args[op_index];  
    114. 2158             tcg_reg_alloc_op(s, def, opc, args, dead_args);  
    115. 2159             break;  
    116. 2160         }  
    117. 2161         args += def->nb_args;  
    118. 2162     next:  
    119. 2163         if (search_pc >= 0 && search_pc < s->code_ptr - gen_code_buf) {  
    120. 2164             return op_index;  
    121. 2165         }  
    122. 2166         op_index++;  
    123. 2167 #ifndef NDEBUG  
    124. 2168         check_regs(s);  
    125. 2169 #endif  
    126. 2170     }  
    127.  2171  the_end:  
    128. 2172     return -1;  
    129. 2173 }  

           大部分执行default分支,tcg_reg_alloc_op主要是分析该指令的输入、输出约束,根据这些约束分配寄存器等,然后调用tcg_out_op将该中间码翻译成host机器码。

    3.翻译代码块的执行

         代码块翻译好之后,主函数调用tcg_qemu_tb_exec,该函数会进入tcg的入口函数。

    hostarm为例,入口函数主要是保存寄存器的状态,然后将tcg_qemu_tb_exec传进来的第一的参数(env)TCG_AREG0,然后跳转至tb_ptr,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。

    以host arm 为例,入口函数主要是保存寄存器的状态,然后将 tcg_qemu_tb_exec 传进来的第一的参数 (env) TCG_AREG0 ,然后跳转至 tb_ptr ,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。
    [cpp]  view plain copy
    1. 100 #define tcg_qemu_tb_exec(env, tb_ptr) \  
    2. 101     ((long __attribute__ ((longcall)) \  
    3. 102       (*)(void *, void *))code_gen_prologue)(env, tb_ptr)  

          code_gen_prologuetcg的入口函数,在tcg初始化的时候会生成相应的代码.

             以hostarm为例,入口函数主要是保存寄存器的状态,然后将tcg_qemu_tb_exec传进来的第一的参数(env)TCG_AREG0,然后跳转至tb_ptr,开始执行代码。同时代码执行的返回地址也确定了,返回后恢复之前保存的状态。

    [cpp]  view plain copy
    1. 1881 static void tcg_target_qemu_prologue(TCGContext *s)  
    2. 1882 {  
    3. 1883     /* Calling convention requires us to save r4-r11 and lr; 
    4. 1884      * save also r12 to maintain stack 8-alignment. 
    5. 1885      */  
    6. 1886       
    7. 1887     /* stmdb sp!, { r4 - r12, lr } */  
    8. 1888     tcg_out32(s, (COND_AL << 28) | 0x092d5ff0);  
    9. 1889   
    10. 1890     tcg_out_mov(s, TCG_TYPE_PTR, TCG_AREG0, tcg_target_call_iarg_regs[0]);  
    11. 1891   
    12. 1892     tcg_out_bx(s, COND_AL, tcg_target_call_iarg_regs[1]);  
    13. 1893     tb_ret_addr = s->code_ptr;  
    14. 1894       
    15. 1895     /* ldmia sp!, { r4 - r12, pc } */  
    16. 1896     tcg_out32(s, (COND_AL << 28) | 0x08bd9ff0);  
    17. 1897 }     

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 139,274
精华内容 55,709
关键字:

二进制翻译