2026-07-19 02:05:11 i386 instruction encoding is pretty similar to amd64 instruction encoding 2026-07-19 02:06:54 tabemann: if you want to reduce code size without worrying about speed you can just use millicode 2026-07-19 02:07:21 not very different from subroutine-threaded Forth in the limit 2026-07-19 02:34:44 xentrac: btw, the statistics for american nuclear testing deaths I cited before was a conservative one; less conservative estimates are even as high as 340,000 to 460,000 2026-07-19 02:45:05 in the US 2026-07-19 02:45:17 so far 2026-07-19 02:45:52 the fact that the conservative to liberal estimates have a 40:1 ratio, in a country with good health-care surveillance, may be part of why people are skeptical of nuclear safety claims 2026-07-19 02:46:05 it's hard to tell how dangerous something is if you can't even tell if it killed you 2026-07-19 15:21:58 xentrac: yes, but even in a language not doing "smart" things like Forth, there are still a few more recent instructions that can be useful (shlx/shrx for LSHIFT/RSHIFT), and these have encodings that are very different from x86-32 2026-07-19 15:22:56 I decided to try to simplify my code generator by always emitting REX prefixes 2026-07-19 18:14:14 lofty: I didn't know about those! 2026-07-19 18:15:58 xentrac: less flag stomping, less cl stomping, what's not to love? aside from the VEX prefix... 2026-07-19 18:22:05 tell me how x86-64 has instructions useful for LSHIFT/RSHIFT lacking from x86? does x86 only have old 8-bitter-style single-bit shift operations? 2026-07-19 18:24:29 oh, they don't touch flags 2026-07-19 18:25:34 ACTION is used to ARM Cortex-M, where tons of things (unnecessarily) touch flags... 2026-07-19 18:28:04 tabemann: shlx/shrx also accept a register to shift by and a register to put the result in 2026-07-19 18:28:23 all useful things 2026-07-19 18:28:43 shl/shr can only use cl as the register to shift by, so if you're using rcx for something you need to spill and fill it 2026-07-19 18:29:16 so it's not that x86 can't do LSHIFT/RSHIFT, it's that with BMI2 it can do it more efficiently 2026-07-19 18:29:21 I must say that I've never thought highly of x86... 2026-07-19 18:33:22 (I can't say I have a favorite architecture though -- I dislike most architectures, but for varying reasons) 2026-07-19 18:34:02 like, X Y LSHIFT has the shift value as the top of the stack, so if you keep the top of the stack in a register - I use rbx - you need to spill rcx, move rbx to rcx, pop rbx from the parameter stack, shift rbx by cl, and then fill rcx 2026-07-19 18:34:06 I'd say that the core of RV is the nicest design I've seen, but the mistakes made by the RV people put a sour taste in my mouth 2026-07-19 18:35:30 lofty: in zeptoforth here is the implementation of LSHIFT when not using a constant shift: 2026-07-19 18:36:24 @@ Logical shift left 2026-07-19 18:36:26 define_word "lshift", visible_flag | fold_flag 2026-07-19 18:36:28 _lshift: 2026-07-19 18:36:30 movs r0, tos 2026-07-19 18:36:32 pull_tos 2026-07-19 18:36:34 lsls tos, tos, r0 2026-07-19 18:36:36 bx lr 2026-07-19 18:36:47 I do wish I had some better code generation than inlining, but even something naïve like destination-driven code generation would add a lot of complexity 2026-07-19 18:36:53 where pull_tos is: 2026-07-19 18:37:12 ldmia dp!, {tos} 2026-07-19 18:37:38 oh what I did was make a number of very simple and very common words do constant-folding 2026-07-19 18:37:55 where I not only inline them but do specialization to encode the constant in the instructions 2026-07-19 18:38:13 e.g. a constant LSHIFT will encode to: LSLS R6, R6, #x 2026-07-19 18:39:10 this saves a lot of code space and provides a significant speed boost vis-à-vis naive inlining 2026-07-19 18:39:36 note that my constant folding is hard-coded in the compiler, mind you 2026-07-19 18:41:18 (the other problem with DDCG is that I would need to know destinations - which I think in Forth means I need to infer a stack comment) 2026-07-19 18:42:08 DDCG? 2026-07-19 18:42:21 destination-driven code generation 2026-07-19 18:42:39 what's that? 2026-07-19 18:43:45 say that a function returns a value in rax. therefore, the destination register of the final operation must be rax. 2026-07-19 18:44:22 on x86-64, because most instructions are 2-op, one argument register must therefore be in rax 2026-07-19 18:44:42 and you can follow this logic backwards through the logic assigning registers and such by knowing where they need to go 2026-07-19 18:44:49 oh, you're mapping stack locations to registers? 2026-07-19 18:45:04 I'm not, but that's what would be done with DDCG 2026-07-19 18:45:06 I'm doing a much simpler approach where TOS is in R6 and everything else is in RAM 2026-07-19 20:22:11 https://cagire.raphaelforment.fr/ 2026-07-19 20:22:46 xentrac: Understood (re "yes, I agree" etc)