-
Notifications
You must be signed in to change notification settings - Fork 15
Inline Assembly #248
Copy link
Copy link
Open
Description
Language Feature Proposal: Inline Assembly
Overview
This proposal extends the Cyrus language with inline assembly support, allowing developers to write platform-specific assembly code directly within Cyrus programs. The design follows a built-in function approach similar to other low-level operations, providing type safety and integration with the Cyrus type system.
Syntax
Basic Inline Assembly
// Basic form
@asm("assembly template" : outputs : inputs : clobbers);
// With constraints
@asm("mov %0, %1" : "=r"(result) : "r"(input) : "cc");
Extended Form for Multiple Instructions
@asm {
"assembly line 1\n"
"assembly line 2\n"
...
} : outputs : inputs : clobbers;
Design
Core Function Signature
// Pseudo-signature
fn @asm(
comptime template: []const u8,
outputs: ...,
inputs: ...,
clobbers: ...,
options: AsmOptions
) -> ReturnType;
Return Type Inference
The return type is inferred from the outputs:
- No outputs →
void - Single output → Type of that output
- Multiple outputs → Tuple of output types
Constraint Modifiers
Common Constraints
| Constraint | Description | Example |
|---|---|---|
r |
Any general-purpose register | "r"(value) |
m |
Memory operand | "m"(ptr) |
i |
Immediate integer | "i"(42) |
g |
Any register, memory, or immediate | "g"(expr) |
=r |
Write-only output register | "=r"(result) |
+r |
Read-write operand | "+r"(counter) |
&r |
Early-clobber register | "=&r"(temp) |
Architecture-specific Constraints
// x86/x86-64 specific
@asm("rdtsc" : "={eax}"(low), "={edx}"(high) : : "eax", "edx");
// ARM/AArch64 specific
@asm("mrs %0, cntvct_el0" : "=r"(timer) : : );
Examples
Basic Operations
// Read CPU timestamp counter on x86
fn rdtsc() -> u64 {
var low: u32;
var high: u32;
@asm("rdtsc"
: "={eax}"(low), "={edx}"(high)
:
: "eax", "edx"
);
return (@cast(u64, high) << 32) | @cast(u64, low);
}
// System call on x86-64 Linux
fn syscall1(number: i64, arg1: i64) -> i64 {
var result: i64;
@asm("syscall"
: "={rax}"(result)
: "{rax}"(number), "{rdi}"(arg1)
: "rcx", "r11", "memory"
);
return result;
}
Memory Operations
// Atomic compare-and-swap
fn cmpxchg(ptr: *mut u32, expected: u32, desired: u32) -> (u32, bool) {
var prev: u32 = expected;
var zero: u32;
@asm("lock cmpxchg %2, %1"
: "={eax}"(prev), "=m"(*ptr), "=@ccz"(zero)
: "{eax}"(expected), "m"(*ptr), "r"(desired)
: "memory"
);
return (prev, zero != 0);
}
// Memory barrier
fn memory_barrier() {
@asm("mfence" : : : "memory");
}
Architecture Detection
// Architecture-specific implementations
fn pause_cpu() {
const target = @env().target;
switch (target.cpu.arch) {
case .X86, .X86_64 => {
@asm("pause" : : : );
},
case .Arm, .AArch64 => {
@asm("yield" : : : );
},
default => {
// Generic memory barrier as fallback
@asm("" : : : "memory");
}
}
}
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Type
Projects
Status
New Phase