<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: dzaima</title><link>https://news.ycombinator.com/user?id=dzaima</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 15 Oct 2026 04:04:12 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=dzaima" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by dzaima in "your C is not standard C"]]></title><description><![CDATA[
<p>> gcc, however, always defines FLT_ROUNDS to 1<p>Well, considering that gcc doesn't support the FENV_ACCESS pragma, and as such all fesetround calls are always UB, it is valid for it to act as if the rounding mode never changes from the default :)</p>
]]></description><pubDate>Thu, 15 Oct 2026 01:50:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=50098144</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=50098144</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50098144</guid></item><item><title><![CDATA[New comment by dzaima in "Who is vfmaddrnd231pd?"]]></title><description><![CDATA[
<p>Have to be rather careful with such - e.g. an x86 vaddpd or an ARM fadd aren't commutative because of NaN bit patterns (even worse for fma, esp. if you have it automatically choose the operation from which arg it's destructive over).<p>Perhaps not significant for writing code (though maybe someone does want the NaN bit pattern to be taken from a specific arg!), but is one aspect that can easily go missing in a higher-level assembler (or esp. disassembler).</p>
]]></description><pubDate>Tue, 13 Oct 2026 18:04:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=50075984</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=50075984</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50075984</guid></item><item><title><![CDATA[New comment by dzaima in "Float and integer arithmetic follow two different paradigms"]]></title><description><![CDATA[
<p>Except gcc doesn't actually support it to any sane extent (it ignores and warns on "#pragma STDC FENV_ACCESS ON", which C requires for fenv.h to actually function; and as such gcc makes a bunch invalid optimizations); clang supports it, but only as of somewhat-recently.</p>
]]></description><pubDate>Thu, 08 Oct 2026 16:14:52 +0000</pubDate><link>https://news.ycombinator.com/item?id=50007688</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=50007688</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50007688</guid></item><item><title><![CDATA[New comment by dzaima in "Fearless SIMD v1.0"]]></title><description><![CDATA[
<p>Stop the presses! 5 instructions!<p><pre><code>    vpor        xmm2, xmm0, 0x80000000
    vpcmpeqd    xmm2, xmm1, xmm2
    vcmpunordps xmm2, xmm2, xmm0
    vminps      xmm0, xmm1, xmm0
    vblendvps   xmm0, xmm0, xmm1, xmm2
