Skip to content

Proposal: Access pre-mangled program symbols from inline assembly #5211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Apr 29, 2020 · 4 comments
Closed

Proposal: Access pre-mangled program symbols from inline assembly #5211

ghost opened this issue Apr 29, 2020 · 4 comments
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@ghost
Copy link

ghost commented Apr 29, 2020

(UPDATED, AGAIN AND AGAIN AND AGAIN -- syntax is from #5241)

Currently, inline assembly is limited by its dependence on surrounding code to integrate with the rest of the program. This means certain functions that would make more sense as external assembly programs, such as those that run in stackless contexts, need inelegant hacks to work, such as using globals to pass values between them. Much tighter integration could be achieved if inline assembly had facilities to safely refer to program symbols directly.

I propose we do this with @, like @[variable] and @(function), to fit with the local/global convention employed in ZIR (and escape a literal @ with @@, just like we do for %). The compiler can mangle the symbols and perform any optimisations it likes, and any @'s will point to the correct location for the expected behaviour. For instance, here's a simple bare metal OS entry point on RISC-V:

// See #5241 for syntax

const stack_height: usize = 16 * 1024;
var stack: [stack_height]usize = undefined;

const _start = fn callconv(.Naked) () noreturn {
    asm |
        "=r" stack_base: [*]usize,
        "=r" stack_height,
        "=r" slot_size: usize = @sizeOf(usize),
        "sp", "ra",
    | noreturn {
        // Load the address of a global
        \\li %[stack_base], @[stack]
        \\mul %[stack_height], %[stack_height], %[slot_size]
        \\add sp, %[stack_base], %[stack_height]
        // Call a function -- this can be used to calculate stack growth
        \\call @(kmain)
        \\%(hang): j %(hang)
    };
};
const kmain = fn () void {
    // kernel kernel kernel
};

With this, you can mix and match assembly and Zig however you like. There is very little friction to just writing pure assembly functions in a Zig wrapper, or writing your own callsite-controlled "calling conventions" for naked functions, or whatever else.

@Vexu Vexu added the proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. label Apr 29, 2020
@Vexu Vexu added this to the 0.7.0 milestone Apr 29, 2020
@ghost ghost mentioned this issue Apr 29, 2020
@ghost
Copy link
Author

ghost commented May 1, 2020

Ok, I've edited this issue a lot, but I think I'm done now.

@ghost
Copy link
Author

ghost commented May 1, 2020

OK SORRY ONE MORE TIME

@ghost
Copy link
Author

ghost commented May 1, 2020

Fork it. It's a living document, whatever.

@ghost
Copy link
Author

ghost commented May 10, 2020

Rendered obsolete by changes to #5241. No reason for this to stay open.

@ghost ghost closed this as completed May 10, 2020
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

1 participant