[llvm-uc] Re: [llvm-uc] uc32 function ret 的匯編應該長什麼樣子?

  • From: 刘智猷 <liuzhiyou.cs@xxxxxxxxx>
  • To: llvm-uc@xxxxxxxxxxxxx
  • Date: Wed, 12 Dec 2012 17:06:09 +0800

chenwj,

O1和O0生成代码部分对返回值的处理是一样的:将返回值存入r0寄存器中。

不一样的地方只在于:uc32中O1生成的代码与O0生成代码的区别在于O0的代码在栈上创建了类似于x86的栈帧结构,将lr的值保存在栈上,其后通过弹栈指令ldm将原来压在栈上的lr寄存器值恢复到pc中,这就相当于jump
lr。

如果能保证在Ret发生时lr寄存器的值和刚进入该函数时的值一样,固定用jump lr是没有问题的。

祝好,
刘智猷



2012/12/12 ���f任 (Wei-Ren Chen) <chenwj@xxxxxxxxxxxxxxxxx>

> Hi all,
>
>   目前我正��著�� LLVM uc 後端通�^ ret_void.ll 和 ret0.ll �����y��。
> 遇到了一�c小���}。就我目前的理解,"ret" 和 "ret 0" �@���� LLVM IR
> 是不一�拥母拍睢G罢呤��渭�的控制流�D移,後者多了返回值。控制流�D移
> 和返回值是分�_��理的。以 or1k �碚f [1],控制流�D移是透�^ il.jr r9
> 呈�F:
>
> myfunc:
>   il.jr r9 /* here we are jumping back to the return address, i.e.
>               'returning' */
>   l.nop
>
> main:
>   l.jal myfunc /* calls my_func and places the return address in r9
>                   (that's the OR1K link register) */
>   l.nop
>   l.nop /* this is where we will return */
>   l.nop
>   ....
>
> 如果有返回值,其�R��如下:
>
> test:
>   l.movhi r11, 0 /* this is 'returning something' */
>   l.jr r9 /* this is 'returning' */
>   l.nop
>
> 可以看到返回值和控制流�D移分�e是�傻乐噶睢R� ARM �碚f,不��是 "ret void"
> 或是 "ret 0",我在其�R��都能看到以 "bx lr" �Y尾做控制流�D移。
>
> ---- -O0 ----
>
> -- ret_void.ll --
> main:
>         str     fp, [sp, #-4]!
>         .save {fp}
>         .setfp fp, sp, #0
>         add     fp, sp, #0
>         add     sp, fp, #0
>         ldmfd   sp!, {fp}
>         bx      lr             <---
>
> -- ret0.ll --
> main:
>         str     fp, [sp, #-4]!
>         .save {fp}
>         .setfp fp, sp, #0
>         add     fp, sp, #0
>         mov     r3, #0
>         mov     r0, r3
>         add     sp, fp, #0
>         ldmfd   sp!, {fp}
>         bx      lr              <---
>
> ---- -O1 ----
>
> -- ret_void.ll --
> main:
>         bx      lr      <---
>
> -- ret0.ll --
> main:
>         mov     r0, #0
>         bx      lr      <---
>
>
> 但是在 uc32 我看到的�Y果,函式�Y尾的控制流�D移�s不一�印�
>
> ---- -O0 ----
>
> -- ret_void.ll --
> main:
>         mov     ip, sp
>         stm.w   (fp, ip, lr, pc), [sp-]
>         sub     fp, ip, #4
>         ldm     (fp, sp, pc), [fp-]
>
> -- ret0.ll --
> main:
>         mov     ip, sp
>         stm.w   (fp, ip, lr, pc), [sp-]
>         sub     fp, ip, #4
>         mov     r15, #0
>         mov     r0, r15
>         ldm     (fp, sp, pc), [fp-]
>
> ---- -O1 ----
>
> -- ret_void.ll --
> main:
>         jump    lr
>
> -- ret0.ll --
> main:
>         mov     r0, #0
>         jump    lr
>
>
> 可以看出 uc 在 -O0 和 -O1 �Y尾的部分不同,ARM �t是都以
> "bx lr" �Y尾。�@��我在�� UniCoreInstInfo.td 底下�@��
> pattern �r有些不�_定:
>
> let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
>   def Ret : UniCoreInst<(outs), (ins),
>                         "jump\tlr",    <---
>                         [(ret)]>;
> }
>
> 我�@�e是固定��填 "jump lr" 或是?
>
> Regards,
> chenwj
>
> [1] https://github.com/skristiansson/llvm-or1k/
>
> --
> Wei-Ren Chen (���f任)
> Computer Systems Lab, Institute of Information Science,
> Academia Sinica, Taiwan (R.O.C.)
> Tel:886-2-2788-3799 #1667
> Homepage: http://people.cs.nctu.edu.tw/~chenwj
>
>

Other related posts: