LMMS
Loading...
Searching...
No Matches
glue_aarch64.h
Go to the documentation of this file.
1#ifndef _NSEEL_GLUE_AARCH64_H_
2#define _NSEEL_GLUE_AARCH64_H_
3
4// x0=return value, first parm, x1-x2 parms (x3-x7 more params)
5// x8 return struct?
6// x9-x15 temporary
7// x16-x17 = PLT, linker
8// x18 reserved (TLS)
9// x19-x28 callee-saved
10// x19 = worktable
11// x20 = ramtable
12// x21 = consttab
13// x22 = worktable ptr
14// x23-x28 spare
15// x29 frame pointer
16// x30 link register
17// x31 SP/zero
18
19// x0=p1
20// x1=p2
21// x2=p3
22
23// d0 is return value for fp?
24// d/v/f0-7 = arguments/results
25// 8-15 callee saved
26// 16-31 temporary
27
28// v8-v15 spill registers
29#define GLUE_MAX_SPILL_REGS 8
30#define GLUE_SAVE_TO_SPILL_SIZE(x) (4)
31#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4)
32
33static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
34{
35 *(unsigned int *)b = 0x1e604101 + (ws<<5); // fmov d1, d8+ws
36}
37static void GLUE_SAVE_TO_SPILL(void *b, int ws)
38{
39 *(unsigned int *)b = 0x1e604008 + ws; // fmov d8+ws, d0
40}
41
42
43#define GLUE_HAS_FPREG2 1
44
45static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[] = { 0x1e604001 }; // fmov d1, d0
46static unsigned int GLUE_POP_STACK_TO_FPREG2[] = {
47 0xfc4107e1 // ldr d1, [sp], #16
48};
49
50#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
51#define GLUE_MAX_JMPSIZE ((1<<20) - 1024) // maximum relative jump size
52
53// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
54// 0 = current instruction
55static void GLUE_JMP_SET_OFFSET(void *endOfInstruction, int offset)
56{
57 unsigned int *a = (unsigned int*) endOfInstruction - 1;
58 offset += 4;
59 offset >>= 2; // as dwords
60 if ((a[0] & 0xFC000000) == 0x14000000)
61 {
62 // NC b = 0x14 + 26 bit offset
63 a[0] = 0x14000000 | (offset & 0x3FFFFFF);
64 }
65 else if ((a[0] & 0xFF000000) == 0x54000000)
66 {
67 // condb = 0x54 + 20 bit offset + 5 bit condition: 0=eq, 1=ne, b=lt, c=gt, d=le, a=ge
68 a[0] = 0x54000000 | (a[0] & 0xF) | ((offset & 0x7FFFF) << 5);
69 }
70}
71
72static const unsigned int GLUE_JMP_NC[] = { 0x14000000 };
73
74static const unsigned int GLUE_JMP_IF_P1_Z[]=
75{
76 0x7100001f, // cmp w0, #0
77 0x54000000, // b.eq
78};
79static const unsigned int GLUE_JMP_IF_P1_NZ[]=
80{
81 0x7100001f, // cmp w0, #0
82 0x54000001, // b.ne
83};
84
85#define GLUE_MOV_PX_DIRECTVALUE_TOFPREG2_SIZE 16 // wr=-2, sets d1
86#define GLUE_MOV_PX_DIRECTVALUE_SIZE 12
87static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
88{
89 static const unsigned int tab[3] = {
90 0xd2800000, // mov x0, #0000 (val<<5) | reg
91 0xf2a00000, // movk x0, #0000, lsl 16 (val<<5) | reg
92 0xf2c00000, // movk x0, #0000, lsl 32 (val<<5) | reg
93 };
94 // 0xABAAA, B is register, A are bits of word
95 unsigned int *p=(unsigned int *)b;
96 int wvo = wv;
97 if (wv<0) wv=0;
98 p[0] = tab[0] | wv | ((v&0xFFFF)<<5);
99 p[1] = tab[1] | wv | (((v>>16)&0xFFFF)<<5);
100 p[2] = tab[2] | wv | (((v>>32)&0xFFFF)<<5);
101 if (wvo == -2) p[3] = 0xfd400001; // ldr d1, [x0]
102}
103
104const static unsigned int GLUE_FUNC_ENTER[2] = { 0xa9bf7bfd, 0x910003fd }; // stp x29, x30, [sp, #-16]! ; mov x29, sp
105#define GLUE_FUNC_ENTER_SIZE 4
106const static unsigned int GLUE_FUNC_LEAVE[1] = { 0 }; // let GLUE_RET pop
107#define GLUE_FUNC_LEAVE_SIZE 0
108const static unsigned int GLUE_RET[]={ 0xa8c17bfd, 0xd65f03c0 }; // ldp x29,x30, [sp], #16 ; ret
109
110static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
111{
112 const static unsigned int GLUE_SET_WTP_FROM_R19 = 0xaa1303f6; // mov r22, r19
113 if (out) memcpy(out,&GLUE_SET_WTP_FROM_R19,sizeof(GLUE_SET_WTP_FROM_R19));
114 return 4;
115}
116
117
118const static unsigned int GLUE_PUSH_P1[1]={ 0xf81f0fe0 }; // str x0, [sp, #-16]!
119
120#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(offs) ((offs)>=32768 ? 8 : 4)
121static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
122{
123 if (offs >= 32768)
124 {
125 // add x1, sp, (offs/4096) lsl 12
126 *(unsigned int *)b = 0x914003e1 + ((offs>>12)<<10);
127
128 // str x0, [x1, #offs & 4095]
129 offs &= 4095;
130 offs <<= 10-3;
131 offs &= 0x7FFC00;
132 ((unsigned int *)b)[1] = 0xf9000020 + offs;
133 }
134 else
135 {
136 // str x0, [sp, #offs]
137 offs <<= 10-3;
138 offs &= 0x7FFC00;
139 *(unsigned int *)b = 0xf90003e0 + offs;
140 }
141}
142
143#define GLUE_MOVE_PX_STACKPTR_SIZE 4
144static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
145{
146 // mov xX, sp
147 *(unsigned int *)b = 0x910003e0 + wv;
148}
149
150#define GLUE_MOVE_STACK_SIZE 4
151static void GLUE_MOVE_STACK(void *b, int amt)
152{
153 if (amt>=0)
154 {
155 if (amt >= 4096)
156 *(unsigned int*)b = 0x914003ff | (((amt+4095)>>12)<<10);
157 else
158 *(unsigned int*)b = 0x910003ff | (amt << 10);
159 }
160 else
161 {
162 amt = -amt;
163 if (amt >= 4096)
164 *(unsigned int*)b = 0xd14003ff | (((amt+4095)>>12)<<10);
165 else
166 *(unsigned int*)b = 0xd10003ff | (amt << 10);
167 }
168}
169
170#define GLUE_POP_PX_SIZE 4
171static void GLUE_POP_PX(void *b, int wv)
172{
173 ((unsigned int *)b)[0] = 0xf84107e0 | wv; // ldr x, [sp], 16
174}
175
176#define GLUE_SET_PX_FROM_P1_SIZE 4
177static void GLUE_SET_PX_FROM_P1(void *b, int wv)
178{
179 *(unsigned int *)b = 0xaa0003e0 | wv;
180}
181
182
183static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] =
184{
185 0xfd400007, // ldr d7, [x0]
186 0xfc1f0fe7, // str d7, [sp, #-16]!
187};
188
189static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
190{
191 if (buf)
192 {
193 unsigned int *bufptr = (unsigned int *)buf;
194 *bufptr++ = 0xfc4107e7; // ldr d7, [sp], #16
195 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
197 *bufptr++ = 0xfd000007; // str d7, [x0]
198 }
199 return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
200}
201
202static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
203{
204 if (buf)
205 {
206 unsigned int *bufptr = (unsigned int *)buf;
207 *bufptr++ = 0xfd400007; // ldr d7, [x0]
208 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
210 *bufptr++ = 0xfd000007; // str d7, [x0]
211 }
212 return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
213}
214
215
216#ifndef _MSC_VER
217#define GLUE_CALL_CODE(bp, cp, rt) do { \
218 unsigned long f; \
219 if (!(h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) && \
220 !((f=glue_getscr())&(1<<24))) { \
221 glue_setscr(f|(1<<24)); \
222 eel_callcode64(bp, cp, rt); \
223 glue_setscr(f); \
224 } else eel_callcode64(bp, cp, rt);\
225 } while(0)
226
228{
229 //fwrite((void *)cp,4,20,stdout);
230 //return;
231 static const double consttab[] = {
233 0.0,
234 1.0,
235 -1.0,
236 -0.5, // for invsqrt
237 1.5,
238 };
239 __asm__(
240 "mov x1, %2\n"
241 "mov x2, %3\n"
242 "mov x3, %1\n"
243 "mov x0, %0\n"
244 "stp x29, x30, [sp, #-64]!\n"
245 "stp x18, x20, [sp, 16]\n"
246 "stp x21, x19, [sp, 32]\n"
247 "stp x22, x23, [sp, 48]\n"
248 "mov x29, sp\n"
249 "mov x19, x3\n"
250 "mov x20, x1\n"
251 "mov x21, x2\n"
252 "blr x0\n"
253 "ldp x29, x30, [sp], 16\n"
254 "ldp x18, x20, [sp], 16\n"
255 "ldp x21, x19, [sp], 16\n"
256 "ldp x22, x23, [sp], 16\n"
257 ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab) :"x0","x1","x2","x3","x4","x5","x6","x7",
258 "x8","x9","x10","x11","x12","x13","x14","x15",
259 "v8","v9","v10","v11","v12","v13","v14","v15");
260
261};
262#endif
263
264static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
265{
266 unsigned int *p=(unsigned int *)_p;
267// 0xd2800000, // mov x0, #0000 (val<<5) | reg
268 // 0xf2a00000, // movk x0, #0000, lsl 16 (val<<5) | reg
269 // 0xf2c00000, // movk x0, #0000, lsl 32 (val<<5) | reg
270 while (((p[0]>>5)&0xffff)!=0xdead ||
271 ((p[1]>>5)&0xffff)!=0xbeef ||
272 ((p[2]>>5)&0xffff)!=0xbeef) p++;
273
274 p[0] = (p[0] & 0xFFE0001F) | ((newv&0xffff)<<5);
275 p[1] = (p[1] & 0xFFE0001F) | (((newv>>16)&0xffff)<<5);
276 p[2] = (p[2] & 0xFFE0001F) | (((newv>>32)&0xffff)<<5);
277
278 return (unsigned char *)(p+2);
279}
280
281#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
282static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
283{
284 *(unsigned int *)b = 0xaa1603e0 + wv; // mov x, x22
285}
286
287static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
288{
289 if (buf)
290 {
291 unsigned int *bufptr = (unsigned int *)buf;
292 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
294
295 *bufptr++ = 0xfd000000; // str d0, [x0]
296 }
297 return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
298}
299
300#define GLUE_POP_FPSTACK_SIZE 0
301static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
302
303static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
304 0xfc1f0fe0, // str d0, [sp, #-16]!
305
306};
307
308static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
309 0xfc0086c0, // str d0, [x22], #8
310};
311
312#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
313static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
314{
315 *(unsigned int *)b = 0xfd400000 + (wv<<5); // ldr d0, [xX]
316}
317
318#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
319static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
320{
321 GLUE_SET_PX_FROM_WTP(buf,wv);
323};
324
325static const unsigned int GLUE_SET_P1_Z[] = { 0x52800000 }; // mov w0, #0
326static const unsigned int GLUE_SET_P1_NZ[] = { 0x52800020 }; // mov w0, #1
327
328
329static void *GLUE_realAddress(void *fn, int *size)
330{
331 while ((*(int*)fn & 0xFC000000) == 0x14000000)
332 {
333 int offset = (*(int*)fn & 0x3FFFFFF);
334 if (offset & 0x2000000)
335 offset |= 0xFC000000;
336
337 fn = (int*)fn + offset;
338 }
339 static const unsigned int sig[3] = { 0xaa0003e0, 0xaa0103e1, 0xaa0203e2 };
340 unsigned char *p = (unsigned char *)fn;
341
342 while (memcmp(p,sig,sizeof(sig))) p+=4;
343 p+=sizeof(sig);
344 fn = p;
345
346 while (memcmp(p,sig,sizeof(sig))) p+=4;
347 *size = p - (unsigned char *)fn;
348 return fn;
349}
350
351
352static unsigned long __attribute__((unused)) glue_getscr()
353{
354 unsigned long rv;
355 asm volatile ( "mrs %0, fpcr" : "=r" (rv));
356 return rv;
357}
358static void __attribute__((unused)) glue_setscr(unsigned long v)
359{
360 asm volatile ( "msr fpcr, %0" :: "r"(v));
361}
362
363void eel_enterfp(int _s[2])
364{
365 unsigned long *s = (unsigned long*)_s;
366 s[0] = glue_getscr();
367 glue_setscr(s[0] | (1<<24));
368}
369void eel_leavefp(int _s[2])
370{
371 unsigned long *s = (unsigned long*)_s;
372 glue_setscr(s[0]);
373}
374
375#define GLUE_HAS_FUSE 1
376static int GLUE_FUSE(compileContext *ctx, unsigned char *code, int left_size, int right_size, int fuse_flags, int spill_reg)
377{
378 if (left_size>=4 && right_size == 4)
379 {
380 unsigned int instr = ((unsigned int *)code)[-1];
381 if (spill_reg >= 0 && (instr & 0xfffffc1f) == 0x1e604001) // fmov d1, dX
382 {
383 const int src_reg = (instr>>5)&0x1f;
384 if (src_reg == spill_reg + 8)
385 {
386 instr = ((unsigned int *)code)[0];
387 if ((instr & 0xffffcfff) == 0x1e600820)
388 {
389 ((unsigned int *)code)[-1] = instr + ((src_reg-1) << 5);
390 return -4;
391 }
392 }
393 }
394 }
395 return 0;
396}
397
398
399#endif
uint8_t a
Definition Spc_Cpu.h:141
unsigned v[N_MAX]
Definition inflate.c:1584
unsigned s
Definition inflate.c:1555
void(* eel_leavefp)(int s[2])
Definition eel_import.h:43
void(* eel_enterfp)(int s[2])
Definition eel_import.h:42
static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[]
Definition glue_aarch64.h:183
static void GLUE_MOVE_STACK(void *b, int amt)
Definition glue_aarch64.h:151
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
Definition glue_aarch64.h:282
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
Definition glue_aarch64.h:319
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
Definition glue_aarch64.h:87
static const unsigned int GLUE_POP_FPSTACK_TOSTACK[]
Definition glue_aarch64.h:303
static const unsigned int GLUE_POP_FPSTACK[1]
Definition glue_aarch64.h:301
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
Definition glue_aarch64.h:33
#define GLUE_SET_PX_FROM_WTP_SIZE
Definition glue_aarch64.h:281
static void * GLUE_realAddress(void *fn, int *size)
Definition glue_aarch64.h:329
static const unsigned int GLUE_FUNC_LEAVE[1]
Definition glue_aarch64.h:106
static const unsigned int GLUE_POP_FPSTACK_TO_WTP[]
Definition glue_aarch64.h:308
#define GLUE_MOV_PX_DIRECTVALUE_SIZE
Definition glue_aarch64.h:86
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
Definition glue_aarch64.h:110
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
Definition glue_aarch64.h:189
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
Definition glue_aarch64.h:37
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
Definition glue_aarch64.h:144
static const unsigned int GLUE_JMP_NC[]
Definition glue_aarch64.h:72
static unsigned int GLUE_POP_STACK_TO_FPREG2[]
Definition glue_aarch64.h:46
static int GLUE_FUSE(compileContext *ctx, unsigned char *code, int left_size, int right_size, int fuse_flags, int spill_reg)
Definition glue_aarch64.h:376
static const unsigned int GLUE_JMP_IF_P1_NZ[]
Definition glue_aarch64.h:79
static const unsigned int GLUE_FUNC_ENTER[2]
Definition glue_aarch64.h:104
static const unsigned int GLUE_SET_P1_Z[]
Definition glue_aarch64.h:325
static const unsigned int GLUE_RET[]
Definition glue_aarch64.h:108
static const unsigned int GLUE_JMP_IF_P1_Z[]
Definition glue_aarch64.h:74
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
Definition glue_aarch64.h:121
static void GLUE_POP_PX(void *b, int wv)
Definition glue_aarch64.h:171
static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[]
Definition glue_aarch64.h:45
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_aarch64.h:287
static unsigned char * EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
Definition glue_aarch64.h:264
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
Definition glue_aarch64.h:313
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
Definition glue_aarch64.h:177
static unsigned long __attribute__((unused)) glue_getscr()
Definition glue_aarch64.h:352
static void eel_callcode64(INT_PTR bp, INT_PTR cp, INT_PTR rt)
Definition glue_aarch64.h:227
static const unsigned int GLUE_PUSH_P1[1]
Definition glue_aarch64.h:118
static const unsigned int GLUE_SET_P1_NZ[]
Definition glue_aarch64.h:326
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_aarch64.h:202
#define GLUE_JMP_SET_OFFSET(endOfInstruction, offset)
Definition glue_arm.h:52
INT_PTR INT_PTR rt
Definition glue_arm.h:222
float out
Definition lilv_test.c:1461
struct _compileContext compileContext
#define NSEEL_CLOSEFACTOR
Definition ns-eel-int.h:101
Definition inftrees.h:27
const char const char const char const char char * fn
Definition swell-functions.h:168
intptr_t INT_PTR
Definition swell-types.h:42
uch * p
Definition crypt.c:594
memcpy(hh, h, RAND_HEAD_LEN)
b
Definition crypt.c:628
ulg size
Definition extract.c:2350
char * cp
Definition unix.c:513
typedef int(UZ_EXP MsgFn)()