|
|
@@ -6,6 +6,7 @@
|
|
6
|
6
|
#include <linux/bpf.h>
|
|
7
|
7
|
|
|
8
|
8
|
#include "ir.h"
|
|
|
9
|
+#include "ply.h"
|
|
9
|
10
|
#include "sym.h"
|
|
10
|
11
|
#include "type.h"
|
|
11
|
12
|
|
|
|
@@ -225,11 +226,6 @@ void vinsn_dump(struct vinsn *vi, FILE *fp)
|
|
225
|
226
|
offset_dump(vi->label, fp);
|
|
226
|
227
|
fputc(':', fp);
|
|
227
|
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,9 +241,6 @@ void ir_dump(struct ir *ir, FILE *fp)
|
|
245
|
241
|
case VI_LDMAP:
|
|
246
|
242
|
fputc('\t', fp);
|
|
247
|
243
|
break;
|
|
248
|
|
- case VI_REG_GET:
|
|
249
|
|
- case VI_REG_PUT:
|
|
250
|
|
- fputs("\e[2m", fp);
|
|
251
|
244
|
case VI_LABEL:
|
|
252
|
245
|
default:
|
|
253
|
246
|
break;
|
|
|
@@ -255,26 +248,6 @@ void ir_dump(struct ir *ir, FILE *fp)
|
|
255
|
248
|
|
|
256
|
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
|
251
|
fputc('\n', fp);
|
|
279
|
252
|
}
|
|
280
|
253
|
}
|
|
|
@@ -534,9 +507,82 @@ struct ir *ir_new(void)
|
|
534
|
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
|
587
|
return 0;
|
|
542
|
588
|
}
|