📄 parser.y
字号:
| Y_USW_POP SRC1 ADDRESS {#ifdef BIGENDIAN i_type_inst (Y_SWL_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); i_type_inst_free (Y_SWR_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 3));#else i_type_inst_free (Y_SWL_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 3)); i_type_inst (Y_SWR_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p));#endif free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | Y_USH_POP SRC1 ADDRESS { i_type_inst (Y_SB_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); /* ROL SRC, SRC, 8 */ r_sh_type_inst (Y_SLL_OP, 1, $2.i, 24); r_sh_type_inst (Y_SRL_OP, $2.i, $2.i, 8); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); i_type_inst_free (Y_SB_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 1)); /* ROR SRC, SRC, 8 */ r_sh_type_inst (Y_SRL_OP, 1, $2.i, 24); r_sh_type_inst (Y_SLL_OP, $2.i, $2.i, 8); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | STOREFP_OPS F_SRC1 ADDRESS { i_type_inst ($1.i, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | STOREFP_INDEX_OPS F_DEST ADDRESS { mips32_r2_inst (); } | SYS_OPS { r_type_inst ($1.i, 0, 0, 0); } | PREFETCH_OPS ADDRESS { mips32_r2_inst (); } | CACHE_OPS Y_INT ADDRESS { i_type_inst_free ($1.i, $2.i, 0, (imm_expr *)$3.p); } | TLB_OPS { r_type_inst ($1.i, 0, 0, 0); } | Y_SYNC_OP { r_type_inst ($1.i, 0, 0, 0); } | Y_SYNC_OP Y_INT { r_type_inst ($1.i, $2.i, 0, 0); } | Y_BREAK_OP Y_INT { if ($2.i == 1) yyerror ("Breakpoint 1 is reserved for debugger"); r_type_inst ($1.i, $2.i, 0, 0); } | Y_NOP_POP { nop_inst (); } | Y_SSNOP_OP { r_sh_type_inst (Y_SLL_OP, 0, 0, 1); /* SLL r0 r0 1 */ } | Y_ABS_POP DEST SRC1 { if ($2.i != $3.i) r_type_inst (Y_ADDU_OP, $2.i, 0, $3.i); i_type_inst_free (Y_BGEZ_OP, 0, $3.i, branch_offset (2)); r_type_inst (Y_SUB_OP, $2.i, 0, $3.i); } | Y_NEG_POP DEST SRC1 { r_type_inst (Y_SUB_OP, $2.i, 0, $3.i); } | Y_NEGU_POP DEST SRC1 { r_type_inst (Y_SUBU_OP, $2.i, 0, $3.i); } | Y_NOT_POP DEST SRC1 { r_type_inst (Y_NOR_OP, $2.i, $3.i, 0); } | Y_MOVE_POP DEST SRC1 { r_type_inst (Y_ADDU_OP, $2.i, 0, $3.i); } | NULLARY_OPS { r_type_inst ($1.i, 0, 0, 0); } | NULLARY_OPS_REV2 { mips32_r2_inst (); } | COUNT_LEADING_OPS DEST SRC1 { /* RT must be equal to RD */ r_type_inst ($1.i, $2.i, $3.i, $2.i); } | UNARY_OPS_REV2 DEST { mips32_r2_inst (); } | BINARYI_OPS DEST SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | BINARYI_OPS DEST SRC1 IMM32 { i_type_inst_free (op_to_imm_op ($1.i), $2.i, $3.i, (imm_expr *)$4.p); } | BINARYI_OPS DEST IMM32 { i_type_inst_free (op_to_imm_op ($1.i), $2.i, $2.i, (imm_expr *)$3.p); } | BINARYIR_OPS DEST SRC1 SRC2 { r_type_inst ($1.i, $2.i, $4.i, $3.i); } | BINARYIR_OPS DEST SRC1 Y_INT { r_sh_type_inst (op_to_imm_op ($1.i), $2.i, $3.i, $4.i); } | BINARYIR_OPS DEST Y_INT { r_sh_type_inst (op_to_imm_op ($1.i), $2.i, $2.i, $3.i); } | BINARY_ARITHI_OPS DEST SRC1 IMM16 { i_type_inst_free ($1.i, $2.i, $3.i, (imm_expr *)$4.p); } | BINARY_ARITHI_OPS DEST IMM16 { i_type_inst_free ($1.i, $2.i, $2.i, (imm_expr *)$3.p); } | BINARY_LOGICALI_OPS DEST SRC1 UIMM16 { i_type_inst_free ($1.i, $2.i, $3.i, (imm_expr *)$4.p); } | BINARY_LOGICALI_OPS DEST UIMM16 { i_type_inst_free ($1.i, $2.i, $2.i, (imm_expr *)$3.p); } | SHIFT_OPS DEST SRC1 Y_INT { if (($4.i < 0) || (31 < $4.i)) yywarn ("Shift distance can only be in the range 0..31"); r_sh_type_inst ($1.i, $2.i, $3.i, $4.i); } | SHIFT_OPS DEST SRC1 SRC2 { r_type_inst (imm_op_to_op ($1.i), $2.i, $4.i, $3.i); } | SHIFT_OPS_REV2 DEST SRC1 Y_INT { mips32_r2_inst (); } | SHIFTV_OPS_REV2 DEST SRC1 SRC2 { mips32_r2_inst (); } | BINARY_OPS DEST SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | BINARY_OPS DEST SRC1 IMM32 { if (bare_machine && !accept_pseudo_insts) yyerror ("Immediate form not allowed in bare machine"); else { if (!zero_imm ((imm_expr *)$4.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); r_type_inst ($1.i, $2.i, $3.i, (zero_imm ((imm_expr *)$4.p) ? 0 : 1)); } free ((imm_expr *)$4.p); } | BINARY_OPS DEST IMM32 { check_uimm_range ((imm_expr *)$3.p, UIMM_MIN, UIMM_MAX); if (bare_machine && !accept_pseudo_insts) yyerror ("Immediate form not allowed in bare machine"); else { if (!zero_imm ((imm_expr *)$3.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3.p); r_type_inst ($1.i, $2.i, $2.i, (zero_imm ((imm_expr *)$3.p) ? 0 : 1)); } free ((imm_expr *)$3.p); } | BINARY_OPS_REV2 DEST SRC1 { mips32_r2_inst (); } | SUB_OPS DEST SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | SUB_OPS DEST SRC1 IMM32 { int val = eval_imm_expr ((imm_expr *)$4.p); if (bare_machine && !accept_pseudo_insts) yyerror ("Immediate form not allowed in bare machine"); else i_type_inst ($1.i == Y_SUB_OP ? Y_ADDI_OP : $1.i == Y_SUBU_OP ? Y_ADDIU_OP : (fatal_error ("Bad SUB_OP\n"), 0), $2.i, $3.i, make_imm_expr (-val, NULL, 0)); free ((imm_expr *)$4.p); } | SUB_OPS DEST IMM32 { int val = eval_imm_expr ((imm_expr *)$3.p); if (bare_machine && !accept_pseudo_insts) yyerror ("Immediate form not allowed in bare machine"); else i_type_inst ($1.i == Y_SUB_OP ? Y_ADDI_OP : $1.i == Y_SUBU_OP ? Y_ADDIU_OP : (fatal_error ("Bad SUB_OP\n"), 0), $2.i, $2.i, make_imm_expr (-val, NULL, 0)); free ((imm_expr *)$3.p); } | DIV_POPS DEST SRC1 { /* The hardware divide operation (ignore 1st arg) */ if ($1.i != Y_DIV_OP && $1.i != Y_DIVU_OP) yyerror ("REM requires 3 arguments"); else r_type_inst ($1.i, 0, $2.i, $3.i); } | DIV_POPS DEST SRC1 SRC2 { /* Pseudo divide operations */ div_inst ($1.i, $2.i, $3.i, $4.i, 0); } | DIV_POPS DEST SRC1 IMM32 { if (zero_imm ((imm_expr *)$4.p)) yyerror ("Divide by zero"); else { /* Use $at */ i_type_inst_free (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); div_inst ($1.i, $2.i, $3.i, 1, 1); } } | MUL_POPS DEST SRC1 SRC2 { mult_inst ($1.i, $2.i, $3.i, $4.i); } | MUL_POPS DEST SRC1 IMM32 { if (zero_imm ((imm_expr *)$4.p)) /* Optimize: n * 0 == 0 */ i_type_inst_free (Y_ORI_OP, $2.i, 0, (imm_expr *)$4.p); else { /* Use $at */ i_type_inst_free (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); mult_inst ($1.i, $2.i, $3.i, 1); } } | MULT_OPS SRC1 SRC2 { r_type_inst ($1.i, 0, $2.i, $3.i); } | MULT_OPS3 DEST SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | MULT_OPS3 DEST SRC1 IMM32 { /* Special case, for backward compatibility with pseudo-op MULT instruction */ i_type_inst_free (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); /* Use $at */ r_type_inst ($1.i, $2.i, $3.i, 1); } | Y_ROR_POP DEST SRC1 SRC2 { r_type_inst (Y_SUBU_OP, 1, 0, $4.i); r_type_inst (Y_SLLV_OP, 1, 1, $3.i); r_type_inst (Y_SRLV_OP, $2.i, $4.i, $3.i); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); } | Y_ROL_POP DEST SRC1 SRC2 { r_type_inst (Y_SUBU_OP, 1, 0, $4.i); r_type_inst (Y_SRLV_OP, 1, 1, $3.i); r_type_inst (Y_SLLV_OP, $2.i, $4.i, $3.i); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); } | Y_ROR_POP DEST SRC1 IMM32 { long dist = eval_imm_expr ((imm_expr *)$4.p); check_imm_range ((imm_expr *)$4.p, 0, 31); r_sh_type_inst (Y_SLL_OP, 1, $3.i, -dist); r_sh_type_inst (Y_SRL_OP, $2.i, $3.i, dist); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); free ((imm_expr *)$4.p); } | Y_ROL_POP DEST SRC1 IMM32 { long dist = eval_imm_expr ((imm_expr *)$4.p); check_imm_range ((imm_expr *)$4.p, 0, 31); r_sh_type_inst (Y_SRL_OP, 1, $3.i, -dist); r_sh_type_inst (Y_SLL_OP, $2.i, $3.i, dist); r_type_inst (Y_OR_OP, $2.i, $2.i, 1); free ((imm_expr *)$4.p); } | BF_OPS_REV2 F_DEST F_SRC2 Y_INT Y_INT { mips32_r2_inst (); } | SET_LE_POPS DEST SRC1 SRC2 { set_le_inst ($1.i, $2.i, $3.i, $4.i); } | SET_LE_POPS DEST SRC1 IMM32 { if (!zero_imm ((imm_expr *)$4.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); set_le_inst ($1.i, $2.i, $3.i, (zero_imm ((imm_expr *)$4.p) ? 0 : 1)); free ((imm_expr *)$4.p); } | SET_GT_POPS DEST SRC1 SRC2 { set_gt_inst ($1.i, $2.i, $3.i, $4.i); } | SET_GT_POPS DEST SRC1 IMM32 { if (!zero_imm ((imm_expr *)$4.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); set_gt_inst ($1.i, $2.i, $3.i, (zero_imm ((imm_expr *)$4.p) ? 0 : 1)); free ((imm_expr *)$4.p); } | SET_GE_POPS DEST SRC1 SRC2 { set_ge_inst ($1.i, $2.i, $3.i, $4.i); } | SET_GE_POPS DEST SRC1 IMM32 { if (!zero_imm ((imm_expr *)$4.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); set_ge_inst ($1.i, $2.i, $3.i, (zero_imm ((imm_expr *)$4.p) ? 0 : 1)); free ((imm_expr *)$4.p); } | SET_EQ_POPS DEST SRC1 SRC2 { set_eq_inst ($1.i, $2.i, $3.i, $4.i); } | SET_EQ_POPS DEST SRC1 IMM32 { if (!zero_imm ((imm_expr *)$4.p)) /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$4.p); set_eq_inst ($1.i, $2.i, $3.i, (zero_imm ((imm_expr *)$4.p) ? 0 : 1)); free ((imm_expr *)$4.p); } | BR_COP_OPS LABEL { /* RS and RT fields contain information on test */ int nd = opcode_is_nullified_branch ($1.i); int tf = opcode_is_true_branch ($1.i); i_type_inst_free ($1.i, cc_to_rt (0, nd, tf), BIN_RS ($1.i), (imm_expr *)$2.p); } | BR_COP_OPS CC_REG LABEL { /* RS and RT fields contain information on test */ int nd = opcode_is_nullified_branch ($1.i); int tf = opcode_is_true_branch ($1.i); i_type_inst_free ($1.i, cc_to_rt ($2.i, nd, tf), BIN_RS ($1.i), (imm_expr *)$3.p); } | UNARY_BR_OPS SRC1 LABEL { i_type_inst_free ($1.i, 0, $2.i, (imm_expr *)$3.p); } | UNARY_BR_POPS SRC1 LABEL { i_type_inst_free ($1.i == Y_BEQZ_POP ? Y_BEQ_OP : Y_BNE_OP, 0, $2.i, (imm_expr *)$3.p); } | BINARY_BR_OPS SRC1 SRC2 LABEL { i_type_inst_free ($1.i, $3.i, $2.i, (imm_expr *)$4.p); } | BINARY_BR_OPS SRC1 BR_IMM32 LABEL { if (bare_machine && !accept_pseudo_insts) yyerror ("Immediate form not allowed in bare machine"); else { if (zero_imm ((imm_expr *)$3.p)) i_type_inst ($1.i, $2.i, (zero_imm ((imm_expr *)$3.p) ? 0 : 1), (imm_expr *)$4.p); else { /* Use $at */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3.p); i_type_inst ($1.i, $2.i, (zero_imm ((imm_expr *)$3.p) ? 0 : 1), (imm_expr *)$4.p); } } free ((imm_expr *)$3.p); free ((imm_expr *)$4.p); } | BR_GT_POPS SRC1 SRC2 LABEL { r_type_inst ($1.i == Y_BGT_POP ? Y_SLT_OP : Y_SLTU_OP, 1, $3.i, $2.i); /* Use $at */ i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4.p); } | BR_GT_POPS SRC1 BR_IMM32 LABEL { if ($1.i == Y_BGT_POP) { /* Use $at */ i_type_inst_free (Y_SLTI_OP, 1, $2.i, incr_expr_offset ((imm_expr *)$3.p, 1)); i_type_inst (Y_BEQ_OP, 0, 1, (imm_expr *)$4.p); } else { /* Use $at */ /* Can't add 1 to immediate since 0xffffffff+1 = 0 < 1 */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3.p); i_type_inst_free (Y_BEQ_OP, $2.i, 1, branch_offset (3)); r_type_inst (Y_SLTU_OP, 1, $2.i, 1); i_type_inst (Y_BEQ_OP, 0, 1, (imm_expr *)$4.p); } free ((imm_expr *)$3.p); free ((imm_expr *)$4.p); } | BR_GE_POPS SRC1 SRC2 LABEL { r_type_inst ($1.i == Y_BGE_POP ? Y_SLT_OP : Y_SLTU_OP, 1, $2.i, $3.i); /* Use $at */ i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4.p); } | BR_GE_POPS SRC1 BR_IMM32 LABEL { i_type_inst ($1.i == Y_BGE_POP ? Y_SLTI_OP : Y_SLTIU_OP, 1, $2.i, (imm_expr *)$3.p); /* Use $at */ i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4.p); free ((imm_expr *)$3.p); } | BR_LT_POPS SRC1 SRC2 LABEL { r_type_inst ($1.i == Y_BLT_POP ? Y_SLT_OP : Y_SLTU_OP, 1, $2.i, $3.i); /* Use $at */ i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4.p); } | BR_LT_POPS SRC1 BR_IMM32 LABEL { i_type_inst ($1.i == Y_BLT_POP ? Y_SLTI_OP : Y_SLTIU_OP, 1, $2.i, (imm_expr *)$3.p); /* Use $at */ i_type_inst_free (Y_BNE_OP, 0, 1, (imm_expr *)$4.p); free ((imm_expr *)$3.p); } | BR_LE_POPS SRC1 SRC2 LABEL { r_type_inst ($1.i == Y_BLE_POP ? Y_SLT_OP : Y_SLTU_OP, 1, $3.i, $2.i); /* Use $at */ i_type_inst_free (Y_BEQ_OP, 0, 1, (imm_expr *)$4.p); } | BR_LE_POPS SRC1 BR_IMM32 LABEL { if ($1.i == Y_BLE_POP) { /* Use $at */ i_type_inst_free (Y_SLTI_OP, 1, $2.i, incr_expr_offset ((imm_expr *)$3.p, 1)); i_type_inst (Y_BNE_OP, 0, 1, (imm_expr *)$4.p); } else { /* Use $at */ /* Can't add 1 to immediate since 0xffffffff+1 = 0 < 1 */ i_type_inst (Y_ORI_OP, 1, 0, (imm_expr *)$3.p); i_type_inst (Y_BEQ_OP, $2.i, 1, (imm_expr *)$4.p); r_type_inst (Y_SLTU_OP, 1, $2.i, 1); i_type_inst (Y_BNE_OP, 0, 1, (imm_expr *)$4.p); } free ((imm_expr *)$3.p); free ((imm_expr *)$4.p); } | J_OPS LABEL { if (($1.i == Y_J_OP) || ($1.i == Y_JR_OP)) j_type_inst (Y_J_OP, (imm_expr *)$2.p); else if (($1.i == Y_JAL_OP) || ($1.i == Y_JALR_OP)) j_type_inst (Y_JAL_OP, (imm_expr *)$2.p); free ((imm_expr *)$2.p); } | J_OPS SRC1 { if (($1.i == Y_J_OP) || ($1.i == Y_JR_OP)) r_type_inst (Y_JR_OP, 0, $2.i, 0); else if (($1.i == Y_JAL_OP) || ($1.i == Y_JALR_OP)) r_type_inst (Y_JALR_OP, 31, $2.i, 0); } | J_OPS DEST SRC1 { if (($1.i == Y_J_OP) || ($1.i == Y_JR_OP)) r_type_inst (Y_JR_OP, 0, $3.i, 0); else if (($1.i == Y_JAL_OP) || ($1.i == Y_JALR_OP)) r_type_inst (Y_JALR_OP, $2.i, $3.i, 0); } | B_OPS LABEL { i_type_inst_free (($1.i == Y_BAL_POP ? Y_BGEZAL_OP : Y_BGEZ_OP), 0, 0, (imm_expr *)$2.p); } | UNARY_TRAP_OPS SRC1 IMM16 { i_type_inst_free ($1.i, 0, $2.i, (imm_expr *)$3.p); } | BINARY_TRAP_OPS SRC1 SRC2 { r_type_inst ($1.i, 0, $2.i, $3.i); } | FP_MOVE_OPS F_DEST F_SRC1 { r_co_type_inst ($1.i, $2.i, $3.i, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -