radare2/libr/parse/p/parse_ppc_pseudo.c
Giovanni 858dfea170 Fix #6411 - pseudo for AVR (#7978)
* avr.pseudo

* tabs and flavour
2017-07-20 21:36:26 +02:00

1749 lines
58 KiB
C

/* radare - LGPL - Copyright 2015-2017 - pancake */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <r_lib.h>
#include <r_util.h>
#include <r_flag.h>
#include <r_anal.h>
#include <r_parse.h>
#ifndef PFMT32x
#define PFMT32x "lx"
#endif
#define SPR_MQ 0x0
#define SPR_XER 0x1
#define SPR_RTCU 0x4
#define SPR_RTCL 0x5
#define SPR_LR 0x8
#define SPR_CTR 0x9
#define SPR_DSISR 0x12
#define SPR_DAR 0x13
#define SPR_DEC 0x16
#define SPR_SDR1 0x19
#define SPR_SRR0 0x1a
#define SPR_SRR1 0x1b
#define SPR_VRSAVE 0x100
#define SPR_TBRL 0x10c
#define SPR_TBRU 0x10d
#define SPR_SPRG0 0x110
#define SPR_SPRG1 0x111
#define SPR_SPRG2 0x112
#define SPR_SPRG3 0x113
#define SPR_EAR 0x11a
#define SPR_TBL 0x11c
#define SPR_TBU 0x11d
#define SPR_PVR 0x11f
#define SPR_SPEFSCR 0x200
#define SPR_IBAT0U 0x210
#define SPR_IBAT0L 0x211
#define SPR_IBAT1U 0x212
#define SPR_IBAT1L 0x213
#define SPR_IBAT2U 0x214
#define SPR_IBAT2L 0x215
#define SPR_IBAT3U 0x216
#define SPR_IBAT3L 0x217
#define SPR_DBAT0U 0x218
#define SPR_DBAT0L 0x219
#define SPR_DBAT1U 0x21a
#define SPR_DBAT1L 0x21b
#define SPR_DBAT2U 0x21c
#define SPR_DBAT2L 0x21d
#define SPR_DBAT3U 0x21e
#define SPR_DBAT3L 0x21f
#define SPR_UMMCR0 0x3a8
#define SPR_UMMCR1 0x3ac
#define SPR_UPMC1 0x3a9
#define SPR_UPMC2 0x3aa
#define SPR_USIA 0x3ab
#define SPR_UPMC3 0x3ad
#define SPR_UPMC4 0x3ae
#define SPR_MMCR0 0x3b8
#define SPR_PMC1 0x3b9
#define SPR_PMC2 0x3ba
#define SPR_SIA 0x3bb
#define SPR_MMCR1 0x3bc
#define SPR_PMC3 0x3bd
#define SPR_PMC4 0x3be
#define SPR_SDA 0x3bf
#define SPR_DMISS 0x3d0
#define SPR_DCMP 0x3d1
#define SPR_HASH1 0x3d2
#define SPR_HASH2 0x3d3
#define SPR_IMISS 0x3d4
#define SPR_ICMP 0x3d5
#define SPR_RPA 0x3d6
#define SPR_HID0 0x3f0 /* Hardware Implementation Register 0 */
#define SPR_HID1 0x3f1 /* Hardware Implementation Register 1 */
#define SPR_IABR 0x3f2
#define SPR_HID2 0x3f3 /* Hardware Implementation Register 2 */
#define SPR_HID4 0x3f4 /* Hardware Implementation Register 4 */
#define SPR_DABR 0x3f5
#define SPR_HID5 0x3f6 /* Hardware Implementation Register 5 */
#define SPR_HID6 0x3f9 /* Hardware Implementation Register 6 */
//#define SPR_L2CR 0x3f9
#define SPR_ICTC 0x3fb
#define SPR_THRM1 0x3fc
#define SPR_THRM2 0x3fd
#define SPR_THRM3 0x3fe
#define SPR_PIR 0x3ff
ut64 mask64(ut64 mb, ut64 me) {
int i;
ut64 mask = 0;
if (mb > 63 || me > 63) {
return mask;
}
if (mb < (me + 1)) {
for(i = mb; i <= me ; i++) {
mask = mask | (ut64)(1LL << (63 - i));
}
} else if (mb == (me + 1)) {
mask = 0xffffffffffffffffull;
} else if (mb > (me + 1)) {
ut64 lo = mask64(0, me);
ut64 hi = mask64(mb, 63);
mask = lo | hi;
}
return mask;
}
static const char* cmask64(const char *mb_c, const char *me_c){
static char cmask[32];
ut64 mb = 0;
ut64 me = 0;
if (mb_c) mb = atol(mb_c);
if (me_c) me = atol(me_c);
snprintf(cmask, sizeof(cmask), "0x%"PFMT64x"", mask64(mb, me));
return cmask;
}
static ut32 mask32(ut32 mb, ut32 me) {
int i;
ut32 mask = 0;
if (mb > 31 || me > 31) {
return mask;
}
if (mb < (me + 1)) {
for(i = mb; i <= me ; i++) {
mask = mask | (ut32)(1LL << (31 - i));
}
} else if (mb == (me + 1)) {
mask = 0xffffffffu;
} else if (mb > (me + 1)) {
ut32 lo = mask32(0, me);
ut32 hi = mask32(mb, 31);
mask = lo | hi;
}
return mask;
}
static const char* cmask32(const char *mb_c, const char *me_c){
static char cmask[32];
ut32 mb = 32;
ut32 me = 32;
if (mb_c) mb += atol(mb_c);
if (me_c) me += atol(me_c);
snprintf (cmask, sizeof(cmask), "0x%x", mask32 (mb, me));
return cmask;
}
static const char* inv_mask64(const char *mb_c, const char *sh){
static char cmask[32];
ut64 mb = 0;
ut64 me = 0;
if (mb_c) {
mb = atol(mb_c);
}
if (sh) {
me = atol(sh);
}
snprintf(cmask, sizeof(cmask), "0x%"PFMT64x"", mask64 (mb, ~me));
return cmask;
}
#if 0
static const char* inv_mask32(const char *mb_c, const char *sh) {
static char cmask[32];
ut32 mb = 0;
ut32 me = 0;
if (mb_c) {
mb = atol (mb_c);
}
if (sh) {
me = atol (sh);
}
snprintf (cmask, sizeof(cmask), "0x%x", mask32 (mb, ~me));
return cmask;
}
#endif
static int can_replace(const char *str, int idx, int max_operands) {
if (str[idx] < 'A' || str[idx] > 'J') {
return false;
}
if (str[idx + 1] != '\x00' && str[idx + 1] <= 'J' && str[idx + 1] >= 'A') {
return false;
}
if ((int)((int)str[idx] - 0x41) > max_operands) {
return false;
}
return true;
}
static const char* getspr(const char *reg) {
static char cspr[16];
ut32 spr = 0;
if (!reg) return NULL;
spr = strtol(reg, NULL, 16);
if(spr > 9999) return NULL; //just to avoid overflows..
switch (spr) {
case SPR_MQ:
return "mq";
case SPR_XER:
return "xer";
case SPR_RTCU:
return "rtcu";
case SPR_RTCL:
return "rtcl";
case SPR_LR:
return "lr";
case SPR_CTR:
return "ctr";
case SPR_DSISR:
return "dsisr";
case SPR_DAR:
return "dar";
case SPR_DEC:
return "dec";
case SPR_SDR1:
return "sdr1";
case SPR_SRR0:
return "srr0";
case SPR_SRR1:
return "srr1";
case SPR_VRSAVE:
return "vrsave";
case SPR_TBRL:
return "tbrl";
case SPR_TBRU:
return "tbru";
case SPR_SPRG0:
return "sprg0";
case SPR_SPRG1:
return "sprg1";
case SPR_SPRG2:
return "sprg2";
case SPR_SPRG3:
return "sprg3";
case SPR_EAR:
return "ear";
case SPR_TBL:
return "tbl";
case SPR_TBU:
return "tbu";
case SPR_PVR:
return "pvr";
case SPR_SPEFSCR:
return "spefscr";
case SPR_IBAT0U:
return "ibat0u";
case SPR_IBAT0L:
return "ibat0l";
case SPR_IBAT1U:
return "ibat1u";
case SPR_IBAT1L:
return "ibat1l";
case SPR_IBAT2U:
return "ibat2u";
case SPR_IBAT2L:
return "ibat2l";
case SPR_IBAT3U:
return "ibat3u";
case SPR_IBAT3L:
return "ibat3l";
case SPR_DBAT0U:
return "dbat0u";
case SPR_DBAT0L:
return "dbat0l";
case SPR_DBAT1U:
return "dbat1u";
case SPR_DBAT1L:
return "dbat1l";
case SPR_DBAT2U:
return "dbat2u";
case SPR_DBAT2L:
return "dbat2l";
case SPR_DBAT3U:
return "dbat3u";
case SPR_DBAT3L:
return "dbat3l";
case SPR_UMMCR0:
return "ummcr0";
case SPR_UMMCR1:
return "ummcr1";
case SPR_UPMC1:
return "upmc1";
case SPR_UPMC2:
return "upmc2";
case SPR_USIA:
return "usia";
case SPR_UPMC3:
return "upmc3";
case SPR_UPMC4:
return "upmc4";
case SPR_MMCR0:
return "mmcr0";
case SPR_PMC1:
return "pmc1";
case SPR_PMC2:
return "pmc2";
case SPR_SIA:
return "sia";
case SPR_MMCR1:
return "mmcr1";
case SPR_PMC3:
return "pmc3";
case SPR_PMC4:
return "pmc4";
case SPR_SDA:
return "sda";
case SPR_DMISS:
return "dmiss";
case SPR_DCMP:
return "dcmp";
case SPR_HASH1:
return "hash1";
case SPR_HASH2:
return "hash2";
case SPR_IMISS:
return "imiss";
case SPR_ICMP:
return "icmp";
case SPR_RPA:
return "rpa";
case SPR_HID0:
return "hid0";
case SPR_HID1:
return "hid1";
case SPR_IABR:
return "iabr";
case SPR_HID2:
return "hid2";
case SPR_HID4:
return "hid4";
case SPR_DABR:
return "dabr";
case SPR_HID5:
return "hid5";
case SPR_HID6:
return "hid6";
// case SPR_L2CR:
// return "l2cr";
case SPR_ICTC:
return "ictc";
case SPR_THRM1:
return "thrm1";
case SPR_THRM2:
return "thrm2";
case SPR_THRM3:
return "thrm3";
case SPR_PIR:
return "pir";
default:
snprintf(cspr, sizeof(cspr), "spr_%u", spr);
break;
}
return cspr;
}
static int replace(int argc, const char *argv[], char *newstr) {
int i,j,k;
struct {
char *op;
char *str;
int max_operands;
} ops[] = {
{ "cmpb", "A = ((byte) B == (byte) C)", 3}, //0
{ "cmpd", "A = (B == C)", 3},
{ "cmpdi", "A = (B == C)", 3},
{ "cmpld", "A = ((unsigned) B == (unsigned) C)", 3},
{ "cmpldi", "A = ((unsigned) B == (unsigned) C)", 3},
{ "cmplw", "A = ((unsigned) B == (unsigned) C)", 3},
{ "cmplwi", "A = ((unsigned) B == (unsigned) C)", 3},
{ "cmpw", "A = (B == C)", 3},
{ "cmpwi", "A = (B == C)", 3},
{ "beq", "if (A & FLG_EQ) goto B", 2},
{ "beq-", "if (A & FLG_EQ) goto B", 2},
{ "beq+", "if (A & FLG_EQ) goto B", 2},
{ "bge", "if (A & FLG_GE) goto B", 2},
{ "bge-", "if (A & FLG_GE) goto B", 2},
{ "bge+", "if (A & FLG_GE) goto B", 2},
{ "bgt", "if (A & FLG_GT) goto B", 2},
{ "bgt-", "if (A & FLG_GT) goto B", 2},
{ "bgt+", "if (A & FLG_GT) goto B", 2},
{ "ble", "if (A & FLG_LE) goto B", 2},
{ "ble-", "if (A & FLG_LE) goto B", 2},
{ "ble+", "if (A & FLG_LE) goto B", 2},
{ "blt", "if (A & FLG_LT) goto B", 2},
{ "blt-", "if (A & FLG_LT) goto B", 2},
{ "blt+", "if (A & FLG_LT) goto B", 2},
{ "bne", "if (A & FLG_NE) goto B", 2},
{ "bne-", "if (A & FLG_NE) goto B", 2},
{ "bne+", "if (A & FLG_NE) goto B", 2}, //26
{ "rldic", "A = rol64(B, C) & D", 4}, //27
{ "rldcl", "A = rol64(B, C) & D", 4}, //28
{ "rldicl", "A = rol64(B, C) & D", 4}, //29
{ "rldcr", "A = rol64(B, C) & D", 4}, //30
{ "rldicr", "A = rol64(B, C) & D", 4}, //31
{ "rldimi", "mask = D; A = (rol64(B, C) & mask) | (A & ~mask)", 4}, //32
{ "rlwimi", "mask = D; A = (rol32(B, C) & mask) | (A & ~mask)", 4}, //33
{ "rlwinm", "A = rol32(B, C) & D", 4}, //34
{ "rlwnm", "A = rol32(B, C) & D", 4}, //35
{ "td", "if (B A C) trap", 3}, //36
{ "tdi", "if (B A C) trap", 3},
{ "tdu", "if (B A C) trap", 3},
{ "tdui", "if (B A C) trap", 3},
{ "tw", "if ((word) B A (word) C) trap", 3},
{ "twi", "if ((word) B A (word) C) trap", 3},
{ "twu", "if ((word) B A (word) C) trap", 3},
{ "twui", "if ((word) B A (word) C) trap", 3}, //43
{ "mfspr", "A = B", 2}, //44
{ "mtspr", "A = B", 2}, //45
{ "add", "A = B + C", 3},
{ "addc", "A = B + C", 3},
{ "adde", "A = B + C", 3},
{ "addi", "A = B + C", 3},
{ "addic", "A = B + C", 3},
{ "addis", "A = B + (C << 16)", 3},
{ "addme", "A = B - A", 2},
{ "addze", "A = zero extended(B)", 2},
{ "and", "A = B & C", 3},
{ "andc", "A = B & C", 3},
{ "andi", "A = B & C", 3},
{ "andis", "A = B & (C << 16)", 3},
{ "attn", "attention A", 1},
{ "b", "goto A", 1},
{ "ba", "goto A", 1},
//{ "bc", "if (a ?? b) goto C", 3},
//{ "bca", "if (a ?? b) goto C", 3},
//{ "bcctr", "if (a ?? b) goto ctr", 2},
//{ "bcctrl", "if (a ?? b) goto ctr", 2},
//{ "bcl", "if (a ?? b) call C", 3},
//{ "bcla", "if (a ?? b) call C", 3},
//{ "bclr", "if (a ?? b) goto C", 3},
//{ "bclrl", "if (a ?? b) call C", 3},
{ "bct", "goto ct", 0},
{ "bctr", "goto ctr", 3},
{ "bctrl", "call ctr", 3},
{ "bdnz", "if (ctr != 0) goto A", 1},
{ "bdnza", "if (ctr != 0) goto A", 1},
{ "bdnzf", "if (ctr != 0 && !cond) goto A", 1},
{ "bdnzfa", "if (ctr != 0 && !cond) goto A", 1},
{ "bdnzfl", "if (ctr != 0 && !cond) call A", 1},
{ "bdnzfla", "if (ctr != 0 && !cond) call A", 1},
{ "bdnzflrl", "if (ctr != 0 && !cond) call A", 1},
{ "bdnzl", "if (ctr != 0) call A", 1},
{ "bdnzla", "if (ctr != 0) call A", 1},
{ "bdnzlr", "if (ctr != 0) call A", 1},
{ "bdnzlrl", "if (ctr != 0) call A", 1},
{ "bdnzt", "if (ctr != 0 && cond) goto A", 1},
{ "bdnzta", "if (ctr != 0 && cond) goto A", 1},
{ "bdnztl", "if (ctr != 0 && cond) call A", 1},
{ "bdnztla", "if (ctr != 0 && cond) call A", 1},
{ "bdnztlr", "if (ctr != 0 && cond) call A", 1},
{ "bdnztlrl", "if (ctr != 0 && cond) call A", 1},
{ "bdz", "if (ctr == 0) goto A", 1},
{ "bdza", "if (ctr == 0) goto A", 1},
{ "bdzf", "if (ctr == 0 && !cond) goto A", 1},
{ "bdzfa", "if (ctr == 0 && !cond) goto A", 1},
{ "bdzfl", "if (ctr == 0 && !cond) call A", 1},
{ "bdzfla", "if (ctr == 0 && !cond) call A", 1},
{ "bdzflr", "if (ctr == 0 && !cond) call A", 1},
{ "bdzflrl", "if (ctr == 0 && !cond) call A", 1},
{ "bdzl", "if (ctr == 0) call A", 1},
{ "bdzla", "if (ctr == 0) call A", 1},
{ "bdzlr", "if (ctr == 0) call A", 1},
{ "bdzlrl", "if (ctr == 0) call A", 1},
{ "bdzt", "if (ctr == 0 && cond) goto A", 1},
{ "bdzta", "if (ctr == 0 && cond) goto A", 1},
{ "bdztl", "if (ctr == 0 && cond) call A", 1},
{ "bdztla", "if (ctr == 0 && cond) call A", 1},
{ "bdztlr", "if (ctr == 0 && cond) call A", 1},
{ "bdztlrl", "if (ctr == 0 && cond) call A", 1},
{ "bf", "if (!cond) goto A", 1},
{ "bfa", "if (!cond) goto A", 1},
{ "bfctr", "if (!cond) goto ctr", 0},
{ "bfctrl", "if (!cond) call ctr", 0},
{ "bfl", "if (!cond) call A", 1},
{ "bfla", "if (!cond) call A", 1},
{ "bflr", "if (!cond) call A", 1},
{ "bflrl", "if (!cond) call A", 1},
{ "bl", "call A", 1},
{ "bla", "call A", 1},
{ "blr", "return", 0},
{ "blrl", "return", 0},
{ "bltlr", "if (A & FLG_LT) return", 1},
{ "blelr", "if (A & FLG_LE) return", 1},
{ "bgtlr", "if (A & FLG_GT) return", 1},
{ "bgelr", "if (A & FLG_GE) return", 1},
{ "bnelr", "if (A & FLG_NE) return", 1},
{ "beqlr", "if (A & FLG_EQ) return", 1},
{ "brinc", "A = bit_revese(B, C)", 3},
{ "bt", "if (cond) goto A", 1},
{ "bta", "if (cond) goto A", 1},
{ "btctr", "if (cond) goto ctr", 1},
{ "btctrl", "if (cond) call ctr", 1},
{ "btl", "if (cond) call A", 1},
{ "btla", "if (cond) call A", 1},
{ "btlr", "if (cond) call A", 1},
{ "btlrl", "if (cond) call A", 1},
{ "clrldi", "A = B & mask64", 2},
{ "clrlwi", "A = B & mask32", 2},
{ "cntlzd", "A = cnt_leading_zeros(B)", 2},
{ "cntlzw", "A = cnt_leading_zeros(B)", 2},
{ "crand", "A = B & C", 3},
{ "crandc", "A = B & C", 3},
{ "crclr", "A = A ^ A", 1},
{ "creqv", "A = B == C", 3},
{ "crmove", "A = B", 2},
{ "crnand", "A = B & !C", 3},
{ "crnor", "A = B | !C", 3},
{ "crnot", "A = !B", 2},
{ "cror", "A = B | C", 3},
{ "crorc", "A = B | C", 3},
{ "crset", "A = B", 2},
{ "crxor", "A = B ^ C", 3},
{ "dcba", "dcb_alloc(A,B)", 2},
{ "dcbf", "dcb_flush(A,B)", 2},
{ "dcbi", "dcb_inval(A,B)", 2},
{ "dcbst", "dcb_store(A,B)", 2},
{ "dcbt", "dcb_touch(A,B)", 2},
{ "dcbtst", "dcb_touch_store(A, B)", 2},
{ "dcbz", "dcb_zero(A,B)", 2},
{ "dcbzl", "dcb_zero_line(A, B)", 2},
{ "dccci", "dcc_inval(A, B)", 3}, // Data Cache Congruence Class Invalidate
{ "divd", "A = B / C", 3},
{ "divdu", "A = (unsigned) B / C", 3},
{ "divw", "A = (word) B / C", 3},
{ "divwu", "A = (word unsigned) B / C", 3},
{ "dss", "altivec_ds_stop(A)", 1},
{ "dssall", "altivec_ds_stop_all", 0},
{ "dst", "altivec_ds_touch(A,B,C)", 3},
{ "dstst", "altivec_ds_touch_store(A, B, C)", 3},
{ "dststt", "altivec_ds_touch_store_tran(A, B, C)", 3},
{ "dstt", "altivec_ds_touch_tran(A, B, C)", 3},
{ "eieio", "enforce_in_order_exec_io", 0},
{ "eqv", "A = B ^ C", 3},
{ "evabs", "A = (vector) abs(B)", 2},
{ "evaddiw", "A = (vector) B + C", 3},
{ "evaddsmiaaw", "A = (vector) B + C", 3},
{ "evaddssiaaw", "A = (vector) B + C", 3},
{ "evaddumiaaw", "A = (vector) B + C", 3},
{ "evaddusiaaw", "A = (vector) B + C", 3},
{ "evaddw", "A = (vector) B + C", 3},
{ "evand", "A = (vector) B + C", 3},
{ "evandc", "A = (vector) B + C", 3},
{ "evcmpeq", "A = (vector) B == C", 3},
{ "evcmpgts", "A = (vector) B > C", 3},
{ "evcmpgtu", "A = (unsigned vector) B > C", 3},
{ "evcmplts", "A = (vector) B < C", 3},
{ "evcmpltu", "A = (unsigned vector) B <> C", 3},
{ "evcntlsw", "A = (vector) cnt_sign_bits(B)", 2},
{ "evcntlzw", "A = (vector) cnt_zero_bits(B)", 2},
{ "evdivws", "A = (vector) B / C", 3},
{ "evdivwu", "A = (unsigned vector) B + C", 3},
{ "eveqv", "A = (vector) B ^ C", 3},
//{ "evextsb", "", 0}, //extend sign byte
//{ "evextsh", "", 0}, //extend sign half
{ "evldd", "A = vector[C + B]", 3},
{ "evlddx", "A = vector[C + B]", 3},
{ "evldh", "A = vector[C + B]", 3},
{ "evldhx", "A = vector[C + B]", 3},
{ "evldw", "A = vector[C + B]", 3},
{ "evldwx", "A = vector[C + B]", 3},
//Vector Load Half Word into Half Words Even and Splat ??
/*
{ "evlhhesplat", "A = B + C", 3},
{ "evlhhesplatx", "A = B + C", 3},
{ "evlhhossplat", "A = B + C", 3},
{ "evlhhossplatx", "A = B + C", 3},
{ "evlhhousplat", "A = B + C", 3},
{ "evlhhousplatx", "A = B + C", 3},
*/
{ "evlwhe", "A = vector[C + B]", 3},
{ "evlwhex", "A = vector[C + B]", 3},
{ "evlwhos", "A = vector[C + B]", 3},
{ "evlwhosx", "A = vector[C + B]", 3},
{ "evlwhou", "A = vector[C + B]", 3},
{ "evlwhoux", "A = vector[C + B]", 3},
/*
{ "evlwhsplat", "A = vector[C + B]", 3},
{ "evlwhsplatx", "A = vector[C + B]", 3},
{ "evlwwsplat", "A = vector[C + B]", 3},
{ "evlwwsplatx", "A = vector[C + B]", 3},
{ "evmergehi", "A = lo | hi", 3},
{ "evmergehilo", "A = B + C", 3},
{ "evmergelo", "A = B + C", 3},
{ "evmergelohi", "A = B + C", 3},
{ "evmhegsmfaa", "A = B + C", 3},
{ "evmhegsmfan", "A = B + C", 3},
{ "evmhegsmiaa", "A = B + C", 3},
{ "evmhegsmian", "A = B + C", 3},
{ "evmhegumiaa", "A = B + C", 3},
{ "evmhegumian", "A = B + C", 3},
{ "evmhesmf", "A = B + C", 3},
{ "evmhesmfa", "A = B + C", 3},
{ "evmhesmfaaw", "A = B + C", 3},
{ "evmhesmfanw", "A = B + C", 3},
{ "evmhesmi", "A = B + C", 3},
{ "evmhesmia", "A = B + C", 3},
{ "evmhesmiaaw", "A = B + C", 3},
{ "evmhesmianw", "A = B + C", 3},
{ "evmhessf", "A = B + C", 3},
{ "evmhessfa", "A = B + C", 3},
{ "evmhessfaaw", "A = B + C", 3},
{ "evmhessfanw", "A = B + C", 3},
{ "evmhessiaaw", "A = B + C", 3},
{ "evmhessianw", "A = B + C", 3},
{ "evmheumi", "A = B + C", 3},
{ "evmheumia", "A = B + C", 3},
{ "evmheumiaaw", "A = B + C", 3},
{ "evmheumianw", "A = B + C", 3},
{ "evmheusiaaw", "A = B + C", 3},
{ "evmheusianw", "A = B + C", 3},
{ "evmhogsmfaa", "A = B + C", 3},
{ "evmhogsmfan", "A = B + C", 3},
{ "evmhogsmiaa", "A = B + C", 3},
{ "evmhogsmian", "A = B + C", 3},
{ "evmhogumiaa", "A = B + C", 3},
{ "evmhogumian", "A = B + C", 3},
{ "evmhosmf", "A = B + C", 3},
{ "evmhosmfa", "A = B + C", 3},
{ "evmhosmfaaw", "A = B + C", 3},
{ "evmhosmfanw", "A = B + C", 3},
{ "evmhosmi", "A = B + C", 3},
{ "evmhosmia", "A = B + C", 3},
{ "evmhosmiaaw", "A = B + C", 3},
{ "evmhosmianw", "A = B + C", 3},
{ "evmhossf", "A = B + C", 3},
{ "evmhossfa", "A = B + C", 3},
{ "evmhossfaaw", "A = B + C", 3},
{ "evmhossfanw", "A = B + C", 3},
{ "evmhossiaaw", "A = B + C", 3},
{ "evmhossianw", "A = B + C", 3},
{ "evmhoumi", "A = B + C", 3},
{ "evmhoumia", "A = B + C", 3},
{ "evmhoumiaaw", "A = B + C", 3},
{ "evmhoumianw", "A = B + C", 3},
{ "evmhousiaaw", "A = B + C", 3},
{ "evmhousianw", "A = B + C", 3},
{ "evmra", "A = B + C", 3},
{ "evmwhsmf", "A = B + C", 3},
{ "evmwhsmfa", "A = B + C", 3},
{ "evmwhsmi", "A = B + C", 3},
{ "evmwhsmia", "A = B + C", 3},
{ "evmwhssf", "A = B + C", 3},
{ "evmwhssfa", "A = B + C", 3},
{ "evmwhumi", "A = B + C", 3},
{ "evmwhumia", "A = B + C", 3},
{ "evmwlsmiaaw", "A = B + C", 3},
{ "evmwlsmianw", "A = B + C", 3},
{ "evmwlssiaaw", "A = B + C", 3},
{ "evmwlssianw", "A = B + C", 3},
{ "evmwlumi", "A = B + C", 3},
{ "evmwlumia", "A = B + C", 3},
{ "evmwlumiaaw", "A = B + C", 3},
{ "evmwlumianw", "A = B + C", 3},
{ "evmwlusiaaw", "A = B + C", 3},
{ "evmwlusianw", "A = B + C", 3},
{ "evmwsmf", "A = B + C", 3},
{ "evmwsmfa", "A = B + C", 3},
{ "evmwsmfaa", "A = B + C", 3},
{ "evmwsmfan", "A = B + C", 3},
{ "evmwsmi", "A = B + C", 3},
{ "evmwsmia", "A = B + C", 3},
{ "evmwsmiaa", "A = B + C", 3},
{ "evmwsmian", "A = B + C", 3},
{ "evmwssf", "A = B + C", 3},
{ "evmwssfa", "A = B + C", 3},
{ "evmwssfaa", "A = B + C", 3},
{ "evmwssfan", "A = B + C", 3},
{ "evmwumi", "A = B + C", 3},
{ "evmwumia", "A = B + C", 3},
{ "evmwumiaa", "A = B + C", 3},
{ "evmwumian", "A = B + C", 3},
{ "evnand", "A = B + C", 3},
{ "evneg", "A = B + C", 3},
{ "evnor", "A = B + C", 3},
{ "evor", "A = B + C", 3},
{ "evorc", "A = B + C", 3},
{ "evrlw", "A = B + C", 3},
{ "evrlwi", "A = B + C", 3},
{ "evrndw", "A = B + C", 3},
{ "evslw", "A = B + C", 3},
{ "evslwi", "A = B + C", 3},
{ "evsplatfi", "A = B + C", 3},
{ "evsplati", "A = B + C", 3},
{ "evsrwis", "A = B + C", 3},
{ "evsrwiu", "A = B + C", 3},
{ "evsrws", "A = B + C", 3},
{ "evsrwu", "A = B + C", 3},
{ "evstdd", "A = B + C", 3},
{ "evstddx", "A = B + C", 3},
{ "evstdh", "A = B + C", 3},
{ "evstdhx", "A = B + C", 3},
{ "evstdw", "A = B + C", 3},
{ "evstdwx", "A = B + C", 3},
{ "evstwhe", "A = B + C", 3},
{ "evstwhex", "A = B + C", 3},
{ "evstwho", "A = B + C", 3},
{ "evstwhox", "A = B + C", 3},
{ "evstwwe", "A = B + C", 3},
{ "evstwwex", "A = B + C", 3},
{ "evstwwo", "A = B + C", 3},
{ "evstwwox", "A = B + C", 3},
{ "evsubfsmiaaw", "A = B + C", 3},
{ "evsubfssiaaw", "A = B + C", 3},
{ "evsubfumiaaw", "A = B + C", 3},
{ "evsubfusiaaw", "A = B + C", 3},
{ "evsubfw", "A = B + C", 3},
{ "evsubifw", "A = B + C", 3},
{ "evxor", "A = B + C", 3},
*/
{ "extsb", "A = extend_sign(B)", 2},
{ "extsh", "A = extend_sign(B)", 2},
{ "extsw", "A = extend_sign(B)", 2},
{ "fabs", "A = abs(B)", 2},
{ "fadd", "A = B + C", 3},
{ "fadds", "A = (float) B + C", 3},
{ "fcfid", "A = (double) B", 2},
{ "fcfids", "A = (float) B", 2},
{ "fcfidu", "A = (double) B", 2},
{ "fcfidus", "A = (float) B", 2},
{ "fcmpu", "A = B == C", 3},
// This should copy the sign of bit 0 of reg B & c
{ "fcpsgn", "A = flt_copy_sign(B,C)", 3},
{ "fctid", "A = (int64) B", 2},
{ "fctiduz", "A = (uint64) B + C", 3},
{ "fctidz", "A = (int64) B + C", 3},
{ "fctiw", "A = (int32) B + C", 3},
{ "fctiwuz", "A = (uint32) B + C", 3},
{ "fctiwz", "A = (int32) B + C", 3},
{ "fdiv", "A = B / C", 3},
{ "fdivs", "A = (float) B / C", 3},
{ "fmadd", "A = (B * C) + D", 4},
{ "fmadds", "A = (float) (B * C) + D", 3},
{ "fmr", "A = B", 2},
{ "fmsub", "A = (B * C) - d", 4},
{ "fmsubs", "A = (float) (B * C) - D", 4},
{ "fmul", "A = B * C", 3},
{ "fmuls", "A = (float) B * C", 3},
{ "fnabs", "A = - abs(B)", 2},
{ "fneg", "A = - B", 2},
{ "fnmadd", "A = -((B * C) + D)", 4},
{ "fnmadds", "A = (float) -((B * C) + D)", 4},
{ "fnmsub", "A = -((B * C) - D)", 4},
{ "fnmsubs", "A = (float) -((B * C) - D)", 4},
{ "fre", "A = 1/B", 2},
{ "fres", "A = (float) 1/B", 2},
{ "frim", "A = trunc(B)", 2},
{ "frin", "A = floor(B)", 2},
{ "frip", "A = ceil(B)", 2},
{ "friz", "A = trunc(B)", 2},
{ "frsp", "A = (float) B", 3},
{ "frsqrte", "A = 1/sqrt(B)", 2},
{ "frsqrtes", "A = (float) 1/sqrt(B)", 2},
{ "fsel", "if (B >= 0.0) A = C; else A = D", 4},
{ "fsqrt", "A = sqrt(B)", 2},
{ "fsqrts", "A = (float) sqrt(B)", 3},
{ "fsub", "A = B - C", 3},
{ "fsubs", "A = (float) B - C", 3},
{ "icbi", "inst_cache_block_inval", 0},
{ "icbt", "inst_cache_block_touch", 3},
{ "iccci", "inst_cache_inval(A,B)", 2},
// isel lt Rx,Ry,Rz (equivalent to: isel Rx,Ry,Rz,0)
// isel gt Rx,Ry,Rz (equivalent to: isel Rx,Ry,Rz,1)
// isel eq Rx,Ry,Rz (equivalent to: isel Rx,Ry,Rz,2)
// { "isel", "", 4},
{ "isync", "sync_instr_cache", 0},
{ "la", "A = C + B", 3},
{ "lbz", "A = byte[C + B]", 3},
{ "lbzcix", "A = byte[C + B]", 3},
{ "lbzu", "A = byte[C + B]", 3},
{ "lbzux", "A = Byte[C + B]", 3},
{ "lbzx", "A = byte[C + B]", 3},
{ "ld", "A = [C + B]", 3},
// No clue how to reprensent them since they are kinda complex..
// { "ldarx", "A = [C + B]", 3},
// { "ldbrx", "A = [C + B]", 3},
// { "ldcix", "A = B + C", 3},
{ "ldu", "A = [C + B]", 3},
{ "ldux", "A = [C + B]", 3},
{ "ldx", "A = [C + B]", 3},
{ "lfd", "A = double[C + B]", 3},
{ "lfdu", "A = double[C + B]", 3},
{ "lfdux", "A = double[C + B]", 3},
{ "lfdx", "A = double[C + B]", 3},
{ "lfiwax", "A = float[C + B]", },
{ "lfiwzx", "A = float[C + B]", 3},
{ "lfs", "A = float[C + B]", 3},
{ "lfsu", "A = float[C + B]", 3},
{ "lfsux", "A = float[C + B]", 3},
{ "lfsx", "A = float[C + B]", 3},
{ "lha", "A = half[C + B]", 3},
{ "lhau", "A = half[C + B]", 3},
{ "lhaux", "A = half[C + B]", 3},
{ "lhax", "A = half[C + B]", 3},
{ "lhbrx", "A = half[C + B]", 3},
{ "lhz", "A = half[C + B]", 3},
{ "lhzcix", "A = half[C + B]", 3},
{ "lhzu", "A = half[C + B]", 3},
{ "lhzux", "A = half[C + B]", 3},
{ "lhzx", "A = half[C + B]", 3},
{ "li", "A = B", 2},
{ "lis", "A = (B << 16)", 2},
{ "lmw", "A = multiple word[C + B]", 3},
{ "lswi", "A = string word[C + B]", 3},
{ "lvebx", "A = vector[C + B]", 3},
{ "lvehx", "A = vector[C + B]", 3},
{ "lvewx", "A = vector[C + B]", 3},
{ "lvsl", "A = vector[C + B]", 3},
{ "lvsr", "A = vector[C + B]", 3},
{ "lvx", "A = vector[C + B]", 3},
{ "lvxl", "A = vector[C + B]", 3},
{ "lwa", "A = word[C + B]", 3},
{ "lwarx", "A = word[C + B]", 3},
{ "lwaux", "A = word[C + B]", 3},
{ "lwax", "A = word[C + B]", 3},
{ "lwbrx", "A = word[C + B]", 3},
{ "lwsync", "sync_load_store", 0},
{ "lwz", "A = word[C + B]", 3},
{ "lwzcix", "A = word[C + B]", 3},
{ "lwzu", "A = word[C + B]", 3},
{ "lwzux", "A = word[C + B]", 3},
{ "lwzx", "A = word[C + B]", 3},
// { "lxsdx", "A = ???[C + B]", 3},
{ "lxvdbx", "A = vector[C + B]", 3},
{ "lxvdsx", "A = vector[C + B]", 3},
{ "lxvwdx", "A = vector[C + B]", 3},
{ "mbar", "memory_barrier(A)", 1},
{ "mcrf", "A = B", 2},
{ "mcrfs", "A = B", 2},
{ "mfamr", "A = amr", 1},
{ "mfasr", "A = asr", 1},
{ "mfbr0", "A = br0", 1},
{ "mfbra", "A = br1", 1},
{ "mfbrb", "A = br2", 1},
{ "mfbrc", "A = br3", 1},
{ "mfbrd", "A = br4", 1},
{ "mfbr5", "A = br5", 1},
{ "mfbr6", "A = br6", 1},
{ "mfbr7", "A = br7", 1},
{ "mfcfar", "A = cfar", 3},
{ "mfcr", "A = crB", 2},
{ "mfctr", "A = ctr", 3},
{ "mfdar", "A = dar", 1},
{ "mfdbatl", "A = dbatBl", 1},
{ "mfdbatu", "A = dbatBu", 1},
{ "mfdccr", "A = dccr", 1},
{ "mfdcr", "A = dcr", 1},
{ "mfdear", "A = dear", 1},
{ "mfdscr", "A = dscr", 1},
{ "mfdsisr", "A = dsisr", 1},
{ "mfesr", "A = esr", 1},
{ "mffs", "A = fs", 1},
{ "mfibatl", "A = ibatBl", 2},
{ "mfibatu", "A = ibatBu", 2},
{ "mficcr", "A = iccr", 1},
{ "mflr", "A = lr", 1},
{ "mfmsr", "A = msr", 1},
{ "mfocrf", "A = ocrf", 1},
{ "mfpid", "A = pid", 1},
{ "mfpvr", "A = pvr", 1},
{ "mfrtcl", "A = rtc_lo", 1},
{ "mfrtcu", "A = rtc_hi", 1},
{ "mfspefscr", "A = fscr",1},
{ "mfsr", "A = srB", 3},
{ "mfsrin", "A = sr_indirect(B)", 2},
{ "mfsrr2", "A = srr2", 1},
{ "mfsrr3", "A = srr3", 1},
{ "mftb", "A = tb(B)", 2},
{ "mftbhi", "A = tb_hi(B)", 2},
{ "mftblo", "A = tb_lo(B)", 2},
{ "mftbu", "A = tbu", 1},
{ "mftcr", "A = tcr", 1},
{ "mfvscr", "A = vscr", 1},
{ "mfxer", "A = xer", 1},
{ "mr", "A = B", 2},
{ "msync", "sync_memory", 3},
{ "mtamr", "amr = A", 1},
{ "mtbr0", "br0 = A", 1},
{ "mtbr1", "br1 = A", 1},
{ "mtbr2", "br2 = A", 1},
{ "mtbr3", "br3 = A", 1},
{ "mtbr4", "br4 = A", 1},
{ "mtbr5", "br5 = A", 1},
{ "mtbr6", "br6 = A", 1},
{ "mtbr7", "br7 = A", 1},
{ "mtcfar", "cfar = A", 1},
{ "mtcr", "tcr = A", 1},
{ "mtcrf", "crf = A", 1},
{ "mtctr", "ctr = A", 1},
{ "mtdar", "dar = A", 1},
{ "mtdbatl", "dbatBl = A", 2},
{ "mtdbatu", "dbatBu = A", 2},
{ "mtdccr", "dccr = A", 1},
{ "mtdcr", "dcr = A", 1},
{ "mtdear", "dear = A", 1},
{ "mtdscr", "dscr = A", 1},
{ "mtdsisr", "dsisr = A", 1},
{ "mtesr", "esr = A", 1},
{ "mtfsb0", "fsb0 = A", 1},
{ "mtfsb1", "fsb1 = A", 1},
{ "mtfsf", "fsf = A", 1},
{ "mtfsfi", "fsfi = A", 1},
{ "mtibatl", "ibatBl = A", 2},
{ "mtibatu", "ibatBu = A", 2},
{ "mticcr", "iccr = A", 1},
{ "mtlr", "lr = A", 1},
{ "mtmsr", "msr = A", 1},
{ "mtmsrd", "msr = A", 1},
{ "mtocrf", "cr0 = B & fxm_mask(A)", 2},
{ "mtpid", "pid = A", 1},
{ "mtspefscr", "fscr = A", 1},
{ "mtsr", "srA = B", 2},
{ "mtsrin", "sr_indirect(A) = B", 2},
{ "mtsrr2", "srr2 = A", 1},
{ "mtsrr3", "srr3 = A ", 1},
{ "mttbhi", "tb_hi(A) = B", 2},
{ "mttbl", "tbl(A) = B", 2},
{ "mttblo", "tb_lo(A) = B", 2},
{ "mttbu", "tbu = A", 1},
{ "mtvscr", "vscr = A", 1},
{ "mtxer", "xer = A", 1},
{ "mulhd", "A = hi(B) * hi(C)", 3},
{ "mulhdu", "A = (unsigned) hi(B) * hi(C)", 3},
{ "mulhw", "A = (word) hi(B) * hi(C)", 3},
{ "mulhwu", "A = (unsigned word) hi(B) * hi(C)", 3},
{ "mulld", "A = lo(B) * lo(C)", 3},
{ "mulli", "A = lo(B) * lo(C)", 3},
{ "mullw", "A = (word) lo(B) * lo(C)", 3},
{ "nand", "A = B & !C", 3},
{ "neg", "A = -B", 2},
{ "nop", "", 0},
{ "nor", "A = B | !C", 3},
{ "not", "A = !B", 2},
{ "or", "A = B | C", 3},
{ "orc", "A = B | C", 3},
{ "ori", "A = B | C", 3},
{ "oris", "A = B | (C << 16)", 3},
{ "popcntd", "A = count_bits(B)", 2},
{ "popcntw", "A = count_bits(B)", 2},
{ "ptesync", "sync_page_tbl", 0},
// Are you kidding? QPX Architecture totally NO.
/*
{ "qvaligni", "A = B + C", 3},
{ "qvesplati", "A = B + C", 3},
{ "qvfabs", "A = B + C", 3},
{ "qvfadd", "A = B + C", 3},
{ "qvfadds", "A = B + C", 3},
{ "qvfand", "A = B + C", 3},
{ "qvfandc", "A = B + C", 3},
{ "qvfcfid", "A = B + C", 3},
{ "qvfcfids", "A = B + C", 3},
{ "qvfcfidu", "A = B + C", 3},
{ "qvfcfidus", "A = B + C", 3},
{ "qvfclr", "A = B + C", 3},
{ "qvfcmpeq", "A = B + C", 3},
{ "qvfcmpgt", "A = B + C", 3},
{ "qvfcmplt", "A = B + C", 3},
{ "qvfcpsgn", "A = B + C", 3},
{ "qvfctfb", "A = B + C", 3},
{ "qvfctid", "A = B + C", 3},
{ "qvfctidu", "A = B + C", 3},
{ "qvfctiduz", "A = B + C", 3},
{ "qvfctidz", "A = B + C", 3},
{ "qvfctiw", "A = B + C", 3},
{ "qvfctiwu", "A = B + C", 3},
{ "qvfctiwuz", "A = B + C", 3},
{ "qvfctiwz", "A = B + C", 3},
{ "qvfequ", "A = B + C", 3},
{ "qvflogical", "A = B + C", 3},
{ "qvfmadd", "A = B + C", 3},
{ "qvfmadds", "A = B + C", 3},
{ "qvfmr", "A = B + C", 3},
{ "qvfmsub", "A = B + C", 3},
{ "qvfmsubs", "A = B + C", 3},
{ "qvfmul", "A = B + C", 3},
{ "qvfmuls", "A = B + C", 3},
{ "qvfnabs", "A = B + C", 3},
{ "qvfnand", "A = B + C", 3},
{ "qvfneg", "A = B + C", 3},
{ "qvfnmadd", "A = B + C", 3},
{ "qvfnmadds", "A = B + C", 3},
{ "qvfnmsub", "A = B + C", 3},
{ "qvfnmsubs", "A = B + C", 3},
{ "qvfnor", "A = B + C", 3},
{ "qvfnot", "A = B + C", 3},
{ "qvfor", "A = B + C", 3},
{ "qvforc", "A = B + C", 3},
{ "qvfperm", "A = B + C", 3},
{ "qvfre", "A = B + C", 3},
{ "qvfres", "A = B + C", 3},
{ "qvfrim", "A = B + C", 3},
{ "qvfrin", "A = B + C", 3},
{ "qvfrip", "A = B + C", 3},
{ "qvfriz", "A = B + C", 3},
{ "qvfrsp", "A = B + C", 3},
{ "qvfrsqrte", "A = B + C", 3},
{ "qvfrsqrtes", "A = B + C", 3},
{ "qvfsel", "A = B + C", 3},
{ "qvfset", "A = B + C", 3},
{ "qvfsub", "A = B + C", 3},
{ "qvfsubs", "A = B + C", 3},
{ "qvftstnan", "A = B + C", 3},
{ "qvfxmadd", "A = B + C", 3},
{ "qvfxmadds", "A = B + C", 3},
{ "qvfxmul", "A = B + C", 3},
{ "qvfxmuls", "A = B + C", 3},
{ "qvfxor", "A = B + C", 3},
{ "qvfxxcpnmadd", "A = B + C", 3},
{ "qvfxxcpnmadds", "A = B + C", 3},
{ "qvfxxmadd", "A = B + C", 3},
{ "qvfxxmadds", "A = B + C", 3},
{ "qvfxxnpmadd", "A = B + C", 3},
{ "qvfxxnpmadds", "A = B + C", 3},
{ "qvgpci", "A = B + C", 3},
{ "qvlfcdux", "A = B + C", 3},
{ "qvlfcduxa", "A = B + C", 3},
{ "qvlfcdx", "A = B + C", 3},
{ "qvlfcdxa", "A = B + C", 3},
{ "qvlfcsux", "A = B + C", 3},
{ "qvlfcsuxa", "A = B + C", 3},
{ "qvlfcsx", "A = B + C", 3},
{ "qvlfcsxa", "A = B + C", 3},
{ "qvlfdux", "A = B + C", 3},
{ "qvlfduxa", "A = B + C", 3},
{ "qvlfdx", "A = B + C", 3},
{ "qvlfdxa", "A = B + C", 3},
{ "qvlfiwax", "A = B + C", 3},
{ "qvlfiwaxa", "A = B + C", 3},
{ "qvlfiwzx", "A = B + C", 3},
{ "qvlfiwzxa", "A = B + C", 3},
{ "qvlfsux", "A = B + C", 3},
{ "qvlfsuxa", "A = B + C", 3},
{ "qvlfsx", "A = B + C", 3},
{ "qvlfsxa", "A = B + C", 3},
{ "qvlpcldx", "A = B + C", 3},
{ "qvlpclsx", "A = B + C", 3},
{ "qvlpcrdx", "A = B + C", 3},
{ "qvlpcrsx", "A = B + C", 3},
{ "qvstfcdux", "A = B + C", 3},
{ "qvstfcduxa", "A = B + C", 3},
{ "qvstfcduxi", "A = B + C", 3},
{ "qvstfcduxia", "A = B + C", 3},
{ "qvstfcdx", "A = B + C", 3},
{ "qvstfcdxa", "A = B + C", 3},
{ "qvstfcdxi", "A = B + C", 3},
{ "qvstfcdxia", "A = B + C", 3},
{ "qvstfcsux", "A = B + C", 3},
{ "qvstfcsuxa", "A = B + C", 3},
{ "qvstfcsuxi", "A = B + C", 3},
{ "qvstfcsuxia", "A = B + C", 3},
{ "qvstfcsx", "A = B + C", 3},
{ "qvstfcsxa", "A = B + C", 3},
{ "qvstfcsxi", "A = B + C", 3},
{ "qvstfcsxia", "A = B + C", 3},
{ "qvstfdux", "A = B + C", 3},
{ "qvstfduxa", "A = B + C", 3},
{ "qvstfduxi", "A = B + C", 3},
{ "qvstfduxia", "A = B + C", 3},
{ "qvstfdx", "A = B + C", 3},
{ "qvstfdxa", "A = B + C", 3},
{ "qvstfdxi", "A = B + C", 3},
{ "qvstfdxia", "A = B + C", 3},
{ "qvstfiwx", "A = B + C", 3},
{ "qvstfiwxa", "A = B + C", 3},
{ "qvstfsux", "A = B + C", 3},
{ "qvstfsuxa", "A = B + C", 3},
{ "qvstfsuxi", "A = B + C", 3},
{ "qvstfsuxia", "A = B + C", 3},
{ "qvstfsx", "A = B + C", 3},
{ "qvstfsxa", "A = B + C", 3},
{ "qvstfsxi", "A = B + C", 3},
{ "qvstfsxia", "A = B + C", 3},
*/
{ "rfci", "msr = csrr1; nia = csrr0; ret", 0},
{ "rfdi", "msr = drr1; nia = drr0; ret", 0},
{ "rfi", "msr = srr1; nia = srr0; ret", 0},
{ "rfid", "msr = srr1; nia = srr0; ret", 0},
{ "rfmci", "msr = mcrr1; nia = mcrr0; ret", 3},
{ "rotld", "A = rot64(B,C)", 3},
{ "rotldi", "A = rot64(B,C)", 3},
{ "rotlw", "A = rot32(B,C)", 3},
{ "rotlwi", "A = rot32(B,C)", 3},
{ "sc", "syscall", 0},
{ "slbia", "slb_inval_all", 0},
{ "slbie", "slb_inval_entry(A)", 1},
{ "slbmfee", "A = slb[B]", 2},
{ "slbmte", "slb[A] = B", 2},
{ "sld", "A = B << C", 3},
{ "sldi", "A = B << C", 3},
{ "slw", "A = (word) B << C", 3},
{ "slwi", "A = (word) B << C", 3},
{ "srad", "A = B >> C", 3},
{ "sradi", "A = B >> C", 3},
{ "sraw", "A = (word) B >> C", 3},
{ "srawi", "A = (word) B >> C", 3},
{ "srd", "A = B >> C", 3},
{ "srw", "A = (word) B >> C", 3},
{ "srwi", "A = (word) B >> C", 3},
{ "stb", "byte[C + B] = A", 3},
{ "stbcix", "byte[C + B] = A", 3},
{ "stbu", "byte[C + B] = A", 3},
{ "stbux", "byte[C + B] = A", 3},
{ "stbx", "byte[C + B] = A", 3},
{ "std", "[C + B] = A", 3},
{ "stdbrx", "[C + B] = A", 3},
{ "stdcix", "[C + B] = A", 3},
{ "stdcx", "[C + B] = A", 3},
{ "stdu", "[C + B] = A", 3},
{ "stdux", "[C + B] = A", 3},
{ "stdx", "[C + B] = A", 3},
{ "stfd", "float[C + B] = A", 3},
{ "stfdu", "float[C + B] = A", 3},
{ "stfdux", "float[C + B] = A", 3},
{ "stfdx", "float[C + B] = A", 3},
{ "stfiwx", "float[C + B] = A", 3},
{ "stfs", "float[C + B] = A", 3},
{ "stfsu", "float[C + B] = A", 3},
{ "stfsux", "float[C + B] = A", 3},
{ "stfsx", "float[C + B] = A", 3},
{ "sth", "half[C + B] = A", 3},
{ "sthbrx", "half[C + B] = A", 3},
{ "sthcix", "half[C + B] = A", 3},
{ "sthu", "half[C + B] = A", 3},
{ "sthux", "half[C + B] = A", 3},
{ "sthx", "half[C + B] = A", 3},
{ "stmw", "multiple word[C + B] = A", 3},
{ "stswi", "string word[C + B] = A", 3},
{ "stvebx", "vector byte[C + B] = A", 3},
{ "stvehx", "vector half[C + B] = A", 3},
{ "stvewx", "vector word[C + B] = A", 3},
{ "stvx", "vector[C + B] = A", 3},
{ "stvxl", "vector[C + B] = A", 3},
{ "stw", "word[C + B] = A", 3},
{ "stwbrx", "word[C + B] = A", 3},
{ "stwcix", "word[C + B] = A", 3},
{ "stwcx", "word[C + B] = A", 3},
{ "stwu", "word[C + B] = A", 3},
{ "stwux", "word[C + B] = A", 3},
{ "stwx", "word[C + B] = A", 3},
{ "stxsdx", "vsx[C + B] = A", 3},
{ "stxvdbx", "vector double[C + B] = A", 3},
{ "stxvwdx", "vector word[C + B] = A", 3},
{ "sub", "A = C - B", 3},
{ "subc", "A = C - B", 3},
{ "subf", "A = C - B", 3},
{ "subfc", "A = C - B", 3},
{ "subfe", "A = C - B", 3},
{ "subfic", "A = C - B", 3},
{ "subfme", "A = C - B", 3},
{ "subfze", "A = C - B", 3},
{ "sync", "sync_instr_cache", 0},
{ "tdeq", "if (A == B) trap", 2},
{ "tdeqi", "if (A == B) trap",2},
{ "tdgt", "if (A > B) trap", 2},
{ "tdgti", "if (A > B) trap", 2},
{ "tdlgt", "if (A > B) trap", 2},
{ "tdlgti", "if (A > B) trap", 2},
{ "tdllt", "if (A < B) trap", 2},
{ "tdllti", "if (A < B) trap", 2},
{ "tdlt", "if (A < B) trap", 2},
{ "tdlti", "if (A < B) trap", 2},
{ "tdne", "if (A != B) trap", 2},
{ "tdnei", "if (A != B) trap", 2},
{ "tlbia", "inval_all_tlb", 0},
{ "tlbie", "inval_tbl(A, B)", 2},
{ "tlbiel", "inval_tbl(A)", 1},
{ "tlbivax", "inval_va(A, B)", 2},
{ "tlbld", "tlb_data_load(A)", 1},
{ "tlbli", "tlb_instr_load(A)", 1},
{ "tlbre", "A = tlb_read_entry(B,C)", 3},
{ "tlbrehi", "A = tlb_read_entry_hi(B)", 2},
{ "tlbrelo", "A = tlb_read_entry_lo(B)", 2},
{ "tlbsx", "A = tlb_search(B)", 2},
{ "tlbsync", "sync_tlb", 3},
{ "tlbwe", "tlb_write_entry(B,C) = A", 3},
{ "tlbwehi", "tlb_write_entry_hi(B) = A", 2},
{ "tlbwelo", "tlb_write_entry_lo(B) = A", 2},
{ "trap", "trap", 3},
{ "tweq", "if ((word) A == (word) B) trap", 2},
{ "tweqi", "if ((word) A == (word) B) trap",2},
{ "twgt", "if ((word) A > (word) B) trap", 2},
{ "twgti", "if ((word) A > (word) B) trap", 2},
{ "twlgt", "if ((word) A > (word) B) trap", 2},
{ "twlgti", "if ((word) A > (word) B) trap", 2},
{ "twllt", "if ((word) A < (word) B) trap", 2},
{ "twllti", "if ((word) A < (word) B) trap", 2},
{ "twlt", "if ((word) A < (word) B) trap", 2},
{ "twlti", "if ((word) A < (word) B) trap", 2},
{ "twne", "if ((word) A != (word) B) trap", 2},
{ "twnei", "if ((word) A != (word) B) trap", 2},
{ "vaddcuw", "A = (unsigned vector) B + C", 3},
{ "vaddfp", "A = (float vector) B + C", 3},
{ "vaddsbs", "A = (byte vector) B + C", 3},
{ "vaddshs", "A = (half vector) B + C", 3},
{ "vaddsws", "A = (word vector) B + C", 3},
/* too much complexity to represent
{ "vaddubm", "A = (byte vector) B + C + (modulo?)", 3},
{ "vaddubs", "A = (byte vector) B + C", 3},
{ "vaddudm", "A = (vector) B + C + (modulo?)", 3},
{ "vadduhm", "A = (half vector) B + C", 3},
{ "vadduhs", "A = (half vector) B + C", 3},
{ "vadduwm", "A = (word vector) B + C", 3},
{ "vadduws", "A = (word vector) B + C", 3},
*/
{ "vand", "A = B & C", 3},
{ "vandc", "A = B & C", 3},
{ "vavgsb", "A = (byte vector) avg(B, C)", 3},
{ "vavgsh", "A = (half vector) avg(B, C)", 3},
{ "vavgsw", "A = (word vector) avg(B, C)", 3},
{ "vavgub", "A = (unsigned byte vector) avg(B, C)", 3},
{ "vavguh", "A = (unsigned half vector) avg(B, C)", 3},
{ "vavguw", "A = (unsigned word vector) avg(B, C)", 3},
{ "vcfsx", "A = (float vector) B", 2},
{ "vcfux", "A = (float vector) B", 2},
{ "vclzb", "A = (byte vector) count_zeros(B)", 2},
{ "vclzd", "A = (vector) count_zeros(B)", 2},
{ "vclzh", "A = (half vector) count_zeros(B)", 2},
{ "vclzw", "A = (word vector) count_zeros(B)", 2},
{ "vcmpbfp", "A = !(B < C) | (B == C) | !(B > C)", 3},
{ "vcmpeqfp", "A = (float) B == (float) C", 3},
{ "vcmpequb", "A = (unsigned byte) B == (byte) C", 3},
{ "vcmpequd", "A = (unsigned) B == (unsigned) C", 3},
{ "vcmpequh", "A = (unsigned half) B == (unsigned half) C", 3},
{ "vcmpequw", "A = (unsigned word) B == (unsigned word) C", 3},
{ "vcmpgefp", "A = (float) B >= (float) C", 3},
{ "vcmpgtsb", "A = (byte) B > (byte) C", 3},
{ "vcmpgtsd", "A = B > C", 3},
{ "vcmpgtsh", "A = (half) B > (half) C", 3},
{ "vcmpgtsw", "A = (word) B > (word) C", 3},
{ "vcmpgtub", "A = (unsigned byte) B > (byte) C", 3},
{ "vcmpgtud", "A = (unsigned) B > (unsigned) C", 3},
{ "vcmpgtuh", "A = (unsigned half) B > (unsigned half) C", 3},
{ "vcmpgtuw", "A = (unsigned word) B > (unsigned word) C", 3},
{ "vctsxs", "A = (word) B", 2},
{ "vctuxs", "A = (unsigned word) B", 2},
{ "veqv", "A = (vector) B ^ C", 3},
{ "vexptefp", "A = (float vector) pow(2, B)", 2},
{ "vlogefp", "A = (float vector) log2(B)", 2},
{ "vmaddfp", "A = (float vector) (B * C) + round(D)", 4},
{ "vmaxfp", "A = (float vector) max(B, C)", 3},
{ "vmaxsb", "A = (byte vector) max(B, C)", 3},
{ "vmaxsd", "A = (vector) max(B, C)", 3},
{ "vmaxsh", "A = (half vector) max(B, C)", 3},
{ "vmaxsw", "A = (word vector) max(B, C)", 3},
{ "vmaxub", "A = (unsigned byte vector) max(B, C)", 3},
{ "vmaxud", "A = (vector) max(B, C)", 3},
{ "vmaxuh", "A = (unsigned half vector) max(B, C)", 3},
{ "vmaxuw", "A = (unsigned word vector) max(B, C)", 3},
// { "vmhaddshs", "A = (vector) B + C + D", 4},
// { "vmhraddshs", "A = (vector) B + C + D", 4},
{ "vminfp", "A = (float vector) min(B, C)", 3},
{ "vminsb", "A = (byte vector) min(B, C)", 3},
{ "vminsd", "A = (vector) min(B, C)", 3},
{ "vminsh", "A = (half vector) min(B, C)", 3},
{ "vminsw", "A = (word vector) min(B, C)", 3},
{ "vminub", "A = (unsigned byte vector) min(B, C)", 3},
{ "vminud", "A = (vector) min(B, C)", 3},
{ "vminuh", "A = (unsigned half vector) min(B, C)", 3},
{ "vminuw", "A = (unsigned word vector) min(B, C)", 3},
// { "vmladduhm", "A = (unsigned half vector) B + C", 3},
{ "vmrghb", "A = (byte vector) merge_hi(B, C)", 3},
{ "vmrghh", "A = (half vector) merge_hi(B, C)", 3},
{ "vmrghw", "A = (word vector) merge_hi(B, C)", 3},
{ "vmrglb", "A = (byte vector) merge_lo(B, C)", 3},
{ "vmrglh", "A = (half vector) merge_lo(B, C)", 3},
{ "vmrglw", "A = (word vector) merge_lo(B, C)", 3},
{ "vmsummbm", "A = (byte vector) B + C", 3},
{ "vmsumshm", "A = (half vector) B + C", 3},
{ "vmsumshs", "A = (half vector) B + C", 3},
{ "vmsumubm", "A = (unsigned byte vector) B + C", 3},
{ "vmsumuhm", "A = (unsigned half vector) B + C", 3},
{ "vmsumuhs", "A = (unsigned half vector) B + C", 3},
{ "vmulesb", "A = (byte vector) B * C", 3},
{ "vmulesh", "A = (half vector) B * C", 3},
{ "vmulesw", "A = (word vector) B * C", 3},
{ "vmuleub", "A = (unsigned byte vector) B * C", 3},
{ "vmuleuh", "A = (unsigned half vector) B * C", 3},
{ "vmuleuw", "A = (unsigned word vector) B * C", 3},
{ "vmulosb", "A = (byte vector) B * C", 3},
{ "vmulosh", "A = (byte vector) B * C", 3},
{ "vmulosw", "A = (byte vector) B * C", 3},
{ "vmuloub", "A = (byte vector) B * C", 3},
{ "vmulouh", "A = (unsigned byte vector) B * C", 3},
{ "vmulouw", "A = (unsigned byte vector) B * C", 3},
{ "vmuluwm", "A = (unsigned word vector) B * C", 3},
{ "vnand", "A = (vector) B & C", 3},
{ "vnmsubfp", "A = (float vector) (B * C) - round(D)", 4},
{ "vnor", "A = (vector) B | !C", 3},
{ "vor", "A = (vector) B | C", 3},
{ "vorc", "A = (vector) B | C", 3},
// This should be represented as a for loop of bits comparing.. too much complex for pseudo
// { "vperm", "A = (vector) B + C", 3},
{ "vpkpx", "A = (vector) pack_pixel(B, C)", 3},
{ "vpkshss", "A = (half vector) pack_pixel_saturate(B, C)", 3},
{ "vpkshus", "A = (unsigned half vector) pack_pixel_saturate(B, C)", 3},
{ "vpkswss", "A = (word vector) pack_pixel_saturate(B, C)", 3},
{ "vpkswus", "A = (unsigned word vector) pack_pixel_saturate(B, C)", 3},
// { "vpkuhum", "A = (vector) B + C", 3},
// { "vpkuhus", "A = (vector) B + C", 3},
// { "vpkuwum", "A = (vector) B + C", 3},
// { "vpkuwus", "A = (vector) B + C", 3},
{ "vpopcntb", "A = (vector) count_8bits(B)", 2},
{ "vpopcntd", "A = (vector) count_64bits(B)", 2},
{ "vpopcnth", "A = (vector) count_16bits(B)", 2},
{ "vpopcntw", "A = (vector) count_32bits(B)", 2},
{ "vrefp", "A = (float vector) 1/B", 2},
{ "vrfim", "A = (vector) floor(B)", 2},
{ "vrfin", "A = (vector) near(B)", 2},
{ "vrfip", "A = (vector) ceil(B)", 2},
{ "vrfiz", "A = (vector) trunc(B)", 2},
{ "vrlb", "A = (vector) rotl_byte(B, C)", 3},
{ "vrld", "A = (vector) rotl(B, C)", 3},
{ "vrlh", "A = (vector) rotl_half(B, C)", 3},
{ "vrlw", "A = (vector) rotl_word(B, C)", 3},
{ "vrsqrtefp", "A = (vector) sqrt(B)", 2},
{ "vsel", "A = (vector) if (D & 1) B else C", 4},
{ "vsl", "A = (vector) B << C", 3},
{ "vslb", "A = (byte vector) B << C", 3},
{ "vsld", "A = (vector) B << C", 3},
{ "vsldoi", "A = (vector) B << (octet) C", 3},
{ "vslh", "A = (half vector) B << C", 3},
{ "vslo", "A = (vector) B <<< (octet) C", 3},
{ "vslw", "A = (word vector) B + C", 3},
{ "vspltb", "A = (vector) splat_byte(B, C)", 3},
{ "vsplth", "A = (vector) splat_half(B, C)", 3},
{ "vspltisb", "A = (vector) splat_byte(B, C)", 3},
{ "vspltish", "A = (vector) splat_half(B, C)", 3},
{ "vspltisw", "A = (vector) splat_word(B, C)", 3},
{ "vspltw", "A = (vector) splat_word(B, C)", 3},
{ "vsr", "A = (vector) B >> C", 3},
{ "vsrab", "A = (byte vector) B >> C", 3},
{ "vsrad", "A = (vector) B >> C", 3},
{ "vsrah", "A = (half vector) B >> C", 3},
{ "vsraw", "A = (word vector) B >> C", 3},
{ "vsrb", "A = (byte vector) B >> C", 3},
{ "vsrd", "A = (vector) B >> C", 3},
{ "vsrh", "A = (half vector) B >> C", 3},
{ "vsro", "A = (vector) B >> (octet) C", 3},
{ "vsrw", "A = (word vector) B >> C", 3},
{ "vsubcuw", "A = (unsigned word vector) (C - B) & 1", 3},
{ "vsubfp", "A = (float vector) C - B", 3},
{ "vsubsbs", "A = (byte vector) C - B", 3},
{ "vsubshs", "A = (half vector) C - B", 3},
{ "vsubsws", "A = (word vector) C - B", 3},
{ "vsububm", "A = (byte vector) C - B", 3},
{ "vsububs", "A = (byte vector) C - B", 3},
{ "vsubudm", "A = (unsigned vector) C - B", 3},
{ "vsubuhm", "A = (unsigned half vector) C - B", 3},
{ "vsubuhs", "A = (unsigned half vector) C - B", 3},
{ "vsubuwm", "A = (unsigned word vector) C - B", 3},
{ "vsubuws", "A = (unsigned word vector) C - B", 3},
{ "vsumbsws", "A = (word vector) B + C", 3},
{ "vsumdsbs", "A = (byte vector) B + C", 3},
{ "vsumdshs", "A = (half vector) B + C", 3},
{ "vsumdubs", "A = (unsigned vector) B + C", 3},
{ "vsumsws", "A = (word vector) B + C", 3},
{ "vupkhpx", "A = (vector) unpack_hi_pixel(B)", 3},
{ "vupkhsb", "A = (byte vector) unpack_hi_pixel(B)", 3},
{ "vupkhsh", "A = (half vector) unpack_hi_pixel(B)", 3},
{ "vupklpx", "A = (vector) unpack_lo_pixel(B)", 3},
{ "vupklsb", "A = (byte vector) unpack_lo_pixel(B)", 3},
{ "vupklsh", "A = (half vector) unpack_lo_pixel(B)", 3},
{ "vxor", "A = (vector) B ^ C", 3},
{ "wait", "wait_interrupt", 0},
{ "waitimpl", "wait_interrupt_thread_reservation", 0},
{ "waitrsv", "wait_interrupt_implemention", 0},
{ "wrtee", "msr &= A", 1},
{ "wrteei", "msr &= A", 1},
{ "xnop", "", 0},
{ "xor", "A = B ^ C", 3},
{ "xori", "A = B ^ C", 3},
{ "xoris", "A = B ^ (C << 16)", 3},
{ "xsabsdp", "A = (double vector) abs(B)", 2},
{ "xsadddp", "A = (double vector) B + C", 3},
{ "xscmpodp", "A = (double vector) B == C", 3},
{ "xscmpudp", "A = (double vector) B == C", 3},
{ "xscpsgndp", "A = (double vector) copy_sign(B, C)", 3},
{ "xscvdpsp", "A = (double vector) round(B)", 2},
{ "xscvdpsxds", "A = (vector) ((double) B)", 2},
{ "xscvdpsxws", "A = (word vector) ((double) B)", 2},
{ "xscvdpuxds", "A = (unsigned vector) ((double) B)", 2},
{ "xscvdpuxws", "A = (unsigned word vector) ((double) B)", 2},
{ "xscvspdp", "A = (double vector) ((float) B)", 2},
{ "xscvsxddp", "A = (double vector) B", 2},
{ "xscvuxddp", "A = (double vector) ((unsigned) B)", 2},
{ "xsdivdp", "A = (double vector) B / C", 3},
// multiply add
// { "xsmaddadp", "A = (double vector) B * C + ?", 3},
// { "xsmaddmdp", "A = (double vector) B * C + ?", 3},
{ "xsmaxdp", "A = (double vector) max(B, C)", 3},
{ "xsmindp", "A = (double vector) min(B, C)", 3},
// multiply sub
// { "xsmsubadp", "A = (double vector) B * C - ?", 3},
// { "xsmsubmdp", "A = (double vector) B * C - ?", 3},
{ "xsmuldp", "A = (double vector) B * C", 3},
{ "xsnabsdp", "A = (double vector) -abs(B)", 2},
{ "xsnegdp", "A = (double vector) -B", 2},
// negative multiply add
// { "xsnmaddadp", "A = (double vector) B * C + ?", 3},
// { "xsnmaddmdp", "A = (double vector) B + C + ?", 3},
// negative multiply sub
// { "xsnmsubadp", "A = (double vector) B + C - ?", 3},
// { "xsnmsubmdp", "A = (double vector) B + C - ?", 3},
{ "xsrdpi", "A = (double vector) round(B)", 2},
{ "xsrdpic", "A = (double vector) round(B)", 2},
{ "xsrdpim", "A = (double vector) floor(B)", 2},
{ "xsrdpip", "A = (double vector) ceil(B)", 2},
{ "xsrdpiz", "A = (double vector) trunc(B)", 2},
{ "xsredp", "A = (double vector) 1/B", 2},
{ "xsrsqrtedp", "A = (double vector) 1/sqrt(B)", 2},
{ "xssqrtdp", "A = sqrt(B)", 2},
{ "xssubdp", "A = C - B", 3},
{ "xstdivdp", "A = test_sw_divide(B, C)", 3},
{ "xstsqrtdp", "A = test_sw_sqrt(B)", 2},
{ "xvabsdp", "A = (double vector) abs(B)", 2},
{ "xvabssp", "A = (float vector) abs(B)", 2},
{ "xvadddp", "A = (double vector) B + C", 3},
{ "xvaddsp", "A = (float vector) B + C", 3},
{ "xvcmpeqdp", "A = (double vector) B == (double vector) C", 3},
{ "xvcmpeqsp", "A = (float vector) B == (float vector) C", 3},
{ "xvcmpgedp", "A = (double vector) B >= (double vector) C", 3},
{ "xvcmpgesp", "A = (float vector) B >= (float vector) C", 3},
{ "xvcmpgtdp", "A = (double vector) B > (double vector) C", 3},
{ "xvcmpgtsp", "A = (float vector) B > (float vector) C", 3},
{ "xvcpsgndp", "A = (double vector) copy_sign(B, C)", 3},
{ "xvcpsgnsp", "A = (float vector) copy_sign(B, C)", 3},
{ "xvcvdpsp", "A = (float vector) ((double vector)B)", 2},
{ "xvcvdpsxds", "A = (vector) B", 2},
{ "xvcvdpsxws", "A = (word vector) B", 2},
{ "xvcvdpuxds", "A = (unsigned vector) B", 2},
{ "xvcvdpuxws", "A = (unsigned word vector) B", 2},
{ "xvcvspdp", "(double vector) ((float vector) B)", 2},
{ "xvcvspsxds", "A = (vector) ((float vector) B)", 2},
{ "xvcvspsxws", "A = (word vector) ((float vector) B)", 2},
{ "xvcvspuxds", "A = (unsigned vector) ((float vector) B)", 2},
{ "xvcvspuxws", "A = (unsigned word vector) ((float vector) B)", 2},
{ "xvcvsxddp", "A = (double vector) B", 2},
{ "xvcvsxdsp", "A = (float vector) B", 2},
{ "xvcvsxwdp", "A = (double vector) ((word) B)", 2},
{ "xvcvsxwsp", "A = (float vector) ((word) B)", 2},
{ "xvcvuxddp", "A = (double vector) (unsigned) B", 2},
{ "xvcvuxdsp", "A = (float vector) (unsigned) B", 2},
{ "xvcvuxwdp", "A = (double vector) ((unsigned word) B)", 2},
{ "xvcvuxwsp", "A = (float vector) ((unsigned word) B)", 2},
{ "xvdivdp", "A = (double vector) B / C", 3},
{ "xvdivsp", "A = (float vector) B / C", 3},
//Multiply add (double & float)
// { "xvmaddadp", "A = B + C", 3},
// { "xvmaddasp", "A = B + C", 3},
// { "xvmaddmdp", "A = B + C", 3},
// { "xvmaddmsp", "A = B + C", 3},
{ "xvmaxdp", "A = (double vector) max(B)", 2},
{ "xvmaxsp", "A = (float vector) max(B)", 2},
{ "xvmindp", "A = (double vector) min(B)", 2},
{ "xvminsp", "A = (float vector) min(B)", 2},
{ "xvmovdp", "A = (double vector) B", 2},
{ "xvmovsp", "A = (float vector) B", 2},
//Multiply sub (double & float)
// { "xvmsubadp", "A = B + C", 3},
// { "xvmsubasp", "A = B + C", 3},
// { "xvmsubmdp", "A = B + C", 3},
// { "xvmsubmsp", "A = B + C", 3},
{ "xvmuldp", "A = (double vector) B * C", 3},
{ "xvmulsp", "A = (float vector) B * C", 3},
{ "xvnabsdp", "A = (double vector) -abs(B)", 2},
{ "xvnabssp", "A = (float vector) -abs(B)", 2},
{ "xvnegdp", "A = (double vector) -B", 2},
{ "xvnegsp", "A = (float vector) -B", 2},
//Negate multiply add (double & float)
// { "xvnmaddadp", "A = B + C", 3},
// { "xvnmaddasp", "A = B + C", 3},
// { "xvnmaddmdp", "A = B + C", 3},
// { "xvnmaddmsp", "A = B + C", 3},
//Negate multiply sub (double & float)
// { "xvnmsubadp", "A = B + C", 3},
// { "xvnmsubasp", "A = B + C", 3},
// { "xvnmsubmdp", "A = B + C", 3},
// { "xvnmsubmsp", "A = B + C", 3},
{ "xvrdpi", "A = (double vector) round(B)", 2},
{ "xvrdpic", "A = (double vector) round(B)", 2},
{ "xvrdpim", "A = (double vector) floor(B)", 2},
{ "xvrdpip", "A = (double vector) ceil(B)", 2},
{ "xvrdpiz", "A = (double vector) trunc(B)", 2},
{ "xvredp", "A = (double vector) 1/B",2},
{ "xvresp", "A = (float vector) B", 2},
{ "xvrspi", "A = (float vector) round(B)", 2},
{ "xvrspic", "A = (float vector) round(B)", 2},
{ "xvrspim", "A = (float vector) floor(B)", 2},
{ "xvrspip", "A = (float vector) ceil(B)", 2},
{ "xvrspiz", "A = (float vector) trunc(B)", 2},
{ "xvrsqrtedp", "A = (double vector) 1/sqrt(B)", 2},
{ "xvrsqrtesp", "A = (float vector) 1/sqrt(B)", 2},
{ "xvsqrtdp", "A = (double vector) sqrt(B)", 2},
{ "xvsqrtsp", "A = (float vector) sqrt(B)", 2},
{ "xvsubdp", "A = (double vector) C - B", 3},
{ "xvsubsp", "A = (float vector) C - B", 3},
{ "xvtdivdp", "A = (double vector) B / C", 3},
{ "xvtdivsp", "A = (float vector) B / C", 3},
{ "xvtsqrtdp", "A = (double vector) test_sw_sqrt(B)", 3},
{ "xvtsqrtsp", "A = (float vector) test_sw_sqrt(B)", 3},
{ "xxland", "A = B & C", 3},
{ "xxlandc", "A = B & C", 3},
{ "xxleqv", "A = B ^ C", 3},
{ "xxlnand", "A = B & !C", 3},
{ "xxlnor", "A = B + !C", 3},
{ "xxlor", "A = B | C", 3},
{ "xxlorc", "A = B | C", 3},
{ "xxlxor", "A = B ^ C", 3},
{ "xxmrghd", "A = hi(B) || hi(C)", 3},
{ "xxmrghw", "A = (word vector) hi(B) || hi(C)", 3},
{ "xxmrgld", "A = lo(B) || lo(C)", 3},
{ "xxmrglw", "A = (word vector) lo(B) || lo(C)", 3},
// Permute Doubleword Immediate
// { "xxpermdi", "A = B + C", 3},
// Select (aka concat)
// { "xxsel", "A = B + C + D", 4},
{ "xxsldwi", "A = B << C", 3},
{ "xxspltd", "A = split(B)", 2},
{ "xxspltw", "A = (word vector) split(B)", 2},
{ "xxswapd", "swap(A,B)", 2},
{ NULL }
};
for (i = 0; ops[i].op != NULL; i++) {
if (!strcmp (ops[i].op, argv[0])) {
if (newstr) {
for (j = k = 0; ops[i].str[j] != '\0'; j++, k++) {
if (can_replace(ops[i].str, j, ops[i].max_operands)) {
if (i >= 0 && i <= 26 && argv[ops[i].max_operands][0] == 0) {
char* tmp = (char*) argv[ops[i].max_operands];
argv[ops[i].max_operands] = argv[ops[i].max_operands - 1];
if (ops[i].max_operands == 3) {
argv[2] = argv[1];
}
tmp[0] = 'c';
tmp[1] = 'r';
tmp[2] = '0';
tmp[3] = '\0';
argv[1] = tmp;
}
int letter = ops[i].str[j] - '@';
const char *w = argv[letter];
if (letter == 4 && i == 27) {
w = inv_mask64 (argv[4], argv[3]);
} else if (letter == 4 && i >= 28 && i <= 29) {
w = cmask64 (w, "63");
} else if (letter == 4 && i >= 30 && i <= 31) {
w = cmask64 ("0", w);
} else if (letter == 4 && i == 32) {
w = inv_mask64 (argv[4], argv[3]);
} else if (letter == 4 && i >= 33 && i <= 35) {
w = cmask32 (argv[3], argv[4]);
} else if (letter == 1 && i >= 36 && i <= 43) {
int to = atoi (w);
switch(to) {
case 4:
w = "==";
case 1:
case 8:
w = ">";
case 5:
case 12:
w = ">=";
case 2:
case 16:
w = "<";
case 6:
case 20:
w = "<=";
case 24:
w = "!=";
case 31:
// If no parameters t[dw][i] 32, 0, 0 just TRAP
w = "==";
}
w = cmask64("0", w);
} else if ((i == 44 && letter == 2) || (i == 45 && letter == 1)) { //spr
w = getspr(w);
}
if (w != NULL) {
strcpy (newstr + k, w);
k += strlen(w) - 1;
}
} else {
newstr[k] = ops[i].str[j];
}
}
newstr[k]='\0';
}
return true;
}
}
/* TODO: this is slow */
if (newstr) {
newstr[0] = '\0';
for (i = 0; i < argc; i++) {
strcat (newstr, argv[i]);
strcat (newstr, (i == 0 || i == argc - 1) ? " ":", ");
}
}
return false;
}
#define WSZ 128
static int parse(RParse *p, const char *data, char *str) {
int i, len = strlen (data);
char w0[WSZ];
char w1[WSZ];
char w2[WSZ];
char w3[WSZ];
char w4[WSZ];
char *buf, *ptr, *optr;
if (!strcmp (data, "jr ra")) {
strcpy (str, "return");
return true;
}
// malloc can be slow here :?
if (!(buf = malloc (len + 1))) {
return false;
}
memcpy (buf, data, len + 1);
r_str_replace_char (buf, '(', ',');
r_str_replace_char (buf, ')', ' ');
r_str_chop (buf);
if (*buf) {
w0[0] = '\0';
w1[0] = '\0';
w2[0] = '\0';
w3[0] = '\0';
w4[0] = '\0';
ptr = strchr (buf, ' ');
if (!ptr) {
ptr = strchr (buf, '\t');
}
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w0, buf, WSZ - 1);
strncpy (w1, ptr, WSZ - 1);
optr = ptr;
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w1, optr, WSZ - 1);
strncpy (w2, ptr, WSZ - 1);
optr = ptr;
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w2, optr, WSZ - 1);
strncpy (w3, ptr, WSZ - 1);
optr = ptr;
// bonus
ptr = strchr (ptr, ',');
if (ptr) {
*ptr = '\0';
for (++ptr; *ptr == ' '; ptr++) {
//nothing to see here
}
strncpy (w3, optr, WSZ - 1);
strncpy (w4, ptr, WSZ - 1);
}
}
}
} else {
strncpy (w0, buf, WSZ - 1);
}
{
const char *wa[] = { w0, w1, w2, w3, w4 };
int nw = 0;
for (i = 0; i < 4; i++) {
if (wa[i][0] != '\0') {
nw++;
}
}
replace (nw, wa, str);
{
char *p = strdup (str);
p = r_str_replace (p, "+ -", "- ", 0);
p = r_str_replace (p, " + ]", "] ", 0);
// p = r_str_replace (p, "if (r0 == r0) trap", "trap ", 0);
#if EXPERIMENTAL_ZERO
p = r_str_replace (p, "zero", "0", 0);
if (!memcmp (p, "0 = ", 4)) *p = 0; // nop
#endif
if (!strcmp (w1, w2)) {
char a[64], b[64];
#define REPLACE(x,y) \
snprintf (a, 64, x, w1, w1); \
snprintf (b, 64, y, w1); \
p = r_str_replace (p, a, b, 0);
// TODO: optimize
REPLACE ("%s = %s +", "%s +=");
REPLACE ("%s = %s -", "%s -=");
REPLACE ("%s = %s &", "%s &=");
REPLACE ("%s = %s |", "%s |=");
REPLACE ("%s = %s ^", "%s ^=");
REPLACE ("%s = %s >>", "%s >>=");
REPLACE ("%s = %s <<", "%s <<=");
}
p = r_str_replace (p, ":", "0000", 0);
strcpy (str, p);
free (p);
}
}
}
free (buf);
return true;
}
struct r_parse_plugin_t r_parse_plugin_ppc_pseudo = {
.name = "ppc.pseudo",
.desc = "PowerPC pseudo syntax",
.parse = parse,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_PARSE,
.data = &r_parse_plugin_ppc_pseudo,
.version = R2_VERSION
};
#endif