ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/jit-amd64-unix.pl
Revision: 1.2
Committed: Sat Jun 11 15:30:21 2011 UTC (13 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.1: +3 -5 lines
Log Message:
*** empty log message ***

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_disp32 = 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_rm, $store, $offset) = @_;
28
29 if ($offset < -128 || $offset > 127) {
30 $mod_rm |= $modrm_disp16;
31 $offset = pack "V", $offset;
32 } elsif ($offset) {
33 $mod_rm |= $modrm_disp8;
34 $offset = pack "c", $offset;
35 } else {
36 $offset = "";
37 }
38
39 $insn[$store][$size] . (chr $mod_rm) . $offset
40 };
41
42 my $gencopy = sub {
43 my ($save) = shift;
44
45 # all perl variables must be within 32-bits of this address
46 my $curbase = $vars[$#vars >> 1][0];
47
48 my $code = "\x48\xbe" . pack "Q", $curbase; # mov imm64, %rsi
49
50 my $curslot = 0;
51
52 for (@vars) {
53 my ($addr, $slot, $size) = @$_;
54
55 my $slotofs = $slot - $curslot;
56
57 # the sort ensures that this condition and adjustment suffices
58 if ($slotofs > 127) {
59 my $adj = 256;
60 $code .= "\x48\x81\xc7" . pack "i", $adj; # add imm32, %rdi
61 $curslot += $adj;
62 $slotofs -= $adj;
63 }
64
65 if ($save) {
66 $code .= $mov_ind->($size, $modrm_rsi, 0, $addr - $curbase);
67 $code .= $mov_ind->($size, $modrm_rdi, 1, $slotofs);
68 } else {
69 $code .= $mov_ind->($size, $modrm_rdi, 0, $slotofs);
70 $code .= $mov_ind->($size, $modrm_rsi, 1, $addr - $curbase);
71 }
72 }
73
74 $code .= "\xc3"; # retq
75
76 $code
77 };
78
79 sub _jit {
80 @vars = @_;
81
82 # sort all variables into 256 byte blocks, biased by -128
83 # so gencopy can += 256 occasionally. within those blocks,
84 # sort by address so we can play further tricks.
85 @vars = sort {
86 (($a->[1] + 128) & ~255) <=> (($b->[1] + 128) & ~255)
87 or $a->[0] <=> $b->[0]
88 } @vars;
89
90 # we *could* combine adjacent vars, but this is not very common
91
92 $vars[-1][0] - $vars[0][0] <= 0x7fffffff
93 or die "JIT failed, perl var spread >31 bit\n";
94
95 my $load = $gencopy->(0);
96 my $save = $gencopy->(1);
97
98 #open my $fh, ">dat"; syswrite $fh, $save; system "objdump -b binary -m i386 -M x86-64 -D dat";
99 #warn length $load;
100 #warn length $save;
101
102 ($load, $save)
103 }
104 }
105
106 1