tc-i386.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,311 行 · 第 1/5 页
C
2,311 行
else memcpy (fragP->fr_literal + fragP->fr_fix, f32_patt[count - 1], count); fragP->fr_var = count; }}static char *output_invalid PARAMS ((int c));static int i386_operand PARAMS ((char *operand_string));static int i386_intel_operand PARAMS ((char *operand_string, int got_a_float));static const reg_entry *parse_register PARAMS ((char *reg_string, char **end_op));#ifndef I386COFFstatic void s_bss PARAMS ((int));#endifsymbolS *GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_". */static INLINE unsigned intmode_from_disp_size (t) unsigned int t;{ return (t & Disp8) ? 1 : (t & (Disp16 | Disp32 | Disp32S)) ? 2 : 0;}static INLINE intfits_in_signed_byte (num) offsetT num;{ return (num >= -128) && (num <= 127);}static INLINE intfits_in_unsigned_byte (num) offsetT num;{ return (num & 0xff) == num;}static INLINE intfits_in_unsigned_word (num) offsetT num;{ return (num & 0xffff) == num;}static INLINE intfits_in_signed_word (num) offsetT num;{ return (-32768 <= num) && (num <= 32767);}static INLINE intfits_in_signed_long (num) offsetT num ATTRIBUTE_UNUSED;{#ifndef BFD64 return 1;#else return (!(((offsetT) -1 << 31) & num) || (((offsetT) -1 << 31) & num) == ((offsetT) -1 << 31));#endif} /* fits_in_signed_long() */static INLINE intfits_in_unsigned_long (num) offsetT num ATTRIBUTE_UNUSED;{#ifndef BFD64 return 1;#else return (num & (((offsetT) 2 << 31) - 1)) == num;#endif} /* fits_in_unsigned_long() */static intsmallest_imm_type (num) offsetT num;{ if (cpu_arch_flags != (Cpu086 | Cpu186 | Cpu286 | Cpu386 | Cpu486 | CpuNo64) && !(cpu_arch_flags & (CpuUnknown))) { /* This code is disabled on the 486 because all the Imm1 forms in the opcode table are slower on the i486. They're the versions with the implicitly specified single-position displacement, which has another syntax if you really want to use that form. */ if (num == 1) return Imm1 | Imm8 | Imm8S | Imm16 | Imm32 | Imm32S | Imm64; } return (fits_in_signed_byte (num) ? (Imm8S | Imm8 | Imm16 | Imm32 | Imm32S | Imm64) : fits_in_unsigned_byte (num) ? (Imm8 | Imm16 | Imm32 | Imm32S | Imm64) : (fits_in_signed_word (num) || fits_in_unsigned_word (num)) ? (Imm16 | Imm32 | Imm32S | Imm64) : fits_in_signed_long (num) ? (Imm32 | Imm32S | Imm64) : fits_in_unsigned_long (num) ? (Imm32 | Imm64) : Imm64);}static offsetToffset_in_range (val, size) offsetT val; int size;{ addressT mask; switch (size) { case 1: mask = ((addressT) 1 << 8) - 1; break; case 2: mask = ((addressT) 1 << 16) - 1; break; case 4: mask = ((addressT) 2 << 31) - 1; break;#ifdef BFD64 case 8: mask = ((addressT) 2 << 63) - 1; break;#endif default: abort (); } /* If BFD64, sign extend val. */ if (!use_rela_relocations) if ((val & ~(((addressT) 2 << 31) - 1)) == 0) val = (val ^ ((addressT) 1 << 31)) - ((addressT) 1 << 31); if ((val & ~mask) != 0 && (val & ~mask) != ~mask) { char buf1[40], buf2[40]; sprint_value (buf1, val); sprint_value (buf2, val & mask); as_warn (_("%s shortened to %s"), buf1, buf2); } return val & mask;}/* Returns 0 if attempting to add a prefix where one from the same class already exists, 1 if non rep/repne added, 2 if rep/repne added. */static intadd_prefix (prefix) unsigned int prefix;{ int ret = 1; int q; if (prefix >= 0x40 && prefix < 0x50 && flag_code == CODE_64BIT) q = REX_PREFIX; else switch (prefix) { default: abort (); case CS_PREFIX_OPCODE: case DS_PREFIX_OPCODE: case ES_PREFIX_OPCODE: case FS_PREFIX_OPCODE: case GS_PREFIX_OPCODE: case SS_PREFIX_OPCODE: q = SEG_PREFIX; break; case REPNE_PREFIX_OPCODE: case REPE_PREFIX_OPCODE: ret = 2; /* fall thru */ case LOCK_PREFIX_OPCODE: q = LOCKREP_PREFIX; break; case FWAIT_OPCODE: q = WAIT_PREFIX; break; case ADDR_PREFIX_OPCODE: q = ADDR_PREFIX; break; case DATA_PREFIX_OPCODE: q = DATA_PREFIX; break; } if (i.prefix[q]) { as_bad (_("same type of prefix used twice")); return 0; } i.prefixes += 1; i.prefix[q] = prefix; return ret;}static voidset_code_flag (value) int value;{ flag_code = value; cpu_arch_flags &= ~(Cpu64 | CpuNo64); cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64); if (value == CODE_64BIT && !(cpu_arch_flags & CpuSledgehammer)) { as_bad (_("64bit mode not supported on this CPU.")); } if (value == CODE_32BIT && !(cpu_arch_flags & Cpu386)) { as_bad (_("32bit mode not supported on this CPU.")); } stackop_size = '\0';}static voidset_16bit_gcc_code_flag (new_code_flag) int new_code_flag;{ flag_code = new_code_flag; cpu_arch_flags &= ~(Cpu64 | CpuNo64); cpu_arch_flags |= (flag_code == CODE_64BIT ? Cpu64 : CpuNo64); stackop_size = 'l';}static voidset_intel_syntax (syntax_flag) int syntax_flag;{ /* Find out if register prefixing is specified. */ int ask_naked_reg = 0; SKIP_WHITESPACE (); if (! is_end_of_line[(unsigned char) *input_line_pointer]) { char *string = input_line_pointer; int e = get_symbol_end (); if (strcmp (string, "prefix") == 0) ask_naked_reg = 1; else if (strcmp (string, "noprefix") == 0) ask_naked_reg = -1; else as_bad (_("bad argument to syntax directive.")); *input_line_pointer = e; } demand_empty_rest_of_line (); intel_syntax = syntax_flag; if (ask_naked_reg == 0) {#ifdef BFD_ASSEMBLER allow_naked_reg = (intel_syntax && (bfd_get_symbol_leading_char (stdoutput) != '\0'));#else /* Conservative default. */ allow_naked_reg = 0;#endif } else allow_naked_reg = (ask_naked_reg < 0);}static voidset_cpu_arch (dummy) int dummy ATTRIBUTE_UNUSED;{ SKIP_WHITESPACE (); if (! is_end_of_line[(unsigned char) *input_line_pointer]) { char *string = input_line_pointer; int e = get_symbol_end (); int i; for (i = 0; cpu_arch[i].name; i++) { if (strcmp (string, cpu_arch[i].name) == 0) { cpu_arch_name = cpu_arch[i].name; cpu_arch_flags = (cpu_arch[i].flags | (flag_code == CODE_64BIT ? Cpu64 : CpuNo64)); break; } } if (!cpu_arch[i].name) as_bad (_("no such architecture: `%s'"), string); *input_line_pointer = e; } else as_bad (_("missing cpu architecture")); no_cond_jump_promotion = 0; if (*input_line_pointer == ',' && ! is_end_of_line[(unsigned char) input_line_pointer[1]]) { char *string = ++input_line_pointer; int e = get_symbol_end (); if (strcmp (string, "nojumps") == 0) no_cond_jump_promotion = 1; else if (strcmp (string, "jumps") == 0) ; else as_bad (_("no such architecture modifier: `%s'"), string); *input_line_pointer = e; } demand_empty_rest_of_line ();}const pseudo_typeS md_pseudo_table[] ={#if !defined(OBJ_AOUT) && !defined(USE_ALIGN_PTWO) {"align", s_align_bytes, 0},#else {"align", s_align_ptwo, 0},#endif {"arch", set_cpu_arch, 0},#ifndef I386COFF {"bss", s_bss, 0},#endif {"ffloat", float_cons, 'f'}, {"dfloat", float_cons, 'd'}, {"tfloat", float_cons, 'x'}, {"value", cons, 2}, {"noopt", s_ignore, 0}, {"optim", s_ignore, 0}, {"code16gcc", set_16bit_gcc_code_flag, CODE_16BIT}, {"code16", set_code_flag, CODE_16BIT}, {"code32", set_code_flag, CODE_32BIT}, {"code64", set_code_flag, CODE_64BIT}, {"intel_syntax", set_intel_syntax, 1}, {"att_syntax", set_intel_syntax, 0}, {"file", dwarf2_directive_file, 0}, {"loc", dwarf2_directive_loc, 0}, {0, 0, 0}};/* For interface with expression (). */extern char *input_line_pointer;/* Hash table for instruction mnemonic lookup. */static struct hash_control *op_hash;/* Hash table for register lookup. */static struct hash_control *reg_hash;#ifdef BFD_ASSEMBLERunsigned longi386_mach (){ if (!strcmp (default_arch, "x86_64")) return bfd_mach_x86_64; else if (!strcmp (default_arch, "i386")) return bfd_mach_i386_i386; else as_fatal (_("Unknown architecture"));}#endifvoidmd_begin (){ const char *hash_err; /* Initialize op_hash hash table. */ op_hash = hash_new (); { register const template *optab; register templates *core_optab; /* Setup for loop. */ optab = i386_optab; core_optab = (templates *) xmalloc (sizeof (templates)); core_optab->start = optab; while (1) { ++optab; if (optab->name == NULL || strcmp (optab->name, (optab - 1)->name) != 0) { /* different name --> ship out current template list; add to hash table; & begin anew. */ core_optab->end = optab; hash_err = hash_insert (op_hash, (optab - 1)->name, (PTR) core_optab); if (hash_err) { as_fatal (_("Internal Error: Can't hash %s: %s"), (optab - 1)->name, hash_err); } if (optab->name == NULL) break; core_optab = (templates *) xmalloc (sizeof (templates)); core_optab->start = optab; } } } /* Initialize reg_hash hash table. */ reg_hash = hash_new (); { register const reg_entry *regtab; for (regtab = i386_regtab; regtab < i386_regtab + sizeof (i386_regtab) / sizeof (i386_regtab[0]); regtab++) { hash_err = hash_insert (reg_hash, regtab->reg_name, (PTR) regtab); if (hash_err) as_fatal (_("Internal Error: Can't hash %s: %s"), regtab->reg_name, hash_err); } } /* Fill in lexical tables: mnemonic_chars, operand_chars. */ { register int c; register char *p; for (c = 0; c < 256; c++) { if (isdigit (c)) { digit_chars[c] = c; mnemonic_chars[c] = c; register_chars[c] = c; operand_chars[c] = c; } else if (islower (c)) { mnemonic_chars[c] = c; register_chars[c] = c; operand_chars[c] = c; } else if (isupper (c)) { mnemonic_chars[c] = tolower (c); register_chars[c] = mnemonic_chars[c]; operand_chars[c] = c; } if (isalpha (c) || isdigit (c)) identifier_chars[c] = c; else if (c >= 128) { identifier_chars[c] = c; operand_chars[c] = c; } }#ifdef LEX_AT identifier_chars['@'] = '@';#endif digit_chars['-'] = '-';
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?