linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64.
@ 2015-05-12  6:33 Chen Gang
  2015-05-12 10:00 ` Russell King - ARM Linux
  0 siblings, 1 reply; 5+ messages in thread
From: Chen Gang @ 2015-05-12  6:33 UTC (permalink / raw)
  To: linux-arm-kernel

R0 is corrupted after calling __do_div64 and compiler is not informed
about this in macro __do_div_asm. If n is to be used again after this
macro, r0 is not reloaded and n will contain incorrect value

Signed-off-by: Chen Gang <gangchen@rdamicro.com>
---
 arch/arm/include/asm/div64.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
index a66061a..93a9985 100644
--- a/arch/arm/include/asm/div64.h
+++ b/arch/arm/include/asm/div64.h
@@ -34,13 +34,13 @@
 	register unsigned long long __n   asm("r0") = n;	\
 	register unsigned long long __res asm("r2");		\
 	register unsigned int __rem       asm(__xh);		\
-	asm(	__asmeq("%0", __xh)				\
+	asm(	__asmeq("%R0", __xh)				\
 		__asmeq("%1", "r2")				\
 		__asmeq("%2", "r0")				\
 		__asmeq("%3", "r4")				\
 		"bl	__do_div64"				\
-		: "=r" (__rem), "=r" (__res)			\
-		: "r" (__n), "r" (__base)			\
+		: "=r" (__n), "=r" (__res)			\
+		: "0"(__n), "r" (__base)			\
 		: "ip", "lr", "cc");				\
 	n = __res;						\
 	__rem;							\
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64.
  2015-05-12  6:33 [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64 Chen Gang
@ 2015-05-12 10:00 ` Russell King - ARM Linux
  2015-05-12 10:40   ` Chen Gang
  2015-05-12 10:42   ` Chen Gang
  0 siblings, 2 replies; 5+ messages in thread
From: Russell King - ARM Linux @ 2015-05-12 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 12, 2015 at 02:33:06PM +0800, Chen Gang wrote:
> R0 is corrupted after calling __do_div64 and compiler is not informed
> about this in macro __do_div_asm. If n is to be used again after this
> macro, r0 is not reloaded and n will contain incorrect value

This isn't going to work if we're building for big endian (__ARMEB__
set) because then we end up telling the compiler that __rem and __n
are both in r0, which is impossible.

> diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
> index a66061a..93a9985 100644
> --- a/arch/arm/include/asm/div64.h
> +++ b/arch/arm/include/asm/div64.h
> @@ -34,13 +34,13 @@
>  	register unsigned long long __n   asm("r0") = n;	\
>  	register unsigned long long __res asm("r2");		\
>  	register unsigned int __rem       asm(__xh);		\

	register unsigned int __rem_xh    asm(__xh);            \
	register unsigned int __rem_xl    asm(__xl);		\

