-
Notifications
You must be signed in to change notification settings - Fork 0
/
asmspec.pl
executable file
·114 lines (82 loc) · 2.33 KB
/
asmspec.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/usr/bin/env perl
use strict;
use warnings;
# Global hashmap to store rules
my %rules;
while (my $line = <STDIN>) {
chomp $line;
# Ignore comments
next if $line =~ /^\s*--/;
# Parse and process rule
if ($line =~ /^\s*%asm-cond/) {
my ($opcode, $operands, $action) = parse_rule($line);
if (defined $opcode) {
$rules{$opcode} = { operands => $operands, action => $action };
}
}
}
# Print parsed rules
print "Parsed Specifications:\n";
foreach my $opcode (keys %rules) {
print "Opcode: $opcode\n";
my $operands = $rules{$opcode}->{operands};
my $action = $rules{$opcode}->{action};
# Print each operand with its type
for my $operand (@$operands) {
my ($type, $value) = @$operand;
print " $type: $value\n";
}
print "Action: $action\n";
print "------------------------\n";
}
sub parse_rule {
my ($line) = @_;
# Parse condition
my ($opcode, $operands) = parse_condition($line);
return unless defined $opcode;
# Parse action
my $action = parse_action($line);
return unless defined $action;
return ($opcode, $operands, $action);
}
sub parse_action {
my ($line) = @_;
return unless $line =~ /\{\{(.+?)\}\}/;
return $1;
}
sub parse_condition {
my ($line) = @_;
return unless $line =~ /^\s*%asm-cond\s+(\w+)\s+(.+)\s+=>/;
my $opcode = $1;
my $operand_str = $2;
# Parse operand list
my @operands = parse_operand_list($operand_str);
return unless @operands;
return ($opcode, \@operands);
}
sub parse_operand_list {
my ($operand_str) = @_;
my @operands;
my @tokens = split /\s*,\s*/, $operand_str;
foreach my $token (@tokens) {
my $operand = parse_operand($token);
return unless defined $operand;
push @operands, $operand;
}
return @operands;
}
sub parse_operand {
my ($token) = @_;
return unless $token =~ /%reg|%imm/;
my $type = $token =~ /%reg/ ? 'reg' : 'imm';
my $value = $type eq 'reg' ? parse_register($token) : parse_immediate($token);
return $value ? [ $type, $value ] : undef;
}
sub parse_register {
my ($token) = @_;
return $1 if $token =~ /^\s*%reg\s*\(\s*(\w+)\s*\)/;
}
sub parse_immediate {
my ($token) = @_;
return $1 if $token =~ /^\s*%imm(?:\s*\(\s*(\w+)\s*\)\s*)?/;
}