IRC channel logs

2019-12-28.log

back to list of logs

<oriansj>no potential solutions? nor ideas how to address this issue?
<xentrac>I haven't done enough with golang
<xentrac>do you mean the issue of gccgo lacking 1.4, or the issue of autogenerated code?
<xentrac>if it's just a matter of a 1.3 to 1.4 gap, it seems like it's probably not hard to hack the golang version of 6g or whatever to compile in 1.3
<xentrac>but it might be more globally optimal to upgrade gccgo to 1.4
<oriansj>xentrac: I was thinking more of my current problem of figuring out good tests for scheme module support in mes-m2
<xentrac>ah. scheme has modules now?
<oriansj>xentrac: yep and it appears to need to be supported for alot of important scheme programs
<xentrac>that's real progress. I really ought to have been keeping up with this R7RS stuff
<oriansj>xentrac: but the real problem is one needs guile to bootstrap guile from human written source. Hence the need to get mes-m2 fully compatible with guile to enable solving that bootstrap problem as well.
<xentrac>because of syntax-case?
<oriansj>because of psyntax
<xentrac>right
<oriansj>xentrac: so the problem I am supposed to solve with mes-m2 is have a scheme interpreter bootstrappable from M2-Planet, that is also able to run MesCC, Guix and compatible enough to bootstrap guile. As this is a heavy problem with lots of fiddly bits, good tests are fundamental to getting there.
<oriansj>Adding guile primitives is just a simple incremental problem but major pieces like macro support and module support need to be perfect to make this all work.
<oriansj>Hence why I am having so much trouble with writing a good test for modules
<deesix>Hello!
<deesix>What's so hard about writing some code that uses modules?
<deesix>Also, no implementation has tests already? (excuse the silly questions, but I'm sure I'm missing something and I'm trying to close the gap)
<oriansj>deesix: the hard part is I need to figure out the edges of guile's behavior to ensure compatibility to write a test that hits all of them
<oriansj>it also could be me stuck in perfection mode again and not able to commit to a test because I want it to be perfect first
<deesix>I guess it's easier to go for several tests, not just one. And create more as edges are found in real world code.
<oriansj>very true
<deesix>That "real world code" being the code we care about, for the bootstrap; no more.
<oriansj>true
<deesix>Talking about testing... IIRC, M2-Planet gained support for signed types but no tests were added, right?
<oriansj>deesix: correct, I've been so stuck on mes-m2 that I never wrote a good test for signed and unsigned behavior (which would make M2-Planet match gcc in behavior)
<deesix>Fair enough. It'd be great to have some for helping me implement/validate the AArch64 target.
<oriansj>deesix: I am guessing because AArch64 is like armv7l in lacking divide instructions?
<deesix>I haven't researched anything yet, just thinking in the usual workflow I used (making the tests pass).
<oriansj>deesix: well dddddd is currently working on the AArch64 port of M2-Planet
<deesix>Oh, sorry... I'm dddddd.
<oriansj>got it
<oriansj>well the good news is one can simply just copy the unsigned instructions to pass the current tests
<oriansj>but it would be wise to add another test, which tests for the behavior of signed operations one at a time.
<oriansj>now if you look at promote_type in cc_core.c you'll see the behavior is first match and if you look at initialize_types in cc_types.c; that the types are defined in the order void->unsigned long->long->unsigned->int->char*->char->FILE->FUNCTION
<oriansj>to get the signed path simply use int or long and to get the unsigned path just use SCM or unsigned
<deesix>Correct, using the same code for both parameters of the new arithmetic_recursion() does not break the tests, kind of unexpected.
<deesix>From commit dea4f902b729:
<deesix>-DEFINE MULTIPLY_eax_by_ebx_into_eax F7E3
<deesix>+DEFINE MULTIPLY_eax_by_ebx_into_eax F7EB
<deesix>+DEFINE MULTIPLYS_eax_by_ebx_into_eax F7E3
<deesix>For other operations you just added the signed part, but for multiply the assumption seem to be different (that before the commit, the operation was unsigned being multiply the exception).
*deesix looks at the /interesting/ knight diff
<deesix>... there, div & mod were unsigned before the commit
<deesix>*only div & mod
***ng0_ is now known as ng0
<deesix>So, it seems to me that we're really lacking tests for unsigned instead of tests for signed.
<deesix>Maybe a bit on both sides, but I was thinking that you added signed but now I'm starting to understand that is a bit more complex than that.
*deesix refocus and approach it againg thinking "unsigned is the new feature"
<deesix>*again
<oriansj>deesix: well the behavior differences in gcc for signed and unsigned for addition and subtraction never occurred (eg unsigned i = -1;)
<oriansj>the reason that division was unsigned be default is because of the implementation of hex2 required the unsigned division to produce the correct results for x86 labels
<oriansj>on x86 unsigned and signed multiplication produced the same output on the range of numbers being used. So you are correct in that unsigned is the new feature with that change
<oriansj>as mes-m2 required both signed and unsigned divsion behavior to comply with guile's expected behavior given the same inputs; to save the complexity, I just simply made M2-Planet do the correct thing for all operations instead. (even though it doesn't depend upon divisioin of anykind internally but rather bit shifts and masking to make it easier to bootstrap on Relay/TTL implementations)
<deesix>I see, so what the changelog tells is just a simplification.
<deesix>+Added support for signed multiplication, division and modulus
<oriansj>correct
<oriansj>we are just lucky that no architectures are little bit-endian because that would be real trouble
<oriansj>(or more precisely no suriviving architectures are little bit endian)
***freedom is now known as gnufr33d0m
<oriansj>as per the previous question, should M2-Planet v1.x support switch statements
<deesix>I'd say no unless required by some piece of the bootstrap puzzle. Do you have any use in mind?
<oriansj>deesix: no; but I know people want it and it is frequently used in schemes for performance enhancing tricks
<deesix>In AArch64 MUL is an alias of MADD. MADD is unsigned (notice the use if UInt in documentation/reference pseudocodes). This is not the first time I look into the multiplication family of instructions but I can't find one for signed operands. Any hints? For division it's clear (UDIV & SDIV). What am I missing? Some 2-complement arith property?
<deesix>I'd like something like SMUL Xd, Xm, Xn
<deesix>SMULL Xd, Wn, Wm is the closest one, but uses only 32bits of the registers (the "W" part).
<oriansj>deesix: well there isn't a difference if one doesn't care about the top half of the multiplication
<oriansj>aka one only has different signed and unsigned multiplication if one expects to extend to more bits in the register later
<oriansj>so there is a possiblity that AArch64 might require developers to just do the wrong thing.
<oriansj>and always use unsigned multiply
<oriansj>(32bitx32bit=>64bit)
<deesix>Yeah, for the overflow 64x64=>128bits there's SMULH, UMULH... which increases my confusion about the signedness of MUL. There's an example in ARM doc 100898_0100_en.
<deesix>wikipedia: """two's complement has the advantage that the fundamental arithmetic operations of addition, subtraction, and multiplication are identical to those for unsigned binary numbers (as long as the inputs are represented in the same number of bits - as the output, and any overflow beyond those bits is discarded from the result)"""
<deesix>That rings some bells indeed.
<oriansj>indeed
<xentrac>most CPUs with multiplication do have an instruction that provides a full-width result even if it doesn't fit in registers
<xentrac>they just put it in two registers
<deesix>I think that's the case here, xentrac, with a combo of MUL then (for the overflowing part) SMULH/UMULH. What confuses me is that there's only MUL (which I guess is valid for both signed and unsigned combos) (?)
<oriansj>deesix: it is only valid if they don't extend the register size at all (ever)
<oriansj>otherwise they will run into the same issue that SPARC did when they moved to 64bits
<deesix>I don't think it changes any size, I only see the possibility of a ZeroExtend in the "X[] - assignment form" in the final line (X[d] = result<destsize-1:0>;) of the underlying MADD.
<deesix>Page 742 of DDI 0596 ID091318
<deesix>In any case, I don't understand the "assert n >= 0 && n <= 31;" in page 1651 (where X[] is documented)
<oriansj>deesix: overflow for signed is generally undefined in C
<deesix>OK. So, to wrap up: my actual plan is to take care of division and modulo and leave the rest untouched. I even like to don't repeat code (avoid using arithmetic_recursion() if both arguments are equal). Is that fine?
<deesix>I think it makes obvious that there's no different handling for signed/unsigned, instead of read carefully both args only to discover they are the same.
<oriansj>deesix: a reasonable approximation of correct is fine. We can always change it later if we need to