ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/jit-amd64-unix.pl
Revision: 1.1
Committed: Sat Jun 11 13:01:26 2011 UTC (13 years ago) by root
Content type: text/plain
Branch: MAIN
Log Message:
jit, -ERRSV-DEFSV

File Contents

# Content
1 #!/opt/bin/perl
2
3 {
4 package Coro::State;
5
6 use common::sense;
7
8 my @insn;
9
10 $insn[0][1] = "\x0f\xb6"; # movzbl mem -> rax
11 $insn[0][2] = "\x0f\xb7"; # movzwl mem -> rax
12 $insn[0][4] = "\x8b"; # movl mem -> rax
13 $insn[0][8] = "\x48\x8b"; # movq mem -> rax
14 $insn[1][1] = "\x88"; # movb rax -> mem
15 $insn[1][2] = "\x66\x89"; # movw rax -> mem
16 $insn[1][4] = "\x89"; # movl rax -> mem
17 $insn[1][8] = "\x48\x89"; # movq rax -> mem
18
19 my $modrm_disp8 = 0x40;
20 my $modrm_disp16 = 0x80;
21 my $modrm_rsi = 0x06;
22 my $modrm_rdi = 0x07;
23
24 my @vars;
25
26 my $mov_ind = sub {
27 my ($size, $mod_reg, $store, $offset) = @_;
28
29 my $mod_rm = $mod_reg;
30
31 if ($offset < -128 || $offset > 127) {
32 $mod_rm |= $modrm_disp16;
33 $offset = pack "V", $offset;
34 } elsif ($offset) {
35 $mod_rm |= $modrm_disp8;
36 $offset = pack "c", $offset;
37 } else {
38 $offset = "";
39 }
40
41 $insn[$store][$size] . (chr $mod_rm) . $offset
42 };
43
44 my $gencopy = sub {
45 my ($save) = shift;
46
47 # all perl variables must be within 32-bits of this address
48 my $curbase = $vars[$#vars >> 1][0];
49
50 my $code = "\x48\xbe" . pack "Q", $curbase; # mov imm64, %rsi
51
52 my $curslot = 0;
53
54 for (@vars) {
55 my ($addr, $slot, $size) = @$_;
56
57 my $slotofs = $slot - $curslot;
58
59 # the sort ensures that this condition and adjustment suffice
60 if ($slotofs > 127) {
61 my $adj = 256;
62 $code .= "\x48\x81\xc7" . pack "i", $adj; # add imm32, %rdi
63 $curslot += $adj;
64 $slotofs -= $adj;
65 }
66
67 if ($save) {
68 $code .= $mov_ind->($size, $modrm_rsi, 0, $addr - $curbase);
69 $code .= $mov_ind->($size, $modrm_rdi, 1, $slotofs);
70 } else {
71 $code .= $mov_ind->($size, $modrm_rdi, 0, $slotofs);
72 $code .= $mov_ind->($size, $modrm_rsi, 1, $addr - $curbase);
73 }
74 }
75
76 $code .= "\xc3"; # retq
77
78 $code
79 };
80
81 sub _jit {
82 @vars = @_;
83
84 # sort all variables into 256 byte blocks, biased by -128
85 # so gencopy can += 256 occasionally. within those blocks,
86 # sort by address so we can play further tricks.
87 @vars = sort {
88 (($a->[1] + 128) & ~255) <=> (($b->[1] + 128) & ~255)
89 or $a->[0] <=> $b->[0]
90 } @vars;
91
92 # we *could* combine adjacent vars, but this is not very common
93
94 $vars[-1][0] - $vars[0][0] <= 0x7fffffff
95 or die "JIT failed, perl var spread >31 bit\n";
96
97 my $load = $gencopy->(0);
98 my $save = $gencopy->(1);
99
100 #open my $fh, ">dat"; syswrite $fh, $save; system "objdump -b binary -m i386 -M x86-64 -D dat";
101 #warn length $load;
102 #warn length $save;
103
104 ($load, $save)
105 }
106 }
107
108 1