aboutsummaryrefslogtreecommitdiff
path: root/dynasm
diff options
context:
space:
mode:
authorMike Pall <mike>2012-07-29 12:16:33 +0200
committerMike Pall <mike>2012-07-29 12:16:33 +0200
commit2d58872cb5ce72bb99ec5a8ed941cc3a7930a95c (patch)
tree1ed2a867d71eebe21f89b1f7994b72ad443f44c3 /dynasm
parente8af6e9da4465ffb02f89bee8dfc372b48741bf7 (diff)
downloadluajit-2d58872cb5ce72bb99ec5a8ed941cc3a7930a95c.tar.gz
luajit-2d58872cb5ce72bb99ec5a8ed941cc3a7930a95c.tar.bz2
luajit-2d58872cb5ce72bb99ec5a8ed941cc3a7930a95c.zip
DynASM/ARM: Add VFP instructions.
Diffstat (limited to 'dynasm')
-rw-r--r--dynasm/dasm_arm.h17
-rw-r--r--dynasm/dasm_arm.lua267
2 files changed, 235 insertions, 49 deletions
diff --git a/dynasm/dasm_arm.h b/dynasm/dasm_arm.h
index b770c2df..d49ecae0 100644
--- a/dynasm/dasm_arm.h
+++ b/dynasm/dasm_arm.h
@@ -22,7 +22,7 @@ enum {
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, 24 DASM_REL_PC, DASM_LABEL_PC,
25 DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12, 25 DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12, DASM_IMMV8,
26 DASM__MAX 26 DASM__MAX
27}; 27};
28 28
@@ -250,6 +250,9 @@ void dasm_put(Dst_DECL, int start, ...)
250#endif 250#endif
251 b[pos++] = n; 251 b[pos++] = n;
252 break; 252 break;
253 case DASM_IMMV8:
254 CK((n & 3) == 0, RANGE_I);
255 n >>= 2;
253 case DASM_IMML8: 256 case DASM_IMML8:
254 case DASM_IMML12: 257 case DASM_IMML12:
255 CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) : 258 CK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :
@@ -316,7 +319,7 @@ int dasm_link(Dst_DECL, size_t *szp)
316 case DASM_REL_LG: case DASM_REL_PC: pos++; break; 319 case DASM_REL_LG: case DASM_REL_PC: pos++; break;
317 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break; 320 case DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;
318 case DASM_IMM: case DASM_IMM12: case DASM_IMM16: 321 case DASM_IMM: case DASM_IMM12: case DASM_IMM16:
319 case DASM_IMML8: case DASM_IMML12: pos++; break; 322 case DASM_IMML8: case DASM_IMML12: case DASM_IMMV8: pos++; break;
320 } 323 }
321 } 324 }
322 stop: (void)0; 325 stop: (void)0;
@@ -377,9 +380,13 @@ int dasm_encode(Dst_DECL, void *buffer)
377 } else if ((ins & 0x1000)) { 380 } else if ((ins & 0x1000)) {
378 CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL); 381 CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);
379 goto patchimml8; 382 goto patchimml8;
380 } else { 383 } else if ((ins & 0x2000) == 0) {
381 CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL); 384 CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);
382 goto patchimml12; 385 goto patchimml;
386 } else {
387 CK((n & 3) == 0 && -1020 <= n && n <= 1020, RANGE_REL);
388 n >>= 2;
389 goto patchimml;
383 } 390 }
384 break; 391 break;
385 case DASM_LABEL_LG: 392 case DASM_LABEL_LG:
@@ -399,7 +406,7 @@ int dasm_encode(Dst_DECL, void *buffer)
399 cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) : 406 cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :
400 ((-n & 0x0f) | ((-n & 0xf0) << 4)); 407 ((-n & 0x0f) | ((-n & 0xf0) << 4));
401 break; 408 break;
402 case DASM_IMML12: patchimml12: 409 case DASM_IMML12: case DASM_IMMV8: patchimml:
403 cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n); 410 cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);
404 break; 411 break;
405 default: *cp++ = ins; break; 412 default: *cp++ = ins; break;
diff --git a/dynasm/dasm_arm.lua b/dynasm/dasm_arm.lua
index 4735f323..11701691 100644
--- a/dynasm/dasm_arm.lua
+++ b/dynasm/dasm_arm.lua
@@ -39,7 +39,7 @@ local wline, werror, wfatal, wwarn
39local action_names = { 39local action_names = {
40 "STOP", "SECTION", "ESC", "REL_EXT", 40 "STOP", "SECTION", "ESC", "REL_EXT",
41 "ALIGN", "REL_LG", "LABEL_LG", 41 "ALIGN", "REL_LG", "LABEL_LG",
42 "REL_PC", "LABEL_PC", "IMM", "IMM12", "IMM16", "IMML8", "IMML12", 42 "REL_PC", "LABEL_PC", "IMM", "IMM12", "IMM16", "IMML8", "IMML12", "IMMV8",
43} 43}
44 44
45-- Maximum number of section buffer positions for dasm_put(). 45-- Maximum number of section buffer positions for dasm_put().
@@ -405,14 +405,14 @@ local map_op = {
405 strd_2 = "e00000f0DL", strd_3 = "e00000f0DL", -- v5TE 405 strd_2 = "e00000f0DL", strd_3 = "e00000f0DL", -- v5TE
406 ldrsh_2 = "e01000f0DL", ldrsh_3 = "e01000f0DL", 406 ldrsh_2 = "e01000f0DL", ldrsh_3 = "e01000f0DL",
407 407
408 ldm_2 = "e8900000nR", ldmia_2 = "e8900000nR", ldmfd_2 = "e8900000nR", 408 ldm_2 = "e8900000oR", ldmia_2 = "e8900000oR", ldmfd_2 = "e8900000oR",
409 ldmda_2 = "e8100000nR", ldmfa_2 = "e8100000nR", 409 ldmda_2 = "e8100000oR", ldmfa_2 = "e8100000oR",
410 ldmdb_2 = "e9100000nR", ldmea_2 = "e9100000nR", 410 ldmdb_2 = "e9100000oR", ldmea_2 = "e9100000oR",
411 ldmib_2 = "e9900000nR", ldmed_2 = "e9900000nR", 411 ldmib_2 = "e9900000oR", ldmed_2 = "e9900000oR",
412 stm_2 = "e8800000nR", stmia_2 = "e8800000nR", stmfd_2 = "e8800000nR", 412 stm_2 = "e8800000oR", stmia_2 = "e8800000oR", stmfd_2 = "e8800000oR",
413 stmda_2 = "e8000000nR", stmfa_2 = "e8000000nR", 413 stmda_2 = "e8000000oR", stmfa_2 = "e8000000oR",
414 stmdb_2 = "e9000000nR", stmea_2 = "e9000000nR", 414 stmdb_2 = "e9000000oR", stmea_2 = "e9000000oR",
415 stmib_2 = "e9800000nR", stmed_2 = "e9800000nR", 415 stmib_2 = "e9800000oR", stmed_2 = "e9800000oR",
416 pop_1 = "e8bd0000R", push_1 = "e92d0000R", 416 pop_1 = "e8bd0000R", push_1 = "e92d0000R",
417 417
418 -- Branch instructions. 418 -- Branch instructions.
@@ -428,9 +428,89 @@ local map_op = {
428 svc_1 = "ef000000T", swi_1 = "ef000000T", 428 svc_1 = "ef000000T", swi_1 = "ef000000T",
429 ud_0 = "e7f001f0", 429 ud_0 = "e7f001f0",
430 430
431 -- NYI: Advanced SIMD and VFP instructions. 431 -- VFP instructions.
432 432 ["vadd.f32_3"] = "ee300a00dnm",
433 -- NYI instructions, since I have no need for them right now: 433 ["vadd.f64_3"] = "ee300b00Gdnm",
434 ["vsub.f32_3"] = "ee300a40dnm",
435 ["vsub.f64_3"] = "ee300b40Gdnm",
436 ["vmul.f32_3"] = "ee200a00dnm",
437 ["vmul.f64_3"] = "ee200b00Gdnm",
438 ["vnmul.f32_3"] = "ee200a40dnm",
439 ["vnmul.f64_3"] = "ee200b40Gdnm",
440 ["vmla.f32_3"] = "ee000a00dnm",
441 ["vmla.f64_3"] = "ee000b00Gdnm",
442 ["vmls.f32_3"] = "ee000a40dnm",
443 ["vmls.f64_3"] = "ee000b40Gdnm",
444 ["vnmla.f32_3"] = "ee100a40dnm",
445 ["vnmla.f64_3"] = "ee100b40Gdnm",
446 ["vnmls.f32_3"] = "ee100a00dnm",
447 ["vnmls.f64_3"] = "ee100b00Gdnm",
448 ["vdiv.f32_3"] = "ee800a00dnm",
449 ["vdiv.f64_3"] = "ee800b00Gdnm",
450
451 ["vabs.f32_2"] = "eeb00ac0dm",
452 ["vabs.f64_2"] = "eeb00bc0Gdm",
453 ["vneg.f32_2"] = "eeb10a40dm",
454 ["vneg.f64_2"] = "eeb10b40Gdm",
455 ["vsqrt.f32_2"] = "eeb10ac0dm",
456 ["vsqrt.f64_2"] = "eeb10bc0Gdm",
457 ["vcmp.f32_2"] = "eeb40a40dm",
458 ["vcmp.f64_2"] = "eeb40b40Gdm",
459 ["vcmpe.f32_2"] = "eeb40ac0dm",
460 ["vcmpe.f64_2"] = "eeb40bc0Gdm",
461 ["vcmpz.f32_1"] = "eeb50a40d",
462 ["vcmpz.f64_1"] = "eeb50b40Gd",
463 ["vcmpze.f32_1"] = "eeb50ac0d",
464 ["vcmpze.f64_1"] = "eeb50bc0Gd",
465
466 vldr_2 = "ed100a00dl|ed100b00Gdl",
467 vstr_2 = "ed000a00dl|ed000b00Gdl",
468 vldm_2 = "ec900a00or",
469 vldmia_2 = "ec900a00or",
470 vldmdb_2 = "ed100a00or",
471 vpop_1 = "ecbd0a00r",
472 vstm_2 = "ec800a00or",
473 vstmia_2 = "ec800a00or",
474 vstmdb_2 = "ed000a00or",
475 vpush_1 = "ed2d0a00r",
476
477 ["vmov.f32_2"] = "eeb00a40dm|eeb00a00dY", -- #imm is VFPv3 only
478 ["vmov.f64_2"] = "eeb00b40Gdm|eeb00b00GdY", -- #imm is VFPv3 only
479 vmov_2 = "ee100a10Dn|ee000a10nD",
480 vmov_3 = "ec500a10DNm|ec400a10mDN|ec500b10GDNm|ec400b10GmDN",
481
482 vmrs_0 = "eef1fa10",
483 vmrs_1 = "eef10a10D",
484 vmsr_1 = "eee10a10D",
485
486 ["vcvt.s32.f32_2"] = "eebd0ac0dm",
487 ["vcvt.s32.f64_2"] = "eebd0bc0dGm",
488 ["vcvt.u32.f32_2"] = "eebc0ac0dm",
489 ["vcvt.u32.f64_2"] = "eebc0bc0dGm",
490 ["vcvtr.s32.f32_2"] = "eebd0a40dm",
491 ["vcvtr.s32.f64_2"] = "eebd0b40dGm",
492 ["vcvtr.u32.f32_2"] = "eebc0a40dm",
493 ["vcvtr.u32.f64_2"] = "eebc0b40dGm",
494 ["vcvt.f32.s32_2"] = "eeb80ac0dm",
495 ["vcvt.f64.s32_2"] = "eeb80bc0GdFm",
496 ["vcvt.f32.u32_2"] = "eeb80a40dm",
497 ["vcvt.f64.u32_2"] = "eeb80b40GdFm",
498 ["vcvt.f32.f64_2"] = "eeb70bc0dGm",
499 ["vcvt.f64.f32_2"] = "eeb70ac0GdFm",
500
501 -- VFPv4 only:
502 ["vfma.f32_3"] = "eea00a00dnm",
503 ["vfma.f64_3"] = "eea00b00Gdnm",
504 ["vfms.f32_3"] = "eea00a40dnm",
505 ["vfms.f64_3"] = "eea00b40Gdnm",
506 ["vfnma.f32_3"] = "ee900a40dnm",
507 ["vfnma.f64_3"] = "ee900b40Gdnm",
508 ["vfnms.f32_3"] = "ee900a00dnm",
509 ["vfnms.f64_3"] = "ee900b00Gdnm",
510
511 -- NYI: Advanced SIMD instructions.
512
513 -- NYI: I have no need for these instructions right now:
434 -- swp, swpb, strex, ldrex, strexd, ldrexd, strexb, ldrexb, strexh, ldrexh 514 -- swp, swpb, strex, ldrex, strexd, ldrexd, strexb, ldrexb, strexh, ldrexh
435 -- msr, nopv6, yield, wfe, wfi, sev, dbg, bxj, smc, srs, rfe 515 -- msr, nopv6, yield, wfe, wfi, sev, dbg, bxj, smc, srs, rfe
436 -- cps, setend, pli, pld, pldw, clrex, dsb, dmb, isb 516 -- cps, setend, pli, pld, pldw, clrex, dsb, dmb, isb
@@ -476,6 +556,18 @@ local function parse_gpr_pm(expr)
476 return parse_gpr(expr2), (pm == "-") 556 return parse_gpr(expr2), (pm == "-")
477end 557end
478 558
559local function parse_vr(expr, tp)
560 local t, r = match(expr, "^([sd])([0-9]+)$")
561 if t == tp then
562 r = tonumber(r)
563 if r <= 31 then
564 if t == "s" then return shr(r, 1), band(r, 1) end
565 return band(r, 15), shr(r, 4)
566 end
567 end
568 werror("bad register name `"..expr.."'")
569end
570
479local function parse_reglist(reglist) 571local function parse_reglist(reglist)
480 reglist = match(reglist, "^{%s*([^}]*)}$") 572 reglist = match(reglist, "^{%s*([^}]*)}$")
481 if not reglist then werror("register list expected") end 573 if not reglist then werror("register list expected") end
@@ -490,6 +582,21 @@ local function parse_reglist(reglist)
490 return rr 582 return rr
491end 583end
492 584
585local function parse_vrlist(reglist)
586 local ta, ra, tb, rb = match(reglist,
587 "^{%s*([sd])([0-9]+)%s*%-%s*([sd])([0-9]+)%s*}$")
588 ra, rb = tonumber(ra), tonumber(rb)
589 if ta and ta == tb and ra and rb and ra <= 31 and rb <= 31 and ra <= rb then
590 local nr = rb+1 - ra
591 if ta == "s" then
592 return shl(shr(ra,1),12)+shl(band(ra,1),22) + nr
593 else
594 return shl(band(ra,15),12)+shl(shr(ra,4),22) + nr*2 + 0x100
595 end
596 end
597 werror("register list expected")
598end
599
493local function parse_imm(imm, bits, shift, scale, signed) 600local function parse_imm(imm, bits, shift, scale, signed)
494 imm = match(imm, "^#(.*)$") 601 imm = match(imm, "^#(.*)$")
495 if not imm then werror("expected immediate operand") end 602 if not imm then werror("expected immediate operand") end
@@ -680,81 +787,132 @@ local function parse_load(params, nparams, n, op)
680 return op 787 return op
681end 788end
682 789
790local function parse_vload(q)
791 local reg, imm = match(q, "^%[%s*([^,%s]*)%s*(.*)%]$")
792 if reg then
793 local d = shl(parse_gpr(reg), 16)
794 if imm == "" then return d end
795 imm = match(imm, "^,%s*#(.*)$")
796 if imm then
797 local n = tonumber(imm)
798 if n then
799 if n >= -1020 and n <= 1020 and n%4 == 0 then
800 return d + (n >= 0 and n/4+0x00800000 or -n/4)
801 end
802 werror("out of range immediate `"..imm.."'")
803 else
804 waction("IMMV8", 32768 + 32*8, imm)
805 return d
806 end
807 end
808 else
809 if match(q, "^[<>=%-]") or match(q, "^extern%s+") then
810 local mode, n, s = parse_label(q, false)
811 waction("REL_"..mode, n + 0x2800, s, 1)
812 return 15 * 65536
813 end
814 local reg, tailr = match(q, "^([%w_:]+)%s*(.*)$")
815 if reg and tailr ~= "" then
816 local d, tp = parse_gpr(reg)
817 if tp then
818 waction("IMMV8", 32768 + 32*8, format(tp.ctypefmt, tailr))
819 return shl(d, 16)
820 end
821 end
822 end
823 werror("expected address operand")
824end
825
683------------------------------------------------------------------------------ 826------------------------------------------------------------------------------
684 827
685-- Handle opcodes defined with template strings. 828-- Handle opcodes defined with template strings.
686map_op[".template__"] = function(params, template, nparams) 829local function parse_template(params, template, nparams, pos)
687 if not params then return sub(template, 9) end
688 local op = tonumber(sub(template, 1, 8), 16) 830 local op = tonumber(sub(template, 1, 8), 16)
689 local n = 1 831 local n = 1
690 832 local vr = "s"
691 -- Limit number of section buffer positions used by a single dasm_put().
692 -- A single opcode needs a maximum of 3 positions.
693 if secpos+3 > maxsecpos then wflush() end
694 local pos = wpos()
695 833
696 -- Process each character. 834 -- Process each character.
697 for p in gmatch(sub(template, 9), ".") do 835 for p in gmatch(sub(template, 9), ".") do
836 local q = params[n]
698 if p == "D" then 837 if p == "D" then
699 op = op + shl(parse_gpr(params[n]), 12); n = n + 1 838 op = op + shl(parse_gpr(q), 12); n = n + 1
700 elseif p == "N" then 839 elseif p == "N" then
701 op = op + shl(parse_gpr(params[n]), 16); n = n + 1 840 op = op + shl(parse_gpr(q), 16); n = n + 1
702 elseif p == "S" then 841 elseif p == "S" then
703 op = op + shl(parse_gpr(params[n]), 8); n = n + 1 842 op = op + shl(parse_gpr(q), 8); n = n + 1
704 elseif p == "M" then 843 elseif p == "M" then
705 op = op + parse_gpr(params[n]); n = n + 1 844 op = op + parse_gpr(q); n = n + 1
845 elseif p == "d" then
846 local r,h = parse_vr(q, vr); op = op+shl(r,12)+shl(h,22); n = n + 1
847 elseif p == "n" then
848 local r,h = parse_vr(q, vr); op = op+shl(r,16)+shl(h,7); n = n + 1
849 elseif p == "m" then
850 local r,h = parse_vr(q, vr); op = op+r+shl(h,5); n = n + 1
706 elseif p == "P" then 851 elseif p == "P" then
707 local imm = match(params[n], "^#(.*)$") 852 local imm = match(q, "^#(.*)$")
708 if imm then 853 if imm then
709 op = op + parse_imm12(imm) + 0x02000000 854 op = op + parse_imm12(imm) + 0x02000000
710 else 855 else
711 op = op + parse_gpr(params[n]) 856 op = op + parse_gpr(q)
712 end 857 end
713 n = n + 1 858 n = n + 1
714 elseif p == "p" then 859 elseif p == "p" then
715 op = op + parse_shift(params[n], true); n = n + 1 860 op = op + parse_shift(q, true); n = n + 1
716 elseif p == "L" then 861 elseif p == "L" then
717 op = parse_load(params, nparams, n, op) 862 op = parse_load(params, nparams, n, op)
863 elseif p == "l" then
864 op = op + parse_vload(q)
718 elseif p == "B" then 865 elseif p == "B" then
719 local mode, n, s = parse_label(params[n], false) 866 local mode, n, s = parse_label(q, false)
720 waction("REL_"..mode, n, s, 1) 867 waction("REL_"..mode, n, s, 1)
721 elseif p == "C" then -- blx gpr vs. blx label. 868 elseif p == "C" then -- blx gpr vs. blx label.
722 local p = params[n] 869 if match(q, "^([%w_]+):(r1?[0-9])$") or match(q, "^r(1?[0-9])$") then
723 if match(p, "^([%w_]+):(r1?[0-9])$") or match(p, "^r(1?[0-9])$") then 870 op = op + parse_gpr(q)
724 op = op + parse_gpr(p)
725 else 871 else
726 if op < 0xe0000000 then werror("unconditional instruction") end 872 if op < 0xe0000000 then werror("unconditional instruction") end
727 local mode, n, s = parse_label(p, false) 873 local mode, n, s = parse_label(q, false)
728 waction("REL_"..mode, n, s, 1) 874 waction("REL_"..mode, n, s, 1)
729 op = 0xfa000000 875 op = 0xfa000000
730 end 876 end
731 elseif p == "n" then 877 elseif p == "F" then
732 local r, wb = match(params[n], "^([^!]*)(!?)$") 878 vr = "s"
879 elseif p == "G" then
880 vr = "d"
881 elseif p == "o" then
882 local r, wb = match(q, "^([^!]*)(!?)$")
733 op = op + shl(parse_gpr(r), 16) + (wb == "!" and 0x00200000 or 0) 883 op = op + shl(parse_gpr(r), 16) + (wb == "!" and 0x00200000 or 0)
734 n = n + 1 884 n = n + 1
735 elseif p == "R" then 885 elseif p == "R" then
736 op = op + parse_reglist(params[n]); n = n + 1 886 op = op + parse_reglist(q); n = n + 1
887 elseif p == "r" then
888 op = op + parse_vrlist(q); n = n + 1
737 elseif p == "W" then 889 elseif p == "W" then
738 op = op + parse_imm16(params[n]); n = n + 1 890 op = op + parse_imm16(q); n = n + 1
739 elseif p == "v" then 891 elseif p == "v" then
740 op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1 892 op = op + parse_imm(q, 5, 7, 0, false); n = n + 1
741 elseif p == "w" then 893 elseif p == "w" then
742 local imm = match(params[n], "^#(.*)$") 894 local imm = match(q, "^#(.*)$")
743 if imm then 895 if imm then
744 op = op + parse_imm(params[n], 5, 7, 0, false); n = n + 1 896 op = op + parse_imm(q, 5, 7, 0, false); n = n + 1
745 else 897 else
746 op = op + shl(parse_gpr(params[n]), 8) + 16 898 op = op + shl(parse_gpr(q), 8) + 16
747 end 899 end
748 elseif p == "X" then 900 elseif p == "X" then
749 op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1 901 op = op + parse_imm(q, 5, 16, 0, false); n = n + 1
902 elseif p == "Y" then
903 local imm = tonumber(match(q, "^#(.*)$")); n = n + 1
904 if not imm or shr(imm, 8) ~= 0 then
905 werror("bad immediate operand")
906 end
907 op = op + shl(band(imm, 0xf0), 12) + band(imm, 0x0f)
750 elseif p == "K" then 908 elseif p == "K" then
751 local imm = tonumber(match(params[n], "^#(.*)$")); n = n + 1 909 local imm = tonumber(match(q, "^#(.*)$")); n = n + 1
752 if not imm or shr(imm, 16) ~= 0 then 910 if not imm or shr(imm, 16) ~= 0 then
753 werror("bad immediate operand") 911 werror("bad immediate operand")
754 end 912 end
755 op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f) 913 op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f)
756 elseif p == "T" then 914 elseif p == "T" then
757 op = op + parse_imm(params[n], 24, 0, 0, false); n = n + 1 915 op = op + parse_imm(q, 24, 0, 0, false); n = n + 1
758 elseif p == "s" then 916 elseif p == "s" then
759 -- Ignored. 917 -- Ignored.
760 else 918 else
@@ -764,6 +922,27 @@ map_op[".template__"] = function(params, template, nparams)
764 wputpos(pos, op) 922 wputpos(pos, op)
765end 923end
766 924
925map_op[".template__"] = function(params, template, nparams)
926 if not params then return sub(template, 9) end
927
928 -- Limit number of section buffer positions used by a single dasm_put().
929 -- A single opcode needs a maximum of 3 positions.
930 if secpos+3 > maxsecpos then wflush() end
931 local pos = wpos()
932 local apos, spos = #actargs, secpos
933
934 local ok, err
935 for t in gmatch(template, "[^|]+") do
936 ok, err = pcall(parse_template, params, t, nparams, pos)
937 if ok then return end
938 secpos = spos
939 actargs[apos+1] = nil
940 actargs[apos+2] = nil
941 actargs[apos+3] = nil
942 end
943 error(err, 0)
944end
945
767------------------------------------------------------------------------------ 946------------------------------------------------------------------------------
768 947
769-- Pseudo-opcode to mark the position where the action list is to be emitted. 948-- Pseudo-opcode to mark the position where the action list is to be emitted.
@@ -923,10 +1102,10 @@ function _M.mergemaps(map_coreop, map_def)
923 setmetatable(map_op, { __index = function(t, k) 1102 setmetatable(map_op, { __index = function(t, k)
924 local v = map_coreop[k] 1103 local v = map_coreop[k]
925 if v then return v end 1104 if v then return v end
926 local cc = sub(k, -4, -3) 1105 local k1, cc, k2 = match(k, "^(.-)(..)([._].*)$")
927 local cv = map_cond[cc] 1106 local cv = map_cond[cc]
928 if cv then 1107 if cv then
929 local v = rawget(t, sub(k, 1, -5)..sub(k, -2)) 1108 local v = rawget(t, k1..k2)
930 if type(v) == "string" then return format("%x%s", cv, sub(v, 2)) end 1109 if type(v) == "string" then return format("%x%s", cv, sub(v, 2)) end
931 end 1110 end
932 end }) 1111 end })