| author | |
| committer | |
| log | 64a0510205b4d224413de52fd87632fbe6bfe083 |
| tree | c673e98af23f82d939ec0513bfbf8f757704a9a6 |
| parent | b840184bb09b9d5e4272f848dcaa7c4973dfdcd5 |
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 instructions3 files changed, 18 insertions(+), 3 deletions(-)
src/all_types.hpp+3| ... | ... | @@ -604,6 +604,7 @@ enum AsmTokenId { |
| 604 | 604 | AsmTokenIdTemplate, |
| 605 | 605 | AsmTokenIdPercent, |
| 606 | 606 | AsmTokenIdVar, |
| 607 | AsmTokenIdUniqueId, | |
| 607 | 608 | }; |
| 608 | 609 | |
| 609 | 610 | struct AsmToken { |
| ... | ... | @@ -1286,6 +1287,8 @@ struct CodeGen { |
| 1286 | 1287 | |
| 1287 | 1288 | IrInstruction *invalid_instruction; |
| 1288 | 1289 | ConstExprValue const_void_val; |
| 1290 | ||
| 1291 | uint32_t unique_asm_id; | |
| 1289 | 1292 | }; |
| 1290 | 1293 | |
| 1291 | 1294 | enum VarLinkage { |
src/codegen.cpp+11-3| ... | ... | @@ -1481,6 +1481,9 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru |
| 1481 | 1481 | Buf llvm_template = BUF_INIT; |
| 1482 | 1482 | buf_resize(&llvm_template, 0); |
| 1483 | 1483 | |
| 1484 | uint32_t unique_id = g->unique_asm_id; | |
| 1485 | g->unique_asm_id += 1; | |
| 1486 | ||
| 1484 | 1487 | for (size_t token_i = 0; token_i < asm_expr->token_list.length; token_i += 1) { |
| 1485 | 1488 | AsmToken *asm_token = &asm_expr->token_list.at(token_i); |
| 1486 | 1489 | switch (asm_token->id) { |
| ... | ... | @@ -1498,9 +1501,14 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru |
| 1498 | 1501 | buf_append_char(&llvm_template, '%'); |
| 1499 | 1502 | break; |
| 1500 | 1503 | case AsmTokenIdVar: |
| 1501 | size_t index = find_asm_index(g, asm_node, asm_token); | |
| 1502 | assert(index < SIZE_MAX); | |
| 1503 | buf_appendf(&llvm_template, "$%zu", index); | |
| 1504 | { | |
| 1505 | size_t index = find_asm_index(g, asm_node, asm_token); | |
| 1506 | assert(index < SIZE_MAX); | |
| 1507 | buf_appendf(&llvm_template, "$%zu", index); | |
| 1508 | break; | |
| 1509 | } | |
| 1510 | case AsmTokenIdUniqueId: | |
| 1511 | buf_appendf(&llvm_template, "%" PRIu32, unique_id); | |
| 1504 | 1512 | break; |
| 1505 | 1513 | } |
| 1506 | 1514 | } |
src/parser.cpp+4| ... | ... | @@ -136,6 +136,10 @@ static void parse_asm_template(ParseContext *pc, AstNode *node) { |
| 136 | 136 | } else if (c == '[') { |
| 137 | 137 | cur_tok->id = AsmTokenIdVar; |
| 138 | 138 | state = StateVar; |
| 139 | } else if (c == '=') { | |
| 140 | cur_tok->id = AsmTokenIdUniqueId; | |
| 141 | cur_tok->end = i; | |
| 142 | state = StateStart; | |
| 139 | 143 | } else { |
| 140 | 144 | ast_asm_error(pc, node, i, "expected a '%%' or '['"); |
| 141 | 145 | } |