</code></pre>
yay for superoptimizers</p>
]]></description><pubDate>Sat, 26 Sep 2026 13:07:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=49856166</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49856166</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49856166</guid></item><item><title><![CDATA[New comment by dzaima in "Fearless SIMD v1.0"]]></title><description><![CDATA[
<p>That vminpd+vminpd+vorpd actually does handle signed zero properly! Screws up NaN payloads to the max though. Can be easily extended to canonicalize the NaN with 2 instrs + constant though of course. (which ends up at the same number of instrs as your proper impl (albeit with worse port distribution and latency), but you get to have a canonical NaN!)<p>Hit upon <a href="https://github.com/llvm/llvm-project/issues/217376" rel="nofollow">https://github.com/llvm/llvm-project/issues/217376</a> while playing around with proper minimumnum, failing to SMT-verify whatever version of LLVM I had; did find a funky working 6-instr (+ constant) version though:<p><pre><code>    vpandn      ymm2, ymm1, ymm0
    vpcmpeqd    ymm2, ymm2, 0x80000000 # whether ymm0 is -0 and ymm1 is +0 (or other cases that magically don't cause issues)
    vcmpltpd    ymm3, ymm0, ymm1
    vcmpunordpd ymm3, ymm3, ymm1 # regular NaN-is-larger ymm0<ymm1
    vpor        ymm2, ymm2, ymm3
    vpblendvb   ymm0, ymm1, ymm0, ymm2</code></pre></p>
]]></description><pubDate>Fri, 25 Sep 2026 20:17:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=49849374</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49849374</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49849374</guid></item><item><title><![CDATA[New comment by dzaima in "Looking forward to Git 2.56 – and 3.0"]]></title><description><![CDATA[
<p>> they're going through the pain of changing the hash function<p>They've <i>already</i> gone through the pain, deciding on it on 2018[0] (and functional & non-experimental 3 years ago per TFA). What's left is just changing the default (and some stragglers to complete support). Changing the function now would push back changing the default by a couple additional years until the new git version gets widespread deployment (incl. on LTS distros and whatnot).<p>[0]: <a href="https://github.com/git/git/commit/0ed8d8da374f648764758f13038ca93af87ab800" rel="nofollow">https://github.com/git/git/commit/0ed8d8da374f648764758f1303...</a></p>
]]></description><pubDate>Tue, 22 Sep 2026 16:23:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=49803804</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49803804</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49803804</guid></item><item><title><![CDATA[New comment by dzaima in "Microcode in Intel's 8087 floating-point chip: the scale instruction"]]></title><description><![CDATA[
<p>Except the ALU isn't actually 64-bit, it's 67-bit as per article, extra bits for rounding. I'd imagine it was just taken for "prettiness", with 15 bits for exponent being basically reasonable. (maybe some algorithms which double precision per iteration would like it being a power of two? but any such probably vary significantly on initial estimate precision anyway)</p>
]]></description><pubDate>Sun, 13 Sep 2026 20:32:25 +0000</pubDate><link>https://news.ycombinator.com/item?id=49688377</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49688377</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49688377</guid></item><item><title><![CDATA[New comment by dzaima in "Working with Git Worktrees in Magit"]]></title><description><![CDATA[
<p>Or "--ignore-other-worktrees" for "git switch".<p>This leaves things in a weird state though, as modifying the branch from one of the worktrees will effectively change the ref the other is pointing to, but won't update the other's working tree, making it look like it's preparing to revert all the changes that the first worktree made.<p>(obligatory mention of jj, whose workspaces track what state they were snapshotted at, thus never losing what the true diff of a workspace should be, allowing a "jj workspace update-stale" to safely update the working copy with whatever the other workspaces changed (if you change the working copy <i>and</i> in parallel from another workspace change what that workspace points to, you'll get a saved commit of the working copy changes before being updated, which you'll need to squash/rebase wherever those changes were needed))</p>
]]></description><pubDate>Fri, 11 Sep 2026 15:13:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=49659849</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49659849</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49659849</guid></item><item><title><![CDATA[New comment by dzaima in "Replacing a Rust Enum with a 64-Bit Word Made My Interpreter 17% Faster"]]></title><description><![CDATA[
<p>How so? It's replacing multiple enum <i>variants</i>, but just one enum, "enum Value".<p>(also; if anything, the title is implying the exact opposite of "Rust compiler was able to optimize ...", "Replacing a Rust [...] with [...]" is clearly moving away from Rust-magic to something else)</p>
]]></description><pubDate>Tue, 08 Sep 2026 21:48:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=49617590</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49617590</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49617590</guid></item><item><title><![CDATA[New comment by dzaima in "Replacing a Rust Enum with a 64-Bit Word Made My Interpreter 17% Faster"]]></title><description><![CDATA[
<p>Unless the highly-optimized parts are wrapped by an interface that looks similar to the non-optimized version.<p>In the case of a tagged object in Rust, depending on how well the compiler can wrangle through it, you might even be able to add a `.unpack()` method that returns a pretty enum from a packed value, that you can pattern-match on or whatever, and let the compiler remove all the code of unpacking unused cases.<p>(using that directly for the addition example would end up less efficient of course, but still most likely beneficial. It's <i>after</i> this when there's a potential true readability vs performance tradeoff)</p>
]]></description><pubDate>Tue, 08 Sep 2026 19:51:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=49615993</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49615993</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49615993</guid></item><item><title><![CDATA[New comment by dzaima in "bzip3"]]></title><description><![CDATA[
<p>> That always seemed annoying to me. They couldn't allocate 5 more bits somewhere to let the decompressor autodetect longer window sizes?<p>I believe this is just to prevent the decompressor from arbitrarily blowing up memory usage based on the input; I think if you want to accept long windows you can just always decompress with --long=63 regardless of whether the input needs it? (you <i>will</i> run out of RAM decompressing a long=63 file though of course)</p>
]]></description><pubDate>Mon, 07 Sep 2026 16:00:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=49599809</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49599809</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49599809</guid></item><item><title><![CDATA[New comment by dzaima in "GrapheneOS says Pixel 11 has MTE support after all"]]></title><description><![CDATA[
<p>Heh, you can kinda think of MTE as ASan except instead of a small range of a guaranteed redzone around heap pointers, it's a massive `2^56 * (random number, ≥0, on average 15)`-byte "redzone" (and some padding up to a multiple of 16 bytes which can predictably hide a bug, though at least such a bug won't corrupt unrelated heap). Stack handling is a significant difference though.</p>
]]></description><pubDate>Wed, 02 Sep 2026 18:56:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=49540743</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49540743</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49540743</guid></item><item><title><![CDATA[New comment by dzaima in "The creator of Jujutsu has joined ERSC"]]></title><description><![CDATA[
<p>Cleaning it would change the commit ID, so a forge cannot clean it even if it wanted to (not without rewriting all descendant commits too and breaking signed commits, at least).<p>The change-id is exactly as much part of the commit object as the author/committer name/timestamp, description, parent commit ID, tree, and participates in the commit hashing as those do.</p>
]]></description><pubDate>Wed, 02 Sep 2026 06:47:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=49532614</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49532614</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49532614</guid></item><item><title><![CDATA[New comment by dzaima in "The creator of Jujutsu has joined ERSC"]]></title><description><![CDATA[
<p>Technically, you can still tell actually - jj writes a "change-id xyz..." in the git commit object header, which remains there as it's pushed around. It's just typically not made visible by regular things. (I wonder what other random garbage has been hidden in git commit headers that noone has seen)</p>
]]></description><pubDate>Tue, 01 Sep 2026 23:20:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=49529655</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49529655</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49529655</guid></item><item><title><![CDATA[New comment by dzaima in "Luanti removed from Google Play due to baseless AI copyright notice"]]></title><description><![CDATA[
<p>The things/concepts that those screenshots have that infiniminer (a voxel game made before minecraft) doesn't is... grass, trees, glass. I hate to bring it to you, but minecraft didn't invent those. And it certainly didn't invent the concept of a voxel world (not that it could even copyright that if it did).<p>Never mind that the things in those in-game screenshots aren't even in the play store app, they're separately downloadable things.</p>
]]></description><pubDate>Fri, 28 Aug 2026 14:08:02 +0000</pubDate><link>https://news.ycombinator.com/item?id=49478726</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49478726</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49478726</guid></item><item><title><![CDATA[New comment by dzaima in "RISC-V: They Should Have Known Better"]]></title><description><![CDATA[
<p>That is quite a good bit more evenly-spread (the "..." is 5159 instrs).<p>Wonder what's up with bit 21; if whatever uses it so much is repositionable (and not an aarch64-specific thing), could save like 2KB on x86-64 via putting it in the low 8 bits instead.</p>
]]></description><pubDate>Sun, 16 Aug 2026 12:48:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=49319554</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49319554</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49319554</guid></item><item><title><![CDATA[New comment by dzaima in "RISC-V: They Should Have Known Better"]]></title><description><![CDATA[
<p>Some stats on an aarch64 binary of my current main project (1.6MB .text, 6600 symbols as per whatever "nm the-binary | wc -l" includes, from "objdump -d the-binary"):<p><pre><code>    19546 /tbn?z/
    18029 /tbn?z.*, #0x0/  (but this includes boolean checks)
      224 /tbn?z.*, #0x1f/ (i.e. 32-bit x<0)
     1139 /tbn?z.*, #0x3f/ (i.e. 64-bit x<0)
      154 other immediates
</code></pre>
Said project doesn't do fixed bitfields much (there are some, but a chunk of those test multiple bits) so unsurprisingly not much. (I could imagine that the kernel has significantly more, but it's an edge-case (though perhaps an important one) of being basically massive amounts of fixed configurable glue)</p>
]]></description><pubDate>Sun, 16 Aug 2026 10:44:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=49318815</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49318815</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49318815</guid></item><item><title><![CDATA[New comment by dzaima in "RISC-V: They Should Have Known Better"]]></title><description><![CDATA[
<p>Both clang and gcc do actually generate TBZ/TBNZ for checking a bool: <a href="https://godbolt.org/z/K6evhaxGT" rel="nofollow">https://godbolt.org/z/K6evhaxGT</a></p>
]]></description><pubDate>Sun, 16 Aug 2026 06:16:57 +0000</pubDate><link>https://news.ycombinator.com/item?id=49317356</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49317356</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49317356</guid></item><item><title><![CDATA[New comment by dzaima in "RISC-V: They Should Have Known Better"]]></title><description><![CDATA[
<p>Some more:<p>> The spec says that bit must be zero, and yet no encoding uses the space opened up by that bit being one.<p>The spec says "the code points with shamt[5]=1 are designated for custom extensions.", so the space is specifically reserved for custom vendor extensions.<p>So, if I wanted to add a custom "dzaima.c.clear_top_n_bits rd, imm5" instruction, that's space I could safely put it in, knowing that no future standard instruction will be added there that I may regret overlapping. So while that space goes unused in the standard, its existence helps with the overlapping encoding problem!<p>> For I-type instructions, bit 1 [...], bit 11<p>Of course, that's cherry-picking two of the 25% of bits that have multiple positions they come from, and specifically 11 as it's the worst one. Full stats:<p><pre><code>    1 position: 24 bits: (everything that's not listed below)
    2 positions: 7 bits: 0, 1, 2, 3, 4, 12, 20
    3 positions: 1 bits: 11 (the single worst case)
</code></pre>
So that's like 9 muxes for merging all immediates to the same place (or less of course if the different encodings' immediates go to different places), the rest is just wires.<p>Obligatory note is that some of the funkiness is to place the sign-extended bit in the same bit position, so some saved muxes from that.<p>Now, I am a "software person who's never written verilog", but I highly doubt a 3:1 mux is as cheap as a 2:1 mux in silicon, so even if you always need to merge in the sign bit, reducing the number of cases is still beneficial.<p>Compressed does make it a ton more ugly though (combining both 32-bit and 16-bit instruction encodings, placing the 16-bit ones in the low 16 bits):<p><pre><code>    1 position: 13 bits
    2 positions: 7 bits: 10, 13, 14, 15, 16, 17, 20
    3 positions: 4 bits: 3, 4, 9, 12
    4 positions: 5 bits: 0, 1, 2, 5, 11
    5 positions: 3 bits: 6, 7, 8
</code></pre>
looking at aarch64 on <a href="https://asmjit.com/asmgrid/" rel="nofollow">https://asmjit.com/asmgrid/</a>:<p><pre><code>    tbz Xt, #imm, #relS*4   imm:1|0110110|imm:5 |    relS:14 |Rt
    lsl Xd, Xn, #n            1   1010011|01|immr:6|imms:6|Rn|Rd
</code></pre>
Fun! (lsl being a subset of the bitfield extract instrs is neat; tbz's similar-functionality 6-bit field is just entirely-differently placed though. Also.. using the Rd slot for an input-only Rt? that's one thing RISC-V doesn't do, even across compressed and 32-bit instrs!)</p>
]]></description><pubDate>Sat, 15 Aug 2026 21:56:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=49314686</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49314686</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49314686</guid></item><item><title><![CDATA[New comment by dzaima in "RISC-V: They Should Have Known Better"]]></title><description><![CDATA[
<p>Random minor-ish notes:<p>- A big problem with extension detection RISC-V has is that there's no central authority mandating vendors to not overlap things (obviously, given RISC-V being an open standard), so basic bitmasks for supported extensions is generally rather problematic (and of course even if you collected a standardized bitmask of all extensions from all vendors, it'd grow quite massive quite quickly); you'd at least want some grouping/marking by vendor, if not full extension strings. That said, it would be nice to at the very least have some standard in-memory blob format if nothing else, that you could query from any OS/libc. (which maybe somewhat-exists to some extent with a C API meant for libc, but as-is still doesn't attempt to figure out vendor extensions).<p>- many, if not the vast majority, of aarch64 TBZ/TBNZ are probably branching on a boolean; something RISC-V can also of course do in one instruction. Generally, comparing instruction frequencies across ISAs is messy if not approximately meaningless due to different sorts of things existing for solving the same tasks.<p>- "Having this happen means that instead of a clearly-understandable crash you get ... well ... anything." - RISC-V will do you one better - it doesn't even guarantee a crash when an instruction isn't defined at all! Overlapping extensions is definitely messy for disassembly, sure, but that's also just basically unavoidable as long as RISC-V is open (see my first point). (perhaps there could've been stricter rules for reserved-for-standard encodings than reserved-for-vendor ones? of course still doesn't help vendor encodings, nor non-compliant vendors)</p>
]]></description><pubDate>Fri, 14 Aug 2026 22:09:47 +0000</pubDate><link>https://news.ycombinator.com/item?id=49305195</link><dc:creator>dzaima</dc:creator><comments>https://news.ycombinator.com/item?id=49305195</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49305195</guid></item></channel></rss>