On Tue, Apr 28, 2015 at 4:19 PM, Martin Galvan
<martin.gal...@tallertechnologies.com> wrote:
> This patch adds CFI directives to the soft floating point support code for 
> ARM.
>
> Previously, if we tried to do a backtrace from that code in a debug session 
> we'd
> get something like this:
>
> (gdb) bt
> #0  __nedf2 () at 
> ../../../../../../gcc-4.9.2/libgcc/config/arm/ieee754-df.S:1082
> #1  0x00000db6 in __aeabi_cdcmple () at 
> ../../../../../../gcc-4.9.2/libgcc/config/arm/ieee754-df.S:1158
> #2  0xf5c28f5c in ?? ()
> Backtrace stopped: previous frame identical to this frame (corrupt stack?)
>
> Now we'll get something like this:
>
> (gdb) bt
> #0  __nedf2 () at 
> ../../../../../../gcc-4.9.2/libgcc/config/arm/ieee754-df.S:1156
> #1  0x00000db6 in __aeabi_cdcmple () at 
> ../../../../../../gcc-4.9.2/libgcc/config/arm/ieee754-df.S:1263
> #2  0x00000dc8 in __aeabi_dcmpeq () at 
> ../../../../../../gcc-4.9.2/libgcc/config/arm/ieee754-df.S:1285
> #3  0x00000504 in main ()
>
> I have a company-wide copyright assignment. I don't have commit access, 
> though, so it would be great if anyone could commit this for me.
>
> Thanks a lot!
>

this is OK , thanks. Sorry about the delay in reviewing this.

Ramana

