Explorar el Código

map lookup/bzero

Tobias Waldekranz.com hace 8 años
padre
commit
3e0e084c66
Se han modificado 3 ficheros con 52 adiciones y 23 borrados
  1. 27 5
      global.c
  2. 23 18
      ir.c
  3. 2 0
      ir.h

+ 27 - 5
global.c

@@ -135,12 +135,8 @@ static int global_deref_ir_post(const struct func *func, struct node *n,
135 135
                     be overwritten, so skip the load. */
136 136
 		return 0;
137 137
 
138
-	ir_emit_insn(prog->ir, MOV, BPF_REG_1, BPF_REG_BP);
139
-	ir_emit_insn(prog->ir, ALU_IMM(BPF_ADD, dst->stack), BPF_REG_1, 0);
140
-	ir_emit_insn(prog->ir, MOV_IMM((int32_t)dst->size), BPF_REG_2, 0);
141 138
 	ir_emit_sym_to_reg(prog->ir, BPF_REG_3, ptr->sym);
142
-	ir_emit_insn(prog->ir, CALL(BPF_FUNC_probe_read), 0, 0);
143
-	/* TODO if (r0) exit(r0); */
139
+	ir_emit_read_to_sym(prog->ir, n->sym, BPF_REG_3);
144 140
 	return 0;
145 141
 }
146 142
 
@@ -232,6 +228,7 @@ static int global_map_ir_post(const struct func *func, struct node *n,
232 228
 	ssize_t stack = map->sym->irs.stack;
233 229
 	size_t offset;
234 230
 	struct tfield *f;
231
+	int16_t lmiss, lhit;
235 232
 
236 233
 	arg = map->next;
237 234
 	tfields_foreach(f, ktype->sou.fields) {
@@ -239,6 +236,31 @@ static int global_map_ir_post(const struct func *func, struct node *n,
239 236
 		ir_emit_sym_to_stack(prog->ir, stack + offset, arg->sym);
240 237
 		arg = arg->next;
241 238
 	}
239
+
240
+	if (n->sym->irs.hint.lval)
241
+		/* map[key] = val, whatever is in our storage now it
242
+                    will be overwritten, so skip the load. */
243
+		return 0;
244
+
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);
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);
251
+	ir_emit_insn(prog->ir, CALL(BPF_FUNC_map_lookup_elem), 0, 0);
252
+
253
+	lmiss = ir_alloc_label(prog->ir);
254
+	lhit  = ir_alloc_label(prog->ir);
255
+
256
+	ir_emit_insn(prog->ir, JMP_IMM(BPF_JEQ, 0, lmiss), BPF_REG_0, 0);
257
+	ir_emit_read_to_sym(prog->ir, n->sym, BPF_REG_0);
258
+	ir_emit_insn(prog->ir, JMP(BPF_JA, lhit), 0, 0);
259
+
260
+	ir_emit_label(prog->ir, lmiss);
261
+	ir_emit_bzero(prog->ir, n->sym->irs.stack, n->sym->irs.size);
262
+	
263
+	ir_emit_label(prog->ir, lhit);
242 264
 	return 0;
243 265
 }
244 266
 

+ 23 - 18
ir.c

@@ -362,14 +362,13 @@ void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src)
362 362
 		assert(0);
363 363
 	}
364 364
 }
365
-#include "ply.h"
365
+
366 366
 void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src)
367 367
 {
368 368
 	struct irstate *irs = &src->irs;
369 369
 
370 370
 	switch (irs->loc) {
371 371
 	case LOC_IMM:
372
-		_d("WKZ %zu @ %zd (%d)\n", irs->size, offset, irs->imm);
373 372
 		ir_emit_insn(ir, ST_IMM(bpf_width(irs->size), offset, irs->imm),
374 373
 			     BPF_REG_BP, 0);
375 374
 		break;
@@ -384,6 +383,22 @@ void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src)
384 383
 	}
385 384
 }
386 385
 
386
+void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src)
387
+{
388
+	struct irstate *irs = &dst->irs;
389
+
390
+	assert(irs->loc == LOC_STACK);
391
+
392
+	ir_emit_insn(ir, MOV, BPF_REG_1, BPF_REG_BP);
393
+	ir_emit_insn(ir, ALU_IMM(BPF_ADD, irs->stack), BPF_REG_1, 0);
394
+	ir_emit_insn(ir, MOV_IMM((int32_t)irs->size), BPF_REG_2, 0);
395
+	if (src != BPF_REG_3)
396
+		ir_emit_insn(ir, MOV, BPF_REG_3, src);
397
+
398
+	ir_emit_insn(ir, CALL(BPF_FUNC_probe_read), 0, 0);
399
+	/* TODO if (r0) exit(r0); */
400
+}
401
+
387 402
 void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size)
388 403
 {
389 404
 	if (dst == src)
@@ -469,26 +484,16 @@ void ir_init_irs(struct ir *ir, struct irstate *irs, struct type *t)
469 484
 
470 485
 	irs->size = type_sizeof(t);
471 486
 
472
-	if (irs->hint.stack) {
473
-		if (irs->stack) {
474
-			irs->loc = LOC_STACK;
475
-			return;
476
-		}
477
-		goto alloc_stack;
478
-	}
479
-
480
-	switch (t->ttype) {
481
-	case T_SCALAR:
482
-	case T_POINTER:
487
+	if ((!irs->hint.stack)
488
+	    && ((t->ttype == T_SCALAR) || (t->ttype == T_POINTER))) {
483 489
 		irs->loc = LOC_REG;
484 490
 		irs->reg = ir_alloc_register(ir);
485 491
 		return;
486
-
487
-	default:
488
-	alloc_stack:
489
-		irs->loc = LOC_STACK;
490
-		irs->stack = ir_alloc_stack(ir, irs->size, type_alignof(t));
491 492
 	}
493
+	
494
+	irs->loc = LOC_STACK;
495
+	if (!irs->stack)
496
+		irs->stack = ir_alloc_stack(ir, irs->size, type_alignof(t));
492 497
 }
493 498
 
494 499
 void ir_init_sym(struct ir *ir, struct sym *sym)

+ 2 - 0
ir.h

@@ -145,6 +145,8 @@ 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 147
 
148
+void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
149
+
148 150
 void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size);
149 151
 void ir_emit_bzero(struct ir *ir, ssize_t offset, size_t size);
150 152