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 /dynasm | |
parent | b2a5cc82338aad90ca16fced8631ac1a634949e9 (diff) | |
download | luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.tar.gz luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.tar.bz2 luajit-1c968d5b631e3bece678dcdce4c14afb9d79d409.zip |
DynASM/PPC: Add sub/shift/rotate/clear instruction aliases.
Diffstat (limited to 'dynasm')
-rw-r--r-- | dynasm/dasm_ppc.lua | 93 |
1 files changed, 88 insertions, 5 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. |