Post AtHgufSICQPq3doxKy by me_@sueden.social
(DIR) More posts by me_@sueden.social
(DIR) Post #AtHgueE4lnRwFGA5XU by mpweiher@mastodon.social
2025-04-20T06:06:12Z
0 likes, 0 repeats
So golang has a machine-independent assembler. Which is very cool, and yes, machine instruction sets for modern machines are very similar: ALU instructions, memory load/store, branches.However, it appears that this machine-independent instruction set is not actually used by the compiler's code generator. Instead it has completely machine-specific backends, with all the extra effort that entails.Anybody know why?
(DIR) Post #AtHgufSICQPq3doxKy by me_@sueden.social
2025-04-20T08:18:56Z
0 likes, 0 repeats
@mpweiher That’s probably a relic of the compiler’s heritage - they were derived from the Plan 9 C compilers, which also used that intermediate assembler format and left instruction selection for the target architecture (mostly) to the linker.
(DIR) Post #AtHgugY08gZnRdV1sG by mpweiher@mastodon.social
2025-04-20T12:16:42Z
0 likes, 0 repeats
@me_ With that heritage, I would expect the opposite: that the go compiler *does* use the machine-independent assembler. If not the ASCII syntax, but the binary representation.But it does not.At least as far as I can tell.As far as I can tell, each of the backends goes directly to the target machine, without the machine-independent assembler.
(DIR) Post #AtHguhbwBXJqk8LgeG by me_@sueden.social
2025-04-20T13:33:19Z
0 likes, 0 repeats
@mpweiher Maybe that's a misunderstanding. Plan9's C compilers never generated completely machine-independent output.I built some example intermediate assembler outputs generated from this simple and stupid C program using the Plan9 C compiler:int main(void) { int i,j; for (i=1; i<42; i++) if (i%3) j+=i; return j;}
(DIR) Post #AtHguifAH1Uk0QrmJk by me_@sueden.social
2025-04-20T13:35:00Z
0 likes, 0 repeats
@mpweiher Using 8c (32-bit x86, uses x86 register names): TEXT main+0(SB),0,$12 MOVL j+-8(SP),BX MOVL $1,CX JMP ,4(PC) JMP ,2(PC) JMP ,12(PC) INCL ,CX CMPL CX,$42 JGE ,-3(PC) MOVL CX,AX CDQ , MOVL $3,.safe+-12(SP) IDIVL .safe+-12(SP), CMPL DX,$0 JEQ ,2(PC) ADDL CX,BX JMP ,-12(PC) MOVL BX,AX RET , RET , END ,
(DIR) Post #AtHgujKHo8O83y6cPg by me_@sueden.social
2025-04-20T13:35:43Z
0 likes, 0 repeats
@mpweiher With 5c (32-bit ARM): TEXT main+0(SB),0,$8 MOVW j-8(SP),R6 MOVW $1,R1 MOVW R1,R4 B ,4(PC) B ,2(PC) B ,12(PC) ADD $1,R4,R4 CMP $42,R4, BGE ,-3(PC) MOVW R4,R2 MOVW $3,R5 MOD R5,R2 CMP $0,R2, MOVW.NE R4,R1 ADD.NE R4,R6,R3 MOVW.NE R3,R6 B ,-12(PC) MOVW R6,R0 RET , RET , END ,
(DIR) Post #AtHguk1BEehQD0AsGu by me_@sueden.social
2025-04-20T13:36:34Z
0 likes, 0 repeats
@mpweiher With kc (32-bit SPARC): TEXT main+0(SB),0,$12 MOVW j-8(SP),R13 MOVW $1,R11 JMP ,4(PC) JMP ,2(PC) JMP ,10(PC) ADD $1,R11,R11 CMP R11,$42 BGE ,-3(PC) MOVW $3,R12 MOD R12,R11,R9 CMP R9,$0 BE ,2(PC) ADD R11,R13,R13 JMP ,-10(PC) MOVW R13,R7 RETURN , RETURN , END ,
(DIR) Post #AtHgukVfPJ5NjYRDn6 by me_@sueden.social
2025-04-20T13:37:25Z
0 likes, 0 repeats
@mpweiher ...qc (32-bit PPC): TEXT main+0(SB),0,$8 MOVW j-8(SP),R9 MOVW $1,R7 BR ,4(PC) BR ,2(PC) BR ,9(PC) ADD $1,R7,R7 CMP R7,$42 BGE ,-3(PC) MOVW $3,R8 REMCC R8,R7,R5 BEQ ,2(PC) ADD R7,R9,R9 BR ,-9(PC) MOVW R9,R3 RETURN , RETURN , END ,
(DIR) Post #AtHgukyjfEL1Bi2R6G by me_@sueden.social
2025-04-20T13:38:43Z
0 likes, 0 repeats
@mpweiher and vc (32-bit MIPS) as the last one, here you see "HI" used as a MIPS-specific register: TEXT main+0(SB),0,$8 MOVW j-8(SP),R7 MOVW $1,R5 JMP ,4(PC) JMP ,2(PC) JMP ,10(PC) ADDU $1,R5,R5 SGT $42,R5,R2 BEQ R2,-3(PC) MOVW $3,R6 DIV R6,R5, MOVW HI,R3 BEQ R3,2(PC) ADDU R5,R7,R7 JMP ,-10(PC) MOVW R7,R1 RET , RET , END ,
(DIR) Post #AtHgulYXW6ygykn1uK by me_@sueden.social
2025-04-20T13:47:47Z
1 likes, 0 repeats
@mpweiher All of these are superficially very similar, but there are already some optimizations done in the compiler stage, e.g. using "INC" on x86 instead of adding 1 on the RISC architectures. But this is not a higher-level representation e.g. on the level of LLVM IR. Some stuff is unified, "such as left-to-right assignment order for instruction operands and the synthesis of macro instructions such as MOVE" (from [1]).[1] https://9p.io/sys/doc/asm.html
(DIR) Post #AtHguwlhpV2tkm2CSO by me_@sueden.social
2025-04-20T13:49:06Z
0 likes, 0 repeats
@mpweiher There's an example of the abstraction level given in [2]:"For example, on the 68020 the object file may specify a MOVE instruction but the loader will decide just which variant of the MOVE instruction — MOVE immediate, MOVE quick, MOVE address, etc. — is most efficient."Indeed, it's pretty weird at first sight...[2] https://9p.io/sys/doc/comp.html