tkchia / gcc-ia16

Fork of Lambertsen & Jenner (& al.)'s IA-16 (Intel 16-bit x86) port of GNU compilers ― added far pointers & more • use https://github.com/tkchia/build-ia16 to build • Ubuntu binaries at https://launchpad.net/%7Etkchia/+archive/ubuntu/build-ia16/ • DJGPP/MS-DOS binaries at https://gitlab.com/tkchia/build-ia16/-/releases • mirror of https://gitlab.com/tkchia/gcc-ia16
GNU General Public License v2.0
178 stars 13 forks source link

ES register preserved by function calls #14

Closed bartoldeman closed 6 years ago

bartoldeman commented 6 years ago

In the traditional DOS cdecl ABI, ES is clobbered by function calls. ia16-elf-gcc preserves it now unless you give GCC the option -fcall-used-es. Though I managed to cause an ICE with that option: I'll submit a test case later.

bartoldeman commented 6 years ago

Test case:

$ cat tst14.c
extern int foo(int, int);

struct ab {
  int a, b;
};

int bar(struct ab __far * x)
{
  x->a += foo(2, 16);
  return 16 % x->b;
}
$ ia16-elf-gcc -Os -fcall-used-es -c tst14.c
tst14.c: In function ‘bar’:
tst14.c:11:1: internal compiler error: in reload_combine_note_use, at postreload.c:1536
 }
 ^
0x84eac98 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1536
0x84eaa47 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1603
0x84eaa82 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1598
0x84eaa82 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1598
0x84eaa82 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1598
0x84eaa82 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1598
0x84eaa47 reload_combine_note_use
        ../../gcc-ia16/gcc/postreload.c:1603
0x84ec61a reload_combine
        ../../gcc-ia16/gcc/postreload.c:1386
0x84ed58f reload_cse_regs
        ../../gcc-ia16/gcc/postreload.c:68
0x84ed58f execute
        ../../gcc-ia16/gcc/postreload.c:2343
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
tkchia commented 6 years ago

Hello @bartoldeman ,

This is a really interesting bug. At first I had thought that the foo (2, 16) call --- which would clobber %es here --- was causing GCC to get confused. But when I rewrote the routine as

int bar (struct ab __far *x)
{
  return 16 % x->b;
}

I got the same compiler crash. In contrast,

int bar (struct ab __far *x)
{
  x->a += foo (2, 16);
  return x->b;
}

successfully compiles. So perhaps the division operation (divmodhi4) was interacting in some weird way with the call-used-ness of %es in the divisor term to cause the compiler crash. I will need to take a closer look at the bug.

Thank you!