-
Notifications
You must be signed in to change notification settings - Fork 0
/
elfasm2c
executable file
·80 lines (70 loc) · 3.75 KB
/
elfasm2c
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
#!/usr/bin/env php
<?php
include("common.php");
define('TEMPLATEFOLDER', realpath(__DIR__).'/_elfasm2c_templates');
// CODEGEN_SWITCH - It works and achieves ~500 000 000 iterations/s .
// It generates a giant while()( switch(){} } with a loop per 1 elf assembly instruction.
define('CODEGEN_SWITCH', 1);
// CODEGEN_DIRECT - EXPERIMENTAL !!! Should achieve nearly 1:1 mapping to native instructions.
// Should be several times faster than CODEGEN_GOTOS . It should produce code that can be
// further optimized by the C compiler down the line.
define('CODEGEN_DIRECT', 2);
$cpustate = [0,0,0, 0,0,0];
$showheader = $showfooter = true;
$codegenkind = CODEGEN_SWITCH;
for($i=1;$i<$argc;$i++) {
if($argv[$i]==='--help'){
echo "Usage: elfasm2c input.elf [OPTIONS] > input.c \n";
echo "Transpiles elfic assembly to equivalent C source code. \n";
echo "The generated C program can be compiled using g++/clang++ for example.\n";
echo "The goal is to run the native binary *several orders of magnitude* faster.\n";
echo "Options can be: \n";
echo " --help - Shows this help .\n";
echo " --hideheader - no header boilerplate in output. \n";
echo " --hidefooter - no footer boilerplate in output. \n";
echo " --reg Ridx=Rval - Set initial register Ridx to value Rval. \n";
echo " Can be given multiple times. \n";
echo " Example: --reg 0=1231 --reg 5=771 \n";
echo " ... sets both reg0=1231 and reg5=771 . \n";
echo "\n";
echo " --codegenswitch - Use the CODEGEN_SWITCH kind of generation . \n";
echo " This is the default mode. Moderately fast. \n";
echo "\n";
echo " --codegendirect - Use the CODEGEN_DIRECT kind of generation . \n";
echo " (it uses direct translations when possible, \n";
echo " and gotos for the jumps). \n";
echo " Experimental and more complex. \n";
echo " The generated code should be however \n";
echo " Super Duper Insanely Fast (tm) :-) \n";
echo "\n";
exit(0);
}
if($argv[$i]==='--hideheader') $showheader = false;
if($argv[$i]==='--hidefooter') $showfooter = false;
if($argv[$i]==='--reg'){
if($i+1>=$argc) die("Argument --reg need parameter of the form Ridx=Rval .\n");
[$ri, $rv] = explode('=', $argv[$i+1]);
$ri = (int) $ri; $rv = (int) $rv;
if( $ri < 0 || $ri > 5 ) die("Option --reg Ridx=Rval should have 0 <= Ridx <= 5 . Actual Ridx passed: {$ri} \n");
$cpustate[$ri] = $rv;
}
if($argv[$i]==='--codegenswitch') $codegenkind = CODEGEN_SWITCH;
if($argv[$i]==='--codegendirect') $codegenkind = CODEGEN_DIRECT;
}
$program = []; $ipidx =0;
$lines = read_input();
$c=0;
foreach($lines as $line){
[$cmd,$_rest] = explode(' ', $line);
$args = array_pad( line2digits($line), 3, 0);
if($cmd === '#ip'){ $ipidx = $args[0]; continue; }
$program[$c] = array_merge([$cmd], $args);
$c++;
}
function commentSeparatorLine(){ printf("////////////////////////////////////////////////////////////////////////////\n"); }
function stdoutMinusLine(){ return 'printf("--------------------------------------------------------------------------------------------------------\n");'; }
if($showheader) include(TEMPLATEFOLDER.'/header.php');
if($codegenkind === CODEGEN_DIRECT) include(TEMPLATEFOLDER.'/codegendirect.php');
if($codegenkind === CODEGEN_SWITCH) include(TEMPLATEFOLDER.'/codegenswitch.php');
if($showfooter) include(TEMPLATEFOLDER.'/footer.php');
exit(0);