summaryrefslogtreecommitdiff
path: root/dynasm/dasm_arm.h
diff options
context:
space:
mode:
Diffstat (limited to 'dynasm/dasm_arm.h')
-rw-r--r--dynasm/dasm_arm.h20
1 files changed, 14 insertions, 6 deletions
diff --git a/dynasm/dasm_arm.h b/dynasm/dasm_arm.h
index 3fd795b7..87db7f00 100644
--- a/dynasm/dasm_arm.h
+++ b/dynasm/dasm_arm.h
@@ -360,7 +360,7 @@ int dasm_encode(Dst_DECL, void *buffer)
360 case DASM_STOP: case DASM_SECTION: goto stop; 360 case DASM_STOP: case DASM_SECTION: goto stop;
361 case DASM_ESC: *cp++ = *p++; break; 361 case DASM_ESC: *cp++ = *p++; break;
362 case DASM_REL_EXT: 362 case DASM_REL_EXT:
363 n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1); 363 n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));
364 goto patchrel; 364 goto patchrel;
365 case DASM_ALIGN: 365 case DASM_ALIGN:
366 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000; 366 ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;
@@ -369,10 +369,18 @@ int dasm_encode(Dst_DECL, void *buffer)
369 CK(n >= 0, UNDEF_LG); 369 CK(n >= 0, UNDEF_LG);
370 case DASM_REL_PC: 370 case DASM_REL_PC:
371 CK(n >= 0, UNDEF_PC); 371 CK(n >= 0, UNDEF_PC);
372 n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base); 372 n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;
373 patchrel: 373 patchrel:
374 CK((n & 3) == 0 && ((n-4+0x02000000) >> 26) == 0, RANGE_REL); 374 if ((ins & 0x800) == 0) {
375 cp[-1] |= (((n-4) >> 2) & 0x00ffffff); 375 CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);
376 cp[-1] |= ((n >> 2) & 0x00ffffff);
377 } else if ((ins & 0x1000)) {
378 CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
379 goto patchimml8;
380 } else {
381 CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
382 goto patchimml12;
383 }
376 break; 384 break;
377 case DASM_LABEL_LG: 385 case DASM_LABEL_LG:
378 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n); 386 ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);
@@ -387,11 +395,11 @@ int dasm_encode(Dst_DECL, void *buffer)
387 case DASM_IMM16: 395 case DASM_IMM16:
388 cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff); 396 cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);
389 break; 397 break;
390 case DASM_IMML8: 398 case DASM_IMML8: patchimml8:
391 cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) : 399 cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
392 ((-n & 0x0f) | ((-n & 0xf0) << 4)); 400 ((-n & 0x0f) | ((-n & 0xf0) << 4));
393 break; 401 break;
394 case DASM_IMML12: 402 case DASM_IMML12: patchimml12:
395 cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n); 403 cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
396 break; 404 break;
397 default: *cp++ = ins; break; 405 default: *cp++ = ins; break;