aboutsummaryrefslogtreecommitdiff
path: root/dynasm/dasm_mips.h
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_mips.h')
-rw-r--r--dynasm/dasm_mips.h52
1 files changed, 27 insertions, 25 deletions
diff --git a/dynasm/dasm_mips.h b/dynasm/dasm_mips.h
index bd18ab65..3fa2ef42 100644
--- a/dynasm/dasm_mips.h
+++ b/dynasm/dasm_mips.h
@@ -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_IMMS,
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}
@@ -155,10 +150,10 @@ void dasm_setup(Dst_DECL, const void *actionlist)
155#ifdef DASM_CHECKS 150#ifdef DASM_CHECKS
156#define CK(x, st) \ 151#define CK(x, st) \
157 do { if (!(x)) { \ 152 do { if (!(x)) { \
158 D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0) 153 D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
159#define CKPL(kind, st) \ 154#define CKPL(kind, st) \
160 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \ 155 do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \
161 D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0) 156 D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
162#else 157#else
163#define CK(x, st) ((void)0) 158#define CK(x, st) ((void)0)
164#define CKPL(kind, st) ((void)0) 159#define CKPL(kind, st) ((void)0)
@@ -231,7 +226,7 @@ void dasm_put(Dst_DECL, int start, ...)
231 *pl = -pos; /* Label exists now. */ 226 *pl = -pos; /* Label exists now. */
232 b[pos++] = ofs; /* Store pass1 offset estimate. */ 227 b[pos++] = ofs; /* Store pass1 offset estimate. */
233 break; 228 break;
234 case DASM_IMM: 229 case DASM_IMM: case DASM_IMMS:
235#ifdef DASM_CHECKS 230#ifdef DASM_CHECKS
236 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I); 231 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
237#endif 232#endif
@@ -273,7 +268,7 @@ int dasm_link(Dst_DECL, size_t *szp)
273 268
274 { /* Handle globals not defined in this translation unit. */ 269 { /* Handle globals not defined in this translation unit. */
275 int idx; 270 int idx;
276 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) { 271 for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
277 int n = D->lglabels[idx]; 272 int n = D->lglabels[idx];
278 /* Undefined label: Collapse rel chain and replace with marker (< 0). */ 273 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
279 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; } 274 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -299,7 +294,7 @@ int dasm_link(Dst_DECL, size_t *szp)
299 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break; 294 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
300 case DASM_REL_LG: case DASM_REL_PC: pos++; break; 295 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
301 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; 296 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
302 case DASM_IMM: pos++; break; 297 case DASM_IMM: case DASM_IMMS: pos++; break;
303 } 298 }
304 } 299 }
305 stop: (void)0; 300 stop: (void)0;
@@ -314,7 +309,7 @@ int dasm_link(Dst_DECL, size_t *szp)
314 309
315#ifdef DASM_CHECKS 310#ifdef DASM_CHECKS
316#define CK(x, st) \ 311#define CK(x, st) \
317 do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0) 312 do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)
318#else 313#else
319#define CK(x, st) ((void)0) 314#define CK(x, st) ((void)0)
320#endif 315#endif
@@ -349,25 +344,32 @@ int dasm_encode(Dst_DECL, void *buffer)
349 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000; 344 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
350 break; 345 break;
351 case DASM_REL_LG: 346 case DASM_REL_LG:
352 CK(n >= 0, UNDEF_LG); 347 if (n < 0) {
348 n = (int)((ptrdiff_t)D->globals[-n-10] - (ptrdiff_t)cp);
349 goto patchrel;
350 }
353 /* fallthrough */ 351 /* fallthrough */
354 case DASM_REL_PC: 352 case DASM_REL_PC:
355 CK(n >= 0, UNDEF_PC); 353 CK(n >= 0, UNDEF_PC);
356 n = *DASM_POS2PTR(D, n); 354 n = *DASM_POS2PTR(D, n);
357 if (ins & 2048) 355 if (ins & 2048)
358 n = n - (int)((char *)cp - base); 356 n = (n + (int)(size_t)base) & 0x0fffffff;
359 else 357 else
360 n = (n + (int)base) & 0x0fffffff; 358 n = n - (int)((char *)cp - base);
361 patchrel: 359 patchrel: {
360 unsigned int e = 16 + ((ins >> 12) & 15);
362 CK((n & 3) == 0 && 361 CK((n & 3) == 0 &&
363 ((n + ((ins & 2048) ? 0x00020000 : 0)) >> 362 ((n + ((ins & 2048) ? 0 : (1<<(e+1)))) >> (e+2)) == 0, RANGE_REL);
364 ((ins & 2048) ? 18 : 28)) == 0, RANGE_REL); 363 cp[-1] |= ((n>>2) & ((1<<e)-1));
365 cp[-1] |= ((n>>2) & ((ins & 2048) ? 0x0000ffff: 0x03ffffff)); 364 }
366 break; 365 break;
367 case DASM_LABEL_LG: 366 case DASM_LABEL_LG:
368 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); 367 ins &= 2047; if (ins >= 20) D->globals[ins-20] = (void *)(base + n);
369 break; 368 break;
370 case DASM_LABEL_PC: break; 369 case DASM_LABEL_PC: break;
370 case DASM_IMMS:
371 cp[-1] |= ((n>>3) & 4); n &= 0x1f;
372 /* fallthrough */
371 case DASM_IMM: 373 case DASM_IMM:
372 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); 374 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
373 break; 375 break;
@@ -410,7 +412,7 @@ int dasm_checkstep(Dst_DECL, int secmatch)
410 } 412 }
411 if (D->status == DASM_S_OK && secmatch >= 0 && 413 if (D->status == DASM_S_OK && secmatch >= 0 &&
412 D->section != &D->sections[secmatch]) 414 D->section != &D->sections[secmatch])
413 D->status = DASM_S_MATCH_SEC|(D->section-D->sections); 415 D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
414 return D->status; 416 return D->status;
415} 417}
416#endif 418#endif