Discussion Forum

problem using idata in calculations

Next Thread | Thread List | Previous Thread Start a Thread | Settings

DetailsMessage
Read-Only
Author
gregory gosse
Posted
13-Apr-2004 13:15 GMT
Toolset
C51
New! problem using idata in calculations
Hi,

Is there a problem using idata for variables used in "heavy"calculations ?

( heavy = 3 products 2 sums in a same instruction)

I use microvision 1.30 dll 1.30 C compiler v5.20

In my program some calculations produce good results when used with data and wrong and changeant results when used with idata.



Thanks.
Gregory.
Read-Only
Author
erik malund
Posted
13-Apr-2004 14:08 GMT
Toolset
C51
New! RE: problem using idata in calculations
( heavy = 3 products 2 sums in a same instruction)
Have you heard about the competition on how to make the most obfusciated C code?

Erik
Read-Only
Author
Graham Cole
Posted
13-Apr-2004 15:01 GMT
Toolset
C51
New! RE: problem using idata in calculations
The only thing I can think of is that this has to do with stack space.

In a complex statement, intermediate results are placed on the stack and, if you are using idata, there will be less stack space available.

It is sometimes possible to rearrange a statement to minimise stack space and increase speed of execution. For example, you may find that:
    a = b + c * d;
Causes b to be placed on the stack, whereas:
    a = c * d + b;
does not.

Take a look at the object code actually generated.
Read-Only
Author
Stefan Duncanson
Posted
14-Apr-2004 09:44 GMT
Toolset
C51
New! RE: problem using idata in calculations
"In a complex statement, intermediate results are placed on the stack"

Are you sure about this?
Read-Only
Author
Graham Cole
Posted
14-Apr-2004 10:49 GMT
Toolset
C51
New! RE: problem using idata in calculations
Am I sure? Well, it is possible that it only happens to long ints as in:
    9:     la = (lb * lc) + (lb * ld);
0000A1 AF21              MOV     R7,ld+03H
0000A3 AE20              MOV     R6,ld+02H
0000A5 AD1F              MOV     R5,ld+01H
0000A7 AC1E              MOV     R4,ld
0000A9 AB19              MOV     R3,lb+03H
0000AB AA18              MOV     R2,lb+02H
0000AD A917              MOV     R1,lb+01H
0000AF A816              MOV     R0,lb
0000B1 1115              ACALL   ?C?LMUL
0000B3 C004              PUSH    AR4
0000B5 C005              PUSH    AR5
0000B7 C006              PUSH    AR6
0000B9 C007              PUSH    AR7
0000BB AF1D              MOV     R7,lc+03H
0000BD AE1C              MOV     R6,lc+02H
0000BF AD1B              MOV     R5,lc+01H
0000C1 AC1A              MOV     R4,lc
0000C3 AB19              MOV     R3,lb+03H
0000C5 AA18              MOV     R2,lb+02H
0000C7 A917              MOV     R1,lb+01H
0000C9 A816              MOV     R0,lb
0000CB 1115              ACALL   ?C?LMUL
0000CD D003              POP     AR3
0000CF D002              POP     AR2
0000D1 D001              POP     AR1
0000D3 D000              POP     AR0
0000D5 EF                MOV     A,R7
0000D6 2B                ADD     A,R3
0000D7 F515              MOV     la+03H,A
0000D9 EE                MOV     A,R6
0000DA 3A                ADDC    A,R2
0000DB F514              MOV     la+02H,A
0000DD ED                MOV     A,R5
0000DE 39                ADDC    A,R1
0000DF F513              MOV     la+01H,A
0000E1 EC                MOV     A,R4
0000E2 38                ADDC    A,R0
0000E3 F512              MOV     la,A
I well remember optimising some MD5 functions where all the variables were 32-bit and the arrangement of the statement did turn out to be significant. It may be that this only applies to long ints and possibly floats.
Read-Only
Author
Stefan Duncanson
Posted
14-Apr-2004 13:48 GMT
Toolset
C51
New! RE: problem using idata in calculations
Well, there you go. I'd always believed the manual:

http://www.keil.com/support/docs/250.htm
Read-Only
Author
Jon Ward
Posted
14-Apr-2004 23:07 GMT
Toolset
C51
New! RE: problem using idata in calculations
I just updated the knowledgebase article to indicate this.

Jon
Read-Only
Author
Stefan Duncanson
Posted
15-Apr-2004 09:47 GMT
Toolset
C51
New! RE: problem using idata in calculations
Jon,

Can you give any indication of the maximum stack depth the compiler could use when evaluating an arbitrarily complex expression?
Read-Only
Author
Hans-Bernhard Broeker
Posted
17-Apr-2004 19:09 GMT
Toolset
C51
New! RE: problem using idata in calculations
I have a hunch such an upper limit can't possibly exist. As far as I can see, "arbritrarily complex" expressions can, almost by definition, require arbitrarily much stack space to evaluate.
Read-Only
Author
Stefan Duncanson
Posted
19-Apr-2004 09:33 GMT
Toolset
C51
New! RE: problem using idata in calculations
"I have a hunch such an upper limit can't possibly exist. As far as I can see, "arbritrarily complex" expressions can, almost by definition, require arbitrarily much stack space to evaluate."

Really? It srikes me as a bit strange that the compiler doesn't use the stack for parameter passing or local variables 'due to limitations of the 8051 architecture', however it appears that it arbitrarily and silently pushes whatever quantity of stuff it likes on the stack during evaluation of a complex expression. This is why I would really like a definitive answer from Keil on this subject.
Read-Only
Author
Jon Ward
Posted
19-Apr-2004 20:39 GMT
Toolset
C51
New! RE: problem using idata in calculations
Really? It srikes me as a bit strange that the compiler doesn't use the stack for parameter passing or local variables 'due to limitations of the 8051 architecture', however it appears that it arbitrarily and silently pushes whatever quantity of stuff it likes on the stack during evaluation of a complex expression.

If the compiler used the stack for local variables and function arguments, it would need a way to reference those objects on the stack. It would need a base pointer. R0 or R1 would be required for that.

That would leave only 7 registers to be used in the function. Operations with floats or with longs could no longer be performed entirely in registers (like they are now).

ALL local variables and function arguments would take longer to access (because indirect accesses are slower on the 8051 then direct accesses). This would slow down ALL programs and would ultimately require more stack space than is used by the current scheme.

As it is, you are only penalized (more stack space required) for complex expressions.

Jon
Read-Only
Author
Jon Ward
Posted
19-Apr-2004 20:31 GMT
Toolset
C51
New! RE: problem using idata in calculations
Can you give any indication of the maximum stack depth the compiler could use when evaluating an arbitrarily complex expression?

The compiler only stacks temporary results when absolute required. Typically, this is only required in complex expressions using long or float types which include function calls.

For example, consider the following:

long a,b,c,d,e;

e = (a*b) + (c*d);

In this case, the compiler multiplies a and b, then multiplies c and d, and finally adds the two products. Long multiplications are performed by a compiler function ?C?LMUL. The two multiplicands are loaded into R0-R3 and R4-R7. The result is returned in R4-R7.

So, in the above example, after (a*b) is multiplied, the result must be saved (on the stack) and then (c*d) can be calculated. Thus, for this example 4 bytes of stack space are used.

If we complicate the example:

long a,b,c,d,e,f,g;

e = (a*b) + (c*d) + (f*g);

Still, only 4 bytes of stack space are used.

In theory, the maximum stack space that may be used is not limited by the compiler. So, it is possible that the microcontroller could run out of stack space.

In reality, it is extremely difficult to create statements so complex that they require more than 8-10 bytes of stack space.

Jon
Read-Only
Author
Stefan Duncanson
Posted
20-Apr-2004 09:12 GMT
Toolset
C51
New! RE: problem using idata in calculations
Jon,

Thank you for your answer.

Next Thread | Thread List | Previous Thread Start a Thread | Settings