diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-02-04 22:33:58 -0500 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-02-04 22:33:58 -0500 |
| commit | 64a0510205b4d224413de52fd87632fbe6bfe083 (patch) | |
| tree | c673e98af23f82d939ec0513bfbf8f757704a9a6 /src | |
| parent | b840184bb09b9d5e4272f848dcaa7c4973dfdcd5 (diff) | |
| download | zig-64a0510205b4d224413de52fd87632fbe6bfe083.tar.gz zig-64a0510205b4d224413de52fd87632fbe6bfe083.zip | |
inline assembly supports `%=` syntax
it outputs a number that is unique to each instance of the asm
statement in the entire compilation.
useful when creating local labels and referring to them multiple
times in a single template that generates multiple
assembler instructions
Diffstat (limited to 'src')
| -rw-r--r-- | src/all_types.hpp | 3 | ||||
| -rw-r--r-- | src/codegen.cpp | 14 | ||||
| -rw-r--r-- | src/parser.cpp | 4 |
3 files changed, 18 insertions, 3 deletions
diff --git a/src/all_types.hpp b/src/all_types.hpp index 18f668c0ef..169e2266b6 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -604,6 +604,7 @@ enum AsmTokenId { AsmTokenIdTemplate, AsmTokenIdPercent, AsmTokenIdVar, + AsmTokenIdUniqueId, }; struct AsmToken { @@ -1286,6 +1287,8 @@ struct CodeGen { IrInstruction *invalid_instruction; ConstExprValue const_void_val; + + uint32_t unique_asm_id; }; enum VarLinkage { diff --git a/src/codegen.cpp b/src/codegen.cpp index 9ade5cda42..3328bc3de4 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1481,6 +1481,9 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru Buf llvm_template = BUF_INIT; buf_resize(&llvm_template, 0); + uint32_t unique_id = g->unique_asm_id; + g->unique_asm_id += 1; + for (size_t token_i = 0; token_i < asm_expr->token_list.length; token_i += 1) { AsmToken *asm_token = &asm_expr->token_list.at(token_i); switch (asm_token->id) { @@ -1498,9 +1501,14 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru buf_append_char(&llvm_template, '%'); break; case AsmTokenIdVar: - size_t index = find_asm_index(g, asm_node, asm_token); - assert(index < SIZE_MAX); - buf_appendf(&llvm_template, "$%zu", index); + { + size_t index = find_asm_index(g, asm_node, asm_token); + assert(index < SIZE_MAX); + buf_appendf(&llvm_template, "$%zu", index); + break; + } + case AsmTokenIdUniqueId: + buf_appendf(&llvm_template, "%" PRIu32, unique_id); break; } } diff --git a/src/parser.cpp b/src/parser.cpp index aa0d7ddff3..68ccd6aff4 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -136,6 +136,10 @@ static void parse_asm_template(ParseContext *pc, AstNode *node) { } else if (c == '[') { cur_tok->id = AsmTokenIdVar; state = StateVar; + } else if (c == '=') { + cur_tok->id = AsmTokenIdUniqueId; + cur_tok->end = i; + state = StateStart; } else { ast_asm_error(pc, node, i, "expected a '%%' or '['"); } |
