* Fwd: about udelay in mips
[not found] ` <AANLkTim_swh58fCUxZ4e6MDrM9Lqrbm+1ufnp8W767JL@mail.gmail.com>
@ 2011-01-27 9:20 ` loody
2011-01-27 11:29 ` Sergei Shtylyov
0 siblings, 1 reply; 5+ messages in thread
From: loody @ 2011-01-27 9:20 UTC (permalink / raw)
To: gcc-help, Linux MIPS Mailing List
hi all:
I guess there seems be some differences about
"unsigned long long" and "ull" so I forward the letter to gcc-help.
If my guess is correct, what are the differences between them and why
"unsigned long long" cannot let compiler compile the 64-bits
operations as I want?
thanks a lot,
miloody
I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
below are the dis-assemblies:
(as you can see the v0 = v1 = zero.)
My version is 2.6.30.9:
void __udelay(unsigned long us)
{
unsigned int lpj = current_cpu_data.udelay_val;
__delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
80306ed0: 00001821 move v1,zero
80306ed4: 00601021 move v0,v1
#include <asm/compiler.h>
#include <asm/war.h>
inline void __delay(unsigned int loops)
{
__asm__ __volatile__ (
80306ed8: 1440ffff bnez v0,80306ed8 <__udelay+0x8>
80306edc: 2442ffff addiu v0,v0,-1
void __udelay(unsigned long us)
I have double checked the __delay source code of 2.6.33.4
and the dis-assemblies:
void __udelay(unsigned long us)
{
unsigned int lpj = current_cpu_data.udelay_val;
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
802f7310: 3c02804f lui v0,0x804f
802f7314: 8c429360 lw v0,-27808(v0)
802f7318: 3c050010 lui a1,0x10
802f731c: 34a56256 ori a1,a1,0x6256
802f7320: 00450019 multu v0,a1
802f7324: 00002821 move a1,zero
802f7328: 00001012 mflo v0
802f732c: 00001810 mfhi v1
802f7330: 00a20018 mult a1,v0
802f7334: 70640000 madd v1,a0
802f7338: 00003012 mflo a2
802f733c: 00440019 multu v0,a0
802f7340: 00001810 mfhi v1
802f7344: 00c31021 addu v0,a2,v1
#include <asm/compiler.h>
#include <asm/war.h>
inline void __delay(unsigned int loops)
{
__asm__ __volatile__ (
802f7348: 1440ffff bnez v0,802f7348 <__udelay+0x38>
802f734c: 2442ffff addiu v0,v0,-1
void __udelay(unsigned long us)
{
unsigned int lpj = current_cpu_data.udelay_val;
__delay((us * 0x000010c7ull * HZ * lpj) >> 32);
}
802f7350: 03e00008 jr ra
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Fwd: about udelay in mips
2011-01-27 9:20 ` Fwd: about udelay in mips loody
@ 2011-01-27 11:29 ` Sergei Shtylyov
2011-01-27 12:28 ` loody
0 siblings, 1 reply; 5+ messages in thread
From: Sergei Shtylyov @ 2011-01-27 11:29 UTC (permalink / raw)
To: loody; +Cc: gcc-help, Linux MIPS Mailing List
Hello.
On 27-01-2011 12:20, loody wrote:
> hi all:
> I guess there seems be some differences about
> "unsigned long long" and "ull" so I forward the letter to gcc-help.
> If my guess is correct, what are the differences between them and why
> "unsigned long long" cannot let compiler compile the 64-bits
> operations as I want?
Probably because in 2.6.30 you only cast the result of 32-bit multiplies
to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the
0x000010c7ull constant is 64-bit...
> thanks a lot,
> miloody
> I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
> below are the dis-assemblies:
> (as you can see the v0 = v1 = zero.)
> My version is 2.6.30.9:
> void __udelay(unsigned long us)
> {
> unsigned int lpj = current_cpu_data.udelay_val;
>
> __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
> 80306ed0: 00001821 move v1,zero
> 80306ed4: 00601021 move v0,v1
> #include<asm/compiler.h>
> #include<asm/war.h>
>
> inline void __delay(unsigned int loops)
> {
> __asm__ __volatile__ (
> 80306ed8: 1440ffff bnez v0,80306ed8 <__udelay+0x8>
> 80306edc: 2442ffff addiu v0,v0,-1
> void __udelay(unsigned long us)
> I have double checked the __delay source code of 2.6.33.4
> and the dis-assemblies:
> void __udelay(unsigned long us)
> {
> unsigned int lpj = current_cpu_data.udelay_val;
>
> __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
> 802f7310: 3c02804f lui v0,0x804f
> 802f7314: 8c429360 lw v0,-27808(v0)
> 802f7318: 3c050010 lui a1,0x10
> 802f731c: 34a56256 ori a1,a1,0x6256
> 802f7320: 00450019 multu v0,a1
> 802f7324: 00002821 move a1,zero
> 802f7328: 00001012 mflo v0
> 802f732c: 00001810 mfhi v1
> 802f7330: 00a20018 mult a1,v0
> 802f7334: 70640000 madd v1,a0
> 802f7338: 00003012 mflo a2
> 802f733c: 00440019 multu v0,a0
> 802f7340: 00001810 mfhi v1
> 802f7344: 00c31021 addu v0,a2,v1
> #include<asm/compiler.h>
> #include<asm/war.h>
>
> inline void __delay(unsigned int loops)
> {
> __asm__ __volatile__ (
> 802f7348: 1440ffff bnez v0,802f7348 <__udelay+0x38>
> 802f734c: 2442ffff addiu v0,v0,-1
> void __udelay(unsigned long us)
> {
> unsigned int lpj = current_cpu_data.udelay_val;
>
> __delay((us * 0x000010c7ull * HZ * lpj)>> 32);
> }
> 802f7350: 03e00008 jr ra
WBR, Sergei
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Fwd: about udelay in mips
2011-01-27 11:29 ` Sergei Shtylyov
@ 2011-01-27 12:28 ` loody
2011-01-27 21:38 ` Ian Lance Taylor
0 siblings, 1 reply; 5+ messages in thread
From: loody @ 2011-01-27 12:28 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: gcc-help, Linux MIPS Mailing List
hi:
> Probably because in 2.6.30 you only cast the result of 32-bit multiplies
> to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the
> 0x000010c7ull constant is 64-bit...
>> void __udelay(unsigned long us)
>> {
>> unsigned int lpj = current_cpu_data.udelay_val;
>>
>> __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
so that means (us * 0x000010c7 * HZ * lpj) is calculated at 32-bits and finally
(unsigned long long) cast it as 64-bits?
if i remember correctly, "64bit cast to 32-bits" is possible get 0
value, since high bits cast out.
But how 34-bits cast to 64-bits will make the value as 0 if original
low 32-bits value is non-zero?
appreciate your reply,
miloody
>> 80306ed0: 00001821 move v1,zero
>> 80306ed4: 00601021 move v0,v1
>> #include<asm/compiler.h>
>> #include<asm/war.h>
>>
>> inline void __delay(unsigned int loops)
>> {
>> __asm__ __volatile__ (
>> 80306ed8: 1440ffff bnez v0,80306ed8 <__udelay+0x8>
>> 80306edc: 2442ffff addiu v0,v0,-1
>> void __udelay(unsigned long us)
>
>> I have double checked the __delay source code of 2.6.33.4
>> and the dis-assemblies:
>
>> void __udelay(unsigned long us)
>> {
>> unsigned int lpj = current_cpu_data.udelay_val;
>>
>> __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
>> 802f7310: 3c02804f lui v0,0x804f
>> 802f7314: 8c429360 lw v0,-27808(v0)
>> 802f7318: 3c050010 lui a1,0x10
>> 802f731c: 34a56256 ori a1,a1,0x6256
>> 802f7320: 00450019 multu v0,a1
>> 802f7324: 00002821 move a1,zero
>> 802f7328: 00001012 mflo v0
>> 802f732c: 00001810 mfhi v1
>> 802f7330: 00a20018 mult a1,v0
>> 802f7334: 70640000 madd v1,a0
>> 802f7338: 00003012 mflo a2
>> 802f733c: 00440019 multu v0,a0
>> 802f7340: 00001810 mfhi v1
>> 802f7344: 00c31021 addu v0,a2,v1
>> #include<asm/compiler.h>
>> #include<asm/war.h>
>>
>> inline void __delay(unsigned int loops)
>> {
>> __asm__ __volatile__ (
>> 802f7348: 1440ffff bnez v0,802f7348 <__udelay+0x38>
>> 802f734c: 2442ffff addiu v0,v0,-1
>> void __udelay(unsigned long us)
>> {
>> unsigned int lpj = current_cpu_data.udelay_val;
>>
>> __delay((us * 0x000010c7ull * HZ * lpj)>> 32);
>> }
>> 802f7350: 03e00008 jr ra
>
> WBR, Sergei
>
--
Regards,
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Fwd: about udelay in mips
2011-01-27 12:28 ` loody
@ 2011-01-27 21:38 ` Ian Lance Taylor
2011-01-27 21:43 ` Maciej W. Rozycki
0 siblings, 1 reply; 5+ messages in thread
From: Ian Lance Taylor @ 2011-01-27 21:38 UTC (permalink / raw)
To: loody; +Cc: Sergei Shtylyov, gcc-help, Linux MIPS Mailing List
loody <miloody@gmail.com> writes:
>> Probably because in 2.6.30 you only cast the result of 32-bit multiplies
>> to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the
>> 0x000010c7ull constant is 64-bit...
>
>>> void __udelay(unsigned long us)
>>> {
>>> unsigned int lpj = current_cpu_data.udelay_val;
>>>
>>> __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
> so that means (us * 0x000010c7 * HZ * lpj) is calculated at 32-bits and finally
> (unsigned long long) cast it as 64-bits?
> if i remember correctly, "64bit cast to 32-bits" is possible get 0
> value, since high bits cast out.
> But how 34-bits cast to 64-bits will make the value as 0 if original
> low 32-bits value is non-zero?
I don't know the type of HZ. But assuming it is a constant, then the
rules of C are that the expression
us * 0x000010c7 * HZ * lpj
gets evaluated in the type "unsigned long". The fact that you then cast
that "unsigned long" value to "unsigned long long" does not cause the
multiplication to be done in the type "unsigned long long".
You need to write something like
(unsigned long long) us * 0x000010c7 * HZ * (unsigned long long) lpj
to get the multiplication to be done in the "unsigned long long" type.
This questoin has nothing to do with gcc, by the way, it's a C language
question.
Ian
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Fwd: about udelay in mips
2011-01-27 21:38 ` Ian Lance Taylor
@ 2011-01-27 21:43 ` Maciej W. Rozycki
0 siblings, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2011-01-27 21:43 UTC (permalink / raw)
To: Ian Lance Taylor
Cc: loody, Sergei Shtylyov, gcc-help, Linux MIPS Mailing List
On Thu, 27 Jan 2011, Ian Lance Taylor wrote:
> I don't know the type of HZ. But assuming it is a constant, then the
> rules of C are that the expression
> us * 0x000010c7 * HZ * lpj
> gets evaluated in the type "unsigned long". The fact that you then cast
> that "unsigned long" value to "unsigned long long" does not cause the
> multiplication to be done in the type "unsigned long long".
>
> You need to write something like
> (unsigned long long) us * 0x000010c7 * HZ * (unsigned long long) lpj
> to get the multiplication to be done in the "unsigned long long" type.
Though as a matter of coding style, personally I'd rather assigned "us"
to a local variable of the "unsigned long long" type and performed all the
calculations on it instead, avoiding any explicit casts and doubts as to
what type is being used altogether.
Maciej
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-01-27 21:42 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <AANLkTinvdEPwQ=DmcF8nnTAa0Py_O=+p7x1pobcTNHom@mail.gmail.com>
[not found] ` <AANLkTik8hQfd8cvNj=qeq5U=6zpQHw33a9hfK-q8+x1Z@mail.gmail.com>
[not found] ` <AANLkTikpUBtg2zz8tcbcz2rcG-O+fTFwb_pTi88uZe0h@mail.gmail.com>
[not found] ` <AANLkTi=zfr5YuwBCcvH2Jas50UxnUtvzp_CDyN25sT5h@mail.gmail.com>
[not found] ` <AANLkTim_swh58fCUxZ4e6MDrM9Lqrbm+1ufnp8W767JL@mail.gmail.com>
2011-01-27 9:20 ` Fwd: about udelay in mips loody
2011-01-27 11:29 ` Sergei Shtylyov
2011-01-27 12:28 ` loody
2011-01-27 21:38 ` Ian Lance Taylor
2011-01-27 21:43 ` Maciej W. Rozycki
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 read-only IMAP folder(s) and NNTP newsgroup(s).