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

📄 parser.y

📁 用汇编语言编程源代码
💻 Y
📖 第 1 页 / 共 4 页
字号:
	|	Y_ID '(' REGISTER ')'		{		  $$.p = make_addr_expr (0, (char*)$1.p, $3.i);		  if ($1.p) free ((char*)$1.p);		}	|	Y_ID '+' ABS_ADDR		{		  $$.p = make_addr_expr ($3.i, (char*)$1.p, 0);		  if ($1.p) 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);		  if ($1.p) free ((char*)$1.p);		}	|	Y_ID '+' ABS_ADDR '(' REGISTER ')'		{		  $$.p = make_addr_expr ($3.i, (char*)$1.p, $5.i);		  if ($1.p) free ((char*)$1.p);		}	|	Y_ID '-' ABS_ADDR '(' REGISTER ')'		{		  $$.p = make_addr_expr (- $3.i, (char*)$1.p, $5.i);		  if ($1.p) 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		{		  /* Y_INT '-' Y_INT */		  if ($2.i >= 0)		    yyerror ("Syntax error");		  $$.i = $1.i - $2.i;		}	;DEST_REG:	REGISTER ;SRC1:		REGISTER ;SRC2:		REGISTER ;DEST:		REGISTER ;REG:		REGISTER ;SOURCE:		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;		}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, y_str_length, null_term);		  free ((char*)$1.p);		}	|	Y_STR ':' Y_INT		{		  int i;		  for (i = 0; i < $3.i; i ++)		    store_string ((char*)$1.p, y_str_length, 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. */#ifdef __STDC__voidfix_current_label_address (mem_addr new_addr)#elsevoidfix_current_label_address (new_addr)     mem_addr new_addr;#endif{  label_list *l;  for (l = this_line_labels; l != NULL; l = l->tail)    {      l->head->addr = new_addr;    }  clear_labels ();}#ifdef __STDC__static label_list *cons_label (label *head, label_list *tail)#elsestatic label_list *cons_label (head, tail)     label *head;     label_list *tail;#endif{  label_list *c = (label_list *) malloc (sizeof (label_list));  c->head = head;  c->tail = tail;  return (c);}#ifdef __STDC__static voidclear_labels (void)#elsestatic voidclear_labels ()#endif{  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);    }}/* Operations on op codes. */#ifdef __STDC__intop_to_imm_op (int opcode)#elseintop_to_imm_op (opcode)     int opcode;#endif{  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);    }}#ifdef __STDC__intimm_op_to_op (int opcode)#elseintimm_op_to_op (opcode)     int opcode;#endif{  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);    }}#ifdef __STDC__static voidnop_inst (void)#elsestatic voidnop_inst ()#endif{  r_type_inst (Y_SLL_OP, 0, 0, 0); /* = 0 */}#ifdef __STDC__static voidtrap_inst (void)#elsestatic voidtrap_inst ()#endif{  r_type_inst (Y_BREAK_OP, 0, 0, 0);}#ifdef __STDC__static imm_expr *branch_offset (int n_inst)#elsestatic imm_expr *branch_offset (n_inst)     int n_inst;#endif{  return (const_imm_expr (n_inst << 2)); /* Later shifted right 2 places */}#ifdef __STDC__static voiddiv_inst (int op, int rd, int rs, int rt, int const_divisor)#elsestatic voiddiv_inst (op, rd, rs, rt, const_divisor)     int op, rd, rs, rt, const_divisor;#endif{  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);    }}#ifdef __STDC__static voidmult_inst (int op, int rd, int rs, int rt)#elsestatic voidmult_inst (op, rd, rs, rt)     int op, rd, rs, rt;#endif{  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);}#ifdef __STDC__static voidset_le_inst (int op, int rd, int rs, int rt)#elsestatic voidset_le_inst (op, rd, rs, rt)     int op, rd, rs, rt;#endif{  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);}#ifdef __STDC__static voidset_gt_inst (int op, int rd, int rs, int rt)#elsestatic voidset_gt_inst (op, rd, rs, rt)     int op, rd, rs, rt;#endif{  r_type_inst (op == Y_SGT_POP ? Y_SLT_OP : Y_SLTU_OP, rd, rt, rs);}#ifdef __STDC__static voidset_ge_inst (int op, int rd, int rs, int rt)#elsestatic voidset_ge_inst (op, rd, rs, rt)     int op, rd, rs, rt;#endif{  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);}#ifdef __STDC__static voidset_eq_inst (int op, int rd, int rs, int rt)#elsestatic voidset_eq_inst (op, rd, rs, rt)     int op, rd, rs, rt;#endif{  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. */#ifdef __STDC__static voidstore_word_data (int value)#elsestatic voidstore_word_data (value)     int value;#endif{  if (data_dir)    store_word (value);  else if (text_dir)    store_instruction (inst_decode (value));}#ifdef __STDC__voidinitialize_parser (char *file_name)#elsevoidinitialize_parser (file_name)     char *file_name;#endif{  input_file_name = file_name;  only_id = 0;  data_dir = 0;  text_dir = 1;}#ifdef __STDC__static voidcheck_imm_range(imm_expr* expr, int32 min, int32 max)#elsestatic voidcheck_imm_range()     imm_expr* expr;     int32 min;     int32 max;#endif{  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);	}    }}#ifdef __STDC__static voidcheck_uimm_range(imm_expr* expr, uint32 min, uint32 max)#elsestatic voidcheck_uimm_range()^     imm_expr* expr;     int32 umin;     int32 umax;#endif{  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 = 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);	}    }}#ifdef __STDC__voidyyerror (char *s)#elsevoidyyerror (s)     char *s;#endif{  parse_error_occurred = 1;  yywarn (s);}#ifdef __STDC__voidyywarn (char *s)#elsevoidyywarn (s)     char *s;#endif{  error ("spim: (parser) %s on line %d of file %s\n", s, line_no, input_file_name);  print_erroneous_line ();}

⌨️ 快捷键说明

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