# Easiest way to get rid of __clz_tab in winavr compiled code?

I've ported a program from the arduino environment to a makefile build using winavr, which, in turn, is based on avr-gcc (just like arduino).

However, my program started crashing, and after some investigation I found I was running out of data memory due to a 256 byte increase in the heap, even though I hadn't changed the program at all.

Looking at the map file I see a new table being included, __clz_tab, which is 256 bytes, and resides in RAM.

How do I get rid of this table and reclaim my RAM?

• Which version of avr-gcc and avr-libc are you using in both cases? Arduino ships with its own copy of the tool-chain and compiles with various flags set, which you can observe by compiling with verbose output in the Arduino IDE (hold down shift while clicking compile in the < 1.0 IDE , or select it in the preferences dialogue in the >= 1.0 IDE). – vicatcu Jun 12 '12 at 15:20

libc, included with gcc and avr-gcc, has a function that's used to count leading zeros when converting from an int or uint into a float or a double. This function uses a 256 byte table to speed up the zero counting operation, which is fine for computers with lots of memory, but not so great for microcontrollers where 256 bytes is 1/4 or 1/8 of the total ram available.

avr-gcc includes a library, libm.o which has alternate definitions for some functions, including the function that requires __clz_tab. This definition requires less memory, and so you need to instruct the linker to link against libm.

This is done by adding -lm to the linker command line.

However, the position of this command parameter matters - it will only resolve links to symbols before this parameter, so to make the most of it the -lm parameter should be as close to the end of the command line as possible.

In my Makefile it looks like this:

CXX=avr-gcc
CFLAGS=$(MCU)$(CPU_SPEED) -g  -Os -w -Wl,--gc-sections -ffunction-sections -fdata-sections
LFLAGS= -Wl,--section-start=.text=0x0000,-Map=program.map
INCLUDE=-I ../include/arduino/
LIBS=-L ../lib -larduino -lm

default: program.hex

program.hex: program.elf
avr-objcopy -O ihex $<$@

program.elf: bcu_usb.cpp main.cpp programmer.cpp
$(CXX)$(CFLAGS) $(LFLAGS)$(INCLUDE) $^ -o$@ $(LIBS)  Note that the last item on the compiler command line is $(LIBS) and the last item in LIBS is the -lm which ensures that the compiler gives precedence to the definitions in libm when there are multiple definitions available.

Recent versions of avr-gcc have resolved this issue so this doesn't happen even without the -lm, however the arduino IDE is still installing and using the older versions of avr-gcc, and winavr hasn't been updated since this bug was fixed.

You can read the bug report here:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29524

• @vicatcu I will as soon as the system permits it. There's a two day waiting period for accepting one's own answer on Stack Exchange. – Adam Davis Jun 12 '12 at 18:03