LMMS
Loading...
Searching...
No Matches
glue_ppc.h
Go to the documentation of this file.
1#ifndef _NSEEL_GLUE_PPC_H_
2#define _NSEEL_GLUE_PPC_H_
3
4#define GLUE_MAX_FPSTACK_SIZE 0 // no stack support
5#define GLUE_MAX_JMPSIZE 30000 // maximum relative jump size for this arch (if not defined, any jump is possible)
6
7
8// endOfInstruction is end of jump with relative offset, offset passed in is offset from end of dest instruction.
9// on PPC the offset needs to be from the start of the instruction (hence +4), and also the low two bits are flags so
10// we make sure they are clear (they should always be clear, anyway, since we always generate 4 byte instructions)
11#define GLUE_JMP_SET_OFFSET(endOfInstruction,offset) (((short *)(endOfInstruction))[-1] = ((offset) + 4) & 0xFFFC)
12
13static const unsigned char GLUE_JMP_NC[] = { 0x48,0, 0, 0, }; // b <offset>
14
15static const unsigned int GLUE_JMP_IF_P1_Z[]=
16{
17 0x2f830000, //cmpwi cr7, r3, 0
18 0x419e0000, // beq cr7, offset-bytes-from-startofthisinstruction
19};
20static const unsigned int GLUE_JMP_IF_P1_NZ[]=
21{
22 0x2f830000, //cmpwi cr7, r3, 0
23 0x409e0000, // bne cr7, offset-bytes-from-startofthisinstruction
24};
25
26
27#define GLUE_MOV_PX_DIRECTVALUE_SIZE 8
28static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
29{
30 static const unsigned short tab[3][2] = {
31 {0x3C60, 0x6063}, // addis r3, r0, hw -- ori r3,r3, lw
32 {0x3DC0, 0x61CE}, // addis r14, r0, hw -- ori r14, r14, lw
33 {0x3DE0, 0x61EF}, // addis r15, r0, hw -- oris r15, r15, lw
34 };
35 unsigned int uv=(unsigned int)v;
36 unsigned short *p=(unsigned short *)b;
37
38 *p++ = tab[wv][0]; // addis rX, r0, hw
39 *p++ = (uv>>16)&0xffff;
40 *p++ = tab[wv][1]; // ori rX, rX, lw
41 *p++ = uv&0xffff;
42}
43
44
45// mflr r5
46// stwu r5, -16(r1)
47const static unsigned int GLUE_FUNC_ENTER[2] = { 0x7CA802A6, 0x94A1FFF0 };
48#define GLUE_FUNC_ENTER_SIZE 8
49
50// lwz r5, 0(r1)
51// addi r1, r1, 16
52// mtlr r5
53const static unsigned int GLUE_FUNC_LEAVE[3] = { 0x80A10000, 0x38210010, 0x7CA803A6 };
54#define GLUE_FUNC_LEAVE_SIZE 12
55
56const static unsigned int GLUE_RET[]={0x4E800020}; // blr
57
58static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
59{
60 const static unsigned int GLUE_SET_WTP_FROM_R17=0x7E308B78; // mr r16 (dest), r17 (src)
61 if (out) memcpy(out,&GLUE_SET_WTP_FROM_R17,sizeof(GLUE_SET_WTP_FROM_R17));
62 return sizeof(GLUE_SET_WTP_FROM_R17);
63
64}
65
66
67
68// stwu r3, -16(r1)
69const static unsigned int GLUE_PUSH_P1[1]={ 0x9461FFF0};
70
71
72#define GLUE_POP_PX_SIZE 8
73static void GLUE_POP_PX(void *b, int wv)
74{
75 static const unsigned int tab[3] ={
76 0x80610000, // lwz r3, 0(r1)
77 0x81c10000, // lwz r14, 0(r1)
78 0x81e10000, // lwz r15, 0(r1)
79 };
80 ((unsigned int *)b)[0] = tab[wv];
81 ((unsigned int *)b)[1] = 0x38210010; // addi r1,r1, 16
82}
83
84#define GLUE_SET_PX_FROM_P1_SIZE 4
85static void GLUE_SET_PX_FROM_P1(void *b, int wv)
86{
87 static const unsigned int tab[3]={
88 0x7c631b78, // never used: mr r3, r3
89 0x7c6e1b78, // mr r14, r3
90 0x7c6f1b78, // mr r15, r3
91 };
92 *(unsigned int *)b = tab[wv];
93}
94
95
96
97// lfd f2, 0(r3)
98// stfdu f2, -16(r1)
99static const unsigned int GLUE_PUSH_P1PTR_AS_VALUE[] = { 0xC8430000, 0xDC41FFF0 };
100
101static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
102{
103 // lfd f2, 0(r1)
104 // addi r1,r1,16
105 // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
106 // stfd f2, 0(r3)
107 if (buf)
108 {
109 unsigned int *bufptr = (unsigned int *)buf;
110 *bufptr++ = 0xC8410000;
111 *bufptr++ = 0x38210010;
112 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
114 *bufptr++ = 0xd8430000;
115 }
116 return 2*4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
117}
118
119static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
120{
121 // lfd f2, 0(r3)
122 // GLUE_MOV_PX_DIRECTVALUE_GEN / GLUE_MOV_PX_DIRECTVALUE_SIZE (r3)
123 // stfd f2, 0(r3)
124
125 if (buf)
126 {
127 unsigned int *bufptr = (unsigned int *)buf;
128 *bufptr++ = 0xc8430000;
129 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
131 *bufptr++ = 0xd8430000;
132 }
133
134 return 4 + GLUE_MOV_PX_DIRECTVALUE_SIZE + 4;
135}
136
137
139{
140 static const double consttab[] = {
142 4503601774854144.0 /* 0x43300000, 0x80000000, used for integer conversion*/,
143 };
144 // we could have r18 refer to the current user-stack pointer, someday, perhaps
145 __asm__(
146 "subi r1, r1, 128\n"
147 "stfd f31, 8(r1)\n"
148 "stfd f30, 16(r1)\n"
149 "stmw r13, 32(r1)\n"
150 "mtctr %0\n"
151 "mr r17, %1\n"
152 "mr r13, %2\n"
153 "lfd f31, 0(%3)\n"
154 "lfd f30, 8(%3)\n"
155 "subi r17, r17, 8\n"
156 "mflr r0\n"
157 "stw r0, 24(r1)\n"
158 "bctrl\n"
159 "lwz r0, 24(r1)\n"
160 "mtlr r0\n"
161 "lmw r13, 32(r1)\n"
162 "lfd f31, 8(r1)\n"
163 "lfd f30, 16(r1)\n"
164 "addi r1, r1, 128\n"
165 ::"r" (cp), "r" (bp), "r" (rt), "r" (consttab));
166};
167
168static unsigned char *EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
169{
170 // 64 bit ppc would take some work
171 unsigned int *p=(unsigned int *)_p;
172 while ((p[0]&0x0000FFFF) != 0x0000dead &&
173 (p[1]&0x0000FFFF) != 0x0000beef) p++;
174 p[0] = (p[0]&0xFFFF0000) | (((newv)>>16)&0xFFFF);
175 p[1] = (p[1]&0xFFFF0000) | ((newv)&0xFFFF);
176
177 return (unsigned char *)(p+1);
178}
179
180 #define GLUE_SET_PX_FROM_WTP_SIZE sizeof(int)
181 static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
182 {
183 static const unsigned int tab[3]={
184 0x7e038378, // mr r3, r16
185 0x7e0e8378, // mr r14, r16
186 0x7e0f8378, // mr r15, r16
187 };
188 *(unsigned int *)b = tab[wv];
189 }
190 static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
191 {
192 // set r3 to destptr
193 // stfd f1, 0(r3)
194 if (buf)
195 {
196 unsigned int *bufptr = (unsigned int *)buf;
197 GLUE_MOV_PX_DIRECTVALUE_GEN(bufptr, (INT_PTR)destptr,0);
199
200 *bufptr++ = 0xD8230000; // stfd f1, 0(r3)
201 }
202 return GLUE_MOV_PX_DIRECTVALUE_SIZE + sizeof(int);
203 }
204 #define GLUE_POP_FPSTACK_SIZE 0
205 static const unsigned int GLUE_POP_FPSTACK[1] = { 0 }; // no need to pop, not a stack
206
207 static const unsigned int GLUE_POP_FPSTACK_TOSTACK[] = {
208 0xdc21fff0, // stfdu f1, -16(r1)
209 };
210
211 static const unsigned int GLUE_POP_FPSTACK_TO_WTP[] = {
212 0xdc300008, // stfdu f1, 8(r16)
213 };
214
215 #define GLUE_PUSH_VAL_AT_PX_TO_FPSTACK_SIZE 4
216 static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
217 {
218 static const unsigned int tab[3] = {
219 0xC8230000, // lfd f1, 0(r3)
220 0xC82E0000, // lfd f1, 0(r14)
221 0xC82F0000, // lfd f1, 0(r15)
222 };
223 *(unsigned int *)b = tab[wv];
224 }
225
226#define GLUE_POP_FPSTACK_TO_WTP_TO_PX_SIZE (sizeof(GLUE_POP_FPSTACK_TO_WTP) + GLUE_SET_PX_FROM_WTP_SIZE)
227static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
228{
230 GLUE_SET_PX_FROM_WTP(buf + sizeof(GLUE_POP_FPSTACK_TO_WTP),wv); // ppc preincs the WTP, so we do this after
231};
232
233static unsigned int GLUE_POP_STACK_TO_FPSTACK[1] = { 0 }; // todo
234
235
236static const unsigned int GLUE_SET_P1_Z[] = { 0x38600000 }; // li r3, 0
237static const unsigned int GLUE_SET_P1_NZ[] = { 0x38600001 }; // li r3, 1
238
239
240static void *GLUE_realAddress(void *fn, int *size)
241{
242 // magic numbers: mr r0,r0 ; mr r1,r1 ; mr r2, r2
243 static const unsigned char sig[12] = { 0x7c, 0x00, 0x03, 0x78, 0x7c, 0x21, 0x0b, 0x78, 0x7c, 0x42, 0x13, 0x78 };
244 unsigned char *p = (unsigned char *)fn;
245
246 while (memcmp(p,sig,sizeof(sig))) p+=4;
247 p+=sizeof(sig);
248 fn = p;
249
250 while (memcmp(p,sig,sizeof(sig))) p+=4;
251 *size = p - (unsigned char *)fn;
252 return fn;
253}
254
255 #define GLUE_STORE_P1_TO_STACK_AT_OFFS_SIZE(x) 4
256 static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
257 {
258 // limited to 32k offset
259 *(unsigned int *)b = 0x90610000 + (offs&0xffff);
260 }
261
262 #define GLUE_MOVE_PX_STACKPTR_SIZE 4
263 static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
264 {
265 static const unsigned int tab[3] =
266 {
267 0x7c230b78, // mr r3, r1
268 0x7c2e0b78, // mr r14, r1
269 0x7c2f0b78, // mr r15, r1
270 };
271 * (unsigned int *)b = tab[wv];
272 }
273
274 #define GLUE_MOVE_STACK_SIZE 4
275 static void GLUE_MOVE_STACK(void *b, int amt)
276 {
277 // this should be updated to allow for more than 32k moves, but no real need
278 ((unsigned int *)b)[0] = 0x38210000 + (amt&0xffff); // addi r1,r1, amt
279 }
280
281
282
283// end of ppc
284
285#endif
unsigned v[N_MAX]
Definition inflate.c:1584
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
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 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
#define GLUE_CALL_CODE(bp, cp, rt)
Definition glue_aarch64.h:217
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
INT_PTR INT_PTR rt
Definition glue_arm.h:222
static unsigned char GLUE_POP_STACK_TO_FPSTACK[1]
Definition glue_port.h:341
static void GLUE_MOVE_STACK(void *b, int amt)
Definition glue_ppc.h:275
static void GLUE_SET_PX_FROM_WTP(void *b, int wv)
Definition glue_ppc.h:181
static void GLUE_POP_FPSTACK_TO_WTP_TO_PX(unsigned char *buf, int wv)
Definition glue_ppc.h:227
static void GLUE_MOV_PX_DIRECTVALUE_GEN(void *b, INT_PTR v, int wv)
Definition glue_ppc.h:28
static void * GLUE_realAddress(void *fn, int *size)
Definition glue_ppc.h:240
static int GLUE_RESET_WTP(unsigned char *out, void *ptr)
Definition glue_ppc.h:58
static int GLUE_POP_VALUE_TO_ADDR(unsigned char *buf, void *destptr)
Definition glue_ppc.h:101
static void GLUE_MOVE_PX_STACKPTR_GEN(void *b, int wv)
Definition glue_ppc.h:263
static void GLUE_STORE_P1_TO_STACK_AT_OFFS(void *b, int offs)
Definition glue_ppc.h:256
static void GLUE_POP_PX(void *b, int wv)
Definition glue_ppc.h:73
static int GLUE_POP_FPSTACK_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_ppc.h:190
static unsigned char * EEL_GLUE_set_immediate(void *_p, INT_PTR newv)
Definition glue_ppc.h:168
static void GLUE_PUSH_VAL_AT_PX_TO_FPSTACK(void *b, int wv)
Definition glue_ppc.h:216
static void GLUE_SET_PX_FROM_P1(void *b, int wv)
Definition glue_ppc.h:85
static int GLUE_COPY_VALUE_AT_P1_TO_PTR(unsigned char *buf, void *destptr)
Definition glue_ppc.h:119
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)()