public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).