ソースを参照

ir for assign

Tobias Waldekranz.com 8 年 前
コミット
93c45926cf
共有3 個のファイルを変更した70 個の追加3 個の削除を含む
  1. 51 3
      global.c
  2. 18 0
      ir.c
  3. 1 0
      ir.h

+ 51 - 3
global.c

@@ -237,14 +237,14 @@ static int global_map_ir_post(const struct func *func, struct node *n,
237 237
 		arg = arg->next;
238 238
 	}
239 239
 
240
+	n->sym->irs.hint.stack = 1;
241
+	ir_init_sym(prog->ir, n->sym);
242
+
240 243
 	if (n->sym->irs.hint.lval)
241 244
 		/* map[key] = val, whatever is in our storage now it
242 245
                     will be overwritten, so skip the load. */
243 246
 		return 0;
244 247
 
245
-	n->sym->irs.hint.stack = 1;
246
-	ir_init_sym(prog->ir, n->sym);
247
-
248 248
 	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
249 249
 	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
250 250
 	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, stack), BPF_REG_BP, 0);
@@ -324,6 +324,51 @@ static int global_map_static_validate(const struct func *func, struct node *n)
324 324
 
325 325
 /* :assign */
326 326
 
327
+static int global_assign_ir_pre(const struct func *func, struct node *n,
328
+				struct prog *prog)
329
+{
330
+	struct node *lval, *rval;
331
+
332
+	lval = n->expr.args;
333
+	rval = lval->next;
334
+
335
+	n->sym->irs.hint.stack = 1;
336
+	ir_init_irs(prog->ir, &n->sym->irs, lval->sym->type);
337
+
338
+	lval->sym->irs.hint.lval = 1;
339
+	lval->sym->irs.hint.stack = 1;
340
+	lval->sym->irs.stack = n->sym->irs.stack;
341
+
342
+	rval->sym->irs.hint.stack = 1;
343
+	rval->sym->irs.stack = n->sym->irs.stack;
344
+	return 0;
345
+}
346
+
347
+static int global_assign_ir_post(const struct func *func, struct node *n,
348
+				 struct prog *prog)
349
+{
350
+	struct node *lval, *rval, *map;
351
+
352
+	lval = n->expr.args;
353
+	rval = lval->next;
354
+
355
+	ir_emit_sym_to_sym(prog->ir, lval->sym, rval->sym);
356
+	if (!node_is(lval, "{}"))
357
+		return 0;
358
+
359
+	map = lval->expr.args;
360
+
361
+	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
362
+	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
363
+	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, map->sym->irs.stack), BPF_REG_2, 0);
364
+	ir_emit_insn(prog->ir, MOV, BPF_REG_3, BPF_REG_BP);
365
+	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, lval->sym->irs.stack), BPF_REG_3, 0);
366
+	ir_emit_insn(prog->ir, MOV_IMM(0), BPF_REG_4, 0);
367
+	ir_emit_insn(prog->ir, CALL(BPF_FUNC_map_update_elem), 0, 0);
368
+	/* TODO: if (r0) exit(r0); */
369
+	return 0;
370
+}
371
+
327 372
 static int global_assign_type_infer_map(struct node *n)
328 373
 {
329 374
 	struct node *map, *key;
@@ -588,6 +633,9 @@ static const struct func global_funcs[] = {
588 633
 		.type = &t_2args_func,
589 634
 		.type_infer = global_assign_type_infer,
590 635
 		.static_validate = global_assign_static_validate,
636
+
637
+		.ir_pre  = global_assign_ir_pre,
638
+		.ir_post = global_assign_ir_post,
591 639
 	},
592 640
 	{
593 641
 		.name = "{}",

+ 18 - 0
ir.c

@@ -453,6 +453,21 @@ void ir_emit_bzero(struct ir *ir, ssize_t offset, size_t size)
453 453
 	assert(size == 0);
454 454
 }
455 455
 
456
+void ir_emit_sym_to_sym(struct ir *ir, struct sym *dst, struct sym *src)
457
+{
458
+	switch (dst->irs.loc) {
459
+	case LOC_REG:
460
+		ir_emit_sym_to_reg(ir, dst->irs.reg, src);
461
+		break;
462
+	case LOC_STACK:
463
+		ir_emit_sym_to_stack(ir, dst->irs.stack, src);
464
+		break;
465
+	default:
466
+		assert(0);
467
+		break;
468
+	}
469
+}
470
+
456 471
 int16_t ir_alloc_label (struct ir *ir)
457 472
 {
458 473
 	return ir->next_label--;
@@ -492,6 +507,9 @@ void ir_init_irs(struct ir *ir, struct irstate *irs, struct type *t)
492 507
 	}
493 508
 	
494 509
 	irs->loc = LOC_STACK;
510
+
511
+	/* a parent may already have filled in a stack position.
512
+	 * usually this is when we're part of a map key. */
495 513
 	if (!irs->stack)
496 514
 		irs->stack = ir_alloc_stack(ir, irs->size, type_alignof(t));
497 515
 }

+ 1 - 0
ir.h

@@ -144,6 +144,7 @@ void ir_emit_label  (struct ir *ir, int16_t label);
144 144
 void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
145 145
 void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
146 146
 void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src);
147
+void ir_emit_sym_to_sym(struct ir *ir, struct sym *dst, struct sym *src);
147 148
 
148 149
 void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
149 150