diff options
| author | Mike Pall <mike> | 2015-04-12 01:27:17 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2015-04-12 03:46:16 +0200 |
| commit | 1c968d5b631e3bece678dcdce4c14afb9d79d409 (patch) | |
| tree | 4dd2549cdedc62e1c42971928f43febf463432df | |
| parent | b2a5cc82338aad90ca16fced8631ac1a634949e9 (diff) | |
| download | luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.tar.gz luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.tar.bz2 luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.zip | |
DynASM/PPC: Add sub/shift/rotate/clear instruction aliases.
| -rw-r--r-- | dynasm/dasm_ppc.lua | 93 | ||||
| -rw-r--r-- | src/vm_ppc.dasc | 7 |
2 files changed, 88 insertions, 12 deletions
diff --git a/dynasm/dasm_ppc.lua b/dynasm/dasm_ppc.lua index 784223df..278f0952 100644 --- a/dynasm/dasm_ppc.lua +++ b/dynasm/dasm_ppc.lua | |||
| @@ -230,8 +230,18 @@ local map_cond = { | |||
| 230 | 230 | ||
| 231 | ------------------------------------------------------------------------------ | 231 | ------------------------------------------------------------------------------ |
| 232 | 232 | ||
| 233 | local map_op, op_template | ||
| 234 | |||
| 235 | local function op_alias(opname, f) | ||
| 236 | return function(params, nparams) | ||
| 237 | if not params then return "-> "..opname:sub(1, -3) end | ||
| 238 | f(params, nparams) | ||
| 239 | op_template(params, map_op[opname], nparams) | ||
| 240 | end | ||
| 241 | end | ||
| 242 | |||
| 233 | -- Template strings for PPC instructions. | 243 | -- Template strings for PPC instructions. |
| 234 | local map_op = { | 244 | map_op = { |
| 235 | tdi_3 = "08000000ARI", | 245 | tdi_3 = "08000000ARI", |
| 236 | twi_3 = "0c000000ARI", | 246 | twi_3 = "0c000000ARI", |
| 237 | mulli_3 = "1c000000RRI", | 247 | mulli_3 = "1c000000RRI", |
| @@ -299,6 +309,33 @@ local map_op = { | |||
| 299 | std_2 = "f8000000RD", | 309 | std_2 = "f8000000RD", |
| 300 | stdu_2 = "f8000001RD", | 310 | stdu_2 = "f8000001RD", |
| 301 | 311 | ||
| 312 | subi_3 = op_alias("addi_3", function(p) p[3] = "-("..p[3]..")" end), | ||
| 313 | subis_3 = op_alias("addis_3", function(p) p[3] = "-("..p[3]..")" end), | ||
| 314 | subic_3 = op_alias("addic_3", function(p) p[3] = "-("..p[3]..")" end), | ||
| 315 | ["subic._3"] = op_alias("addic._3", function(p) p[3] = "-("..p[3]..")" end), | ||
| 316 | |||
| 317 | rotlwi_3 = op_alias("rlwinm_5", function(p) | ||
| 318 | p[4] = "0"; p[5] = "31" | ||
| 319 | end), | ||
| 320 | rotrwi_3 = op_alias("rlwinm_5", function(p) | ||
| 321 | p[3] = "32-("..p[3]..")"; p[4] = "0"; p[5] = "31" | ||
| 322 | end), | ||
| 323 | rotlw_3 = op_alias("rlwnm_5", function(p) | ||
| 324 | p[4] = "0"; p[5] = "31" | ||
| 325 | end), | ||
| 326 | slwi_3 = op_alias("rlwinm_5", function(p) | ||
| 327 | p[5] = "31-("..p[3]..")"; p[4] = "0" | ||
| 328 | end), | ||
| 329 | srwi_3 = op_alias("rlwinm_5", function(p) | ||
| 330 | p[4] = p[3]; p[3] = "32-("..p[3]..")"; p[5] = "31" | ||
| 331 | end), | ||
| 332 | clrlwi_3 = op_alias("rlwinm_5", function(p) | ||
| 333 | p[4] = p[3]; p[3] = "0"; p[5] = "31" | ||
| 334 | end), | ||
| 335 | clrrwi_3 = op_alias("rlwinm_5", function(p) | ||
| 336 | p[5] = "31-("..p[3]..")"; p[3] = "0"; p[4] = "0" | ||
| 337 | end), | ||
| 338 | |||
| 302 | -- Primary opcode 4: | 339 | -- Primary opcode 4: |
| 303 | mulhhwu_3 = "10000010RRR.", | 340 | mulhhwu_3 = "10000010RRR.", |
| 304 | machhwu_3 = "10000018RRR.", | 341 | machhwu_3 = "10000018RRR.", |
| @@ -790,6 +827,28 @@ local map_op = { | |||
| 790 | rldcl_4 = "78000010RR~RM.", | 827 | rldcl_4 = "78000010RR~RM.", |
| 791 | rldcr_4 = "78000012RR~RM.", | 828 | rldcr_4 = "78000012RR~RM.", |
| 792 | 829 | ||
| 830 | rotldi_3 = op_alias("rldicl_4", function(p) | ||
| 831 | p[4] = "0" | ||
| 832 | end), | ||
| 833 | rotrdi_3 = op_alias("rldicl_4", function(p) | ||
| 834 | p[3] = "64-("..p[3]..")"; p[4] = "0" | ||
| 835 | end), | ||
| 836 | rotld_3 = op_alias("rldcl_4", function(p) | ||
| 837 | p[4] = "0" | ||
| 838 | end), | ||
| 839 | sldi_3 = op_alias("rldicr_4", function(p) | ||
| 840 | p[4] = "63-("..p[3]..")" | ||
| 841 | end), | ||
| 842 | srdi_3 = op_alias("rldicl_4", function(p) | ||
| 843 | p[4] = p[3]; p[3] = "64-("..p[3]..")" | ||
| 844 | end), | ||
| 845 | clrldi_3 = op_alias("rldicl_4", function(p) | ||
| 846 | p[4] = p[3]; p[3] = "0" | ||
| 847 | end), | ||
| 848 | clrrdi_3 = op_alias("rldicr_4", function(p) | ||
| 849 | p[4] = "63-("..p[3]..")"; p[3] = "0" | ||
| 850 | end), | ||
| 851 | |||
| 793 | -- Primary opcode 56: | 852 | -- Primary opcode 56: |
| 794 | lq_2 = "e0000000R:D", -- NYI: displacement must be divisible by 8. | 853 | lq_2 = "e0000000R:D", -- NYI: displacement must be divisible by 8. |
| 795 | 854 | ||
| @@ -1358,7 +1417,7 @@ local map_op = { | |||
| 1358 | do | 1417 | do |
| 1359 | local t = {} | 1418 | local t = {} |
| 1360 | for k,v in pairs(map_op) do | 1419 | for k,v in pairs(map_op) do |
| 1361 | if sub(v, -1) == "." then | 1420 | if type(v) == "string" and sub(v, -1) == "." then |
| 1362 | local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2) | 1421 | local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2) |
| 1363 | t[sub(k, 1, -3).."."..sub(k, -2)] = v2 | 1422 | t[sub(k, 1, -3).."."..sub(k, -2)] = v2 |
| 1364 | end | 1423 | end |
| @@ -1454,8 +1513,30 @@ local function parse_cond(expr) | |||
| 1454 | werror("bad condition bit name `"..expr.."'") | 1513 | werror("bad condition bit name `"..expr.."'") |
| 1455 | end | 1514 | end |
| 1456 | 1515 | ||
| 1516 | local parse_ctx = {} | ||
| 1517 | |||
| 1518 | local loadenv = setfenv and function(s) | ||
| 1519 | local code = loadstring(s, "") | ||
| 1520 | if code then setfenv(code, parse_ctx) end | ||
| 1521 | return code | ||
| 1522 | end or function(s) | ||
| 1523 | return load(s, "", nil, parse_ctx) | ||
| 1524 | end | ||
| 1525 | |||
| 1526 | -- Try to parse simple arithmetic, too, since some basic ops are aliases. | ||
| 1527 | local function parse_number(n) | ||
| 1528 | local x = tonumber(n) | ||
| 1529 | if x then return x end | ||
| 1530 | local code = loadenv("return "..n) | ||
| 1531 | if code then | ||
| 1532 | local ok, y = pcall(code) | ||
| 1533 | if ok then return y end | ||
| 1534 | end | ||
| 1535 | return nil | ||
| 1536 | end | ||
| 1537 | |||
| 1457 | local function parse_imm(imm, bits, shift, scale, signed) | 1538 | local function parse_imm(imm, bits, shift, scale, signed) |
| 1458 | local n = tonumber(imm) | 1539 | local n = parse_number(imm) |
| 1459 | if n then | 1540 | if n then |
| 1460 | local m = sar(n, scale) | 1541 | local m = sar(n, scale) |
| 1461 | if shl(m, scale) == n then | 1542 | if shl(m, scale) == n then |
| @@ -1479,7 +1560,7 @@ local function parse_imm(imm, bits, shift, scale, signed) | |||
| 1479 | end | 1560 | end |
| 1480 | 1561 | ||
| 1481 | local function parse_shiftmask(imm, isshift) | 1562 | local function parse_shiftmask(imm, isshift) |
| 1482 | local n = tonumber(imm) | 1563 | local n = parse_number(imm) |
| 1483 | if n then | 1564 | if n then |
| 1484 | if shr(n, 6) == 0 then | 1565 | if shr(n, 6) == 0 then |
| 1485 | local lsb = band(n, 31) | 1566 | local lsb = band(n, 31) |
| @@ -1567,7 +1648,7 @@ end | |||
| 1567 | ------------------------------------------------------------------------------ | 1648 | ------------------------------------------------------------------------------ |
| 1568 | 1649 | ||
| 1569 | -- Handle opcodes defined with template strings. | 1650 | -- Handle opcodes defined with template strings. |
| 1570 | map_op[".template__"] = function(params, template, nparams) | 1651 | op_template = function(params, template, nparams) |
| 1571 | if not params then return sub(template, 9) end | 1652 | if not params then return sub(template, 9) end |
| 1572 | local op = tonumber(sub(template, 1, 8), 16) | 1653 | local op = tonumber(sub(template, 1, 8), 16) |
| 1573 | local n, rs = 1, 26 | 1654 | local n, rs = 1, 26 |
| @@ -1669,6 +1750,8 @@ map_op[".template__"] = function(params, template, nparams) | |||
| 1669 | wputpos(pos, op) | 1750 | wputpos(pos, op) |
| 1670 | end | 1751 | end |
| 1671 | 1752 | ||
| 1753 | map_op[".template__"] = op_template | ||
| 1754 | |||
| 1672 | ------------------------------------------------------------------------------ | 1755 | ------------------------------------------------------------------------------ |
| 1673 | 1756 | ||
| 1674 | -- Pseudo-opcode to mark the position where the action list is to be emitted. | 1757 | -- Pseudo-opcode to mark the position where the action list is to be emitted. |
diff --git a/src/vm_ppc.dasc b/src/vm_ppc.dasc index 8e5278af..9299c554 100644 --- a/src/vm_ppc.dasc +++ b/src/vm_ppc.dasc | |||
| @@ -320,13 +320,6 @@ | |||
| 320 | | | 320 | | |
| 321 | |//----------------------------------------------------------------------- | 321 | |//----------------------------------------------------------------------- |
| 322 | | | 322 | | |
| 323 | |// These basic macros should really be part of DynASM. | ||
| 324 | |.macro srwi, rx, ry, n; rlwinm rx, ry, 32-n, n, 31; .endmacro | ||
| 325 | |.macro slwi, rx, ry, n; rlwinm rx, ry, n, 0, 31-n; .endmacro | ||
| 326 | |.macro rotlwi, rx, ry, n; rlwinm rx, ry, n, 0, 31; .endmacro | ||
| 327 | |.macro rotlw, rx, ry, rn; rlwnm rx, ry, rn, 0, 31; .endmacro | ||
| 328 | |.macro subi, rx, ry, i; addi rx, ry, -i; .endmacro | ||
| 329 | | | ||
| 330 | |// Trap for not-yet-implemented parts. | 323 | |// Trap for not-yet-implemented parts. |
| 331 | |.macro NYI; tw 4, sp, sp; .endmacro | 324 | |.macro NYI; tw 4, sp, sp; .endmacro |
| 332 | | | 325 | | |
