LMMS
Loading...
Searching...
No Matches
glue_arm.h
Go to the documentation of this file.
1#ifndef _NSEEL_GLUE_ARM_H_
2#define _NSEEL_GLUE_ARM_H_
3
4// r0=return value, first parm, r1-r2 parms
5// r3+ should be reserved
6// blx addr
7// stmfd sp!, {register list, lr}
8// ldmfd sp!, {register list, pc}
9
10// let's make r8 = worktable
11// let's make r7 = ramtable
12// r6 = consttab
13// r5 = worktable ptr
14
15// r0=p1
16// r1=p2
17// r2=p3
18
19// d0 is return value?
20
21
22#define GLUE_HAS_FPREG2 1
23
24static const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[] = {
25 0xeeb01b40 // fcpyd d1, d0
26};
27
28static unsigned int GLUE_POP_STACK_TO_FPREG2[] = {
29 0xed9d1b00,// vldr d1, [sp]
30 0xe28dd008,// add sp, sp, #8
31};
32
33#define GLUE_MAX_SPILL_REGS 8
34#define GLUE_SAVE_TO_SPILL_SIZE(x) (4)
35#define GLUE_RESTORE_SPILL_TO_FPREG2_SIZE(x) (4)
36
37static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
38{
39 *(unsigned int *)b = 0xeeb01b48 + ws; // fcpyd d1, d8+ws
40}
41static void GLUE_SAVE_TO_SPILL(void *b, int ws)
42{
43 *(unsigned int *)b = 0xeeb08b40 + (ws<<12); // fcpyd d8+ws, d0
44}
45
46
47#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
48#define GLUE_MAX_JMPSIZE ((1<<25) - 1024) // maximum relative jump size
49
50// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
51// TODO: verify, but offset probably from next instruction (PC is ahead)
52#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((int *)(endOfInstruction))[-1] = (((int *)(endOfInstruction))[-1]&0xFF000000)|((((offset)>>2)-1)))
53
54 // /=conditional=always = 0xE
55 // |/= 101(L), so 8+2+0 = 10 = A
56static const unsigned int GLUE_JMP_NC[] = { 0xEA000000 };
57
58static const unsigned int GLUE_JMP_IF_P1_Z[]=
59{
60 0xe1100000, // tst r0, r0
61 0x0A000000, // branch if Z set
62};
63static const unsigned int GLUE_JMP_IF_P1_NZ[]=
64{
65 0xe1100000, // tst r0, r0
66 0x1A000000, // branch if Z clear
67};
68
69#define GLUE_MOV_PX_DIRECTVALUE_TOFPREG2_SIZE 12 // wr=-2, sets d1
70#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8
71static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
72{
73 // requires ARMv6thumb2 or later
74 const unsigned int reg_add = wdl_max(wv,0) << 12;
75 static const unsigned int tab[2] = {
76 0xe3000000, // movw r0, #0000
77 0xe3400000, // movt r0, #0000
78 };
79 // 0xABAAA, B is register, A are bits of word
80 unsigned int *p=(unsigned int *)b;
81 p[0] = tab[0] | reg_add | (v&0xfff) | ((v&0xf000)<<4);
82 p[1] = tab[1] | reg_add | ((v>>16)&0xfff) | ((v&0xf0000000)>>12);
83 if (wv == -2) p[2] = 0xed901b00; // fldd d1, [r0]
84}
85
86const static unsigned int GLUE_FUNC_ENTER[1] = { 0xe92d4010 }; // push {r4, lr}
87#define GLUE_FUNC_ENTER_SIZE 4
88const static unsigned int GLUE_FUNC_LEAVE[1] = { 0 }; // let GLUE_RET pop
89#define GLUE_FUNC_LEAVE_SIZE 0
90const static unsigned int GLUE_RET[]={ 0xe8bd8010 }; // pop {r4, pc}
91
92static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
93{
94 const static unsigned int GLUE_SET_WTP_FROM_R8 = 0xe1a05008; // mov r5, r8
95 if (out) memcpy(out,&GLUE_SET_WTP_FROM_R8,sizeof(GLUE_SET_WTP_FROM_R8));
96 return sizeof(GLUE_SET_WTP_FROM_R8);
97}
98
99
100const static unsigned int GLUE_PUSH_P1[1]={ 0xe52d0008 }; // push {r0}, aligned to 8
101
102
103static int arm_encode_constforalu(int amt)
104{
105 int nrot = 16;
106 while (amt >= 0x100 && nrot > 1)
107 {
108 // ARM encodes integers for ALU operations as rotated right by third nibble*2
109 amt = (amt + 3)>>2;
110 nrot--;
111 }
112 return ((nrot&15) << 8) | amt;
113}
114
115
116#define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) ((x)>=4096 ? 8 : 4)
117static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
118{
119 if (offs >= 4096)
120 {
121 // add r2, sp, (offs&~4095)
122 *(unsigned int *)b = 0xe28d2000 | arm_encode_constforalu(offs&~4095);
123 // str r0, [r2, offs&4095]
124 ((unsigned int *)b)[1] = 0xe5820000 + (offs&4095);
125 }
126 else
127 {
128 // str r0, [sp, #offs]
129 *(unsigned int *)b = 0xe58d0000 + offs;
130 }
131}
132
133#define GLUE_MOVE_PX_STACKPTR_SIZE 4
134static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
135{
136 // mov rX, sp
137 *(unsigned int *)b = 0xe1a0000d + (wv<<12);
138}
139
140#define GLUE_MOVE_STACK_SIZE 4
141static void GLUE_MOVE_STACK(void *b, int amt)
142{
143 unsigned int instr = 0xe28dd000;
144 if (amt < 0)
145 {
146 instr = 0xe24dd000;
147 amt=-amt;
148 }
149 *(unsigned int*)b = instr | arm_encode_constforalu(amt);
150}
151
152#define GLUE_POP_PX_SIZE 4
153static void GLUE_POP_PX(void *b, int wv)
154{
155 ((unsigned int *)b)[0] = 0xe49d0008 | (wv<<12); // pop {rX}, aligned to 8
156}
157
158#define GLUE_SET_PX_FROM_P1_SIZE 4
159static void GLUE_SET_PX_FROM_P1(void *b, int wv)
160{
161 *(unsigned int *)b = 0xe1a00000 | (wv<<12); // mov rX, r0
162}
163
164
165static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] =
166{
167 0xed907b00, // fldd d7, [r0]
168 0xe24dd008, // sub sp, sp, #8
169 0xed8d7b00, // fstd d7, [sp]
170};
171
172static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
173{
174 if (buf)
175 {
176 unsigned int *bufptr = (unsigned int *)buf;
177 *bufptr++ = 0xed9d7b00; // fldd d7, [sp]
178 *bufptr++ = 0xe28dd008; // add sp, sp, #8
179 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
181 *bufptr++ = 0xed807b00; // fstd d7, [r0]
182 }
183 return 3*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
184}
185
186static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
187{
188 if (buf)
189 {
190 unsigned int *bufptr = (unsigned int *)buf;
191 *bufptr++ = 0xed907b00; // fldd d7, [r0]
192 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
194 *bufptr++ = 0xed807b00; // fstd d7, [r0]
195 }
196 return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE;
197}
198
199
200#ifndef _MSC_VER
201#define GLUE_CALL_CODE(bp, cp, rt) do { \
202 unsigned int f; \
203 if (!(h->compile_flags&NSEEL_CODE_COMPILE_FLAG_NOFPSTATE) && \
204 !((f=glue_getscr())&(1<<24))) { \
205 glue_setscr(f|(1<<24)); \
206 eel_callcode32(bp, cp, rt); \
207 glue_setscr(f); \
208 } else eel_callcode32(bp, cp, rt);\
209 } while(0)
210
211static const double __consttab[] = {
213 0.0,
214 1.0,
215 -1.0,
216 -0.5, // for invsqrt
217 1.5,
218 };
219
220__attribute__((target("arm")))
222{
223 __asm__ volatile(
224 "mov r7, %2\n"
225 "mov r6, %3\n"
226 "mov r8, %1\n"
227 "mov r0, %0\n"
228 "mov r1, sp\n"
229 "bic sp, sp, #7\n"
230 "push {r1, lr}\n"
231 "blx r0\n"
232 "pop {r1, lr}\n"
233 "mov sp, r1\n"
234 ::"r" (cp), "r" (bp), "r" (rt), "r" (__consttab) :
235 "r5", "r6", "r7", "r8", "r10",
236 "d8","d9","d10","d11","d12","d13","d14","d15");
237};
238#endif
239
240static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
241{
242 unsigned int *p=(unsigned int *)_p;
243 while ((p[0]&0x000F0FFF) != 0x000d0ead &&
244 (p[1]&0x000F0FFF) != 0x000b0eef) p++;
245 p[0] = (p[0]&0xFFF0F000) | (newv&0xFFF) | ((newv << 4) & 0xF0000);
246 p[1] = (p[1]&0xFFF0F000) | ((newv>>16)&0xFFF) | ((newv >> 12)&0xF0000);
247
248 return (unsigned char *)(p+1);
249}
250
251#define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
252static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
253{
254 *(unsigned int *)b = 0xe1a00005 + (wv<<12); // mov rX, r5
255}
256
257static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
258{
259 if (buf)
260 {
261 unsigned int *bufptr = (unsigned int *)buf;
262 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
264
265 *bufptr++ = 0xed800b00; // fstd d0, [r0]
266 }
267 return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
268}
269
270#define GLUE_POP_FPSTACK_SIZE 0
271static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
272
273static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
274 0xe24dd008, // sub sp, sp, #8
275 0xed8d0b00, // fstd d0, [sp]
276};
277
278static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
279 0xed850b00, // fstd d0, [r5]
280 0xe2855008, // add r5, r5, #8
281};
282
283#define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
284static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
285{
286 *(unsigned int *)b = 0xed900b00 + (wv<<16); // fldd d0, [rX]
287}
288
289#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
290static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
291{
292 GLUE_SET_PX_FROM_WTP(buf,wv);
294};
295
296static const unsigned int GLUE_SET_P1_Z[] = { 0xe3a00000 }; // mov r0, #0
297static const unsigned int GLUE_SET_P1_NZ[] = { 0xe3a00001 }; // mov r0, #1
298
299
300static void *GLUE_realAddress(void *fn, int *size)
301{
302 static const unsigned int sig[3] = { 0xe1a00000, 0xe1a01001, 0xe1a02002 };
303 unsigned char *p = (unsigned char *)fn;
304
305 while (memcmp(p,sig,sizeof(sig))) p+=4;
306 p+=sizeof(sig);
307 fn = p;
308
309 while (memcmp(p,sig,sizeof(sig))) p+=4;
310 *size = p - (unsigned char *)fn;
311 return fn;
312}
313
314static unsigned int __attribute__((unused)) glue_getscr()
315{
316 unsigned int rv;
317 asm volatile ( "fmrx %0, fpscr" : "=r" (rv));
318 return rv;
319}
320static void __attribute__((unused)) glue_setscr(unsigned int v)
321{
322 asm volatile ( "fmxr fpscr, %0" :: "r"(v));
323}
324
325void eel_enterfp(int s[2])
326{
327 s[0] = glue_getscr();
328 glue_setscr(s[0] | (1<<24)); // could also do 3<<22 for RTZ
329}
330void eel_leavefp(int s[2])
331{
332 glue_setscr(s[0]);
333}
334
335
336#endif
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 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
#define GLUE_SET_PX_FROM_WTP_SIZE
Definition glue_aarch64.h:281
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 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 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 const unsigned int GLUE_COPY_FPSTACK_TO_FPREG2[]
Definition glue_aarch64.h:45
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 void GLUE_MOVE_STACK(void *b, int amt)
Definition glue_arm.h:141
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
Definition glue_arm.h:252
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
Definition glue_arm.h:290
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
Definition glue_arm.h:71
INT_PTR INT_PTR rt
Definition glue_arm.h:222
static void GLUE_RESTORE_SPILL_TO_FPREG2(void *b, int ws)
Definition glue_arm.h:37
static void * GLUE_realAddress(void *fn, int *size)
Definition glue_arm.h:300
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
Definition glue_arm.h:92
static int arm_encode_constforalu(int amt)
Definition glue_arm.h:103
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
Definition glue_arm.h:172
static void GLUE_SAVE_TO_SPILL(void *b, int ws)
Definition glue_arm.h:41
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
Definition glue_arm.h:134
static const double __consttab[]
Definition glue_arm.h:211
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
Definition glue_arm.h:117
static void GLUE_POP_PX(void *b, int wv)
Definition glue_arm.h:153
__attribute__((target("arm"))) static void eel_callcode32(INT_PTR bp
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_arm.h:257
static unsigned char * EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
Definition glue_arm.h:240
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
Definition glue_arm.h:284
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
Definition glue_arm.h:159
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_arm.h:186
static void eel_callcode32(INT_PTR cp, INT_PTR ramptr)
Definition glue_x86.h:232
float out
Definition lilv_test.c:1461
#define NSEEL_CLOSEFACTOR
Definition ns-eel-int.h:101
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)()
#define wdl_max(x, y)
Definition wdltypes.h:106