On Fri, 15 Mar 2019 at 16:50, Robin Dapp <[email protected]> wrote:
>
> Hi,
>
> during the last few days I tried to get D running on s390x (apparently
> the first Big Endian platform to try it?). I did not yet go through the
> code systematically and add a version(SystemZ) in every place where it
> might be needed but rather tried to fix test failures as they arose.
>
HPPA has been somewhat ported, which is BigEndian as well. But I've
not done any testing beyond just the druntime unittests.
I still have an image available locally and a little more free time
now, so can kickstart a rebuild and start looking at the other
testsuite parts, as the same endian problems should show themselves up
there as well.
>
> After enabling the architecture in the configure files and adding TLS
> support (see initial.diff) the test suite showed 200 something failures.
>
Thanks, I was unsure what to do with the s390 port regarding TLS.
> Including big endian handling in some test cases (tests.diff), the
> number of failures went down to ~130.
>
The changes so far look reasonable, although the version conditions
are LittleEndian and BigEndian.
> Some more involved cases are left: dmd/constfold.c handles
>
> 'a' ~ "abc"
>
> but fails because 'a' is treated as int64 and only the first bytes
> are memcpy'd into the result buffer. When using a similar logic as
> used for
>
> "abc" ~ a.
>
> This works but seems a rather hacky approach (cat.diff).
>
Port::valcpy was introduced precisely for the lack of endian-neutral
code in the dmd front-end, so it looks reasonable to me. I'll send it
upstream if you have no objection to that.
> An even more hacky fix I applied for libdruntime/rt/aaA.d (align.diff)
> where algn = 0 is passed to the talign function. I suppose it shouldn't
> ever be called with algn = 0 but the alignment should be set somewhere
> else initially?
>
Alignment is written to TypeInfo, I don't think it should ever be
zero. That would mean that it isn't being generated by the compiler,
or read by the library correctly, so something else is amiss.
> Another problem is printing of characters. std.uni.isGraphical returns
> false for standard ASCII characters because of the trie traversal or
> rather the final lookup in memory via PackedPtr
>
> cast(inout(T))(cast(U*) origin)[idx]
>
> This gets the first byte but should get the last byte on Big Endian. A
> simple
>
> + ubyte[] buf = nativeToLittleEndian (origin[idx]);
> + auto val = cast(inout(T))(buf.peek!U());
>
> helps here, but has two problems:
>
> - peek!U() apparently does not work in CTFE and subsequently all
> compile-time unit tests fail.
> - simpleIndex() is called in other places and also does the wrong thing
>
> return cast(T)((origin[q] >> bits*r) & mask)
>
> Refraining from peek!... I tried working around it by extracting bytes
> and reversing the order but this seems to hacky to create a diff :)
> I got it to work for test28.d:test39() but the unit tests still fail.
>
> Is there a way to debug the compile-time unit tests easily? What's the
> preferred method to do "the right thing" even at compile time? Any other
> things that should be looked at? Any comments to the diffs so far?
>
There's pragma(msg) that can be used in user code.
i.e:
int foo() { return 42; }
enum A = foo();
pragma(msg, A); // Prints '42' at compile-time.
Otherwise, it's just stepping through CTFE in the compiler front-end
(dmd/dinterpret.c, entrypoint is interpret), and using e->toChars() /
s->toChars() to get the string representation of intermediate
expressions/values.
--
Iain