write to memory mapped registers

Hi everyone,

I'm having a subtle problem with the compiler g21k on an ADSP21020. When I want to write to a specific memory-mapped register the tool addresses the *address+1* instead. I have the address defined as follow:

#define ADDR 0x80000000 > #define REGW (unsigned int *)ADDR

and then I use it like this:

unsigned int *reg = REGW; > *reg = myvalue;

If I look at the assembler output (listing and object) it looks like the address in the listing is correct:

i0=-2147483648; (which is 0x80000000)

while the object code is:

0F1080000001 (which is an 'immediate move' i0=0x80000001!!!)

How can I have such a strange behavior? The 0x80000000 is at the memory bank boundary, but I don't see how that can be a problem. Anything I should be aware of that my compiler is silently taking into account?

Al

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Reply to
alb
Loading thread data ...

A subtle one-complement/two-complement misinterpretation?

Meindert

Reply to
Meindert Sprang

Try #define ADDR 0x80000000UL

Leo Havmøller.

Reply to
Leo Havmøller

no joy.

Reply to
alb

It is true that an 'int' is taken as 32-bit two's complement number but I don't see how this can lead to the described behavior. B.t.w. 0x80000002 is correctly interpreted.

Reply to
alb

You may need to do this in assembly, or with a scrap of assembly. It looks like your problem isn't in just the compiler, but is a mismatch between the compiler and the assembler.

Your compiler is emitting addresses as decimal, two's compliment numbers, so instead of getting 2147483648 (which is 0x80000000 in anyone's book) you're getting -2147483648 (which is only 0x80000000 in 32-bit two's complement when it's correctly interpreted).

I suspect that this bit of bad style in the compiler is being complimented by an assembler uses library code to read in numbers and somehow does the conversion from -2147483648 to 0x80000001 (if you're using saturated arithmetic 0x80000000 is an insidiously bad number; someone may have "fixed" a bug in library code).

Does g21k let you use assembler directives? Try sticking in your own code in there, either using 2147483648 in the assembly, or 0x80000000.

BTW: my preferred way to do memory-mapped registers is to declare them as extern in C (generally as structures of related registers, one for each peripheral), then define their locations either in the linker file (which is easy if you're using something derived from gcc) or in an assembly file (using a directive to absolutely locate stuff). Hopefully doing so would sidestep this nastiness.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

But what looks strange to me is that the assembler is responsible for both the listing and the object file. How can it then produce a different result?

If you mean an in-line assembly instruction within the C code, yes. I can use the instruction 'asm()' to access to the register and the value here seems correct. Is just that I don't like that much to clutter my code with inline assembly functions and I didn't come out with a solution that please my 'sense of aesthetic' :-)

It's indeed an option I would also like to try. So far I have a header file where I defined all the memory-mapped registers. It shouldn't be any problem in moving everything to an assembler file and nail down those values. Thanks for the pointer.

Reply to
alb

(snip)

Are you sure that the listing is coming from the assembler? If the g21k is a gnu toolchain, and if you're making it cough up assembly with the '- s' directive, then it's coming from the compiler.

Even if the listing is coming from the assembler, it would be proper for it to just echo what goes into it. So if the problem is in how it interprets decimal numbers, you would see the symptoms you are seeing.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.