📄 tc-arm.c
字号:
if (preserved_copy_of_name[0] == '_') preserved_copy_of_name++;#endif#ifdef tc_canonicalize_symbol_name preserved_copy_of_name = tc_canonicalize_symbol_name (preserved_copy_of_name);#endif S_SET_NAME (symbolP, preserved_copy_of_name); S_SET_SEGMENT (symbolP, segment); S_SET_VALUE (symbolP, valu); symbol_clear_list_pointers(symbolP); symbol_set_frag (symbolP, frag); /* Link to end of symbol chain. */ { extern int symbol_table_frozen; if (symbol_table_frozen) abort (); } symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP); obj_symbol_new_hook (symbolP);#ifdef tc_symbol_new_hook tc_symbol_new_hook (symbolP);#endif#ifdef DEBUG_SYMS verify_symbol_chain (symbol_rootP, symbol_lastP);#endif /* DEBUG_SYMS */}/* Check that an immediate is valid. If so, convert it to the right format. */static unsigned intvalidate_immediate (val) unsigned int val;{ unsigned int a; unsigned int i;#define rotate_left(v, n) (v << n | v >> (32 - n)) for (i = 0; i < 32; i += 2) if ((a = rotate_left (val, i)) <= 0xff) return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */ return FAIL;}/* Check to see if an immediate can be computed as two seperate immediate values, added together. We already know that this value cannot be computed by just one ARM instruction. */static unsigned intvalidate_immediate_twopart (val, highpart) unsigned int val; unsigned int * highpart;{ unsigned int a; unsigned int i; for (i = 0; i < 32; i += 2) if (((a = rotate_left (val, i)) & 0xff) != 0) { if (a & 0xff00) { if (a & ~ 0xffff) continue; * highpart = (a >> 8) | ((i + 24) << 7); } else if (a & 0xff0000) { if (a & 0xff000000) continue; * highpart = (a >> 16) | ((i + 16) << 7); } else { assert (a & 0xff000000); * highpart = (a >> 24) | ((i + 8) << 7); } return (a & 0xff) | (i << 7); } return FAIL;}static intvalidate_offset_imm (val, hwse) unsigned int val; int hwse;{ if ((hwse && val > 255) || val > 4095) return FAIL; return val;}static voids_req (a) int a ATTRIBUTE_UNUSED;{ as_bad (_("Invalid syntax for .req directive."));}static voids_bss (ignore) int ignore ATTRIBUTE_UNUSED;{ /* We don't support putting frags in the BSS segment, we fake it by marking in_bss, then looking at s_skip for clues. */ subseg_set (bss_section, 0); demand_empty_rest_of_line ();}static voids_even (ignore) int ignore ATTRIBUTE_UNUSED;{ /* Never make frag if expect extra pass. */ if (!need_pass_2) frag_align (1, 0, 0); record_alignment (now_seg, 1); demand_empty_rest_of_line ();}static voids_ltorg (ignored) int ignored ATTRIBUTE_UNUSED;{ int lit_count = 0; char sym_name[20]; if (current_poolP == NULL) return; /* Align pool as you have word accesses. Only make a frag if we have to. */ if (!need_pass_2) frag_align (2, 0, 0); record_alignment (now_seg, 2); sprintf (sym_name, "$$lit_\002%x", lit_pool_num++); symbol_locate (current_poolP, sym_name, now_seg, (valueT) frag_now_fix (), frag_now); symbol_table_insert (current_poolP); ARM_SET_THUMB (current_poolP, thumb_mode);#if defined OBJ_COFF || defined OBJ_ELF ARM_SET_INTERWORK (current_poolP, support_interwork);#endif while (lit_count < next_literal_pool_place) /* First output the expression in the instruction to the pool. */ emit_expr (&(literals[lit_count++].exp), 4); /* .word */ next_literal_pool_place = 0; current_poolP = NULL;}/* Same as s_align_ptwo but align 0 => align 2. */static voids_align (unused) int unused ATTRIBUTE_UNUSED;{ register int temp; register long temp_fill; long max_alignment = 15; temp = get_absolute_expression (); if (temp > max_alignment) as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment); else if (temp < 0) { as_bad (_("Alignment negative. 0 assumed.")); temp = 0; } if (*input_line_pointer == ',') { input_line_pointer++; temp_fill = get_absolute_expression (); } else temp_fill = 0; if (!temp) temp = 2; /* Only make a frag if we HAVE to. */ if (temp && !need_pass_2) frag_align (temp, (int) temp_fill, 0); demand_empty_rest_of_line (); record_alignment (now_seg, temp);}static voids_force_thumb (ignore) int ignore ATTRIBUTE_UNUSED;{ /* If we are not already in thumb mode go into it, EVEN if the target processor does not support thumb instructions. This is used by gcc/config/arm/lib1funcs.asm for example to compile interworking support functions even if the target processor should not support interworking. */ if (! thumb_mode) { thumb_mode = 2; record_alignment (now_seg, 1); } demand_empty_rest_of_line ();}static voids_thumb_func (ignore) int ignore ATTRIBUTE_UNUSED;{ if (! thumb_mode) opcode_select (16); /* The following label is the name/address of the start of a Thumb function. We need to know this for the interworking support. */ label_is_thumb_function_name = true; demand_empty_rest_of_line ();}/* Perform a .set directive, but also mark the alias as being a thumb function. */static voids_thumb_set (equiv) int equiv;{ /* XXX the following is a duplicate of the code for s_set() in read.c We cannot just call that code as we need to get at the symbol that is created. */ register char * name; register char delim; register char * end_name; register symbolS * symbolP; /* Especial apologies for the random logic: This just grew, and could be parsed much more simply! Dean - in haste. */ name = input_line_pointer; delim = get_symbol_end (); end_name = input_line_pointer; *end_name = delim; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { *end_name = 0; as_bad (_("Expected comma after name \"%s\""), name); *end_name = delim; ignore_rest_of_line (); return; } input_line_pointer++; *end_name = 0; if (name[0] == '.' && name[1] == '\0') { /* XXX - this should not happen to .thumb_set. */ abort (); } if ((symbolP = symbol_find (name)) == NULL && (symbolP = md_undefined_symbol (name)) == NULL) {#ifndef NO_LISTING /* When doing symbol listings, play games with dummy fragments living outside the normal fragment chain to record the file and line info for this symbol. */ if (listing & LISTING_SYMBOLS) { extern struct list_info_struct * listing_tail; fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS)); memset (dummy_frag, 0, sizeof (fragS)); dummy_frag->fr_type = rs_fill; dummy_frag->line = listing_tail; symbolP = symbol_new (name, undefined_section, 0, dummy_frag); dummy_frag->fr_symbol = symbolP; } else#endif symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);#ifdef OBJ_COFF /* "set" symbols are local unless otherwise specified. */ SF_SET_LOCAL (symbolP);#endif /* OBJ_COFF */ } /* Make a new symbol. */ symbol_table_insert (symbolP); * end_name = delim; if (equiv && S_IS_DEFINED (symbolP) && S_GET_SEGMENT (symbolP) != reg_section) as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP)); pseudo_set (symbolP); demand_empty_rest_of_line (); /* XXX Now we come to the Thumb specific bit of code. */ THUMB_SET_FUNC (symbolP, 1); ARM_SET_THUMB (symbolP, 1);#if defined OBJ_ELF || defined OBJ_COFF ARM_SET_INTERWORK (symbolP, support_interwork);#endif}/* If we change section we must dump the literal pool first. */static voidarm_s_text (ignore) int ignore;{ if (now_seg != text_section) s_ltorg (0);#ifdef OBJ_ELF obj_elf_text (ignore);#else s_text (ignore);#endif}static voidarm_s_data (ignore) int ignore;{ if (flag_readonly_data_in_text) { if (now_seg != text_section) s_ltorg (0); } else if (now_seg != data_section) s_ltorg (0);#ifdef OBJ_ELF obj_elf_data (ignore);#else s_data (ignore);#endif}#ifdef OBJ_ELFstatic voidarm_s_section (ignore) int ignore;{ s_ltorg (0); obj_elf_section (ignore);}#endifstatic voidopcode_select (width) int width;{ switch (width) { case 16: if (! thumb_mode) { if (! (cpu_variant & ARM_EXT_THUMB)) as_bad (_("selected processor does not support THUMB opcodes")); thumb_mode = 1; /* No need to force the alignment, since we will have been coming from ARM mode, which is word-aligned. */ record_alignment (now_seg, 1); } break; case 32: if (thumb_mode) { if ((cpu_variant & ARM_ANY) == ARM_EXT_THUMB) as_bad (_("selected processor does not support ARM opcodes")); thumb_mode = 0; if (!need_pass_2) frag_align (2, 0, 0); record_alignment (now_seg, 1); } break; default: as_bad (_("invalid instruction size selected (%d)"), width); }}static voids_arm (ignore) int ignore ATTRIBUTE_UNUSED;{ opcode_select (32); demand_empty_rest_of_line ();}static voids_thumb (ignore) int ignore ATTRIBUTE_UNUSED;{ opcode_select (16); demand_empty_rest_of_line ();}static voids_code (unused) int unused ATTRIBUTE_UNUSED;{ register int temp; temp = get_absolute_expression ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -