diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/luajit-2.0/dynasm/dasm_ppc.lua | 1230 |
1 files changed, 0 insertions, 1230 deletions
diff --git a/libraries/luajit-2.0/dynasm/dasm_ppc.lua b/libraries/luajit-2.0/dynasm/dasm_ppc.lua deleted file mode 100644 index b2bee2c..0000000 --- a/libraries/luajit-2.0/dynasm/dasm_ppc.lua +++ /dev/null | |||
@@ -1,1230 +0,0 @@ | |||
1 | ------------------------------------------------------------------------------ | ||
2 | -- DynASM PPC module. | ||
3 | -- | ||
4 | -- Copyright (C) 2005-2011 Mike Pall. All rights reserved. | ||
5 | -- See dynasm.lua for full copyright notice. | ||
6 | ------------------------------------------------------------------------------ | ||
7 | |||
8 | -- Module information: | ||
9 | local _info = { | ||
10 | arch = "ppc", | ||
11 | description = "DynASM PPC module", | ||
12 | version = "1.3.0", | ||
13 | vernum = 10300, | ||
14 | release = "2011-05-05", | ||
15 | author = "Mike Pall", | ||
16 | license = "MIT", | ||
17 | } | ||
18 | |||
19 | -- Exported glue functions for the arch-specific module. | ||
20 | local _M = { _info = _info } | ||
21 | |||
22 | -- Cache library functions. | ||
23 | local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs | ||
24 | local assert, setmetatable = assert, setmetatable | ||
25 | local _s = string | ||
26 | local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char | ||
27 | local match, gmatch = _s.match, _s.gmatch | ||
28 | local concat, sort = table.concat, table.sort | ||
29 | |||
30 | -- Inherited tables and callbacks. | ||
31 | local g_opt, g_arch | ||
32 | local wline, werror, wfatal, wwarn | ||
33 | |||
34 | -- Action name list. | ||
35 | -- CHECK: Keep this in sync with the C code! | ||
36 | local action_names = { | ||
37 | "STOP", "SECTION", "ESC", "REL_EXT", | ||
38 | "ALIGN", "REL_LG", "LABEL_LG", | ||
39 | "REL_PC", "LABEL_PC", "IMM", | ||
40 | } | ||
41 | |||
42 | -- Maximum number of section buffer positions for dasm_put(). | ||
43 | -- CHECK: Keep this in sync with the C code! | ||
44 | local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines. | ||
45 | |||
46 | -- Action name -> action number. | ||
47 | local map_action = {} | ||
48 | for n,name in ipairs(action_names) do | ||
49 | map_action[name] = n-1 | ||
50 | end | ||
51 | |||
52 | -- Action list buffer. | ||
53 | local actlist = {} | ||
54 | |||
55 | -- Argument list for next dasm_put(). Start with offset 0 into action list. | ||
56 | local actargs = { 0 } | ||
57 | |||
58 | -- Current number of section buffer positions for dasm_put(). | ||
59 | local secpos = 1 | ||
60 | |||
61 | ------------------------------------------------------------------------------ | ||
62 | |||
63 | -- Return 8 digit hex number. | ||
64 | local function tohex(x) | ||
65 | return sub(format("%08x", x), -8) -- Avoid 64 bit portability problem in Lua. | ||
66 | end | ||
67 | |||
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)) | ||
74 | end | ||
75 | out:write("\n") | ||
76 | end | ||
77 | |||
78 | -- Write action list buffer as a huge static C array. | ||
79 | local function writeactions(out, name) | ||
80 | local nn = #actlist | ||
81 | if nn == 0 then nn = 1; actlist[0] = map_action.STOP end | ||
82 | out:write("static const unsigned int ", name, "[", nn, "] = {\n") | ||
83 | for i = 1,nn-1 do | ||
84 | assert(out:write("0x", tohex(actlist[i]), ",\n")) | ||
85 | end | ||
86 | assert(out:write("0x", tohex(actlist[nn]), "\n};\n\n")) | ||
87 | end | ||
88 | |||
89 | ------------------------------------------------------------------------------ | ||
90 | |||
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 | ||
95 | end | ||
96 | |||
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 | ||
103 | end | ||
104 | |||
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. | ||
112 | end | ||
113 | |||
114 | -- Put escaped word. | ||
115 | local function wputw(n) | ||
116 | if n <= 0xffffff then waction("ESC") end | ||
117 | wputxw(n) | ||
118 | end | ||
119 | |||
120 | -- Reserve position for word. | ||
121 | local function wpos() | ||
122 | local pos = #actlist+1 | ||
123 | actlist[pos] = "" | ||
124 | return pos | ||
125 | end | ||
126 | |||
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") | ||
130 | actlist[pos] = n | ||
131 | end | ||
132 | |||
133 | ------------------------------------------------------------------------------ | ||
134 | |||
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 | ||
141 | next_global = n + 1 | ||
142 | t[name] = n | ||
143 | return n | ||
144 | end}) | ||
145 | |||
146 | -- Dump global labels. | ||
147 | local function dumpglobals(out, lvl) | ||
148 | local t = {} | ||
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])) | ||
153 | end | ||
154 | out:write("\n") | ||
155 | end | ||
156 | |||
157 | -- Write global label enum. | ||
158 | local function writeglobals(out, prefix) | ||
159 | local t = {} | ||
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") | ||
164 | end | ||
165 | out:write(" ", prefix, "_MAX\n};\n") | ||
166 | end | ||
167 | |||
168 | -- Write global label names. | ||
169 | local function writeglobalnames(out, name) | ||
170 | local t = {} | ||
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") | ||
175 | end | ||
176 | out:write(" (const char *)0\n};\n") | ||
177 | end | ||
178 | |||
179 | ------------------------------------------------------------------------------ | ||
180 | |||
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 | ||
188 | next_extern = n + 1 | ||
189 | t[name] = n | ||
190 | map_extern_[n] = name | ||
191 | return n | ||
192 | end}) | ||
193 | |||
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])) | ||
199 | end | ||
200 | out:write("\n") | ||
201 | end | ||
202 | |||
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") | ||
208 | end | ||
209 | out:write(" (const char *)0\n};\n") | ||
210 | end | ||
211 | |||
212 | ------------------------------------------------------------------------------ | ||
213 | |||
214 | -- Arch-specific maps. | ||
215 | local map_archdef = { sp = "r1" } -- Ext. register name -> int. name. | ||
216 | |||
217 | local map_type = {} -- Type name -> { ctype, reg } | ||
218 | local ctypenum = 0 -- Type number (for Dt... macros). | ||
219 | |||
220 | -- Reverse defines for registers. | ||
221 | function _M.revdef(s) | ||
222 | if s == "r1" then return "sp" end | ||
223 | return s | ||
224 | end | ||
225 | |||
226 | local map_cond = { | ||
227 | lt = 0, gt = 1, eq = 2, so = 3, | ||
228 | ge = 4, le = 5, ne = 6, ns = 7, | ||
229 | } | ||
230 | |||
231 | ------------------------------------------------------------------------------ | ||
232 | |||
233 | -- Template strings for PPC instructions. | ||
234 | local map_op = { | ||
235 | tdi_3 = "08000000ARI", | ||
236 | twi_3 = "0c000000ARI", | ||
237 | mulli_3 = "1c000000RRI", | ||
238 | subfic_3 = "20000000RRI", | ||
239 | cmplwi_3 = "28000000XRU", | ||
240 | cmplwi_2 = "28000000-RU", | ||
241 | cmpldi_3 = "28200000XRU", | ||
242 | cmpldi_2 = "28200000-RU", | ||
243 | cmpwi_3 = "2c000000XRI", | ||
244 | cmpwi_2 = "2c000000-RI", | ||
245 | cmpdi_3 = "2c200000XRI", | ||
246 | cmpdi_2 = "2c200000-RI", | ||
247 | addic_3 = "30000000RRI", | ||
248 | ["addic._3"] = "34000000RRI", | ||
249 | addi_3 = "38000000RR0I", | ||
250 | li_2 = "38000000RI", | ||
251 | la_2 = "38000000RD", | ||
252 | addis_3 = "3c000000RR0I", | ||
253 | lis_2 = "3c000000RI", | ||
254 | lus_2 = "3c000000RU", | ||
255 | bc_3 = "40000000AAK", | ||
256 | bcl_3 = "40000001AAK", | ||
257 | bdnz_1 = "42000000K", | ||
258 | bdz_1 = "42400000K", | ||
259 | sc_0 = "44000000", | ||
260 | b_1 = "48000000J", | ||
261 | bl_1 = "48000001J", | ||
262 | rlwimi_5 = "50000000RR~AAA.", | ||
263 | rlwinm_5 = "54000000RR~AAA.", | ||
264 | rlwnm_5 = "5c000000RR~RAA.", | ||
265 | ori_3 = "60000000RR~U", | ||
266 | nop_0 = "60000000", | ||
267 | oris_3 = "64000000RR~U", | ||
268 | xori_3 = "68000000RR~U", | ||
269 | xoris_3 = "6c000000RR~U", | ||
270 | ["andi._3"] = "70000000RR~U", | ||
271 | ["andis._3"] = "74000000RR~U", | ||
272 | lwz_2 = "80000000RD", | ||
273 | lwzu_2 = "84000000RD", | ||
274 | lbz_2 = "88000000RD", | ||
275 | lbzu_2 = "8c000000RD", | ||
276 | stw_2 = "90000000RD", | ||
277 | stwu_2 = "94000000RD", | ||
278 | stb_2 = "98000000RD", | ||
279 | stbu_2 = "9c000000RD", | ||
280 | lhz_2 = "a0000000RD", | ||
281 | lhzu_2 = "a4000000RD", | ||
282 | lha_2 = "a8000000RD", | ||
283 | lhau_2 = "ac000000RD", | ||
284 | sth_2 = "b0000000RD", | ||
285 | sthu_2 = "b4000000RD", | ||
286 | lmw_2 = "b8000000RD", | ||
287 | stmw_2 = "bc000000RD", | ||
288 | lfs_2 = "c0000000FD", | ||
289 | lfsu_2 = "c4000000FD", | ||
290 | lfd_2 = "c8000000FD", | ||
291 | lfdu_2 = "cc000000FD", | ||
292 | stfs_2 = "d0000000FD", | ||
293 | stfsu_2 = "d4000000FD", | ||
294 | stfd_2 = "d8000000FD", | ||
295 | stfdu_2 = "dc000000FD", | ||
296 | ld_2 = "e8000000RD", -- NYI: displacement must be divisible by 4. | ||
297 | ldu_2 = "e8000001RD", | ||
298 | lwa_2 = "e8000002RD", | ||
299 | std_2 = "f8000000RD", | ||
300 | stdu_2 = "f8000001RD", | ||
301 | |||
302 | -- Primary opcode 19: | ||
303 | mcrf_2 = "4c000000XX", | ||
304 | isync_0 = "4c00012c", | ||
305 | crnor_3 = "4c000042CCC", | ||
306 | crnot_2 = "4c000042CC=", | ||
307 | crandc_3 = "4c000102CCC", | ||
308 | crxor_3 = "4c000182CCC", | ||
309 | crclr_1 = "4c000182C==", | ||
310 | crnand_3 = "4c0001c2CCC", | ||
311 | crand_3 = "4c000202CCC", | ||
312 | creqv_3 = "4c000242CCC", | ||
313 | crset_1 = "4c000242C==", | ||
314 | crorc_3 = "4c000342CCC", | ||
315 | cror_3 = "4c000382CCC", | ||
316 | crmove_2 = "4c000382CC=", | ||
317 | bclr_2 = "4c000020AA", | ||
318 | bclrl_2 = "4c000021AA", | ||
319 | bcctr_2 = "4c000420AA", | ||
320 | bcctrl_2 = "4c000421AA", | ||
321 | blr_0 = "4e800020", | ||
322 | blrl_0 = "4e800021", | ||
323 | bctr_0 = "4e800420", | ||
324 | bctrl_0 = "4e800421", | ||
325 | |||
326 | -- Primary opcode 31: | ||
327 | cmpw_3 = "7c000000XRR", | ||
328 | cmpw_2 = "7c000000-RR", | ||
329 | cmpd_3 = "7c200000XRR", | ||
330 | cmpd_2 = "7c200000-RR", | ||
331 | tw_3 = "7c000008ARR", | ||
332 | subfc_3 = "7c000010RRR.", | ||
333 | subc_3 = "7c000010RRR~.", | ||
334 | mulhdu_3 = "7c000012RRR.", | ||
335 | addc_3 = "7c000014RRR.", | ||
336 | mulhwu_3 = "7c000016RRR.", | ||
337 | isel_4 = "7c00001eRRRC", | ||
338 | isellt_3 = "7c00001eRRR", | ||
339 | iselgt_3 = "7c00005eRRR", | ||
340 | iseleq_3 = "7c00009eRRR", | ||
341 | mfcr_1 = "7c000026R", | ||
342 | mtcrf_2 = "7c000120GR", | ||
343 | -- NYI: mtocrf, mfocrf | ||
344 | lwarx_3 = "7c000028RR0R", | ||
345 | ldx_3 = "7c00002aRR0R", | ||
346 | lwzx_3 = "7c00002eRR0R", | ||
347 | slw_3 = "7c000030RR~R.", | ||
348 | cntlzw_2 = "7c000034RR~", | ||
349 | sld_3 = "7c000036RR~R.", | ||
350 | and_3 = "7c000038RR~R.", | ||
351 | cmplw_3 = "7c000040XRR", | ||
352 | cmplw_2 = "7c000040-RR", | ||
353 | cmpld_3 = "7c200040XRR", | ||
354 | cmpld_2 = "7c200040-RR", | ||
355 | subf_3 = "7c000050RRR.", | ||
356 | sub_3 = "7c000050RRR~.", | ||
357 | ldux_3 = "7c00006aRR0R", | ||
358 | dcbst_2 = "7c00006c-RR", | ||
359 | lwzux_3 = "7c00006eRR0R", | ||
360 | cntlzd_2 = "7c000074RR~", | ||
361 | andc_3 = "7c000078RR~R.", | ||
362 | td_3 = "7c000088ARR", | ||
363 | mulhd_3 = "7c000092RRR.", | ||
364 | mulhw_3 = "7c000096RRR.", | ||
365 | ldarx_3 = "7c0000a8RR0R", | ||
366 | dcbf_2 = "7c0000ac-RR", | ||
367 | lbzx_3 = "7c0000aeRR0R", | ||
368 | neg_2 = "7c0000d0RR.", | ||
369 | lbzux_3 = "7c0000eeRR0R", | ||
370 | popcntb_2 = "7c0000f4RR~", | ||
371 | not_2 = "7c0000f8RR~%.", | ||
372 | nor_3 = "7c0000f8RR~R.", | ||
373 | subfe_3 = "7c000110RRR.", | ||
374 | sube_3 = "7c000110RRR~.", | ||
375 | adde_3 = "7c000114RRR.", | ||
376 | stdx_3 = "7c00012aRR0R", | ||
377 | stwcx_3 = "7c00012cRR0R.", | ||
378 | stwx_3 = "7c00012eRR0R", | ||
379 | prtyw_2 = "7c000134RR~", | ||
380 | stdux_3 = "7c00016aRR0R", | ||
381 | stwux_3 = "7c00016eRR0R", | ||
382 | prtyd_2 = "7c000174RR~", | ||
383 | subfze_2 = "7c000190RR.", | ||
384 | addze_2 = "7c000194RR.", | ||
385 | stdcx_3 = "7c0001acRR0R.", | ||
386 | stbx_3 = "7c0001aeRR0R", | ||
387 | subfme_2 = "7c0001d0RR.", | ||
388 | mulld_3 = "7c0001d2RRR.", | ||
389 | addme_2 = "7c0001d4RR.", | ||
390 | mullw_3 = "7c0001d6RRR.", | ||
391 | dcbtst_2 = "7c0001ec-RR", | ||
392 | stbux_3 = "7c0001eeRR0R", | ||
393 | add_3 = "7c000214RRR.", | ||
394 | dcbt_2 = "7c00022c-RR", | ||
395 | lhzx_3 = "7c00022eRR0R", | ||
396 | eqv_3 = "7c000238RR~R.", | ||
397 | eciwx_3 = "7c00026cRR0R", | ||
398 | lhzux_3 = "7c00026eRR0R", | ||
399 | xor_3 = "7c000278RR~R.", | ||
400 | mfspefscr_1 = "7c0082a6R", | ||
401 | mfxer_1 = "7c0102a6R", | ||
402 | mflr_1 = "7c0802a6R", | ||
403 | mfctr_1 = "7c0902a6R", | ||
404 | lwax_3 = "7c0002aaRR0R", | ||
405 | lhax_3 = "7c0002aeRR0R", | ||
406 | mftb_1 = "7c0c42e6R", | ||
407 | mftbu_1 = "7c0d42e6R", | ||
408 | lwaux_3 = "7c0002eaRR0R", | ||
409 | lhaux_3 = "7c0002eeRR0R", | ||
410 | sthx_3 = "7c00032eRR0R", | ||
411 | orc_3 = "7c000338RR~R.", | ||
412 | ecowx_3 = "7c00036cRR0R", | ||
413 | sthux_3 = "7c00036eRR0R", | ||
414 | or_3 = "7c000378RR~R.", | ||
415 | mr_2 = "7c000378RR~%.", | ||
416 | divdu_3 = "7c000392RRR.", | ||
417 | divwu_3 = "7c000396RRR.", | ||
418 | mtspefscr_1 = "7c0083a6R", | ||
419 | mtxer_1 = "7c0103a6R", | ||
420 | mtlr_1 = "7c0803a6R", | ||
421 | mtctr_1 = "7c0903a6R", | ||
422 | dcbi_2 = "7c0003ac-RR", | ||
423 | nand_3 = "7c0003b8RR~R.", | ||
424 | divd_3 = "7c0003d2RRR.", | ||
425 | divw_3 = "7c0003d6RRR.", | ||
426 | cmpb_3 = "7c0003f8RR~R.", | ||
427 | mcrxr_1 = "7c000400X", | ||
428 | subfco_3 = "7c000410RRR.", | ||
429 | subco_3 = "7c000410RRR~.", | ||
430 | addco_3 = "7c000414RRR.", | ||
431 | ldbrx_3 = "7c000428RR0R", | ||
432 | lswx_3 = "7c00042aRR0R", | ||
433 | lwbrx_3 = "7c00042cRR0R", | ||
434 | lfsx_3 = "7c00042eFR0R", | ||
435 | srw_3 = "7c000430RR~R.", | ||
436 | srd_3 = "7c000436RR~R.", | ||
437 | subfo_3 = "7c000450RRR.", | ||
438 | subo_3 = "7c000450RRR~.", | ||
439 | lfsux_3 = "7c00046eFR0R", | ||
440 | lswi_3 = "7c0004aaRR0A", | ||
441 | sync_0 = "7c0004ac", | ||
442 | lwsync_0 = "7c2004ac", | ||
443 | ptesync_0 = "7c4004ac", | ||
444 | lfdx_3 = "7c0004aeFR0R", | ||
445 | nego_2 = "7c0004d0RR.", | ||
446 | lfdux_3 = "7c0004eeFR0R", | ||
447 | subfeo_3 = "7c000510RRR.", | ||
448 | subeo_3 = "7c000510RRR~.", | ||
449 | addeo_3 = "7c000514RRR.", | ||
450 | stdbrx_3 = "7c000528RR0R", | ||
451 | stswx_3 = "7c00052aRR0R", | ||
452 | stwbrx_3 = "7c00052cRR0R", | ||
453 | stfsx_3 = "7c00052eFR0R", | ||
454 | stfsux_3 = "7c00056eFR0R", | ||
455 | subfzeo_2 = "7c000590RR.", | ||
456 | addzeo_2 = "7c000594RR.", | ||
457 | stswi_3 = "7c0005aaRR0A", | ||
458 | stfdx_3 = "7c0005aeFR0R", | ||
459 | subfmeo_2 = "7c0005d0RR.", | ||
460 | mulldo_3 = "7c0005d2RRR.", | ||
461 | addmeo_2 = "7c0005d4RR.", | ||
462 | mullwo_3 = "7c0005d6RRR.", | ||
463 | dcba_2 = "7c0005ec-RR", | ||
464 | stfdux_3 = "7c0005eeFR0R", | ||
465 | addo_3 = "7c000614RRR.", | ||
466 | lhbrx_3 = "7c00062cRR0R", | ||
467 | sraw_3 = "7c000630RR~R.", | ||
468 | srad_3 = "7c000634RR~R.", | ||
469 | srawi_3 = "7c000670RR~A.", | ||
470 | eieio_0 = "7c0006ac", | ||
471 | lfiwax_3 = "7c0006aeFR0R", | ||
472 | sthbrx_3 = "7c00072cRR0R", | ||
473 | extsh_2 = "7c000734RR~.", | ||
474 | extsb_2 = "7c000774RR~.", | ||
475 | divduo_3 = "7c000792RRR.", | ||
476 | divwou_3 = "7c000796RRR.", | ||
477 | icbi_2 = "7c0007ac-RR", | ||
478 | stfiwx_3 = "7c0007aeFR0R", | ||
479 | extsw_2 = "7c0007b4RR~.", | ||
480 | divdo_3 = "7c0007d2RRR.", | ||
481 | divwo_3 = "7c0007d6RRR.", | ||
482 | dcbz_2 = "7c0007ec-RR", | ||
483 | |||
484 | -- Primary opcode 59: | ||
485 | fdivs_3 = "ec000024FFF.", | ||
486 | fsubs_3 = "ec000028FFF.", | ||
487 | fadds_3 = "ec00002aFFF.", | ||
488 | fsqrts_2 = "ec00002cF-F.", | ||
489 | fres_2 = "ec000030F-F.", | ||
490 | fmuls_3 = "ec000032FF-F.", | ||
491 | frsqrtes_2 = "ec000034F-F.", | ||
492 | fmsubs_4 = "ec000038FFFF~.", | ||
493 | fmadds_4 = "ec00003aFFFF~.", | ||
494 | fnmsubs_4 = "ec00003cFFFF~.", | ||
495 | fnmadds_4 = "ec00003eFFFF~.", | ||
496 | |||
497 | -- Primary opcode 63: | ||
498 | fdiv_3 = "fc000024FFF.", | ||
499 | fsub_3 = "fc000028FFF.", | ||
500 | fadd_3 = "fc00002aFFF.", | ||
501 | fsqrt_2 = "fc00002cF-F.", | ||
502 | fsel_4 = "fc00002eFFFF~.", | ||
503 | fre_2 = "fc000030F-F.", | ||
504 | fmul_3 = "fc000032FF-F.", | ||
505 | frsqrte_2 = "fc000034F-F.", | ||
506 | fmsub_4 = "fc000038FFFF~.", | ||
507 | fmadd_4 = "fc00003aFFFF~.", | ||
508 | fnmsub_4 = "fc00003cFFFF~.", | ||
509 | fnmadd_4 = "fc00003eFFFF~.", | ||
510 | fcmpu_3 = "fc000000XFF", | ||
511 | fcpsgn_3 = "fc000010FFF.", | ||
512 | fcmpo_3 = "fc000040XFF", | ||
513 | mtfsb1_1 = "fc00004cA", | ||
514 | fneg_2 = "fc000050F-F.", | ||
515 | mcrfs_2 = "fc000080XX", | ||
516 | mtfsb0_1 = "fc00008cA", | ||
517 | fmr_2 = "fc000090F-F.", | ||
518 | frsp_2 = "fc000018F-F.", | ||
519 | fctiw_2 = "fc00001cF-F.", | ||
520 | fctiwz_2 = "fc00001eF-F.", | ||
521 | mtfsfi_2 = "fc00010cAA", -- NYI: upshift. | ||
522 | fnabs_2 = "fc000110F-F.", | ||
523 | fabs_2 = "fc000210F-F.", | ||
524 | frin_2 = "fc000310F-F.", | ||
525 | friz_2 = "fc000350F-F.", | ||
526 | frip_2 = "fc000390F-F.", | ||
527 | frim_2 = "fc0003d0F-F.", | ||
528 | mffs_1 = "fc00048eF.", | ||
529 | -- NYI: mtfsf, mtfsb0, mtfsb1. | ||
530 | fctid_2 = "fc00065cF-F.", | ||
531 | fctidz_2 = "fc00065eF-F.", | ||
532 | fcfid_2 = "fc00069cF-F.", | ||
533 | |||
534 | -- Primary opcode 4, SPE APU extension: | ||
535 | evaddw_3 = "10000200RRR", | ||
536 | evaddiw_3 = "10000202RAR~", | ||
537 | evsubw_3 = "10000204RRR~", | ||
538 | evsubiw_3 = "10000206RAR~", | ||
539 | evabs_2 = "10000208RR", | ||
540 | evneg_2 = "10000209RR", | ||
541 | evextsb_2 = "1000020aRR", | ||
542 | evextsh_2 = "1000020bRR", | ||
543 | evrndw_2 = "1000020cRR", | ||
544 | evcntlzw_2 = "1000020dRR", | ||
545 | evcntlsw_2 = "1000020eRR", | ||
546 | brinc_3 = "1000020fRRR", | ||
547 | evand_3 = "10000211RRR", | ||
548 | evandc_3 = "10000212RRR", | ||
549 | evxor_3 = "10000216RRR", | ||
550 | evor_3 = "10000217RRR", | ||
551 | evmr_2 = "10000217RR=", | ||
552 | evnor_3 = "10000218RRR", | ||
553 | evnot_2 = "10000218RR=", | ||
554 | eveqv_3 = "10000219RRR", | ||
555 | evorc_3 = "1000021bRRR", | ||
556 | evnand_3 = "1000021eRRR", | ||
557 | evsrwu_3 = "10000220RRR", | ||
558 | evsrws_3 = "10000221RRR", | ||
559 | evsrwiu_3 = "10000222RRA", | ||
560 | evsrwis_3 = "10000223RRA", | ||
561 | evslw_3 = "10000224RRR", | ||
562 | evslwi_3 = "10000226RRA", | ||
563 | evrlw_3 = "10000228RRR", | ||
564 | evsplati_2 = "10000229RS", | ||
565 | evrlwi_3 = "1000022aRRA", | ||
566 | evsplatfi_2 = "1000022bRS", | ||
567 | evmergehi_3 = "1000022cRRR", | ||
568 | evmergelo_3 = "1000022dRRR", | ||
569 | evcmpgtu_3 = "10000230XRR", | ||
570 | evcmpgtu_2 = "10000230-RR", | ||
571 | evcmpgts_3 = "10000231XRR", | ||
572 | evcmpgts_2 = "10000231-RR", | ||
573 | evcmpltu_3 = "10000232XRR", | ||
574 | evcmpltu_2 = "10000232-RR", | ||
575 | evcmplts_3 = "10000233XRR", | ||
576 | evcmplts_2 = "10000233-RR", | ||
577 | evcmpeq_3 = "10000234XRR", | ||
578 | evcmpeq_2 = "10000234-RR", | ||
579 | evsel_4 = "10000278RRRW", | ||
580 | evsel_3 = "10000278RRR", | ||
581 | evfsadd_3 = "10000280RRR", | ||
582 | evfssub_3 = "10000281RRR", | ||
583 | evfsabs_2 = "10000284RR", | ||
584 | evfsnabs_2 = "10000285RR", | ||
585 | evfsneg_2 = "10000286RR", | ||
586 | evfsmul_3 = "10000288RRR", | ||
587 | evfsdiv_3 = "10000289RRR", | ||
588 | evfscmpgt_3 = "1000028cXRR", | ||
589 | evfscmpgt_2 = "1000028c-RR", | ||
590 | evfscmplt_3 = "1000028dXRR", | ||
591 | evfscmplt_2 = "1000028d-RR", | ||
592 | evfscmpeq_3 = "1000028eXRR", | ||
593 | evfscmpeq_2 = "1000028e-RR", | ||
594 | evfscfui_2 = "10000290R-R", | ||
595 | evfscfsi_2 = "10000291R-R", | ||
596 | evfscfuf_2 = "10000292R-R", | ||
597 | evfscfsf_2 = "10000293R-R", | ||
598 | evfsctui_2 = "10000294R-R", | ||
599 | evfsctsi_2 = "10000295R-R", | ||
600 | evfsctuf_2 = "10000296R-R", | ||
601 | evfsctsf_2 = "10000297R-R", | ||
602 | evfsctuiz_2 = "10000298R-R", | ||
603 | evfsctsiz_2 = "1000029aR-R", | ||
604 | evfststgt_3 = "1000029cXRR", | ||
605 | evfststgt_2 = "1000029c-RR", | ||
606 | evfststlt_3 = "1000029dXRR", | ||
607 | evfststlt_2 = "1000029d-RR", | ||
608 | evfststeq_3 = "1000029eXRR", | ||
609 | evfststeq_2 = "1000029e-RR", | ||
610 | efsadd_3 = "100002c0RRR", | ||
611 | efssub_3 = "100002c1RRR", | ||
612 | efsabs_2 = "100002c4RR", | ||
613 | efsnabs_2 = "100002c5RR", | ||
614 | efsneg_2 = "100002c6RR", | ||
615 | efsmul_3 = "100002c8RRR", | ||
616 | efsdiv_3 = "100002c9RRR", | ||
617 | efscmpgt_3 = "100002ccXRR", | ||
618 | efscmpgt_2 = "100002cc-RR", | ||
619 | efscmplt_3 = "100002cdXRR", | ||
620 | efscmplt_2 = "100002cd-RR", | ||
621 | efscmpeq_3 = "100002ceXRR", | ||
622 | efscmpeq_2 = "100002ce-RR", | ||
623 | efscfd_2 = "100002cfR-R", | ||
624 | efscfui_2 = "100002d0R-R", | ||
625 | efscfsi_2 = "100002d1R-R", | ||
626 | efscfuf_2 = "100002d2R-R", | ||
627 | efscfsf_2 = "100002d3R-R", | ||
628 | efsctui_2 = "100002d4R-R", | ||
629 | efsctsi_2 = "100002d5R-R", | ||
630 | efsctuf_2 = "100002d6R-R", | ||
631 | efsctsf_2 = "100002d7R-R", | ||
632 | efsctuiz_2 = "100002d8R-R", | ||
633 | efsctsiz_2 = "100002daR-R", | ||
634 | efststgt_3 = "100002dcXRR", | ||
635 | efststgt_2 = "100002dc-RR", | ||
636 | efststlt_3 = "100002ddXRR", | ||
637 | efststlt_2 = "100002dd-RR", | ||
638 | efststeq_3 = "100002deXRR", | ||
639 | efststeq_2 = "100002de-RR", | ||
640 | efdadd_3 = "100002e0RRR", | ||
641 | efdsub_3 = "100002e1RRR", | ||
642 | efdcfuid_2 = "100002e2R-R", | ||
643 | efdcfsid_2 = "100002e3R-R", | ||
644 | efdabs_2 = "100002e4RR", | ||
645 | efdnabs_2 = "100002e5RR", | ||
646 | efdneg_2 = "100002e6RR", | ||
647 | efdmul_3 = "100002e8RRR", | ||
648 | efddiv_3 = "100002e9RRR", | ||
649 | efdctuidz_2 = "100002eaR-R", | ||
650 | efdctsidz_2 = "100002ebR-R", | ||
651 | efdcmpgt_3 = "100002ecXRR", | ||
652 | efdcmpgt_2 = "100002ec-RR", | ||
653 | efdcmplt_3 = "100002edXRR", | ||
654 | efdcmplt_2 = "100002ed-RR", | ||
655 | efdcmpeq_3 = "100002eeXRR", | ||
656 | efdcmpeq_2 = "100002ee-RR", | ||
657 | efdcfs_2 = "100002efR-R", | ||
658 | efdcfui_2 = "100002f0R-R", | ||
659 | efdcfsi_2 = "100002f1R-R", | ||
660 | efdcfuf_2 = "100002f2R-R", | ||
661 | efdcfsf_2 = "100002f3R-R", | ||
662 | efdctui_2 = "100002f4R-R", | ||
663 | efdctsi_2 = "100002f5R-R", | ||
664 | efdctuf_2 = "100002f6R-R", | ||
665 | efdctsf_2 = "100002f7R-R", | ||
666 | efdctuiz_2 = "100002f8R-R", | ||
667 | efdctsiz_2 = "100002faR-R", | ||
668 | efdtstgt_3 = "100002fcXRR", | ||
669 | efdtstgt_2 = "100002fc-RR", | ||
670 | efdtstlt_3 = "100002fdXRR", | ||
671 | efdtstlt_2 = "100002fd-RR", | ||
672 | efdtsteq_3 = "100002feXRR", | ||
673 | efdtsteq_2 = "100002fe-RR", | ||
674 | evlddx_3 = "10000300RR0R", | ||
675 | evldd_2 = "10000301R8", | ||
676 | evldwx_3 = "10000302RR0R", | ||
677 | evldw_2 = "10000303R8", | ||
678 | evldhx_3 = "10000304RR0R", | ||
679 | evldh_2 = "10000305R8", | ||
680 | evlwhex_3 = "10000310RR0R", | ||
681 | evlwhe_2 = "10000311R4", | ||
682 | evlwhoux_3 = "10000314RR0R", | ||
683 | evlwhou_2 = "10000315R4", | ||
684 | evlwhosx_3 = "10000316RR0R", | ||
685 | evlwhos_2 = "10000317R4", | ||
686 | evstddx_3 = "10000320RR0R", | ||
687 | evstdd_2 = "10000321R8", | ||
688 | evstdwx_3 = "10000322RR0R", | ||
689 | evstdw_2 = "10000323R8", | ||
690 | evstdhx_3 = "10000324RR0R", | ||
691 | evstdh_2 = "10000325R8", | ||
692 | evstwhex_3 = "10000330RR0R", | ||
693 | evstwhe_2 = "10000331R4", | ||
694 | evstwhox_3 = "10000334RR0R", | ||
695 | evstwho_2 = "10000335R4", | ||
696 | evstwwex_3 = "10000338RR0R", | ||
697 | evstwwe_2 = "10000339R4", | ||
698 | evstwwox_3 = "1000033cRR0R", | ||
699 | evstwwo_2 = "1000033dR4", | ||
700 | evmhessf_3 = "10000403RRR", | ||
701 | evmhossf_3 = "10000407RRR", | ||
702 | evmheumi_3 = "10000408RRR", | ||
703 | evmhesmi_3 = "10000409RRR", | ||
704 | evmhesmf_3 = "1000040bRRR", | ||
705 | evmhoumi_3 = "1000040cRRR", | ||
706 | evmhosmi_3 = "1000040dRRR", | ||
707 | evmhosmf_3 = "1000040fRRR", | ||
708 | evmhessfa_3 = "10000423RRR", | ||
709 | evmhossfa_3 = "10000427RRR", | ||
710 | evmheumia_3 = "10000428RRR", | ||
711 | evmhesmia_3 = "10000429RRR", | ||
712 | evmhesmfa_3 = "1000042bRRR", | ||
713 | evmhoumia_3 = "1000042cRRR", | ||
714 | evmhosmia_3 = "1000042dRRR", | ||
715 | evmhosmfa_3 = "1000042fRRR", | ||
716 | evmwhssf_3 = "10000447RRR", | ||
717 | evmwlumi_3 = "10000448RRR", | ||
718 | evmwhumi_3 = "1000044cRRR", | ||
719 | evmwhsmi_3 = "1000044dRRR", | ||
720 | evmwhsmf_3 = "1000044fRRR", | ||
721 | evmwssf_3 = "10000453RRR", | ||
722 | evmwumi_3 = "10000458RRR", | ||
723 | evmwsmi_3 = "10000459RRR", | ||
724 | evmwsmf_3 = "1000045bRRR", | ||
725 | evmwhssfa_3 = "10000467RRR", | ||
726 | evmwlumia_3 = "10000468RRR", | ||
727 | evmwhumia_3 = "1000046cRRR", | ||
728 | evmwhsmia_3 = "1000046dRRR", | ||
729 | evmwhsmfa_3 = "1000046fRRR", | ||
730 | evmwssfa_3 = "10000473RRR", | ||
731 | evmwumia_3 = "10000478RRR", | ||
732 | evmwsmia_3 = "10000479RRR", | ||
733 | evmwsmfa_3 = "1000047bRRR", | ||
734 | evmra_2 = "100004c4RR", | ||
735 | evdivws_3 = "100004c6RRR", | ||
736 | evdivwu_3 = "100004c7RRR", | ||
737 | evmwssfaa_3 = "10000553RRR", | ||
738 | evmwumiaa_3 = "10000558RRR", | ||
739 | evmwsmiaa_3 = "10000559RRR", | ||
740 | evmwsmfaa_3 = "1000055bRRR", | ||
741 | evmwssfan_3 = "100005d3RRR", | ||
742 | evmwumian_3 = "100005d8RRR", | ||
743 | evmwsmian_3 = "100005d9RRR", | ||
744 | evmwsmfan_3 = "100005dbRRR", | ||
745 | evmergehilo_3 = "1000022eRRR", | ||
746 | evmergelohi_3 = "1000022fRRR", | ||
747 | evlhhesplatx_3 = "10000308RR0R", | ||
748 | evlhhesplat_2 = "10000309R2", | ||
749 | evlhhousplatx_3 = "1000030cRR0R", | ||
750 | evlhhousplat_2 = "1000030dR2", | ||
751 | evlhhossplatx_3 = "1000030eRR0R", | ||
752 | evlhhossplat_2 = "1000030fR2", | ||
753 | evlwwsplatx_3 = "10000318RR0R", | ||
754 | evlwwsplat_2 = "10000319R4", | ||
755 | evlwhsplatx_3 = "1000031cRR0R", | ||
756 | evlwhsplat_2 = "1000031dR4", | ||
757 | evaddusiaaw_2 = "100004c0RR", | ||
758 | evaddssiaaw_2 = "100004c1RR", | ||
759 | evsubfusiaaw_2 = "100004c2RR", | ||
760 | evsubfssiaaw_2 = "100004c3RR", | ||
761 | evaddumiaaw_2 = "100004c8RR", | ||
762 | evaddsmiaaw_2 = "100004c9RR", | ||
763 | evsubfumiaaw_2 = "100004caRR", | ||
764 | evsubfsmiaaw_2 = "100004cbRR", | ||
765 | evmheusiaaw_3 = "10000500RRR", | ||
766 | evmhessiaaw_3 = "10000501RRR", | ||
767 | evmhessfaaw_3 = "10000503RRR", | ||
768 | evmhousiaaw_3 = "10000504RRR", | ||
769 | evmhossiaaw_3 = "10000505RRR", | ||
770 | evmhossfaaw_3 = "10000507RRR", | ||
771 | evmheumiaaw_3 = "10000508RRR", | ||
772 | evmhesmiaaw_3 = "10000509RRR", | ||
773 | evmhesmfaaw_3 = "1000050bRRR", | ||
774 | evmhoumiaaw_3 = "1000050cRRR", | ||
775 | evmhosmiaaw_3 = "1000050dRRR", | ||
776 | evmhosmfaaw_3 = "1000050fRRR", | ||
777 | evmhegumiaa_3 = "10000528RRR", | ||
778 | evmhegsmiaa_3 = "10000529RRR", | ||
779 | evmhegsmfaa_3 = "1000052bRRR", | ||
780 | evmhogumiaa_3 = "1000052cRRR", | ||
781 | evmhogsmiaa_3 = "1000052dRRR", | ||
782 | evmhogsmfaa_3 = "1000052fRRR", | ||
783 | evmwlusiaaw_3 = "10000540RRR", | ||
784 | evmwlssiaaw_3 = "10000541RRR", | ||
785 | evmwlumiaaw_3 = "10000548RRR", | ||
786 | evmwlsmiaaw_3 = "10000549RRR", | ||
787 | evmheusianw_3 = "10000580RRR", | ||
788 | evmhessianw_3 = "10000581RRR", | ||
789 | evmhessfanw_3 = "10000583RRR", | ||
790 | evmhousianw_3 = "10000584RRR", | ||
791 | evmhossianw_3 = "10000585RRR", | ||
792 | evmhossfanw_3 = "10000587RRR", | ||
793 | evmheumianw_3 = "10000588RRR", | ||
794 | evmhesmianw_3 = "10000589RRR", | ||
795 | evmhesmfanw_3 = "1000058bRRR", | ||
796 | evmhoumianw_3 = "1000058cRRR", | ||
797 | evmhosmianw_3 = "1000058dRRR", | ||
798 | evmhosmfanw_3 = "1000058fRRR", | ||
799 | evmhegumian_3 = "100005a8RRR", | ||
800 | evmhegsmian_3 = "100005a9RRR", | ||
801 | evmhegsmfan_3 = "100005abRRR", | ||
802 | evmhogumian_3 = "100005acRRR", | ||
803 | evmhogsmian_3 = "100005adRRR", | ||
804 | evmhogsmfan_3 = "100005afRRR", | ||
805 | evmwlusianw_3 = "100005c0RRR", | ||
806 | evmwlssianw_3 = "100005c1RRR", | ||
807 | evmwlumianw_3 = "100005c8RRR", | ||
808 | evmwlsmianw_3 = "100005c9RRR", | ||
809 | |||
810 | -- NYI: some 64 bit PowerPC and Book E instructions: | ||
811 | -- rldicl, rldicr, rldic, rldimi, rldcl, rldcr, sradi, 64 bit ext. add/sub, | ||
812 | -- extended addressing branches, cache management, loads and stores | ||
813 | } | ||
814 | |||
815 | -- Add mnemonics for "." variants. | ||
816 | do | ||
817 | local t = {} | ||
818 | for k,v in pairs(map_op) do | ||
819 | if sub(v, -1) == "." then | ||
820 | local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2) | ||
821 | t[sub(k, 1, -3).."."..sub(k, -2)] = v2 | ||
822 | end | ||
823 | end | ||
824 | for k,v in pairs(t) do | ||
825 | map_op[k] = v | ||
826 | end | ||
827 | end | ||
828 | |||
829 | -- Add more branch mnemonics. | ||
830 | for cond,c in pairs(map_cond) do | ||
831 | local b1 = "b"..cond | ||
832 | local c1 = (c%4)*0x00010000 + (c < 4 and 0x01000000 or 0) | ||
833 | -- bX[l] | ||
834 | map_op[b1.."_1"] = tohex(0x40800000 + c1).."K" | ||
835 | map_op[b1.."y_1"] = tohex(0x40a00000 + c1).."K" | ||
836 | map_op[b1.."l_1"] = tohex(0x40800001 + c1).."K" | ||
837 | map_op[b1.."_2"] = tohex(0x40800000 + c1).."-XK" | ||
838 | map_op[b1.."y_2"] = tohex(0x40a00000 + c1).."-XK" | ||
839 | map_op[b1.."l_2"] = tohex(0x40800001 + c1).."-XK" | ||
840 | -- bXlr[l] | ||
841 | map_op[b1.."lr_0"] = tohex(0x4c800020 + c1) | ||
842 | map_op[b1.."lrl_0"] = tohex(0x4c800021 + c1) | ||
843 | map_op[b1.."ctr_0"] = tohex(0x4c800420 + c1) | ||
844 | map_op[b1.."ctrl_0"] = tohex(0x4c800421 + c1) | ||
845 | -- bXctr[l] | ||
846 | map_op[b1.."lr_1"] = tohex(0x4c800020 + c1).."-X" | ||
847 | map_op[b1.."lrl_1"] = tohex(0x4c800021 + c1).."-X" | ||
848 | map_op[b1.."ctr_1"] = tohex(0x4c800420 + c1).."-X" | ||
849 | map_op[b1.."ctrl_1"] = tohex(0x4c800421 + c1).."-X" | ||
850 | end | ||
851 | |||
852 | ------------------------------------------------------------------------------ | ||
853 | |||
854 | local function parse_gpr(expr) | ||
855 | local tname, ovreg = match(expr, "^([%w_]+):(r[1-3]?[0-9])$") | ||
856 | local tp = map_type[tname or expr] | ||
857 | if tp then | ||
858 | local reg = ovreg or tp.reg | ||
859 | if not reg then | ||
860 | werror("type `"..(tname or expr).."' needs a register override") | ||
861 | end | ||
862 | expr = reg | ||
863 | end | ||
864 | local r = match(expr, "^r([1-3]?[0-9])$") | ||
865 | if r then | ||
866 | r = tonumber(r) | ||
867 | if r <= 31 then return r, tp end | ||
868 | end | ||
869 | werror("bad register name `"..expr.."'") | ||
870 | end | ||
871 | |||
872 | local function parse_fpr(expr) | ||
873 | local r = match(expr, "^f([1-3]?[0-9])$") | ||
874 | if r then | ||
875 | r = tonumber(r) | ||
876 | if r <= 31 then return r end | ||
877 | end | ||
878 | werror("bad register name `"..expr.."'") | ||
879 | end | ||
880 | |||
881 | local function parse_cr(expr) | ||
882 | local r = match(expr, "^cr([0-7])$") | ||
883 | if r then return tonumber(r) end | ||
884 | werror("bad condition register name `"..expr.."'") | ||
885 | end | ||
886 | |||
887 | local function parse_cond(expr) | ||
888 | local r, cond = match(expr, "^4%*cr([0-7])%+(%w%w)$") | ||
889 | if r then | ||
890 | r = tonumber(r) | ||
891 | local c = map_cond[cond] | ||
892 | if c and c < 4 then return r*4+c end | ||
893 | end | ||
894 | werror("bad condition bit name `"..expr.."'") | ||
895 | end | ||
896 | |||
897 | local function parse_imm(imm, bits, shift, scale, signed) | ||
898 | local n = tonumber(imm) | ||
899 | if n then | ||
900 | if n % 2^scale == 0 then | ||
901 | n = n / 2^scale | ||
902 | if signed then | ||
903 | if n >= 0 then | ||
904 | if n < 2^(bits-1) then return n*2^shift end | ||
905 | else | ||
906 | if n >= -(2^(bits-1))-1 then return (n+2^bits)*2^shift end | ||
907 | end | ||
908 | else | ||
909 | if n >= 0 and n <= 2^bits-1 then return n*2^shift end | ||
910 | end | ||
911 | end | ||
912 | werror("out of range immediate `"..imm.."'") | ||
913 | elseif match(imm, "^r([1-3]?[0-9])$") or | ||
914 | match(imm, "^([%w_]+):(r[1-3]?[0-9])$") then | ||
915 | werror("expected immediate operand, got register") | ||
916 | else | ||
917 | waction("IMM", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm) | ||
918 | return 0 | ||
919 | end | ||
920 | end | ||
921 | |||
922 | local function parse_disp(disp) | ||
923 | local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$") | ||
924 | if imm then | ||
925 | local r = parse_gpr(reg) | ||
926 | if r == 0 then werror("cannot use r0 in displacement") end | ||
927 | return r*65536 + parse_imm(imm, 16, 0, 0, true) | ||
928 | end | ||
929 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") | ||
930 | if reg and tailr ~= "" then | ||
931 | local r, tp = parse_gpr(reg) | ||
932 | if r == 0 then werror("cannot use r0 in displacement") end | ||
933 | if tp then | ||
934 | waction("IMM", 32768+16*32, format(tp.ctypefmt, tailr)) | ||
935 | return r*65536 | ||
936 | end | ||
937 | end | ||
938 | werror("bad displacement `"..disp.."'") | ||
939 | end | ||
940 | |||
941 | local function parse_u5disp(disp, scale) | ||
942 | local imm, reg = match(disp, "^(.*)%(([%w_:]+)%)$") | ||
943 | if imm then | ||
944 | local r = parse_gpr(reg) | ||
945 | if r == 0 then werror("cannot use r0 in displacement") end | ||
946 | return r*65536 + parse_imm(imm, 5, 11, scale, false) | ||
947 | end | ||
948 | local reg, tailr = match(disp, "^([%w_:]+)%s*(.*)$") | ||
949 | if reg and tailr ~= "" then | ||
950 | local r, tp = parse_gpr(reg) | ||
951 | if r == 0 then werror("cannot use r0 in displacement") end | ||
952 | if tp then | ||
953 | waction("IMM", scale*1024+5*32+11, format(tp.ctypefmt, tailr)) | ||
954 | return r*65536 | ||
955 | end | ||
956 | end | ||
957 | werror("bad displacement `"..disp.."'") | ||
958 | end | ||
959 | |||
960 | local function parse_label(label, def) | ||
961 | local prefix = sub(label, 1, 2) | ||
962 | -- =>label (pc label reference) | ||
963 | if prefix == "=>" then | ||
964 | return "PC", 0, sub(label, 3) | ||
965 | end | ||
966 | -- ->name (global label reference) | ||
967 | if prefix == "->" then | ||
968 | return "LG", map_global[sub(label, 3)] | ||
969 | end | ||
970 | if def then | ||
971 | -- [1-9] (local label definition) | ||
972 | if match(label, "^[1-9]$") then | ||
973 | return "LG", 10+tonumber(label) | ||
974 | end | ||
975 | else | ||
976 | -- [<>][1-9] (local label reference) | ||
977 | local dir, lnum = match(label, "^([<>])([1-9])$") | ||
978 | if dir then -- Fwd: 1-9, Bkwd: 11-19. | ||
979 | return "LG", lnum + (dir == ">" and 0 or 10) | ||
980 | end | ||
981 | -- extern label (extern label reference) | ||
982 | local extname = match(label, "^extern%s+(%S+)$") | ||
983 | if extname then | ||
984 | return "EXT", map_extern[extname] | ||
985 | end | ||
986 | end | ||
987 | werror("bad label `"..label.."'") | ||
988 | end | ||
989 | |||
990 | ------------------------------------------------------------------------------ | ||
991 | |||
992 | -- Handle opcodes defined with template strings. | ||
993 | map_op[".template__"] = function(params, template, nparams) | ||
994 | if not params then return sub(template, 9) end | ||
995 | local op = tonumber(sub(template, 1, 8), 16) | ||
996 | local n, rs = 1, 26 | ||
997 | |||
998 | -- Limit number of section buffer positions used by a single dasm_put(). | ||
999 | -- A single opcode needs a maximum of 3 positions (rlwinm). | ||
1000 | if secpos+3 > maxsecpos then wflush() end | ||
1001 | local pos = wpos() | ||
1002 | |||
1003 | -- Process each character. | ||
1004 | for p in gmatch(sub(template, 9), ".") do | ||
1005 | if p == "R" then | ||
1006 | rs = rs - 5; op = op + parse_gpr(params[n]) * 2^rs; n = n + 1 | ||
1007 | elseif p == "F" then | ||
1008 | rs = rs - 5; op = op + parse_fpr(params[n]) * 2^rs; n = n + 1 | ||
1009 | elseif p == "A" then | ||
1010 | rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1 | ||
1011 | elseif p == "S" then | ||
1012 | rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, true); n = n + 1 | ||
1013 | elseif p == "I" then | ||
1014 | op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1 | ||
1015 | elseif p == "U" then | ||
1016 | op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1 | ||
1017 | elseif p == "D" then | ||
1018 | op = op + parse_disp(params[n]); n = n + 1 | ||
1019 | elseif p == "2" then | ||
1020 | op = op + parse_u5disp(params[n], 1); n = n + 1 | ||
1021 | elseif p == "4" then | ||
1022 | op = op + parse_u5disp(params[n], 2); n = n + 1 | ||
1023 | elseif p == "8" then | ||
1024 | op = op + parse_u5disp(params[n], 3); n = n + 1 | ||
1025 | elseif p == "C" then | ||
1026 | rs = rs - 5; op = op + parse_cond(params[n]) * 2^rs; n = n + 1 | ||
1027 | elseif p == "X" then | ||
1028 | rs = rs - 5; op = op + parse_cr(params[n]) * 2^(rs+2); n = n + 1 | ||
1029 | elseif p == "W" then | ||
1030 | op = op + parse_cr(params[n]); n = n + 1 | ||
1031 | elseif p == "G" then | ||
1032 | op = op + parse_imm(params[n], 8, 12, 0, false); n = n + 1 | ||
1033 | elseif p == "J" or p == "K" then | ||
1034 | local mode, n, s = parse_label(params[n], false) | ||
1035 | if p == "K" then n = n + 2048 end | ||
1036 | waction("REL_"..mode, n, s, 1) | ||
1037 | n = n + 1 | ||
1038 | elseif p == "0" then | ||
1039 | local mm = 2^rs | ||
1040 | local t = op % mm | ||
1041 | if ((op - t) / mm) % 32 == 0 then werror("cannot use r0") end | ||
1042 | elseif p == "=" or p == "%" then | ||
1043 | local mm = 2^(rs + (p == "%" and 5 or 0)) | ||
1044 | local t = ((op - op % mm) / mm) % 32 | ||
1045 | rs = rs - 5 | ||
1046 | op = op + t * 2^rs | ||
1047 | elseif p == "~" then | ||
1048 | local mm = 2^rs | ||
1049 | local t1l = op % mm | ||
1050 | local t1h = (op - t1l) / mm | ||
1051 | local t2l = t1h % 32 | ||
1052 | local t2h = (t1h - t2l) / 32 | ||
1053 | local t3l = t2h % 32 | ||
1054 | op = ((t2h - t3l + t2l)*32 + t3l)*mm + t1l | ||
1055 | elseif p == "-" then | ||
1056 | rs = rs - 5 | ||
1057 | elseif p == "." then | ||
1058 | -- Ignored. | ||
1059 | else | ||
1060 | assert(false) | ||
1061 | end | ||
1062 | end | ||
1063 | wputpos(pos, op) | ||
1064 | end | ||
1065 | |||
1066 | ------------------------------------------------------------------------------ | ||
1067 | |||
1068 | -- Pseudo-opcode to mark the position where the action list is to be emitted. | ||
1069 | map_op[".actionlist_1"] = function(params) | ||
1070 | if not params then return "cvar" end | ||
1071 | local name = params[1] -- No syntax check. You get to keep the pieces. | ||
1072 | wline(function(out) writeactions(out, name) end) | ||
1073 | end | ||
1074 | |||
1075 | -- Pseudo-opcode to mark the position where the global enum is to be emitted. | ||
1076 | map_op[".globals_1"] = function(params) | ||
1077 | if not params then return "prefix" end | ||
1078 | local prefix = params[1] -- No syntax check. You get to keep the pieces. | ||
1079 | wline(function(out) writeglobals(out, prefix) end) | ||
1080 | end | ||
1081 | |||
1082 | -- Pseudo-opcode to mark the position where the global names are to be emitted. | ||
1083 | map_op[".globalnames_1"] = function(params) | ||
1084 | if not params then return "cvar" end | ||
1085 | local name = params[1] -- No syntax check. You get to keep the pieces. | ||
1086 | wline(function(out) writeglobalnames(out, name) end) | ||
1087 | end | ||
1088 | |||
1089 | -- Pseudo-opcode to mark the position where the extern names are to be emitted. | ||
1090 | map_op[".externnames_1"] = function(params) | ||
1091 | if not params then return "cvar" end | ||
1092 | local name = params[1] -- No syntax check. You get to keep the pieces. | ||
1093 | wline(function(out) writeexternnames(out, name) end) | ||
1094 | end | ||
1095 | |||
1096 | ------------------------------------------------------------------------------ | ||
1097 | |||
1098 | -- Label pseudo-opcode (converted from trailing colon form). | ||
1099 | map_op[".label_1"] = function(params) | ||
1100 | if not params then return "[1-9] | ->global | =>pcexpr" end | ||
1101 | if secpos+1 > maxsecpos then wflush() end | ||
1102 | local mode, n, s = parse_label(params[1], true) | ||
1103 | if mode == "EXT" then werror("bad label definition") end | ||
1104 | waction("LABEL_"..mode, n, s, 1) | ||
1105 | end | ||
1106 | |||
1107 | ------------------------------------------------------------------------------ | ||
1108 | |||
1109 | -- Pseudo-opcodes for data storage. | ||
1110 | map_op[".long_*"] = function(params) | ||
1111 | if not params then return "imm..." end | ||
1112 | for _,p in ipairs(params) do | ||
1113 | local n = tonumber(p) | ||
1114 | if not n then werror("bad immediate `"..p.."'") end | ||
1115 | if n < 0 then n = n + 2^32 end | ||
1116 | wputw(n) | ||
1117 | if secpos+2 > maxsecpos then wflush() end | ||
1118 | end | ||
1119 | end | ||
1120 | |||
1121 | -- Alignment pseudo-opcode. | ||
1122 | map_op[".align_1"] = function(params) | ||
1123 | if not params then return "numpow2" end | ||
1124 | if secpos+1 > maxsecpos then wflush() end | ||
1125 | local align = tonumber(params[1]) | ||
1126 | if align then | ||
1127 | local x = align | ||
1128 | -- Must be a power of 2 in the range (2 ... 256). | ||
1129 | for i=1,8 do | ||
1130 | x = x / 2 | ||
1131 | if x == 1 then | ||
1132 | waction("ALIGN", align-1, nil, 1) -- Action byte is 2**n-1. | ||
1133 | return | ||
1134 | end | ||
1135 | end | ||
1136 | end | ||
1137 | werror("bad alignment") | ||
1138 | end | ||
1139 | |||
1140 | ------------------------------------------------------------------------------ | ||
1141 | |||
1142 | -- Pseudo-opcode for (primitive) type definitions (map to C types). | ||
1143 | map_op[".type_3"] = function(params, nparams) | ||
1144 | if not params then | ||
1145 | return nparams == 2 and "name, ctype" or "name, ctype, reg" | ||
1146 | end | ||
1147 | local name, ctype, reg = params[1], params[2], params[3] | ||
1148 | if not match(name, "^[%a_][%w_]*$") then | ||
1149 | werror("bad type name `"..name.."'") | ||
1150 | end | ||
1151 | local tp = map_type[name] | ||
1152 | if tp then | ||
1153 | werror("duplicate type `"..name.."'") | ||
1154 | end | ||
1155 | -- Add #type to defines. A bit unclean to put it in map_archdef. | ||
1156 | map_archdef["#"..name] = "sizeof("..ctype..")" | ||
1157 | -- Add new type and emit shortcut define. | ||
1158 | local num = ctypenum + 1 | ||
1159 | map_type[name] = { | ||
1160 | ctype = ctype, | ||
1161 | ctypefmt = format("Dt%X(%%s)", num), | ||
1162 | reg = reg, | ||
1163 | } | ||
1164 | wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype)) | ||
1165 | ctypenum = num | ||
1166 | end | ||
1167 | map_op[".type_2"] = map_op[".type_3"] | ||
1168 | |||
1169 | -- Dump type definitions. | ||
1170 | local function dumptypes(out, lvl) | ||
1171 | local t = {} | ||
1172 | for name in pairs(map_type) do t[#t+1] = name end | ||
1173 | sort(t) | ||
1174 | out:write("Type definitions:\n") | ||
1175 | for _,name in ipairs(t) do | ||
1176 | local tp = map_type[name] | ||
1177 | local reg = tp.reg or "" | ||
1178 | out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg)) | ||
1179 | end | ||
1180 | out:write("\n") | ||
1181 | end | ||
1182 | |||
1183 | ------------------------------------------------------------------------------ | ||
1184 | |||
1185 | -- Set the current section. | ||
1186 | function _M.section(num) | ||
1187 | waction("SECTION", num) | ||
1188 | wflush(true) -- SECTION is a terminal action. | ||
1189 | end | ||
1190 | |||
1191 | ------------------------------------------------------------------------------ | ||
1192 | |||
1193 | -- Dump architecture description. | ||
1194 | function _M.dumparch(out) | ||
1195 | out:write(format("DynASM %s version %s, released %s\n\n", | ||
1196 | _info.arch, _info.version, _info.release)) | ||
1197 | dumpactions(out) | ||
1198 | end | ||
1199 | |||
1200 | -- Dump all user defined elements. | ||
1201 | function _M.dumpdef(out, lvl) | ||
1202 | dumptypes(out, lvl) | ||
1203 | dumpglobals(out, lvl) | ||
1204 | dumpexterns(out, lvl) | ||
1205 | end | ||
1206 | |||
1207 | ------------------------------------------------------------------------------ | ||
1208 | |||
1209 | -- Pass callbacks from/to the DynASM core. | ||
1210 | function _M.passcb(wl, we, wf, ww) | ||
1211 | wline, werror, wfatal, wwarn = wl, we, wf, ww | ||
1212 | return wflush | ||
1213 | end | ||
1214 | |||
1215 | -- Setup the arch-specific module. | ||
1216 | function _M.setup(arch, opt) | ||
1217 | g_arch, g_opt = arch, opt | ||
1218 | end | ||
1219 | |||
1220 | -- Merge the core maps and the arch-specific maps. | ||
1221 | function _M.mergemaps(map_coreop, map_def) | ||
1222 | setmetatable(map_op, { __index = map_coreop }) | ||
1223 | setmetatable(map_def, { __index = map_archdef }) | ||
1224 | return map_op, map_def | ||
1225 | end | ||
1226 | |||
1227 | return _M | ||
1228 | |||
1229 | ------------------------------------------------------------------------------ | ||
1230 | |||