> -	asm(	__asmeq("%0", __xh)				\
> +	asm(	__asmeq("%R0", __xh)				\

	asm(	__asmeq("%0", __xh)				\
		__asmeq("%1", __xl)				\

... and increment each following register %-spec by one...

>  		__asmeq("%1", "r2")				\
>  		__asmeq("%2", "r0")				\
>  		__asmeq("%3", "r4")				\
>  		"bl	__do_div64"				\
> -		: "=r" (__rem), "=r" (__res)			\
> -		: "r" (__n), "r" (__base)			\
> +		: "=r" (__n), "=r" (__res)			\
> +		: "0"(__n), "r" (__base)			\

This is obviously wrong because __rem is left unset, and that's one of
the two values this macro returns.

		: "=r" (__rem_xh), "=r" (__rem_xl), "=r" (__res) \
		: "r" (__n), "r" (__base)			\

>  		: "ip", "lr", "cc");				\
>  	n = __res;						\
>  	__rem;							\

	__rem_xh;

Basically this renames __rem to __rem_xh, and introduces a new __rem_xl
to take the other half of the remainder which we don't use.

-- 
FTTC broadband for 0.8mile line: currently at 10.5Mbps down 400kbps up
according to speedtest.net.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64.
  2015-05-12 10:00 ` Russell King - ARM Linux
@ 2015-05-12 10:40   ` Chen Gang
  2015-05-14  3:39     ` Chen Gang
  2015-05-12 10:42   ` Chen Gang
  1 sibling, 1 reply; 5+ messages in thread
From: Chen Gang @ 2015-05-12 10:40 UTC (permalink / raw)
  To: linux-arm-kernel

R0 is corrupted after calling __do_div64 and compiler is not informed
about this in macro __do_div_asm. If n is to be used again after this
macro, r0 is not reloaded and n will contain incorrect value

Signed-off-by: Chen Gang <gangchen@rdamicro.com>
---
 arch/arm/include/asm/div64.h | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
index a66061a..4829618 100644
--- a/arch/arm/include/asm/div64.h
+++ b/arch/arm/include/asm/div64.h
@@ -34,13 +34,15 @@
 	register unsigned long long __n   asm("r0") = n;	\
 	register unsigned long long __res asm("r2");		\
 	register unsigned int __rem       asm(__xh);		\
+	register unsigned int __clobber   asm(__xl);		\
 	asm(	__asmeq("%0", __xh)				\
-		__asmeq("%1", "r2")				\
-		__asmeq("%2", "r0")				\
-		__asmeq("%3", "r4")				\
+		__asmeq("%1", __xl)				\
+		__asmeq("%2", "r2")				\
+		__asmeq("%3", "r0")				\
+		__asmeq("%4", "r4")				\
 		"bl	__do_div64"				\
-		: "=r" (__rem), "=r" (__res)			\
-		: "r" (__n), "r" (__base)			\
+		: "=r"(__rem), "=r"(__clobber), "=r"(__res)	\
+		: "r"(__n), "r"(__base)				\
 		: "ip", "lr", "cc");				\
 	n = __res;						\
 	__rem;							\
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64.
  2015-05-12 10:00 ` Russell King - ARM Linux
  2015-05-12 10:40   ` Chen Gang
@ 2015-05-12 10:42   ` Chen Gang
  1 sibling, 0 replies; 5+ messages in thread
From: Chen Gang @ 2015-05-12 10:42 UTC (permalink / raw)
  To: linux-arm-kernel



On 05/12/2015 06:00 PM, Russell King - ARM Linux wrote:
> On Tue, May 12, 2015 at 02:33:06PM +0800, Chen Gang wrote:
>> R0 is corrupted after calling __do_div64 and compiler is not informed
>> about this in macro __do_div_asm. If n is to be used again after this
>> macro, r0 is not reloaded and n will contain incorrect value
> This isn't going to work if we're building for big endian (__ARMEB__
> set) because then we end up telling the compiler that __rem and __n
> are both in r0, which is impossible.
We tested your suggestion , it works and it feels better. I have
sent another patch based on your suggestions.
>
>> diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
>> index a66061a..93a9985 100644
>> --- a/arch/arm/include/asm/div64.h
>> +++ b/arch/arm/include/asm/div64.h
>> @@ -34,13 +34,13 @@
>>   	register unsigned long long __n   asm("r0") = n;	\
>>   	register unsigned long long __res asm("r2");		\
>>   	register unsigned int __rem       asm(__xh);		\
> 	register unsigned int __rem_xh    asm(__xh);            \
> 	register unsigned int __rem_xl    asm(__xl);		\
>
>> -	asm(	__asmeq("%0", __xh)				\
>> +	asm(	__asmeq("%R0", __xh)				\
> 	asm(	__asmeq("%0", __xh)				\
> 		__asmeq("%1", __xl)				\
>
> ... and increment each following register %-spec by one...
>
>>   		__asmeq("%1", "r2")				\
>>   		__asmeq("%2", "r0")				\
>>   		__asmeq("%3", "r4")				\
>>   		"bl	__do_div64"				\
>> -		: "=r" (__rem), "=r" (__res)			\
>> -		: "r" (__n), "r" (__base)			\
>> +		: "=r" (__n), "=r" (__res)			\
>> +		: "0"(__n), "r" (__base)			\
> This is obviously wrong because __rem is left unset, and that's one of
> the two values this macro returns.
>
> 		: "=r" (__rem_xh), "=r" (__rem_xl), "=r" (__res) \
> 		: "r" (__n), "r" (__base)			\
>
>>   		: "ip", "lr", "cc");				\
>>   	n = __res;						\
>>   	__rem;							\
> 	__rem_xh;
>
> Basically this renames __rem to __rem_xh, and introduces a new __rem_xl
> to take the other half of the remainder which we don't use.
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64.
  2015-05-12 10:40   ` Chen Gang
@ 2015-05-14  3:39     ` Chen Gang
  0 siblings, 0 replies; 5+ messages in thread
From: Chen Gang @ 2015-05-14  3:39 UTC (permalink / raw)
  To: linux-arm-kernel

Hi, Russell

The following patch is made according to your suggestion. Could you 
review or merge it before your context is cleaned? Thanks!

Br, Chen Gang

On 05/12/2015 06:40 PM, Chen Gang wrote:
> R0 is corrupted after calling __do_div64 and compiler is not informed
> about this in macro __do_div_asm. If n is to be used again after this
> macro, r0 is not reloaded and n will contain incorrect value
>
> Signed-off-by: Chen Gang <gangchen@rdamicro.com>
> ---
>   arch/arm/include/asm/div64.h | 12 +++++++-----
>   1 file changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
> index a66061a..4829618 100644
> --- a/arch/arm/include/asm/div64.h
> +++ b/arch/arm/include/asm/div64.h
> @@ -34,13 +34,15 @@
>   	register unsigned long long __n   asm("r0") = n;	\
>   	register unsigned long long __res asm("r2");		\
>   	register unsigned int __rem       asm(__xh);		\
> +	register unsigned int __clobber   asm(__xl);		\
>   	asm(	__asmeq("%0", __xh)				\
> -		__asmeq("%1", "r2")				\
> -		__asmeq("%2", "r0")				\
> -		__asmeq("%3", "r4")				\
> +		__asmeq("%1", __xl)				\
> +		__asmeq("%2", "r2")				\
> +		__asmeq("%3", "r0")				\
> +		__asmeq("%4", "r4")				\
>   		"bl	__do_div64"				\
> -		: "=r" (__rem), "=r" (__res)			\
> -		: "r" (__n), "r" (__base)			\
> +		: "=r"(__rem), "=r"(__clobber), "=r"(__res)	\
> +		: "r"(__n), "r"(__base)				\
>   		: "ip", "lr", "cc");				\
>   	n = __res;						\
>   	__rem;							\

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2015-05-14  3:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-12  6:33 [PATCH 1/1] ARM:r0 is also corrupted after calling __do_div64 Chen Gang
2015-05-12 10:00 ` Russell King - ARM Linux
2015-05-12 10:40   ` Chen Gang
2015-05-14  3:39     ` Chen Gang
2015-05-12 10:42   ` Chen Gang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).