📄 parser.y
字号:
free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | Y_USH_POP SOURCE 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); } | STOREF_OP F_SRC1 ADDRESS { i_type_inst (Y_SWC1_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); if ($1.i == Y_S_D_POP) i_type_inst_free (Y_SWC1_OP, $2.i + 1, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 4)); free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | SYS_OP { r_type_inst ($1.i, 0, 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_ABS_POP DEST_REG 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_REG SRC1 { r_type_inst (Y_SUB_OP, $2.i, 0, $3.i); } | Y_NEGU_POP DEST_REG SRC1 { r_type_inst (Y_SUBU_OP, $2.i, 0, $3.i); } | Y_NOT_POP DEST_REG SRC1 { r_type_inst (Y_NOR_OP, $2.i, $3.i, 0); } | Y_MOVE_POP DEST_REG SRC1 { r_type_inst (Y_ADDU_OP, $2.i, 0, $3.i); } | BINARY_OP_I DEST_REG SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | BINARY_OP_I DEST_REG SRC1 IMM32 { i_type_inst_free (op_to_imm_op ($1.i), $2.i, $3.i, (imm_expr *)$4.p); } | BINARY_OP_I DEST_REG IMM32 { i_type_inst_free (op_to_imm_op ($1.i), $2.i, $2.i, (imm_expr *)$3.p); } | BINARY_OPR_I DEST_REG SRC1 SRC2 { r_type_inst ($1.i, $2.i, $4.i, $3.i); } | BINARY_OPR_I DEST_REG SRC1 Y_INT { r_sh_type_inst (op_to_imm_op ($1.i), $2.i, $3.i, $4.i); } | BINARY_OPR_I DEST_REG Y_INT { r_sh_type_inst (op_to_imm_op ($1.i), $2.i, $2.i, $3.i); } | BINARY_IMM_ARITH_OP DEST_REG SRC1 IMM16 { i_type_inst_free ($1.i, $2.i, $3.i, (imm_expr *)$4.p); } | BINARY_IMM_ARITH_OP DEST_REG IMM16 { i_type_inst_free ($1.i, $2.i, $2.i, (imm_expr *)$3.p); } | BINARY_IMM_LOGICAL_OP DEST_REG SRC1 UIMM16 { i_type_inst_free ($1.i, $2.i, $3.i, (imm_expr *)$4.p); } | BINARY_IMM_LOGICAL_OP DEST_REG UIMM16 { i_type_inst_free ($1.i, $2.i, $2.i, (imm_expr *)$3.p); } | SHIFT_OP DEST_REG 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_OP DEST_REG SRC1 SRC2 { r_type_inst (imm_op_to_op ($1.i), $2.i, $4.i, $3.i); } | BINARY_OP_NOI DEST_REG SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | BINARY_OP_NOI DEST_REG 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_OP_NOI DEST_REG 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); } | SUB_OP DEST_REG SRC1 SRC2 { r_type_inst ($1.i, $2.i, $3.i, $4.i); } | SUB_OP DEST_REG 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_OP DEST_REG 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_POP DEST_REG 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_POP DEST_REG SRC1 SRC2 { /* Pseudo divide operations */ div_inst ($1.i, $2.i, $3.i, $4.i, 0); } | DIV_POP DEST_REG 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_POP DEST_REG SRC1 SRC2 { mult_inst ($1.i, $2.i, $3.i, $4.i); } | MUL_POP DEST_REG 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_OP SRC1 SRC2 { r_type_inst ($1.i, 0, $2.i, $3.i); } | Y_ROR_POP DEST_REG 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_REG 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_REG 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_REG 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); } | SET_LE_POP DEST_REG SRC1 SRC2 { set_le_inst ($1.i, $2.i, $3.i, $4.i); } | SET_LE_POP DEST_REG 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_POP DEST_REG SRC1 SRC2 { set_gt_inst ($1.i, $2.i, $3.i, $4.i); } | SET_GT_POP DEST_REG 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_POP DEST_REG SRC1 SRC2 { set_ge_inst ($1.i, $2.i, $3.i, $4.i); } | SET_GE_POP DEST_REG 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_POP DEST_REG SRC1 SRC2 { set_eq_inst ($1.i, $2.i, $3.i, $4.i); } | SET_EQ_POP DEST_REG 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); } | NULLARY_BR_OP LABEL { i_type_inst_free ($1.i, 0, 0, (imm_expr *)$2.p); } | UNARY_BR_OP SRC1 LABEL { i_type_inst_free ($1.i, 0, $2.i, (imm_expr *)$3.p); } | UNARY_BR_POP 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_OP SRC1 SRC2 LABEL { i_type_inst_free ($1.i, $3.i, $2.i, (imm_expr *)$4.p); } | BINARY_BR_OP 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_POP 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_POP 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_POP 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_POP 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_POP 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_POP 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_POP 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_POP 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_OP LABEL { i_type_inst_free (($1.i == Y_BAL_POP ? Y_BGEZAL_OP : Y_BGEZ_OP), 0, 0, (imm_expr *)$2.p); } | MOVE_COP_OP COP_REG COP_REG { r_type_inst ($1.i, $2.i, $3.i, 0); } | MOV_FROM_HILO_OP REG { r_type_inst ($1.i, $2.i, 0, 0); } | MOV_TO_HILO_OP REG { r_type_inst ($1.i, 0, $2.i, 0); } | MOV_COP_OP REG COP_REG { if ($1.i == Y_MFC1_D_POP) { r_type_inst (Y_MFC1_OP, $3.i, 0, $2.i); r_type_inst (Y_MFC1_OP, $3.i + 1, 0, $2.i + 1); } else if ($1.i == Y_MTC1_D_POP) { r_type_inst (Y_MTC1_OP, $3.i, 0, $2.i); r_type_inst (Y_MTC1_OP, $3.i + 1, 0, $2.i + 1); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -