-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbinds.c
124 lines (100 loc) · 2.94 KB
/
binds.c
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
114
115
116
117
118
119
120
121
122
123
124
#include <stdlib.h>
#include <sys/mman.h>
#include <lightning.h>
/* This library contains function equivalents for the macros in GNU
lightning. Hopefully this will make it possible for Guile to use
them. */
/* this is a pseudo-register: it could actually be an Rn register. */
int reg_ret = JIT_RET;
/* three caller-save integer registers */
int reg_r0 = JIT_R0;
int reg_r1 = JIT_R1;
int reg_r2 = JIT_R2;
/* three callee-save integer registers */
int reg_v0 = JIT_V0;
int reg_v1 = JIT_V1;
int reg_v2 = JIT_V2;
/* six caller-save floating-point registers */
int reg_fpr0 = JIT_FPR0;
int reg_fpr1 = JIT_FPR1;
int reg_fpr2 = JIT_FPR2;
int reg_fpr3 = JIT_FPR3;
int reg_fpr4 = JIT_FPR4;
int reg_fpr5 = JIT_FPR5;
/* and a floating-point return register (unclear from the docs if it's
a pseudoregister or not - better assume it is) */
/* this is commented out because gcc didn't believe JIT_FPRET was
defined, and it's not really important to me. */
/* int reg_fpret = JIT_FPRET; */
/* Using this from Scheme will leak memory. */
jit_insn *make_instruction_array(int bytes)
{
jit_insn *array;
size_t pagesize, size;
pagesize = getpagesize();
size = (bytes/pagesize)*pagesize; /* these two lines together make */
if (size < bytes) size += pagesize; /* size the smallest multiple of */
/* pagesize that's >= bytes */
array = mmap(0, size, PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE, 0, 0);
if (array == MAP_FAILED) {
return NULL; /* todo: make better error convention. */
} else {
return array;
}
}
void *begin_function_in_buffer(jit_insn *buffer)
{
return jit_set_ip(buffer).iptr; /* it doesn't matter what type we
use because it'll be cast by the Guile
interface code anyway. */
/* the return value is also the pointer to the function which we
will hopefully construct in the buffer. */
}
void declare_leaf_function(int num_args)
{
jit_leaf(num_args);
}
int make_int_argument(void)
{
return jit_arg_i();
}
void retrieve_int_argument(int reg, int argument)
{
jit_getarg_i(reg, argument);
}
void move_integer_between_regs(int dest, int src)
{
jit_movr_i(dest, src);
}
void make_return(void)
{
jit_ret();
}
void flush_instruction_buffer(jit_insn *buffer)
{
jit_flush_code(buffer, jit_get_ip().ptr);
}
/*
typedef int (*pifi)(int);
int main(int argc, char *argv[])
{
jit_insn *insn_buffer = make_instruction_array(1024);
pifi pointer_to_beginning = begin_function_in_buffer(insn_buffer);
int arg;
pifi function;
if (insn_buffer == NULL) {
perror("Couldn't allocate instruction buffer");
exit(1);
}
declare_leaf_function(1);
arg = make_int_argument();
retrieve_int_argument(JIT_R0, arg);
move_integer_between_regs(JIT_RET, JIT_R0);
make_return();
flush_instruction_buffer(insn_buffer);
function = pointer_to_beginning;
printf("Ran function(1); got %d\n", function(1));
return 0;
}
*/