avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] dev and mod may not be optimized


From: David Brown
Subject: Re: [avr-gcc-list] dev and mod may not be optimized
Date: Wed, 12 Dec 2007 12:37:36 +0100
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

Dmitry K. wrote:
On Wednesday 12 December 2007 01:16, Albert Andras wrote:
----- Original Message -----
From: "Nathan Moore" <address@hidden>

unsigned char a, b, c;
c = some_input_function();
LABEL:
a = c/10;
b = c%10;
...

*****************************************
LABEL:
mov r24,r18
ldi r22,lo8(10)
call __udivmodqi4
mov r19,r24
.LM436:
mov r24,r18
 call __udivmodqi4

If I'm understanding __udivmodqi4 it produces the results of both of
these with one call.
Acording to:
http://www.nongnu.org/avr-libc/user-manual/structdiv__t.html

you could do:

div_t t;
      t=div(c/10);
      a=t.quot;
      b=t.rem;

Alas, the usage of div() function is more space and more time
expansive. The reason is that div() uses an another function:
__divmodhi4(), i.e. 16-bits.

Compare two programs:
  prog1:  150 bytes, 238 clocks
  prog2:  212 bytes, 316 clocks

Regards,
Dmitry.

-------------------------------------------------------------
volatile unsigned char a, b, v = 123;
int main ()
{
    unsigned char c = v;
    a = c / 10;
    b = c % 10;
    return 0;
}
-------------------------------------------------------------
#include <stdlib.h>
volatile unsigned char a, b, v = 123;
int main ()
{
    div_t d;
    d = div (v, 10);
    a = d.quot;
    b = d.rem;
    return 0;
}
--------------------------------------------------------------


How about:

volatile unsigned char a, b, v = 123;
int main ()
{
    unsigned char c = v;
    a = c / 10;
    b = c - a * 10;
    return 0;
}

It's a little inelegant, but multiplying by 10 and then subtracting is much smaller and faster than doing a second division.

mvh.,

David





reply via email to

[Prev in Thread] Current Thread [Next in Thread]