Saturday, October 18, 2014

It turns out that I only needed to implement floating point multiplication, division and exponentiation and some comparison wrappers to be complete.

I've got a working float multiply function, but it's ugly and needs to be streamlined. I also need to check for boundary conditions (infinities and infinitesimals).

Mostly I need to reacquaint myself with this code. It's all written in twisty assembly since I wanted to maximize performance and minimize space. Unfortunately, it takes a while to understand how all the pieces fit together.

Doing all this in assembly may have been a mistake.

Saturday, October 11, 2014

Now that I've sent a release out, I need to find something else to work on for a while. I think I should probably finish the floating point stuff. Right now it's more than halfway done. If I can get that done I can move on to other stuff. Maybe libc? Oh well, I can figure that out later.

Friday, October 10, 2014

Binutils 2.19.1 patch 1.6

Changes this version:

Added support for numeric registers
Correct handling of comments
Added support for dwarf debugging information (-g option)

Download: binutils-2.19.1-tms9900-1.6-patch.tar.gz

GCC 4.4.0 patch 1.9

Changes this version:

Changed order of jumps for less-than-or-equal tests to improve performance
Fixed several integer type conversion bugs
Corrected handling of variable shift by zero bits
Fixed signed division
Added support for dwarf debugging information (-g option)

Download: gcc-4.4.0-tms9900-1.9-patch.tar.gz
Alright, I finally got all the dwarf stuff figured out. The debug_line section was actually built by the assembler, but the contents were malformed. The problem is that the assembler was trying to create a four-byte relocation record. This is a problem since for the tms9900 anything beyond a two byte address in a relocation record is meaningless.

I had implemented a workaround, but that was broken, and placed the relocation in the upper word. This made the actual section size and the size declared in the header disagree, as a result, no source line information ever gets parsed. Realizing this problem was long and painful.

I spent some time studying the dwarf2 specification, but the debug_line section is implemented as bytecode for a virtual machine, so I wanted to avoid manual translation if I could. I tried to find something which could dump the strings section, but no such luck.

In the end I made a one-line program and stepped my way through the section using the dwarf specification and did some trial-and-error work to fix the broken header values.

Long story short, we're good now and I can finally prepare another release.

Thursday, October 9, 2014

Well, I've made a mess of things by forcing line number information to be built by gcc. There are lots of interdependancies between the dwarf sections, and what I did left some loose ends resulting in some unknown symbols being found during the assembly process.

Apparently, the preferred method is for the assembler to compose the line number section based on the .file and .loc directives. Now I need to find out why those aren't being built.

Wednesday, October 8, 2014

It took a while, but I found that the code which handles the debug option for gcc is in the set_debug_level function. Specifically, the "write_symbols" variable is used to store the debug level. We can test that to see if the file line directives should be used or not.

One drawback of this is that by enabling source line information with .file and .loc directives, the dwarf .debug_line section is not created. I'm not sure why that is, but this is hard-coded behavior and not configurable. This just sounds dumb, so I'm overriding this. If you want debug sections, you now get all of them. I just like the idea of being able to use objdump to view the source code.

So I'm not sure what else to do right now. It might be time to do a release.

Tuesday, October 7, 2014

Well, that was a lot harder than I expected. The start_line_hook function in the assembler got a major overhaul just to deal with TI comments. But at least we can now properly assemble code again.

I had to implement a grammatical parser to recognize each part of an assembly line in order to see if a given chunk of text was a comment or not. This was needed because a comment starting with an asterisk may be incorrectly merged into an expression ("ai r1, 2 * comment"). The same kind problem may be seen if a comment follows an instruction using a postincrement argument ("a r1, *r2+ comment") since the intervening space was getting removed and we saw invalid expression errors.

I also had to remove all trailing whitespace caused by the comments because the gas file parser assumes that by the time start_line_hook is called, all comments and extra whitespace has already been removed. The file parser apparently can only handle whitespaces one character long.

Ugh. At least the assembler is working again. Now I can get back to the DWARF debugging stuff, using div_signed.c for testing.

OK, Looking better. I can compile using the "-g" option to include debugging information, and then use "tms9900-objdump -S" to disassemble and view the source code. Nice.

The problem is that the standard way of viewing mixed source and assembly output is to use "tms9900-gcc -Wa,-adhln -g". If I try this right now, I just see the assembly with no interleaved C code. Hmm.

After a lot of poking around, I got mixed assembly output working, but there are a lot of ".file" and ".loc" directives all over the place to deal with, which a stricter TI assembler will choke on. I want to only emit those when the "-g" option is invoked. Otherwise only straight TI code should be emitted.

Thursday, October 2, 2014

This seems like a small update, but I solved a lot of the problems I was having with the asterisk character. The problem was that gas would eat the spaces around them, making it impossible to see if the asterisk was intended as an operator or a comment delimiter.

In looking through the parsing code, I found that if defined, tc_symbol_chars could be used to indicate which characters may start a symbol. If a symbol character is found, the surrounding whitespace is preserved. This list of characters is used to handle cases like mine for other machines. If not for the comments in the parser code, I would not have even considered using tc_symbol_chars for this.

By the time I found this I was fairly far down the road of performing a parallel parsing of the input files, but preserving all spaces. That would have been a long, error prone mess. This new approach is so much cleaner.

One down side of this approach is that I need to scan through the line to see if it's OK to collapse the surrounding spaces. Another problem is that I had to remove the asterisk from the list of comment characters, since that would override the "used as part of a symbol" option. I'll have to scan each line and handle all comments myself. Oh well. No matter what, this approach will be more correct and much easier to implement than what I was doing.