mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-18 03:12:10 +00:00
Add asm directive #align N
This commit is contained in:
@@ -1515,7 +1515,38 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (name == "align") {
|
||||
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 a power-of-two integer 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 a power-of-two integer for the asm directive #%.*s", LIT(name));
|
||||
continue;
|
||||
}
|
||||
i64 i = exact_value_to_i64(ev);
|
||||
if (i < 0 || !is_power_of_two(i)) {
|
||||
error(op.expr, "Expected a power-of-two integer for the asm directive #%.*s, got %lld", LIT(name), cast(long long)i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
error(dir->name, "Unknown asm directive: #%.*s", LIT(name));
|
||||
}
|
||||
|
||||
case_end;
|
||||
|
||||
default:
|
||||
|
||||
@@ -495,6 +495,15 @@ struct lbAsmGenerate_amd64 : lbAsmGenerate {
|
||||
asm_string = gb_string_append_fmt(asm_string, "%d", cast(int)i);
|
||||
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_append_fmt(asm_string, "%llu", cast(unsigned long long)i_log2);
|
||||
} else {
|
||||
GB_PANIC("Invalid asm directive: %.*s", LIT(name));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user