Sourcery CodeBench Lite for IA16 (GCC for 8086, 286)

So, this was released today, and it doesn't appear to be an April Fools joke. Supposedly, it has up-to-date C language support, so us 16-bit aficionados can finally move up to C11 and leave OpenWatcom behind.

It might only be able to produce COM binaries, so I've heard, but I haven't read too much into it.

Re: Sourcery CodeBench Lite for IA16 (GCC for 8086, 286)

No joke but perhaps a bit limited (and buggy). No huge complaints, though, just them getting this far is impressive. Hopefully it will improve further.

Quote:

Supposedly, it has up-to-date C language support, so us 16-bit aficionados can finally move up to C11 and leave OpenWatcom behind.

Seriously? What did you miss from OW19 that you direly needed? C11 wasn't that useful for DOS, was it? Or do you just mean missing C99 features (not even supported via "-za99")?

Anyways, this has better license but is inferior due to limited target/models. (BCC/Dev86 is Tiny or Small only. Not sure on Desmet, wasn't totally cleaned up and re-released. Heck, even FPC [GPL] officially supports i8086-msdos cross-target since 3.0.0 [Nov. 2015], all models except Huge [trunk only].)

Quote:

It might only be able to produce COM binaries, so I've heard, but I haven't read too much into it.

I tried my Befunge-93 interpreter, which works on almost all C89-ish compilers. -O and -O2 don't compile correctly, only -Os. Similarly -march=i80186 and -march=i80286 don't work either. I had to also comment out a call to time(), which fails trying to link nonexistent gettimeofday().

There's also probably some extreme memory limits, perhaps not enough room for needed spare memory. Linking with printf() leads to 48 kb .COM that won't run properly. Luckily I long ago gave up on that in lieu of a simple replacement ("%ld" only), which gives me 19 kb instead. That works, but only if I don't (also) malloc more than 9000*sizeof(long) or so.

Seriously? What did you miss from OW19 that you direly needed? C11 wasn't that useful for DOS, was it? Or do you just mean missing C99 features (not even supported via "-za99")?

I was just being a smartass.

Getting Started Guide wrote:

Far pointers currently do not work, so accessing memory outside the program's 64kB segment requires the use of assembly (either inline or a separate file that is assembled and then linked into the program).

IA16 GCC does have support for floating-point code, but it does not make use of an 80x87 co-processor. The library is currently quite large so non-trivial programs making use of floating-point types
may fail to link.

So yes, very limited. Maybe the April Fools joke was that it's barely usable. It's a work in progress, at least.

Hello! I'm the one responsible for unleashing this monstrosity upon the world. Yes, it does currently have some fairly severe limitations but hopefully it will be useful to somebody. I'm also working on removing those limitations (I was hoping to at least add far pointers and memory models other than tiny before release, but when one of my colleagues suggested an April 1st release last month I thought that was too good of an idea to pass up.)

Yes, ia16-elf-gcc does currently use elf32 as the intermediate format. This is not *too* bad of a hack since it is theoretically possible to link 16-bit code to 32-bit code. Unfortunately the corresponding dwarf standard for debug information doesn't allow stack offsets that are not 4-byte aligned, so there's no debugger support yet. Using elf rather than OMF as the default object format is important to allow things like link time optimization to work, but I'm hoping to add OMF support (reading and writing) to the linker at some point (I did find a patch to add enough OMF support to binutils for objdump to work). Currently the linker outputs a .com file, but .exe format output is coming.

-masm=intel is a feature of the i386 backend but I'll investigate adding it to ia16 (looks like it's not too much code). I'll take a look at adding gettimeofday() to the BSP as well.

rugxulo, if you point me to your Befunge-93 source I'll see if I can figure out what's going wrong at -O and -O2 (assuming it's not just a 64kB limit problem). Likewise with -march=i80186 and -march=i80286 (I'm afraid I haven't done much in the way of testing with those CPUs - I've been concentrating on 8088/8086).

