# GSoC syncup: inline assembly
Rolling agenda.
## 2024-08-14
- Jasmine to put together a hackmd to ask GCC community for help on debugging the GENERIC/GIMPLE issue
## 2024-08-08
- Investigate side-effect
## 2024-08-01
- bdbt: failure on CompileExpr::Compile for asm_construct_outputs in resolve paths, why do we need to resolve path of an expr? and why typecheck
- Trying to solve https://github.com/Rust-GCC/gccrs/issues/3099, in
```cpp
template <typename ManagedTokenSource>
std::unique_ptr<AST::Expr>
Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
AST::AttrVec outer_attrs,
ParseRestrictions restrictions)
{
const_TokenPtr current_token = lexer.peek_token ();
// Special hack because we are allowed to return nullptr, in that case we
// don't want to skip the token, since we don't actually parse it. But if
// null isn't allowed it indicates an error, and we want to skip past that.
// So return early if it is one of the tokens that ends an expression
// (or at least cannot start a new expression).
if (restrictions.expr_can_be_null)
{
TokenId id = current_token->get_id ();
if (id == SEMICOLON || id == RIGHT_PAREN || id == RIGHT_CURLY
|| id == RIGHT_SQUARE || id == COMMA || id == LEFT_CURLY)
return nullptr;
}
if (current_token->get_id () == LEFT_SHIFT)
{
lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
current_token = lexer.peek_token ();
}
lexer.skip_token ();
ParseRestrictions null_denotation_restrictions = restrictions;
null_denotation_restrictions.expr_can_be_stmt = false;
// parse null denotation (unary part of expression)
std::unique_ptr<AST::Expr> expr
= null_denotation (current_token, {}, null_denotation_restrictions);
return left_denotations (std::move (expr), right_binding_power,
std::move (outer_attrs), restrictions);
}
```
why do we pass an empty outer_attr to null_denotation
## 2024-07-25
- bdbt: Should i create a new PR for my parser fix? I committed in asm_generic_il and not sure how to bring that one commit to the new branch.
- bddt: in fixing the parser i have to disable a case that is trying to parse '_', can't do it via parse_expr since another case involves x => y and it can't handle that right now. Should I bandage it by checking if an identifier is either ident token or a blank _ ? -> Open issue
## 2024-07-09
- bdbt: when you first started porting stuff from gcc/c to gccrs, how did you first trace out the global variables and convert them into things like context?
> there is something in the codebase of c that is something like this with cur_stmt_list being a global variable and it's causing me not knowing how to port this code to gccrs, like i don't where it is first initialized and what condition it needs so that the generic il pipeline recognizes it as "valid"
> Arthur Cohen: @Jasmine Tang there should be an equivalent method in the context struct
https://github.com/Rust-GCC/gccrs/blob/master/gcc%2Frust%2Fbackend%2Frust-compile-context.h#L126
, make sure that when you create your CompileAsm visitor you give it that instance of ctx or something
find enum, add extra option
```c++
const Fmt::Pieces &get_template () const { return template_pieces; }
```
__Actions__:
- Arthur to review [#3060](https://github.com/Rust-GCC/gccrs/pull/3060)
- bdbt to go back to the parser to add more functionality
## 2024-07-02
hard code nop that gcc generates nop (put in PRs)
seperate smaller step (start with build_stmt)
- bdbt: it seems that after the gcc parser parse inline assembyly once, it now perform the parse on the tree data structure with parse_input_constraint and parse_output_constraint
## 2024-06-27
- bdbt: Return type of asm! depends on options, should defaults to (), unless options(no_return) dictates the type to be !
https://doc.rust-lang.org/reference/inline-assembly.html#options
- bdbt: I was wrong about the label, it needs an explicit keyword: `label` and will be handled with a parse_block since after the keyword it starts with a `{}`
__Actions__:
- Open 2 pr, 1 for label, 1 for
- Arthur to find a "why gccrs" slide and put it here
- Take a look at permission issues for building gccrs for badumbatish
## 2024-06-20
global opt of project, why write rust in gcc
- only 1 rust compiler
- rustc is not free software
- support older architecture
- compile rust code and compile rust linux
- Look through gcc/testsuite/gcc and see how they test inline asm. The other case is use crab1 proper and check by hand.
- `dg-scan-assembler`
- `-fdump-tree-gimple` will output `GIMPLE`
- `-fdump-tree-original` and `-fdump-tree-gimple`
```c
tree
build_asm_expr (location_t loc, tree string, tree outputs, tree inputs,
tree clobbers, tree labels, bool simple, bool is_inline)
```
There is familiar stuff such as inputs , outputs, clobbers, labels(unprocessed), we always set is_inline to true.
- The parser emits errors lazily, because it can be interesting to try parsing functions without necessarily emitting errors.
- review Actions
__Actions__:
- Arthur to find a "why gccrs" slide and put it here
- Arthur to check asm!() grammar and propose parsing schema for `parse_expr` question
- Jasmine to look into the API to use with the parser for error emission
## 2024-06-13
- Working a bit on expected()
- badumbatish: parser.parse_expr() is parsing weird, it parses until end of invocation asm!()
```rs
// I called parse_expr (with no arguments) with current token of the first num1 and it kept on parsing until the right parenthesis of asm!
unsafe {
asm!(
"add {0}, {0}",
inout(reg) num1 => num1,
in(reg) num2,
);
}
```
peek(n);
- badumbatish: Not sure about C++'s equivalent ast node for rust's ast::ExprKind::Path(qself, path), do we need to add another kind to enum class Kind?

- Not sure where should i stop tl::optional-ing all the members variables and structs
- rust's asm.rs is checking for the keyword `label` but there isn't any label, only strings that represents a numberic label such as `2:` or `43:`. But all string-based tokens should be processed via
string token in the first case (Updated: This is satisfied, the parser accepts the numeric label, but it accepts it via parse_format_string, technically this is wrong but I just want to let it be known that it actually parses)
- what does expected fails mean in make check-rust
- not hitting unreachable() calls:
- same issue as #2866
- not Jasmine's fault, issue with the macro expander
__Actions__:
- Arthur to work on 2866 to fix lowering issue
- Look at parser issues from last week
## 2024-05-30
- review [Actions](#2024-05-23)
- badumbatish: Not sure how visitor pattern with walk_item works https://doc.rust-lang.org/stable/nightly-rustc/rustc_ast/visit/trait.Visitor.html
- badumbatish: https://github.com/rust-lang/rust/tree/e1884a8e3c3e813aada8254edfa120e85bf5ffca
- Should we look into lookback on parser - is it possible with our setup?
- rust_error("this is %<quoted%> and this is %qs", "too")
- gcc/rust/hir llok into, ::translate, ::visit
- https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/hir.rs#L2837
- lots of work done on inline assembly parser
- the PR is in very good shape, only a couple cosmetic fixes and it's ready to merge
- badumbatish to maybe check the next steps in the pipeline: lowering from AST -> HIR and/or UnsafeChecker
- badumbatish starting her internship (congrats!) so progress should slow down a little bit :)
> one thing we can look at here is improving error handling by returning a tl::expected<T, E> - this way, errors can be properly chained and emitted whenever we'd like
https://github.com/Rust-GCC/gccrs/blob/master/gcc/rust/checks/errors/rust-unsafe-checker.cc
__Actions__:
@badumbatish to look at https://github.com/rust-lang/rust/blob/master/compiler/rustc_ast_lowering/src/asm.rs
## 2024-05-23
- review [Actions](#2024-05-16)
- `expand_global_asm`?
- `expand_asm`?
- `expand_preparsed_asm`?
- what is allow_template in parse_asm_arg?
- Debugging in the compiler
- `rust_debug`/`rust_debug_loc`
- `-frust-debug`
- `build/gcc/crab1 test.rs -frust-debug`
- badumbatish: I think the BNF grammar that https://doc.rust-lang.org/reference/inline-assembly.html give is incomplete. (Make new docs detailing this)
I'm not sure about naming convention, clearly in ABNF, the procedure to be parsed is operand, but in rustc asm.rs, the function that performs that duty is parse_asm_args
- badumbatish: Out of line but in https://github.com/Rust-GCC/gccrs/issues/3000, how can you just pass in -frust-name-resolution-2.0 and gccrs knows how to use the 2.0 and not the 1.x
- badumbatish: Noticing a lot of repetitive argument passing between my functions in rust-macro-builtins-asm.cc, maybe i should inherit from `Parser<MacroInvocLexer>` for a new parsing class.
```cpp
struct AsmParserCtx {
Parser<MacroInvocLexer> parser;
constToken_t last_token_id;
...
}
```
- is last_token_id acting like vector.end()?
```
vec![1, 2, 3];
^^^^^^^^^
asm!("yoooo", x = 14, 15);
^^^^^^^^^^^^^^^^^^^^^
```
- For parsing formatted strings, i think they use parse_expr in asm.rs so should i somehow follow the same principle? Not sure how I would do that
- How do i regression test only a subset of tests related to inline assembly only.
```
make -C build check-rust RUNTESTFLAGS="compile.exp"
```
- todo: work on formatted string parsing and parsing operand. Validity checking soon
- You can have something like `asm!(include_str!("foo.s"), ...)`
- `foo!(bar!())` -> `foo!()` -> `bar!()`
- `asm!(15)`
- Split Pr, first pr simple parsing good.
__Actions__:
Arthur to review "inline asm" PR.
Arthur to look into `expand_preparsed_asm`.
## 2024-05-16
__Actions__:
@Arthur/@PE to review PRs from @badumbatish
@badumbatish how rustc does inline assembly as string parsing (look at rustc source itself see how its handled).
https://github.com/rust-lang/rust/blob/master/compiler/rustc_builtin_macros/
https://github.com/rust-lang/rust/blob/master/compiler/rustc_builtin_macros/src/asm.rs
@badumbatish look at `format_args!()` in gccrs compiler: https://github.com/Rust-GCC/gccrs/blob/master/gcc/rust/expand/rust-macro-builtins-format-args.cc