浏览代码

basic vreg->r0-9 replacement

Tobias Waldekranz.com 8 年之前
父节点
当前提交
256174d880
共有 3 个文件被更改,包括 81 次插入33 次删除
  1. 75 29
      ir.c
  2. 4 3
      ir.h
  3. 2 1
      ply.c

+ 75 - 29
ir.c

6
 #include <linux/bpf.h>
6
 #include <linux/bpf.h>
7
 
7
 
8
 #include "ir.h"
8
 #include "ir.h"
9
+#include "ply.h"
9
 #include "sym.h"
10
 #include "sym.h"
10
 #include "type.h"
11
 #include "type.h"
11
 
12
 
225
 		offset_dump(vi->label, fp);
226
 		offset_dump(vi->label, fp);
226
 		fputc(':', fp);
227
 		fputc(':', fp);
227
 		return;
228
 		return;
228
-	case VI_REG_GET:
229
-	case VI_REG_PUT:
230
-		fputs((vi->vitype == VI_REG_GET) ? "+ " : "- ", fp);
231
-		reg_dump(vi->reg, 0, fp);
232
-		return;
233
 	}
229
 	}
234
 }
230
 }
235
 
231
 
245
 		case VI_LDMAP:
241
 		case VI_LDMAP:
246
 			fputc('\t', fp);
242
 			fputc('\t', fp);
247
 			break;
243
 			break;
248
-		case VI_REG_GET:
249
-		case VI_REG_PUT:
250
-			fputs("\e[2m", fp);
251
 		case VI_LABEL:
244
 		case VI_LABEL:
252
 		default:
245
 		default:
253
 			break;
246
 			break;
255
 
248
 
256
 		vinsn_dump(vi, fp);
249
 		vinsn_dump(vi, fp);
257
 
250
 
258
-		/* print multiple gets/puts on one line */
259
-		switch (vi->vitype) {
260
-		case VI_REG_GET:
261
-			for (; (vi + 1)->vitype == VI_REG_GET; vi++, i++) {
262
-				fputs(", ", fp);
263
-				reg_dump((vi + 1)->reg, 0, fp);
264
-			}
265
-			fputs("\e[0m", fp);
266
-			break;
267
-		case VI_REG_PUT:
268
-			for (; (vi + 1)->vitype == VI_REG_PUT; vi++, i++) {
269
-				fputs(", ", fp);
270
-				reg_dump((vi + 1)->reg, 0, fp);
271
-			}
272
-			fputs("\e[0m", fp);
273
-			break;
274
-		default:
275
-			break;
276
-		}
277
-
278
 		fputc('\n', fp);
251
 		fputc('\n', fp);
279
 	}
252
 	}
280
 }
253
 }
534
 	return ir;
507
 	return ir;
535
 }
508
 }
536
 
509
 
510
+static void ir_bpf_vreg_replace(struct ir *ir, struct vinsn *last, int reg)
511
+{
512
+	struct vinsn *vi;
513
+
514
+	_d("ir_bpf_generate: v%d -> r%d\n", last->insn.src & ~vreg_base, reg);
515
+
516
+	for (vi = ir->vi; vi <= last; vi++) {
517
+		if (vi->vitype != VI_INSN)
518
+			continue;
519
+
520
+		if (vi->insn.dst == last->insn.src)
521
+			vi->insn.dst = reg;
522
+		if (vi->insn.src == last->insn.src)
523
+			vi->insn.src = reg;
524
+	}	
525
+}
537
 
526
 
538
 
527
 
