GenArch: gen_ppc_arch.py

File gen_ppc_arch.py, 51.3 kB (added by peter@tortall.net, 1 year ago)

Example PPC generator (uses gen_arch.py)

Line 
1 #! /usr/bin/env python2.4
2 # Yasm PowerPC Architecture Generator
3 # $Id$
4 #
5 #  Copyright (C) 2006  Peter Johnson
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
9 # are met:
10 # 1. Redistributions of source code must retain the above copyright
11 #    notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 #    notice, this list of conditions and the following disclaimer in the
14 #    documentation and/or other materials provided with the distribution.
15 #
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
17 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
20 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 # POSSIBILITY OF SUCH DAMAGE.
27
28 from gen_arch import *
29
30 # Nonzero lsb_bit also switches meaning of field "pos" parameter from
31 # specifying LSB bit position to specifying MSB bit position.
32 config_arch(lsb_bit = 31,
33             insn_bit_width = 32,
34             machines = ["ppc"],
35             parsers = ["nasm"])
36
37 #
38 # Registers
39 #
40
41 for x in range(32):
42     add_register("r%d" % x, "GPR", x)
43 for x in range(32):
44     add_register("f%d" % x, "FPR", x)
45 for x in range(8):
46     add_register("cr%d" % x, "CR", x)
47 add_register("lt", "CR_BIT", 0)
48 add_register("gt", "CR_BIT", 1)
49 add_register("eq", "CR_BIT", 2)
50 add_register("so", "CR_BIT", 3)
51 add_register("un", "CR_BIT", 3)
52
53 #
54 # Fields
55 #
56
57 add_field("AA", msb=30, lsb=30)
58 add_field("BA", msb=11, lsb=15)
59 add_field("BB", msb=16, lsb=20)
60 add_field("BD", msb=16, lsb=29, rshift=2, pc_rel=True, save="imm")
61 add_field("BD_ABS", msb=16, lsb=29, rshift=2, pc_rel=False, signed=True,
62           save="imm")
63 add_field("BF", msb=6, lsb=8)
64 add_field("BFA", msb=11, lsb=13)
65 add_field("BH", msb=19, lsb=20)
66 add_field("BI", msb=11, lsb=15)
67 add_field("BI_CR", msb=11, lsb=13)
68 add_field("BI_CC", msb=14, lsb=15)
69 add_field("BO", msb=6, lsb=10)
70 add_field("BT", msb=6, lsb=10)
71 add_field("D", msb=16, lsb=31)
72 add_field("DS", msb=16, lsb=29)
73 add_field("FLM", msb=7, lsb=14)
74 add_field("FRA", msb=11, lsb=15)
75 add_field("FRB", msb=16, lsb=20)
76 add_field("FRC", msb=21, lsb=25)
77 add_field("FRS", msb=6, lsb=10)
78 add_field("FRT", msb=6, lsb=10)
79 add_field("FXM", msb=12, lsb=19)
80 #L (10 or 15)
81 add_field("L", msb=9, lsb=10)
82 add_field("LEV", msb=20, lsb=26)
83 add_field("LI", msb=6, lsb=29, rshift=2, pc_rel=True, save="imm")
84 add_field("LI_ABS", msb=6, lsb=29, rshift=2, pc_rel=False, signed=True,
85           save="imm")
86 add_field("LK", msb=31, lsb=31)
87 add_field("MB", msb=21, lsb=25)
88 add_field("ME", msb=26, lsb=30)
89 add_field("mb", ooo=[(26, 26), (21, 25)])
90 add_field("me", ooo=[(26, 26), (21, 25)])
91 add_field("NB", msb=16, lsb=20)
92 add_field("OPCD", msb=0, lsb=5)
93 add_field("OE", msb=21, lsb=21)
94 add_field("RA", msb=11, lsb=15)
95 add_field("RB", msb=16, lsb=20)
96 add_field("Rc", msb=31, lsb=31)
97 add_field("RS", msb=6, lsb=10)
98 add_field("RT", msb=6, lsb=10)
99 add_field("SH", msb=16, lsb=20)
100 add_field("sh", ooo=[(30, 30), (16, 20)])
101 add_field("SI", msb=16, lsb=31, signed=True, save="imm")
102 add_field("SI_neg", msb=16, lsb=31, signed=True, save="imm", special="-X")
103 add_field("spr", ooo=[(16, 20), (11, 15)])
104 add_field("SR", msb=12, lsb=15)
105 add_field("TBR", msb=11, lsb=20)
106 add_field("TH", msb=9, lsb=10)
107 add_field("TO", msb=6, lsb=10)
108 add_field("U", msb=16, lsb=19, save="imm")
109 add_field("UI", msb=16, lsb=31, signed=False, save="imm")
110 add_field("DS_XO", msb=30, lsb=31)
111 add_field("X_XO", msb=21, lsb=30) # Also XL, XFX, XFL
112 add_field("XS_XO", msb=21, lsb=29)
113 add_field("XO_XO", msb=22, lsb=30)
114 add_field("A_XO", msb=26, lsb=30)
115 add_field("MD_XO", msb=27, lsb=29)
116 add_field("MDS_XO", msb=27, lsb=30)
117
118 add_field("bit11", msb=11, lsb=11)
119
120 add_field("cr_bx", to_fields=["BT", "BA", "BB"])
121 add_field("cr_by", to_fields=["BA", "BB"])
122 add_field("rs_rb", to_fields=["RS", "RB"])
123
124 #
125 # Instructions
126 #
127
128 # Page 23
129
130 add_insn("b", "Branch (relative)",
131          ["target_addr"],
132          ["imm"],
133          dict(OPCD=18, AA=0, LK=0),
134          dict(LI="target_addr"))
135
136 add_insn("ba", "Branch (absolute)",
137          ["target_addr"],
138          ["imm"],
139          dict(OPCD=18, AA=1, LK=0),
140          dict(LI_ABS="target_addr"))
141
142 add_derived_insn("bl", "b", update_fields_fixed=dict(LK=1))
143 add_derived_insn("bla", "ba", update_fields_fixed=dict(LK=1))
144
145 add_insn("bc", "Branch conditional (relative)",
146          ["BO", "BI", "target_addr"],
147          ["imm", "imm", "imm"],
148          dict(OPCD=16, AA=0, LK=0),
149          dict(BO="BO", BI="BI", BD="target_addr"))
150
151 add_insn("bca", "Branch conditional (absolute)",
152          ["BO", "BI", "target_addr"],
153          ["imm", "imm", "imm"],
154          dict(OPCD=16, AA=1, LK=0),
155          dict(BO="BO", BI="BI", BD_ABS="target_addr"))
156
157 add_derived_insn("bcl", "bc", update_fields_fixed=dict(LK=1))
158 add_derived_insn("bcla", "bca", update_fields_fixed=dict(LK=1))
159
160 # Page 24
161
162 add_insn("bclr", "Branch Conditional to Link Register",
163          ["BO", "BI", "BH"],
164          ["imm", "imm", "imm"],
165          dict(OPCD=19, X_XO=16, LK=0))
166
167 add_insn("bclr", "Branch Conditional to Link Register",
168          ["BO", "BI"],
169          ["imm", "imm"],
170          dict(OPCD=19, BH=0, X_XO=16, LK=0))
171
172 add_derived_insn("bclrl", "bclr", update_fields_fixed=dict(LK=1))
173
174 add_insn("bcctr", "Branch Conditional to Count Register",
175          ["BO", "BI", "BH"],
176          ["imm", "imm", "imm"],
177          dict(OPCD=19, X_XO=528, LK=0))
178
179 add_insn("bcctr", "Branch Conditional to Count Register",
180          ["BO", "BI"],
181          ["imm", "imm"],
182          dict(OPCD=19, BH=0, X_XO=528, LK=0))
183
184 add_derived_insn("bcctrl", "bcctr", update_fields_fixed=dict(LK=1))
185
186 # Extended Mnemonics (Page 144)
187
188 branch_condition_codes = dict(lt=(12, 0), le=(4, 1),
189                               eq=(12, 2), ge=(4, 0),
190                               gt=(12, 1),
191                               nl=(4, 0), ne=(4, 2), ng=(4, 1),
192                               so=(12, 3), ns=(4, 3),
193                               un=(12, 3), nu=(4, 3))
194 for k, v in branch_condition_codes.iteritems():
195     for s in ["bc", "bca"]:
196         # Replace the second letter (the "c") with the condition code
197         # One operand version (default to CR0)
198         add_derived_insn(s[0]+k+s[2:], s,
199                          fix_operands=dict(BO=v[0], BI=v[1]))
200         # Two operand version (CR specified)
201         add_derived_insn(s[0]+k+s[2:], s,
202                          operands=["CR", "target_addr"],
203                          operand_types=["imm", "imm"],
204                          fields_operands=dict(BI_CR="CR", BD="target_addr"),
205                          update_fields_fixed=dict(BO=v[0], BI_CC=v[1]))
206     for s in ["bclr", "bcctr", "bcl", "bcla", "bclrl", "bcctrl"]:
207         pass
208         # Replace the second letter (the "c") with the condition code
209         # Zero operand version (default to CR0)
210 #        add_derived_one_insn(s[0]+k+s[2:], s,
211 #                             fix_operands=dict(BO=v[0], BI=v[1], BH=0))
212         # One operand version (CR specified)
213 #        add_derived_one_insn(s[0]+k+s[2:], s,
214 #                             operands=["CR"],
215 #                             operand_types=["imm"],
216 #                             fields_operands=dict(BI_CR="CR"),
217 #                             update_fields_fixed=dict(BO=v[0], BI_CC=v[1],
218 #                                                      BH=0))
219         # Two operand version (CR and BH specified)
220 #        add_derived_one_insn(s[0]+k+s[2:], s,
221 #                             operands=["CR", "BH"],
222 #                             operand_types=["imm", "imm"],
223 #                             fields_operands=dict(BI_CR="CR", BH="BH"),
224 #                             update_fields_fixed=dict(BO=v[0], BI_CC=v[1]))
225
226 # Page 25
227
228 add_insn("sc", "System call", ["LEV"], ["imm"], dict(OPCD=17, AA=1))
229 add_insn("sc", "System call", [], [], dict(OPCD=17, AA=1))
230
231 # Page 26
232
233 add_insn("crand", "Condition Register AND",
234          ["BT", "BA", "BB"],
235          ["imm", "imm", "imm"],
236          dict(OPCD=19, X_XO=257))
237
238 add_insn("cror", "Condition Register OR",
239          ["BT", "BA", "BB"],
240          ["imm", "imm", "imm"],
241          dict(OPCD=19, X_XO=449))
242
243 add_insn("crxor", "Condition Register XOR",
244          ["BT", "BA", "BB"],
245          ["imm", "imm", "imm"],
246          dict(OPCD=19, X_XO=193))
247
248 add_insn("crnand", "Condition Register NAND",
249          ["BT", "BA", "BB"],
250          ["imm", "imm", "imm"],
251          dict(OPCD=19, X_XO=225))
252
253 # Page 27
254
255 add_insn("crnor", "Condition Register NOR",
256          ["BT", "BA", "BB"],
257          ["imm", "imm", "imm"],
258          dict(OPCD=19, X_XO=33))
259
260 add_insn("creqv", "Condition Register Equivalent",
261          ["BT", "BA", "BB"],
262          ["imm", "imm", "imm"],
263          dict(OPCD=19, X_XO=289))
264
265 add_insn("crandc", "Condition Register AND with Complement",
266          ["BT", "BA", "BB"],
267          ["imm", "imm", "imm"],
268          dict(OPCD=19, X_XO=129))
269
270 add_insn("crorc", "Condition Register OR with Complement",
271          ["BT", "BA", "BB"],
272          ["imm", "imm", "imm"],
273          dict(OPCD=19, X_XO=417))
274
275 # Page 28
276
277 add_insn("mcrf", "Move Condition Register Field",
278          ["BF", "BFA"],
279          ["imm", "imm"],
280          dict(OPCD=19, X_XO=0))
281
282 # Extended Mnemonics (Page 147)
283 add_derived_insn("crset", "creqv",
284                  operands=["bx"],
285                  operand_types=["imm"],
286                  fields_operands=dict(cr_bx="bx"))
287
288 add_derived_insn("crclr", "crxor",
289                  operands=["bx"],
290                  operand_types=["imm"],
291                  fields_operands=dict(cr_bx="bx"))
292
293 add_derived_insn("crmove", "cror",
294                  operands=["bx", "by"],
295                  operand_types=["imm", "imm"],
296                  fields_operands=dict(BT="bx", cr_by="by"))
297
298 add_derived_insn("crnot", "crnor",
299                  operands=["bx", "by"],
300                  operand_types=["imm", "imm"],
301                  fields_operands=dict(BT="bx", cr_by="by"))
302
303 # Page 32
304
305 # FIXME: D/RA should be one mem operand
306 add_insn("lbz", "Load Byte and Zero",
307          ["RT", "D", "RA"],
308          ["gpr", "mem_imm", "mem_reg"],
309          dict(OPCD=34))
310
311 add_insn("lbzx", "Load Byte and Zero Indexed",
312          ["RT", "RA", "RB"],
313          ["gpr", "gpr", "gpr"],
314          dict(OPCD=31, X_XO=87))
315
316 # FIXME: D/RA should be one mem operand
317 add_insn("lbzu", "Load Byte and Zero with Update",
318          ["RT", "D", "RA"],
319          ["gpr", "mem_imm", "mem_reg"],
320          dict(OPCD=35))
321
322 add_insn("lbzux", "Load Byte and Zero with Update Indexed",
323          ["RT", "RA", "RB"],
324          ["gpr", "gpr", "gpr"],
325          dict(OPCD=31, X_XO=119))
326
327 # Page 33
328
329 # FIXME: D/RA should be one mem operand
330 add_insn("lhz", "Load Halfword and Zero",
331          ["RT", "D", "RA"],
332          ["gpr", "mem_imm", "mem_reg"],
333          dict(OPCD=40))
334
335 add_insn("lhzx", "Load Halfword and Zero Indexed",
336          ["RT", "RA", "RB"],
337          ["gpr", "gpr", "gpr"],
338          dict(OPCD=31, X_XO=279))
339
340 # FIXME: D/RA should be one mem operand
341 add_insn("lhzu", "Load Halfword and Zero with Update",
342          ["RT", "D", "RA"],
343          ["gpr", "mem_imm", "mem_reg"],
344          dict(OPCD=41))
345
346 add_insn("lhzux", "Load Halfword and Zero with Update Indexed",
347          ["RT", "RA", "RB"],
348          ["gpr", "gpr", "gpr"],
349          dict(OPCD=31, X_XO=311))
350
351 # Page 34
352
353 # FIXME: D/RA should be one mem operand
354 add_insn("lha", "Load Halfword Algebraic",
355          ["RT", "D", "RA"],
356          ["gpr", "mem_imm", "mem_reg"],
357          dict(OPCD=42))
358
359 add_insn("lhax", "Load Halfword Algebraic Indexed",
360          ["RT", "RA", "RB"],
361          ["gpr", "gpr", "gpr"],
362          dict(OPCD=31, X_XO=343))
363
364 # FIXME: D/RA should be one mem operand
365 add_insn("lhau", "Load Halfword Algebraic with Update",
366          ["RT", "D", "RA"],
367          ["gpr", "mem_imm", "mem_reg"],
368          dict(OPCD=43))
369
370 add_insn("lhaux", "Load Halfword Algebraic with Update Indexed",
371          ["RT", "RA", "RB"],
372          ["gpr", "gpr", "gpr"],
373          dict(OPCD=31, X_XO=375))
374
375 # Page 35
376
377 # FIXME: D/RA should be one mem operand
378 add_insn("lwz", "Load Word and Zero",
379          ["RT", "D", "RA"],
380          ["gpr", "mem_imm", "mem_reg"],
381          dict(OPCD=32))
382
383 add_insn("lwzx", "Load Word and Zero Indexed",
384          ["RT", "RA", "RB"],
385          ["gpr", "gpr", "gpr"],
386          dict(OPCD=31, X_XO=23))
387
388 # FIXME: D/RA should be one mem operand
389 add_insn("lwzu", "Load Word and Zero with Update",
390          ["RT", "D", "RA"],
391          ["gpr", "mem_imm", "mem_reg"],
392          dict(OPCD=33))
393
394 add_insn("lwzux", "Load Word and Zero with Update Indexed",
395          ["RT", "RA", "RB"],
396          ["gpr", "gpr", "gpr"],
397          dict(OPCD=31, X_XO=55))
398
399 # Page 36
400
401 # FIXME: D/RA should be one mem operand
402 add_insn("lwa", "Load Word Algebraic",
403          ["RT", "DS", "RA"],
404          ["gpr", "mem_imm", "mem_reg"],
405          dict(OPCD=58, DS_XO=2))
406
407 add_insn("lwax", "Load Word Algebraic Indexed",
408          ["RT", "RA", "RB"],
409          ["gpr", "gpr", "gpr"],
410          dict(OPCD=31, X_XO=341))
411
412 add_insn("lwaux", "Load Word Algebraic with Update Indexed",
413          ["RT", "RA", "RB"],
414          ["gpr", "gpr", "gpr"],
415          dict(OPCD=31, X_XO=373))
416
417 # Page 37
418
419 # FIXME: D/RA should be one mem operand
420 add_insn("ld", "Load Doubleword",
421          ["RT", "DS", "RA"],
422          ["gpr", "mem_imm", "mem_reg"],
423          dict(OPCD=58, DS_XO=0))
424
425 add_insn("ldx", "Load Doubleword Indexed",
426          ["RT", "RA", "RB"],
427          ["gpr", "gpr", "gpr"],
428          dict(OPCD=31, X_XO=21))
429
430 # FIXME: D/RA should be one mem operand
431 add_insn("ldu", "Load Doubleword with Update",
432          ["RT", "DS", "RA"],
433          ["gpr", "mem_imm", "mem_reg"],
434          dict(OPCD=58, DS_XO=1))
435
436 add_insn("ldux", "Load Doubleword with Update Indexed",
437          ["RT", "RA", "RB"],
438          ["gpr", "gpr", "gpr"],
439          dict(OPCD=31, X_XO=53))
440
441 # Page 38
442
443 # FIXME: D/RA should be one mem operand
444 add_insn("stb", "Store Byte",
445          ["RS", "D", "RA"],
446          ["gpr", "mem_imm", "mem_reg"],
447          dict(OPCD=38))
448
449 add_insn("stbx", "Store Byte Indexed",
450          ["RS", "RA", "RB"],
451          ["gpr", "gpr", "gpr"],
452          dict(OPCD=31, X_XO=215))
453
454 # FIXME: D/RA should be one mem operand
455 add_insn("stbu", "Store Byte with Update",
456          ["RS", "D", "RA"],
457          ["gpr", "mem_imm", "mem_reg"],
458          dict(OPCD=39))
459
460 add_insn("stbux", "Store Byte with Update Indexed",
461          ["RS", "RA", "RB"],
462          ["gpr", "gpr", "gpr"],
463          dict(OPCD=31, X_XO=247))
464
465 # Page 39
466
467 # FIXME: D/RA should be one mem operand
468 add_insn("sth", "Store Halfword",
469          ["RS", "D", "RA"],
470          ["gpr", "mem_imm", "mem_reg"],
471          dict(OPCD=44))
472
473 add_insn("sthx", "Store Halfword Indexed",
474          ["RS", "RA", "RB"],
475          ["gpr", "gpr", "gpr"],
476          dict(OPCD=31, X_XO=407))
477
478 # FIXME: D/RA should be one mem operand
479 add_insn("sthu", "Store Halfword with Update",
480          ["RS", "D", "RA"],
481          ["gpr", "mem_imm", "mem_reg"],
482          dict(OPCD=45))
483
484 add_insn("sthux", "Store Halfword with Update Indexed",
485          ["RS", "RA", "RB"],
486          ["gpr", "gpr", "gpr"],
487          dict(OPCD=31, X_XO=439))
488
489 # Page 40
490
491 # FIXME: D/RA should be one mem operand
492 add_insn("stw", "Store Word",
493          ["RS", "D", "RA"],
494          ["gpr", "mem_imm", "mem_reg"],
495          dict(OPCD=36))
496
497 add_insn("stwx", "Store Word Indexed",
498          ["RS", "RA", "RB"],
499          ["gpr", "gpr", "gpr"],
500          dict(OPCD=31, X_XO=151))
501
502 # FIXME: D/RA should be one mem operand
503 add_insn("stwu", "Store Word with Update",
504          ["RS", "D", "RA"],
505          ["gpr", "mem_imm", "mem_reg"],
506          dict(OPCD=37))
507
508 add_insn("stwux", "Store Word with Update Indexed",
509          ["RS", "RA", "RB"],
510          ["gpr", "gpr", "gpr"],
511          dict(OPCD=31, X_XO=183))
512
513 # Page 41
514
515 # FIXME: D/RA should be one mem operand
516 add_insn("std", "Store Doubleword",
517          ["RS", "DS", "RA"],
518          ["gpr", "mem_imm", "mem_reg"],
519          dict(OPCD=62, DS_XO=0))
520
521 add_insn("stdx", "Store Doubleword Indexed",
522          ["RS", "RA", "RB"],
523          ["gpr", "gpr", "gpr"],
524          dict(OPCD=31, X_XO=149))
525
526 # FIXME: D/RA should be one mem operand
527 add_insn("stdu", "Store Doubleword with Update",
528          ["RS", "DS", "RA"],
529          ["gpr", "mem_imm", "mem_reg"],
530          dict(OPCD=62, DS_XO=1))
531
532 add_insn("stdux", "Store Doubleword with Update Indexed",
533          ["RS", "RA", "RB"],
534          ["gpr", "gpr", "gpr"],
535          dict(OPCD=31, X_XO=181))
536
537 # Page 42
538
539 add_insn("lhbrx", "Load Halfword Byte-Reversed Indexed",
540          ["RT", "RA", "RB"],
541          ["gpr", "gpr", "gpr"],
542          dict(OPCD=31, X_XO=790))
543
544 add_insn("lwbrx", "Load Word Byte-Reversed Indexed",
545          ["RT", "RA", "RB"],
546          ["gpr", "gpr", "gpr"],
547          dict(OPCD=31, X_XO=534))
548
549 # Page 43
550
551 add_insn("sthbrx", "Store Halfword Byte-Reversed Indexed",
552          ["RT", "RA", "RB"],
553          ["gpr", "gpr", "gpr"],
554          dict(OPCD=31, X_XO=918))
555
556 add_insn("stwbrx", "Store Word Byte-Reversed Indexed",
557          ["RT", "RA", "RB"],
558          ["gpr", "gpr", "gpr"],
559          dict(OPCD=31, X_XO=662))
560
561 # Page 44
562
563 # FIXME: D/RA should be one mem operand
564 add_insn("lmw", "Load Multiple Word",
565          ["RT", "D", "RA"],
566          ["gpr", "mem_imm", "mem_reg"],
567          dict(OPCD=46))
568
569 # FIXME: D/RA should be one mem operand
570 add_insn("stmw", "Store Multiple Word",
571          ["RS", "D", "RA"],
572          ["gpr", "mem_imm", "mem_reg"],
573          dict(OPCD=47))
574
575 # Page 46
576
577 add_insn("lswi", "Load String Word Immediate",
578          ["RT", "RA", "NB"],
579          ["gpr", "gpr", "imm"],
580          dict(OPCD=31, X_XO=597))
581
582 add_insn("lswx", "Load String Word Indexed",
583          ["RT", "RA", "RB"],
584          ["gpr", "gpr", "gpr"],
585          dict(OPCD=31, X_XO=533))
586
587 # Page 47
588
589 add_insn("stswi", "Store String Word Immediate",
590          ["RS", "RA", "NB"],
591          ["gpr", "gpr", "imm"],
592          dict(OPCD=31, X_XO=725))
593
594 add_insn("stswx", "Store String Word Indexed",
595          ["RS", "RA", "RB"],
596          ["gpr", "gpr", "gpr"],
597          dict(OPCD=31, X_XO=661))
598
599 # Page 49
600
601 add_insn("addi", "Add Immediate",
602          ["RT", "RA", "SI"],
603          ["gpr", "gpr", "imm"],
604          dict(OPCD=14))
605
606 add_insn("addis", "Add Immediate Shifted",
607          ["RT", "RA", "SI"],
608          ["gpr", "gpr", "imm"],
609          dict(OPCD=15))
610
611 # Extended Mnemonics (Page 153)
612
613 add_derived_insn("li", "addi", descr="Load Immediate",
614                  fix_operands=dict(RA=0))
615 add_derived_insn("lis", "addis", descr="Load Immediate Shifted",
616                  fix_operands=dict(RA=0))
617
618 # FIXME: D/RA should be one mem operand
619 add_derived_insn("la", "addi", descr="Load Address",
620                  operands=["Rx", "D", "Ry"],
621                  operand_types=["gpr", "imm", "gpr"],
622                  fields_operands=dict(RT="Rx", RA="Ry", SI="D"))
623
624 # Page 50
625
626 add_insn("add", "Add",
627          ["RT", "RA", "RB"],
628          ["gpr", "gpr", "gpr"],
629          dict(OPCD=31, XO_XO=266, OE=0, Rc=0))
630 add_derived_insn("add.", "add", update_fields_fixed=dict(OE=0, Rc=1))
631 add_derived_insn("addo", "add", update_fields_fixed=dict(OE=1, Rc=0))
632 add_derived_insn("addo.", "add", update_fields_fixed=dict(OE=1, Rc=1))
633
634 add_insn("subf", "Subtract From",
635          ["RT", "RA", "RB"],
636          ["gpr", "gpr", "gpr"],
637          dict(OPCD=31, XO_XO=40, OE=0, Rc=0))
638 add_derived_insn("subf.", "subf", update_fields_fixed=dict(OE=0, Rc=1))
639 add_derived_insn("subfo", "subf", update_fields_fixed=dict(OE=1, Rc=0))
640 add_derived_insn("subfo.", "subf", update_fields_fixed=dict(OE=1, Rc=1))
641
642 add_insn("addic", "Add Immediate Carrying",
643          ["RT", "RA", "SI"],
644          ["gpr", "gpr", "imm"],
645          dict(OPCD=12))
646
647 add_insn("addic.", "Add Immediate Carrying and Record",
648          ["RT", "RA", "SI"],
649          ["gpr", "gpr", "imm"],
650          dict(OPCD=13))
651
652 # Page 51
653
654 add_insn("subfic", "Subtract From Immediate Carrying",
655          ["RT", "RA", "SI"],
656          ["gpr", "gpr", "imm"],
657          dict(OPCD=8))
658
659 add_insn("addc", "Add Carrying",
660          ["RT", "RA", "RB"],
661          ["gpr", "gpr", "gpr"],
662          dict(OPCD=31, XO_XO=10, OE=0, Rc=0))
663 add_derived_insn("addc.", "addc", update_fields_fixed=dict(OE=0, Rc=1))
664 add_derived_insn("addco", "addc", update_fields_fixed=dict(OE=1, Rc=0))
665 add_derived_insn("addco.", "addc", update_fields_fixed=dict(OE=1, Rc=1))
666
667 add_insn("subfc", "Subtract From Carrying",
668          ["RT", "RA", "RB"],
669          ["gpr", "gpr", "gpr"],
670          dict(OPCD=31, XO_XO=8, OE=0, Rc=0))
671 add_derived_insn("subfc.", "subfc", update_fields_fixed=dict(OE=0, Rc=1))
672 add_derived_insn("subfco", "subfc", update_fields_fixed=dict(OE=1, Rc=0))
673 add_derived_insn("subfco.", "subfc", update_fields_fixed=dict(OE=1, Rc=1))
674
675 # Extended Mnemonics (Page 147)
676
677 add_derived_insn("subi", "addi",
678                  operands=["Rx", "Ry", "value"],
679                  fields_operands=dict(RT="Rx", RA="Ry", SI_neg="value"))
680 add_derived_insn("subis", "addis",
681                  operands=["Rx", "Ry", "value"],
682                  fields_operands=dict(RT="Rx", RA="Ry", SI_neg="value"))
683 add_derived_insn("subic", "addic",
684                  operands=["Rx", "Ry", "value"],
685                  fields_operands=dict(RT="Rx", RA="Ry", SI_neg="value"))
686 add_derived_insn("subic.", "addic.",
687                  operands=["Rx", "Ry", "value"],
688                  fields_operands=dict(RT="Rx", RA="Ry", SI_neg="value"))
689
690 # Extended Mnemonics (Page 148)
691
692 #add_macro_insn("sub", "Subtract",
693 #               ["Rx", "Ry", "Rz"],
694 #               ["gpr", "gpr", "gpr"],
695 #               "subf", ["Rx", "Rz", "Ry"])
696 add_derived_insn("sub", "subf",
697                  operands=["Rx", "Ry", "Rz"],
698                  fields_operands=dict(RT="Rx", RA="Rz", RB="Ry"))
699 add_derived_insn("sub.", "sub", update_fields_fixed=dict(OE=0, Rc=1))
700 add_derived_insn("subo", "sub", update_fields_fixed=dict(OE=1, Rc=0))
701 add_derived_insn("subo.", "sub", update_fields_fixed=dict(OE=1, Rc=1))
702
703 add_derived_insn("subc", "subfc",
704                  operands=["Rx", "Ry", "Rz"],
705                  fields_operands=dict(RT="Rx", RA="Rz", RB="Ry"))
706 add_derived_insn("subc.", "subc", update_fields_fixed=dict(OE=0, Rc=1))
707 add_derived_insn(