📄 tc-i860.c
字号:
t = atof_ieee (input_line_pointer, type, words); if (t) input_line_pointer = t; *sizeP = prec * sizeof (LITTLENUM_TYPE); for (wordP = words; prec--;) { md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0;}/* Write out in current endian mode. */voidmd_number_to_chars (buf, val, n) char *buf; valueT val; int n;{ if (target_big_endian) number_to_chars_bigendian (buf, val, n); else number_to_chars_littleendian (buf, val, n);}/* This should never be called for i860. */voidmd_number_to_disp (buf, val, n) char *buf ATTRIBUTE_UNUSED; long val ATTRIBUTE_UNUSED; int n ATTRIBUTE_UNUSED;{ as_fatal (_("md_number_to_disp\n"));}/* This should never be called for i860. */voidmd_number_to_field (buf, val, fix) char *buf ATTRIBUTE_UNUSED; long val ATTRIBUTE_UNUSED; void *fix ATTRIBUTE_UNUSED;{ as_fatal (_("i860_number_to_field\n"));}/* This should never be called for i860. */intmd_estimate_size_before_relax (fragP, segtype) register fragS *fragP ATTRIBUTE_UNUSED; segT segtype ATTRIBUTE_UNUSED;{ as_fatal (_("i860_estimate_size_before_relax\n"));}#ifdef DEBUG_I860static voidprint_insn (insn) struct i860_it *insn;{ if (insn->error) fprintf (stderr, "ERROR: %s\n", insn->error); fprintf (stderr, "opcode = 0x%08lx\t", insn->opcode); fprintf (stderr, "expand = 0x%x\t", insn->expand); fprintf (stderr, "reloc = %s\t\n", bfd_get_reloc_code_name (insn->reloc)); fprintf (stderr, "exp = {\n"); fprintf (stderr, "\t\tX_add_symbol = %s\n", insn->exp.X_add_symbol ? (S_GET_NAME (insn->exp.X_add_symbol) ? S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0"); fprintf (stderr, "\t\tX_op_symbol = %s\n", insn->exp.X_op_symbol ? (S_GET_NAME (insn->exp.X_op_symbol) ? S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0"); fprintf (stderr, "\t\tX_add_number = %lx\n", insn->exp.X_add_number); fprintf (stderr, "}\n");}#endif /* DEBUG_I860 */#ifdef OBJ_ELFCONST char *md_shortopts = "VQ:";#elseCONST char *md_shortopts = "";#endif#define OPTION_EB (OPTION_MD_BASE + 0)#define OPTION_EL (OPTION_MD_BASE + 1)#define OPTION_WARN_EXPAND (OPTION_MD_BASE + 2)struct option md_longopts[] = { { "EB", no_argument, NULL, OPTION_EB }, { "EL", no_argument, NULL, OPTION_EL }, { "mwarn-expand", no_argument, NULL, OPTION_WARN_EXPAND }, { NULL, no_argument, NULL, 0 }};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg) int c; char *arg ATTRIBUTE_UNUSED;{ switch (c) { case OPTION_EB: target_big_endian = 1; break; case OPTION_EL: target_big_endian = 0; break; case OPTION_WARN_EXPAND: target_warn_expand = 1; break;#ifdef OBJ_ELF /* SVR4 argument compatibility (-V): print version ID. */ case 'V': print_version_id (); break; /* SVR4 argument compatibility (-Qy, -Qn): controls whether a .comment section should be emitted or not (ignored). */ case 'Q': break;#endif default: return 0; } return 1;}voidmd_show_usage (stream) FILE *stream;{ fprintf (stream, _("\ -EL generate code for little endian mode (default)\n\ -EB generate code for big endian mode\n\ -mwarn-expand warn if pseudo operations are expanded\n"));#ifdef OBJ_ELF /* SVR4 compatibility flags. */ fprintf (stream, _("\ -V print assembler version number\n\ -Qy, -Qn ignored\n"));#endif}/* We have no need to default values of symbols. */symbolS *md_undefined_symbol (name) char *name ATTRIBUTE_UNUSED;{ return 0;}/* The i860 denotes auto-increment with '++'. */voidmd_operand (exp) expressionS *exp;{ char *s; for (s = input_line_pointer; *s; s++) { if (s[0] == '+' && s[1] == '+') { input_line_pointer += 2; exp->X_op = O_register; break; } }}/* Round up a section size to the appropriate boundary. */valueTmd_section_align (segment, size) segT segment ATTRIBUTE_UNUSED; valueT size ATTRIBUTE_UNUSED;{ /* Byte alignment is fine. */ return size;}/* On the i860, a PC-relative offset is relative to the address of the of the offset plus its size. */longmd_pcrel_from (fixP) fixS *fixP;{ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;}/* Determine the relocation needed for non PC-relative 16-bit immediates. Also adjust the given immediate as necessary. Finally, check that all constraints (such as alignment) are satisfied. */static bfd_reloc_code_real_typeobtain_reloc_for_imm16 (fix, val) fixS *fix; long *val;{ valueT fup = fix->fx_addnumber; bfd_reloc_code_real_type reloc; if (fix->fx_pcrel) abort (); /* Check alignment restrictions. */ if ((fup & OP_ALIGN2) && (*val & 0x1)) as_bad_where (fix->fx_file, fix->fx_line, _("This immediate requires 0 MOD 2 alignment")); else if ((fup & OP_ALIGN4) && (*val & 0x3)) as_bad_where (fix->fx_file, fix->fx_line, _("This immediate requires 0 MOD 4 alignment")); else if ((fup & OP_ALIGN8) && (*val & 0x7)) as_bad_where (fix->fx_file, fix->fx_line, _("This immediate requires 0 MOD 8 alignment")); else if ((fup & OP_ALIGN16) && (*val & 0xf)) as_bad_where (fix->fx_file, fix->fx_line, _("This immediate requires 0 MOD 16 alignment")); if (fup & OP_SEL_HA) { *val = (*val >> 16) + (*val & 0x8000 ? 1 : 0); reloc = BFD_RELOC_860_HIGHADJ; } else if (fup & OP_SEL_H) { *val >>= 16; reloc = BFD_RELOC_860_HIGH; } else if (fup & OP_SEL_L) { int num_encode; if (fup & OP_IMM_SPLIT16) { if (fup & OP_ENCODE1) { num_encode = 1; reloc = BFD_RELOC_860_SPLIT1; } else if (fup & OP_ENCODE2) { num_encode = 2; reloc = BFD_RELOC_860_SPLIT2; } else { num_encode = 0; reloc = BFD_RELOC_860_SPLIT0; } } else { if (fup & OP_ENCODE1) { num_encode = 1; reloc = BFD_RELOC_860_LOW1; } else if (fup & OP_ENCODE2) { num_encode = 2; reloc = BFD_RELOC_860_LOW2; } else if (fup & OP_ENCODE3) { num_encode = 3; reloc = BFD_RELOC_860_LOW3; } else { num_encode = 0; reloc = BFD_RELOC_860_LOW0; } } /* Preserve size encode bits. */ *val &= ~((1 << num_encode) - 1); } else { /* No selector. What reloc do we generate (???)? */ reloc = BFD_RELOC_32; } return reloc;}/* Attempt to simplify or eliminate a fixup. To indicate that a fixup has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL, we will have to generate a reloc entry. */intmd_apply_fix3 (fix, valuep, seg) fixS *fix; valueT *valuep; segT seg ATTRIBUTE_UNUSED;{ char *buf; long val = (long) (*valuep); unsigned long insn; valueT fup; buf = fix->fx_frag->fr_literal + fix->fx_where; /* Recall that earlier we stored the opcode little-endian. */ insn = bfd_getl32 (buf); /* We stored a fix-up in this oddly-named scratch field. */ fup = fix->fx_addnumber; /* Determine the necessary relocations as well as inserting an immediate into the instruction. */ if (fup == OP_IMM_U5) { if (val & ~0x1f) as_bad_where (fix->fx_file, fix->fx_line, _("5-bit immediate too large")); if (fix->fx_addsy) as_bad_where (fix->fx_file, fix->fx_line, _("5-bit field must be absolute")); insn |= (val & 0x1f) << 11; bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } else if (fup & OP_IMM_S16) { fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val); /* Insert the immediate. */ if (fix->fx_addsy) fix->fx_done = 0; else { insn |= val & 0xffff; bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } } else if (fup & OP_IMM_U16) { abort (); } else if (fup & OP_IMM_SPLIT16) { fix->fx_r_type = obtain_reloc_for_imm16 (fix, &val); /* Insert the immediate. */ if (fix->fx_addsy) fix->fx_done = 0; else { insn |= val & 0x7ff; insn |= (val & 0xf800) << 5; bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } } else if (fup & OP_IMM_BR16) { if (val & 0x3) as_bad_where (fix->fx_file, fix->fx_line, _("A branch offset requires 0 MOD 4 alignment")); val = val >> 2; /* Insert the immediate. */ if (fix->fx_addsy) { fix->fx_done = 0; fix->fx_r_type = BFD_RELOC_860_PC16; } else { insn |= (val & 0x7ff); insn |= ((val & 0xf800) << 5); bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } } else if (fup & OP_IMM_BR26) { if (val & 0x3) as_bad_where (fix->fx_file, fix->fx_line, _("A branch offset requires 0 MOD 4 alignment")); val >>= 2; /* Insert the immediate. */ if (fix->fx_addsy) { fix->fx_r_type = BFD_RELOC_860_PC26; fix->fx_done = 0; } else { insn |= (val & 0x3ffffff); bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } } else if (fup != OP_NONE) { as_bad_where (fix->fx_file, fix->fx_line, _("Unrecognized fix-up (0x%08x)"), fup); abort (); } else { /* I believe only fix-ups such as ".long .ep.main-main+0xc8000000" reach here (???). */ if (fix->fx_addsy) { fix->fx_r_type = BFD_RELOC_32; fix->fx_done = 0; } else { insn |= (val & 0xffffffff); bfd_putl32 (insn, buf); fix->fx_r_type = BFD_RELOC_NONE; fix->fx_done = 1; } } /* Return value ignored. */ return 0;}/* Generate a machine dependent reloc from a fixup. */arelent*tc_gen_reloc (section, fixp) asection *section ATTRIBUTE_UNUSED; fixS *fixp;{ arelent *reloc; reloc = xmalloc (sizeof (*reloc)); reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; reloc->addend = fixp->fx_offset; reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); if (! reloc->howto) { as_bad_where (fixp->fx_file, fixp->fx_line, "Cannot represent %s relocation in object file", bfd_get_reloc_code_name (fixp->fx_r_type)); } return reloc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -