📄 tc-tic54x.c
字号:
symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); } } switch (type) { case 'l': case 'L': case 'x': octets = 4; break; case 'b': case 'B': case 'c': case 'C': octets = 1; break; default: octets = 2; break; } do { if (*input_line_pointer == '"') { input_line_pointer++; while (is_a_char (c = next_char_of_string ())) tic54x_emit_char (c); know (input_line_pointer[-1] == '\"'); } else { expressionS exp; input_line_pointer = parse_expression (input_line_pointer, &exp); if (exp.X_op == O_constant) { offsetT value = exp.X_add_number; /* Truncate overflows. */ switch (octets) { case 1: if ((value > 0 && value > 0xFF) || (value < 0 && value < - 0x100)) as_warn ("Overflow in expression, truncated to 8 bits"); break; case 2: if ((value > 0 && value > 0xFFFF) || (value < 0 && value < - 0x10000)) as_warn ("Overflow in expression, truncated to 16 bits"); break; } } if (exp.X_op != O_constant && octets < 2) { /* Disallow .byte with a non constant expression that will require relocation. */ as_bad (_("Relocatable values require at least WORD storage")); ignore_rest_of_line (); return; } if (exp.X_op != O_constant && amode == c_mode && octets == 4) { /* FIXME -- at one point TI tools used to output REL16 relocations, but I don't think the latest tools do at all The current tools output extended relocations regardless of the addresing mode (I actually think that ".c_mode" is totally ignored in the latest tools). */ amode = far_mode; emitting_long = 1; emit_expr (&exp, 4); emitting_long = 0; amode = c_mode; } else { emitting_long = octets == 4; emit_expr (&exp, (octets == 1) ? 2 : octets); emitting_long = 0; } } } while (*input_line_pointer++ == ','); input_line_pointer--; /* Put terminator back into stream. */ demand_empty_rest_of_line ();}/* .global <symbol>[,...,<symbolN>] .def <symbol>[,...,<symbolN>] .ref <symbol>[,...,<symbolN>] These all identify global symbols. .def means the symbol is defined in the current module and can be accessed by other files. The symbol should be placed in the symbol table. .ref means the symbol is used in the current module but defined in another module. The linker is to resolve this symbol's definition at link time. .global should act as a .ref or .def, as needed. global, def and ref all have symbol storage classes of C_EXT. I can't identify any difference in how the "other" c54x assembler treats these, so we ignore the type here. */voidtic54x_global (type) int type;{ char *name; int c; symbolS *symbolP; if (type == 'r') as_warn (_("Use of .def/.ref is deprecated. Use .global instead")); ILLEGAL_WITHIN_STRUCT (); do { name = input_line_pointer; c = get_symbol_end (); symbolP = symbol_find_or_make (name); *input_line_pointer = c; S_SET_STORAGE_CLASS (symbolP, C_EXT); if (c == ',') { input_line_pointer++; if (is_end_of_line[(int) *input_line_pointer]) c = *input_line_pointer; } } while (c == ','); demand_empty_rest_of_line ();}/* Remove the symbol from the local label hash lookup. */static voidtic54x_remove_local_label (key, value) const char *key; PTR value ATTRIBUTE_UNUSED;{ PTR *elem = hash_delete (local_label_hash[macro_level], key); free (elem);}/* Reset all local labels. */static voidtic54x_clear_local_labels (ignored) int ignored ATTRIBUTE_UNUSED;{ hash_traverse (local_label_hash[macro_level], tic54x_remove_local_label);}/* .text .data .sect "section name" Initialized section make sure local labels get cleared when changing sections ARG is 't' for text, 'd' for data, or '*' for a named section For compatibility, '*' sections have SEC_DATA set instead of SEC_CODE. */static voidtic54x_sect (int arg){ ILLEGAL_WITHIN_STRUCT (); /* Local labels are cleared when changing sections. */ tic54x_clear_local_labels (0); if (arg == 't') s_text (0); else if (arg == 'd') s_data (0); else { char *name = NULL; int len; /* If there are quotes, remove them. */ if (*input_line_pointer == '"') { name = demand_copy_C_string (&len); demand_empty_rest_of_line (); name = strcpy (xmalloc (len + 10), name); } else { int c; name = input_line_pointer; c = get_symbol_end (); name = strcpy (xmalloc (len + 10), name); *input_line_pointer = c; demand_empty_rest_of_line (); } /* Make sure all named initialized sections are SEC_DATA. */ strcat (name, ",\"w\"\n"); input_scrub_insert_line (name); obj_coff_section (0); /* If there was a line label, make sure that it gets assigned the proper section. This is for compatibility, even though the actual behavior is not explicitly defined. For consistency, we make .sect behave like .usect, since that is probably what people expect. */ if (line_label != NULL) { S_SET_SEGMENT (line_label, now_seg); symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); if (S_GET_STORAGE_CLASS (line_label) != C_EXT) S_SET_STORAGE_CLASS (line_label, C_LABEL); } }}/* [symbol] .space space_in_bits [symbol] .bes space_in_bits BES puts the symbol at the *last* word allocated cribbed from s_space. */static voidtic54x_space (int arg){ expressionS exp; char *p = 0; int octets = 0; long words; int bits_per_byte = (OCTETS_PER_BYTE * 8); int bit_offset = 0; symbolS *label = line_label; int bes = arg; ILLEGAL_WITHIN_STRUCT ();#ifdef md_flush_pending_output md_flush_pending_output ();#endif /* Read the bit count. */ expression (&exp); /* Some expressions are unresolvable until later in the assembly pass; postpone until relaxation/fixup. we also have to postpone if a previous partial allocation has not been completed yet. */ if (exp.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1) { struct bit_info *bi = xmalloc (sizeof (struct bit_info)); char *p; bi->seg = now_seg; bi->type = bes; bi->sym = label; p = frag_var (rs_machine_dependent, 65536 * 2, 1, (relax_substateT) 0, make_expr_symbol (&exp), (offsetT) 0, (char *) bi); if (p) *p = 0; return; } /* Reduce the required size by any bit offsets currently left over from a previous .space/.bes/.field directive. */ bit_offset = frag_now->tc_frag_data; if (bit_offset != 0 && bit_offset < 16) { int spare_bits = bits_per_byte - bit_offset; if (spare_bits >= exp.X_add_number) { /* Don't have to do anything; sufficient bits have already been allocated; just point the label to the right place. */ if (label != NULL) { symbol_set_frag (label, frag_now); S_SET_VALUE (label, frag_now_fix () - 1); label = NULL; } frag_now->tc_frag_data += exp.X_add_number; goto getout; } exp.X_add_number -= spare_bits; /* Set the label to point to the first word allocated, which in this case is the previous word, which was only partially filled. */ if (!bes && label != NULL) { symbol_set_frag (label, frag_now); S_SET_VALUE (label, frag_now_fix () - 1); label = NULL; } } /* Convert bits to bytes/words and octets, rounding up. */ words = ((exp.X_add_number + bits_per_byte - 1) / bits_per_byte); /* How many do we have left over? */ bit_offset = exp.X_add_number % bits_per_byte; octets = words * OCTETS_PER_BYTE; if (octets < 0) { as_warn (_(".space/.bes repeat count is negative, ignored")); goto getout; } else if (octets == 0) { as_warn (_(".space/.bes repeat count is zero, ignored")); goto getout; } /* If we are in the absolute section, just bump the offset. */ if (now_seg == absolute_section) { abs_section_offset += words; if (bes && label != NULL) S_SET_VALUE (label, abs_section_offset - 1); frag_now->tc_frag_data = bit_offset; goto getout; } if (!need_pass_2) p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) 0, (offsetT) octets, (char *) 0); /* Make note of how many bits of this word we've allocated so far. */ frag_now->tc_frag_data = bit_offset; /* .bes puts label at *last* word allocated. */ if (bes && label != NULL) { symbol_set_frag (label, frag_now); S_SET_VALUE (label, frag_now_fix () - 1); } if (p) *p = 0; getout: demand_empty_rest_of_line ();}/* [symbol] .usect "section-name", size-in-words [, [blocking-flag] [, alignment-flag]] Unitialized section. Non-zero blocking means that if the section would cross a page (128-word) boundary, it will be page-aligned. Non-zero alignment aligns on a longword boundary. Has no effect on the current section. */static voidtic54x_usect (x) int x ATTRIBUTE_UNUSED;{ char c; char *name; char *section_name; char *p; segT seg; int size, blocking_flag, alignment_flag; segT current_seg; subsegT current_subseg; flagword flags; ILLEGAL_WITHIN_STRUCT (); current_seg = now_seg; /* Save current seg. */ current_subseg = now_subseg; /* Save current subseg. */ if (*input_line_pointer == '"') input_line_pointer++; section_name = input_line_pointer; c = get_symbol_end (); /* Get terminator. */ input_line_pointer++; /* Skip null symbol terminator. */ name = xmalloc (input_line_pointer - section_name + 1); strcpy (name, section_name); if (*input_line_pointer == ',') ++input_line_pointer; else if (c != ',') { as_bad (_("Missing size argument")); ignore_rest_of_line (); return; } size = get_absolute_expression (); /* Read a possibly present third argument (blocking flag). */ if (*input_line_pointer == ',') { ++input_line_pointer; if (*input_line_pointer != ',') blocking_flag = get_absolute_expression (); else blocking_flag = 0; /* Read a possibly present fourth argument (alignment flag). */ if (*input_line_pointer == ',') { ++input_line_pointer; alignment_flag = get_absolute_expression (); } else alignment_flag = 0; } else blocking_flag = alignment_flag = 0; seg = subseg_new (name, 0); flags = bfd_get_section_flags (stdoutput, seg) | SEC_ALLOC; if (alignment_flag) { /* s_align eats end of line; restore it. */ s_align_bytes (4); --input_line_pointer; } if (line_label != NULL) { S_SET_SEGMENT (line_label, seg); symbol_set_frag (line_label, frag_now); S_SET_VALUE (line_label, frag_now_fix ()); /* Set scl to label, since that's what TI does. */ if (S_GET_STORAGE_CLASS (line_label) != C_EXT) S_SET_STORAGE_CLASS (line_label, C_LABEL); } seg_info (seg)->bss = 1; /* Uninitialized data. */ p = frag_var (rs_fill, 1, 1, (relax_substateT) 0, (symbolS *) line_label, size * OCTETS_PER_BYTE, (char *) 0); *p = 0; if (blocking_flag) flags |= SEC_BLOCK; if (!bfd_set_section_flags (stdoutput, seg, flags)) as_warn ("Error setting flags for \"%s\": %s", name, bfd_errmsg (bfd_get_error ())); subseg_set (current_seg, current_subseg); /* Restore current seg. */ demand_empty_rest_of_line ();}static enum cpu_versionlookup_version (ver) const char *ver;{ enum cpu_version version = VNONE; if (ver[0] == '5' && ver[1] == '4') { if (strlen (ver) == 3 && (ver[2] == '1' || ver[2] == '2' || ver[2] == '3' || ver[2] == '5' || ver[2] == '8' || ver[2] == '9')) version = ver[2] - '0'; else if (strlen (ver) == 5 && toupper (ver[3]) == 'L' && toupper (ver[4]) == 'P' && (ver[2] == '5' || ver[2] == '6')) version = ver[2] - '0' + 10; } return version;}static voidset_cpu (version) enum cpu_version version;{ cpu = version; if (version == V545LP || version == V546LP) { symbolS *symbolP = symbol_new ("__allow_lp", absolute_section, (valueT) 1, &zero_address_frag); SF_SET_LOCAL (symbolP); symbol_table_insert (symbolP); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -