From patchwork Tue May 12 13:01:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Galvan X-Patchwork-Id: 471333 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id AC29A140D23 for ; Tue, 12 May 2015 23:03:05 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=G8Zg4dW6; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; q=dns; s=default; b=ftNEhej5LiqCZ94 up/b9FB7pptFHMA1iRbTAQYB2ltC4Jg2ySm30HhmIekLHnxdJMwjmD8GAJ09zTOt 4x9zQVqJyGZ1NUIAGSgYq9BCHjbYuvy4yLWfshTOu1Y1LBHooGqhydiZvHNdz64+ EM3fwXpRxBMlWO+JV2llKA2UxqMo= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; s=default; bh=QAW09RYWqM8Gr7BrABQGI jnNZ6E=; b=G8Zg4dW6fI5rJh2VROSmqmzuO7z5JPpc3jnpjtZQZhsfWPHdh1QPk MFa9cyKWbHHUnmf3Gfv8/esbvmeRISIttpNElP+XZWl3DENdC+p8JT0IyrALk+/1 1ondWn1osB8qF5EQTwRA9z0h7zxhW7Nd8UPOQvYdjgIKfOTvUWVXNI= Received: (qmail 78109 invoked by alias); 12 May 2015 13:02:57 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 78095 invoked by uid 89); 12 May 2015 13:02:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-lb0-f181.google.com Received: from mail-lb0-f181.google.com (HELO mail-lb0-f181.google.com) (209.85.217.181) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Tue, 12 May 2015 13:02:53 +0000 Received: by lbbqq2 with SMTP id qq2so5153475lbb.3 for ; Tue, 12 May 2015 06:02:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=BhrH4DckuyIWQQdn+5yhfvCHcSo5UnwegXwzUKiHVik=; b=N1h564sRj1KsIbMymwG9UsXRvqCiC4qntAzD7VZdf/XBSdtrVnLquNgXPAombpcD2F o8/2snlPPyolXkc340i73ypui7SGe9EIFKlCMnRJ2e+5TflTLiBl/ZMMzu5dRTn/ybdC ZtsZ5IRKbda4OzzgZRMeaVszkVGOY4NaQuW0ivtIMvCPon/bb8Z9jMyawADAd28Z+Ux/ 131XBK7c/0qC7PmxuKk002oScgtD6lK/QbRan27deVEuSrVR6CazLKNIAEW5eItt2iAs qdMM56UBe8Sv+97h3vZ3T0VIO9L4+Tx5utCrXXdp22KsFe6QRCp8ZybVHE4Cw3PI38kE J/pw== X-Gm-Message-State: ALoCoQlXl1curGf4CUPTUOOvVvT1k8eAupKpSVqlxdx4WqbmGLi2lfAWE1k/gzxieN6oMAP2vNCc X-Received: by 10.152.37.65 with SMTP id w1mr11823450laj.111.1431435760555; Tue, 12 May 2015 06:02:40 -0700 (PDT) MIME-Version: 1.0 Received: by 10.112.52.71 with HTTP; Tue, 12 May 2015 06:01:58 -0700 (PDT) In-Reply-To: <5551BEA3.3040109@arm.com> References: <1431373465-14294-1-git-send-email-martin.galvan@tallertechnologies.com> <5551BEA3.3040109@arm.com> From: Martin Galvan Date: Tue, 12 May 2015 10:01:58 -0300 Message-ID: Subject: Re: Fwd: [PING 2][PATCH] libgcc: Add CFI directives to the soft floating point support code for ARM To: Ramana Radhakrishnan Cc: "gcc-patches@gcc.gnu.org" On Tue, May 12, 2015 at 5:49 AM, Ramana Radhakrishnan wrote: > That's what I mean when I say email clients "munged it" : email clients and > / or some popular email servers appear to end up munging white spaces and > patches don't apply cleanly. > > So, no it doesn't work - once you've sent it through your email client / > server. I am unable to apply the patch as it stands today either taking the > raw text from the gcc-patches archive or from your email message in my > inbox. It's not like line endings and things have been munged but every > whitespace / tab is in trouble here. > > Please send it back as an attachment if you want me to apply it. Oh, I see! Sorry for that, I thought the problem was on my side. Here's the patch, it's the cfi.patch file. 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 / -> 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..31f93a2 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 / -> 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"