📄 tc-arc.c
字号:
if (opertype) { /* If the symbol already exists, point it at the new definition. */ if ((symbolP = symbol_find (name))) { if (S_GET_SEGMENT (symbolP) == reg_section) S_SET_VALUE (symbolP, (int) &ext_oper->operand); else { as_bad ("attempt to override symbol: %s", name); ignore_rest_of_line (); free (name); free (ext_oper); return; } } else { /* If its not there, add it. */ symbol_table_insert (symbol_create (name, reg_section, (int) &ext_oper->operand, &zero_address_frag)); } } ext_oper->operand.name = name; ext_oper->operand.value = number; ext_oper->operand.type = arc_operand_type (opertype); ext_oper->operand.flags = imode; ext_oper->next = arc_ext_operands; arc_ext_operands = ext_oper; /* OK, now that we know what this operand is, put a description in the arc extension section of the output file. */ old_sec = now_seg; old_subsec = now_subseg; arc_set_ext_seg (); switch (opertype) { case 0: p = frag_more (1); *p = 3 + strlen (name) + 1; p = frag_more (1); *p = EXT_COND_CODE; p = frag_more (1); *p = number; p = frag_more (strlen (name) + 1); strcpy (p, name); break; case 1: p = frag_more (1); *p = 3 + strlen (name) + 1; p = frag_more (1); *p = EXT_CORE_REGISTER; p = frag_more (1); *p = number; p = frag_more (strlen (name) + 1); strcpy (p, name); break; case 2: p = frag_more (1); *p = 6 + strlen (name) + 1; p = frag_more (1); *p = EXT_AUX_REGISTER; p = frag_more (1); *p = number >> 24 & 0xff; p = frag_more (1); *p = number >> 16 & 0xff; p = frag_more (1); *p = number >> 8 & 0xff; p = frag_more (1); *p = number & 0xff; p = frag_more (strlen (name) + 1); strcpy (p, name); break; default: as_bad ("invalid opertype"); ignore_rest_of_line (); free (name); return; break; } subseg_set (old_sec, old_subsec); /* Enter all registers into the symbol table. */ demand_empty_rest_of_line ();}static voidarc_extinst (ignore) int ignore ATTRIBUTE_UNUSED;{ unsigned char syntax[129]; char *name; char *p; char c; int suffixcode = -1; int opcode, subopcode; int i; int class = 0; int name_len; struct arc_opcode *ext_op; segT old_sec; int old_subsec; name = input_line_pointer; c = get_symbol_end (); name = xstrdup (name); if (NULL == name) { ignore_rest_of_line (); return; } strcpy (syntax, name); name_len = strlen (name); /* just after name is now '\0' */ p = input_line_pointer; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("expected comma after operand name"); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ opcode = get_absolute_expression (); SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("expected comma after opcode"); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ subopcode = get_absolute_expression (); if (subopcode < 0) { as_bad ("negative subopcode %d", subopcode); ignore_rest_of_line (); return; } if (subopcode) { if (3 != opcode) { as_bad ("subcode value found when opcode not equal 0x03"); ignore_rest_of_line (); return; } else { if (subopcode < 0x09 || subopcode == 0x3f) { as_bad ("invalid subopcode %d", subopcode); ignore_rest_of_line (); return; } } } SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("expected comma after subopcode"); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ for (i = 0; i < (int) MAXSUFFIXCLASS; i++) { if (!strncmp (suffixclass[i].name,input_line_pointer, suffixclass[i].len)) { suffixcode = i; input_line_pointer += suffixclass[i].len; break; } } if (-1 == suffixcode) { as_bad ("invalid suffix class"); ignore_rest_of_line (); return; } SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("expected comma after suffix class"); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ for (i = 0; i < (int) MAXSYNTAXCLASS; i++) { if (!strncmp (syntaxclass[i].name,input_line_pointer, syntaxclass[i].len)) { class = syntaxclass[i].class; input_line_pointer += syntaxclass[i].len; break; } } if (0 == (SYNTAX_VALID & class)) { as_bad ("invalid syntax class"); ignore_rest_of_line (); return; } if ((0x3 == opcode) & (class & SYNTAX_3OP)) { as_bad ("opcode 0x3 and SYNTAX_3OP invalid"); ignore_rest_of_line (); return; } switch (suffixcode) { case 0: strcat (syntax, "%.q%.f "); break; case 1: strcat (syntax, "%.f "); break; case 2: strcat (syntax, "%.q "); break; case 3: strcat (syntax, " "); break; default: as_bad ("unknown suffix class"); ignore_rest_of_line (); return; break; }; strcat (syntax, ((opcode == 0x3) ? "%a,%b" : ((class & SYNTAX_3OP) ? "%a,%b,%c" : "%b,%c"))); if (suffixcode < 2) strcat (syntax, "%F"); strcat (syntax, "%S%L"); ext_op = (struct arc_opcode *) xmalloc (sizeof (struct arc_opcode)); if (NULL == ext_op) { ignore_rest_of_line (); return; } ext_op->syntax = xstrdup (syntax); if (NULL == ext_op->syntax) { ignore_rest_of_line (); return; } ext_op->mask = I (-1) | ((0x3 == opcode) ? C (-1) : 0); ext_op->value = I (opcode) | ((0x3 == opcode) ? C (subopcode) : 0); ext_op->flags = class; ext_op->next_asm = arc_ext_opcodes; ext_op->next_dis = arc_ext_opcodes; arc_ext_opcodes = ext_op; /* OK, now that we know what this inst is, put a description in the arc extension section of the output file. */ old_sec = now_seg; old_subsec = now_subseg; arc_set_ext_seg (); p = frag_more (1); *p = 5 + name_len + 1; p = frag_more (1); *p = EXT_INSTRUCTION; p = frag_more (1); *p = opcode; p = frag_more (1); *p = subopcode; p = frag_more (1); *p = (class & (OP1_MUST_BE_IMM | OP1_IMM_IMPLIED) ? IGNORE_FIRST_OPD : 0); p = frag_more (name_len); strncpy (p, syntax, name_len); p = frag_more (1); *p = '\0'; subseg_set (old_sec, old_subsec); demand_empty_rest_of_line ();}intarc_set_ext_seg (){ if (!arcext_section) { arcext_section = subseg_new (".arcextmap", 0); bfd_set_section_flags (stdoutput, arcext_section, SEC_READONLY | SEC_HAS_CONTENTS); } else subseg_set (arcext_section, 0); return 1;}static voidarc_common (localScope) int localScope;{ char *name; char c; char *p; int align, size; symbolS *symbolP; name = input_line_pointer; c = get_symbol_end (); /* just after name is now '\0' */ p = input_line_pointer; *p = c; SKIP_WHITESPACE (); if (*input_line_pointer != ',') { as_bad ("expected comma after symbol name"); ignore_rest_of_line (); return; } input_line_pointer++; /* skip ',' */ size = get_absolute_expression (); if (size < 0) { as_bad ("negative symbol length"); ignore_rest_of_line (); return; } *p = 0; symbolP = symbol_find_or_make (name); *p = c; if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) { as_bad ("ignoring attempt to re-define symbol"); ignore_rest_of_line (); return; } if (((int) S_GET_VALUE (symbolP) != 0) \ && ((int) S_GET_VALUE (symbolP) != size)) { as_warn ("length of symbol \"%s\" already %ld, ignoring %d", S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size); } assert (symbolP->sy_frag == &zero_address_frag); /* Now parse the alignment field. This field is optional for local and global symbols. Default alignment is zero. */ if (*input_line_pointer == ',') { input_line_pointer++; align = get_absolute_expression (); if (align < 0) { align = 0; as_warn ("assuming symbol alignment of zero"); } } else align = 0; if (localScope != 0) { segT old_sec; int old_subsec; char *pfrag; old_sec = now_seg; old_subsec = now_subseg; record_alignment (bss_section, align); subseg_set (bss_section, 0); /* ??? subseg_set (bss_section, 1); ??? */ if (align) /* Do alignment. */ frag_align (align, 0, 0); /* Detach from old frag. */ if (S_GET_SEGMENT (symbolP) == bss_section) symbolP->sy_frag->fr_symbol = NULL; symbolP->sy_frag = frag_now; pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, (offsetT) size, (char *) 0); *pfrag = 0; S_SET_SIZE (symbolP, size); S_SET_SEGMENT (symbolP, bss_section); S_CLEAR_EXTERNAL (symbolP); symbolP->local = 1; subseg_set (old_sec, old_subsec); } else { S_SET_VALUE (symbolP, (valueT) size); S_SET_ALIGN (symbolP, align); S_SET_EXTERNAL (symbolP); S_SET_SEGMENT (symbolP, bfd_com_section_ptr); } symbolP->bsym->flags |= BSF_OBJECT; demand_empty_rest_of_line (); return;}/* Select the cpu we're assembling for. */static voidarc_option (ignore) int ignore ATTRIBUTE_UNUSED;{ int mach; char c; char *cpu; cpu = input_line_pointer; c = get_symbol_end (); mach = arc_get_mach (cpu); *input_line_pointer = c; /* If an instruction has already been seen, it's too late. */ if (cpu_tables_init_p) { as_bad ("\".option\" directive must appear before any instructions"); ignore_rest_of_line (); return; } if (mach == -1) goto bad_cpu; if (mach_type_specified_p && mach != arc_mach_type) { as_bad ("\".option\" directive conflicts with initial definition"); ignore_rest_of_line (); return; } else { /* The cpu may have been selected on the command line. */ if (mach != arc_mach_type) as_warn ("\".option\" directive overrides command-line (default) value"); arc_mach_type = mach; if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach)) as_fatal ("could not set architecture and machine"); mach_type_specified_p = 1; } demand_empty_rest_of_line (); return; bad_cpu: as_bad ("invalid identifier for \".option\""); ignore_rest_of_line ();}/* Turn a string in input_line_pointer into a floating point constant of type TYPE, and store the appropriate bytes in *LITP. The number of LITTLENUMS emitted is stored in *SIZEP. An error message is returned, or NULL on OK. *//* Equal to MAX_PRECISION in atof-ieee.c */#define MAX_LITTLENUMS 6char *md_atof (type, litP, sizeP) char type; char *litP; int *sizeP;{ int prec; LITTLENUM_TYPE words[MAX_LITTLENUMS]; LITTLENUM_TYPE *wordP; char *t; char *atof_ieee (); switch (type) { case 'f': case 'F': prec = 2; break; case 'd': case 'D': prec = 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -