Hi.

I am currently porting the x64 version of PDOS-generic,
a mini Windows clone (available at pdos.org, start with
makebios.leb in sourceforge), to EBCDIC.

So I am using the -fexec-charset option of gcc 15.2.0.
Debian Linux x64 is the only one I have (MacOS doesn't,
Debian Linux ARM64 doesn't) with an iconv that can
convert from UTF-8 to IBM1047.

It is going very well, and I can do:

./bios.exe pdos fba1b1.vhd
(extracted from zpg.zip)

And do:

type test.c
("dir" doesn't work currently btw)

And get my sample C program in EBCDIC to display.
Except all the lines run together, because it uses x'15'
as the newline character, while the result of iconv was
just linefeed, x'25'.

I made a quick change to charset.cc to fix this issue,
and just thought I'd document it, in case anyone is
interested.

$ cat doit
./xgcc -S -O0 -funsigned-char -fexec-charset=IBM1047 foo.c
cat foo.s

$ cat foo.c
int foo(int flag)
{
return flag ? '0' : '\n';
}

Original has 240 for character '0', which is x'F0',
which is correct. And 37 for '\n', which is x'25', which
is incorrect depending on definition.

$ cat foo.bad
.file "foo.c"
.text
.globl foo
.def foo; .scl 2; .type 32; .endef
.seh_proc foo
foo:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
.seh_endprologue
movl %ecx, 16(%rbp)
cmpl $0, 16(%rbp)
je .L2
movl $240, %eax
jmp .L4
.L2:
movl $37, %eax
.L4:
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 15.2.0"


After making this change to libcpp/charset.cc:

$ cat diff.txt
654a655,657
>       char *out_before = outbuf;
>       char *out_after;
>       char *out_p;
655a659,664
>       out_after = outbuf;
>       while ((out_p =
>               (char *)memchr(out_before, 0x25, out_after - out_before)) != 
> NULL)
>       {
>           *out_p = 0x15;
>       }

I've made the modified file available at:

https://pdos.org/charset.cc

too.

I now get decimal 21, x'15', as I am after:

$ cat foo.good
.file "foo.c"
.text
.globl foo
.def foo; .scl 2; .type 32; .endef
.seh_proc foo
foo:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
.seh_setframe %rbp, 0
.seh_endprologue
movl %ecx, 16(%rbp)
cmpl $0, 16(%rbp)
je .L2
movl $240, %eax
jmp .L4
.L2:
movl $21, %eax
.L4:
popq %rbp
ret
.seh_endproc
.ident "GCC: (GNU) 15.2.0"


And my "type" command now produces nice output.

BFN. Paul.

Reply via email to