📄 tc-h8300.c
字号:
nibble_count++; *p++ = nib; } /* Disgusting. Why, oh why didn't someone ask us for advice on the assembler format. */ if (strcmp (this_try->name, "stm.l") == 0 || strcmp (this_try->name, "ldm.l") == 0) { int high, low; high = (operand[this_try->name[0] == 'l' ? 1 : 0].reg >> 8) & 0xf; low = operand[this_try->name[0] == 'l' ? 1 : 0].reg & 0xf; asnibbles[2] = high - low; asnibbles[7] = (this_try->name[0] == 'l') ? high : low; } for (i = 0; i < this_try->length; i++) { output[i] = (asnibbles[i * 2] << 4) | asnibbles[i * 2 + 1]; } /* Note if this is a movb instruction -- there's a special relaxation which only applies to them. */ if (strcmp (this_try->name, "mov.b") == 0) movb = 1; /* Output any fixes. */ for (i = 0; i < 2; i++) { int x = operand[i].mode; if (x & (IMM | DISP)) { do_a_fix_imm (output - frag_now->fr_literal + immat, operand + i, x & MEMRELAX != 0); } else if (x & ABS) { do_a_fix_imm (output - frag_now->fr_literal + absat, operand + i, x & MEMRELAX ? movb + 1 : 0); } else if (x & PCREL) { int size16 = x & L_16; int where = size16 ? 2 : 1; int size = size16 ? 2 : 1; int type = size16 ? R_PCRWORD : R_PCRBYTE; check_operand (operand + i, size16 ? 0x7fff : 0x7f, "@"); if (operand[i].exp.X_add_number & 1) { as_warn (_("branch operand has odd offset (%lx)\n"), (unsigned long) operand->exp.X_add_number); } operand[i].exp.X_add_number -= 1; operand[i].exp.X_add_number = ((operand[i].exp.X_add_number & 0xff) ^ 0x80) - 0x80; fix_new_exp (frag_now, output - frag_now->fr_literal + where, size, &operand[i].exp, 1, type); } else if (x & MEMIND) { check_operand (operand + i, 0xff, "@@"); fix_new_exp (frag_now, output - frag_now->fr_literal + 1, 1, &operand[i].exp, 0, R_MEM_INDIRECT); } else if (x & ABSJMP) { /* This jmp may be a jump or a branch. */ check_operand (operand + i, Hmode ? 0xffffff : 0xffff, "@"); if (operand[i].exp.X_add_number & 1) { as_warn (_("branch operand has odd offset (%lx)\n"), (unsigned long) operand->exp.X_add_number); } if (!Hmode) operand[i].exp.X_add_number = ((operand[i].exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000; fix_new_exp (frag_now, output - frag_now->fr_literal, 4, &operand[i].exp, 0, R_JMPL1); } }}/* Try to give an intelligent error message for common and simple to detect errors. */static voidclever_message (opcode, operand) struct h8_opcode *opcode; struct h8_op *operand;{ /* Find out if there was more than one possible opcode. */ if ((opcode + 1)->idx != opcode->idx) { unsigned int argn; /* Only one opcode of this flavour, try to guess which operand didn't match. */ for (argn = 0; argn < opcode->noperands; argn++) { switch (opcode->args.nib[argn]) { case RD16: if (operand[argn].mode != RD16) { as_bad (_("destination operand must be 16 bit register")); return; } break; case RS8: if (operand[argn].mode != RS8) { as_bad (_("source operand must be 8 bit register")); return; } break; case ABS16DST: if (operand[argn].mode != ABS16DST) { as_bad (_("destination operand must be 16bit absolute address")); return; } break; case RD8: if (operand[argn].mode != RD8) { as_bad (_("destination operand must be 8 bit register")); return; } break; case ABS16SRC: if (operand[argn].mode != ABS16SRC) { as_bad (_("source operand must be 16bit absolute address")); return; } break; } } } as_bad (_("invalid operands"));}/* This is the guts of the machine-dependent assembler. STR points to a machine dependent instruction. This function is supposed to emit the frags/bytes it assembles. */voidmd_assemble (str) char *str;{ char *op_start; char *op_end; struct h8_op operand[2]; struct h8_opcode *opcode; struct h8_opcode *prev_opcode; char *dot = 0; char c; int size; /* Drop leading whitespace. */ while (*str == ' ') str++; /* Find the op code end. */ for (op_start = op_end = str; *op_end != 0 && *op_end != ' '; op_end++) { if (*op_end == '.') { dot = op_end + 1; *op_end = 0; op_end += 2; break; } } if (op_end == op_start) { as_bad (_("can't find opcode ")); } c = *op_end; *op_end = 0; opcode = (struct h8_opcode *) hash_find (opcode_hash_control, op_start); if (opcode == NULL) { as_bad (_("unknown opcode")); return; } /* We used to set input_line_pointer to the result of get_operands, but that is wrong. Our caller assumes we don't change it. */ (void) get_operands (opcode->noperands, op_end, operand); *op_end = c; prev_opcode = opcode; size = SN; if (dot) { switch (*dot) { case 'b': size = SB; break; case 'w': size = SW; break; case 'l': size = SL; break; } } opcode = get_specific (opcode, operand, size); if (opcode == 0) { /* Couldn't find an opcode which matched the operands. */ char *where = frag_more (2); where[0] = 0x0; where[1] = 0x0; clever_message (prev_opcode, operand); return; } if (opcode->size && dot) { if (opcode->size != *dot) { as_warn (_("mismatch between opcode size and operand size")); } } build_bytes (opcode, operand);}voidtc_crawl_symbol_chain (headers) object_headers *headers ATTRIBUTE_UNUSED;{ printf (_("call to tc_crawl_symbol_chain \n"));}symbolS *md_undefined_symbol (name) char *name ATTRIBUTE_UNUSED;{ return 0;}voidtc_headers_hook (headers) object_headers *headers ATTRIBUTE_UNUSED;{ 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 ATTRIBUTE_UNUSED; char *arg ATTRIBUTE_UNUSED;{ return 0;}voidmd_show_usage (stream) FILE *stream ATTRIBUTE_UNUSED;{}voidtc_aout_fix_to_chars (){ printf (_("call to tc_aout_fix_to_chars \n")); abort ();}voidmd_convert_frag (headers, seg, fragP) object_headers *headers ATTRIBUTE_UNUSED; segT seg ATTRIBUTE_UNUSED; fragS *fragP ATTRIBUTE_UNUSED;{ printf (_("call to md_convert_frag \n")); abort ();}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; switch (fixP->fx_size) { case 1: *buf++ = val; break; case 2: *buf++ = (val >> 8); *buf++ = val; break; case 4: *buf++ = (val >> 24); *buf++ = (val >> 16); *buf++ = (val >> 8); *buf++ = val; break; default: abort (); }}intmd_estimate_size_before_relax (fragP, segment_type) register fragS *fragP ATTRIBUTE_UNUSED; register segT segment_type ATTRIBUTE_UNUSED;{ printf (_("call tomd_estimate_size_before_relax \n")); abort ();}/* 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 ATTRIBUTE_UNUSED;{ abort ();}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 == TC_CONS_RELOC) { /* cons likes to create reloc32's whatever the size of the reloc.. */ switch (fix_ptr->fx_size) { case 4: intr->r_type = R_RELLONG; break; case 2: intr->r_type = R_RELWORD; break; case 1: intr->r_type = R_RELBYTE; 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; if (symbol_ptr) { if (symbol_ptr->sy_number != -1) intr->r_symndx = symbol_ptr->sy_number; else { symbolS *segsym; /* This case arises when a reference is made to `.'. */ segsym = seg_info (S_GET_SEGMENT (symbol_ptr))->dot; if (segsym == NULL) intr->r_symndx = -1; else { intr->r_symndx = segsym->sy_number; intr->r_offset += S_GET_VALUE (symbol_ptr); } } } else intr->r_symndx = -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -