📄 tc-h8500.c
字号:
/* Find the op code end. */ for (op_start = op_end = str; !is_end_of_line[(unsigned char) *op_end] && *op_end != ' '; op_end++) { if ( /**op_end != '.' && *op_end != ':' && */ nlen < 10) { name[nlen++] = *op_end; } } name[nlen] = 0; if (op_end == op_start) as_bad (_("can't find opcode ")); opcode = (h8500_opcode_info *) hash_find (opcode_hash_control, name); if (opcode == NULL) { as_bad (_("unknown opcode")); return; } get_operands (opcode, op_end, operand); prev_opcode = opcode; opcode = get_specific (opcode, operand); if (opcode == 0) { /* Couldn't find an opcode which matched the operands */ char *where = frag_more (2); where[0] = 0x0; where[1] = 0x0; as_bad (_("invalid operands for opcode")); return; } build_bytes (opcode, operand);}voidtc_crawl_symbol_chain (headers) object_headers *headers;{ printf (_("call to tc_crawl_symbol_chain \n"));}symbolS *md_undefined_symbol (name) char *name;{ return 0;}voidtc_headers_hook (headers) object_headers *headers;{ printf (_("call to tc_headers_hook \n"));}/* Various routines to kill one day. *//* Equal to MAX_PRECISION in atof-ieee.c. */#define MAX_LITTLENUMS 6/* 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. */char *md_atof (type, litP, sizeP) char type; char *litP; int *sizeP;{ int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; 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; case 'x': case 'X': prec = 6; break; case 'p': case 'P': prec = 6; break; 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 (wordP = words; prec--;) { md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE)); litP += sizeof (LITTLENUM_TYPE); } return 0;}CONST char *md_shortopts = "";struct option md_longopts[] = { {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof (md_longopts);intmd_parse_option (c, arg) int c; char *arg;{ return 0;}voidmd_show_usage (stream) FILE *stream;{}voidtc_aout_fix_to_chars (){ printf (_("call to tc_aout_fix_to_chars \n")); abort ();}static voidwordify_scb (buffer, disp_size, inst_size) char *buffer; int *disp_size; int *inst_size;{ int rn = buffer[1] & 0x7; switch (buffer[0]) { case 0x0e: /* BSR */ case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29: case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f: buffer[0] |= 0x10; buffer[1] = 0; buffer[2] = 0; *disp_size = 2; *inst_size = 1; return; default: abort (); case 0x01: *inst_size = 6; *disp_size = 2; break; case 0x06: *inst_size = 8; *disp_size = 2; *buffer++ = 0x26; /* bne + 8 */ *buffer++ = 0x08; break; case 0x07: *inst_size = 8; *disp_size = 2; *buffer++ = 0x27; /* bne + 8 */ *buffer++ = 0x08; break; } *buffer++ = 0xa8 | rn; /* addq -1,rn */ *buffer++ = 0x0c; *buffer++ = 0x04; /* cmp #0xff:8, rn */ *buffer++ = 0xff; *buffer++ = 0x70 | rn; *buffer++ = 0x36; /* bne ... */ *buffer++ = 0; *buffer++ = 0;}/* Called after relaxing, change the frags so they know how big they are. */voidmd_convert_frag (headers, seg, fragP) object_headers *headers; segT seg; fragS *fragP;{ int disp_size = 0; int inst_size = 0; char *buffer = fragP->fr_fix + fragP->fr_literal; switch (fragP->fr_subtype) { case C (BRANCH, BYTE_DISP): disp_size = 1; inst_size = 1; break; case C (SCB_F, BYTE_DISP): case C (SCB_TST, BYTE_DISP): disp_size = 1; inst_size = 2; break; /* Branches to a known 16 bit displacement. */ /* Turn on the 16bit bit. */ case C (BRANCH, WORD_DISP): case C (SCB_F, WORD_DISP): case C (SCB_TST, WORD_DISP): wordify_scb (buffer, &disp_size, &inst_size); break; case C (BRANCH, UNDEF_WORD_DISP): case C (SCB_F, UNDEF_WORD_DISP): case C (SCB_TST, UNDEF_WORD_DISP): /* This tried to be relaxed, but didn't manage it, it now needs a fix. */ wordify_scb (buffer, &disp_size, &inst_size); /* Make a reloc */ fix_new (fragP, fragP->fr_fix + inst_size, 4, fragP->fr_symbol, fragP->fr_offset, 0, R_H8500_PCREL16); fragP->fr_fix += disp_size + inst_size; return; break; default: abort (); } if (inst_size) { /* Get the address of the end of the instruction */ int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size; int targ_addr = (S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset); int disp = targ_addr - next_inst; md_number_to_chars (buffer + inst_size, disp, disp_size); fragP->fr_fix += disp_size + inst_size; }}valueTmd_section_align (seg, size) segT seg ; valueT size;{ return ((size + (1 << section_alignment[(int) seg]) - 1) & (-1 << section_alignment[(int) seg]));}voidmd_apply_fix (fixP, val) fixS *fixP; long val;{ char *buf = fixP->fx_where + fixP->fx_frag->fr_literal; if (fixP->fx_r_type == 0) { fixP->fx_r_type = fixP->fx_size == 4 ? R_H8500_IMM32 : R_H8500_IMM16; } switch (fixP->fx_r_type) { case R_H8500_IMM8: case R_H8500_PCREL8: *buf++ = val; break; case R_H8500_IMM16: case R_H8500_LOW16: case R_H8500_PCREL16: *buf++ = (val >> 8); *buf++ = val; break; case R_H8500_HIGH8: *buf++ = val >> 16; break; case R_H8500_HIGH16: *buf++ = val >> 24; *buf++ = val >> 16; break; case R_H8500_IMM24: *buf++ = (val >> 16); *buf++ = (val >> 8); *buf++ = val; break; case R_H8500_IMM32: *buf++ = (val >> 24); *buf++ = (val >> 16); *buf++ = (val >> 8); *buf++ = val; break; default: abort (); }}/*called just before address relaxation, return the lengthby which a fragment must grow to reach it's destination*/intmd_estimate_size_before_relax (fragP, segment_type) register fragS *fragP; register segT segment_type;{ int what; switch (fragP->fr_subtype) { default: abort (); case C (BRANCH, UNDEF_BYTE_DISP): case C (SCB_F, UNDEF_BYTE_DISP): case C (SCB_TST, UNDEF_BYTE_DISP): what = GET_WHAT (fragP->fr_subtype); /* used to be a branch to somewhere which was unknown */ if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type) { /* Got a symbol and it's defined in this segment, become byte sized - maybe it will fix up. */ fragP->fr_subtype = C (what, BYTE_DISP); } else { /* Its got a segment, but its not ours, so it will always be long. */ fragP->fr_subtype = C (what, UNDEF_WORD_DISP); } break; case C (BRANCH, BYTE_DISP): case C (BRANCH, WORD_DISP): case C (BRANCH, UNDEF_WORD_DISP): case C (SCB_F, BYTE_DISP): case C (SCB_F, WORD_DISP): case C (SCB_F, UNDEF_WORD_DISP): case C (SCB_TST, BYTE_DISP): case C (SCB_TST, WORD_DISP): case C (SCB_TST, UNDEF_WORD_DISP): /* When relaxing a section for the second time, we don't need to do anything besides return the current size. */ break; } return md_relax_table[fragP->fr_subtype].rlx_length;}/* Put number into target byte order. */voidmd_number_to_chars (ptr, use, nbytes) char *ptr; valueT use; int nbytes;{ number_to_chars_bigendian (ptr, use, nbytes);}longmd_pcrel_from (fixP) fixS *fixP;{ return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;}voidtc_coff_symbol_emit_hook (ignore) symbolS *ignore;{}shorttc_coff_fix2rtype (fix_ptr) fixS *fix_ptr;{ if (fix_ptr->fx_r_type == RELOC_32) { /* cons likes to create reloc32's whatever the size of the reloc.. */ switch (fix_ptr->fx_size) { case 2: return R_H8500_IMM16; break; case 1: return R_H8500_IMM8; break; default: abort (); } } return fix_ptr->fx_r_type;}voidtc_reloc_mangle (fix_ptr, intr, base) fixS *fix_ptr; struct internal_reloc *intr; bfd_vma base;{ symbolS *symbol_ptr; symbol_ptr = fix_ptr->fx_addsy; /* If this relocation is attached to a symbol then it's ok to output it */ if (fix_ptr->fx_r_type == RELOC_32) { /* cons likes to create reloc32's whatever the size of the reloc.. */ switch (fix_ptr->fx_size) { case 2: intr->r_type = R_IMM16; break; case 1: intr->r_type = R_IMM8; break; default: abort (); } } else { intr->r_type = fix_ptr->fx_r_type; } intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base; intr->r_offset = fix_ptr->fx_offset; /* Turn the segment of the symbol into an offset. */ if (symbol_ptr) { symbolS *dot; dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot; if (dot) {#if 0 intr->r_offset -= segment_info[S_GET_SEGMENT (symbol_ptr)].scnhdr.s_paddr;#endif intr->r_offset += S_GET_VALUE (symbol_ptr); intr->r_symndx = dot->sy_number; } else { intr->r_symndx = symbol_ptr->sy_number; } } else { intr->r_symndx = -1; }}intstart_label (ptr) char *ptr;{ /* Check for :s.w */ if (isalpha (ptr[1]) && ptr[2] == '.') return 0; /* Check for :s */ if (isalpha (ptr[1]) && !isalpha (ptr[2])) return 0; return 1;}inttc_coff_sizemachdep (frag) fragS *frag;{ return md_relax_table[frag->fr_subtype].rlx_length;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -