summaryrefslogtreecommitdiff
path: root/dynasm/dasm_ppc.h
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_ppc.h')
-rw-r--r--dynasm/dasm_ppc.h35
1 files changed, 20 insertions, 15 deletions
diff --git a/dynasm/dasm_ppc.h b/dynasm/dasm_ppc.h
index e2d6f1fc..4c7d7289 100644
--- a/dynasm/dasm_ppc.h
+++ b/dynasm/dasm_ppc.h
@@ -1,5 +1,5 @@
1/* 1/*
2** DynASM PPC encoding engine. 2** DynASM PPC/PPC64 encoding engine.
3** Copyright (C) 2005-2023 Mike Pall. All rights reserved. 3** Copyright (C) 2005-2023 Mike Pall. All rights reserved.
4** Released under the MIT license. See dynasm.lua for full copyright notice. 4** Released under the MIT license. See dynasm.lua for full copyright notice.
5*/ 5*/
@@ -21,7 +21,7 @@ enum {
21 /* The following actions need a buffer position. */ 21 /* The following actions need a buffer position. */
22 DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG, 22 DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,
23 /* The following actions also have an argument. */ 23 /* The following actions also have an argument. */
24 DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, 24 DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH,
25 DASM__MAX 25 DASM__MAX
26}; 26};
27 27
@@ -69,7 +69,7 @@ struct dasm_State {
69 size_t lgsize; 69 size_t lgsize;
70 int *pclabels; /* PC label chains/pos ptrs. */ 70 int *pclabels; /* PC label chains/pos ptrs. */
71 size_t pcsize; 71 size_t pcsize;
72 void **globals; /* Array of globals (bias -10). */ 72 void **globals; /* Array of globals. */
73 dasm_Section *section; /* Pointer to active section. */ 73 dasm_Section *section; /* Pointer to active section. */
74 size_t codesize; /* Total size of all code sections. */ 74 size_t codesize; /* Total size of all code sections. */
75 int maxsection; /* 0 <= sectionidx < maxsection. */ 75 int maxsection; /* 0 <= sectionidx < maxsection. */
@@ -86,7 +86,6 @@ void dasm_init(Dst_DECL, int maxsection)
86{ 86{
87 dasm_State *D; 87 dasm_State *D;
88 size_t psz = 0; 88 size_t psz = 0;
89 int i;
90 Dst_REF = NULL; 89 Dst_REF = NULL;
91 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection)); 90 DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
92 D = Dst_REF; 91 D = Dst_REF;
@@ -97,12 +96,7 @@ void dasm_init(Dst_DECL, int maxsection)
97 D->pcsize = 0; 96 D->pcsize = 0;
98 D->globals = NULL; 97 D->globals = NULL;
99 D->maxsection = maxsection; 98 D->maxsection = maxsection;
100 for (i = 0; i < maxsection; i++) { 99 memset((void *)D->sections, 0, maxsection * sizeof(dasm_Section));
101 D->sections[i].buf = NULL; /* Need this for pass3. */
102 D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
103 D->sections[i].bsize = 0;
104 D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
105 }
106} 100}
107 101
108/* Free DynASM state. */ 102/* Free DynASM state. */
@@ -122,7 +116,7 @@ void dasm_free(Dst_DECL)
122void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl) 116void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)
123{ 117{
124 dasm_State *D = Dst_REF; 118 dasm_State *D = Dst_REF;
125 D->globals = gl - 10; /* Negative bias to compensate for locals. */ 119 D->globals = gl;
126 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int)); 120 DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
127} 121}
128 122
@@ -147,6 +141,7 @@ void dasm_setup(Dst_DECL, const void *actionlist)
147 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize); 141 if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
148 for (i = 0; i < D->maxsection; i++) { 142 for (i = 0; i < D->maxsection; i++) {
149 D->sections[i].pos = DASM_SEC2POS(i); 143 D->sections[i].pos = DASM_SEC2POS(i);
144 D->sections[i].rbuf = D->sections[i].buf - D->sections[i].pos;
150 D->sections[i].ofs = 0; 145 D->sections[i].ofs = 0;
151 } 146 }
152} 147}
@@ -244,6 +239,10 @@ void dasm_put(Dst_DECL, int start, ...)
244#endif 239#endif
245 b[pos++] = n; 240 b[pos++] = n;
246 break; 241 break;
242 case DASM_IMMSH:
243 CK((n >> 6) == 0, RANGE_I);
244 b[pos++] = n;
245 break;
247 } 246 }
248 } 247 }
249 } 248 }
@@ -273,7 +272,7 @@ int dasm_link(Dst_DECL, size_t *szp)
273 272
274 { /* Handle globals not defined in this translation unit. */ 273 { /* Handle globals not defined in this translation unit. */
275 int idx; 274 int idx;
276 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) { 275 for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
277 int n = D->lglabels[idx]; 276 int n = D->lglabels[idx];
278 /* Undefined label: Collapse rel chain and replace with marker (< 0). */ 277 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
279 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; } 278 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -299,7 +298,7 @@ int dasm_link(Dst_DECL, size_t *szp)
299 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break; 298 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
300 case DASM_REL_LG: case DASM_REL_PC: pos++; break; 299 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
301 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; 300 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
302 case DASM_IMM: pos++; break; 301 case DASM_IMM: case DASM_IMMSH: pos++; break;
303 } 302 }
304 } 303 }
305 stop: (void)0; 304 stop: (void)0;
@@ -349,7 +348,10 @@ int dasm_encode(Dst_DECL, void *buffer)
349 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000; 348 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
350 break; 349 break;
351 case DASM_REL_LG: 350 case DASM_REL_LG:
352 CK(n >= 0, UNDEF_LG); 351 if (n < 0) {
352 n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
353 goto patchrel;
354 }
353 /* fallthrough */ 355 /* fallthrough */
354 case DASM_REL_PC: 356 case DASM_REL_PC:
355 CK(n >= 0, UNDEF_PC); 357 CK(n >= 0, UNDEF_PC);
@@ -361,12 +363,15 @@ int dasm_encode(Dst_DECL, void *buffer)
361 cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc)); 363 cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));
362 break; 364 break;
363 case DASM_LABEL_LG: 365 case DASM_LABEL_LG:
364 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); 366 ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
365 break; 367 break;
366 case DASM_LABEL_PC: break; 368 case DASM_LABEL_PC: break;
367 case DASM_IMM: 369 case DASM_IMM:
368 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); 370 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
369 break; 371 break;
372 case DASM_IMMSH:
373 cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32);
374 break;
370 default: *cp++ = ins; break; 375 default: *cp++ = ins; break;
371 } 376 }
372 } 377 }