> libgcc/ChangeLog:
> 2015-04-23  Martin Galvan  <martin.gal...@tallertechnologies.com>
>
>         * config/arm/lib1funcs.S (CFI_START_FUNCTION, CFI_END_FUNCTION):
>         New macros.
>         * config/arm/ieee754-df.S: Add CFI directives.
>         * config/arm/ieee754-sf.S: Add CFI directives.
>
> ---
> libgcc/config/arm/ieee754-df.S |  177 ++-
> libgcc/config/arm/ieee754-sf.S | 1727 ++++++++++++++-------------
> libgcc/config/arm/lib1funcs.S  |   10 +
> 3 files changed, 1074 insertions(+), 840 deletions(-)
>
> diff --git a/libgcc/config/arm/ieee754-df.S b/libgcc/config/arm/ieee754-df.S
> index f75630b..d1f9066 100644
> --- a/libgcc/config/arm/ieee754-df.S
> +++ b/libgcc/config/arm/ieee754-df.S
> @@ -33,8 +33,12 @@
>   * Only the default rounding mode is intended for best performances.
>   * Exceptions aren't supported yet, but that can be added quite easily
>   * if necessary without impacting performances.
> + *
> + * In the CFI related comments, 'previousOffset' refers to the previous 
> offset
> + * from sp used to compute the CFA.
>   */
>
> +    .cfi_sections .debug_frame
>
>  #ifndef __ARMEB__
>  #define xl r0
> @@ -53,11 +57,13 @@
>
>  ARM_FUNC_START negdf2
>  ARM_FUNC_ALIAS aeabi_dneg negdf2
> +    CFI_START_FUNCTION
>
>      @ flip sign bit
>      eor xh, xh, #0x80000000
>      RET
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dneg
>      FUNC_END negdf2
>
> @@ -66,6 +72,7 @@ ARM_FUNC_ALIAS aeabi_dneg negdf2
>  #ifdef L_arm_addsubdf3
>
>  ARM_FUNC_START aeabi_drsub
> +    CFI_START_FUNCTION
>
>      eor xh, xh, #0x80000000 @ flip sign bit of first arg
>      b   1f
> @@ -81,7 +88,11 @@ ARM_FUNC_ALIAS aeabi_dsub subdf3
>  ARM_FUNC_START adddf3
>  ARM_FUNC_ALIAS aeabi_dadd adddf3
>
> -1:  do_push {r4, r5, lr}
> +1:  do_push {r4, r5, lr}        @ sp -= 12
> +    .cfi_adjust_cfa_offset 12   @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0       @ Registers are saved from sp to sp + 8
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
>
>      @ Look for zeroes, equal values, INF, or NAN.
>      shift1  lsl, r4, xh, #1
> @@ -148,6 +159,11 @@ ARM_FUNC_ALIAS aeabi_dadd adddf3
>      @ Since this is not common case, rescale them off line.
>      teq r4, r5
>      beq LSYM(Lad_d)
> +
> +@ CFI note: we're lucky that the branches to Lad_* that appear after this 
> function
> +@ have a CFI state that's exactly the same as the one we're in at this
> +@ point. Otherwise the CFI would change to a different state after the 
> branch,
> +@ which would be disastrous for backtracing.
>  LSYM(Lad_x):
>
>      @ Compensate for the exponent overlapping the mantissa MSB added later
> @@ -413,6 +429,7 @@ LSYM(Lad_i):
>      orrne   xh, xh, #0x00080000 @ quiet NAN
>      RETLDM  "r4, r5"
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dsub
>      FUNC_END subdf3
>      FUNC_END aeabi_dadd
> @@ -420,12 +437,19 @@ LSYM(Lad_i):
>
>  ARM_FUNC_START floatunsidf
>  ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
> +    CFI_START_FUNCTION
>
>      teq r0, #0
>      do_it   eq, t
>      moveq   r1, #0
>      RETc(eq)
> -    do_push {r4, r5, lr}
> +
> +    do_push {r4, r5, lr}        @ sp -= 12
> +    .cfi_adjust_cfa_offset 12   @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0       @ Registers are saved from sp + 0 to sp + 8.
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
> +
>      mov r4, #0x400      @ initial exponent
>      add r4, r4, #(52-1 - 1)
>      mov r5, #0          @ sign bit is 0
> @@ -435,17 +459,25 @@ ARM_FUNC_ALIAS aeabi_ui2d floatunsidf
>      mov xh, #0
>      b   LSYM(Lad_l)
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_ui2d
>      FUNC_END floatunsidf
>
>  ARM_FUNC_START floatsidf
>  ARM_FUNC_ALIAS aeabi_i2d floatsidf
> +    CFI_START_FUNCTION
>
>      teq r0, #0
>      do_it   eq, t
>      moveq   r1, #0
>      RETc(eq)
> -    do_push {r4, r5, lr}
> +
> +    do_push {r4, r5, lr}        @ sp -= 12
> +    .cfi_adjust_cfa_offset 12   @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0       @ Registers are saved from sp + 0 to sp + 8.
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
> +
>      mov r4, #0x400      @ initial exponent
>      add r4, r4, #(52-1 - 1)
>      ands    r5, r0, #0x80000000 @ sign bit in r5
> @@ -457,11 +489,13 @@ ARM_FUNC_ALIAS aeabi_i2d floatsidf
>      mov xh, #0
>      b   LSYM(Lad_l)
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_i2d
>      FUNC_END floatsidf
>
>  ARM_FUNC_START extendsfdf2
>  ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
> +    CFI_START_FUNCTION
>
>      movs    r2, r0, lsl #1      @ toss sign bit
>      mov xh, r2, asr #3      @ stretch exponent
> @@ -480,34 +514,54 @@ ARM_FUNC_ALIAS aeabi_f2d extendsfdf2
>
>      @ value was denormalized.  We can normalize it now.
>      do_push {r4, r5, lr}
> +    .cfi_adjust_cfa_offset 12   @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0       @ Registers are saved from sp + 0 to sp + 8.
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
> +
>      mov r4, #0x380      @ setup corresponding exponent
>      and r5, xh, #0x80000000 @ move sign bit in r5
>      bic xh, xh, #0x80000000
>      b   LSYM(Lad_l)
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_f2d
>      FUNC_END extendsfdf2
>
>  ARM_FUNC_START floatundidf
>  ARM_FUNC_ALIAS aeabi_ul2d floatundidf
> +    CFI_START_FUNCTION
> +    .cfi_remember_state        @ Save the current CFA state.
>
>      orrs    r2, r0, r1
>      do_it   eq
>      RETc(eq)
>
> -    do_push {r4, r5, lr}
> +    do_push {r4, r5, lr}       @ sp -= 12
> +    .cfi_adjust_cfa_offset 12  @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0      @ Registers are saved from sp + 0 to sp + 8
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
>
>      mov r5, #0
>      b   2f
>
>  ARM_FUNC_START floatdidf
>  ARM_FUNC_ALIAS aeabi_l2d floatdidf
> +    .cfi_restore_state
> +    @ Restore the CFI state we saved above. If we didn't do this then the
> +    @ following instructions would have the CFI state that was set by the
> +    @ offset adjustments made in floatundidf.
>
>      orrs    r2, r0, r1
>      do_it   eq
>      RETc(eq)
>
> -    do_push {r4, r5, lr}
> +    do_push {r4, r5, lr}       @ sp -= 12
> +    .cfi_adjust_cfa_offset 12  @ CFA is now sp + previousOffset + 12
> +    .cfi_rel_offset r4, 0      @ Registers are saved from sp to sp + 8
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset lr, 8
>
>      ands    r5, ah, #0x80000000 @ sign bit in r5
>      bpl 2f
> @@ -550,6 +604,7 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
>      add r4, r4, r2
>      b   LSYM(Lad_p)
>
> +    CFI_END_FUNCTION
>      FUNC_END floatdidf
>      FUNC_END aeabi_l2d
>      FUNC_END floatundidf
> @@ -561,7 +616,14 @@ ARM_FUNC_ALIAS aeabi_l2d floatdidf
>
>  ARM_FUNC_START muldf3
>  ARM_FUNC_ALIAS aeabi_dmul muldf3
> -    do_push {r4, r5, r6, lr}
> +    CFI_START_FUNCTION
> +
> +    do_push {r4, r5, r6, lr}    @ sp -= 16
> +    .cfi_adjust_cfa_offset 16   @ CFA is now sp + previousOffset + 16
> +    .cfi_rel_offset r4, 0       @ Registers are saved from sp to sp + 12.
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset r6, 8
> +    .cfi_rel_offset lr, 12
>
>      @ Mask out exponents, trap any zero/denormal/INF/NAN.
>      mov ip, #0xff
> @@ -596,7 +658,16 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
>      and   r6, r6, #0x80000000
>
>      @ Well, no way to make it shorter without the umull instruction.
> -    stmfd   sp!, {r6, r7, r8, r9, sl, fp}
> +    stmfd   sp!, {r6, r7, r8, r9, sl, fp}   @ sp -= 24
> +    .cfi_remember_state         @ Save the current CFI state.
> +    .cfi_adjust_cfa_offset 24   @ CFA is now sp + previousOffset + 24.
> +    .cfi_rel_offset r6, 0       @ Registers are saved from sp to sp + 20.
> +    .cfi_rel_offset r7, 4
> +    .cfi_rel_offset r8, 8
> +    .cfi_rel_offset r9, 12
> +    .cfi_rel_offset sl, 16
> +    .cfi_rel_offset fp, 20
> +
>      mov r7, xl, lsr #16
>      mov r8, yl, lsr #16
>      mov r9, xh, lsr #16
> @@ -648,8 +719,8 @@ ARM_FUNC_ALIAS aeabi_dmul muldf3
>      mul fp, xh, yh
>      adcs    r5, r5, fp
>      adc r6, r6, #0
> -    ldmfd   sp!, {yl, r7, r8, r9, sl, fp}
> -
> +    ldmfd   sp!, {yl, r7, r8, r9, sl, fp}   @ sp += 24
> +    .cfi_restore_state   @ Restore the previous CFI state.
>  #else
>
>      @ Here is the actual multiplication.
> @@ -715,7 +786,6 @@ LSYM(Lml_1):
>      orr xh, xh, #0x00100000
>      mov lr, #0
>      subs    r4, r4, #1
> -
>  LSYM(Lml_u):
>      @ Overflow?
>      bgt LSYM(Lml_o)
> @@ -863,13 +933,20 @@ LSYM(Lml_n):
>      orr xh, xh, #0x00f80000
>      RETLDM  "r4, r5, r6"
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dmul
>      FUNC_END muldf3
>
>  ARM_FUNC_START divdf3
>  ARM_FUNC_ALIAS aeabi_ddiv divdf3
> +    CFI_START_FUNCTION
>
>      do_push {r4, r5, r6, lr}
> +    .cfi_adjust_cfa_offset 16
> +    .cfi_rel_offset r4, 0
> +    .cfi_rel_offset r5, 4
> +    .cfi_rel_offset r6, 8
> +    .cfi_rel_offset lr, 12
>
>      @ Mask out exponents, trap any zero/denormal/INF/NAN.
>      mov ip, #0xff
> @@ -1052,6 +1129,7 @@ LSYM(Ldv_s):
>      bne LSYM(Lml_z)     @ 0 / <non_zero> -> 0
>      b   LSYM(Lml_n)     @ 0 / 0 -> NAN
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_ddiv
>      FUNC_END divdf3
>
> @@ -1063,6 +1141,7 @@ LSYM(Ldv_s):
>
>  ARM_FUNC_START gtdf2
>  ARM_FUNC_ALIAS gedf2 gtdf2
> +    CFI_START_FUNCTION
>      mov ip, #-1
>      b   1f
>
> @@ -1077,6 +1156,10 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
>      mov ip, #1          @ how should we specify unordered here?
>
>  1:  str ip, [sp, #-4]!
> +    .cfi_adjust_cfa_offset 4        @ CFA is now sp + previousOffset + 4.
> +    @ We're not adding CFI for ip as it's pushed into the stack only because
> +    @ it may be popped off later as a return value (i.e. we're not preserving
> +    @ it anyways).
>
>      @ Trap any INF/NAN first.
>      mov ip, xh, lsl #1
> @@ -1085,10 +1168,18 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
>      do_it   ne
>      COND(mvn,s,ne)  ip, ip, asr #21
>      beq 3f
> +    .cfi_remember_state
> +    @ Save the current CFI state. This is done because the branch is 
> conditional,
> +    @ and if we don't take it we'll issue a .cfi_adjust_cfa_offset and 
> return.
> +    @ If we do take it, however, the .cfi_adjust_cfa_offset from the 
> non-branch
> +    @ code will affect the branch code as well. To avoid this we'll restore
> +    @ the current state before executing the branch code.
>
>      @ Test for equality.
>      @ Note that 0.0 is equal to -0.0.
>  2:  add sp, sp, #4
> +    .cfi_adjust_cfa_offset -4       @ CFA is now sp + previousOffset.
> +
>      orrs    ip, xl, xh, lsl #1  @ if x == 0.0 or -0.0
>      do_it   eq, e
>      COND(orr,s,eq)  ip, yl, yh, lsl #1  @ and y == 0.0 or -0.0
> @@ -1117,8 +1208,13 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
>      orr r0, r0, #1
>      RET
>
> -    @ Look for a NAN.
> -3:  mov ip, xh, lsl #1
> +3:  @ Look for a NAN.
> +
> +    @ Restore the previous CFI state (i.e. keep the CFI state as it was
> +    @ before the branch).
> +    .cfi_restore_state
> +
> +    mov ip, xh, lsl #1
>      mvns    ip, ip, asr #21
>      bne 4f
>      orrs    ip, xl, xh, lsl #12
> @@ -1128,9 +1224,13 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
>      bne 2b
>      orrs    ip, yl, yh, lsl #12
>      beq 2b          @ y is not NAN
> +
>  5:  ldr r0, [sp], #4        @ unordered return code
> +    .cfi_adjust_cfa_offset -4       @ CFA is now sp + previousOffset.
> +
>      RET
>
> +    CFI_END_FUNCTION
>      FUNC_END gedf2
>      FUNC_END gtdf2
>      FUNC_END ledf2
> @@ -1140,6 +1240,7 @@ ARM_FUNC_ALIAS eqdf2 cmpdf2
>      FUNC_END cmpdf2
>
>  ARM_FUNC_START aeabi_cdrcmple
> +    CFI_START_FUNCTION
>
>      mov ip, r0
>      mov r0, r2
> @@ -1149,12 +1250,16 @@ ARM_FUNC_START aeabi_cdrcmple
>      mov r3, ip
>      b   6f
>
> -ARM_FUNC_START aeabi_cdcmpeq
> +; ARM_FUNC_START aeabi_cdcmpeq
>  ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
>
>      @ The status-returning routines are required to preserve all
>      @ registers except ip, lr, and cpsr.
>  6:  do_push {r0, lr}
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8.
> +    .cfi_rel_offset r0, 0     @ Previous r0 is saved at sp.
> +    .cfi_rel_offset lr, 4     @ Previous lr is saved at sp + 4.
> +
>      ARM_CALL cmpdf2
>      @ Set the Z flag correctly, and the C flag unconditionally.
>      cmp r0, #0
> @@ -1162,59 +1267,86 @@ ARM_FUNC_ALIAS aeabi_cdcmple aeabi_cdcmpeq
>      @ that the first operand was smaller than the second.
>      do_it   mi
>      cmnmi   r0, #0
> +
>      RETLDM  "r0"
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_cdcmple
>      FUNC_END aeabi_cdcmpeq
>      FUNC_END aeabi_cdrcmple
>
>  ARM_FUNC_START  aeabi_dcmpeq
> +    CFI_START_FUNCTION
> +
> +    str lr, [sp, #-8]!        @ sp -= 8
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +    .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>      ARM_CALL aeabi_cdcmple
>      do_it   eq, e
>      moveq   r0, #1  @ Equal to.
>      movne   r0, #0  @ Less than, greater than, or unordered.
> +
>      RETLDM
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dcmpeq
>
>  ARM_FUNC_START  aeabi_dcmplt
> +    CFI_START_FUNCTION
> +
> +    str lr, [sp, #-8]!        @ sp -= 8
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +    .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>      ARM_CALL aeabi_cdcmple
>      do_it   cc, e
>      movcc   r0, #1  @ Less than.
>      movcs   r0, #0  @ Equal to, greater than, or unordered.
>      RETLDM
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dcmplt
>
>  ARM_FUNC_START  aeabi_dcmple
> +    CFI_START_FUNCTION
> +
> +    str lr, [sp, #-8]!        @ sp -= 8
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +    .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>      ARM_CALL aeabi_cdcmple
>      do_it   ls, e
>      movls   r0, #1  @ Less than or equal to.
>      movhi   r0, #0  @ Greater than or unordered.
>      RETLDM
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dcmple
>
>  ARM_FUNC_START  aeabi_dcmpge
> +    CFI_START_FUNCTION
> +
> +    str lr, [sp, #-8]!        @ sp -= 8
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +    .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>      ARM_CALL aeabi_cdrcmple
>      do_it   ls, e
>      movls   r0, #1  @ Operand 2 is less than or equal to operand 1.
>      movhi   r0, #0  @ Operand 2 greater than operand 1, or unordered.
>      RETLDM
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dcmpge
>
>  ARM_FUNC_START  aeabi_dcmpgt
> +    CFI_START_FUNCTION
> +
> +    str lr, [sp, #-8]!        @ sp -= 8
> +    .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +    .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>      ARM_CALL aeabi_cdrcmple
>      do_it   cc, e
>      movcc   r0, #1  @ Operand 2 is less than operand 1.
> @@ -1222,6 +1354,7 @@ ARM_FUNC_START  aeabi_dcmpgt
>              @ or they are unordered.
>      RETLDM
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_dcmpgt
>
>  #endif /* L_cmpdf2 */
> @@ -1230,6 +1363,7 @@ ARM_FUNC_START  aeabi_dcmpgt
>
>  ARM_FUNC_START unorddf2
>  ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
> +    .cfi_startproc
>
>      mov ip, xh, lsl #1
>      mvns    ip, ip, asr #21
> @@ -1247,6 +1381,7 @@ ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
>  3:  mov r0, #1          @ arguments are unordered.
>      RET
>
> +    .cfi_endproc
>      FUNC_END aeabi_dcmpun
>      FUNC_END unorddf2
>
> @@ -1256,6 +1391,7 @@ ARM_FUNC_ALIAS aeabi_dcmpun unorddf2
>
>  ARM_FUNC_START fixdfsi
>  ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
> +    CFI_START_FUNCTION
>
>      @ check exponent range.
>      mov r2, xh, lsl #1
> @@ -1289,6 +1425,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
>  4:  mov r0, #0          @ How should we convert NAN?
>      RET
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_d2iz
>      FUNC_END fixdfsi
>
> @@ -1298,6 +1435,7 @@ ARM_FUNC_ALIAS aeabi_d2iz fixdfsi
>
>  ARM_FUNC_START fixunsdfsi
>  ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
> +    CFI_START_FUNCTION
>
>      @ check exponent range.
>      movs    r2, xh, lsl #1
> @@ -1327,6 +1465,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
>  4:  mov r0, #0          @ How should we convert NAN?
>      RET
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_d2uiz
>      FUNC_END fixunsdfsi
>
> @@ -1336,6 +1475,7 @@ ARM_FUNC_ALIAS aeabi_d2uiz fixunsdfsi
>
>  ARM_FUNC_START truncdfsf2
>  ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
> +    CFI_START_FUNCTION
>
>      @ check exponent range.
>      mov r2, xh, lsl #1
> @@ -1400,6 +1540,7 @@ ARM_FUNC_ALIAS aeabi_d2f truncdfsf2
>      orr r0, r0, #0x00800000
>      RET
>
> +    CFI_END_FUNCTION
>      FUNC_END aeabi_d2f
>      FUNC_END truncdfsf2
>
> diff --git a/libgcc/config/arm/ieee754-sf.S b/libgcc/config/arm/ieee754-sf.S
> index 3e76241..a93d40a 100644
> --- a/libgcc/config/arm/ieee754-sf.S
> +++ b/libgcc/config/arm/ieee754-sf.S
> @@ -31,16 +31,21 @@
>   * Only the default rounding mode is intended for best performances.
>   * Exceptions aren't supported yet, but that can be added quite easily
>   * if necessary without impacting performances.
> + *
> + * In the CFI related comments, 'previousOffset' refers to the previous 
> offset
> + * from sp used to compute the CFA.
>   */
>
>  #ifdef L_arm_negsf2
>
>  ARM_FUNC_START negsf2
>  ARM_FUNC_ALIAS aeabi_fneg negsf2
> +       CFI_START_FUNCTION
>
>         eor     r0, r0, #0x80000000     @ flip sign bit
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fneg
>         FUNC_END negsf2
>
> @@ -49,6 +54,7 @@ ARM_FUNC_ALIAS aeabi_fneg negsf2
>  #ifdef L_arm_addsubsf3
>
>  ARM_FUNC_START aeabi_frsub
> +       CFI_START_FUNCTION
>
>         eor     r0, r0, #0x80000000     @ flip sign bit of first arg
>         b       1f
> @@ -284,6 +290,7 @@ LSYM(Lad_i):
>         orrne   r0, r0, #0x00400000     @ quiet NAN
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_frsub
>         FUNC_END aeabi_fadd
>         FUNC_END addsf3
> @@ -292,6 +299,7 @@ LSYM(Lad_i):
>
>  ARM_FUNC_START floatunsisf
>  ARM_FUNC_ALIAS aeabi_ui2f floatunsisf
> +       CFI_START_FUNCTION
>
>         mov     r3, #0
>         b       1f
> @@ -316,6 +324,7 @@ ARM_FUNC_ALIAS aeabi_i2f floatsisf
>         mov     al, #0
>         b       2f
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_i2f
>         FUNC_END floatsisf
>         FUNC_END aeabi_ui2f
> @@ -323,6 +332,7 @@ ARM_FUNC_ALIAS aeabi_i2f floatsisf
>
>  ARM_FUNC_START floatundisf
>  ARM_FUNC_ALIAS aeabi_ul2f floatundisf
> +       CFI_START_FUNCTION
>
>         orrs    r2, r0, r1
>         do_it   eq
> @@ -409,6 +419,7 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
>         biceq   r0, r0, ip, lsr #31
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END floatdisf
>         FUNC_END aeabi_l2f
>         FUNC_END floatundisf
> @@ -420,6 +431,7 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf
>
>  ARM_FUNC_START mulsf3
>  ARM_FUNC_ALIAS aeabi_fmul mulsf3
> +       CFI_START_FUNCTION
>
>         @ Mask out exponents, trap any zero/denormal/INF/NAN.
>         mov     ip, #0xff
> @@ -454,7 +466,13 @@ LSYM(Lml_x):
>         and     r3, ip, #0x80000000
>
>         @ Well, no way to make it shorter without the umull instruction.
> -    do_push {r3, r4, r5}
> +       do_push {r3, r4, r5}       @ sp -= 12
> +       .cfi_remember_state        @ Save the current CFI state
> +       .cfi_adjust_cfa_offset 12  @ CFA is now sp + previousOffset + 12
> +       .cfi_rel_offset r3, 0      @ Registers are saved from sp to sp + 8
> +       .cfi_rel_offset r4, 4
> +       .cfi_rel_offset r5, 8
> +
>         mov     r4, r0, lsr #16
>         mov     r5, r1, lsr #16
>         bic     r0, r0, r4, lsl #16
> @@ -465,7 +483,8 @@ LSYM(Lml_x):
>         mla     r0, r4, r1, r0
>         adds    r3, r3, r0, lsl #16
>         adc     r1, ip, r0, lsr #16
> -    do_pop  {r0, r4, r5}
> +       do_pop  {r0, r4, r5}       @ sp += 12
> +       .cfi_restore_state         @ Restore the previous CFI state
>
>  #else
>
> @@ -618,11 +637,13 @@ LSYM(Lml_n):
>         orr     r0, r0, #0x00c00000
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fmul
>         FUNC_END mulsf3
>
>  ARM_FUNC_START divsf3
>  ARM_FUNC_ALIAS aeabi_fdiv divsf3
> +       CFI_START_FUNCTION
>
>         @ Mask out exponents, trap any zero/denormal/INF/NAN.
>         mov     ip, #0xff
> @@ -758,6 +779,7 @@ LSYM(Ldv_s):
>         bne     LSYM(Lml_z)             @ 0 / <non_zero> -> 0
>         b       LSYM(Lml_n)             @ 0 / 0 -> NAN
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fdiv
>         FUNC_END divsf3
>
> @@ -782,6 +804,7 @@ LSYM(Ldv_s):
>
>  ARM_FUNC_START gtsf2
>  ARM_FUNC_ALIAS gesf2 gtsf2
> +       CFI_START_FUNCTION
>         mov     ip, #-1
>         b       1f
>
> @@ -796,6 +819,10 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
>         mov     ip, #1                  @ how should we specify unordered 
> here?
>
>  1:     str     ip, [sp, #-4]!
> +       .cfi_adjust_cfa_offset 4  @ CFA is now sp + previousOffset + 4.
> +       @ We're not adding CFI for ip as it's pushed into the stack only 
> because
> +       @ it may be popped off later as a return value (i.e. we're not 
> preserving
> +       @ it anyways).
>
>         @ Trap any INF/NAN first.
>         mov     r2, r0, lsl #1
> @@ -804,10 +831,18 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
>         do_it   ne
>         COND(mvn,s,ne)  ip, r3, asr #24
>         beq     3f
> +       .cfi_remember_state
> +       @ Save the current CFI state. This is done because the branch is 
> conditional,
> +       @ and if we don't take it we'll issue a .cfi_adjust_cfa_offset and 
> return.
> +       @ If we do take it, however, the .cfi_adjust_cfa_offset from the 
> non-branch
> +       @ code will affect the branch code as well. To avoid this we'll 
> restore
> +       @ the current state before executing the branch code.
>
>         @ Compare values.
>         @ Note that 0.0 is equal to -0.0.
>  2:     add     sp, sp, #4
> +       .cfi_adjust_cfa_offset -4       @ CFA is now sp + previousOffset.
> +
>         orrs    ip, r2, r3, lsr #1      @ test if both are 0, clear C flag
>         do_it   ne
>         teqne   r0, r1                  @ if not 0 compare sign
> @@ -823,8 +858,13 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
>         orrne   r0, r0, #1
>         RET
>
> -    @ Look for a NAN.
> -3:  mvns    ip, r2, asr #24
> +3:     @ Look for a NAN.
> +
> +       @ Restore the previous CFI state (i.e. keep the CFI state as it was
> +       @ before the branch).
> +       .cfi_restore_state
> +
> +       mvns    ip, r2, asr #24
>         bne     4f
>         movs    ip, r0, lsl #9
>         bne     5f                      @ r0 is NAN
> @@ -832,9 +872,12 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
>         bne     2b
>         movs    ip, r1, lsl #9
>         beq     2b                      @ r1 is not NAN
> +
>  5:     ldr     r0, [sp], #4            @ return unordered code.
> +       .cfi_adjust_cfa_offset -4       @ CFA is now sp + previousOffset.
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END gesf2
>         FUNC_END gtsf2
>         FUNC_END lesf2
> @@ -844,6 +887,7 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2
>         FUNC_END cmpsf2
>
>  ARM_FUNC_START aeabi_cfrcmple
> +       CFI_START_FUNCTION
>
>         mov     ip, r0
>         mov     r0, r1
> @@ -856,6 +900,13 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
>         @ The status-returning routines are required to preserve all
>         @ registers except ip, lr, and cpsr.
>  6:     do_push {r0, r1, r2, r3, lr}
> +       .cfi_adjust_cfa_offset 20  @ CFA is at sp + previousOffset + 20
> +       .cfi_rel_offset r0, 0      @ Registers are saved from sp to sp + 16
> +       .cfi_rel_offset r1, 4
> +       .cfi_rel_offset r2, 8
> +       .cfi_rel_offset r3, 12
> +       .cfi_rel_offset lr, 16
> +
>         ARM_CALL cmpsf2
>         @ Set the Z flag correctly, and the C flag unconditionally.
>         cmp     r0, #0
> @@ -865,57 +916,82 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq
>         cmnmi   r0, #0
>         RETLDM  "r0, r1, r2, r3"
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_cfcmple
>         FUNC_END aeabi_cfcmpeq
>         FUNC_END aeabi_cfrcmple
>
>  ARM_FUNC_START aeabi_fcmpeq
> +       CFI_START_FUNCTION
> +
> +       str     lr, [sp, #-8]!    @ sp -= 8
> +       .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +       .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>         ARM_CALL aeabi_cfcmple
>         do_it   eq, e
>         moveq   r0, #1  @ Equal to.
>         movne   r0, #0  @ Less than, greater than, or unordered.
>         RETLDM
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmpeq
>
>  ARM_FUNC_START aeabi_fcmplt
> +       CFI_START_FUNCTION
> +
> +       str     lr, [sp, #-8]!    @ sp -= 8
> +       .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +       .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>         ARM_CALL aeabi_cfcmple
>         do_it   cc, e
>         movcc   r0, #1  @ Less than.
>         movcs   r0, #0  @ Equal to, greater than, or unordered.
>         RETLDM
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmplt
>
>  ARM_FUNC_START aeabi_fcmple
> +       CFI_START_FUNCTION
> +
> +       str     lr, [sp, #-8]!    @ sp -= 8
> +       .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +       .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>         ARM_CALL aeabi_cfcmple
>         do_it   ls, e
>         movls   r0, #1  @ Less than or equal to.
>         movhi   r0, #0  @ Greater than or unordered.
>         RETLDM
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmple
>
>  ARM_FUNC_START aeabi_fcmpge
> +       CFI_START_FUNCTION
> +
> +       str     lr, [sp, #-8]!    @ sp -= 8
> +       .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +       .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>         ARM_CALL aeabi_cfrcmple
>         do_it   ls, e
>         movls   r0, #1  @ Operand 2 is less than or equal to operand 1.
>         movhi   r0, #0  @ Operand 2 greater than operand 1, or unordered.
>         RETLDM
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmpge
>
>  ARM_FUNC_START aeabi_fcmpgt
> +       CFI_START_FUNCTION
> +
> +       str     lr, [sp, #-8]!    @ sp -= 8
> +       .cfi_adjust_cfa_offset 8  @ CFA is now sp + previousOffset + 8
> +       .cfi_rel_offset lr, 0     @ lr is at sp
>
> -    str lr, [sp, #-8]!
>         ARM_CALL aeabi_cfrcmple
>         do_it   cc, e
>         movcc   r0, #1  @ Operand 2 is less than operand 1.
> @@ -923,6 +999,7 @@ ARM_FUNC_START  aeabi_fcmpgt
>                         @ or they are unordered.
>         RETLDM
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmpgt
>
>  #endif /* L_cmpsf2 */
> @@ -931,6 +1008,7 @@ ARM_FUNC_START  aeabi_fcmpgt
>
>  ARM_FUNC_START unordsf2
>  ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
> +       CFI_START_FUNCTION
>
>         mov     r2, r0, lsl #1
>         mov     r3, r1, lsl #1
> @@ -947,6 +1025,7 @@ ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
>  3:     mov     r0, #1                  @ arguments are unordered.
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_fcmpun
>         FUNC_END unordsf2
>
> @@ -956,6 +1035,7 @@ ARM_FUNC_ALIAS aeabi_fcmpun unordsf2
>
>  ARM_FUNC_START fixsfsi
>  ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
> +       CFI_START_FUNCTION
>
>         @ check exponent range.
>         mov     r2, r0, lsl #1
> @@ -989,6 +1069,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
>  4:     mov     r0, #0                  @ What should we convert NAN to?
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_f2iz
>         FUNC_END fixsfsi
>
> @@ -998,6 +1079,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi
>
>  ARM_FUNC_START fixunssfsi
>  ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
> +       CFI_START_FUNCTION
>
>         @ check exponent range.
>         movs    r2, r0, lsl #1
> @@ -1027,6 +1109,7 @@ ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi
>  4:     mov     r0, #0                  @ What should we convert NAN to?
>         RET
>
> +       CFI_END_FUNCTION
>         FUNC_END aeabi_f2uiz
>         FUNC_END fixunssfsi
>
> diff --git a/libgcc/config/arm/lib1funcs.S b/libgcc/config/arm/lib1funcs.S
> index d2d0d20..4b63924 100644
> --- a/libgcc/config/arm/lib1funcs.S
> +++ b/libgcc/config/arm/lib1funcs.S
> @@ -1965,6 +1965,16 @@ LSYM(Lchange_\register):
>
>  #endif /* Arch supports thumb.  */
>
> +.macro CFI_START_FUNCTION
> +    .cfi_startproc
> +    .cfi_remember_state
> +.endm
> +
> +.macro CFI_END_FUNCTION
> +    .cfi_restore_state
> +    .cfi_endproc
> +.endm
> +
>  #ifndef __symbian__
>  #ifndef __ARM_ARCH_6M__
>  #include "ieee754-df.S"

Reply via email to