⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.y

📁 Spim软件的一些源码。其中有Xspim的
💻 Y
📖 第 1 页 / 共 4 页
字号:
		  fatal_error ("File contains an .err directive\n");		}	|	Y_FILE_DIR	Y_INT	Y_STR	|	Y_FLOAT_DIR		{		  store_op = store_float;		  if (data_dir) set_data_alignment (2);		}		FP_EXPR_LST		{		  if (text_dir)		    yyerror ("Can't put data in text segment");		}	|	Y_FMASK_DIR	Y_INT	Y_INT	|	Y_FRAME_DIR	REGISTER	Y_INT	REGISTER	|	Y_GLOBAL_DIR	ID		{		  (void)make_label_global ((char*)$2.p);		  free ((char*)$2.p);		}	|	Y_HALF_DIR		{		  store_op = store_half;		  if (data_dir) set_data_alignment (1);		}		EXPR_LST		{		  if (text_dir)		    yyerror ("Can't put data in text segment");		}	|	Y_LABEL_DIR	ID		{		  (void)record_label ((char*)$2.p,				      text_dir				      ? current_text_pc ()				      : current_data_pc (),				      1);		  free ((char*)$2.p);		}	|	Y_LCOMM_DIR	ID	EXPR		{		  lcomm_directive ((char*)$2.p, $3.i);		}		/* Produced by cc 2.10 */	|	Y_LIVEREG_DIR	Y_INT	Y_INT	|	Y_LOC_DIR	Y_INT	Y_INT	|	Y_MASK_DIR	Y_INT	Y_INT	|	Y_NOALIAS_DIR	Y_REG	Y_REG	|	Y_OPTIONS_DIR	ID	|	Y_REPEAT_DIR	EXPR		{		  yyerror ("Warning: repeat directive ignored");		}	|	Y_RDATA_DIR		{		  user_kernel_data_segment (0);		  data_dir = 1; text_dir = 0;		  enable_data_alignment ();		}	|	Y_RDATA_DIR	Y_INT		{		  user_kernel_data_segment (0);		  data_dir = 1; text_dir = 0;		  enable_data_alignment ();		  set_data_pc ($2.i);		}	|	Y_SDATA_DIR		{		  user_kernel_data_segment (0);		  data_dir = 1; text_dir = 0;		  enable_data_alignment ();		}	|	Y_SDATA_DIR	Y_INT		{		  user_kernel_data_segment (0);		  data_dir = 1; text_dir = 0;		  enable_data_alignment ();		  set_data_pc ($2.i);		}	|	Y_SET_DIR	ID		{		  if (streq ((char*)$2.p, "noat"))		    noat_flag = 1;		  else if (streq ((char*)$2.p, "at"))		    noat_flag = 0;		}	|	Y_SPACE_DIR	EXPR		{		  if (data_dir)		    increment_data_pc ($2.i);		  else if (text_dir)		    increment_text_pc ($2.i);		}	|	Y_STRUCT_DIR	EXPR		{		  yyerror ("Warning: struct directive ignored");		}	|	Y_TEXT_DIR		{		  user_kernel_text_segment (0);		  data_dir = 0; text_dir = 1;		  enable_data_alignment ();		}	|	Y_TEXT_DIR	Y_INT		{		  user_kernel_text_segment (0);		  data_dir = 0; text_dir = 1;		  enable_data_alignment ();		  set_text_pc ($2.i);		}	|	Y_K_TEXT_DIR		{		  user_kernel_text_segment (1);		  data_dir = 0; text_dir = 1;		  enable_data_alignment ();		}	|	Y_K_TEXT_DIR	Y_INT		{		  user_kernel_text_segment (1);		  data_dir = 0; text_dir = 1;		  enable_data_alignment ();		  set_text_pc ($2.i);		}	|	Y_VERSTAMP_DIR	Y_INT	Y_INT	|	Y_VREG_DIR	REGISTER	Y_INT	Y_INT	|	Y_WORD_DIR		{		  store_op = store_word_data;		  if (data_dir) set_data_alignment (2);		}		EXPR_LST	;ADDRESS:	{only_id = 1;} ADDR {only_id = 0; $$ = $2;}ADDR:		'(' REGISTER ')'		{		  $$.p = make_addr_expr (0, NULL, $2.i);		}	|	ABS_ADDR		{		  $$.p = make_addr_expr ($1.i, NULL, 0);		}	|	ABS_ADDR '(' REGISTER ')'		{		  $$.p = make_addr_expr ($1.i, NULL, $3.i);		}	|	Y_ID		{		  $$.p = make_addr_expr (0, (char*)$1.p, 0);		  free ((char*)$1.p);		}	|	Y_ID '(' REGISTER ')'		{		  $$.p = make_addr_expr (0, (char*)$1.p, $3.i);		  free ((char*)$1.p);		}	|	Y_ID '+' ABS_ADDR		{		  $$.p = make_addr_expr ($3.i, (char*)$1.p, 0);		  free ((char*)$1.p);		}	|	ABS_ADDR '+' ID		{		  $$.p = make_addr_expr ($1.i, (char*)$3.p, 0);		}	|	Y_ID '-' ABS_ADDR		{		  $$.p = make_addr_expr (- $3.i, (char*)$1.p, 0);		  free ((char*)$1.p);		}	|	Y_ID '+' ABS_ADDR '(' REGISTER ')'		{		  $$.p = make_addr_expr ($3.i, (char*)$1.p, $5.i);		  free ((char*)$1.p);		}	|	Y_ID '-' ABS_ADDR '(' REGISTER ')'		{		  $$.p = make_addr_expr (- $3.i, (char*)$1.p, $5.i);		  free ((char*)$1.p);		}	;BR_IMM32:	{only_id = 1;} IMM32 {only_id = 0; $$ = $2;}IMM16:	IMM32		{		  check_imm_range ($1.p, IMM_MIN, IMM_MAX);		  $$ = $1;		}UIMM16:	IMM32		{		  check_uimm_range ($1.p, UIMM_MIN, UIMM_MAX);		  $$ = $1;		}IMM32:		ABS_ADDR		{		  $$.p = make_imm_expr ($1.i, NULL, 0);		}	|	'(' ABS_ADDR ')' '>' '>' Y_INT		{		  $$.p = make_imm_expr ($2.i >> $6.i, NULL, 0);		}	|	ID		{		  $$.p = make_imm_expr (0, (char*)$1.p, 0);		}	|	Y_ID '+' ABS_ADDR		{		  $$.p = make_imm_expr ($3.i, (char*)$1.p, 0);		  free ((char*)$1.p);		}	|	Y_ID '-' ABS_ADDR		{		  $$.p = make_imm_expr (- $3.i, (char*)$1.p, 0);		  free ((char*)$1.p);		}	;ABS_ADDR:	Y_INT	|	Y_INT '+' Y_INT		{$$.i = $1.i + $3.i;}	|	Y_INT Y_INT		{		  /* This is actually: Y_INT '-' Y_INT, since the binary		     subtract operator gets scanned as a unary negation		     operator. */		  if ($2.i >= 0) yyerror ("Syntax error");		  $$.i = $1.i - -$2.i;		}	;SRC1:		REGISTER ;SRC2:		REGISTER ;DEST:		REGISTER ;REG:		REGISTER ;REGISTER:	Y_REG		{		  if ($1.i < 0 || $1.i > 31)		    yyerror ("Register number out of range");		  if ($1.i == 1 && !bare_machine && !noat_flag)		    yyerror ("Register 1 is reserved for assembler");		  $$ = $1;		}F_DEST:		FP_REGISTER ;F_SRC1:		FP_REGISTER ;F_SRC2:		FP_REGISTER ;FP_REGISTER:	Y_FP_REG		{		  if ($1.i < 0 || $1.i > 31)		    yyerror ("FP register number out of range");		  $$ = $1;		}CC_REG:	       Y_INT		{		  if ($1.i < 0 || $1.i > 7)		    yyerror ("CC register number out of range");		  $$ = $1;		}COP_REG:	Y_REG	|	Y_FP_REG	;LABEL:		ID		{		  $$.p = make_imm_expr (-(int)current_text_pc (), (char*)$1.p, 1);		}STR_LST:	STR_LST STR	|	STR	;STR:		Y_STR		{		  store_string ((char*)$1.p, strlen((char*)$1.p), null_term);		  free ((char*)$1.p);		}	|	Y_STR ':' Y_INT		{		  int i;		  for (i = 0; i < $3.i; i ++)		    store_string ((char*)$1.p, strlen((char*)$1.p), null_term);		  free ((char*)$1.p);		}	;EXPRESSION:	{only_id = 1;} EXPR {only_id = 0; $$ = $2;}EXPR:		Y_INT	|	ID		{		  label *l = lookup_label ((char*)$1.p);		  if (l->addr == 0)		    {		      record_data_uses_symbol (current_data_pc (), l);		      $$.p = NULL;		    }		  else		    $$.i = l->addr;		}EXPR_LST:	EXPR_LST	EXPRESSION		{		  store_op ($2.p);		}	|	EXPRESSION		{		  store_op ($1.p);		}	|	EXPRESSION ':' Y_INT		{		  int i;		  for (i = 0; i < $3.i; i ++)		    store_op ($1.p);		}	;FP_EXPR_LST:	FP_EXPR_LST Y_FP		{		  store_op ($2.p);		}	|	Y_FP		{		  store_op ($1.p);		}	;OPTIONAL_ID:	{only_id = 1;} OPT_ID {only_id = 0; $$ = $2;}OPT_ID:		ID	|	{$$.p = (void*)NULL;}	;ID:		{only_id = 1;} Y_ID {only_id = 0; $$ = $2;}%%/* Maintain and update the address of labels for the current line. */voidfix_current_label_address (mem_addr new_addr){  label_list *l;  for (l = this_line_labels; l != NULL; l = l->tail)    {      l->head->addr = new_addr;    }  clear_labels ();}static label_list *cons_label (label *head, label_list *tail){  label_list *c = (label_list *) malloc (sizeof (label_list));  c->head = head;  c->tail = tail;  return (c);}static voidclear_labels (){  label_list *n;  for ( ; this_line_labels != NULL; this_line_labels = n)    {      resolve_label_uses (this_line_labels->head);      n = this_line_labels->tail;      free (this_line_labels);    }    this_line_labels = NULL;}/* Operations on op codes. */intop_to_imm_op (int opcode){  switch (opcode)    {    case Y_ADD_OP: return (Y_ADDI_OP);    case Y_ADDU_OP: return (Y_ADDIU_OP);    case Y_AND_OP: return (Y_ANDI_OP);    case Y_OR_OP: return (Y_ORI_OP);    case Y_XOR_OP: return (Y_XORI_OP);    case Y_SLT_OP: return (Y_SLTI_OP);    case Y_SLTU_OP: return (Y_SLTIU_OP);    case Y_SLLV_OP: return (Y_SLL_OP);    case Y_SRAV_OP: return (Y_SRA_OP);    case Y_SRLV_OP: return (Y_SRL_OP);    default: fatal_error ("Can't convert op to immediate op\n"); return (0);    }}intimm_op_to_op (int opcode){  switch (opcode)    {    case Y_ADDI_OP: return (Y_ADD_OP);    case Y_ADDIU_OP: return (Y_ADDU_OP);    case Y_ANDI_OP: return (Y_AND_OP);    case Y_ORI_OP: return (Y_OR_OP);    case Y_XORI_OP: return (Y_XOR_OP);    case Y_SLTI_OP: return (Y_SLT_OP);    case Y_SLTIU_OP: return (Y_SLTU_OP);    case Y_J_OP: return (Y_JR_OP);    case Y_LUI_OP: return (Y_ADDU_OP);    case Y_SLL_OP: return (Y_SLLV_OP);    case Y_SRA_OP: return (Y_SRAV_OP);    case Y_SRL_OP: return (Y_SRLV_OP);    default: fatal_error ("Can't convert immediate op to op\n"); return (0);    }}static voidnop_inst (){  r_type_inst (Y_SLL_OP, 0, 0, 0); /* = 0 */}static voidtrap_inst (){  r_type_inst (Y_BREAK_OP, 0, 0, 0);}static imm_expr *branch_offset (int n_inst){  return (const_imm_expr (n_inst << 2)); /* Later shifted right 2 places */}static voiddiv_inst (int op, int rd, int rs, int rt, int const_divisor){  if (rd != 0 && !const_divisor)    {      i_type_inst_free (Y_BNE_OP, 0, rt, branch_offset (2));      trap_inst ();    }  if (op == Y_DIV_OP || op == Y_REM_POP)    r_type_inst (Y_DIV_OP, 0, rs, rt);  else    r_type_inst (Y_DIVU_OP, 0, rs, rt);  if (rd != 0)    {      if (op == Y_DIV_OP || op == Y_DIVU_OP)	/* Quotient */	r_type_inst (Y_MFLO_OP, rd, 0, 0);      else	/* Remainder */	r_type_inst (Y_MFHI_OP, rd, 0, 0);    }}static voidmult_inst (int op, int rd, int rs, int rt){  if (op == Y_MULOU_POP)    r_type_inst (Y_MULTU_OP, 0, rs, rt);  else    r_type_inst (Y_MULT_OP, 0, rs, rt);  if (op == Y_MULOU_POP && rd != 0)    {      r_type_inst (Y_MFHI_OP, 1, 0, 0);	/* Use $at */      i_type_inst_free (Y_BEQ_OP, 0, 1, branch_offset (2));      trap_inst ();    }  else if (op == Y_MULO_POP && rd != 0)    {      r_type_inst (Y_MFHI_OP, 1, 0, 0); /* use $at */      r_type_inst (Y_MFLO_OP, rd, 0, 0);      r_sh_type_inst (Y_SRA_OP, rd, rd, 31);      i_type_inst_free (Y_BEQ_OP, rd, 1, branch_offset (2));      trap_inst ();    }  if (rd != 0)    r_type_inst (Y_MFLO_OP, rd, 0, 0);}static voidset_le_inst (int op, int rd, int rs, int rt){  i_type_inst_free (Y_BNE_OP, rs, rt, branch_offset (3));  i_type_inst_free (Y_ORI_OP, rd, 0, const_imm_expr (1));  i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2));  r_type_inst ((op == Y_SLE_POP ? Y_SLT_OP : Y_SLTU_OP), rd, rs, rt);}static voidset_gt_inst (int op, int rd, int rs, int rt){  r_type_inst (op == Y_SGT_POP ? Y_SLT_OP : Y_SLTU_OP, rd, rt, rs);}static voidset_ge_inst (int op, int rd, int rs, int rt){  i_type_inst_free (Y_BNE_OP, rs, rt, branch_offset (3));  i_type_inst_free (Y_ORI_OP, rd, 0, const_imm_expr (1));  i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2));  r_type_inst (op == Y_SGE_POP ? Y_SLT_OP : Y_SLTU_OP, rd, rt, rs);}static voidset_eq_inst (int op, int rd, int rs, int rt){  imm_expr *if_eq, *if_neq;  if (op == Y_SEQ_POP)    if_eq = const_imm_expr (1), if_neq = const_imm_expr (0);  else    if_eq = const_imm_expr (0), if_neq = const_imm_expr (1);  i_type_inst_free (Y_BEQ_OP, rs, rt, branch_offset (3));  /* RD <- 0 (if not equal) */  i_type_inst_free (Y_ORI_OP, rd, 0, if_neq);  i_type_inst_free (Y_BEQ_OP, 0, 0, branch_offset (2)); /* Branch always */  /* RD <- 1 */  i_type_inst_free (Y_ORI_OP, rd, 0, if_eq);}/* Store the value either as a datum or instruction. */static voidstore_word_data (int value){  if (data_dir)    store_word (value);  else if (text_dir)    store_instruction (inst_decode (value));}voidinitialize_parser (char *file_name){  input_file_name = file_name;  only_id = 0;  data_dir = 0;  text_dir = 1;}static voidcheck_imm_range (imm_expr* expr, int32 min, int32 max){  if (expr->symbol == NULL || SYMBOL_IS_DEFINED (expr->symbol))    {      /* If expression can be evaluated, compare its value against the limits	 and complain if the value is out of bounds. */      int32 value = eval_imm_expr (expr);      if (value < min || max < value)	{	  char str[200];	  sprintf (str, "immediate value (%d) out of range (%d .. %d)",		   value, min, max);	  yywarn (str);	}    }}static voidcheck_uimm_range (imm_expr* expr, uint32 min, uint32 max){  if (expr->symbol == NULL || SYMBOL_IS_DEFINED (expr->symbol))    {      /* If expression can be evaluated, compare its value against the limits	     and complain if the value is out of bounds. */      uint32 value = (uint32)eval_imm_expr (expr);      if (value < min || max < value)	{	  char str[200];	  sprintf (str, "immediate value (%d) out of range (%d .. %d)",		   (int32)value, (int32)min, (int32)max);	  yywarn (str);	}    }}voidyyerror (char *s){  parse_error_occurred = 1;  clear_labels ();  yywarn (s);}voidyywarn (char *s){  error ("spim: (parser) %s on line %d of file %s\n", s, line_no, input_file_name);  print_erroneous_line ();}static voidmips32_r2_inst (){	yyerror ("Warning: MIPS32 Rev 2 instruction is not implemented. Instruction ignored.");}static intcc_to_rt (int cc, int nd, int tf){  return (cc << 2) | (nd << 1) | tf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -