Gingerbill: Odin's inline assembler is best in any language
Developer argues Odin's type-checked, integrated inline assembly outperforms GCC, Clang, and Rust.
What to know
- Gingerbill argues Odin's custom inline assembler integrates type checking and respects the host language's semantics, unlike string-based approaches in GCC, Clang, Rust, and Go.
- The core claim: most languages treat assembly as an escape hatch with minimal compiler involvement; Odin designed it as a first-class language feature.
- Commenters challenge the technical definitions—whether multi-backend instruction generation is truly assembly, and what 'typed' means in assembly contexts.
The dispute Whether Odin's system, which generates different instructions on different backends, qualifies as assembly at all or should be classified as a compiled language. · positions read across 59 posts and comments
Odin's cross-backend code generation disqualifies it as assembly—it's a compiled language, not an assembler.
-
“Did I understand correctly that Odin defines a "move" operation that generates separate Load and Store instructions on arm64? That's a compiled language.”
Leverkaas2516 · Reddit
The definitions of 'assembly' and 'typed' in this context are semantic rather than settled—valid generic assembly is inherently typed under certain definitions.
-
“I am saying any (valid) generic assembly is also typed. Provided certain definitions of "typed".”
Ameisen · Reddit
“The body is a string. "=r" and "r" are explicit constraint strings, another little stringly-typed DSL glued to the side of the real DSL.”
Gingerbill · gingerbill.org article
Gingerbill Odin language designer
The record 3 articles and posts · last 30 days
- summary covers to here · Aug 20, 7:09 PM · 1 piece above arrived after
What people are saying 24 voices from 3 sites · best of 59 · verbatim
- Aug 23
-
I think it gets very confusing when you move between the notion of types of program variables: "how should I interpret the 64 bit value in R2" and the type of an assembly instruction and its effect "R1 is modified to have the value currently in R2", which does things like annihilate the previous value of R1, and could have been masked to 32 bits…
- Aug 22
-
One of the problems with smart inline assembly syntax like this is that it turns out to be less helpful in a lot of practical inline assembly.If you look at the way, say, the Linux kernel uses inline assembly, it really just wants the inline assembly to pass directly to the assembler. There's a lot of assembler directives in the inline ASM to do…
-
I feel like this article means well, but assembly or machine level types are not the same. Sure, the assembler and cpu will execute the instruction with the given type, but the next instruction can use a different instruction with different types and no one will be any the wiser. So one operation’s uint64 is another operation’s int64.The type data…
-
>Assembly is usually considered the perfect example of such an “untyped” language.>However, every instruction has a set of valid forms. Each form dictates the kind of each operand (register, memory, immediate, label), the class of each register...So if I lea that means the type is pointer. If I add it's an int. If I print it's some kind of char.So…
-
The correct assembly syntax is a matter of convention and personal preference – not a category error.Historically, some ISA's have adopted the «src, dst» convention, whilst others have preferred «dst, src». We should be grateful that no engineer, in a moment of excessive creativity, attempted boustrophedon – a conceptual device solely appropriate…
-
Following the vendor syntax may be useful if you only ever program in assembly for only a single target ISA.Otherwise, all the vendor syntaxes are different and all of them have many ugly quirks, for various historical reasons.If you ever have to write assembly for at least 2 ISAs, e.g. x86-64 and Aarch64, then it is much more productive to use a…
-
Here's how D does it for the x86_64:https://github.com/dlang/dmd/blob/master/druntime/src/core/i...It's the statement form, uses Intel syntax, and the compiler keeps track of which registers are modified.
- Aug 21
-
This article is really about the inline assembly syntax developed for the author's programming language Odin (and definitely nothing about TALs, typed assembly languages). There are a lot of interesting ideas here.One of my criticisms, however, is simply pointing to how similar mainstream general purpose CPU architectures have become; they are all…
-
> AT&T bakes the width into the mnemonic (movb, movw, movl, movq [...] Intel’s syntax is to prefix the memory operand with byte, word, dword, or qword, but Odin’s just uses the Odin type system directly.In GAS you can skip the width suffix from the mnemonic, and in most Intel assemblers you can skip the memory type operators like byte. They…
-
> How do you think GCC's/Clang's inline assembly currently works? GCC's originally was implemented as basically printf. It emitted the fragment into the assembly that it generated (GCC always emitted assembly, GAS assembled it). When they are doing register allocation, they will spill to make space for the registers that are live in the block…
-
The advantage of intrinsics is that they permit optimizations. The compiler can constant-fold them, optimize shuffles for the target architecture, etc.; Clang/LLVM does this. The disadvantage of intrinsics is that they permit optimizations. The compiler can constant-fold them and generate completely different instructions than specified by the…
-
It can insert stack spills in the middle of inline asm blocks? That's... problematic.
-
They additionally encode semantic intent. So optimizers can reason about their composition to produce better code, not just the specific instruction the intrinsic initially wanted. e.g. converting `_mm_xor_si128(a, _mm_xor_si128(b, c))` into `mm_ternarylogic_epi32(a, b, c, 0x96)` or more trivially `memcpy(a, b, 16);` into `_mm_storeu_si128(a…
-
LDM and STM also take a register *list* as the source / destination argument, so it's convenient for those to be at the end because you read them as 'base and stuff'. It's also very useful for them to have the same order in assembly because you almost always pair them: STM in the prolog, copy and paste it to the epilog and replace the ST with LD.
-
The advantage of intrinsics is that they don't expose register allocation. The compiler is free to reorder them where it can prove the reordering is equivalent and to insert stack spills and reloads as needed in the middle. The disadvantage of intrinsics is that they don't expose register allocation. The compiler is free to reorder them where it…
- Aug 20
-
I have very mixed opinions about the custom syntax. IMO the correct asm syntax, with very few exceptions, is the one in the manual. This is why Intel syntax is right and AT&T syntax is wrong: the ISA comes from Intel, the docs are from Intel and AMD, and those docs use Intel syntax.So I was kind of hoping that the custom syntax would at least…
-
> But because of its time period, the built-in assembler only ever understood up to 80286 instructions, so the day you wanted a 386 and its 32-bit registers you were sent off to an external assembler anyway.Or you just prefixed the instructions with "db $66", et voila your instructions were 32bit. I wrote a lot of inline 32bit assembly that way in…
-
I love that somebody is putting this much thought into inline asm, especially since I've also been frustrated by GCC and Clang completely phoning this in. Before this post, I would've given the "best inline assembler" crown to Rust, whose inline asm I think the post is underselling by calling it "a little more sophisticated because of the macro…
-
As I've already said, just becomes tomatoes are fruit doesn't mean that it belongs in a fruit salad. In culinary contexts, it's an acidic vegetable. In the vast majority of programming contexts, type has a much more specific meaning than the more meaning of "type". Those more-specific meanings are not wrong as you keep implying, and the people…
-
The other comment I get is usually "are intrinsics not good enough?". And part of the point of these `asm` templates in Odin is that they serve the role of an intrinsic because they are callable. It means you have the benefits of both worlds and the compiler doesn't need to have any extra redundancy to implement them.
-
I am saying any (valid) generic assembly is also typed. Provided certain definitions of "typed".
-
“Why even bother having its own inline assembler” — I really feel that people who say things like this have never actually used a compiler with integrated assembly. It is so much more pleasant, easier to manage, and easier to reason about than the asm string model we get in clang and gcc. I really do wish more people would see what other…
-
> destination-first is not an Intel quirk, it is the majority convention across ISAs. ARM writes add r0, r1, r2 (destination first) Well, except for load and store instructions: an LDM puts the source address on the left and the destination registers on the right; an STR or STP puts the source registers on the left and the destination address on…
-
An assembler is already a compiler I disagree. To me, an assembler is a program that translates mnemonics into machine code. It gives a one-to-one correspondence from textual representation to machine instructions. A translator that targets multiple backends is already not an assembler. Did I understand correctly that Odin defines a "move"…