Browse Source

ir for assign

Tobias Waldekranz.com 8 years ago
parent
commit
93c45926cf
3 changed files with 70 additions and 3 deletions
  1. 51 3
      global.c
  2. 18 0
      ir.c
  3. 1 0
      ir.h

+ 51 - 3
global.c

237
 		arg = arg->next;
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
 	if (n->sym->irs.hint.lval)
243
 	if (n->sym->irs.hint.lval)
241
 		/* map[key] = val, whatever is in our storage now it
244
 		/* map[key] = val, whatever is in our storage now it
242
                     will be overwritten, so skip the load. */
245
                     will be overwritten, so skip the load. */
243
 		return 0;
246
 		return 0;
244
 
247
 
245
-	n->sym->irs.hint.stack = 1;
246
-	ir_init_sym(prog->ir, n->sym);
247
-
248
 	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
248
 	ir_emit_ldmap(prog->ir, BPF_REG_1, map->sym);
249
 	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
249
 	ir_emit_insn(prog->ir, MOV, BPF_REG_2, BPF_REG_BP);
250
 	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, stack), BPF_REG_BP, 0);
250
 	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, stack), BPF_REG_BP, 0);
324
 
324
 
325
 /* :assign */
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
 static int global_assign_type_infer_map(struct node *n)
372
 static int global_assign_type_infer_map(struct node *n)
328
 {
373
 {
329
 	struct node *map, *key;
374
 	struct node *map, *key;
588
 		.type = &t_2args_func,
633
 		.type = &t_2args_func,
589
 		.type_infer = global_assign_type_infer,
634
 		.type_infer = global_assign_type_infer,
590
 		.static_validate = global_assign_static_validate,
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
 		.name = "{}",
641
 		.name = "{}",

+ 18 - 0
ir.c

453
 	assert(size == 0);
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
 int16_t ir_alloc_label (struct ir *ir)
471
 int16_t ir_alloc_label (struct ir *ir)
457
 {
472
 {
458
 	return ir->next_label--;
473
 	return ir->next_label--;
492
 	}
507
 	}
493
 	
508
 	
494
 	irs->loc = LOC_STACK;
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
 	if (!irs->stack)
513
 	if (!irs->stack)
496
 		irs->stack = ir_alloc_stack(ir, irs->size, type_alignof(t));
514
 		irs->stack = ir_alloc_stack(ir, irs->size, type_alignof(t));
497
 }
515
 }

+ 1 - 0
ir.h

144
 void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
144
 void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
145
 void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
145
 void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
146
 void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src);
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
 void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
149
 void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
149
 
150