📄 tc-mn10300.c
字号:
{ fprintf (stream, _("MN10300 options:\n\none yet\n"));}intmd_parse_option (c, arg) int c ATTRIBUTE_UNUSED; char *arg ATTRIBUTE_UNUSED;{ return 0;}symbolS *md_undefined_symbol (name) char *name ATTRIBUTE_UNUSED;{ return 0;}char *md_atof (type, litp, sizep) int type; char *litp; int *sizep;{ int prec; LITTLENUM_TYPE words[4]; char *t; int i; switch (type) { case 'f': prec = 2; break; case 'd': prec = 4; 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 * 2; for (i = prec - 1; i >= 0; i--) { md_number_to_chars (litp, (valueT) words[i], 2); litp += 2; } return NULL;}voidmd_convert_frag (abfd, sec, fragP) bfd *abfd ATTRIBUTE_UNUSED; asection *sec; fragS *fragP;{ static unsigned long label_count = 0; char buf[40]; subseg_change (sec, 0); if (fragP->fr_subtype == 0) { fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL); fragP->fr_var = 0; fragP->fr_fix += 2; } else if (fragP->fr_subtype == 1) { /* Reverse the condition of the first branch. */ int offset = fragP->fr_fix; int opcode = fragP->fr_literal[offset] & 0xff; switch (opcode) { case 0xc8: opcode = 0xc9; break; case 0xc9: opcode = 0xc8; break; case 0xc0: opcode = 0xc2; break; case 0xc2: opcode = 0xc0; break; case 0xc3: opcode = 0xc1; break; case 0xc1: opcode = 0xc3; break; case 0xc4: opcode = 0xc6; break; case 0xc6: opcode = 0xc4; break; case 0xc7: opcode = 0xc5; break; case 0xc5: opcode = 0xc7; break; default: abort (); } fragP->fr_literal[offset] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 1, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 2] = 0xcc; fix_new (fragP, fragP->fr_fix + 3, 2, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 5; } else if (fragP->fr_subtype == 2) { /* Reverse the condition of the first branch. */ int offset = fragP->fr_fix; int opcode = fragP->fr_literal[offset] & 0xff; switch (opcode) { case 0xc8: opcode = 0xc9; break; case 0xc9: opcode = 0xc8; break; case 0xc0: opcode = 0xc2; break; case 0xc2: opcode = 0xc0; break; case 0xc3: opcode = 0xc1; break; case 0xc1: opcode = 0xc3; break; case 0xc4: opcode = 0xc6; break; case 0xc6: opcode = 0xc4; break; case 0xc7: opcode = 0xc5; break; case 0xc5: opcode = 0xc7; break; default: abort (); } fragP->fr_literal[offset] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 1, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 2] = 0xdc; fix_new (fragP, fragP->fr_fix + 3, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL); fragP->fr_var = 0; fragP->fr_fix += 7; } else if (fragP->fr_subtype == 3) { fix_new (fragP, fragP->fr_fix + 2, 1, fragP->fr_symbol, fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL); fragP->fr_var = 0; fragP->fr_fix += 3; } else if (fragP->fr_subtype == 4) { /* Reverse the condition of the first branch. */ int offset = fragP->fr_fix; int opcode = fragP->fr_literal[offset + 1] & 0xff; switch (opcode) { case 0xe8: opcode = 0xe9; break; case 0xe9: opcode = 0xe8; break; case 0xea: opcode = 0xeb; break; case 0xeb: opcode = 0xea; break; default: abort (); } fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 3] = 0xcc; fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 6; } else if (fragP->fr_subtype == 5) { /* Reverse the condition of the first branch. */ int offset = fragP->fr_fix; int opcode = fragP->fr_literal[offset + 1] & 0xff; switch (opcode) { case 0xe8: opcode = 0xe9; break; case 0xea: opcode = 0xeb; break; case 0xeb: opcode = 0xea; break; default: abort (); } fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 3] = 0xdc; fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL); fragP->fr_var = 0; fragP->fr_fix += 8; } else if (fragP->fr_subtype == 6) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xcd; fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 5; } else if (fragP->fr_subtype == 7) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xdd; fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3]; fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4]; fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL); fragP->fr_var = 0; fragP->fr_fix += 7; } else if (fragP->fr_subtype == 8) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xfa; fragP->fr_literal[offset + 1] = 0xff; fix_new (fragP, fragP->fr_fix + 2, 2, fragP->fr_symbol, fragP->fr_offset + 2, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 4; } else if (fragP->fr_subtype == 9) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xfc; fragP->fr_literal[offset + 1] = 0xff; fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, fragP->fr_offset + 2, 1, BFD_RELOC_32_PCREL); fragP->fr_var = 0; fragP->fr_fix += 6; } else if (fragP->fr_subtype == 10) { fragP->fr_literal[fragP->fr_fix] = 0xca; fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL); fragP->fr_var = 0; fragP->fr_fix += 2; } else if (fragP->fr_subtype == 11) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xcc; fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 3; } else if (fragP->fr_subtype == 12) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xdc; fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL); fragP->fr_var = 0; fragP->fr_fix += 5; } else abort ();}valueTmd_section_align (seg, addr) asection *seg; valueT addr;{ int align = bfd_get_section_alignment (stdoutput, seg); return ((addr + (1 << align) - 1) & (-1 << align));}voidmd_begin (){ char *prev_name = ""; register const struct mn10300_opcode *op; mn10300_hash = hash_new (); /* Insert unique names into hash table. The MN10300 instruction set has many identical opcode names that have different opcodes based on the operands. This hash table then provides a quick index to the first opcode with a particular name in the opcode table. */ op = mn10300_opcodes; while (op->name) { if (strcmp (prev_name, op->name)) { prev_name = (char *) op->name; hash_insert (mn10300_hash, op->name, (char *) op); } op++; } /* Set the default machine type. */ if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, MN103)) as_warn (_("could not set architecture and machine")); current_machine = MN103;}voidmd_assemble (str) char *str;{ char *s; struct mn10300_opcode *opcode; struct mn10300_opcode *next_opcode; const unsigned char *opindex_ptr; int next_opindex, relaxable; unsigned long insn, extension, size = 0; char *f; int i; int match; /* Get the opcode. */ for (s = str; *s != '\0' && !isspace (*s); s++) ; if (*s != '\0') *s++ = '\0'; /* Find the first opcode with the proper name. */ opcode = (struct mn10300_opcode *) hash_find (mn10300_hash, str); if (opcode == NULL) { as_bad (_("Unrecognized opcode: `%s'"), str); return; } str = s; while (isspace (*str)) ++str; input_line_pointer = str; for (;;) { const char *errmsg; int op_idx; char *hold; int extra_shift = 0; errmsg = _("Invalid opcode/operands"); /* Reset the array of register operands. */ memset (mn10300_reg_operands, -1, sizeof (mn10300_reg_operands)); relaxable = 0; fc = 0; match = 0; next_opindex = 0; insn = opcode->opcode; extension = 0; /* If the instruction is not available on the current machine then it can not possibly match. */ if (opcode->machine && !(opcode->machine == AM33 && HAVE_AM33) && !(opcode->machine == AM30 && HAVE_AM30)) goto error; for (op_idx = 1, opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++, op_idx++) { const struct mn10300_operand *operand; expressionS ex; if (next_opindex == 0) { operand = &mn10300_operands[*opindex_ptr]; } else { operand = &mn10300_operands[next_opindex]; next_opindex = 0; } while (*str == ' ' || *str == ',') ++str; if (operand->flags & MN10300_OPERAND_RELAX) relaxable = 1; /* Gather the operand. */ hold = input_line_pointer; input_line_pointer = str; if (operand->flags & MN10300_OPERAND_PAREN) { if (*input_line_pointer != ')' && *input_line_pointer != '(') { input_line_pointer = hold; str = hold; goto error; } input_line_pointer++; goto keep_going; } /* See if we can match the operands. */ else if (operand->flags & MN10300_OPERAND_DREG) { if (!data_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10300_OPERAND_AREG) { if (!address_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10300_OPERAND_SP) { char *start = input_line_pointer; char c = get_symbol_end (); if (strcasecmp (start, "sp") != 0) { *input_line_pointer = c; input_line_pointer = hold; str = hold; goto error; } *input_line_pointer = c; goto keep_going; } else if (operand->flags & MN10300_OPERAND_RREG) { if (!r_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10300_OPERAND_XRREG) { if (!xr_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10300_OPERAND_USP) { char *start = input_line_pointer; char c = get_symbol_end ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -