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.h29
1 files changed, 18 insertions, 11 deletions
diff --git a/dynasm/dasm_mips.h b/dynasm/dasm_mips.h
index 15b4b137..c92c9bf4 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
@@ -231,7 +231,7 @@ void dasm_put(Dst_DECL, int start, ...)
231 *pl = -pos; /* Label exists now. */ 231 *pl = -pos; /* Label exists now. */
232 b[pos++] = ofs; /* Store pass1 offset estimate. */ 232 b[pos++] = ofs; /* Store pass1 offset estimate. */
233 break; 233 break;
234 case DASM_IMM: 234 case DASM_IMM: case DASM_IMMS:
235#ifdef DASM_CHECKS 235#ifdef DASM_CHECKS
236 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I); 236 CK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);
237#endif 237#endif
@@ -273,7 +273,7 @@ int dasm_link(Dst_DECL, size_t *szp)
273 273
274 { /* Handle globals not defined in this translation unit. */ 274 { /* Handle globals not defined in this translation unit. */
275 int idx; 275 int idx;
276 for (idx = 20; idx*sizeof(int) < D->lgsize; idx++) { 276 for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
277 int n = D->lglabels[idx]; 277 int n = D->lglabels[idx];
278 /* Undefined label: Collapse rel chain and replace with marker (< 0). */ 278 /* Undefined label: Collapse rel chain and replace with marker (< 0). */
279 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; } 279 while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
@@ -299,7 +299,7 @@ int dasm_link(Dst_DECL, size_t *szp)
299 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break; 299 case DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;
300 case DASM_REL_LG: case DASM_REL_PC: pos++; break; 300 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
301 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; 301 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
302 case DASM_IMM: pos++; break; 302 case DASM_IMM: case DASM_IMMS: pos++; break;
303 } 303 }
304 } 304 }
305 stop: (void)0; 305 stop: (void)0;
@@ -349,25 +349,32 @@ int dasm_encode(Dst_DECL, void *buffer)
349 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000; 349 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;
350 break; 350 break;
351 case DASM_REL_LG: 351 case DASM_REL_LG:
352 CK(n >= 0, UNDEF_LG); 352 if (n < 0) {
353 n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);
354 goto patchrel;
355 }
353 /* fallthrough */ 356 /* fallthrough */
354 case DASM_REL_PC: 357 case DASM_REL_PC:
355 CK(n >= 0, UNDEF_PC); 358 CK(n >= 0, UNDEF_PC);
356 n = *DASM_POS2PTR(D, n); 359 n = *DASM_POS2PTR(D, n);
357 if (ins & 2048) 360 if (ins & 2048)
358 n = n - (int)((char *)cp - base); 361 n = (n + (int)(size_t)base) & 0x0fffffff;
359 else 362 else
360 n = (n + (int)base) & 0x0fffffff; 363 n = n - (int)((char *)cp - base);
361 patchrel: 364 patchrel: {
365 unsigned int e = 16 + ((ins >> 12) & 15);
362 CK((n & 3) == 0 && 366 CK((n & 3) == 0 &&
363 ((n + ((ins & 2048) ? 0x00020000 : 0)) >> 367 ((n + ((ins & 2048) ? 0 : (1<<(e+1)))) >> (e+2)) == 0, RANGE_REL);
364 ((ins & 2048) ? 18 : 28)) == 0, RANGE_REL); 368 cp[-1] |= ((n>>2) & ((1<<e)-1));
365 cp[-1] |= ((n>>2) & ((ins & 2048) ? 0x0000ffff: 0x03ffffff)); 369 }
366 break; 370 break;
367 case DASM_LABEL_LG: 371 case DASM_LABEL_LG:
368 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); 372 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
369 break; 373 break;
370 case DASM_LABEL_PC: break; 374 case DASM_LABEL_PC: break;
375 case DASM_IMMS:
376 cp[-1] |= ((n>>3) & 4); n &= 0x1f;
377 /* fallthrough */
371 case DASM_IMM: 378 case DASM_IMM:
372 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31); 379 cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);
373 break; 380 break;