I found out that gcc has had support for fixed-point since 2007, however for most targets it is implemented completely in c library calls. I decided I would try to get gcc to emit reasonable assembly for avr.
When configuring gcc I used the following line:
./configure --target=avr --enable-languages=c --disable-libssp --enable-fixed-point
This will break without my patch. You only need the dwarf and gdb patches if you want to debug.
Currently there are a bunch of types with the following formats:
short _Fract s.7 unsigned short _Fract .8 _Fract s.15 unsigned _Fract .16 long _Fract s.31 unsigned long _Fract .32 long long _Fract s.64 unsigned long long _Fract .64 short _Accum s7.8 unsigned short _Accum 8.8 _Accum s15.16 unsigned _Accum 16.16 long _Accum s31.32 unsigned long _Accum 32.32 long long _Accum s63.64 unsigned long long _Accum 64.64
Initially everything basically worked, but emitted a lot of large slow c routines to do the work.
Now I have support builtin to gcc for the following:
1. Conversions between all fixed-point types and integers.
2. Addition and Subtraction for types not "long" or "long long"
3. Multiplication for short _Fract
In assembly libraries I have support for:
1. Conversion to and from fixed-point and floating point for types not "long" or "long long"
2. Multiplication for all types that are not "long" or "long long" except a few cases (see below)
Things missing: (hopefully some people are interested in helping)
1. Multiplication - Currently for micros without a mul instruction, I don't have assembly routines for s7.8 8.8 s15.16 or 16.16 types. (update: completed)
2. Division - I do not have any routines for division, so I would greatly appreciate this support. (update: completed)
3. Optimization - gcc often emits instructions to load into one register, then move to another before performing an operation resulting in an extra move. There are also a lot of other opportunities for other optimizations. (I noticed it does stupid stuff even with integers)
4. Fixed point math library - I would like to pick a few types, probably signed only, (s7.8 and s15.16) and provide library routines similar to the floating point library (sqrt, sin, cos, tan, asin, acos, atan, log, pow, etc...)
5. String conversion - I'm not sure it would be correct to build this into printf, but various routines like atof (except atok or ator etc see: http://gcc.gnu.org/wiki/FixedPoi... for suffixes) and also converting to strings. In some situations it would be best to convert to float then string, but that would use more memory if you didn't use floats otherwise.
6. Saturating types - The fixed point stardard adds types with saturation (_Sat attribute) which effectively doubles the number of new types from above. The only difference is these types saturate to the maximum or minimum value, so they are slower to use, but have certain applications. I have basically ignored these types, so all support is via the c library.
Let me know if you have any interest in this and what you have tried with it.