implement array subscript for assignment in codegen
This commit is contained in:
parent
870cf8f0b4
commit
667769d1c0
3 changed files with 195 additions and 5 deletions
108
codegen.c
108
codegen.c
|
|
@ -152,14 +152,114 @@ void gen_binary(FILE *fp, ast_node *expr)
|
||||||
fprintf(fp, "or %%rcx, %%rax\n");
|
fprintf(fp, "or %%rcx, %%rax\n");
|
||||||
break;
|
break;
|
||||||
case OP_ASSIGN: {
|
case OP_ASSIGN: {
|
||||||
if (expr->expr.binary.left->type != NODE_IDENTIFIER) {
|
if (expr->expr.binary.left->type == NODE_IDENTIFIER) {
|
||||||
fprintf(fp, "# ERROR: left side of assignment must be identifier\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gen_expr(fp, expr->expr.binary.right);
|
gen_expr(fp, expr->expr.binary.right);
|
||||||
int offset = get_var_offset(expr->expr.binary.left->expr.string.start,
|
int offset = get_var_offset(expr->expr.binary.left->expr.string.start,
|
||||||
expr->expr.binary.left->expr.string.len);
|
expr->expr.binary.left->expr.string.len);
|
||||||
fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset);
|
fprintf(fp, "mov %%rax, -%d(%%rbp)\n", offset);
|
||||||
|
} else if (expr->expr.binary.left->type == NODE_ARRAY_SUBSCRIPT) {
|
||||||
|
ast_node *subscript = expr->expr.binary.left;
|
||||||
|
usize element_size = 8;
|
||||||
|
type *base_type = subscript->expr.subscript.expr->expr_type;
|
||||||
|
bool is_slice = false;
|
||||||
|
|
||||||
|
if (base_type) {
|
||||||
|
if (base_type->tag == TYPE_PTR && base_type->data.ptr.child) {
|
||||||
|
element_size = base_type->data.ptr.child->size;
|
||||||
|
} else if (base_type->tag == TYPE_SLICE && base_type->data.slice.child) {
|
||||||
|
element_size = base_type->data.slice.child->size;
|
||||||
|
is_slice = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subscript->expr.subscript.expr->type == NODE_IDENTIFIER && is_slice) {
|
||||||
|
int base_offset = get_var_offset(subscript->expr.subscript.expr->expr.string.start,
|
||||||
|
subscript->expr.subscript.expr->expr.string.len);
|
||||||
|
|
||||||
|
fprintf(fp, "mov -%d(%%rbp), %%rcx\n", base_offset);
|
||||||
|
gen_expr(fp, subscript->expr.subscript.index);
|
||||||
|
|
||||||
|
if (element_size != 1) {
|
||||||
|
fprintf(fp, "imul $%lu, %%rax\n", element_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "add %%rcx, %%rax\n");
|
||||||
|
fprintf(fp, "push %%rax\n");
|
||||||
|
|
||||||
|
gen_expr(fp, expr->expr.binary.right);
|
||||||
|
|
||||||
|
fprintf(fp, "pop %%rcx\n");
|
||||||
|
|
||||||
|
if (subscript->expr_type && subscript->expr_type->size == 4) {
|
||||||
|
fprintf(fp, "mov %%eax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 2) {
|
||||||
|
fprintf(fp, "mov %%ax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 1) {
|
||||||
|
fprintf(fp, "mov %%al, (%%rcx)\n");
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "mov %%rax, (%%rcx)\n");
|
||||||
|
}
|
||||||
|
} else if (subscript->expr.subscript.expr->type == NODE_IDENTIFIER) {
|
||||||
|
int base_offset = get_var_offset(subscript->expr.subscript.expr->expr.string.start,
|
||||||
|
subscript->expr.subscript.expr->expr.string.len);
|
||||||
|
|
||||||
|
gen_expr(fp, subscript->expr.subscript.index);
|
||||||
|
|
||||||
|
if (element_size != 1) {
|
||||||
|
fprintf(fp, "imul $%lu, %%rax\n", element_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "add $%d, %%rax\n", base_offset);
|
||||||
|
fprintf(fp, "neg %%rax\n");
|
||||||
|
fprintf(fp, "add %%rbp, %%rax\n");
|
||||||
|
fprintf(fp, "push %%rax\n");
|
||||||
|
|
||||||
|
gen_expr(fp, expr->expr.binary.right);
|
||||||
|
|
||||||
|
fprintf(fp, "pop %%rcx\n");
|
||||||
|
|
||||||
|
if (subscript->expr_type && subscript->expr_type->size == 4) {
|
||||||
|
fprintf(fp, "mov %%eax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 2) {
|
||||||
|
fprintf(fp, "mov %%ax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 1) {
|
||||||
|
fprintf(fp, "mov %%al, (%%rcx)\n");
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "mov %%rax, (%%rcx)\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gen_expr(fp, subscript->expr.subscript.expr);
|
||||||
|
fprintf(fp, "push %%rax\n");
|
||||||
|
|
||||||
|
gen_expr(fp, subscript->expr.subscript.index);
|
||||||
|
|
||||||
|
if (element_size != 1) {
|
||||||
|
fprintf(fp, "imul $%lu, %%rax\n", element_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fp, "pop %%rcx\n");
|
||||||
|
fprintf(fp, "add %%rcx, %%rax\n");
|
||||||
|
fprintf(fp, "push %%rax\n");
|
||||||
|
|
||||||
|
gen_expr(fp, expr->expr.binary.right);
|
||||||
|
|
||||||
|
fprintf(fp, "pop %%rcx\n");
|
||||||
|
|
||||||
|
if (subscript->expr_type && subscript->expr_type->size == 4) {
|
||||||
|
fprintf(fp, "mov %%eax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 2) {
|
||||||
|
fprintf(fp, "mov %%ax, (%%rcx)\n");
|
||||||
|
} else if (subscript->expr_type && subscript->expr_type->size == 1) {
|
||||||
|
fprintf(fp, "mov %%al, (%%rcx)\n");
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "mov %%rax, (%%rcx)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fprintf(fp, "# ERROR: left side of assignment must be identifier\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_ASSIGN_PTR: {
|
case OP_ASSIGN_PTR: {
|
||||||
|
|
|
||||||
BIN
test
Executable file
BIN
test
Executable file
Binary file not shown.
90
test.s
Normal file
90
test.s
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
.section .text
|
||||||
|
.global main
|
||||||
|
main:
|
||||||
|
push %rbp
|
||||||
|
mov %rsp, %rbp
|
||||||
|
sub $256, %rsp
|
||||||
|
movb $72, -32(%rbp)
|
||||||
|
movb $101, -31(%rbp)
|
||||||
|
movb $108, -30(%rbp)
|
||||||
|
movb $108, -29(%rbp)
|
||||||
|
movb $111, -28(%rbp)
|
||||||
|
movb $32, -27(%rbp)
|
||||||
|
movb $119, -26(%rbp)
|
||||||
|
movb $111, -25(%rbp)
|
||||||
|
movb $114, -24(%rbp)
|
||||||
|
movb $108, -23(%rbp)
|
||||||
|
movb $100, -22(%rbp)
|
||||||
|
movb $33, -21(%rbp)
|
||||||
|
movb $10, -20(%rbp)
|
||||||
|
lea -32(%rbp), %rax
|
||||||
|
mov %rax, -48(%rbp)
|
||||||
|
mov $14, %rax
|
||||||
|
mov %rax, -40(%rbp)
|
||||||
|
mov -40(%rbp), %rax
|
||||||
|
push %rax
|
||||||
|
pop %rdi
|
||||||
|
call malloc
|
||||||
|
mov %rax, -56(%rbp)
|
||||||
|
mov -56(%rbp), %rcx
|
||||||
|
mov $0, %rax
|
||||||
|
push %rax
|
||||||
|
mov $13, %rax
|
||||||
|
mov %rax, %rdx
|
||||||
|
pop %rax
|
||||||
|
mov %rdx, %r8
|
||||||
|
sub %rax, %r8
|
||||||
|
inc %r8
|
||||||
|
add %rcx, %rax
|
||||||
|
mov %rax, -88(%rbp)
|
||||||
|
mov %r8, -80(%rbp)
|
||||||
|
lea -88(%rbp), %rax
|
||||||
|
mov (%rax), %rcx
|
||||||
|
mov 8(%rax), %rdx
|
||||||
|
mov %rcx, -72(%rbp)
|
||||||
|
mov %rdx, -64(%rbp)
|
||||||
|
mov $0, %rax
|
||||||
|
mov %rax, -96(%rbp)
|
||||||
|
.L0:
|
||||||
|
mov -96(%rbp), %rax
|
||||||
|
mov %rax, %rcx
|
||||||
|
mov -40(%rbp), %rax
|
||||||
|
cmp %rax, %rcx
|
||||||
|
setl %al
|
||||||
|
movzx %al, %rax
|
||||||
|
test %rax, %rax
|
||||||
|
jz .L1
|
||||||
|
mov -72(%rbp), %rcx
|
||||||
|
mov -96(%rbp), %rax
|
||||||
|
add %rcx, %rax
|
||||||
|
push %rax
|
||||||
|
mov -48(%rbp), %rcx
|
||||||
|
mov -96(%rbp), %rax
|
||||||
|
add %rcx, %rax
|
||||||
|
movzbl (%rax), %eax
|
||||||
|
pop %rcx
|
||||||
|
mov %al, (%rcx)
|
||||||
|
mov -96(%rbp), %rax
|
||||||
|
mov %rax, %rcx
|
||||||
|
mov $1, %rax
|
||||||
|
add %rcx, %rax
|
||||||
|
mov %rax, -96(%rbp)
|
||||||
|
jmp .L0
|
||||||
|
.L1:
|
||||||
|
mov $1, %rax
|
||||||
|
push %rax
|
||||||
|
mov -72(%rbp), %rax
|
||||||
|
push %rax
|
||||||
|
mov -64(%rbp), %rax
|
||||||
|
push %rax
|
||||||
|
pop %rdx
|
||||||
|
pop %rsi
|
||||||
|
pop %rdi
|
||||||
|
call write
|
||||||
|
mov $0, %rax
|
||||||
|
mov %rbp, %rsp
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
|
mov %rbp, %rsp
|
||||||
|
pop %rbp
|
||||||
|
ret
|
||||||
Loading…
Add table
Add a link
Reference in a new issue