Skip to content

Commit

Permalink
[JIT] Parse oplist as a module
Browse files Browse the repository at this point in the history
I want to have access to the type and size information in the expression
template compiler, so I want to access the oplist information first.
  • Loading branch information
bdw committed Jun 29, 2018
1 parent 160925a commit a75746f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 21 deletions.
4 changes: 3 additions & 1 deletion build/Makefile.in
Expand Up @@ -626,7 +626,9 @@ src/jit/x64/emit@obj@: src/jit/x64/emit.c $(DYNASM_HEADERS)
src/jit/x64/emit.c: src/jit/x64/emit.dasc src/jit/x64/tiles.dasc $(MINILUA) $(DYNASM_SCRIPTS)

# Expression list tables
src/jit/core_templates.h: src/jit/core_templates.expr src/jit/macro.expr tools/expr-template-compiler.pl src/core/oplist src/jit/expr_ops.h
src/jit/core_templates.h: src/jit/core_templates.expr src/jit/macro.expr \
tools/expr-template-compiler.pl tools/sexpr.pm tools/expr_ops.pm tools/oplist.pm \
src/core/oplist src/jit/expr_ops.h

# Architecture-specific tiles
src/jit/x64/tile_pattern.h: src/jit/x64/tile_pattern.tile tools/tiler-table-generator.pl src/jit/expr_ops.h
Expand Down
2 changes: 1 addition & 1 deletion src/jit/expr.c
Expand Up @@ -331,7 +331,7 @@ static void check_template(MVMThreadContext *tc, const MVMJitExprTemplate *templ
if (template->code[i] < 0 ||
(template->code[i] >= ins->info->num_operands &&
!ins_has_single_input_output_operand(ins)))
MVM_oops(tc, "JIT: Operand access out of bounds (instruction: %s)", ins->info->name);
MVM_oops(tc, "JIT: Operand access (%d) out of bounds (instruction: %s)", template->code[i], ins->info->name);
break;
default:
continue;
Expand Down
30 changes: 11 additions & 19 deletions tools/expr-template-compiler.pl
Expand Up @@ -14,6 +14,7 @@

use sexpr;
use expr_ops;
use oplist;


# Input:
Expand Down Expand Up @@ -130,7 +131,7 @@ sub validate_template {
die "Can't match up types";
}
}
use Data::Dumper;


for (my $i = 0; $i < $nchild; $i++) {
my $child = $template->[$offset+$i];
Expand Down Expand Up @@ -313,18 +314,8 @@ sub write_template {
}


# first read the correct order of opcodes
my (@opcodes, %names);
{
open( my $oplist, '<', $OPLIST ) or die $!;
while (<$oplist>) {
next unless (m/^\w+/);
my $opcode = substr $_, 0, $+[0];
push @opcodes, $opcode;
$names{$opcode} = $#opcodes;
}
close( $oplist ) or die $!;
}
# first read the correct order of opcodes
my %OPNAMES = map { $OPLIST[$_][0] => $_ } keys @OPLIST;

my %SEEN;

Expand All @@ -347,10 +338,10 @@ sub parse_file {
$opcode = substr $opcode, 0, -1;
$flags |= 1;
}
die "Opcode '$opcode' unknown" unless defined $names{$opcode};
die "Opcode '$opcode' unknown" unless defined $OPNAMES{$opcode};
die "Opcode '$opcode' redefined" if defined $info{$opcode};
# Validate template for consistency with expr.h node definitions
validate_template($template);
validate_template($template, $OPLIST{$opcode});
my $compiled = compile_template($template);

$info{$opcode} = {
Expand Down Expand Up @@ -408,9 +399,10 @@ sub parse_file {
}
print "\n};\n";
print "static const MVMJitExprTemplate MVM_jit_expr_template_info[] = {\n";
for (@opcodes) {
if (defined($info->{$_})) {
my $td = $info->{$_};
for my $opcode (@OPLIST) {
my ($name) = @$opcode;
if (defined($info->{$name})) {
my $td = $info->{$name};
printf ' { MVM_jit_expr_templates + %d, "%s", %d, %d, %d },%s',
$td->{idx}, $td->{info}, $td->{len}, $td->{root}, $td->{flags}, "\n";
} else {
Expand All @@ -424,7 +416,7 @@ sub parse_file {
print " $_,\n" for @constants;
print "};\n";

printf <<'FOOTER', scalar @opcodes;
printf <<'FOOTER', scalar @OPLIST;
static const MVMJitExprTemplate * MVM_jit_get_template_for_opcode(MVMuint16 opcode) {
if (opcode >= %d) return NULL;
if (MVM_jit_expr_template_info[opcode].len < 0) return NULL;
Expand Down
50 changes: 50 additions & 0 deletions tools/oplist.pm
@@ -0,0 +1,50 @@
package oplist;
use strict;
use warnings;
use Data::Dumper;
use File::Spec;
use constant OPLIST => do {
my ($path, $directory, $filename) = File::Spec->splitpath(__FILE__);
File::Spec->catpath($path, File::Spec->catdir($directory, File::Spec->updir(), qw(src core)), 'oplist');
};
# Parse MoarVM oplist file and stash it in @OPLIST and %OPLIST
sub parse_oplist {
my ($fh) = @_;
my @oplist;
while (<$fh>) {
# remove comments and skip empty strings
chomp and s/#.*$//;
next unless length;
my ($name, @meta) = split /\s+/;
my ($attribute, @operands, @adverbs);
for (@meta) {
if (m/^[-+.:*]\w$/) {
$attribute = $_;
} elsif (m/^:\w+$/) {
push @adverbs, $_;
} else {
push @operands, $_;
}
}
push @oplist, [ $name, $attribute, \@operands, \@adverbs ];
}
return @oplist;
}

sub import {
my ($class, $file) = (@_, OPLIST);
open my $fh, '<', $file or die $!;
my @oplist = parse_oplist($fh);
my %oplist = map {
$_->[0] => { attr => $_->[1], operands => $_->[2], adverbs => $_->[3] }
} @oplist;
my ($caller) = caller();
{
no strict 'refs';
*{$caller . '::OPLIST'} = \@oplist;
*{$caller . '::OPLIST'} = \%oplist;
}
close $fh;
}

1;

0 comments on commit a75746f

Please sign in to comment.