📄 tc-mn10200.c
字号:
case 0xe8: opcode = 0xe9; break; case 0xe9: opcode = 0xe8; break; case 0xe0: opcode = 0xe2; break; case 0xe2: opcode = 0xe0; break; case 0xe3: opcode = 0xe1; break; case 0xe1: opcode = 0xe3; break; case 0xe4: opcode = 0xe6; break; case 0xe6: opcode = 0xe4; break; case 0xe7: opcode = 0xe5; break; case 0xe5: opcode = 0xe7; break; default: abort (); } fragP->fr_literal[offset] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%d", 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, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 2] = 0xf4; fragP->fr_literal[offset + 3] = 0xe0; fix_new (fragP, fragP->fr_fix + 4, 4, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_24_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, 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 0xfc: opcode = 0xfd; break; case 0xfd: opcode = 0xfc; break; case 0xfe: opcode = 0xff; break; case 0xff: opcode = 0xfe; case 0xe8: opcode = 0xe9; break; case 0xe9: opcode = 0xe8; break; case 0xe0: opcode = 0xe2; break; case 0xe2: opcode = 0xe0; break; case 0xe3: opcode = 0xe1; break; case 0xe1: opcode = 0xe3; break; case 0xe4: opcode = 0xe6; break; case 0xe6: opcode = 0xe4; break; case 0xe7: opcode = 0xe5; break; case 0xe5: opcode = 0xe7; break; case 0xec: opcode = 0xed; break; case 0xed: opcode = 0xec; break; case 0xee: opcode = 0xef; break; case 0xef: opcode = 0xee; break; default: abort (); } fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 3] = 0xfc; fix_new (fragP, fragP->fr_fix + 4, 2, fragP->fr_symbol, fragP->fr_offset, 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 0xfc: opcode = 0xfd; break; case 0xfd: opcode = 0xfc; break; case 0xfe: opcode = 0xff; break; case 0xff: opcode = 0xfe; case 0xe8: opcode = 0xe9; break; case 0xe9: opcode = 0xe8; break; case 0xe0: opcode = 0xe2; break; case 0xe2: opcode = 0xe0; break; case 0xe3: opcode = 0xe1; break; case 0xe1: opcode = 0xe3; break; case 0xe4: opcode = 0xe6; break; case 0xe6: opcode = 0xe4; break; case 0xe7: opcode = 0xe5; break; case 0xe5: opcode = 0xe7; break; case 0xec: opcode = 0xed; break; case 0xed: opcode = 0xec; break; case 0xee: opcode = 0xef; break; case 0xef: opcode = 0xee; break; default: abort (); } fragP->fr_literal[offset + 1] = opcode; /* Create a fixup for the reversed conditional branch. */ sprintf (buf, ".%s_%d", FAKE_LABEL_NAME, label_count++); fix_new (fragP, fragP->fr_fix + 2, 1, symbol_new (buf, sec, 0, fragP->fr_next), fragP->fr_offset, 1, BFD_RELOC_8_PCREL); /* Now create the unconditional branch + fixup to the final target. */ fragP->fr_literal[offset + 3] = 0xf4; fragP->fr_literal[offset + 4] = 0xe0; fix_new (fragP, fragP->fr_fix + 5, 4, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_24_PCREL); fragP->fr_var = 0; fragP->fr_fix += 8; } else if (fragP->fr_subtype == 6) { fix_new (fragP, fragP->fr_fix + 1, 2, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 3; } else if (fragP->fr_subtype == 7) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xf4; fragP->fr_literal[offset + 1] = 0xe1; fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_24_PCREL); fragP->fr_var = 0; fragP->fr_fix += 5; } else if (fragP->fr_subtype == 8) { fragP->fr_literal[fragP->fr_fix] = 0xea; fix_new (fragP, fragP->fr_fix + 1, 1, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_8_PCREL); fragP->fr_var = 0; fragP->fr_fix += 2; } else if (fragP->fr_subtype == 9) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xfc; fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_16_PCREL); fragP->fr_var = 0; fragP->fr_fix += 3; } else if (fragP->fr_subtype == 10) { int offset = fragP->fr_fix; fragP->fr_literal[offset] = 0xf4; fragP->fr_literal[offset + 1] = 0xe0; fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol, fragP->fr_offset, 1, BFD_RELOC_24_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 mn10200_opcode *op; mn10200_hash = hash_new (); /* Insert unique names into hash table. The MN10200 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 = mn10200_opcodes; while (op->name) { if (strcmp (prev_name, op->name)) { prev_name = (char *) op->name; hash_insert (mn10200_hash, op->name, (char *) op); } op++; } /* This is both a simplification (we don't have to write md_apply_fix) and support for future optimizations (branch shortening and similar stuff in the linker. */ linkrelax = 1;}voidmd_assemble (str) char *str;{ char *s; struct mn10200_opcode *opcode; struct mn10200_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 mn10200_opcode *) hash_find (mn10200_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 = NULL; int op_idx; char *hold; int extra_shift = 0; relaxable = 0; fc = 0; match = 0; next_opindex = 0; insn = opcode->opcode; extension = 0; for (op_idx = 1, opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++, op_idx++) { const struct mn10200_operand *operand; expressionS ex; if (next_opindex == 0) { operand = &mn10200_operands[*opindex_ptr]; } else { operand = &mn10200_operands[next_opindex]; next_opindex = 0; } errmsg = NULL; while (*str == ' ' || *str == ',') ++str; if (operand->flags & MN10200_OPERAND_RELAX) relaxable = 1; /* Gather the operand. */ hold = input_line_pointer; input_line_pointer = str; if (operand->flags & MN10200_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 & MN10200_OPERAND_DREG) { if (!data_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10200_OPERAND_AREG) { if (!address_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } } else if (operand->flags & MN10200_OPERAND_PSW) { char *start = input_line_pointer; char c = get_symbol_end (); if (strcmp (start, "psw") != 0) { *input_line_pointer = c; input_line_pointer = hold; str = hold; goto error; } *input_line_pointer = c; goto keep_going; } else if (operand->flags & MN10200_OPERAND_MDR) { char *start = input_line_pointer; char c = get_symbol_end (); if (strcmp (start, "mdr") != 0) { *input_line_pointer = c; input_line_pointer = hold; str = hold; goto error; } *input_line_pointer = c; goto keep_going; } else if (data_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } else if (address_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } else if (other_register_name (&ex)) { input_line_pointer = hold; str = hold; goto error; } else if (*str == ')' || *str == '(') { input_line_pointer = hold; str = hold; goto error; } else { expression (&ex); } switch (ex.X_op) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -