1 ------------------------------------------------------------------------------
2 -- DynASM PPC/PPC64 module.
4 -- Copyright (C) 2005-2023 Mike Pall. All rights reserved.
5 -- See dynasm.lua for full copyright notice.
7 -- Support for various extensions contributed by Caio Souza Oliveira.
8 ------------------------------------------------------------------------------
10 -- Module information:
13 description
= "DynASM PPC module",
16 release
= "2021-05-02",
21 -- Exported glue functions for the arch-specific module.
22 local _M
= { _info
= _info
}
24 -- Cache library functions.
25 local type, tonumber, pairs
, ipairs
= type, tonumber, pairs
, ipairs
26 local assert, setmetatable
= assert, setmetatable
28 local sub
, format, byte
, char
= _s
.sub
, _s
.format, _s
.byte
, _s
.char
29 local match
, gmatch
= _s
.match
, _s
.gmatch
30 local concat
, sort = table.concat
, table.sort
31 local bit
= bit
or require("bit")
32 local band
, shl
, shr
, sar
= bit
.band
, bit
.lshift
, bit
.rshift
, bit
.arshift
33 local tohex
= bit
.tohex
35 -- Inherited tables and callbacks.
37 local wline
, werror
, wfatal
, wwarn
40 -- CHECK: Keep this in sync with the C code!
41 local action_names
= {
42 "STOP", "SECTION", "ESC", "REL_EXT",
43 "ALIGN", "REL_LG", "LABEL_LG",
44 "REL_PC", "LABEL_PC", "IMM", "IMMSH"
47 -- Maximum number of section buffer positions for dasm_put().
48 -- CHECK: Keep this in sync with the C code!
49 local maxsecpos
= 25 -- Keep this low, to avoid excessively long C lines.
51 -- Action name -> action number.
53 for n
,name
in ipairs(action_names
) do
54 map_action
[name
] = n
-1
57 -- Action list buffer.
60 -- Argument list for next dasm_put(). Start with offset 0 into action list.
63 -- Current number of section buffer positions for dasm_put().
66 ------------------------------------------------------------------------------
68 -- Dump action names and numbers.
69 local function dumpactions(out
)
70 out
:write("DynASM encoding engine action codes:\n")
71 for n
,name
in ipairs(action_names
) do
72 local num
= map_action
[name
]
73 out
:write(format(" %-10s %02X %d\n", name
, num
, num
))
78 -- Write action list buffer as a huge static C array.
79 local function writeactions(out
, name
)
81 if nn
== 0 then nn
= 1; actlist
[0] = map_action
.STOP
end
82 out
:write("static const unsigned int ", name
, "[", nn
, "] = {\n")
84 assert(out
:write("0x", tohex(actlist
[i
]), ",\n"))
86 assert(out
:write("0x", tohex(actlist
[nn
]), "\n};\n\n"))
89 ------------------------------------------------------------------------------
91 -- Add word to action list.
92 local function wputxw(n
)
93 assert(n
>= 0 and n
<= 0xffffffff and n
% 1 == 0, "word out of range")
94 actlist
[#actlist
+1] = n
97 -- Add action to list with optional arg. Advance buffer pos, too.
98 local function waction(action
, val
, a
, num
)
99 local w
= assert(map_action
[action
], "bad action name `"..action
.."'")
100 wputxw(w
* 0x10000 + (val
or 0))
101 if a
then actargs
[#actargs
+1] = a
end
102 if a
or num
then secpos
= secpos
+ (num
or 1) end
105 -- Flush action list (intervening C code or buffer pos overflow).
106 local function wflush(term
)
107 if #actlist
== actargs
[1] then return end -- Nothing to flush.
108 if not term
then waction("STOP") end -- Terminate action list.
109 wline(format("dasm_put(Dst, %s);", concat(actargs
, ", ")), true)
110 actargs
= { #actlist
} -- Actionlist offset is 1st arg to next dasm_put().
111 secpos
= 1 -- The actionlist offset occupies a buffer position, too.
115 local function wputw(n
)
116 if n
<= 0xffffff then waction("ESC") end
120 -- Reserve position for word.
121 local function wpos()
122 local pos
= #actlist
+1
127 -- Store word to reserved position.
128 local function wputpos(pos
, n
)
129 assert(n
>= 0 and n
<= 0xffffffff and n
% 1 == 0, "word out of range")
133 ------------------------------------------------------------------------------
135 -- Global label name -> global label number. With auto assignment on 1st use.
136 local next_global
= 20
137 local map_global
= setmetatable({}, { __index
= function(t
, name
)
138 if not match(name
, "^[%a_][%w_]*$") then werror("bad global label") end
139 local n
= next_global
140 if n
> 2047 then werror("too many global labels") end
146 -- Dump global labels.
147 local function dumpglobals(out
, lvl
)
149 for name
, n
in pairs(map_global
) do t
[n
] = name
end
150 out
:write("Global labels:\n")
151 for i
=20,next_global
-1 do
152 out
:write(format(" %s\n", t
[i
]))
157 -- Write global label enum.
158 local function writeglobals(out
, prefix
)
160 for name
, n
in pairs(map_global
) do t
[n
] = name
end
161 out
:write("enum {\n")
162 for i
=20,next_global
-1 do
163 out
:write(" ", prefix
, t
[i
], ",\n")
165 out
:write(" ", prefix
, "_MAX\n};\n")
168 -- Write global label names.
169 local function writeglobalnames(out
, name
)
171 for name
, n
in pairs(map_global
) do t
[n
] = name
end
172 out
:write("static const char *const ", name
, "[] = {\n")
173 for i
=20,next_global
-1 do
174 out
:write(" \"", t
[i
], "\",\n")
176 out
:write(" (const char *)0\n};\n")
179 ------------------------------------------------------------------------------
181 -- Extern label name -> extern label number. With auto assignment on 1st use.
182 local next_extern
= 0
183 local map_extern_
= {}
184 local map_extern
= setmetatable({}, { __index
= function(t
, name
)
185 -- No restrictions on the name for now.
186 local n
= next_extern
187 if n
> 2047 then werror("too many extern labels") end
190 map_extern_
[n
] = name
194 -- Dump extern labels.
195 local function dumpexterns(out
, lvl
)
196 out
:write("Extern labels:\n")
197 for i
=0,next_extern
-1 do
198 out
:write(format(" %s\n", map_extern_
[i
]))
203 -- Write extern label names.
204 local function writeexternnames(out
, name
)
205 out
:write("static const char *const ", name
, "[] = {\n")
206 for i
=0,next_extern
-1 do
207 out
:write(" \"", map_extern_
[i
], "\",\n")
209 out
:write(" (const char *)0\n};\n")
212 ------------------------------------------------------------------------------
214 -- Arch-specific maps.
215 local map_archdef
= { sp
= "r1" } -- Ext. register name -> int. name.
217 local map_type
= {} -- Type name -> { ctype, reg }
218 local ctypenum
= 0 -- Type number (for Dt... macros).
220 -- Reverse defines for registers.
221 function _M
.revdef(s
)
222 if s
== "r1" then return "sp" end
227 lt
= 0, gt
= 1, eq
= 2, so
= 3,
228 ge
= 4, le
= 5, ne
= 6, ns
= 7,
231 ------------------------------------------------------------------------------
233 local map_op
, op_template
235 local function op_alias(opname
, f
)
236 return function(params
, nparams
)
237 if not params
then return "-> "..opname
:sub(1, -3) end
239 op_template(params
, map_op
[opname
], nparams
)
243 -- Template strings for PPC instructions.
245 tdi_3
= "08000000ARI",
246 twi_3
= "0c000000ARI",
247 mulli_3
= "1c000000RRI",
248 subfic_3
= "20000000RRI",
249 cmplwi_3
= "28000000XRU",
250 cmplwi_2
= "28000000-RU",
251 cmpldi_3
= "28200000XRU",
252 cmpldi_2
= "28200000-RU",
253 cmpwi_3
= "2c000000XRI",
254 cmpwi_2
= "2c000000-RI",
255 cmpdi_3
= "2c200000XRI",
256 cmpdi_2
= "2c200000-RI",
257 addic_3
= "30000000RRI",
258 ["addic._3"] = "34000000RRI",
259 addi_3
= "38000000RR0I",
262 addis_3
= "3c000000RR0I",
263 lis_2
= "3c000000RI",
264 lus_2
= "3c000000RU",
265 bc_3
= "40000000AAK",
266 bcl_3
= "40000001AAK",
267 bdnz_1
= "42000000K",
272 rlwimi_5
= "50000000RR~AAA.",
273 rlwinm_5
= "54000000RR~AAA.",
274 rlwnm_5
= "5c000000RR~RAA.",
275 ori_3
= "60000000RR~U",
277 oris_3
= "64000000RR~U",
278 xori_3
= "68000000RR~U",
279 xoris_3
= "6c000000RR~U",
280 ["andi._3"] = "70000000RR~U",
281 ["andis._3"] = "74000000RR~U",
282 lwz_2
= "80000000RD",
283 lwzu_2
= "84000000RD",
284 lbz_2
= "88000000RD",
285 lbzu_2
= "8c000000RD",
286 stw_2
= "90000000RD",
287 stwu_2
= "94000000RD",
288 stb_2
= "98000000RD",
289 stbu_2
= "9c000000RD",
290 lhz_2
= "a0000000RD",
291 lhzu_2
= "a4000000RD",
292 lha_2
= "a8000000RD",
293 lhau_2
= "ac000000RD",
294 sth_2
= "b0000000RD",
295 sthu_2
= "b4000000RD",
296 lmw_2
= "b8000000RD",
297 stmw_2
= "bc000000RD",
298 lfs_2
= "c0000000FD",
299 lfsu_2
= "c4000000FD",
300 lfd_2
= "c8000000FD",
301 lfdu_2
= "cc000000FD",
302 stfs_2
= "d0000000FD",
303 stfsu_2
= "d4000000FD",
304 stfd_2
= "d8000000FD",
305 stfdu_2
= "dc000000FD",
306 ld_2
= "e8000000RD", -- NYI: displacement must be divisible by 4.
307 ldu_2
= "e8000001RD",
308 lwa_2
= "e8000002RD",
309 std_2
= "f8000000RD",
310 stdu_2
= "f8000001RD",
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),
317 rotlwi_3
= op_alias("rlwinm_5", function(p
)
318 p
[4] = "0"; p
[5] = "31"
320 rotrwi_3
= op_alias("rlwinm_5", function(p
)
321 p
[3] = "32-("..p
[3]..")"; p
[4] = "0"; p
[5] = "31"
323 rotlw_3
= op_alias("rlwnm_5", function(p
)
324 p
[4] = "0"; p
[5] = "31"
326 slwi_3
= op_alias("rlwinm_5", function(p
)
327 p
[5] = "31-("..p
[3]..")"; p
[4] = "0"
329 srwi_3
= op_alias("rlwinm_5", function(p
)
330 p
[4] = p
[3]; p
[3] = "32-("..p
[3]..")"; p
[5] = "31"
332 clrlwi_3
= op_alias("rlwinm_5", function(p
)
333 p
[4] = p
[3]; p
[3] = "0"; p
[5] = "31"
335 clrrwi_3
= op_alias("rlwinm_5", function(p
)
336 p
[5] = "31-("..p
[3]..")"; p
[3] = "0"; p
[4] = "0"
340 mulhhwu_3
= "10000010RRR.",
341 machhwu_3
= "10000018RRR.",
342 mulhhw_3
= "10000050RRR.",
343 nmachhw_3
= "1000005cRRR.",
344 machhwsu_3
= "10000098RRR.",
345 machhws_3
= "100000d8RRR.",
346 nmachhws_3
= "100000dcRRR.",
347 mulchwu_3
= "10000110RRR.",
348 macchwu_3
= "10000118RRR.",
349 mulchw_3
= "10000150RRR.",
350 macchw_3
= "10000158RRR.",
351 nmacchw_3
= "1000015cRRR.",
352 macchwsu_3
= "10000198RRR.",
353 macchws_3
= "100001d8RRR.",
354 nmacchws_3
= "100001dcRRR.",
355 mullhw_3
= "10000350RRR.",
356 maclhw_3
= "10000358RRR.",
357 nmaclhw_3
= "1000035cRRR.",
358 maclhwsu_3
= "10000398RRR.",
359 maclhws_3
= "100003d8RRR.",
360 nmaclhws_3
= "100003dcRRR.",
361 machhwuo_3
= "10000418RRR.",
362 nmachhwo_3
= "1000045cRRR.",
363 machhwsuo_3
= "10000498RRR.",
364 machhwso_3
= "100004d8RRR.",
365 nmachhwso_3
= "100004dcRRR.",
366 macchwuo_3
= "10000518RRR.",
367 macchwo_3
= "10000558RRR.",
368 nmacchwo_3
= "1000055cRRR.",
369 macchwsuo_3
= "10000598RRR.",
370 macchwso_3
= "100005d8RRR.",
371 nmacchwso_3
= "100005dcRRR.",
372 maclhwo_3
= "10000758RRR.",
373 nmaclhwo_3
= "1000075cRRR.",
374 maclhwsuo_3
= "10000798RRR.",
375 maclhwso_3
= "100007d8RRR.",
376 nmaclhwso_3
= "100007dcRRR.",
378 vaddubm_3
= "10000000VVV",
379 vmaxub_3
= "10000002VVV",
380 vrlb_3
= "10000004VVV",
381 vcmpequb_3
= "10000006VVV",
382 vmuloub_3
= "10000008VVV",
383 vaddfp_3
= "1000000aVVV",
384 vmrghb_3
= "1000000cVVV",
385 vpkuhum_3
= "1000000eVVV",
386 vmhaddshs_4
= "10000020VVVV",
387 vmhraddshs_4
= "10000021VVVV",
388 vmladduhm_4
= "10000022VVVV",
389 vmsumubm_4
= "10000024VVVV",
390 vmsummbm_4
= "10000025VVVV",
391 vmsumuhm_4
= "10000026VVVV",
392 vmsumuhs_4
= "10000027VVVV",
393 vmsumshm_4
= "10000028VVVV",
394 vmsumshs_4
= "10000029VVVV",
395 vsel_4
= "1000002aVVVV",
396 vperm_4
= "1000002bVVVV",
397 vsldoi_4
= "1000002cVVVP",
398 vpermxor_4
= "1000002dVVVV",
399 vmaddfp_4
= "1000002eVVVV~",
400 vnmsubfp_4
= "1000002fVVVV~",
401 vaddeuqm_4
= "1000003cVVVV",
402 vaddecuq_4
= "1000003dVVVV",
403 vsubeuqm_4
= "1000003eVVVV",
404 vsubecuq_4
= "1000003fVVVV",
405 vadduhm_3
= "10000040VVV",
406 vmaxuh_3
= "10000042VVV",
407 vrlh_3
= "10000044VVV",
408 vcmpequh_3
= "10000046VVV",
409 vmulouh_3
= "10000048VVV",
410 vsubfp_3
= "1000004aVVV",
411 vmrghh_3
= "1000004cVVV",
412 vpkuwum_3
= "1000004eVVV",
413 vadduwm_3
= "10000080VVV",
414 vmaxuw_3
= "10000082VVV",
415 vrlw_3
= "10000084VVV",
416 vcmpequw_3
= "10000086VVV",
417 vmulouw_3
= "10000088VVV",
418 vmuluwm_3
= "10000089VVV",
419 vmrghw_3
= "1000008cVVV",
420 vpkuhus_3
= "1000008eVVV",
421 vaddudm_3
= "100000c0VVV",
422 vmaxud_3
= "100000c2VVV",
423 vrld_3
= "100000c4VVV",
424 vcmpeqfp_3
= "100000c6VVV",
425 vcmpequd_3
= "100000c7VVV",
426 vpkuwus_3
= "100000ceVVV",
427 vadduqm_3
= "10000100VVV",
428 vmaxsb_3
= "10000102VVV",
429 vslb_3
= "10000104VVV",
430 vmulosb_3
= "10000108VVV",
431 vrefp_2
= "1000010aV-V",
432 vmrglb_3
= "1000010cVVV",
433 vpkshus_3
= "1000010eVVV",
434 vaddcuq_3
= "10000140VVV",
435 vmaxsh_3
= "10000142VVV",
436 vslh_3
= "10000144VVV",
437 vmulosh_3
= "10000148VVV",
438 vrsqrtefp_2
= "1000014aV-V",
439 vmrglh_3
= "1000014cVVV",
440 vpkswus_3
= "1000014eVVV",
441 vaddcuw_3
= "10000180VVV",
442 vmaxsw_3
= "10000182VVV",
443 vslw_3
= "10000184VVV",
444 vmulosw_3
= "10000188VVV",
445 vexptefp_2
= "1000018aV-V",
446 vmrglw_3
= "1000018cVVV",
447 vpkshss_3
= "1000018eVVV",
448 vmaxsd_3
= "100001c2VVV",
449 vsl_3
= "100001c4VVV",
450 vcmpgefp_3
= "100001c6VVV",
451 vlogefp_2
= "100001caV-V",
452 vpkswss_3
= "100001ceVVV",
453 vadduhs_3
= "10000240VVV",
454 vminuh_3
= "10000242VVV",
455 vsrh_3
= "10000244VVV",
456 vcmpgtuh_3
= "10000246VVV",
457 vmuleuh_3
= "10000248VVV",
458 vrfiz_2
= "1000024aV-V",
459 vsplth_3
= "1000024cVV3",
460 vupkhsh_2
= "1000024eV-V",
461 vminuw_3
= "10000282VVV",
462 vminud_3
= "100002c2VVV",
463 vcmpgtud_3
= "100002c7VVV",
464 vrfim_2
= "100002caV-V",
465 vcmpgtsb_3
= "10000306VVV",
466 vcfux_3
= "1000030aVVA~",
467 vaddshs_3
= "10000340VVV",
468 vminsh_3
= "10000342VVV",
469 vsrah_3
= "10000344VVV",
470 vcmpgtsh_3
= "10000346VVV",
471 vmulesh_3
= "10000348VVV",
472 vcfsx_3
= "1000034aVVA~",
473 vspltish_2
= "1000034cVS",
474 vupkhpx_2
= "1000034eV-V",
475 vaddsws_3
= "10000380VVV",
476 vminsw_3
= "10000382VVV",
477 vsraw_3
= "10000384VVV",
478 vcmpgtsw_3
= "10000386VVV",
479 vmulesw_3
= "10000388VVV",
480 vctuxs_3
= "1000038aVVA~",
481 vspltisw_2
= "1000038cVS",
482 vminsd_3
= "100003c2VVV",
483 vsrad_3
= "100003c4VVV",
484 vcmpbfp_3
= "100003c6VVV",
485 vcmpgtsd_3
= "100003c7VVV",
486 vctsxs_3
= "100003caVVA~",
487 vupklpx_2
= "100003ceV-V",
488 vsububm_3
= "10000400VVV",
489 ["bcdadd._4"] = "10000401VVVy.",
490 vavgub_3
= "10000402VVV",
491 vand_3
= "10000404VVV",
492 ["vcmpequb._3"] = "10000406VVV",
493 vmaxfp_3
= "1000040aVVV",
494 vsubuhm_3
= "10000440VVV",
495 ["bcdsub._4"] = "10000441VVVy.",
496 vavguh_3
= "10000442VVV",
497 vandc_3
= "10000444VVV",
498 ["vcmpequh._3"] = "10000446VVV",
499 vminfp_3
= "1000044aVVV",
500 vpkudum_3
= "1000044eVVV",
501 vsubuwm_3
= "10000480VVV",
502 vavguw_3
= "10000482VVV",
503 vor_3
= "10000484VVV",
504 ["vcmpequw._3"] = "10000486VVV",
505 vpmsumw_3
= "10000488VVV",
506 ["vcmpeqfp._3"] = "100004c6VVV",
507 ["vcmpequd._3"] = "100004c7VVV",
508 vpkudus_3
= "100004ceVVV",
509 vavgsb_3
= "10000502VVV",
510 vavgsh_3
= "10000542VVV",
511 vorc_3
= "10000544VVV",
512 vbpermq_3
= "1000054cVVV",
513 vpksdus_3
= "1000054eVVV",
514 vavgsw_3
= "10000582VVV",
515 vsld_3
= "100005c4VVV",
516 ["vcmpgefp._3"] = "100005c6VVV",
517 vpksdss_3
= "100005ceVVV",
518 vsububs_3
= "10000600VVV",
519 mfvscr_1
= "10000604V--",
520 vsum4ubs_3
= "10000608VVV",
521 vsubuhs_3
= "10000640VVV",
522 mtvscr_1
= "10000644--V",
523 ["vcmpgtuh._3"] = "10000646VVV",
524 vsum4shs_3
= "10000648VVV",
525 vupkhsw_2
= "1000064eV-V",
526 vsubuws_3
= "10000680VVV",
527 vshasigmaw_4
= "10000682VVYp",
528 veqv_3
= "10000684VVV",
529 vsum2sws_3
= "10000688VVV",
530 vmrgow_3
= "1000068cVVV",
531 vshasigmad_4
= "100006c2VVYp",
532 vsrd_3
= "100006c4VVV",
533 ["vcmpgtud._3"] = "100006c7VVV",
534 vupklsw_2
= "100006ceV-V",
535 vupkslw_2
= "100006ceV-V",
536 vsubsbs_3
= "10000700VVV",
537 vclzb_2
= "10000702V-V",
538 vpopcntb_2
= "10000703V-V",
539 ["vcmpgtsb._3"] = "10000706VVV",
540 vsum4sbs_3
= "10000708VVV",
541 vsubshs_3
= "10000740VVV",
542 vclzh_2
= "10000742V-V",
543 vpopcnth_2
= "10000743V-V",
544 ["vcmpgtsh._3"] = "10000746VVV",
545 vsubsws_3
= "10000780VVV",
546 vclzw_2
= "10000782V-V",
547 vpopcntw_2
= "10000783V-V",
548 ["vcmpgtsw._3"] = "10000786VVV",
549 vsumsws_3
= "10000788VVV",
550 vmrgew_3
= "1000078cVVV",
551 vclzd_2
= "100007c2V-V",
552 vpopcntd_2
= "100007c3V-V",
553 ["vcmpbfp._3"] = "100007c6VVV",
554 ["vcmpgtsd._3"] = "100007c7VVV",
556 -- Primary opcode 19:
557 mcrf_2
= "4c000000XX",
558 isync_0
= "4c00012c",
559 crnor_3
= "4c000042CCC",
560 crnot_2
= "4c000042CC=",
561 crandc_3
= "4c000102CCC",
562 crxor_3
= "4c000182CCC",
563 crclr_1
= "4c000182C==",
564 crnand_3
= "4c0001c2CCC",
565 crand_3
= "4c000202CCC",
566 creqv_3
= "4c000242CCC",
567 crset_1
= "4c000242C==",
568 crorc_3
= "4c000342CCC",
569 cror_3
= "4c000382CCC",
570 crmove_2
= "4c000382CC=",
571 bclr_2
= "4c000020AA",
572 bclrl_2
= "4c000021AA",
573 bcctr_2
= "4c000420AA",
574 bcctrl_2
= "4c000421AA",
575 bctar_2
= "4c000460AA",
576 bctarl_2
= "4c000461AA",
580 bctrl_0
= "4e800421",
582 -- Primary opcode 31:
583 cmpw_3
= "7c000000XRR",
584 cmpw_2
= "7c000000-RR",
585 cmpd_3
= "7c200000XRR",
586 cmpd_2
= "7c200000-RR",
587 tw_3
= "7c000008ARR",
588 lvsl_3
= "7c00000cVRR",
589 subfc_3
= "7c000010RRR.",
590 subc_3
= "7c000010RRR~.",
591 mulhdu_3
= "7c000012RRR.",
592 addc_3
= "7c000014RRR.",
593 mulhwu_3
= "7c000016RRR.",
594 isel_4
= "7c00001eRRRC",
595 isellt_3
= "7c00001eRRR",
596 iselgt_3
= "7c00005eRRR",
597 iseleq_3
= "7c00009eRRR",
598 mfcr_1
= "7c000026R",
599 mfocrf_2
= "7c100026RG",
600 mtcrf_2
= "7c000120GR",
601 mtocrf_2
= "7c100120GR",
602 lwarx_3
= "7c000028RR0R",
603 ldx_3
= "7c00002aRR0R",
604 lwzx_3
= "7c00002eRR0R",
605 slw_3
= "7c000030RR~R.",
606 cntlzw_2
= "7c000034RR~",
607 sld_3
= "7c000036RR~R.",
608 and_3
= "7c000038RR~R.",
609 cmplw_3
= "7c000040XRR",
610 cmplw_2
= "7c000040-RR",
611 cmpld_3
= "7c200040XRR",
612 cmpld_2
= "7c200040-RR",
613 lvsr_3
= "7c00004cVRR",
614 subf_3
= "7c000050RRR.",
615 sub_3
= "7c000050RRR~.",
616 lbarx_3
= "7c000068RR0R",
617 ldux_3
= "7c00006aRR0R",
618 dcbst_2
= "7c00006c-RR",
619 lwzux_3
= "7c00006eRR0R",
620 cntlzd_2
= "7c000074RR~",
621 andc_3
= "7c000078RR~R.",
622 td_3
= "7c000088ARR",
623 lvewx_3
= "7c00008eVRR",
624 mulhd_3
= "7c000092RRR.",
625 addg6s_3
= "7c000094RRR",
626 mulhw_3
= "7c000096RRR.",
627 dlmzb_3
= "7c00009cRR~R.",
628 ldarx_3
= "7c0000a8RR0R",
629 dcbf_2
= "7c0000ac-RR",
630 lbzx_3
= "7c0000aeRR0R",
631 lvx_3
= "7c0000ceVRR",
632 neg_2
= "7c0000d0RR.",
633 lharx_3
= "7c0000e8RR0R",
634 lbzux_3
= "7c0000eeRR0R",
635 popcntb_2
= "7c0000f4RR~",
636 not_2
= "7c0000f8RR~%.",
637 nor_3
= "7c0000f8RR~R.",
638 stvebx_3
= "7c00010eVRR",
639 subfe_3
= "7c000110RRR.",
640 sube_3
= "7c000110RRR~.",
641 adde_3
= "7c000114RRR.",
642 stdx_3
= "7c00012aRR0R",
643 ["stwcx._3"] = "7c00012dRR0R.",
644 stwx_3
= "7c00012eRR0R",
645 prtyw_2
= "7c000134RR~",
646 stvehx_3
= "7c00014eVRR",
647 stdux_3
= "7c00016aRR0R",
648 ["stqcx._3"] = "7c00016dR:R0R.",
649 stwux_3
= "7c00016eRR0R",
650 prtyd_2
= "7c000174RR~",
651 stvewx_3
= "7c00018eVRR",
652 subfze_2
= "7c000190RR.",
653 addze_2
= "7c000194RR.",
654 ["stdcx._3"] = "7c0001adRR0R.",
655 stbx_3
= "7c0001aeRR0R",
656 stvx_3
= "7c0001ceVRR",
657 subfme_2
= "7c0001d0RR.",
658 mulld_3
= "7c0001d2RRR.",
659 addme_2
= "7c0001d4RR.",
660 mullw_3
= "7c0001d6RRR.",
661 dcbtst_2
= "7c0001ec-RR",
662 stbux_3
= "7c0001eeRR0R",
663 bpermd_3
= "7c0001f8RR~R",
664 lvepxl_3
= "7c00020eVRR",
665 add_3
= "7c000214RRR.",
666 lqarx_3
= "7c000228R:R0R",
667 dcbt_2
= "7c00022c-RR",
668 lhzx_3
= "7c00022eRR0R",
669 cdtbcd_2
= "7c000234RR~",
670 eqv_3
= "7c000238RR~R.",
671 lvepx_3
= "7c00024eVRR",
672 eciwx_3
= "7c00026cRR0R",
673 lhzux_3
= "7c00026eRR0R",
674 cbcdtd_2
= "7c000274RR~",
675 xor_3
= "7c000278RR~R.",
676 mfspefscr_1
= "7c0082a6R",
677 mfxer_1
= "7c0102a6R",
678 mflr_1
= "7c0802a6R",
679 mfctr_1
= "7c0902a6R",
680 lwax_3
= "7c0002aaRR0R",
681 lhax_3
= "7c0002aeRR0R",
682 mftb_1
= "7c0c42e6R",
683 mftbu_1
= "7c0d42e6R",
684 lvxl_3
= "7c0002ceVRR",
685 lwaux_3
= "7c0002eaRR0R",
686 lhaux_3
= "7c0002eeRR0R",
687 popcntw_2
= "7c0002f4RR~",
688 divdeu_3
= "7c000312RRR.",
689 divweu_3
= "7c000316RRR.",
690 sthx_3
= "7c00032eRR0R",
691 orc_3
= "7c000338RR~R.",
692 ecowx_3
= "7c00036cRR0R",
693 sthux_3
= "7c00036eRR0R",
694 or_3
= "7c000378RR~R.",
695 mr_2
= "7c000378RR~%.",
696 divdu_3
= "7c000392RRR.",
697 divwu_3
= "7c000396RRR.",
698 mtspefscr_1
= "7c0083a6R",
699 mtxer_1
= "7c0103a6R",
700 mtlr_1
= "7c0803a6R",
701 mtctr_1
= "7c0903a6R",
702 dcbi_2
= "7c0003ac-RR",
703 nand_3
= "7c0003b8RR~R.",
704 dsn_2
= "7c0003c6-RR",
705 stvxl_3
= "7c0003ceVRR",
706 divd_3
= "7c0003d2RRR.",
707 divw_3
= "7c0003d6RRR.",
708 popcntd_2
= "7c0003f4RR~",
709 cmpb_3
= "7c0003f8RR~R.",
710 mcrxr_1
= "7c000400X",
711 lbdx_3
= "7c000406RRR",
712 subfco_3
= "7c000410RRR.",
713 subco_3
= "7c000410RRR~.",
714 addco_3
= "7c000414RRR.",
715 ldbrx_3
= "7c000428RR0R",
716 lswx_3
= "7c00042aRR0R",
717 lwbrx_3
= "7c00042cRR0R",
718 lfsx_3
= "7c00042eFR0R",
719 srw_3
= "7c000430RR~R.",
720 srd_3
= "7c000436RR~R.",
721 lhdx_3
= "7c000446RRR",
722 subfo_3
= "7c000450RRR.",
723 subo_3
= "7c000450RRR~.",
724 lfsux_3
= "7c00046eFR0R",
725 lwdx_3
= "7c000486RRR",
726 lswi_3
= "7c0004aaRR0A",
728 lwsync_0
= "7c2004ac",
729 ptesync_0
= "7c4004ac",
730 lfdx_3
= "7c0004aeFR0R",
731 lddx_3
= "7c0004c6RRR",
732 nego_2
= "7c0004d0RR.",
733 lfdux_3
= "7c0004eeFR0R",
734 stbdx_3
= "7c000506RRR",
735 subfeo_3
= "7c000510RRR.",
736 subeo_3
= "7c000510RRR~.",
737 addeo_3
= "7c000514RRR.",
738 stdbrx_3
= "7c000528RR0R",
739 stswx_3
= "7c00052aRR0R",
740 stwbrx_3
= "7c00052cRR0R",
741 stfsx_3
= "7c00052eFR0R",
742 sthdx_3
= "7c000546RRR",
743 ["stbcx._3"] = "7c00056dRRR",
744 stfsux_3
= "7c00056eFR0R",
745 stwdx_3
= "7c000586RRR",
746 subfzeo_2
= "7c000590RR.",
747 addzeo_2
= "7c000594RR.",
748 stswi_3
= "7c0005aaRR0A",
749 ["sthcx._3"] = "7c0005adRRR",
750 stfdx_3
= "7c0005aeFR0R",
751 stddx_3
= "7c0005c6RRR",
752 subfmeo_2
= "7c0005d0RR.",
753 mulldo_3
= "7c0005d2RRR.",
754 addmeo_2
= "7c0005d4RR.",
755 mullwo_3
= "7c0005d6RRR.",
756 dcba_2
= "7c0005ec-RR",
757 stfdux_3
= "7c0005eeFR0R",
758 stvepxl_3
= "7c00060eVRR",
759 addo_3
= "7c000614RRR.",
760 lhbrx_3
= "7c00062cRR0R",
761 lfdpx_3
= "7c00062eF:RR",
762 sraw_3
= "7c000630RR~R.",
763 srad_3
= "7c000634RR~R.",
764 lfddx_3
= "7c000646FRR",
765 stvepx_3
= "7c00064eVRR",
766 srawi_3
= "7c000670RR~A.",
767 sradi_3
= "7c000674RR~H.",
768 eieio_0
= "7c0006ac",
769 lfiwax_3
= "7c0006aeFR0R",
770 divdeuo_3
= "7c000712RRR.",
771 divweuo_3
= "7c000716RRR.",
772 sthbrx_3
= "7c00072cRR0R",
773 stfdpx_3
= "7c00072eF:RR",
774 extsh_2
= "7c000734RR~.",
775 stfddx_3
= "7c000746FRR",
776 divdeo_3
= "7c000752RRR.",
777 divweo_3
= "7c000756RRR.",
778 extsb_2
= "7c000774RR~.",
779 divduo_3
= "7c000792RRR.",
780 divwou_3
= "7c000796RRR.",
781 icbi_2
= "7c0007ac-RR",
782 stfiwx_3
= "7c0007aeFR0R",
783 extsw_2
= "7c0007b4RR~.",
784 divdo_3
= "7c0007d2RRR.",
785 divwo_3
= "7c0007d6RRR.",
786 dcbz_2
= "7c0007ec-RR",
788 ["tbegin._1"] = "7c00051d1",
789 ["tbegin._0"] = "7c00051d",
790 ["tend._1"] = "7c00055dY",
791 ["tend._0"] = "7c00055d",
792 ["tendall._0"] = "7e00055d",
793 tcheck_1
= "7c00059cX",
794 ["tsr._1"] = "7c0005dd1",
795 ["tsuspend._0"] = "7c0005dd",
796 ["tresume._0"] = "7c2005dd",
797 ["tabortwc._3"] = "7c00061dARR",
798 ["tabortdc._3"] = "7c00065dARR",
799 ["tabortwci._3"] = "7c00069dARS",
800 ["tabortdci._3"] = "7c0006ddARS",
801 ["tabort._1"] = "7c00071d-R-",
802 ["treclaim._1"] = "7c00075d-R",
803 ["trechkpt._0"] = "7c0007dd",
805 lxsiwzx_3
= "7c000018QRR",
806 lxsiwax_3
= "7c000098QRR",
807 mfvsrd_2
= "7c000066-Rq",
808 mfvsrwz_2
= "7c0000e6-Rq",
809 stxsiwx_3
= "7c000118QRR",
810 mtvsrd_2
= "7c000166QR",
811 mtvsrwa_2
= "7c0001a6QR",
812 lxvdsx_3
= "7c000298QRR",
813 lxsspx_3
= "7c000418QRR",
814 lxsdx_3
= "7c000498QRR",
815 stxsspx_3
= "7c000518QRR",
816 stxsdx_3
= "7c000598QRR",
817 lxvw4x_3
= "7c000618QRR",
818 lxvd2x_3
= "7c000698QRR",
819 stxvw4x_3
= "7c000718QRR",
820 stxvd2x_3
= "7c000798QRR",
822 -- Primary opcode 30:
823 rldicl_4
= "78000000RR~HM.",
824 rldicr_4
= "78000004RR~HM.",
825 rldic_4
= "78000008RR~HM.",
826 rldimi_4
= "7800000cRR~HM.",
827 rldcl_4
= "78000010RR~RM.",
828 rldcr_4
= "78000012RR~RM.",
830 rotldi_3
= op_alias("rldicl_4", function(p
)
833 rotrdi_3
= op_alias("rldicl_4", function(p
)
834 p
[3] = "64-("..p
[3]..")"; p
[4] = "0"
836 rotld_3
= op_alias("rldcl_4", function(p
)
839 sldi_3
= op_alias("rldicr_4", function(p
)
840 p
[4] = "63-("..p
[3]..")"
842 srdi_3
= op_alias("rldicl_4", function(p
)
843 p
[4] = p
[3]; p
[3] = "64-("..p
[3]..")"
845 clrldi_3
= op_alias("rldicl_4", function(p
)
846 p
[4] = p
[3]; p
[3] = "0"
848 clrrdi_3
= op_alias("rldicr_4", function(p
)
849 p
[4] = "63-("..p
[3]..")"; p
[3] = "0"
852 -- Primary opcode 56:
853 lq_2
= "e0000000R:D", -- NYI: displacement must be divisible by 8.
855 -- Primary opcode 57:
856 lfdp_2
= "e4000000F:D", -- NYI: displacement must be divisible by 4.
858 -- Primary opcode 59:
859 fdivs_3
= "ec000024FFF.",
860 fsubs_3
= "ec000028FFF.",
861 fadds_3
= "ec00002aFFF.",
862 fsqrts_2
= "ec00002cF-F.",
863 fres_2
= "ec000030F-F.",
864 fmuls_3
= "ec000032FF-F.",
865 frsqrtes_2
= "ec000034F-F.",
866 fmsubs_4
= "ec000038FFFF~.",
867 fmadds_4
= "ec00003aFFFF~.",
868 fnmsubs_4
= "ec00003cFFFF~.",
869 fnmadds_4
= "ec00003eFFFF~.",
870 fcfids_2
= "ec00069cF-F.",
871 fcfidus_2
= "ec00079cF-F.",
873 dadd_3
= "ec000004FFF.",
874 dqua_4
= "ec000006FFFZ.",
875 dmul_3
= "ec000044FFF.",
876 drrnd_4
= "ec000046FFFZ.",
877 dscli_3
= "ec000084FF6.",
878 dquai_4
= "ec000086SF~FZ.",
879 dscri_3
= "ec0000c4FF6.",
880 drintx_4
= "ec0000c61F~FZ.",
881 dcmpo_3
= "ec000104XFF",
882 dtstex_3
= "ec000144XFF",
883 dtstdc_3
= "ec000184XF6",
884 dtstdg_3
= "ec0001c4XF6",
885 drintn_4
= "ec0001c61F~FZ.",
886 dctdp_2
= "ec000204F-F.",
887 dctfix_2
= "ec000244F-F.",
888 ddedpd_3
= "ec000284ZF~F.",
889 dxex_2
= "ec0002c4F-F.",
890 dsub_3
= "ec000404FFF.",
891 ddiv_3
= "ec000444FFF.",
892 dcmpu_3
= "ec000504XFF",
893 dtstsf_3
= "ec000544XFF",
894 drsp_2
= "ec000604F-F.",
895 dcffix_2
= "ec000644F-F.",
896 denbcd_3
= "ec000684YF~F.",
897 diex_3
= "ec0006c4FFF.",
899 -- Primary opcode 60:
900 xsaddsp_3
= "f0000000QQQ",
901 xsmaddasp_3
= "f0000008QQQ",
902 xxsldwi_4
= "f0000010QQQz",
903 xsrsqrtesp_2
= "f0000028Q-Q",
904 xssqrtsp_2
= "f000002cQ-Q",
905 xxsel_4
= "f0000030QQQQ",
906 xssubsp_3
= "f0000040QQQ",
907 xsmaddmsp_3
= "f0000048QQQ",
908 xxpermdi_4
= "f0000050QQQz",
909 xsresp_2
= "f0000068Q-Q",
910 xsmulsp_3
= "f0000080QQQ",
911 xsmsubasp_3
= "f0000088QQQ",
912 xxmrghw_3
= "f0000090QQQ",
913 xsdivsp_3
= "f00000c0QQQ",
914 xsmsubmsp_3
= "f00000c8QQQ",
915 xsadddp_3
= "f0000100QQQ",
916 xsmaddadp_3
= "f0000108QQQ",
917 xscmpudp_3
= "f0000118XQQ",
918 xscvdpuxws_2
= "f0000120Q-Q",
919 xsrdpi_2
= "f0000124Q-Q",
920 xsrsqrtedp_2
= "f0000128Q-Q",
921 xssqrtdp_2
= "f000012cQ-Q",
922 xssubdp_3
= "f0000140QQQ",
923 xsmaddmdp_3
= "f0000148QQQ",
924 xscmpodp_3
= "f0000158XQQ",
925 xscvdpsxws_2
= "f0000160Q-Q",
926 xsrdpiz_2
= "f0000164Q-Q",
927 xsredp_2
= "f0000168Q-Q",
928 xsmuldp_3
= "f0000180QQQ",
929 xsmsubadp_3
= "f0000188QQQ",
930 xxmrglw_3
= "f0000190QQQ",
931 xsrdpip_2
= "f00001a4Q-Q",
932 xstsqrtdp_2
= "f00001a8X-Q",
933 xsrdpic_2
= "f00001acQ-Q",
934 xsdivdp_3
= "f00001c0QQQ",
935 xsmsubmdp_3
= "f00001c8QQQ",
936 xsrdpim_2
= "f00001e4Q-Q",
937 xstdivdp_3
= "f00001e8XQQ",
938 xvaddsp_3
= "f0000200QQQ",
939 xvmaddasp_3
= "f0000208QQQ",
940 xvcmpeqsp_3
= "f0000218QQQ",
941 xvcvspuxws_2
= "f0000220Q-Q",
942 xvrspi_2
= "f0000224Q-Q",
943 xvrsqrtesp_2
= "f0000228Q-Q",
944 xvsqrtsp_2
= "f000022cQ-Q",
945 xvsubsp_3
= "f0000240QQQ",
946 xvmaddmsp_3
= "f0000248QQQ",
947 xvcmpgtsp_3
= "f0000258QQQ",
948 xvcvspsxws_2
= "f0000260Q-Q",
949 xvrspiz_2
= "f0000264Q-Q",
950 xvresp_2
= "f0000268Q-Q",
951 xvmulsp_3
= "f0000280QQQ",
952 xvmsubasp_3
= "f0000288QQQ",
953 xxspltw_3
= "f0000290QQg~",
954 xvcmpgesp_3
= "f0000298QQQ",
955 xvcvuxwsp_2
= "f00002a0Q-Q",
956 xvrspip_2
= "f00002a4Q-Q",
957 xvtsqrtsp_2
= "f00002a8X-Q",
958 xvrspic_2
= "f00002acQ-Q",
959 xvdivsp_3
= "f00002c0QQQ",
960 xvmsubmsp_3
= "f00002c8QQQ",
961 xvcvsxwsp_2
= "f00002e0Q-Q",
962 xvrspim_2
= "f00002e4Q-Q",
963 xvtdivsp_3
= "f00002e8XQQ",
964 xvadddp_3
= "f0000300QQQ",
965 xvmaddadp_3
= "f0000308QQQ",
966 xvcmpeqdp_3
= "f0000318QQQ",
967 xvcvdpuxws_2
= "f0000320Q-Q",
968 xvrdpi_2
= "f0000324Q-Q",
969 xvrsqrtedp_2
= "f0000328Q-Q",
970 xvsqrtdp_2
= "f000032cQ-Q",
971 xvsubdp_3
= "f0000340QQQ",
972 xvmaddmdp_3
= "f0000348QQQ",
973 xvcmpgtdp_3
= "f0000358QQQ",
974 xvcvdpsxws_2
= "f0000360Q-Q",
975 xvrdpiz_2
= "f0000364Q-Q",
976 xvredp_2
= "f0000368Q-Q",
977 xvmuldp_3
= "f0000380QQQ",
978 xvmsubadp_3
= "f0000388QQQ",
979 xvcmpgedp_3
= "f0000398QQQ",
980 xvcvuxwdp_2
= "f00003a0Q-Q",
981 xvrdpip_2
= "f00003a4Q-Q",
982 xvtsqrtdp_2
= "f00003a8X-Q",
983 xvrdpic_2
= "f00003acQ-Q",
984 xvdivdp_3
= "f00003c0QQQ",
985 xvmsubmdp_3
= "f00003c8QQQ",
986 xvcvsxwdp_2
= "f00003e0Q-Q",
987 xvrdpim_2
= "f00003e4Q-Q",
988 xvtdivdp_3
= "f00003e8XQQ",
989 xsnmaddasp_3
= "f0000408QQQ",
990 xxland_3
= "f0000410QQQ",
991 xscvdpsp_2
= "f0000424Q-Q",
992 xscvdpspn_2
= "f000042cQ-Q",
993 xsnmaddmsp_3
= "f0000448QQQ",
994 xxlandc_3
= "f0000450QQQ",
995 xsrsp_2
= "f0000464Q-Q",
996 xsnmsubasp_3
= "f0000488QQQ",
997 xxlor_3
= "f0000490QQQ",
998 xscvuxdsp_2
= "f00004a0Q-Q",
999 xsnmsubmsp_3
= "f00004c8QQQ",
1000 xxlxor_3
= "f00004d0QQQ",
1001 xscvsxdsp_2
= "f00004e0Q-Q",
1002 xsmaxdp_3
= "f0000500QQQ",
1003 xsnmaddadp_3
= "f0000508QQQ",
1004 xxlnor_3
= "f0000510QQQ",
1005 xscvdpuxds_2
= "f0000520Q-Q",
1006 xscvspdp_2
= "f0000524Q-Q",
1007 xscvspdpn_2
= "f000052cQ-Q",
1008 xsmindp_3
= "f0000540QQQ",
1009 xsnmaddmdp_3
= "f0000548QQQ",
1010 xxlorc_3
= "f0000550QQQ",
1011 xscvdpsxds_2
= "f0000560Q-Q",
1012 xsabsdp_2
= "f0000564Q-Q",
1013 xscpsgndp_3
= "f0000580QQQ",
1014 xsnmsubadp_3
= "f0000588QQQ",
1015 xxlnand_3
= "f0000590QQQ",
1016 xscvuxddp_2
= "f00005a0Q-Q",
1017 xsnabsdp_2
= "f00005a4Q-Q",
1018 xsnmsubmdp_3
= "f00005c8QQQ",
1019 xxleqv_3
= "f00005d0QQQ",
1020 xscvsxddp_2
= "f00005e0Q-Q",
1021 xsnegdp_2
= "f00005e4Q-Q",
1022 xvmaxsp_3
= "f0000600QQQ",
1023 xvnmaddasp_3
= "f0000608QQQ",
1024 ["xvcmpeqsp._3"] = "f0000618QQQ",
1025 xvcvspuxds_2
= "f0000620Q-Q",
1026 xvcvdpsp_2
= "f0000624Q-Q",
1027 xvminsp_3
= "f0000640QQQ",
1028 xvnmaddmsp_3
= "f0000648QQQ",
1029 ["xvcmpgtsp._3"] = "f0000658QQQ",
1030 xvcvspsxds_2
= "f0000660Q-Q",
1031 xvabssp_2
= "f0000664Q-Q",
1032 xvcpsgnsp_3
= "f0000680QQQ",
1033 xvnmsubasp_3
= "f0000688QQQ",
1034 ["xvcmpgesp._3"] = "f0000698QQQ",
1035 xvcvuxdsp_2
= "f00006a0Q-Q",
1036 xvnabssp_2
= "f00006a4Q-Q",
1037 xvnmsubmsp_3
= "f00006c8QQQ",
1038 xvcvsxdsp_2
= "f00006e0Q-Q",
1039 xvnegsp_2
= "f00006e4Q-Q",
1040 xvmaxdp_3
= "f0000700QQQ",
1041 xvnmaddadp_3
= "f0000708QQQ",
1042 ["xvcmpeqdp._3"] = "f0000718QQQ",
1043 xvcvdpuxds_2
= "f0000720Q-Q",
1044 xvcvspdp_2
= "f0000724Q-Q",
1045 xvmindp_3
= "f0000740QQQ",
1046 xvnmaddmdp_3
= "f0000748QQQ",
1047 ["xvcmpgtdp._3"] = "f0000758QQQ",
1048 xvcvdpsxds_2
= "f0000760Q-Q",
1049 xvabsdp_2
= "f0000764Q-Q",
1050 xvcpsgndp_3
= "f0000780QQQ",
1051 xvnmsubadp_3
= "f0000788QQQ",
1052 ["xvcmpgedp._3"] = "f0000798QQQ",
1053 xvcvuxddp_2
= "f00007a0Q-Q",
1054 xvnabsdp_2
= "f00007a4Q-Q",
1055 xvnmsubmdp_3
= "f00007c8QQQ",
1056 xvcvsxddp_2
= "f00007e0Q-Q",
1057 xvnegdp_2
= "f00007e4Q-Q",
1059 -- Primary opcode 61:
1060 stfdp_2
= "f4000000F:D", -- NYI: displacement must be divisible by 4.
1062 -- Primary opcode 62:
1063 stq_2
= "f8000002R:D", -- NYI: displacement must be divisible by 8.
1065 -- Primary opcode 63:
1066 fdiv_3
= "fc000024FFF.",
1067 fsub_3
= "fc000028FFF.",
1068 fadd_3
= "fc00002aFFF.",
1069 fsqrt_2
= "fc00002cF-F.",
1070 fsel_4
= "fc00002eFFFF~.",
1071 fre_2
= "fc000030F-F.",
1072 fmul_3
= "fc000032FF-F.",
1073 frsqrte_2
= "fc000034F-F.",
1074 fmsub_4
= "fc000038FFFF~.",
1075 fmadd_4
= "fc00003aFFFF~.",
1076 fnmsub_4
= "fc00003cFFFF~.",
1077 fnmadd_4
= "fc00003eFFFF~.",
1078 fcmpu_3
= "fc000000XFF",
1079 fcpsgn_3
= "fc000010FFF.",
1080 fcmpo_3
= "fc000040XFF",
1081 mtfsb1_1
= "fc00004cA",
1082 fneg_2
= "fc000050F-F.",
1083 mcrfs_2
= "fc000080XX",
1084 mtfsb0_1
= "fc00008cA",
1085 fmr_2
= "fc000090F-F.",
1086 frsp_2
= "fc000018F-F.",
1087 fctiw_2
= "fc00001cF-F.",
1088 fctiwz_2
= "fc00001eF-F.",
1089 ftdiv_2
= "fc000100X-F.",
1090 fctiwu_2
= "fc00011cF-F.",
1091 fctiwuz_2
= "fc00011eF-F.",
1092 mtfsfi_2
= "fc00010cAA", -- NYI: upshift.
1093 fnabs_2
= "fc000110F-F.",
1094 ftsqrt_2
= "fc000140X-F.",
1095 fabs_2
= "fc000210F-F.",
1096 frin_2
= "fc000310F-F.",
1097 friz_2
= "fc000350F-F.",
1098 frip_2
= "fc000390F-F.",
1099 frim_2
= "fc0003d0F-F.",
1100 mffs_1
= "fc00048eF.",
1101 -- NYI: mtfsf, mtfsb0, mtfsb1.
1102 fctid_2
= "fc00065cF-F.",
1103 fctidz_2
= "fc00065eF-F.",
1104 fmrgow_3
= "fc00068cFFF",
1105 fcfid_2
= "fc00069cF-F.",
1106 fctidu_2
= "fc00075cF-F.",
1107 fctiduz_2
= "fc00075eF-F.",
1108 fmrgew_3
= "fc00078cFFF",
1109 fcfidu_2
= "fc00079cF-F.",
1111 daddq_3
= "fc000004F:F:F:.",
1112 dquaq_4
= "fc000006F:F:F:Z.",
1113 dmulq_3
= "fc000044F:F:F:.",
1114 drrndq_4
= "fc000046F:F:F:Z.",
1115 dscliq_3
= "fc000084F:F:6.",
1116 dquaiq_4
= "fc000086SF:~F:Z.",
1117 dscriq_3
= "fc0000c4F:F:6.",
1118 drintxq_4
= "fc0000c61F:~F:Z.",
1119 dcmpoq_3
= "fc000104XF:F:",
1120 dtstexq_3
= "fc000144XF:F:",
1121 dtstdcq_3
= "fc000184XF:6",
1122 dtstdgq_3
= "fc0001c4XF:6",
1123 drintnq_4
= "fc0001c61F:~F:Z.",
1124 dctqpq_2
= "fc000204F:-F:.",
1125 dctfixq_2
= "fc000244F:-F:.",
1126 ddedpdq_3
= "fc000284ZF:~F:.",
1127 dxexq_2
= "fc0002c4F:-F:.",
1128 dsubq_3
= "fc000404F:F:F:.",
1129 ddivq_3
= "fc000444F:F:F:.",
1130 dcmpuq_3
= "fc000504XF:F:",
1131 dtstsfq_3
= "fc000544XF:F:",
1132 drdpq_2
= "fc000604F:-F:.",
1133 dcffixq_2
= "fc000644F:-F:.",
1134 denbcdq_3
= "fc000684YF:~F:.",
1135 diexq_3
= "fc0006c4F:FF:.",
1137 -- Primary opcode 4, SPE APU extension:
1138 evaddw_3
= "10000200RRR",
1139 evaddiw_3
= "10000202RAR~",
1140 evsubw_3
= "10000204RRR~",
1141 evsubiw_3
= "10000206RAR~",
1142 evabs_2
= "10000208RR",
1143 evneg_2
= "10000209RR",
1144 evextsb_2
= "1000020aRR",
1145 evextsh_2
= "1000020bRR",
1146 evrndw_2
= "1000020cRR",
1147 evcntlzw_2
= "1000020dRR",
1148 evcntlsw_2
= "1000020eRR",
1149 brinc_3
= "1000020fRRR",
1150 evand_3
= "10000211RRR",
1151 evandc_3
= "10000212RRR",
1152 evxor_3
= "10000216RRR",
1153 evor_3
= "10000217RRR",
1154 evmr_2
= "10000217RR=",
1155 evnor_3
= "10000218RRR",
1156 evnot_2
= "10000218RR=",
1157 eveqv_3
= "10000219RRR",
1158 evorc_3
= "1000021bRRR",
1159 evnand_3
= "1000021eRRR",
1160 evsrwu_3
= "10000220RRR",
1161 evsrws_3
= "10000221RRR",
1162 evsrwiu_3
= "10000222RRA",
1163 evsrwis_3
= "10000223RRA",
1164 evslw_3
= "10000224RRR",
1165 evslwi_3
= "10000226RRA",
1166 evrlw_3
= "10000228RRR",
1167 evsplati_2
= "10000229RS",
1168 evrlwi_3
= "1000022aRRA",
1169 evsplatfi_2
= "1000022bRS",
1170 evmergehi_3
= "1000022cRRR",
1171 evmergelo_3
= "1000022dRRR",
1172 evcmpgtu_3
= "10000230XRR",
1173 evcmpgtu_2
= "10000230-RR",
1174 evcmpgts_3
= "10000231XRR",
1175 evcmpgts_2
= "10000231-RR",
1176 evcmpltu_3
= "10000232XRR",
1177 evcmpltu_2
= "10000232-RR",
1178 evcmplts_3
= "10000233XRR",
1179 evcmplts_2
= "10000233-RR",
1180 evcmpeq_3
= "10000234XRR",
1181 evcmpeq_2
= "10000234-RR",
1182 evsel_4
= "10000278RRRW",
1183 evsel_3
= "10000278RRR",
1184 evfsadd_3
= "10000280RRR",
1185 evfssub_3
= "10000281RRR",
1186 evfsabs_2
= "10000284RR",
1187 evfsnabs_2
= "10000285RR",
1188 evfsneg_2
= "10000286RR",
1189 evfsmul_3
= "10000288RRR",
1190 evfsdiv_3
= "10000289RRR",
1191 evfscmpgt_3
= "1000028cXRR",
1192 evfscmpgt_2
= "1000028c-RR",
1193 evfscmplt_3
= "1000028dXRR",
1194 evfscmplt_2
= "1000028d-RR",
1195 evfscmpeq_3
= "1000028eXRR",
1196 evfscmpeq_2
= "1000028e-RR",
1197 evfscfui_2
= "10000290R-R",
1198 evfscfsi_2
= "10000291R-R",
1199 evfscfuf_2
= "10000292R-R",
1200 evfscfsf_2
= "10000293R-R",
1201 evfsctui_2
= "10000294R-R",
1202 evfsctsi_2
= "10000295R-R",
1203 evfsctuf_2
= "10000296R-R",
1204 evfsctsf_2
= "10000297R-R",
1205 evfsctuiz_2
= "10000298R-R",
1206 evfsctsiz_2
= "1000029aR-R",
1207 evfststgt_3
= "1000029cXRR",
1208 evfststgt_2
= "1000029c-RR",
1209 evfststlt_3
= "1000029dXRR",
1210 evfststlt_2
= "1000029d-RR",
1211 evfststeq_3
= "1000029eXRR",
1212 evfststeq_2
= "1000029e-RR",
1213 efsadd_3
= "100002c0RRR",
1214 efssub_3
= "100002c1RRR",
1215 efsabs_2
= "100002c4RR",
1216 efsnabs_2
= "100002c5RR",
1217 efsneg_2
= "100002c6RR",
1218 efsmul_3
= "100002c8RRR",
1219 efsdiv_3
= "100002c9RRR",
1220 efscmpgt_3
= "100002ccXRR",
1221 efscmpgt_2
= "100002cc-RR",
1222 efscmplt_3
= "100002cdXRR",
1223 efscmplt_2
= "100002cd-RR",
1224 efscmpeq_3
= "100002ceXRR",
1225 efscmpeq_2
= "100002ce-RR",
1226 efscfd_2
= "100002cfR-R",
1227 efscfui_2
= "100002d0R-R",
1228 efscfsi_2
= "100002d1R-R",
1229 efscfuf_2
= "100002d2R-R",
1230 efscfsf_2
= "100002d3R-R",
1231 efsctui_2
= "100002d4R-R",
1232 efsctsi_2
= "100002d5R-R",
1233 efsctuf_2
= "100002d6R-R",
1234 efsctsf_2
= "100002d7R-R",
1235 efsctuiz_2
= "100002d8R-R",
1236 efsctsiz_2
= "100002daR-R",
1237 efststgt_3
= "100002dcXRR",
1238 efststgt_2
= "100002dc-RR",
1239 efststlt_3
= "100002ddXRR",
1240 efststlt_2
= "100002dd-RR",
1241 efststeq_3
= "100002deXRR",
1242 efststeq_2
= "100002de-RR",
1243 efdadd_3
= "100002e0RRR",
1244 efdsub_3
= "100002e1RRR",
1245 efdcfuid_2
= "100002e2R-R",
1246 efdcfsid_2
= "100002e3R-R",
1247 efdabs_2
= "100002e4RR",
1248 efdnabs_2
= "100002e5RR",
1249 efdneg_2
= "100002e6RR",
1250 efdmul_3
= "100002e8RRR",
1251 efddiv_3
= "100002e9RRR",
1252 efdctuidz_2
= "100002eaR-R",
1253 efdctsidz_2
= "100002ebR-R",
1254 efdcmpgt_3
= "100002ecXRR",
1255 efdcmpgt_2
= "100002ec-RR",
1256 efdcmplt_3
= "100002edXRR",
1257 efdcmplt_2
= "100002ed-RR",
1258 efdcmpeq_3
= "100002eeXRR",
1259 efdcmpeq_2
= "100002ee-RR",
1260 efdcfs_2
= "100002efR-R",
1261 efdcfui_2
= "100002f0R-R",
1262 efdcfsi_2
= "100002f1R-R",
1263 efdcfuf_2
= "100002f2R-R",
1264 efdcfsf_2
= "100002f3R-R",
1265 efdctui_2
= "100002f4R-R",
1266 efdctsi_2
= "100002f5R-R",
1267 efdctuf_2
= "100002f6R-R",
1268 efdctsf_2
= "100002f7R-R",
1269 efdctuiz_2
= "100002f8R-R",
1270 efdctsiz_2
= "100002faR-R",
1271 efdtstgt_3
= "100002fcXRR",
1272 efdtstgt_2
= "100002fc-RR",
1273 efdtstlt_3
= "100002fdXRR",
1274 efdtstlt_2
= "100002fd-RR",
1275 efdtsteq_3
= "100002feXRR",
1276 efdtsteq_2
= "100002fe-RR",
1277 evlddx_3
= "10000300RR0R",
1278 evldd_2
= "10000301R8",
1279 evldwx_3
= "10000302RR0R",
1280 evldw_2
= "10000303R8",
1281 evldhx_3
= "10000304RR0R",
1282 evldh_2
= "10000305R8",
1283 evlwhex_3
= "10000310RR0R",
1284 evlwhe_2
= "10000311R4",
1285 evlwhoux_3
= "10000314RR0R",
1286 evlwhou_2
= "10000315R4",
1287 evlwhosx_3
= "10000316RR0R",
1288 evlwhos_2
= "10000317R4",
1289 evstddx_3
= "10000320RR0R",
1290 evstdd_2
= "10000321R8",
1291 evstdwx_3
= "10000322RR0R",
1292 evstdw_2
= "10000323R8",
1293 evstdhx_3
= "10000324RR0R",
1294 evstdh_2
= "10000325R8",
1295 evstwhex_3
= "10000330RR0R",
1296 evstwhe_2
= "10000331R4",
1297 evstwhox_3
= "10000334RR0R",
1298 evstwho_2
= "10000335R4",
1299 evstwwex_3
= "10000338RR0R",
1300 evstwwe_2
= "10000339R4",
1301 evstwwox_3
= "1000033cRR0R",
1302 evstwwo_2
= "1000033dR4",
1303 evmhessf_3
= "10000403RRR",
1304 evmhossf_3
= "10000407RRR",
1305 evmheumi_3
= "10000408RRR",
1306 evmhesmi_3
= "10000409RRR",
1307 evmhesmf_3
= "1000040bRRR",
1308 evmhoumi_3
= "1000040cRRR",
1309 evmhosmi_3
= "1000040dRRR",
1310 evmhosmf_3
= "1000040fRRR",
1311 evmhessfa_3
= "10000423RRR",
1312 evmhossfa_3
= "10000427RRR",
1313 evmheumia_3
= "10000428RRR",
1314 evmhesmia_3
= "10000429RRR",
1315 evmhesmfa_3
= "1000042bRRR",
1316 evmhoumia_3
= "1000042cRRR",
1317 evmhosmia_3
= "1000042dRRR",
1318 evmhosmfa_3
= "1000042fRRR",
1319 evmwhssf_3
= "10000447RRR",
1320 evmwlumi_3
= "10000448RRR",
1321 evmwhumi_3
= "1000044cRRR",
1322 evmwhsmi_3
= "1000044dRRR",
1323 evmwhsmf_3
= "1000044fRRR",
1324 evmwssf_3
= "10000453RRR",
1325 evmwumi_3
= "10000458RRR",
1326 evmwsmi_3
= "10000459RRR",
1327 evmwsmf_3
= "1000045bRRR",
1328 evmwhssfa_3
= "10000467RRR",
1329 evmwlumia_3
= "10000468RRR",
1330 evmwhumia_3
= "1000046cRRR",
1331 evmwhsmia_3
= "1000046dRRR",
1332 evmwhsmfa_3
= "1000046fRRR",
1333 evmwssfa_3
= "10000473RRR",
1334 evmwumia_3
= "10000478RRR",
1335 evmwsmia_3
= "10000479RRR",
1336 evmwsmfa_3
= "1000047bRRR",
1337 evmra_2
= "100004c4RR",
1338 evdivws_3
= "100004c6RRR",
1339 evdivwu_3
= "100004c7RRR",
1340 evmwssfaa_3
= "10000553RRR",
1341 evmwumiaa_3
= "10000558RRR",
1342 evmwsmiaa_3
= "10000559RRR",
1343 evmwsmfaa_3
= "1000055bRRR",
1344 evmwssfan_3
= "100005d3RRR",
1345 evmwumian_3
= "100005d8RRR",
1346 evmwsmian_3
= "100005d9RRR",
1347 evmwsmfan_3
= "100005dbRRR",
1348 evmergehilo_3
= "1000022eRRR",
1349 evmergelohi_3
= "1000022fRRR",
1350 evlhhesplatx_3
= "10000308RR0R",
1351 evlhhesplat_2
= "10000309R2",
1352 evlhhousplatx_3
= "1000030cRR0R",
1353 evlhhousplat_2
= "1000030dR2",
1354 evlhhossplatx_3
= "1000030eRR0R",
1355 evlhhossplat_2
= "1000030fR2",
1356 evlwwsplatx_3
= "10000318RR0R",
1357 evlwwsplat_2
= "10000319R4",
1358 evlwhsplatx_3
= "1000031cRR0R",
1359 evlwhsplat_2
= "1000031dR4",
1360 evaddusiaaw_2
= "100004c0RR",
1361 evaddssiaaw_2
= "100004c1RR",
1362 evsubfusiaaw_2
= "100004c2RR",
1363 evsubfssiaaw_2
= "100004c3RR",
1364 evaddumiaaw_2
= "100004c8RR",
1365 evaddsmiaaw_2
= "100004c9RR",
1366 evsubfumiaaw_2
= "100004caRR",
1367 evsubfsmiaaw_2
= "100004cbRR",
1368 evmheusiaaw_3
= "10000500RRR",
1369 evmhessiaaw_3
= "10000501RRR",
1370 evmhessfaaw_3
= "10000503RRR",
1371 evmhousiaaw_3
= "10000504RRR",
1372 evmhossiaaw_3
= "10000505RRR",
1373 evmhossfaaw_3
= "10000507RRR",
1374 evmheumiaaw_3
= "10000508RRR",
1375 evmhesmiaaw_3
= "10000509RRR",
1376 evmhesmfaaw_3
= "1000050bRRR",
1377 evmhoumiaaw_3
= "1000050cRRR",
1378 evmhosmiaaw_3
= "1000050dRRR",
1379 evmhosmfaaw_3
= "1000050fRRR",
1380 evmhegumiaa_3
= "10000528RRR",
1381 evmhegsmiaa_3
= "10000529RRR",
1382 evmhegsmfaa_3
= "1000052bRRR",
1383 evmhogumiaa_3
= "1000052cRRR",
1384 evmhogsmiaa_3
= "1000052dRRR",
1385 evmhogsmfaa_3
= "1000052fRRR",
1386 evmwlusiaaw_3
= "10000540RRR",
1387 evmwlssiaaw_3
= "10000541RRR",
1388 evmwlumiaaw_3
= "10000548RRR",
1389 evmwlsmiaaw_3
= "10000549RRR",
1390 evmheusianw_3
= "10000580RRR",
1391 evmhessianw_3
= "10000581RRR",
1392 evmhessfanw_3
= "10000583RRR",
1393 evmhousianw_3
= "10000584RRR",
1394 evmhossianw_3
= "10000585RRR",
1395 evmhossfanw_3
= "10000587RRR",
1396 evmheumianw_3
= "10000588RRR",
1397 evmhesmianw_3
= "10000589RRR",
1398 evmhesmfanw_3
= "1000058bRRR",
1399 evmhoumianw_3
= "1000058cRRR",
1400 evmhosmianw_3
= "1000058dRRR",
1401 evmhosmfanw_3
= "1000058fRRR",
1402 evmhegumian_3
= "100005a8RRR",
1403 evmhegsmian_3
= "100005a9RRR",
1404 evmhegsmfan_3
= "100005abRRR",
1405 evmhogumian_3
= "100005acRRR",
1406 evmhogsmian_3
= "100005adRRR",
1407 evmhogsmfan_3
= "100005afRRR",
1408 evmwlusianw_3
= "100005c0RRR",
1409 evmwlssianw_3
= "100005c1RRR",
1410 evmwlumianw_3
= "100005c8RRR",
1411 evmwlsmianw_3
= "100005c9RRR",
1413 -- NYI: Book E instructions.
1416 -- Add mnemonics for "." variants.
1419 for k
,v
in pairs(map_op
) do
1420 if type(v
) == "string" and sub(v
, -1) == "." then
1421 local v2
= sub(v
, 1, 7)..char(byte(v
, 8)+1)..sub(v
, 9, -2)
1422 t
[sub(k
, 1, -3).."."..sub(k
, -2)] = v2
1425 for k
,v
in pairs(t
) do
1430 -- Add more branch mnemonics.
1431 for cond
,c
in pairs(map_cond
) do
1432 local b1
= "b"..cond
1433 local c1
= shl(band(c
, 3), 16) + (c
< 4 and 0x01000000 or 0)
1435 map_op
[b1
.."_1"] = tohex(0x40800000 + c1
).."K"
1436 map_op
[b1
.."y_1"] = tohex(0x40a00000 + c1
).."K"
1437 map_op
[b1
.."l_1"] = tohex(0x40800001 + c1
).."K"
1438 map_op
[b1
.."_2"] = tohex(0x40800000 + c1
).."-XK"
1439 map_op
[b1
.."y_2"] = tohex(0x40a00000 + c1
).."-XK"
1440 map_op
[b1
.."l_2"] = tohex(0x40800001 + c1
).."-XK"
1442 map_op
[b1
.."lr_0"] = tohex(0x4c800020 + c1
)
1443 map_op
[b1
.."lrl_0"] = tohex(0x4c800021 + c1
)
1444 map_op
[b1
.."ctr_0"] = tohex(0x4c800420 + c1
)
1445 map_op
[b1
.."ctrl_0"] = tohex(0x4c800421 + c1
)
1447 map_op
[b1
.."lr_1"] = tohex(0x4c800020 + c1
).."-X"
1448 map_op
[b1
.."lrl_1"] = tohex(0x4c800021 + c1
).."-X"
1449 map_op
[b1
.."ctr_1"] = tohex(0x4c800420 + c1
).."-X"
1450 map_op
[b1
.."ctrl_1"] = tohex(0x4c800421 + c1
).."-X"
1453 ------------------------------------------------------------------------------
1455 local function parse_gpr(expr
)
1456 local tname
, ovreg
= match(expr
, "^([%w_]+):(r[1-3]?[0-9])$")
1457 local tp
= map_type
[tname
or expr
]
1459 local reg
= ovreg
or tp
.reg
1461 werror("type `"..(tname
or expr
).."' needs a register override")
1465 local r
= match(expr
, "^r([1-3]?[0-9])$")
1468 if r
<= 31 then return r
, tp
end
1470 werror("bad register name `"..expr
.."'")
1473 local function parse_fpr(expr
)
1474 local r
= match(expr
, "^f([1-3]?[0-9])$")
1477 if r
<= 31 then return r
end
1479 werror("bad register name `"..expr
.."'")
1482 local function parse_vr(expr
)
1483 local r
= match(expr
, "^v([1-3]?[0-9])$")
1486 if r
<= 31 then return r
end
1488 werror("bad register name `"..expr
.."'")
1491 local function parse_vs(expr
)
1492 local r
= match(expr
, "^vs([1-6]?[0-9])$")
1495 if r
<= 63 then return r
end
1497 werror("bad register name `"..expr
.."'")
1500 local function parse_cr(expr
)
1501 local r
= match(expr
, "^cr([0-7])$")
1502 if r
then return tonumber(r
) end
1503 werror("bad condition register name `"..expr
.."'")
1506 local function parse_cond(expr
)
1507 local r
, cond
= match(expr
, "^4%*cr([0-7])%+(%w%w)$")
1510 local c
= map_cond
[cond
]
1511 if c
and c
< 4 then return r
*4+c
end
1513 werror("bad condition bit name `"..expr
.."'")
1516 local parse_ctx
= {}
1518 local loadenv
= setfenv
and function(s
)
1519 local code
= loadstring(s
, "")
1520 if code
then setfenv(code
, parse_ctx
) end
1523 return load(s
, "", nil, parse_ctx
)
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
)
1532 local ok
, y
= pcall(code
)
1533 if ok
then return y
end
1538 local function parse_imm(imm
, bits
, shift
, scale
, signed
)
1539 local n
= parse_number(imm
)
1541 local m
= sar(n
, scale
)
1542 if shl(m
, scale
) == n
then
1544 local s
= sar(m
, bits
-1)
1545 if s
== 0 then return shl(m
, shift
)
1546 elseif s
== -1 then return shl(m
+ shl(1, bits
), shift
) end
1548 if sar(m
, bits
) == 0 then return shl(m
, shift
) end
1551 werror("out of range immediate `"..imm
.."'")
1552 elseif match(imm
, "^[rfv]([1-3]?[0-9])$") or
1553 match(imm
, "^vs([1-6]?[0-9])$") or
1554 match(imm
, "^([%w_]+):(r[1-3]?[0-9])$") then
1555 werror("expected immediate operand, got register")
1557 waction("IMM", (signed
and 32768 or 0)+scale
*1024+bits
*32+shift
, imm
)
1562 local function parse_shiftmask(imm
, isshift
)
1563 local n
= parse_number(imm
)
1565 if shr(n
, 6) == 0 then
1566 local lsb
= band(n
, 31)
1568 return isshift
and (shl(lsb
, 11)+shr(msb
, 4)) or (shl(lsb
, 6)+msb
)
1570 werror("out of range immediate `"..imm
.."'")
1571 elseif match(imm
, "^r([1-3]?[0-9])$") or
1572 match(imm
, "^([%w_]+):(r[1-3]?[0-9])$") then
1573 werror("expected immediate operand, got register")
1575 waction("IMMSH", isshift
and 1 or 0, imm
)
1580 local function parse_disp(disp
)
1581 local imm
, reg
= match(disp
, "^(.*)%(([%w_:]+)%)$")
1583 local r
= parse_gpr(reg
)
1584 if r
== 0 then werror("cannot use r0 in displacement") end
1585 return shl(r
, 16) + parse_imm(imm
, 16, 0, 0, true)
1587 local reg
, tailr
= match(disp
, "^([%w_:]+)%s*(.*)$")
1588 if reg
and tailr
~= "" then
1589 local r
, tp
= parse_gpr(reg
)
1590 if r
== 0 then werror("cannot use r0 in displacement") end
1592 waction("IMM", 32768+16*32, format(tp
.ctypefmt
, tailr
))
1596 werror("bad displacement `"..disp
.."'")
1599 local function parse_u5disp(disp
, scale
)
1600 local imm
, reg
= match(disp
, "^(.*)%(([%w_:]+)%)$")
1602 local r
= parse_gpr(reg
)
1603 if r
== 0 then werror("cannot use r0 in displacement") end
1604 return shl(r
, 16) + parse_imm(imm
, 5, 11, scale
, false)
1606 local reg
, tailr
= match(disp
, "^([%w_:]+)%s*(.*)$")
1607 if reg
and tailr
~= "" then
1608 local r
, tp
= parse_gpr(reg
)
1609 if r
== 0 then werror("cannot use r0 in displacement") end
1611 waction("IMM", scale
*1024+5*32+11, format(tp
.ctypefmt
, tailr
))
1615 werror("bad displacement `"..disp
.."'")
1618 local function parse_label(label
, def
)
1619 local prefix
= sub(label
, 1, 2)
1620 -- =>label (pc label reference)
1621 if prefix
== "=>" then
1622 return "PC", 0, sub(label
, 3)
1624 -- ->name (global label reference)
1625 if prefix
== "->" then
1626 return "LG", map_global
[sub(label
, 3)]
1629 -- [1-9] (local label definition)
1630 if match(label
, "^[1-9]$") then
1631 return "LG", 10+tonumber(label
)
1634 -- [<>][1-9] (local label reference)
1635 local dir
, lnum
= match(label
, "^([<>])([1-9])$")
1636 if dir
then -- Fwd: 1-9, Bkwd: 11-19.
1637 return "LG", lnum
+ (dir
== ">" and 0 or 10)
1639 -- extern label (extern label reference)
1640 local extname
= match(label
, "^extern%s+(%S+)$")
1642 return "EXT", map_extern
[extname
]
1645 werror("bad label `"..label
.."'")
1648 ------------------------------------------------------------------------------
1650 -- Handle opcodes defined with template strings.
1651 op_template
= function(params
, template
, nparams
)
1652 if not params
then return sub(template
, 9) end
1653 local op
= tonumber(sub(template
, 1, 8), 16)
1656 -- Limit number of section buffer positions used by a single dasm_put().
1657 -- A single opcode needs a maximum of 3 positions (rlwinm).
1658 if secpos
+3 > maxsecpos
then wflush() end
1661 -- Process each character.
1662 for p
in gmatch(sub(template
, 9), ".") do
1664 rs
= rs
- 5; op
= op
+ shl(parse_gpr(params
[n
]), rs
); n
= n
+ 1
1665 elseif p
== "F" then
1666 rs
= rs
- 5; op
= op
+ shl(parse_fpr(params
[n
]), rs
); n
= n
+ 1
1667 elseif p
== "V" then
1668 rs
= rs
- 5; op
= op
+ shl(parse_vr(params
[n
]), rs
); n
= n
+ 1
1669 elseif p
== "Q" then
1670 local vs
= parse_vs(params
[n
]); n
= n
+ 1; rs
= rs
- 5
1671 local sh
= rs
== 6 and 2 or 3 + band(shr(rs
, 1), 3)
1672 op
= op
+ shl(band(vs
, 31), rs
) + shr(band(vs
, 32), sh
)
1673 elseif p
== "q" then
1674 local vs
= parse_vs(params
[n
]); n
= n
+ 1
1675 op
= op
+ shl(band(vs
, 31), 21) + shr(band(vs
, 32), 5)
1676 elseif p
== "A" then
1677 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 5, rs
, 0, false); n
= n
+ 1
1678 elseif p
== "S" then
1679 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 5, rs
, 0, true); n
= n
+ 1
1680 elseif p
== "I" then
1681 op
= op
+ parse_imm(params
[n
], 16, 0, 0, true); n
= n
+ 1
1682 elseif p
== "U" then
1683 op
= op
+ parse_imm(params
[n
], 16, 0, 0, false); n
= n
+ 1
1684 elseif p
== "D" then
1685 op
= op
+ parse_disp(params
[n
]); n
= n
+ 1
1686 elseif p
== "2" then
1687 op
= op
+ parse_u5disp(params
[n
], 1); n
= n
+ 1
1688 elseif p
== "4" then
1689 op
= op
+ parse_u5disp(params
[n
], 2); n
= n
+ 1
1690 elseif p
== "8" then
1691 op
= op
+ parse_u5disp(params
[n
], 3); n
= n
+ 1
1692 elseif p
== "C" then
1693 rs
= rs
- 5; op
= op
+ shl(parse_cond(params
[n
]), rs
); n
= n
+ 1
1694 elseif p
== "X" then
1695 rs
= rs
- 5; op
= op
+ shl(parse_cr(params
[n
]), rs
+2); n
= n
+ 1
1696 elseif p
== "1" then
1697 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 1, rs
, 0, false); n
= n
+ 1
1698 elseif p
== "g" then
1699 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 2, rs
, 0, false); n
= n
+ 1
1700 elseif p
== "3" then
1701 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 3, rs
, 0, false); n
= n
+ 1
1702 elseif p
== "P" then
1703 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 4, rs
, 0, false); n
= n
+ 1
1704 elseif p
== "p" then
1705 op
= op
+ parse_imm(params
[n
], 4, rs
, 0, false); n
= n
+ 1
1706 elseif p
== "6" then
1707 rs
= rs
- 6; op
= op
+ parse_imm(params
[n
], 6, rs
, 0, false); n
= n
+ 1
1708 elseif p
== "Y" then
1709 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 1, rs
+4, 0, false); n
= n
+ 1
1710 elseif p
== "y" then
1711 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 1, rs
+3, 0, false); n
= n
+ 1
1712 elseif p
== "Z" then
1713 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 2, rs
+3, 0, false); n
= n
+ 1
1714 elseif p
== "z" then
1715 rs
= rs
- 5; op
= op
+ parse_imm(params
[n
], 2, rs
+2, 0, false); n
= n
+ 1
1716 elseif p
== "W" then
1717 op
= op
+ parse_cr(params
[n
]); n
= n
+ 1
1718 elseif p
== "G" then
1719 op
= op
+ parse_imm(params
[n
], 8, 12, 0, false); n
= n
+ 1
1720 elseif p
== "H" then
1721 op
= op
+ parse_shiftmask(params
[n
], true); n
= n
+ 1
1722 elseif p
== "M" then
1723 op
= op
+ parse_shiftmask(params
[n
], false); n
= n
+ 1
1724 elseif p
== "J" or p
== "K" then
1725 local mode
, m
, s
= parse_label(params
[n
], false)
1726 if p
== "K" then m
= m
+ 2048 end
1727 waction("REL_"..mode
, m
, s
, 1)
1729 elseif p
== "0" then
1730 if band(shr(op
, rs
), 31) == 0 then werror("cannot use r0") end
1731 elseif p
== "=" or p
== "%" then
1732 local t
= band(shr(op
, p
== "%" and rs
+5 or rs
), 31)
1734 op
= op
+ shl(t
, rs
)
1735 elseif p
== "~" then
1736 local mm
= shl(31, rs
)
1737 local lo
= band(op
, mm
)
1738 local hi
= band(op
, shl(mm
, 5))
1739 op
= op
- lo
- hi
+ shl(lo
, 5) + shr(hi
, 5)
1740 elseif p
== ":" then
1741 if band(shr(op
, rs
), 1) ~= 0 then werror("register pair expected") end
1742 elseif p
== "-" then
1744 elseif p
== "." then
1753 map_op
[".template__"] = op_template
1755 ------------------------------------------------------------------------------
1757 -- Pseudo-opcode to mark the position where the action list is to be emitted.
1758 map_op
[".actionlist_1"] = function(params
)
1759 if not params
then return "cvar" end
1760 local name
= params
[1] -- No syntax check. You get to keep the pieces.
1761 wline(function(out
) writeactions(out
, name
) end)
1764 -- Pseudo-opcode to mark the position where the global enum is to be emitted.
1765 map_op
[".globals_1"] = function(params
)
1766 if not params
then return "prefix" end
1767 local prefix
= params
[1] -- No syntax check. You get to keep the pieces.
1768 wline(function(out
) writeglobals(out
, prefix
) end)
1771 -- Pseudo-opcode to mark the position where the global names are to be emitted.
1772 map_op
[".globalnames_1"] = function(params
)
1773 if not params
then return "cvar" end
1774 local name
= params
[1] -- No syntax check. You get to keep the pieces.
1775 wline(function(out
) writeglobalnames(out
, name
) end)
1778 -- Pseudo-opcode to mark the position where the extern names are to be emitted.
1779 map_op
[".externnames_1"] = function(params
)
1780 if not params
then return "cvar" end
1781 local name
= params
[1] -- No syntax check. You get to keep the pieces.
1782 wline(function(out
) writeexternnames(out
, name
) end)
1785 ------------------------------------------------------------------------------
1787 -- Label pseudo-opcode (converted from trailing colon form).
1788 map_op
[".label_1"] = function(params
)
1789 if not params
then return "[1-9] | ->global | =>pcexpr" end
1790 if secpos
+1 > maxsecpos
then wflush() end
1791 local mode
, n
, s
= parse_label(params
[1], true)
1792 if mode
== "EXT" then werror("bad label definition") end
1793 waction("LABEL_"..mode
, n
, s
, 1)
1796 ------------------------------------------------------------------------------
1798 -- Pseudo-opcodes for data storage.
1799 map_op
[".long_*"] = function(params
)
1800 if not params
then return "imm..." end
1801 for _
,p
in ipairs(params
) do
1802 local n
= tonumber(p
)
1803 if not n
then werror("bad immediate `"..p
.."'") end
1804 if n
< 0 then n
= n
+ 2^
32 end
1806 if secpos
+2 > maxsecpos
then wflush() end
1810 -- Alignment pseudo-opcode.
1811 map_op
[".align_1"] = function(params
)
1812 if not params
then return "numpow2" end
1813 if secpos
+1 > maxsecpos
then wflush() end
1814 local align
= tonumber(params
[1])
1817 -- Must be a power of 2 in the range (2 ... 256).
1821 waction("ALIGN", align
-1, nil, 1) -- Action byte is 2**n-1.
1826 werror("bad alignment")
1829 ------------------------------------------------------------------------------
1831 -- Pseudo-opcode for (primitive) type definitions (map to C types).
1832 map_op
[".type_3"] = function(params
, nparams
)
1834 return nparams
== 2 and "name, ctype" or "name, ctype, reg"
1836 local name
, ctype
, reg
= params
[1], params
[2], params
[3]
1837 if not match(name
, "^[%a_][%w_]*$") then
1838 werror("bad type name `"..name
.."'")
1840 local tp
= map_type
[name
]
1842 werror("duplicate type `"..name
.."'")
1844 -- Add #type to defines. A bit unclean to put it in map_archdef.
1845 map_archdef
["#"..name
] = "sizeof("..ctype
..")"
1846 -- Add new type and emit shortcut define.
1847 local num
= ctypenum
+ 1
1850 ctypefmt
= format("Dt%X(%%s)", num
),
1853 wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num
, ctype
))
1856 map_op
[".type_2"] = map_op
[".type_3"]
1858 -- Dump type definitions.
1859 local function dumptypes(out
, lvl
)
1861 for name
in pairs(map_type
) do t
[#t
+1] = name
end
1863 out
:write("Type definitions:\n")
1864 for _
,name
in ipairs(t
) do
1865 local tp
= map_type
[name
]
1866 local reg
= tp
.reg
or ""
1867 out
:write(format(" %-20s %-20s %s\n", name
, tp
.ctype
, reg
))
1872 ------------------------------------------------------------------------------
1874 -- Set the current section.
1875 function _M
.section(num
)
1876 waction("SECTION", num
)
1877 wflush(true) -- SECTION is a terminal action.
1880 ------------------------------------------------------------------------------
1882 -- Dump architecture description.
1883 function _M
.dumparch(out
)
1884 out
:write(format("DynASM %s version %s, released %s\n\n",
1885 _info
.arch
, _info
.version
, _info
.release
))
1889 -- Dump all user defined elements.
1890 function _M
.dumpdef(out
, lvl
)
1892 dumpglobals(out
, lvl
)
1893 dumpexterns(out
, lvl
)
1896 ------------------------------------------------------------------------------
1898 -- Pass callbacks from/to the DynASM core.
1899 function _M
.passcb(wl
, we
, wf
, ww
)
1900 wline
, werror
, wfatal
, wwarn
= wl
, we
, wf
, ww
1904 -- Setup the arch-specific module.
1905 function _M
.setup(arch
, opt
)
1906 g_arch
, g_opt
= arch
, opt
1909 -- Merge the core maps and the arch-specific maps.
1910 function _M
.mergemaps(map_coreop
, map_def
)
1911 setmetatable(map_op
, { __index
= map_coreop
})
1912 setmetatable(map_def
, { __index
= map_archdef
})
1913 return map_op
, map_def
1918 ------------------------------------------------------------------------------