📄 parser.y
字号:
/* SPIM S20 MIPS simulator. Parser for instructions and assembler directives. Copyright (C) 1990-2004 by James Larus (larus@cs.wisc.edu). ALL RIGHTS RESERVED. SPIM is distributed under the following conditions: You may make copies of SPIM for your own use and modify those copies. All copies of SPIM must retain my name and copyright notice. You may not sell SPIM or distributed SPIM in conjunction with a commerical product or service without the expressed written consent of James Larus. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//* $Header: $*/%start LINE%token Y_EOF%token Y_NL%token Y_INT%token Y_ID%token Y_REG%token Y_FP_REG%token Y_STR%token Y_FP/* MIPS instructions op codes: */%token Y_ABS_D_OP%token Y_ABS_PS_OP%token Y_ABS_S_OP%token Y_ADD_D_OP%token Y_ADD_OP%token Y_ADD_PS_OP%token Y_ADD_S_OP%token Y_ADDI_OP%token Y_ADDIU_OP%token Y_ADDU_OP%token Y_ALNV_PS_OP%token Y_AND_OP%token Y_ANDI_OP%token Y_BC1F_OP%token Y_BC1FL_OP%token Y_BC1T_OP%token Y_BC1TL_OP%token Y_BC2F_OP%token Y_BC2FL_OP%token Y_BC2T_OP%token Y_BC2TL_OP%token Y_BEQ_OP%token Y_BEQL_OP%token Y_BGEZ_OP%token Y_BGEZAL_OP%token Y_BGEZALL_OP%token Y_BGEZL_OP%token Y_BGTZ_OP%token Y_BGTZL_OP%token Y_BLEZ_OP%token Y_BLEZL_OP%token Y_BLTZ_OP%token Y_BLTZAL_OP%token Y_BLTZALL_OP%token Y_BLTZL_OP%token Y_BNE_OP%token Y_BNEL_OP%token Y_BREAK_OP%token Y_C_EQ_D_OP%token Y_C_EQ_PS_OP%token Y_C_EQ_S_OP%token Y_C_F_D_OP%token Y_C_F_PS_OP%token Y_C_F_S_OP%token Y_C_LE_D_OP%token Y_C_LE_PS_OP%token Y_C_LE_S_OP%token Y_C_LT_D_OP%token Y_C_LT_PS_OP%token Y_C_LT_S_OP%token Y_C_NGE_D_OP%token Y_C_NGE_PS_OP%token Y_C_NGE_S_OP%token Y_C_NGL_D_OP%token Y_C_NGL_PS_OP%token Y_C_NGL_S_OP%token Y_C_NGLE_D_OP%token Y_C_NGLE_PS_OP%token Y_C_NGLE_S_OP%token Y_C_NGT_D_OP%token Y_C_NGT_PS_OP%token Y_C_NGT_S_OP%token Y_C_OLE_D_OP%token Y_C_OLE_PS_OP%token Y_C_OLE_S_OP%token Y_C_OLT_D_OP%token Y_C_OLT_PS_OP%token Y_C_OLT_S_OP%token Y_C_SEQ_D_OP%token Y_C_SEQ_PS_OP%token Y_C_SEQ_S_OP%token Y_C_SF_D_OP%token Y_C_SF_PS_OP%token Y_C_SF_S_OP%token Y_C_UEQ_D_OP%token Y_C_UEQ_PS_OP%token Y_C_UEQ_S_OP%token Y_C_ULE_D_OP%token Y_C_ULE_PS_OP%token Y_C_ULE_S_OP%token Y_C_ULT_D_OP%token Y_C_ULT_PS_OP%token Y_C_ULT_S_OP%token Y_C_UN_D_OP%token Y_C_UN_PS_OP%token Y_C_UN_S_OP%token Y_CACHE_OP%token Y_CEIL_L_D_OP%token Y_CEIL_L_S_OP%token Y_CEIL_W_D_OP%token Y_CEIL_W_S_OP%token Y_CFC0_OP%token Y_CFC1_OP%token Y_CFC2_OP%token Y_CLO_OP%token Y_CLZ_OP%token Y_COP2_OP%token Y_CTC0_OP%token Y_CTC1_OP%token Y_CTC2_OP%token Y_CVT_D_L_OP%token Y_CVT_D_S_OP%token Y_CVT_D_W_OP%token Y_CVT_L_D_OP%token Y_CVT_L_S_OP%token Y_CVT_PS_S_OP%token Y_CVT_S_D_OP%token Y_CVT_S_L_OP%token Y_CVT_S_PL_OP%token Y_CVT_S_PU_OP%token Y_CVT_S_W_OP%token Y_CVT_W_D_OP%token Y_CVT_W_S_OP%token Y_DERET_OP%token Y_DI_OP%token Y_DIV_D_OP%token Y_DIV_OP%token Y_DIV_S_OP%token Y_DIVU_OP%token Y_EHB_OP%token Y_EI_OP%token Y_ERET_OP%token Y_EXT_OP%token Y_FLOOR_L_D_OP%token Y_FLOOR_L_S_OP%token Y_FLOOR_W_D_OP%token Y_FLOOR_W_S_OP%token Y_INS_OP%token Y_J_OP%token Y_JAL_OP%token Y_JALR_HB_OP%token Y_JALR_OP%token Y_JR_HB_OP%token Y_JR_OP%token Y_LB_OP%token Y_LBU_OP%token Y_LDC1_OP%token Y_LDC2_OP%token Y_LDXC1_OP%token Y_LH_OP%token Y_LHU_OP%token Y_LL_OP%token Y_LUI_OP%token Y_LUXC1_OP%token Y_LW_OP%token Y_LWC1_OP%token Y_LWC2_OP%token Y_LWL_OP%token Y_LWR_OP%token Y_LWXC1_OP%token Y_MADD_D_OP%token Y_MADD_OP%token Y_MADD_PS_OP%token Y_MADD_S_OP%token Y_MADDU_OP%token Y_MFC0_OP%token Y_MFC1_OP%token Y_MFC2_OP%token Y_MFHC1_OP%token Y_MFHC2_OP%token Y_MFHI_OP%token Y_MFLO_OP%token Y_MOV_D_OP%token Y_MOV_PS_OP%token Y_MOV_S_OP%token Y_MOVF_D_OP%token Y_MOVF_OP%token Y_MOVF_PS_OP%token Y_MOVF_S_OP%token Y_MOVN_D_OP%token Y_MOVN_OP%token Y_MOVN_PS_OP%token Y_MOVN_S_OP%token Y_MOVT_D_OP%token Y_MOVT_OP%token Y_MOVT_PS_OP%token Y_MOVT_S_OP%token Y_MOVZ_D_OP%token Y_MOVZ_OP%token Y_MOVZ_PS_OP%token Y_MOVZ_S_OP%token Y_MSUB_D_OP%token Y_MSUB_OP%token Y_MSUB_PS_OP%token Y_MSUB_S_OP%token Y_MSUBU_OP%token Y_MTC0_OP%token Y_MTC1_OP%token Y_MTC2_OP%token Y_MTHC1_OP%token Y_MTHC2_OP%token Y_MTHI_OP%token Y_MTLO_OP%token Y_MUL_D_OP%token Y_MUL_PS_OP%token Y_MUL_S_OP%token Y_MUL_OP%token Y_MULT_OP%token Y_MULTU_OP%token Y_NEG_D_OP%token Y_NEG_PS_OP%token Y_NEG_S_OP%token Y_NMADD_D_OP%token Y_NMADD_PS_OP%token Y_NMADD_S_OP%token Y_NMSUB_D_OP%token Y_NMSUB_PS_OP%token Y_NMSUB_S_OP%token Y_NOR_OP%token Y_OR_OP%token Y_ORI_OP%token Y_PFW_OP%token Y_PLL_PS_OP%token Y_PLU_PS_OP%token Y_PREF_OP%token Y_PREFX_OP%token Y_PUL_PS_OP%token Y_PUU_PS_OP%token Y_RDHWR_OP%token Y_RDPGPR_OP%token Y_RECIP_D_OP%token Y_RECIP_S_OP%token Y_RFE_OP%token Y_ROTR_OP%token Y_ROTRV_OP%token Y_ROUND_L_D_OP%token Y_ROUND_L_S_OP%token Y_ROUND_W_D_OP%token Y_ROUND_W_S_OP%token Y_RSQRT_D_OP%token Y_RSQRT_S_OP%token Y_SB_OP%token Y_SC_OP%token Y_SDBBP_OP%token Y_SDC1_OP%token Y_SDC2_OP%token Y_SDXC1_OP%token Y_SEB_OP%token Y_SEH_OP%token Y_SH_OP%token Y_SLL_OP%token Y_SLLV_OP%token Y_SLT_OP%token Y_SLTI_OP%token Y_SLTIU_OP%token Y_SLTU_OP%token Y_SQRT_D_OP%token Y_SQRT_S_OP%token Y_SRA_OP%token Y_SRAV_OP%token Y_SRL_OP%token Y_SRLV_OP%token Y_SSNOP_OP%token Y_SUB_D_OP%token Y_SUB_OP%token Y_SUB_PS_OP%token Y_SUB_S_OP%token Y_SUBU_OP%token Y_SUXC1_OP%token Y_SW_OP%token Y_SWC1_OP%token Y_SWC2_OP%token Y_SWL_OP%token Y_SWR_OP%token Y_SWXC1_OP%token Y_SYNC_OP%token Y_SYNCI_OP%token Y_SYSCALL_OP%token Y_TEQ_OP%token Y_TEQI_OP%token Y_TGE_OP%token Y_TGEI_OP%token Y_TGEIU_OP%token Y_TGEU_OP%token Y_TLBP_OP%token Y_TLBR_OP%token Y_TLBWI_OP%token Y_TLBWR_OP%token Y_TLT_OP%token Y_TLTI_OP%token Y_TLTIU_OP%token Y_TLTU_OP%token Y_TNE_OP%token Y_TNEI_OP%token Y_TRUNC_L_D_OP%token Y_TRUNC_L_S_OP%token Y_TRUNC_W_D_OP%token Y_TRUNC_W_S_OP%token Y_WRPGPR_OP%token Y_WSBH_OP%token Y_XOR_OP%token Y_XORI_OP/* Assembler pseudo operations op codes: */%token Y_ABS_POP%token Y_B_POP%token Y_BAL_POP%token Y_BEQZ_POP%token Y_BGE_POP%token Y_BGEU_POP%token Y_BGT_POP%token Y_BGTU_POP%token Y_BLE_POP%token Y_BLEU_POP%token Y_BLT_POP%token Y_BLTU_POP%token Y_BNEZ_POP%token Y_LA_POP%token Y_LD_POP%token Y_L_D_POP%token Y_L_S_POP%token Y_LI_D_POP%token Y_LI_POP%token Y_LI_S_POP%token Y_MFC1_D_POP%token Y_MOVE_POP%token Y_MTC1_D_POP%token Y_MULO_POP%token Y_MULOU_POP%token Y_NEG_POP%token Y_NEGU_POP%token Y_NOP_POP%token Y_NOT_POP%token Y_REM_POP%token Y_REMU_POP%token Y_ROL_POP%token Y_ROR_POP%token Y_S_D_POP%token Y_S_S_POP%token Y_SD_POP%token Y_SEQ_POP%token Y_SGE_POP%token Y_SGEU_POP%token Y_SGT_POP%token Y_SGTU_POP%token Y_SLE_POP%token Y_SLEU_POP%token Y_SNE_POP%token Y_ULH_POP%token Y_ULHU_POP%token Y_ULW_POP%token Y_USH_POP%token Y_USW_POP/* Assembler directives: */%token Y_ALIAS_DIR%token Y_ALIGN_DIR%token Y_ASCII_DIR%token Y_ASCIIZ_DIR%token Y_ASM0_DIR%token Y_BGNB_DIR%token Y_BYTE_DIR%token Y_COMM_DIR%token Y_DATA_DIR%token Y_DOUBLE_DIR%token Y_END_DIR%token Y_ENDB_DIR%token Y_ENDR_DIR%token Y_ENT_DIR%token Y_ERR_DIR%token Y_EXTERN_DIR%token Y_FILE_DIR%token Y_FLOAT_DIR%token Y_FMASK_DIR%token Y_FRAME_DIR%token Y_GLOBAL_DIR%token Y_HALF_DIR%token Y_K_DATA_DIR%token Y_K_TEXT_DIR%token Y_LABEL_DIR%token Y_LCOMM_DIR%token Y_LIVEREG_DIR%token Y_LOC_DIR%token Y_MASK_DIR%token Y_NOALIAS_DIR%token Y_OPTIONS_DIR%token Y_RDATA_DIR%token Y_REPEAT_DIR%token Y_SDATA_DIR%token Y_SET_DIR%token Y_SPACE_DIR%token Y_STRUCT_DIR%token Y_TEXT_DIR%token Y_VERSTAMP_DIR%token Y_VREG_DIR%token Y_WORD_DIR%{#include <stdio.h>#include "spim.h"#include "string-stream.h"#include "spim-utils.h"#include "inst.h"#include "reg.h"#include "mem.h"#include "sym-tbl.h"#include "data.h"#include "scanner.h"#include "parser.h"/* return (0) */#define LINE_PARSE_DONE YYACCEPT/* return (1) */#define FILE_PARSE_DONE YYABORTtypedef struct ll{ label *head; struct ll *tail;} label_list;/* Exported Variables: */int data_dir; /* Non-zero means item in data segment */int text_dir; /* Non-zero means item in text segment */int parse_error_occurred; /* Non-zero => parse resulted in error *//* Local functions: */static imm_expr *branch_offset (int n_inst);static int cc_to_rt (int cc, int nd, int tf);static void check_imm_range (imm_expr*, int32, int32);static void check_uimm_range (imm_expr*, uint32, uint32);static void clear_labels ();static label_list *cons_label (label *head, label_list *tail);static void div_inst (int op, int rd, int rs, int rt, int const_divisor);static void mips32_r2_inst ();static void mult_inst (int op, int rd, int rs, int rt);static void nop_inst ();static void set_eq_inst (int op, int rd, int rs, int rt);static void set_ge_inst (int op, int rd, int rs, int rt);static void set_gt_inst (int op, int rd, int rs, int rt);static void set_le_inst (int op, int rd, int rs, int rt);static void store_word_data (int value);static void trap_inst ();static void yywarn (char*);/* Local variables: */static int null_term; /* Non-zero means string terminate by \0 */static void (*store_op) (); /* Function to store items in an EXPR_LST */static label_list *this_line_labels = NULL; /* List of label for curent line */static int noat_flag = 0; /* Non-zero means program can use $1 */static char *input_file_name; /* Name of file being parsed */%}%%LINE: {parse_error_occurred = 0; scanner_start_line (); } LBL_CMD ;LBL_CMD: OPT_LBL CMD | CMD ;OPT_LBL: ID ':' { /* Call outside of cons_label, since an error sets that variable to NULL. */ label* l = record_label ((char*)$1.p, text_dir ? current_text_pc () : current_data_pc (), 0); this_line_labels = cons_label (l, this_line_labels); free ((char*)$1.p); } | ID '=' Y_INT { label *l = record_label ((char*)$1.p, (mem_addr)$3.i, 1); free ((char*)$1.p); l->const_flag = 1; clear_labels (); } ;CMD: ASM_CODE { clear_labels (); } TERM | ASM_DIRECTIVE { clear_labels (); } TERM | TERM ;TERM: Y_NL { LINE_PARSE_DONE; } | Y_EOF { clear_labels (); FILE_PARSE_DONE; } ;ASM_CODE: LOAD_OPS DEST ADDRESS { i_type_inst ($1.i == Y_LD_POP ? Y_LW_OP : $1.i, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); if ($1.i == Y_LD_POP) i_type_inst_free (Y_LW_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); } | LOADC_OPS COP_REG 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); } | LOADFP_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); } | LOADI_OPS DEST UIMM16 { i_type_inst_free ($1.i, $2.i, 0, (imm_expr *)$3.p); } | Y_LA_POP DEST ADDRESS { if (addr_expr_reg ((addr_expr *)$3.p)) i_type_inst (Y_ADDI_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); else i_type_inst (Y_ORI_OP, $2.i, 0, addr_expr_imm ((addr_expr *)$3.p)); free (((addr_expr *)$3.p)->imm); free ((addr_expr *)$3.p); } | Y_LI_POP DEST IMM32 { i_type_inst_free (Y_ORI_OP, $2.i, 0, (imm_expr *)$3.p); } | Y_LI_D_POP F_DEST Y_FP { int *x = (int *) $3.p; i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*x)); r_co_type_inst (Y_MTC1_OP, 0, $2.i, 1); i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*(x+1))); r_co_type_inst (Y_MTC1_OP, 0, $2.i + 1, 1); } | Y_LI_S_POP F_DEST Y_FP { float x = (float) *((double *) $3.p); int *y = (int *) &x; i_type_inst (Y_ORI_OP, 1, 0, const_imm_expr (*y)); r_co_type_inst (Y_MTC1_OP, 0, $2.i, 1); } | Y_ULW_POP DEST ADDRESS {#ifdef BIGENDIAN i_type_inst (Y_LWL_OP, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); i_type_inst_free (Y_LWR_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_LWL_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_LWR_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); } | ULOADH_POPS DEST ADDRESS {#ifdef BIGENDIAN i_type_inst (($1.i == Y_ULH_POP ? Y_LB_OP : Y_LBU_OP), $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); i_type_inst_free (Y_LBU_OP, 1, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 1));#else i_type_inst_free (($1.i == Y_ULH_POP ? Y_LB_OP : Y_LBU_OP), $2.i, addr_expr_reg ((addr_expr *)$3.p), incr_expr_offset (addr_expr_imm ((addr_expr *)$3.p), 1)); i_type_inst (Y_LBU_OP, 1, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p));#endif 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); } | LOADFP_INDEX_OPS F_DEST ADDRESS { mips32_r2_inst (); } | STORE_OPS SRC1 ADDRESS { i_type_inst ($1.i == Y_SD_POP ? Y_SW_OP : $1.i, $2.i, addr_expr_reg ((addr_expr *)$3.p), addr_expr_imm ((addr_expr *)$3.p)); if ($1.i == Y_SD_POP) i_type_inst_free (Y_SW_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); } | STOREC_OPS COP_REG 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -