Advanced Users can post their questions and comments here for the not so Newbie crowd.

Moderator: eriksl

User avatar
eriksl wrote:Something is written to the adress in a5, which transferred to a12 later. I think that is the only point where something is written to memory/IO other than to stack.

It looks like:

a2_a3 double argument 1
a4 int argument 1
a5 pointer/int argument

Yesterday i put rfpll_set_freq into a for loop and i saw different results on the UART terminal. So im dure that it does something with the PLL, becouse the cfharacters was changing even if the msg was the same.
User avatar
By eriksl
#92283 Interesting, I will look again.

In the old days I used to have an 68000 machine that was rated at 16 Mhz, but the clock could be set to 24 Mhz too. The situation was a bit comparable to this, it would run fine for some time, but then strange things would be starting to happen. I think we really hit the "hard limit" here. At some point the electrical capacities between the signal lines will grow to large (for the given frequency) and then signal deformation will happen, causing tranmission errors (within the die). Also the die will start using much more power at higher frequencies, if it's not designed for it. I am not even worried about heat generation, but it might cause dips in the (local) power supply (on parts of the die itself).
User avatar
By eriksl
#92284 More notes:

- the stack pointer [a1] is lowered by 32 bytes, 8 32 bit words.
- any argument passed on the stack, is therefore on 32(a1) or higher
- it looks like no arguments are passed over the stack, that seem to be unusual for xtensa (even on call0)
- at 0(a1) = a3 (saved register)
- at 4(a1) = a0 (saved register)
- at 8(a1) = a12 (saved register)
- at 12(a1) = a13 (saved register)
- at 16(a1) = a14 (saved register)
- interesting what 20(a1) - 28(a1) is used for...
- a5 is a 32 bit parameter to the function, it's not set anywhere in the function. It must be either an integer (probable) or a float (less probable). a5 is "moved" to a12 and a12 is then used in a calculation.
- something is also done with a2 and a4, looks also like 32 bit values
- a3 is never used though (only as a result)
- this is interesting:
Code: Select all4000797c:   110260     slli   a0, a2, 10
4000797f:   040a         add.n   a0, a4, a0
40007981:   1120e0    slli   a2, a0, 2

it calculates a0 = ((a2 << 10) + a4) << 2. The last shift will probably turn an "index" into a pointer into an array of 32 bit values. Yep, confirmed, they're not integers though, but floats (also 32 bit).
- also there are three s8i instructions, all of them write a single byte from a2 to (a12) with an offset of 0, 1 or 2. Maybe a12 contains a register address at this point. There are no other relevant writes to memory addresses. a12 is set from a5 and definitely not calculated in the function...
User avatar
By eriksl
#92285 According to gcc:

When this option is enabled function parameters are passed in registers a2 through a7, registers a12 through a15 are caller-saved, and register a15 may be used as a frame pointer.

So really a2 = arg1, a3 = arg2, a4 = arg3, a5 = arg4 etc. Another page noted that doubles (and other non-32 bit values) are always aligned. So if you have an integer parameter and a double, they will end up in:

a2 = int_parameter
a3 = not used
a4 = double_part_1
a5 = double_part_2

That would explain why a3 isn't used, still it seems that a4 and a5 are not used together, it looks like they're both integers instead.

I could never find a function prototype for this function, so we will have to keep guessing.