asm: add #skip N and #nop N

This commit is contained in:
gingerBill
2026-08-17 13:36:59 +01:00
parent bd95d2ae66
commit d71c25dd9b
2 changed files with 45 additions and 1 deletions

View File

@@ -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));
}

View File

@@ -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));
}