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

📄 gen-idecode.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		       gen_entry *entry,		       insn_entry * insn, int depth, void *data){  cache_entry *cache_rules = (cache_entry *) data;  if (options.generate_expanded_instructions)    {      ASSERT (entry->nr_insns == 1	      && entry->opcode == NULL	      && entry->parent != NULL && entry->parent->opcode != NULL);      ASSERT (entry->nr_insns == 1	      && entry->opcode == NULL	      && entry->parent != NULL	      && entry->parent->opcode != NULL	      && entry->parent->opcode_rule != NULL);      print_jump_insn (file,		       entry->insns->words[0]->insn,		       entry->expanded_bits, entry->opcode, cache_rules);    }  else    {      print_jump_insn (file,		       instruction->words[0]->insn, NULL, NULL, cache_rules);    }}#endif#if 0static voidprint_jump_internal_function (lf *file,			      gen_entry *table,			      function_entry * function, void *data){  if (function->is_internal)    {      lf_printf (file, "\n");      lf_print__line_ref (file, function->line);      lf_indent (file, -1);      print_function_name (file,			   function->name,			   NULL,			   (options.gen.icache			    ? function_name_prefix_icache			    : function_name_prefix_semantics));      lf_printf (file, ":\n");      lf_indent (file, +1);      lf_printf (file, "{\n");      lf_indent (file, +2);      lf_printf (file, "const unsigned_word cia = nia;\n");      table_print_code (file, function->code);      lf_print__internal_ref (file);      print_sim_engine_abort (file, "Internal function must longjump");      lf_indent (file, -2);      lf_printf (file, "}\n");    }}#endif#if 0static voidprint_jump_until_stop_body (lf *file,			    insn_table *table, cache_table * cache_rules){  lf_printf (file, "{\n");  lf_indent (file, +2);  lf_putstr (file, "jmp_buf halt;\n");  lf_putstr (file, "jmp_buf restart;\n");  lf_putstr (file, "sim_cpu *cpu = NULL;\n");  lf_putstr (file, "unsigned_word nia = -1;\n");  lf_putstr (file, "instruction_word instruction = 0;\n");  if ((code & generate_with_icache))    {      lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");    }  if (generate_smp)    {      lf_putstr (file, "int current_cpu = -1;\n");    }  /* all the switches and tables - they know about jumping */  print_idecode_lookups (file, table, cache_rules);  /* start the simulation up */  if ((code & generate_with_icache))    {      lf_putstr (file, "\n");      lf_putstr (file, "{\n");      lf_putstr (file, "  int cpu_nr;\n");      lf_putstr (file, "  for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");      lf_putstr (file, "    cpu_flush_icache(cpus[cpu_nr]);\n");      lf_putstr (file, "}\n");    }  lf_putstr (file, "\n");  lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");  lf_putstr (file, "\n");  lf_putstr (file, "if (setjmp(halt))\n");  lf_putstr (file, "  return;\n");  lf_putstr (file, "\n");  lf_putstr (file, "setjmp(restart);\n");  lf_putstr (file, "\n");  if (!generate_smp)    {      lf_putstr (file, "cpu = cpus[0];\n");      lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");    }  else    {      lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");    }  if (!(code & generate_with_icache))    {      lf_printf (file, "\n");      lf_indent (file, -1);      lf_printf (file, "idecode:\n");      lf_indent (file, +1);    }  print_jump (file, 0 /*is_tail */ );  if ((code & generate_with_icache))    {      lf_indent (file, -1);      lf_printf (file, "cache_miss:\n");      lf_indent (file, +1);    }  lf_putstr (file, "instruction\n");  lf_putstr (file, "  = vm_instruction_map_read(cpu_instruction_map(cpu),\n");  lf_putstr (file, "                            cpu, nia);\n");  print_idecode_body (file, table, "/*IGORE*/");  /* print out a table of all the internals functions */  insn_table_traverse_function (table,				file, NULL, print_jump_internal_function);  /* print out a table of all the instructions */  if (generate_expanded_instructions)    insn_table_traverse_tree (table, file, cache_rules, 1, NULL,	/* start */			      print_jump_definition,	/* leaf */			      NULL,	/* end */			      NULL);	/* padding */  else    insn_table_traverse_insn (table,			      file, cache_rules, print_jump_definition);  lf_indent (file, -2);  lf_printf (file, "}\n");}#endif/****************************************************************//* Output code to do any final checks on the decoded instruction.   This includes things like verifying any on decoded fields have the   correct value and checking that (for floating point) floating point   hardware isn't disabled */voidprint_idecode_validate (lf *file,			insn_entry * instruction, insn_opcodes *opcode_paths){  /* Validate: unchecked instruction fields     If any constant fields in the instruction were not checked by the     idecode tables, output code to check that they have the correct     value here */  {    int nr_checks = 0;    int word_nr;    lf_printf (file, "\n");    lf_indent_suppress (file);    lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");    lf_printf (file, "/* validate: ");    print_insn_words (file, instruction);    lf_printf (file, " */\n");    for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)      {	insn_uint check_mask = 0;	insn_uint check_val = 0;	insn_word_entry *word = instruction->word[word_nr];	int bit_nr;	/* form check_mask/check_val containing what needs to be checked	   in the instruction */	for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)	  {	    insn_bit_entry *bit = word->bit[bit_nr];	    insn_field_entry *field = bit->field;	    /* Make space for the next bit */	    check_mask <<= 1;	    check_val <<= 1;	    /* Only need to validate constant (and reserved)	       bits. Skip any others */	    if (field->type != insn_field_int		&& field->type != insn_field_reserved)	      continue;	    /* Look through the list of opcode paths that lead to this	       instruction.  See if any have failed to check the	       relevant bit */	    if (opcode_paths != NULL)	      {		insn_opcodes *entry;		for (entry = opcode_paths; entry != NULL; entry = entry->next)		  {		    opcode_field *opcode;		    for (opcode = entry->opcode;			 opcode != NULL; opcode = opcode->parent)		      {			if (opcode->word_nr == word_nr			    && opcode->first <= bit_nr			    && opcode->last >= bit_nr)			  /* we've decoded on this bit */			  break;		      }		    if (opcode == NULL)		      /* the bit wasn't decoded on */		      break;		  }		if (entry == NULL)		  /* all the opcode paths decoded on BIT_NR, no need		     to check it */		  continue;	      }	    check_mask |= 1;	    check_val |= bit->value;	  }	/* if any bits not checked by opcode tables, output code to check them */	if (check_mask)	  {	    if (nr_checks == 0)	      {		lf_printf (file, "if (WITH_RESERVED_BITS)\n");		lf_printf (file, "  {\n");		lf_indent (file, +4);	      }	    nr_checks++;	    if (options.insn_bit_size > 32)	      {		lf_printf (file, "if ((instruction_%d\n", word_nr);		lf_printf (file, "     & UNSIGNED64 (0x%08lx%08lx))\n",			   (unsigned long) (check_mask >> 32),			   (unsigned long) (check_mask));		lf_printf (file, "    != UNSIGNED64 (0x%08lx%08lx))\n",			   (unsigned long) (check_val >> 32),			   (unsigned long) (check_val));	      }	    else	      {		lf_printf (file,			   "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",			   word_nr, (unsigned long) (check_mask),			   (unsigned long) (check_val));	      }	    lf_indent (file, +2);	    print_idecode_invalid (file, "return", invalid_illegal);	    lf_indent (file, -2);	  }      }    if (nr_checks > 0)      {	lf_indent (file, -4);	lf_printf (file, "  }\n");      }    lf_indent_suppress (file);    lf_printf (file, "#endif\n");  }  /* Validate: Floating Point hardware     If the simulator is being built with out floating point hardware     (different to it being disabled in the MSR) then floating point     instructions are invalid */  {    if (filter_is_member (instruction->flags, "f"))      {	lf_printf (file, "\n");	lf_indent_suppress (file);	lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");	lf_printf (file, "/* Validate: FP hardware exists */\n");	lf_printf (file,		   "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");	lf_indent (file, +2);	print_idecode_invalid (file, "return", invalid_illegal);	lf_indent (file, -2);	lf_printf (file, "}\n");	lf_indent_suppress (file);	lf_printf (file, "#endif\n");      }  }  /* Validate: Floating Point available     If floating point is not available, we enter a floating point     unavailable interrupt into the cache instead of the instruction     proper.     The PowerPC spec requires a CSI after MSR[FP] is changed and when     ever a CSI occures we flush the instruction cache. */  {    if (filter_is_member (instruction->flags, "f"))      {	lf_printf (file, "\n");	lf_indent_suppress (file);	lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");	lf_printf (file, "/* Validate: FP available according to cpu */\n");	lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");	lf_indent (file, +2);	print_idecode_invalid (file, "return", invalid_fp_unavailable);	lf_indent (file, -2);	lf_printf (file, "}\n");	lf_indent_suppress (file);	lf_printf (file, "#endif\n");      }  }  /* Validate: Validate Instruction in correct slot     Some architectures place restrictions on the slot that an     instruction can be issued in */  {    if (filter_is_member (instruction->options, "s")	|| options.gen.slot_verification)      {	lf_printf (file, "\n");	lf_indent_suppress (file);	lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");	lf_printf (file,		   "/* Validate: Instruction issued in correct slot */\n");	lf_printf (file, "if (IS_WRONG_SLOT) {\n");	lf_indent (file, +2);	print_idecode_invalid (file, "return", invalid_wrong_slot);	lf_indent (file, -2);	lf_printf (file, "}\n");	lf_indent_suppress (file);	lf_printf (file, "#endif\n");      }  }}/****************************************************************/voidprint_idecode_issue_function_header (lf *file,				     const char *processor,				     function_decl_type decl_type,				     int nr_prefetched_words){  int indent;  lf_printf (file, "\n");  switch (decl_type)    {    case is_function_declaration:      lf_print__function_type_function (file, print_semantic_function_type,					"INLINE_IDECODE", " ");      break;    case is_function_definition:      lf_print__function_type_function (file, print_semantic_function_type,					"INLINE_IDECODE", "\n");      break;    case is_function_variable:      print_semantic_function_type (file);      lf_printf (file, " (*");      break;    }  indent = print_function_name (file,				"issue",				NULL,				processor,				NULL, function_name_prefix_idecode);  switch (decl_type)    {    case is_function_definition:      indent += lf_printf (file, " (");      break;    case is_function_declaration:      lf_putstr (file, "\n(");      indent = 1;      break;    case is_function_variable:      lf_putstr (file, ")\n(");      indent = 1;      break;    }  lf_indent (file, +indent);  print_semantic_function_formal (file, nr_prefetched_words);  lf_putstr (file, ")");  lf_indent (file, -indent);  switch (decl_type)    {    case is_function_definition:      lf_printf (file, "\n");      break;    case is_function_declaration:    case is_function_variable:      lf_putstr (file, ";\n");      break;    }}voidprint_idecode_globals (lf *file){  lf_printf (file, "enum {\n");  lf_printf (file, "  /* greater or equal to zero => table */\n");  lf_printf (file, "  function_entry = -1,\n");  lf_printf (file, "  boolean_entry = -2,\n");  lf_printf (file, "};\n");  lf_printf (file, "\n");  lf_printf (file, "typedef struct _idecode_table_entry {\n");  lf_printf (file, "  int shift;\n");  lf_printf (file, "  unsigned%d mask;\n", options.insn_bit_size);  lf_printf (file, "  unsigned%d value;\n", options.insn_bit_size);  lf_printf (file, "  void *function_or_table;\n");  lf_printf (file, "} idecode_table_entry;\n");}

⌨️ 快捷键说明

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