diff --git a/src/check_asm.cpp b/src/check_asm.cpp index c847b1932..4f2a21bad 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -1543,6 +1543,34 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity } } + } else if (name == "skip" || + name == "nop") { + if (dir->operands.count != 1) { + error(dir->name, "Expected 1 integer for the asm directive #%.*s", LIT(name)); + break; + } + array_clear(&operands); + for (Ast *expr : dir->operands) { + Operand operand = {}; + check_asm_instruction_operand(asm_ctx, ctx, entity, &operand, expr, /*allow_memory_operands*/true); + array_add(&operands, operand); + } + for (auto const &op : operands) { + if (op.mode != Addressing_Constant) { + error(op.expr, "Expected an integer >0 for the asm directive #%.*s", LIT(name)); + continue; + } + ExactValue ev = exact_value_to_integer(op.value); + if (ev.kind != ExactValue_Integer) { + error(op.expr, "Expected an integer >0 for the asm directive #%.*s", LIT(name)); + continue; + } + i64 i = exact_value_to_i64(ev); + if (i < 0) { + error(op.expr, "Expected an integer >0 for the asm directive #%.*s, got %lld", LIT(name), cast(long long)i); + continue; + } + } } else { error(dir->name, "Unknown asm directive: #%.*s", LIT(name)); } diff --git a/src/llvm_backend_asm.cpp b/src/llvm_backend_asm.cpp index 5cca6d89b..bc6425147 100644 --- a/src/llvm_backend_asm.cpp +++ b/src/llvm_backend_asm.cpp @@ -496,14 +496,30 @@ struct lbAsmGenerate_amd64 : lbAsmGenerate { op_index += 1; } } else if (name == "align") { - asm_string = gb_string_appendc(asm_string, ".p2align "); GB_ASSERT(dir->operands.count == 1); auto const &op = dir->operands[0]; ExactValue ev = exact_value_to_integer(op->tav.value); GB_ASSERT(ev.kind == ExactValue_Integer); u64 i = exact_value_to_u64(ev); u64 i_log2 = floor_log2(i); + asm_string = gb_string_appendc(asm_string, ".p2align "); asm_string = gb_string_append_fmt(asm_string, "%llu", cast(unsigned long long)i_log2); + } else if (name == "skip") { + GB_ASSERT(dir->operands.count == 1); + auto const &op = dir->operands[0]; + ExactValue ev = exact_value_to_integer(op->tav.value); + GB_ASSERT(ev.kind == ExactValue_Integer); + u64 i = exact_value_to_u64(ev); + asm_string = gb_string_appendc(asm_string, ".skip "); + asm_string = gb_string_append_fmt(asm_string, "%llu", cast(unsigned long long)i); + } else if (name == "nop") { + GB_ASSERT(dir->operands.count == 1); + auto const &op = dir->operands[0]; + ExactValue ev = exact_value_to_integer(op->tav.value); + GB_ASSERT(ev.kind == ExactValue_Integer); + u64 i = exact_value_to_u64(ev); + asm_string = gb_string_appendc(asm_string, ".nops "); + asm_string = gb_string_append_fmt(asm_string, "%llu", cast(unsigned long long)i); } else { GB_PANIC("Invalid asm directive: %.*s", LIT(name)); }