Thanks for the feedback, and please let me know if you have any questions or feature requests!

Hello! I'm the one responsible for unleashing this monstrosity upon the world. Yes, it does currently have some fairly severe limitations but hopefully it will be useful to somebody. I'm also working on removing those limitations (I was hoping to at least add far pointers and memory models other than tiny before release,

It does (mostly) work, so that's already impressive. It's a daunting task, so I don't blame you for limitations.

Quote:

but when one of my colleagues suggested an April 1st release last month I thought that was too good of an idea to pass up.)

April 1st is (sometimes) the day for new releases of esoteric language implementations (e.g. Intercal or Befunge or ...). I guess because they are silly.

Quote:

Yes, ia16-elf-gcc does currently use elf32 as the intermediate format. This is not *too* bad of a hack since it is theoretically possible to link 16-bit code to 32-bit code. Unfortunately the corresponding dwarf standard for debug information doesn't allow stack offsets that are not 4-byte aligned, so there's no debugger support yet. Using elf rather than OMF as the default object format is important to allow things like link time optimization to work, but I'm hoping to add OMF support (reading and writing) to the linker at some point (I did find a patch to add enough OMF support to binutils for objdump to work). Currently the linker outputs a .com file, but .exe format output is coming.

FYI, not sure if it will help, but DJ Delorie had some 16-bit OMF tools here (e.g. linker, "GNUish").

Quote:

-masm=intel is a feature of the i386 backend but I'll investigate adding it to ia16 (looks like it's not too much code). I'll take a look at adding gettimeofday() to the BSP as well.

"objdump -d -M intel,i8086" still works here, IIRC.

Quote:

rugxulo, if you point me to your Befunge-93 source I'll see if I can figure out what's going wrong at -O and -O2 (assuming it's not just a 64kB limit problem). Likewise with -march=i80186 and -march=i80286 (I'm afraid I haven't done much in the way of testing with those CPUs - I've been concentrating on 8088/8086).

-O and -O2 are roughly the same output, about 22 kb (when using outint.c instead of printf). But I didn't look closely.

Anyways, I don't claim this is truly useful or good code, obviously, but it's fairly small and something I've written for fun (and p.d./FOSS): BEFI_4S.ZIP (see newb93c.txt and beftest.txt)

Quote:

Thanks for the feedback, and please let me know if you have any questions or feature requests!

My only suggestion, and this is only if you're really adventurous or bored, would be to build a native DJGPP (DOS) cross-compiler (instead of only Linux or Windows). Maybe these will help?

... gives me a .COM of 19150 bytes. Running "befunge guessnew.bef" (or faster "befunge guessnew.bef 1000") under DOSBox shows the correct output. It also passes the B93 subset of the Mycology test suite ("3-clause BSD"), which is the quasi-official test used by most good implementations.

It does (mostly) work, so that's already impressive. It's a daunting task, so I don't blame you for limitations.

Thanks! Though Rask Ingemann Lambertsen (who originally made the GCC backend 10 years ago) deserves the lion's share of the credit.

rugxulo wrote:

FYI, not sure if it will help, but DJ Delorie had some 16-bit OMF tools here (e.g. linker, "GNUish").

That might be useful as an OMF reference. What I'd really like to do is to add OMF support to gas and ld so you can link together elf+omf and output elf, omf, com or exe.

rugxulo wrote:

"objdump -d -M intel,i8086" still works here, IIRC.

Yep, and I've been using that extensively during the development of this toolchain. Even after working on GCC for 9 years I still find the Intel syntax easier to read than AT&T.

rugxulo wrote:

My only suggestion, and this is only if you're really adventurous or bored, would be to build a native DJGPP (DOS) cross-compiler (instead of only Linux or Windows). Maybe these will help?

I've thought about doing that, but I didn't think there would be anybody for whom that would actually be useful. If you're doing native development on 386+ DOS, there's djgpp. If you're doing cross-development for ia16 there's ia16-elf-gcc. A DOS hosted ia16-elf-gcc would only be useful if you're developing on 386+ DOS (since it wouldn't fit on a 16-bit machine) but targeting 8086 - a niche within a niche! I'll do if there's demand, though - it's not super difficult, but our build system at Mentor isn't set up to do it at the moment.

rugxulo wrote:

... gives me a .COM of 19150 bytes. Running "befunge guessnew.bef" (or faster "befunge guessnew.bef 1000") under DOSBox shows the correct output. It also passes the B93 subset of the Mycology test suite ("3-clause BSD"), which is the quasi-official test used by most good implementations.

Thanks - I'll take a look at this. I got the -Os version running correctly in DOSBox, but when I run it under my simulator it just outputs "103 " over and over again, so it seems I've got some simulator bugs to fix first!

I found a minor library bug by trying to run under QEMU. (BTW, DOSBox is better than nothing but far from perfect. It actually hides this bug, though.) It seems to omit printing the all-too-crucial '\r', so the output on the screen is a bit disjointed.

I hate to even mention it, surely you have your own methods of testing, but a VirtualBox tutorial (and even premade FreeDOS 1.2 VM images) are available. To me, that greatly simplifies testing (although I also native boot). Of course, every time I tell someone this, they usually just ignore me. Feel free to do the same.

Thanks - I'll take a look at this. I got the -Os version running correctly in DOSBox, but when I run it under my simulator it just outputs "103 " over and over again, so it seems I've got some simulator bugs to fix first!

Okay, fixed the simulator (my "read from file" code was broken) and tracked down the bug causing befunge to be broken at -O and -O2. There's a linker bug which makes it unable to understand one of the more complex expressions I used in the linker script. I did most of my testing with a more recent version of binutils which doesn't have this bug, but unfortunately the Mentor Graphics release used a slightly older binutils which did. I've fixed this in github now, so the fix will be in the next binary release.

rugxulo wrote:

I found a minor library bug by trying to run under QEMU. (BTW, DOSBox is better than nothing but far from perfect. It actually hides this bug, though.) It seems to omit printing the all-too-crucial '\r', so the output on the screen is a bit disjointed.

Ah, good catch. I've fixed this in github as well (fortunately I was able to reuse some of the code from the Cygwin newlib target). Yeah, DOSBox does have some rough edges but its debugger and the ability to access the host filesystem directly are really useful. I've been doing most of the testing with a little simulator I made myself that's optimized for running GCC testcases. It runs on Linux so line-ending issues aren't too surprising, but I am surprised that Windows XP's command prompt has the same problem.

rugxulo wrote:

I hate to even mention it, surely you have your own methods of testing, but a VirtualBox tutorial (and even premade FreeDOS 1.2 VM images) are available. To me, that greatly simplifies testing (although I also native boot). Of course, every time I tell someone this, they usually just ignore me. Feel free to do the same.

I almost don't want to waste your time with my inanity, but at the same time I'd like to be encouraging of this project. This is still very cool stuff!

No pressure, obviously, but feel free to occasionally keep us updated on your progress here.

reenigne wrote:

Yeah, DOSBox does have some rough edges but its debugger and the ability to access the host filesystem directly are really useful.

DOSBox is good for games (gfx, sound) but overall very limited. Even vanilla QEMU is better. Still better (and faster) is VBox (VT-X) or KVM or similar hypervisor. Of course, those can use networking (even in DOS), which makes things much more convenient. (There's a third-party DOSBox fork that allegedly supports networking too, but I never bothered trying. Similarly I don't recall if it includes a debugger by default.)

Sharing guest files between host is a pain! One guy wrote (DOS driver) VMSMOUNT for VMware. QEMU only has "fat:/" kludge. I guess you could also use GNU Mtools to copy to/from image or (as quoted above) mount .VHD under Win7's Explorer (etc). VBox can use (DOS) FTPSRV. But honestly, DOSEMU2 might be easier (Linux only, but x64 works!).

