Project

General

Profile

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?


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.

    (1-2/2)