First off, here's an inconsistancy I found: In test.pasm
REDO: eq_i_ic I2, I4, DONE, NEXT
appears. Shouldn't this be comparing to a constant, not a register? It
became a little obvious when I made a few changes to the
assembler/disassembler to give more details about the data (and to allow
shortcuts like "add I1,I2,I3" to go to "add_i I1,I2,I3", etc)
There's 3 pieces: opcode_table, disassemble.pl and assemble.pl
The opcode_table patch changes the argument encoding to use these terms:
# i Integer constant
# I Integer register
# n Numeric constant
# N Numeric register
# s String constant?
# S String register
# D Destination
The opcodes definitions were changed accordingly.
Disassemble.pl takes the new definitions and prints things out a little
prettier (test.pbc):
00000000 time_i I1
00000008 set_i_ic I2 0
00000014 set_i_ic I3 1
00000020 set_i_ic I4 10000000
0000002c eq_i_ic I2 4 00000058 00000040
00000040 add_i I2 I2 I3
00000050 branch_ic 0000002c
00000058 time_i I5
00000060 print_i I1
00000068 print_i I5
00000070 print_i I2
00000078 sub_i I2 I5 I1
00000088 print_i I2
00000090 set_i_ic I1 3
0000009c mul_i I4 I4 I1
000000ac iton_n_i N1 I4
000000b8 iton_n_i N2 I2
000000c4 print_i I4
000000cc print_n N1
000000d4 print_i I2
000000dc print_n N2
000000e4 div_n N1 N1 N2
000000f4 print_n N1
It also skips the magic number, and skips (but doesn't handle) the
constant data. String registers aren't handled either...yet
assemble.pl: this just contains workarounds to the new opcode_table
format.
Brian
Lastly, here's the patch:
Index: assemble.pl
===================================================================
RCS file: /home/perlcvs/parrot/assemble.pl,v
retrieving revision 1.5
diff -u -r1.5 assemble.pl
--- assemble.pl 2001/09/10 17:30:29 1.5
+++ assemble.pl 2001/09/10 22:04:29
@@ -10,6 +10,15 @@
%pack_type = (i => 'l',
n => 'd',
);
+my %real_type=('i'=>'i',
+ 'n'=>'n',
+ 'N'=>'i',
+ 'I'=>'i',
+ 'S'=>'i',
+ 's'=>'i',
+ 'D'=>'i');
+
+
my $sizeof_packi = length(pack($pack_type{i},1024));
@@ -20,6 +29,7 @@
s/^\s+//;
next unless $_;
my ($code, $name, $args, @types) = split /\s+/, $_;
+ @types=map { $_ = $real_type{$_}} @types;
$opcodes{$name} = {CODE => $code,
ARGS => $args,
TYPES => [@types]
Index: disassemble.pl
===================================================================
RCS file: /home/perlcvs/parrot/disassemble.pl,v
retrieving revision 1.1
diff -u -r1.1 disassemble.pl
--- disassemble.pl 2001/08/29 12:07:02 1.1
+++ disassemble.pl 2001/09/10 22:04:29
@@ -7,10 +7,20 @@
my %unpack_type;
%unpack_type = (i => 'l',
+ I => 'l',
n => 'd',
+ N => 'l',
+ D => 'l',
+ S => 'l',
+ s => 'l',
);
my %unpack_size = (i => 4,
n => 8,
+ I => 4,
+ N => 4,
+ D => 4,
+ S => 4,
+ s => 4,
);
open OPCODES, "<opcode_table" or die "Can't get opcode table, $!/$^E";
@@ -28,16 +38,34 @@
}
}
+
$/ = \4;
+my $magic=<>;
+my $constants=<>;
+ $constants=<>;
+
+my $offset=0;
while (<>) {
$code = unpack 'l', $_;
$args = $opcodes[$code]{ARGS};
- print $opcodes[$code]{NAME};
+ my $op_offset=$offset;
+ print sprintf("%08x",$offset)," ",$opcodes[$code]{NAME};
+ $offset+=4;
+
if ($args) {
foreach (1..$args) {
local $/ = \$unpack_size{$opcodes[$code]{TYPES}[$_-1]};
$data = <>;
- print " ", unpack $unpack_type{$opcodes[$code]{TYPES}[$_-1]},
$data;+ $offset+=$ {$/ };
+ if($opcodes[$code]{TYPES}[$_-1] eq "N" ||
+ $opcodes[$code]{TYPES}[$_-1] eq "I") {
+ print " ",$opcodes[$code]{TYPES}[$_-1],unpack
$unpack_type{$opcodes[$code]{TYPES}[$_-1]}, $data;
+ } elsif($opcodes[$code]{TYPES}[$_-1] eq "D") {
+ # handle destination
+ print "
",sprintf("%08x",$op_offset+unpack($unpack_type{$opcodes[$code]{TYPES}[$_-1]},$data)*4);
+ } else {
+ print " ", unpack $unpack_type{$opcodes[$code]{TYPES}[$_-1]}, $data;
+ }
}
}
print "\n";
Index: opcode_table
===================================================================
RCS file: /home/perlcvs/parrot/opcode_table,v
retrieving revision 1.5
diff -u -r1.5 opcode_table
--- opcode_table 2001/09/10 15:48:36 1.5
+++ opcode_table 2001/09/10 22:04:30
@@ -9,61 +9,70 @@
# not the type of the register or anything. So N3 is still an i, since
that
# 3 specifying the register should be packed as an integer.
+# Revised arg types:
+# i Integer constant
+# I Integer register
+# n Numeric constant
+# N Numeric register
+# s String constant?
+# S String register
+# D Destination
+
# Integer ops
-6 set_i_ic 2 i i
-1 add_i 3 i i i
-7 sub_i 3 i i i
-8 mul_i 3 i i i
-9 div_i 3 i i i
-11 inc_i 1 i
-12 inc_i_ic 2 i i
+6 set_i_ic 2 I i
+1 add_i 3 I I I
+7 sub_i 3 I I I
+8 mul_i 3 I I I
+9 div_i 3 I I I
+11 inc_i 1 I
+12 inc_i_ic 2 I i
13 dec_i 1 i
-14 dec_i_ic 2 i i
+14 dec_i_ic 2 I i
# NUM ops
-16 set_n_nc 2 i n
-17 add_n 3 i i i
-18 sub_n 3 i i i
-19 mul_n 3 i i i
-20 div_n 3 i i i
-25 inc_n 1 i
-26 inc_n_nc 2 i n
-27 dec_n 1 i
-28 dec_n_nc 2 i n
+16 set_n_nc 2 N n
+17 add_n 3 N N N
+18 sub_n 3 N N N
+19 mul_n 3 N N N
+20 div_n 3 N N N
+25 inc_n 1 N
+26 inc_n_nc 2 N n
+27 dec_n 1 N
+28 dec_n_nc 2 N n
# String ops
-31 set_s_sc 2 i i
-32 print_s 1 i
-33 length_s_i 2 i i
-34 chopn_s_ic 2 i i
+31 set_s_sc 2 S D
+32 print_s 1 S
+33 length_s_i 2 S I
+34 chopn_s_ic 2 S i
# Comparators
-2 eq_i_ic 4 i i i i
-21 eq_n_ic 4 i i i i
+2 eq_i_ic 4 I i D D
+21 eq_n_ic 4 N i D D
# Flow control
0 end 0
-15 jump_i 1 i
-5 branch_ic 1 i
-10 if_i_ic 3 i i i
-24 if_n_ic 3 i i i
+15 jump_i 1 D
+5 branch_ic 1 D
+10 if_i_ic 3 I i D
+24 if_n_ic 3 N i D
# Convertors
-29 iton_n_i 2 i i
-30 ntoi_i_n 2 i i
+29 iton_n_i 2 N I
+30 ntoi_i_n 2 I N
# Miscellaneous and debugging ops
-3 time_i 1 i
-4 print_i 1 i
-22 time_n 1 i
-23 print_n 1 i
+3 time_i 1 I
+4 print_i 1 I
+22 time_n 1 N
+23 print_n 1 N
47 noop 0
# Register ops