aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-08 02:44:21 +0200
committerMike Pall <mike>2011-04-08 02:44:21 +0200
commit3f8fed53587e406415945389243dd18284a20939 (patch)
tree573d03f63c855c4c47e3059141abf56db9a7bb6e
parent1a56dacbcf49e959971689fceef889f82a2dd3c5 (diff)
downloadluajit-3f8fed53587e406415945389243dd18284a20939.tar.gz
luajit-3f8fed53587e406415945389243dd18284a20939.tar.bz2
luajit-3f8fed53587e406415945389243dd18284a20939.zip
ARM: Add pc-relative loads to DynASM.
-rw-r--r--dynasm/dasm_arm.h20
-rw-r--r--dynasm/dasm_arm.lua70
2 files changed, 52 insertions, 38 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;
diff --git a/dynasm/dasm_arm.lua b/dynasm/dasm_arm.lua
index 243cfe90..1876078b 100644
--- a/dynasm/dasm_arm.lua
+++ b/dynasm/dasm_arm.lua
@@ -586,6 +586,36 @@ local function parse_shift(shift, gprok)
586 end 586 end
587end 587end
588 588
589local function parse_label(label, def)
590 local prefix = sub(label, 1, 2)
591 -- =>label (pc label reference)
592 if prefix == "=>" then
593 return "PC", 0, sub(label, 3)
594 end
595 -- ->name (global label reference)
596 if prefix == "->" then
597 return "LG", map_global[sub(label, 3)]
598 end
599 if def then
600 -- [1-9] (local label definition)
601 if match(label, "^[1-9]$") then
602 return "LG", 10+tonumber(label)
603 end
604 else
605 -- [<>][1-9] (local label reference)
606 local dir, lnum = match(label, "^([<>])([1-9])$")
607 if dir then -- Fwd: 1-9, Bkwd: 11-19.
608 return "LG", lnum + (dir == ">" and 0 or 10)
609 end
610 -- extern label (extern label reference)
611 local extname = match(label, "^extern%s+(%S+)$")
612 if extname then
613 return "EXT", map_extern[extname]
614 end
615 end
616 werror("bad label `"..label.."'")
617end
618
589local function parse_load(params, nparams, n, op) 619local function parse_load(params, nparams, n, op)
590 local oplo = op % 256 620 local oplo = op % 256
591 local ext, ldrd = (oplo ~= 0), (oplo == 208) 621 local ext, ldrd = (oplo ~= 0), (oplo == 208)
@@ -594,11 +624,17 @@ local function parse_load(params, nparams, n, op)
594 d = ((op - (op % 4096)) / 4096) % 16 624 d = ((op - (op % 4096)) / 4096) % 16
595 if d % 2 ~= 0 then werror("odd destination register") end 625 if d % 2 ~= 0 then werror("odd destination register") end
596 end 626 end
597 local p1, wb = match(params[n], "^%[%s*(.-)%s*%](!?)$") 627 local pn = params[n]
628 local p1, wb = match(pn, "^%[%s*(.-)%s*%](!?)$")
598 local p2 = params[n+1] 629 local p2 = params[n+1]
599 if not p1 then 630 if not p1 then
600 if not p2 then 631 if not p2 then
601 local reg, tailr = match(params[n], "^([%w_:]+)%s*(.*)$") 632 if match(pn, "^[<>=%-]") or match(pn, "^extern%s+") then
633 local mode, n, s = parse_label(pn, false)
634 waction("REL_"..mode, n + (ext and 0x1800 or 0x0800), s, 1)
635 return op + 15 * 65536 + 0x01000000 + (ext and 0x00400000 or 0)
636 end
637 local reg, tailr = match(pn, "^([%w_:]+)%s*(.*)$")
602 if reg and tailr ~= "" then 638 if reg and tailr ~= "" then
603 local d, tp = parse_gpr(reg) 639 local d, tp = parse_gpr(reg)
604 if tp then 640 if tp then
@@ -653,36 +689,6 @@ local function parse_load(params, nparams, n, op)
653 return op 689 return op
654end 690end
655 691
656local function parse_label(label, def)
657 local prefix = sub(label, 1, 2)
658 -- =>label (pc label reference)
659 if prefix == "=>" then
660 return "PC", 0, sub(label, 3)
661 end
662 -- ->name (global label reference)
663 if prefix == "->" then
664 return "LG", map_global[sub(label, 3)]
665 end
666 if def then
667 -- [1-9] (local label definition)
668 if match(label, "^[1-9]$") then
669 return "LG", 10+tonumber(label)
670 end
671 else
672 -- [<>][1-9] (local label reference)
673 local dir, lnum = match(label, "^([<>])([1-9])$")
674 if dir then -- Fwd: 1-9, Bkwd: 11-19.
675 return "LG", lnum + (dir == ">" and 0 or 10)
676 end
677 -- extern label (extern label reference)
678 local extname = match(label, "^extern%s+(%S+)$")
679 if extname then
680 return "EXT", map_extern[extname]
681 end
682 end
683 werror("bad label `"..label.."'")
684end
685
686------------------------------------------------------------------------------ 692------------------------------------------------------------------------------
687 693
688-- Handle opcodes defined with template strings. 694-- Handle opcodes defined with template strings.