Forums » Programming with the ECS » Intermediate Code »
fill operation
Added by Rochus Keller about 1 year ago
I have a case where the code generated by chibicc and cdamd32 causes a segfault, but the same code generated by cppamd32 works. I was able to trace it to the fill operation.
Please find attached a minimal C file to reproduce the segfault and the generated cod.
If I comment out lines 39 and 40 of the cod (mov and fill), the segfault doesn't occur. Interestingly, the segfault neither occurs if "const char* str = 0;" is in "main", not in "f". Do I have a misconception concerning fill?
fill_test.cod (1009 Bytes) fill_test.cod | |||
fill_test.c (72 Bytes) fill_test.c |
Replies (2)
RE: fill operation - Added by Florian Negele about 1 year ago
What do you actually want to achieve with the fill instruction? Please read its description carefully: The second operand denotes values not bytes.
RE: fill operation - Added by Rochus Keller about 1 year ago
values not bytes.
Ok, that was the crucial clue, thanks! I had read the text and had indeed interpreted "value" as byte. But now that I know that this refers to the explicit data type of the third operator, I understand the concept. I quickly changed the code to "fill ptr $0, ptr %d, u1 0" and now everything works.
What do you actually want to achieve with the fill instruction?
I use it to implement the ND_MEMZERO instruction of chibicc. It is created here (original code):
static Node *lvar_initializer(Token **rest, Token *tok, Obj *var) { Initializer *init = initializer(rest, tok, var->ty, &var->ty); InitDesg desg = {NULL, 0, NULL, var}; // If a partial initializer list is given, the standard requires // that unspecified elements are set to 0. Here, we simply // zero-initialize the entire memory region of a variable before // initializing it with user-supplied values. Node *lhs = new_node(ND_MEMZERO, tok); lhs->var = var; Node *rhs = create_lvar_init(init, var->ty, &desg, tok); return new_binary(ND_COMMA, lhs, rhs, tok); }
and the code generator originally made this:
// `rep stosb` is equivalent to `memset(%rdi, %al, %rcx)`. println(" mov $%d, %%rcx", node->var->ty->size); println(" lea %d(%%rbp), %%rdi", node->var->offset); println(" mov $0, %%al"); println(" rep stosb");
I have essentially migrated the code generator 1:1 to ECS IR without improving anything.