I know I'm somewhat repeating myself. It's definitely tedious and kludgy, but there are various successful ways of doing these things.

I was using dosemu for a while for the compiler test suite, but booting DOS for each of the ~200000 testcases was taking a long time - hence writing my own minimalist simulator which works great for compiler development almost all the time (most of these testcases don't do any IO other than returning a status code to say whether the test passed or not, so emulator fidelity isn't hugely important). It also does a (slightly crude but extremely repeatable) count of cycles so I can tell if my changes are actually improving things! But yes, if I get around to writing some more library support for DOS and other PC functionality then these tools may be more important for testing that.

Status update: lately I've been working on switching the calling convention to fastcall. I know I said I would do far pointers next but I hadn't touched that for a while and wanted to get back into the codebase by doing something I thought would be relatively easy and get a decent speed boost. Unfortunately I was a bit overoptimistic - trying to put parameters in AX, BX, CX and DX made the compiler fail to build libstdc++ (I know why, but I don't know how to fix it yet) so for now I'm just using AX, CX and DX and I'm still getting 1026 new errors in the testsuite. It gives a 4.5% improvement in speed and a 2.6% improvement in size, which is okay but not as much as I had been hoping for. The main problem I was trying to solve there is that the floating point library is just so big. I tried an alternate library (GCC has two different ones to choose between) but that one turned out to be even bigger, so I think I'll have to hand-write some soft-FP code in assembly to fix that problem (that's a way off, it's not a high priority).

GCC 7 should be released any day now - when it is, I'll switch over to using that which should hopefully bring some more improvements.

I was using dosemu for a while for the compiler test suite, but booting DOS for each of the ~200000 testcases was taking a long time

All the more reason to have a DJGPP hosted version! And especially if your machine supports (advanced) VT-X ("unrestricted guest mode"), that will help tremendously. It's the same era for when RDTSCP was introduced too. Yes, a bit overkill, and maybe you can live without, but it's not that far-fetched.

reenigne wrote:

Status update: lately I've been working on switching the calling convention to fastcall. I know I said I would do far pointers next but I hadn't touched that for a while and wanted to get back into the codebase by doing something I thought would be relatively easy and get a decent speed boost.

I don't blame you for working on something less annoying.

Quote:

Unfortunately I was a bit overoptimistic - trying to put parameters in AX, BX, CX and DX made the compiler fail to build libstdc++ (I know why, but I don't know how to fix it yet)

And this I don't understand. (Sorry, I didn't really peruse the docs fully, to say the least.) Are you really intending to support C++ here? I don't grok that and find it a bit unwieldy. But who knows what some crafty person could do with it. I doubt modern C++ even gives thought to anything outside of Windows, POSIX, ARM, PPC, etc.

reenigne wrote:

so for now I'm just using AX, CX and DX and I'm still getting 1026 new errors in the testsuite. It gives a 4.5% improvement in speed and a 2.6% improvement in size, which is okay but not as much as I had been hoping for.

Dare I ask the obvious, but since you're using ELF, have you considered "--gc-sections" ?

reenigne wrote:

The main problem I was trying to solve there is that the floating point library is just so big. I tried an alternate library (GCC has two different ones to choose between) but that one turned out to be even bigger, so I think I'll have to hand-write some soft-FP code in assembly to fix that problem (that's a way off, it's not a high priority).

Too many FWAIT(s)? Honestly, I don't really understand the FPU.

reenigne wrote:

GCC 7 should be released any day now - when it is, I'll switch over to using that which should hopefully bring some more improvements.

It's in rc1, last I heard. Not really sure, but I just assume DJGPP will get a port for it. Dunno if they will flip on C++17 by default (since that's also finalized nowadays). Hmmm, GCC changes says pretty much all of "c++1z" is supported, but I guess it's not default.

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum