📄 tc-a29k.c
字号:
} else if (fixP->fx_pcrel) { long v = val >> 17; if (v != 0 && v != -1) as_bad_where (fixP->fx_file, fixP->fx_line, "call/jmp target out of range"); } else /* this case was supposed to be handled in machine_ip */ abort (); buf[1] = val >> 10; /* Holds bits 0003FFFC of address */ buf[3] = val >> 2; break; case RELOC_CONST: /* 00XX00XX pattern in a word */ buf[1] = val >> 8; /* Holds bits 0000XXXX */ buf[3] = val; break; case RELOC_CONSTH: /* 00XX00XX pattern in a word */ buf[1] = val >> 24; /* Holds bits XXXX0000 */ buf[3] = val >> 16; break; case NO_RELOC: default: as_bad (_("bad relocation type: 0x%02x"), fixP->fx_r_type); break; }}#ifdef OBJ_COFFshorttc_coff_fix2rtype (fixP) fixS *fixP;{ switch (fixP->fx_r_type) { case RELOC_32: return (R_WORD); case RELOC_8: return (R_BYTE); case RELOC_CONST: return (R_ILOHALF); case RELOC_CONSTH: return (R_IHIHALF); case RELOC_JUMPTARG: return (R_IREL); default: printf (_("need %o3\n"), fixP->fx_r_type); abort (); } /* switch on type */ return (0);}#endif /* OBJ_COFF *//* should never be called for 29k */voidmd_convert_frag (headers, seg, fragP) object_headers *headers; segT seg; register fragS *fragP;{ as_fatal (_("a29k_convert_frag\n"));}/* should never be called for a29k */intmd_estimate_size_before_relax (fragP, segtype) register fragS *fragP; segT segtype;{ as_fatal (_("a29k_estimate_size_before_relax\n")); return 0;}#if 0/* for debugging only */static voidprint_insn (insn) struct machine_it *insn;{ char *Reloc[] = { "RELOC_8", "RELOC_16", "RELOC_32", "RELOC_DISP8", "RELOC_DISP16", "RELOC_DISP32", "RELOC_WDISP30", "RELOC_WDISP22", "RELOC_HI22", "RELOC_22", "RELOC_13", "RELOC_LO10", "RELOC_SFA_BASE", "RELOC_SFA_OFF13", "RELOC_BASE10", "RELOC_BASE13", "RELOC_BASE22", "RELOC_PC10", "RELOC_PC22", "RELOC_JMP_TBL", "RELOC_SEGOFF16", "RELOC_GLOB_DAT", "RELOC_JMP_SLOT", "RELOC_RELATIVE", "NO_RELOC" }; if (insn->error) { fprintf (stderr, "ERROR: %s\n"); } fprintf (stderr, "opcode=0x%08x\n", insn->opcode); fprintf (stderr, "reloc = %s\n", Reloc[insn->reloc]); fprintf (stderr, "exp = {\n"); fprintf (stderr, "\t\tX_add_symbol = %s\n", insn->exp.X_add_symbol ? (S_GET_NAME (insn->exp.X_add_symbol) ? S_GET_NAME (insn->exp.X_add_symbol) : "???") : "0"); fprintf (stderr, "\t\tX_op_symbol = %s\n", insn->exp.X_op_symbol ? (S_GET_NAME (insn->exp.X_op_symbol) ? S_GET_NAME (insn->exp.X_op_symbol) : "???") : "0"); fprintf (stderr, "\t\tX_add_number = %d\n", insn->exp.X_add_number); fprintf (stderr, "}\n");}#endif/* Translate internal representation of relocation info to target format. On sparc/29k: first 4 bytes are normal unsigned long address, next three bytes are index, most sig. byte first. Byte 7 is broken up with bit 7 as external, bits 6 & 5 unused, and the lower five bits as relocation type. Next 4 bytes are long addend. *//* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */#ifdef OBJ_AOUTvoidtc_aout_fix_to_chars (where, fixP, segment_address_in_file) char *where; fixS *fixP; relax_addressT segment_address_in_file;{ long r_symbolnum; know (fixP->fx_r_type < NO_RELOC); know (fixP->fx_addsy != NULL); md_number_to_chars (where, fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file, 4); r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy) ? S_GET_TYPE (fixP->fx_addsy) : fixP->fx_addsy->sy_number); where[4] = (r_symbolnum >> 16) & 0x0ff; where[5] = (r_symbolnum >> 8) & 0x0ff; where[6] = r_symbolnum & 0x0ff; where[7] = (((!S_IS_DEFINED (fixP->fx_addsy)) << 7) & 0x80) | (0 & 0x60) | (fixP->fx_r_type & 0x1F); /* Also easy */ md_number_to_chars (&where[8], fixP->fx_addnumber, 4);}#endif /* OBJ_AOUT */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;{}/* This is called when a line is unrecognized. This is used to handle definitions of a29k style local labels. */inta29k_unrecognized_line (c) int c;{ int lab; char *s; if (c != '$' || ! isdigit ((unsigned char) input_line_pointer[0])) return 0; s = input_line_pointer; lab = 0; while (isdigit ((unsigned char) *s)) { lab = lab * 10 + *s - '0'; ++s; } if (*s != ':') { /* Not a label definition. */ return 0; } if (dollar_label_defined (lab)) { as_bad (_("label \"$%d\" redefined"), lab); return 0; } define_dollar_label (lab); colon (dollar_label_name (lab, 0)); input_line_pointer = s + 1; return 1;}/* Default the values of symbols known that should be "predefined". We don't bother to predefine them unless you actually use one, since there are a lot of them. */symbolS *md_undefined_symbol (name) char *name;{ long regnum; char testbuf[5 + /*SLOP*/ 5]; if (name[0] == 'g' || name[0] == 'G' || name[0] == 'l' || name[0] == 'L' || name[0] == 's' || name[0] == 'S') { /* Perhaps a global or local register name */ if (name[1] == 'r' || name[1] == 'R') { long maxreg; /* Parse the number, make sure it has no extra zeroes or trailing chars. */ regnum = atol (&name[2]); if (name[0] == 's' || name[0] == 'S') maxreg = 255; else maxreg = 127; if (regnum > maxreg) return NULL; sprintf (testbuf, "%ld", regnum); if (strcmp (testbuf, &name[2]) != 0) return NULL; /* gr007 or lr7foo or whatever */ /* We have a wiener! Define and return a new symbol for it. */ if (name[0] == 'l' || name[0] == 'L') regnum += 128; else if (name[0] == 's' || name[0] == 'S') regnum += SREG; return (symbol_new (name, SEG_REGISTER, (valueT) regnum, &zero_address_frag)); } } return NULL;}/* Parse an operand that is machine-specific. */voidmd_operand (expressionP) expressionS *expressionP;{ if (input_line_pointer[0] == '%' && input_line_pointer[1] == '%') { /* We have a numeric register expression. No biggy. */ input_line_pointer += 2; /* Skip %% */ (void) expression (expressionP); if (expressionP->X_op != O_constant || expressionP->X_add_number > 255) as_bad (_("Invalid expression after %%%%\n")); expressionP->X_op = O_register; } else if (input_line_pointer[0] == '&') { /* We are taking the 'address' of a register...this one is not in the manual, but it *is* in traps/fpsymbol.h! What they seem to want is the register number, as an absolute number. */ input_line_pointer++; /* Skip & */ (void) expression (expressionP); if (expressionP->X_op != O_register) as_bad (_("Invalid register in & expression")); else expressionP->X_op = O_constant; } else if (input_line_pointer[0] == '$' && isdigit ((unsigned char) input_line_pointer[1])) { long lab; char *name; symbolS *sym; /* This is a local label. */ ++input_line_pointer; lab = (long) get_absolute_expression (); if (dollar_label_defined (lab)) { name = dollar_label_name (lab, 0); sym = symbol_find (name); } else { name = dollar_label_name (lab, 1); sym = symbol_find_or_make (name); } expressionP->X_op = O_symbol; expressionP->X_add_symbol = sym; expressionP->X_add_number = 0; } else if (input_line_pointer[0] == '$') { char *s; char type; int fieldnum, fieldlimit; LITTLENUM_TYPE floatbuf[8]; /* $float(), $doubleN(), or $extendN() convert floating values to integers. */ s = input_line_pointer; ++s; fieldnum = 0; if (strncmp (s, "double", sizeof "double" - 1) == 0) { s += sizeof "double" - 1; type = 'd'; fieldlimit = 2; } else if (strncmp (s, "float", sizeof "float" - 1) == 0) { s += sizeof "float" - 1; type = 'f'; fieldlimit = 1; } else if (strncmp (s, "extend", sizeof "extend" - 1) == 0) { s += sizeof "extend" - 1; type = 'x'; fieldlimit = 4; } else { return; } if (isdigit (*s)) { fieldnum = *s - '0'; ++s; } if (fieldnum >= fieldlimit) return; SKIP_WHITESPACE (); if (*s != '(') return; ++s; SKIP_WHITESPACE (); s = atof_ieee (s, type, floatbuf); if (s == NULL) return; s = s; SKIP_WHITESPACE (); if (*s != ')') return; ++s; SKIP_WHITESPACE (); input_line_pointer = s; expressionP->X_op = O_constant; expressionP->X_unsigned = 1; expressionP->X_add_number = ((floatbuf[fieldnum * 2] << LITTLENUM_NUMBER_OF_BITS) + floatbuf[fieldnum * 2 + 1]); }}/* Round up a section size to the appropriate boundary. */valueTmd_section_align (segment, size) segT segment; valueT size;{ return size; /* Byte alignment is fine */}/* Exactly what point is a PC-relative offset relative TO? On the 29000, they're relative to the address of the instruction, which we have set up as the address of the fixup too. */longmd_pcrel_from (fixP) fixS *fixP;{ return fixP->fx_where + fixP->fx_frag->fr_address;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -