📄 ppc-opc.c
字号:
uval = value; if (uval == 0) { if (errmsg != (const char **) NULL) *errmsg = "illegal bitmask"; return insn; } me = 31; while ((uval & 1) == 0) { uval >>= 1; --me; } mb = me; uval >>= 1; while ((uval & 1) != 0) { uval >>= 1; --mb; } if (uval != 0) { if (errmsg != (const char **) NULL) *errmsg = "illegal bitmask"; } return insn | (mb << 6) | (me << 1);}static longextract_mbe (insn, invalid) unsigned long insn; int *invalid;{ long ret; int mb, me; int i; if (invalid != (int *) NULL) *invalid = 1; ret = 0; mb = (insn >> 6) & 0x1f; me = (insn >> 1) & 0x1f; for (i = mb; i < me; i++) ret |= 1 << (31 - i); return ret;}/* The MB or ME field in an MD or MDS form instruction. The high bit is wrapped to the low end. *//*ARGSUSED*/static unsigned longinsert_mb6 (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ return insn | ((value & 0x1f) << 6) | (value & 0x20);}/*ARGSUSED*/static longextract_mb6 (insn, invalid) unsigned long insn; int *invalid;{ return ((insn >> 6) & 0x1f) | (insn & 0x20);}/* The NB field in an X form instruction. The value 32 is stored as 0. */static unsigned longinsert_nb (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ if (value < 0 || value > 32) *errmsg = "value out of range"; if (value == 32) value = 0; return insn | ((value & 0x1f) << 11);}/*ARGSUSED*/static longextract_nb (insn, invalid) unsigned long insn; int *invalid;{ long ret; ret = (insn >> 11) & 0x1f; if (ret == 0) ret = 32; return ret;}/* The NSI field in a D form instruction. This is the same as the SI field, only negated. The extraction function always marks it as invalid, since we never want to recognize an instruction which uses a field of this type. *//*ARGSUSED*/static unsigned longinsert_nsi (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ return insn | ((- value) & 0xffff);}static longextract_nsi (insn, invalid) unsigned long insn; int *invalid;{ if (invalid != (int *) NULL) *invalid = 1; if ((insn & 0x8000) != 0) return - ((insn & 0xffff) - 0x10000); else return - (insn & 0xffff);}/* 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. */static unsigned longinsert_ral (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ if (value == 0 || value == ((insn >> 21) & 0x1f)) *errmsg = "invalid register operand when updating"; return insn | ((value & 0x1f) << 16);}/* The RA field in an lmw instruction, which has special value restrictions. */static unsigned longinsert_ram (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ if (value >= ((insn >> 21) & 0x1f)) *errmsg = "index register in load range"; 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. */static unsigned longinsert_ras (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ if (value == 0) *errmsg = "invalid register operand when updating"; return insn | ((value & 0x1f) << 16);}/* The RB field in an X form instruction when it must be the same as the RS field in the instruction. This is used for extended mnemonics like mr. This operand is marked FAKE. The insertion function just copies the BT field into the BA field, and the extraction function just checks that the fields are the same. *//*ARGSUSED*/static unsigned long insert_rbs (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ return insn | (((insn >> 21) & 0x1f) << 11);}static longextract_rbs (insn, invalid) unsigned long insn; int *invalid;{ if (invalid != (int *) NULL && ((insn >> 21) & 0x1f) != ((insn >> 11) & 0x1f)) *invalid = 1; return 0;}/* The SH field in an MD form instruction. This is split. *//*ARGSUSED*/static unsigned longinsert_sh6 (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);}/*ARGSUSED*/static longextract_sh6 (insn, invalid) unsigned long insn; int *invalid;{ return ((insn >> 11) & 0x1f) | ((insn << 4) & 0x20);}/* The SPR field in an XFX form instruction. This is flipped--the lower 5 bits are stored in the upper 5 and vice- versa. */static unsigned longinsert_spr (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);}static longextract_spr (insn, invalid) unsigned long insn; int *invalid;{ return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);}/* The TBR field in an XFX instruction. This is just like SPR, but it is optional. When TBR is omitted, it must be inserted as 268 (the magic number of the TB register). These functions treat 0 (indicating an omitted optional operand) as 268. This means that ``mftb 4,0'' is not handled correctly. This does not matter very much, since the architecture manual does not define mftb as accepting any values other than 268 or 269. */#define TB (268)static unsigned longinsert_tbr (insn, value, errmsg) unsigned long insn; long value; const char **errmsg;{ if (value == 0) value = TB; return insn | ((value & 0x1f) << 16) | ((value & 0x3e0) << 6);}static longextract_tbr (insn, invalid) unsigned long insn; int *invalid;{ long ret; ret = ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); if (ret == TB) ret = 0; return ret;}/* Macros used to form opcodes. *//* The main opcode. */#define OP(x) (((x) & 0x3f) << 26)#define OP_MASK OP (0x3f)/* The main opcode combined with a trap code in the TO field of a D form instruction. Used for extended mnemonics for the trap instructions. */#define OPTO(x,to) (OP (x) | (((to) & 0x1f) << 21))#define OPTO_MASK (OP_MASK | TO_MASK)/* The main opcode combined with a comparison size bit in the L field of a D form or X form instruction. Used for extended mnemonics for the comparison instructions. */#define OPL(x,l) (OP (x) | (((l) & 1) << 21))#define OPL_MASK OPL (0x3f,1)/* An A form instruction. */#define A(op, xop, rc) (OP (op) | (((xop) & 0x1f) << 1) | ((rc) & 1))#define A_MASK A (0x3f, 0x1f, 1)/* An A_MASK with the FRB field fixed. */#define AFRB_MASK (A_MASK | FRB_MASK)/* An A_MASK with the FRC field fixed. */#define AFRC_MASK (A_MASK | FRC_MASK)/* An A_MASK with the FRA and FRC fields fixed. */#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)/* A B form instruction. */#define B(op, aa, lk) (OP (op) | (((aa) & 1) << 1) | ((lk) & 1))#define B_MASK B (0x3f, 1, 1)/* A B form instruction setting the BO field. */#define BBO(op, bo, aa, lk) (B ((op), (aa), (lk)) | (((bo) & 0x1f) << 21))#define BBO_MASK BBO (0x3f, 0x1f, 1, 1)/* A BBO_MASK with the y bit of the BO field removed. This permits matching a conditional branch regardless of the setting of the y bit. */#define Y_MASK (1 << 21)#define BBOY_MASK (BBO_MASK &~ Y_MASK)/* A B form instruction setting the BO field and the condition bits of the BI field. */#define BBOCB(op, bo, cb, aa, lk) \ (BBO ((op), (bo), (aa), (lk)) | (((cb) & 0x3) << 16))#define BBOCB_MASK BBOCB (0x3f, 0x1f, 0x3, 1, 1)/* A BBOCB_MASK with the y bit of the BO field removed. */#define BBOYCB_MASK (BBOCB_MASK &~ Y_MASK)/* A BBOYCB_MASK in which the BI field is fixed. */#define BBOYBI_MASK (BBOYCB_MASK | BI_MASK)/* The main opcode mask with the RA field clear. */#define DRA_MASK (OP_MASK | RA_MASK)/* A DS form instruction. */#define DSO(op, xop) (OP (op) | ((xop) & 0x3))#define DS_MASK DSO (0x3f, 3)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -