diff options
Diffstat (limited to 'opcodes/ppc-opc.c')
-rw-r--r-- | opcodes/ppc-opc.c | 120 |
1 files changed, 116 insertions, 4 deletions
diff --git a/opcodes/ppc-opc.c b/opcodes/ppc-opc.c index 27eb23e..a6e9313 100644 --- a/opcodes/ppc-opc.c +++ b/opcodes/ppc-opc.c @@ -68,6 +68,10 @@ static unsigned long insert_boe PARAMS ((unsigned long, long, int, const char **)); static long extract_boe PARAMS ((unsigned long, int, int *)); +static unsigned long insert_dq + PARAMS ((unsigned long, long, int, const char **)); +static long extract_dq + PARAMS ((unsigned long, int, int *)); static unsigned long insert_ds PARAMS ((unsigned long, long, int, const char **)); static long extract_ds @@ -104,12 +108,18 @@ static unsigned long insert_ral PARAMS ((unsigned long, long, int, const char **)); static unsigned long insert_ram PARAMS ((unsigned long, long, int, const char **)); +static unsigned long insert_raq + PARAMS ((unsigned long, long, int, const char **)); static unsigned long insert_ras PARAMS ((unsigned long, long, int, const char **)); static unsigned long insert_rbs PARAMS ((unsigned long, long, int, const char **)); static long extract_rbs PARAMS ((unsigned long, int, int *)); +static unsigned long insert_rsq + PARAMS ((unsigned long, long, int, const char **)); +static unsigned long insert_rtq + PARAMS ((unsigned long, long, int, const char **)); static unsigned long insert_sh6 PARAMS ((unsigned long, long, int, const char **)); static long extract_sh6 @@ -279,9 +289,15 @@ const struct powerpc_operand powerpc_operands[] = #define DES DE + 1 { 14, 0, insert_des, extract_des, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED }, + /* The DQ field in a DQ form instruction. This is like D, but the + lower four bits are forced to zero. */ +#define DQ DES + 1 + { 16, 0, insert_dq, extract_dq, + PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DQ }, + /* The DS field in a DS form instruction. This is like D, but the lower two bits are forced to zero. */ -#define DS DES + 1 +#define DS DQ + 1 { 16, 0, insert_ds, extract_ds, PPC_OPERAND_PARENS | PPC_OPERAND_SIGNED | PPC_OPERAND_DS }, @@ -389,15 +405,20 @@ const struct powerpc_operand powerpc_operands[] = { 16, 0, insert_nsi, extract_nsi, PPC_OPERAND_NEGATIVE | PPC_OPERAND_SIGNED }, - /* The RA field in an D, DS, X, XO, M, or MDS form instruction. */ + /* The RA field in an D, DS, DQ, X, XO, M, or MDS form instruction. */ #define RA NSI + 1 #define RA_MASK (0x1f << 16) { 5, 16, 0, 0, PPC_OPERAND_GPR }, + /* The RA field in the DQ form lq instruction, which has special + value restrictions. */ +#define RAQ RA + 1 + { 5, 16, insert_raq, 0, PPC_OPERAND_GPR }, + /* The RA field in a D or X form instruction which is an updating load, which means that the RA field may not be zero and may not equal the RT field. */ -#define RAL RA + 1 +#define RAL RAQ + 1 { 5, 16, insert_ral, 0, PPC_OPERAND_GPR }, /* The RA field in an lmw instruction, which has special value @@ -430,8 +451,18 @@ const struct powerpc_operand powerpc_operands[] = #define RT_MASK (0x1f << 21) { 5, 21, 0, 0, PPC_OPERAND_GPR }, + /* The RS field of the DS form stq instruction, which has special + value restrictions. */ +#define RSQ RS + 1 + { 5, 21, insert_rsq, 0, PPC_OPERAND_GPR }, + + /* The RT field of the DQ form lq instruction, which has special + value restrictions. */ +#define RTQ RSQ + 1 + { 5, 21, insert_rtq, 0, PPC_OPERAND_GPR }, + /* The SH field in an X or M form instruction. */ -#define SH RS + 1 +#define SH RTQ + 1 #define SH_MASK (0x1f << 11) { 5, 11, 0, 0, 0 }, @@ -870,6 +901,32 @@ extract_boe (insn, dialect, invalid) return value & 0x1e; } + /* The DQ field in a DQ form instruction. This is like D, but the + lower four bits are forced to zero. */ + +/*ARGSUSED*/ +static unsigned long +insert_dq (insn, value, dialect, errmsg) + unsigned long insn; + long value; + int dialect ATTRIBUTE_UNUSED; + const char ** errmsg ATTRIBUTE_UNUSED; +{ + if ((value & 0xf) != 0 && errmsg != NULL) + *errmsg = _("offset not a multiple of 16"); + return insn | (value & 0xfff0); +} + +/*ARGSUSED*/ +static long +extract_dq (insn, dialect, invalid) + unsigned long insn; + int dialect ATTRIBUTE_UNUSED; + int *invalid ATTRIBUTE_UNUSED; +{ + return ((insn & 0xfff0) ^ 0x8000) - 0x8000; +} + static unsigned long insert_ev2 (insn, value, dialect, errmsg) unsigned long insn; @@ -1253,6 +1310,24 @@ insert_ram (insn, value, dialect, errmsg) return insn | ((value & 0x1f) << 16); } + /* The RA field in the DQ form lq instruction, which has special + value restrictions. */ + +/*ARGSUSED*/ +static unsigned long +insert_raq (insn, value, dialect, errmsg) + unsigned long insn; + long value; + int dialect ATTRIBUTE_UNUSED; + const char **errmsg; +{ + long rtvalue = (insn & RT_MASK) >> 21; + + if (value == rtvalue && errmsg != NULL) + *errmsg = _("source and target register operands must be different"); + return insn | ((value & 0x1f) << 16); +} + /* The RA field in a D or X form instruction which is an updating store or an updating floating point load, which means that the RA field may not be zero. */ @@ -1298,6 +1373,38 @@ extract_rbs (insn, dialect, invalid) return 0; } + /* The RT field of the DQ form lq instruction, which has special + value restrictions. */ + +/*ARGSUSED*/ +static unsigned long +insert_rtq (insn, value, dialect, errmsg) + unsigned long insn; + long value; + int dialect ATTRIBUTE_UNUSED; + const char **errmsg; +{ + if ((value & 1) != 0 && errmsg != NULL) + *errmsg = _("target register operand must be even"); + return insn | ((value & 0x1f) << 21); +} + + /* The RS field of the DS form stq instruction, which has special + value restrictions. */ + +/*ARGSUSED*/ +static unsigned long +insert_rsq (insn, value, dialect, errmsg) + unsigned long insn; + long value ATTRIBUTE_UNUSED; + int dialect ATTRIBUTE_UNUSED; + const char **errmsg; +{ + if ((value & 1) != 0 && errmsg != NULL) + *errmsg = _("source register operand must be even"); + return insn | ((value & 0x1f) << 21); +} + /* The SH field in an MD form instruction. This is split. */ /*ARGSUSED*/ @@ -1768,6 +1875,7 @@ extract_tbr (insn, dialect, invalid) sorted by major opcode. */ const struct powerpc_opcode powerpc_opcodes[] = { +{ "attn", X(0,256), X_MASK, POWER4, { 0 } }, { "tdlgti", OPTO(2,TOLGT), OPTO_MASK, PPC64, { RA, SI } }, { "tdllti", OPTO(2,TOLLT), OPTO_MASK, PPC64, { RA, SI } }, { "tdeqi", OPTO(2,TOEQ), OPTO_MASK, PPC64, { RA, SI } }, @@ -4335,6 +4443,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } }, +{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } }, + { "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } }, { "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } }, @@ -4411,6 +4521,8 @@ const struct powerpc_opcode powerpc_opcodes[] = { { "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } }, +{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA } }, + { "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, { "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } }, |