Use of volatile in structure definitions to force word accesses

As I see it, there is only one reasonable choice for an alternative to gcc for ARM development, and that is clang/llvm. Clang is in many ways gcc's strongest competitor - and also its closest partner, as the developers work together on features such as the sanitizers. A key point here is that ARM have chosen clang/llvm as their compiler for the official ARM development tools of the future (replacing the Keil compiler). Of course, ARM continues to support gcc development - they want to sell cores, not compilers! But if you do change to clang in the future, you can expect your bitfields to continue working - clang make a point of keeping as good compatibility with gcc as possible.

Reply to
David Brown
Loading thread data ...

I've been looking at improving my skills with more modern techniques, and this is what I'm planning on using:

It combines the expessiveness of bit fields with the efficiency and control of the traditional macro approach, and should be portable. The caveats are that it's C++14 and so needs a modern compiler. It also absolutely needs to be compiled with optimizations turned on for everything to be precomputed at compile time, and I've found some GCC ports to be fiddly about that (eg. the SuperH port of GCC 5.2.0 would not precompute the bitmask at -Os, but the RX port had no such problems).

-a

Reply to
Anders.Montonen

You can ease the optimizer's work if make mask = (1

Reply to
frantas

To put that in context, that would be:

template constexpr reg_type generate_mask(unsigned int width, unsigned int position) { return (width ? ((((((reg_type) 1)

Reply to
David Brown

Reply to
Anders.Montonen

Reply to
David Brown

(snip)

(snip)

Rotate (by one) instructions were common on some early CPUs. That included both N bit and N+1 (rotate through carry), where combinations of such would shift between registers.

A little later, and as processors got more powerful, the multiple bit shifts appeared. For some, there would be a processor loop shifting one bit at a time, such that the shift time was proportional (plus a small constant) the the shift amount. Consider that a

36 bit machine might allow for a 2**36 bit shift.

More specifically, the 8086 allows for a 256 bit shift, as the shift amount is in an 8 bit register. With the 80286 the shift amount was changed to modulo 32, for one to reduce the possible instruction execution time, but also it allows for a barrel shifter instead of a processor loop.

For another specific case, IBM S/360 does both single (32 bit) and double register (64 bit) shifts modulo 64. Early versions of Hercules used the C shift operator on 32 bit values, not realizing that it needed to check for appropriate shift values. Figuring that out was my biggest contribution to Hercules.

Reply to
glen herrmannsfeldt

You are of course right, I was looking at the wrong shift.

Shifting unsigned integers is defined: "The value of E1 > E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type or if E1 has a signed type and a non-negative value, the value of the result is the integral part of the quotient of E1/2^E2."

Accordingly, calculating the mask as an unsigned long long should avoid problems and be more readable.

-a

Reply to
Anders.Montonen

I'm guessing that is from 5.8 in the C++ standards (N3337 is the freely available version for C++11). But you forgot the paragraph above:

"The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand."

So the left operand (1u in this case) is promoted if necessary (i.e., if it is smaller than "int" or "unsigned int" it gets bumped up to "int" or "unsigned int"). If the right operand is greater than or equal to the length in bits of the promoted left operator, the result is undefined.

Thus on a 32-bit system, ((uint16_t) 1) Accordingly, calculating the mask as an unsigned long long should avoid

You could certainly use ((uint64_t) 1u) for the shift - that would would up to 63 bits. But you would hit the same problem at 64 bits. It is better to have the somewhat ugly code here - it is correct, will work regardless of the bit size of the system, and will still give optimal code (assuming a sane compiler and sensible compiler options).

Reply to
David Brown

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.