Browse Source

map lookup/bzero

Tobias Waldekranz.com 8 years ago
parent
commit
3e0e084c66
3 changed files with 52 additions and 23 deletions
  1. 27 5
      global.c
  2. 23 18
      ir.c
  3. 2 0
      ir.h

+ 27 - 5
global.c

135
                     be overwritten, so skip the load. */
135
                     be overwritten, so skip the load. */
136
 		return 0;
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
 	ir_emit_sym_to_reg(prog->ir, BPF_REG_3, ptr->sym);
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
 	return 0;
140
 	return 0;
145
 }
141
 }
146
 
142
 
232
 	ssize_t stack = map->sym->irs.stack;
228
 	ssize_t stack = map->sym->irs.stack;
233
 	size_t offset;
229
 	size_t offset;
234
 	struct tfield *f;
230
 	struct tfield *f;
231
+	int16_t lmiss, lhit;
235
 
232
 
236
 	arg = map->next;
233
 	arg = map->next;
237
 	tfields_foreach(f, ktype->sou.fields) {
234
 	tfields_foreach(f, ktype->sou.fields) {
239
 		ir_emit_sym_to_stack(prog->ir, stack + offset, arg->sym);
236
 		ir_emit_sym_to_stack(prog->ir, stack + offset, arg->sym);
240
 		arg = arg->next;
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
 	return 0;
264
 	return 0;
243
 }
265
 }
244
 
266
 

+ 23 - 18
ir.c

362
 		assert(0);
362
 		assert(0);
363
 	}
363
 	}
364
 }
364
 }
365
-#include "ply.h"
365
+
366
 void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src)
366
 void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src)
367
 {
367
 {
368
 	struct irstate *irs = &src->irs;
368
 	struct irstate *irs = &src->irs;
369
 
369
 
370
 	switch (irs->loc) {
370
 	switch (irs->loc) {
371
 	case LOC_IMM:
371
 	case LOC_IMM:
372
-		_d("WKZ %zu @ %zd (%d)\n", irs->size, offset, irs->imm);
373
 		ir_emit_insn(ir, ST_IMM(bpf_width(irs->size), offset, irs->imm),
372
 		ir_emit_insn(ir, ST_IMM(bpf_width(irs->size), offset, irs->imm),
374
 			     BPF_REG_BP, 0);
373
 			     BPF_REG_BP, 0);
375
 		break;
374
 		break;
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
 void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size)
402
 void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size)
388
 {
403
 {
389
 	if (dst == src)
404
 	if (dst == src)
469
 
484
 
470
 	irs->size = type_sizeof(t);
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
 		irs->loc = LOC_REG;
489
 		irs->loc = LOC_REG;
484
 		irs->reg = ir_alloc_register(ir);
490
 		irs->reg = ir_alloc_register(ir);
485
 		return;
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
 void ir_init_sym(struct ir *ir, struct sym *sym)
499
 void ir_init_sym(struct ir *ir, struct sym *sym)

+ 2 - 0
ir.h

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