539
-int ir_generate_bpf(struct ir *ir)
528
+int ir_bpf_registerize_one(struct ir *ir, struct vinsn *last)
540
 {
529
 {
530
+	struct vinsn *vi;
531
+	uint16_t clean = 0x3ff;
532
+
533
+	for (vi = ir->vi; clean && (vi < last); vi++) {
534
+		if (vi->vitype != VI_INSN)
535
+			continue;
536
+
537
+		if (!(vi->insn.src & vreg_base))
538
+			clean &= ~(1 << vi->insn.src);
539
+		if (!(vi->insn.dst & vreg_base))
540
+			clean &= ~(1 << vi->insn.dst);
541
+		if (vi->insn.bpf.code == (BPF_JMP | BPF_CALL))
542
+			clean &= ~BPF_REG_CALLER_SAVE;
543
+	}
544
+
545
+	if (clean) {
546
+		int reg;
547
+
548
+		for (reg = BPF_REG_0; !(clean & 1); clean >>= 1, reg++);
549
+
550
+		ir_bpf_vreg_replace(ir, last, reg);
551
+		return 0;
552
+	}
553
+
554
+	/* TODO ir_bpf_vreg_spill(ir, last); */
555
+	return -1;
556
+}
557
+
558
+int ir_bpf_registerize(struct ir *ir)
559
+{
560
+	struct vinsn *vi;
561
+	int err = 0;
562
+
563
+	if (!ir->len)
564
+		return 0;
565
+	
566
+	for (vi = &ir->vi[ir->len - 1]; vi >= ir->vi; vi--) {
567
+		if (vi->vitype != VI_INSN)
568
+			continue;
569
+
570
+		if (vi->insn.src & vreg_base) {
571
+			err = ir_bpf_registerize_one(ir, vi);
572
+			if (err)
573
+				return err;
574
+		}
575
+	}
576
+	return err;
577
+}
578
+
579
+int ir_bpf_generate(struct ir *ir)
580
+{
581
+	int err;
582
+
583
+	err = ir_bpf_registerize(ir);
584
+	if (err)
585
+		return err;
586
+
541
 	return 0;
587
 	return 0;
542
 }
588
 }

+ 4 - 3
ir.h

53
 
53
 
54
 #define BPF_REG_BP BPF_REG_10
54
 #define BPF_REG_BP BPF_REG_10
55
 
55
 
56
+/* r0 is return value and r1-r5 are used for arguments */
57
+#define BPF_REG_CALLER_SAVE 0x3f
58
+
56
 static inline int bpf_width(size_t size)
59
 static inline int bpf_width(size_t size)
57
 {
60
 {
58
 	switch (size) {
61
 	switch (size) {
72
 	VI_INSN,
75
 	VI_INSN,
73
 	VI_LDMAP,
76
 	VI_LDMAP,
74
 	VI_LABEL,
77
 	VI_LABEL,
75
-	VI_REG_GET,
76
-	VI_REG_PUT,
77
 };
78
 };
78
 
79
 
79
 struct vinsn {
80
 struct vinsn {
153
 
154
 
154
 struct ir *ir_new(void);
155
 struct ir *ir_new(void);
155
 
156
 
156
-int ir_generate_bpf(struct ir *ir);
157
+int ir_bpf_generate(struct ir *ir);
157
 
158
 
158
 #endif	/* _PLY_IR_H */
159
 #endif	/* _PLY_IR_H */

+ 2 - 1
ply.c

270
 	for (progp = ctx->progs; *progp; progp++) {
270
 	for (progp = ctx->progs; *progp; progp++) {
271
 		struct prog *prog = *progp;
271
 		struct prog *prog = *progp;
272
 
272
 
273
-		err = ir_generate_bpf(prog->ir);
273
+		err = ir_bpf_generate(prog->ir);
274
 		if (err)
274
 		if (err)
275
 			return err;
275
 			return err;
276
 	}
276
 	}
290
 	{ .run = run_ir },
290
 	{ .run = run_ir },
291
 	/* program flattened to vBPF instructions, now rewrite it to
291
 	/* program flattened to vBPF instructions, now rewrite it to
292
 	 * fit into the actual hw/vm. */
292
 	 * fit into the actual hw/vm. */
293
+	{ .run = run_bpf },
293
 
294
 
294
 	/* BPF program ready */
295
 	/* BPF program ready */
295
 	{ NULL }
296
 	{ NULL }