📄 tc-fr30.c
字号:
fragP->fr_type == rs_machine_dependent. fragP->fr_subtype is the subtype of what the address relaxed to. */voidmd_convert_frag (abfd, sec, fragP) bfd * abfd; segT sec; fragS * fragP;{#if 0 char * opcode; char * displacement; int target_address; int opcode_address; int extension; int addend; opcode = fragP->fr_opcode; /* Address opcode resides at in file space. */ opcode_address = fragP->fr_address + fragP->fr_fix - 2; switch (fragP->fr_subtype) { case 1 : extension = 0; displacement = & opcode[1]; break; case 2 : opcode[0] |= 0x80; extension = 2; displacement = & opcode[1]; break; case 3 : opcode[2] = opcode[0] | 0x80; md_number_to_chars (opcode, PAR_NOP_INSN, 2); opcode_address += 2; extension = 4; displacement = & opcode[3]; break; default : abort (); } if (S_GET_SEGMENT (fragP->fr_symbol) != sec) { /* symbol must be resolved by linker */ if (fragP->fr_offset & 3) as_warn (_("Addend to unresolved symbol not on word boundary.")); addend = fragP->fr_offset >> 2; } else { /* Address we want to reach in file space. */ target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset; target_address += symbol_get_frag (fragP->fr_symbol)->fr_address; addend = (target_address - (opcode_address & -4)) >> 2; } /* Create a relocation for symbols that must be resolved by the linker. Otherwise output the completed insn. */ if (S_GET_SEGMENT (fragP->fr_symbol) != sec) { assert (fragP->fr_subtype != 1); assert (fragP->fr_cgen.insn != 0); gas_cgen_record_fixup (fragP, /* Offset of branch insn in frag. */ fragP->fr_fix + extension - 4, fragP->fr_cgen.insn, 4 /*length*/, /* FIXME: quick hack */#if 0 CGEN_OPERAND_ENTRY (fragP->fr_cgen.opindex),#else CGEN_OPERAND_ENTRY (FR30_OPERAND_DISP24),#endif fragP->fr_cgen.opinfo, fragP->fr_symbol, fragP->fr_offset); }#define SIZE_FROM_RELAX_STATE(n) ((n) == 1 ? 1 : 3) md_number_to_chars (displacement, (valueT) addend, SIZE_FROM_RELAX_STATE (fragP->fr_subtype)); fragP->fr_fix += extension;#endif}/* Functions concerning relocs. *//* The location from which a PC relative jump should be calculated, given a PC relative reloc. */longmd_pcrel_from_section (fixP, sec) fixS * fixP; segT sec;{ if (fixP->fx_addsy != (symbolS *) NULL && (! S_IS_DEFINED (fixP->fx_addsy) || S_GET_SEGMENT (fixP->fx_addsy) != sec)) { /* The symbol is undefined (or is defined but not in this section). Let the linker figure it out. */ return 0; } return (fixP->fx_frag->fr_address + fixP->fx_where) & ~1;}/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP. Returns BFD_RELOC_NONE if no reloc type can be found. *FIXP may be modified if desired. */bfd_reloc_code_real_typemd_cgen_lookup_reloc (insn, operand, fixP) const CGEN_INSN * insn; const CGEN_OPERAND * operand; fixS * fixP;{ switch (operand->type) { case FR30_OPERAND_LABEL9: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_9_PCREL; case FR30_OPERAND_LABEL12: fixP->fx_pcrel = 1; return BFD_RELOC_FR30_12_PCREL; case FR30_OPERAND_DISP10: return BFD_RELOC_FR30_10_IN_8; case FR30_OPERAND_DISP9: return BFD_RELOC_FR30_9_IN_8; case FR30_OPERAND_DISP8: return BFD_RELOC_FR30_8_IN_8; case FR30_OPERAND_UDISP6: return BFD_RELOC_FR30_6_IN_4; case FR30_OPERAND_I8: return BFD_RELOC_8; case FR30_OPERAND_I32: return BFD_RELOC_FR30_48; case FR30_OPERAND_I20: return BFD_RELOC_FR30_20; default : /* avoid -Wall warning */ break; } return BFD_RELOC_NONE;}/* See whether we need to force a relocation into the output file. This is used to force out switch and PC relative relocations when relaxing. */intfr30_force_relocation (fix) fixS * fix;{ if ( fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 1; return 0;}/* Write a value out to the object file, using the appropriate endianness. */voidmd_number_to_chars (buf, val, n) char * buf; valueT val; int n;{ number_to_chars_bigendian (buf, val, n);}/* Turn a string in input_line_pointer into a floating point constant of type type, and store the appropriate bytes in *litP. The number of LITTLENUMS emitted is stored in *sizeP . An error message is returned, or NULL on OK.*//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6char *md_atof (type, litP, sizeP) char type; char * litP; int * sizeP;{ int i; int prec; LITTLENUM_TYPE words [MAX_LITTLENUMS]; char * t; char * atof_ieee (); switch (type) { case 'f': case 'F': case 's': case 'S': prec = 2; break; case 'd': case 'D': case 'r': case 'R': prec = 4; break; /* FIXME: Some targets allow other format chars for bigger sizes here. */ default: * sizeP = 0; return _("Bad call to md_atof()"); } t = atof_ieee (input_line_pointer, type, words); if (t) input_line_pointer = t; * sizeP = prec * sizeof (LITTLENUM_TYPE); for (i = 0; i < prec; i++) { md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0;}/* Worker function for fr30_is_colon_insn(). */static charrestore_colon (advance_i_l_p_by) int advance_i_l_p_by;{ char c; /* Restore the colon, and advance input_line_pointer to the end of the new symbol. */ * input_line_pointer = ':'; input_line_pointer += advance_i_l_p_by; c = * input_line_pointer; * input_line_pointer = 0; return c;}/* Determines if the symbol starting at START and ending in a colon that was at the location pointed to by INPUT_LINE_POINTER (but which has now been replaced bu a NUL) is in fact an LDI:8, LDI:20, LDI:32, CALL:D. JMP:D, RET:D or Bcc:D instruction. If it is, then it restores the colon, advances INPUT_LINE_POINTER to the real end of the instruction/symbol, and returns the character that really terminated the symbol. Otherwise it returns 0. */charfr30_is_colon_insn (start) char * start;{ char * i_l_p = input_line_pointer; /* Check to see if the symbol parsed so far is 'ldi' */ if ( (start[0] != 'l' && start[0] != 'L') || (start[1] != 'd' && start[1] != 'D') || (start[2] != 'i' && start[2] != 'I') || start[3] != 0) { /* Nope - check to see a 'd' follows the colon. */ if ( (i_l_p[1] == 'd' || i_l_p[1] == 'D') && (i_l_p[2] == ' ' || i_l_p[2] == '\t' || i_l_p[2] == '\n')) { /* Yup - it might be delay slot instruction. */ int i; static char * delay_insns [] = { "call", "jmp", "ret", "bra", "bno", "beq", "bne", "bc", "bnc", "bn", "bp", "bv", "bnv", "blt", "bge", "ble", "bgt", "bls", "bhi" }; for (i = sizeof (delay_insns) / sizeof (delay_insns[0]); i--;) { char * insn = delay_insns[i]; int len = strlen (insn); if (start [len] != 0) continue; while (len --) if (tolower (start [len]) != insn [len]) break; if (len == -1) return restore_colon (1); } } /* Nope - it is a normal label. */ return 0; } /* Check to see if the text following the colon is '8' */ if (i_l_p[1] == '8' && (i_l_p[2] == ' ' || i_l_p[2] == '\t')) return restore_colon (2); /* Check to see if the text following the colon is '20' */ else if (i_l_p[1] == '2' && i_l_p[2] =='0' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) return restore_colon (3); /* Check to see if the text following the colon is '32' */ else if (i_l_p[1] == '3' && i_l_p[2] =='2' && (i_l_p[3] == ' ' || i_l_p[3] == '\t')) return restore_colon (3); return 0;}booleanfr30_fix_adjustable (fixP) fixS * fixP;{ if (fixP->fx_addsy == NULL) return 1;#if 0 /* Prevent all adjustments to global symbols. */ if (S_IS_EXTERN (fixP->fx_addsy)) return 0; if (S_IS_WEAK (fixP->fx_addsy)) return 0;#endif /* We need the symbol name for the VTABLE entries */ if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY) return 0; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -