fragS *frag;
fragS *frag ATTRIBUTE_UNUSED;
static symbolS *get_symbol PARAMS ((void));static void mips_align PARAMS ((int to, int fill, symbolS *label));static void s_align PARAMS ((int));static void s_change_sec PARAMS ((int));static void s_cons PARAMS ((int));static void s_float_cons PARAMS ((int));static void s_mips_globl PARAMS ((int));static void s_option PARAMS ((int));static void s_mipsset PARAMS ((int));static void s_abicalls PARAMS ((int));static void s_cpload PARAMS ((int));static void s_cprestore PARAMS ((int));static void s_gpword PARAMS ((int));static void s_cpadd PARAMS ((int));static void s_insn PARAMS ((int));static void md_obj_begin PARAMS ((void));static void md_obj_end PARAMS ((void));static long get_number PARAMS ((void));static void s_mips_ent PARAMS ((int));static void s_mips_end PARAMS ((int));static void s_mips_frame PARAMS ((int));static void s_mips_mask PARAMS ((int));static void s_mips_stab PARAMS ((int));static void s_mips_weakext PARAMS ((int));static void s_file PARAMS ((int));static int mips16_extended_frag PARAMS ((fragS *, asection *, long));static int validate_mips_insn PARAMS ((const struct mips_opcode *));/* Pseudo-op table.   The following pseudo-ops from the Kane and Heinrich MIPS book   should be defined here, but are currently unsupported: .alias,   .galive, .gjaldef, .gjrlive, .livereg, .noalias.   The following pseudo-ops from the Kane and Heinrich MIPS book are   specific to the type of debugging information being generated, and   should be defined by the object format: .aent, .begin, .bend,   .bgnb, .end, .endb, .ent, .fmask, .frame, .loc, .mask, .verstamp,   .vreg.   The following pseudo-ops from the Kane and Heinrich MIPS book are   not MIPS CPU specific, but are also not specific to the object file   format.  This file is probably the best place to define them, but   they are not currently supported: .asm0, .endr, .lab, .repeat,   .struct.  */static const pseudo_typeS mips_pseudo_table[] ={ /* MIPS specific pseudo-ops.  */  {"option", s_option, 0},  {"set", s_mipsset, 0},  {"rdata", s_change_sec, 'r'},  {"sdata", s_change_sec, 's'},  {"livereg", s_ignore, 0},  {"abicalls", s_abicalls, 0},  {"cpload", s_cpload, 0},  {"cprestore", s_cprestore, 0},  {"gpword", s_gpword, 0},  {"cpadd", s_cpadd, 0},  {"insn", s_insn, 0}, /* Relatively generic pseudo-ops that happen to be used on MIPS     chips.  */  {"asciiz", stringer, 1},  {"bss", s_change_sec, 'b'},  {"err", s_err, 0},  {"half", s_cons, 1},  {"dword", s_cons, 3},  {"weakext", s_mips_weakext, 0}, /* These pseudo-ops are defined in read.c, but must be overridden     here for one reason or another.  */  {"align", s_align, 0},  {"byte", s_cons, 0},  {"data", s_change_sec, 'd'},  {"double", s_float_cons, 'd'},  {"float", s_float_cons, 'f'},  {"globl", s_mips_globl, 0},  {"global", s_mips_globl, 0},  {"hword", s_cons, 1},  {"int", s_cons, 2},  {"long", s_cons, 2},  {"octa", s_cons, 4},  {"quad", s_cons, 3},  {"short", s_cons, 1},  {"single", s_float_cons, 'f'},  {"stabn", s_mips_stab, 'n'},  {"text", s_change_sec, 't'},  {"word", s_cons, 2},  { 0 },};static const pseudo_typeS mips_nonecoff_pseudo_table[] = { /* These pseudo-ops should be defined by the object file format.    However, a.out doesn't support them, so we have versions here.  */  {"aent", s_mips_ent, 1},  {"bgnb", s_ignore, 0},  {"end", s_mips_end, 0},  {"endb", s_ignore, 0},  {"ent", s_mips_ent, 0},  {"file", s_file, 0},  {"fmask", s_mips_mask, 'F'},  {"frame", s_mips_frame, 0},  {"loc", s_ignore, 0},  {"mask", s_mips_mask, 'R'},  {"verstamp", s_ignore, 0},  { 0 },};extern void pop_insert PARAMS ((const pseudo_typeS *));voidmips_pop_insert (){  pop_insert (mips_pseudo_table);  if (! ECOFF_DEBUGGING)    pop_insert (mips_nonecoff_pseudo_table);}/* Symbols labelling the current insn.  */struct insn_label_list{  struct insn_label_list *next;  symbolS *label;};static struct insn_label_list *insn_labels;static struct insn_label_list *free_insn_labels;static void mips_clear_insn_labels PARAMS ((void));static inline voidmips_clear_insn_labels (){  register struct insn_label_list **pl;  for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next)    ;  *pl = insn_labels;  insn_labels = NULL;}static char *expr_end;/* Expressions which appear in instructions.  These are set by   mips_ip.  */static expressionS imm_expr;static expressionS offset_expr;/* Relocs associated with imm_expr and offset_expr.  */static bfd_reloc_code_real_type imm_reloc;static bfd_reloc_code_real_type offset_reloc;/* This is set by mips_ip if imm_reloc is an unmatched HI16_S reloc.  */static boolean imm_unmatched_hi;/* These are set by mips16_ip if an explicit extension is used.  */static boolean mips16_small, mips16_ext;#ifdef MIPS_STABS_ELF/* The pdr segment for per procedure frame/regmask info */static segT pdr_seg;#endif/* * This function is called once, at assembler startup time.  It should * set up all the tables, etc. that the MD part of the assembler will need. */voidmd_begin (){  boolean ok = false;  register const char *retval = NULL;  register unsigned int i = 0;  const char *cpu;  char *a = NULL;  int broken = 0;  int mips_isa_from_cpu;  /* GP relative stuff not working for PE */  if (strncmp (TARGET_OS, "pe", 2) == 0      && g_switch_value != 0)    {      if (g_switch_seen)	as_bad (_("-G not supported in this configuration."));      g_switch_value = 0;    }  cpu = TARGET_CPU;  if (strcmp (cpu + (sizeof TARGET_CPU) - 3, "el") == 0)    {      a = xmalloc (sizeof TARGET_CPU);      strcpy (a, TARGET_CPU);      a[(sizeof TARGET_CPU) - 3] = '\0';      cpu = a;    }  if (mips_cpu < 0)    {      /* Set mips_cpu based on TARGET_CPU, unless TARGET_CPU is         just the generic 'mips', in which case set mips_cpu based         on the given ISA, if any. */      if (strcmp (cpu, "mips") == 0)        {	  if (mips_opts.isa < 0)	    mips_cpu = 3000;   	  else if (mips_opts.isa == 2)            mips_cpu = 6000;          else if (mips_opts.isa == 3)            mips_cpu = 4000;          else if (mips_opts.isa == 4)            mips_cpu = 8000;          else             mips_cpu = 3000;        }            else if (strcmp (cpu, "r3900") == 0               || strcmp (cpu, "mipstx39") == 0               )        mips_cpu = 3900;      else if (strcmp (cpu, "r6000") == 0	       || strcmp (cpu, "mips2") == 0)        mips_cpu = 6000;      else if (strcmp (cpu, "mips64") == 0	       || strcmp (cpu, "r4000") == 0	       || strcmp (cpu, "mips3") == 0)        mips_cpu = 4000;      else if (strcmp (cpu, "r4400") == 0)        mips_cpu = 4400;      else if (strcmp (cpu, "mips64orion") == 0	       || strcmp (cpu, "r4600") == 0)        mips_cpu = 4600;      else if (strcmp (cpu, "r4650") == 0)        mips_cpu = 4650;      else if (strcmp (cpu, "mips64vr4300") == 0)        mips_cpu = 4300;      else if (strcmp (cpu, "mips64vr4111") == 0)        mips_cpu = 4111;      else if (strcmp (cpu, "mips64vr4100") == 0)        mips_cpu = 4100;      else if (strcmp (cpu, "r4010") == 0)        mips_cpu = 4010;      else if (strcmp (cpu, "r5000") == 0	       || strcmp (cpu, "mips64vr5000") == 0)        mips_cpu = 5000;      else if (strcmp (cpu, "r8000") == 0	       || strcmp (cpu, "mips4") == 0)        mips_cpu = 8000;            else if (strcmp (cpu, "r10000") == 0)        mips_cpu = 10000;      else if (strcmp (cpu, "mips16") == 0)        mips_cpu = 0; /* FIXME */      else        mips_cpu = 3000;    }  if (mips_cpu == 3000      || mips_cpu == 3900)    mips_isa_from_cpu = 1;  else if (mips_cpu == 6000	   || mips_cpu == 4010)    mips_isa_from_cpu = 2;  else if (mips_cpu == 4000	   || mips_cpu == 4100	   || mips_cpu == 4111	   || mips_cpu == 4400	   || mips_cpu == 4300	   || mips_cpu == 4600	   || mips_cpu == 4650)    mips_isa_from_cpu = 3;  else if (mips_cpu == 5000	   || mips_cpu == 8000               || mips_cpu == 10000)    mips_isa_from_cpu = 4;  else    mips_isa_from_cpu = -1;  if (mips_opts.isa == -1)    {      if (mips_isa_from_cpu != -1)	mips_opts.isa = mips_isa_from_cpu;      else	mips_opts.isa = 1;    }  if (mips_opts.mips16 < 0)    {      if (strncmp (TARGET_CPU, "mips16", sizeof "mips16" - 1) == 0)	mips_opts.mips16 = 1;      else	mips_opts.mips16 = 0;    }  /* End of TARGET_CPU processing, get rid of malloced memory     if necessary. */  cpu = NULL;  if (a != NULL)    {    free (a);    a = NULL;    }  if (mips_opts.isa == 1 && mips_trap)    as_bad (_("trap exception not supported at ISA 1"));  /* Set the EABI kind based on the ISA before the user gets     to change the ISA with directives.  This isn't really     the best, but then neither is basing the abi on the isa. */       if (ISA_HAS_64BIT_REGS (mips_opts.isa)      && mips_abi_string      && 0 == strcmp (mips_abi_string,"eabi"))    mips_eabi64 = 1;  if (mips_cpu != 0 && mips_cpu != -1)    {      ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, mips_cpu);            /* If they asked for mips1 or mips2 and a cpu that is	 mips3 or greater, then mark the object file 32BITMODE. */      if (mips_isa_from_cpu != -1	  && ! ISA_HAS_64BIT_REGS (mips_opts.isa) 	  && ISA_HAS_64BIT_REGS (mips_isa_from_cpu))	mips_32bitmode = 1;    }  else    {      switch (mips_opts.isa)	{	case 1:	  ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 3000);	  break;	case 2:	  ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 6000);	  break;	case 3:	  ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 4000);	  break;	case 4:	  ok = bfd_set_arch_mach (stdoutput, bfd_arch_mips, 8000);	  break;	}    }  if (! ok)    as_warn (_("Could not set architecture and machine"));  file_mips_isa = mips_opts.isa;  op_hash = hash_new ();  for (i = 0; i < NUMOPCODES;)    {      const char *name = mips_opcodes[i].name;      retval = hash_insert (op_hash, name, (PTR) &mips_opcodes[i]);      if (retval != NULL)	{	  fprintf (stderr, _("internal error: can't hash `%s': %s\n"),		   mips_opcodes[i].name, retval);	  /* Probably a memory allocation problem?  Give up now.  */	  as_fatal (_("Broken assembler.  No assembly attempted."));	}      do	{	  if (mips_opcodes[i].pinfo != INSN_MACRO)	    {	      if (!validate_mips_insn (&mips_opcodes[i]))		broken = 1;	    }	  ++i;	}      while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));    }  mips16_op_hash = hash_new ();  i = 0;  while (i < bfd_mips16_num_opcodes)    {      const char *name = mips16_opcodes[i].name;      retval = hash_insert (mips16_op_hash, name, (PTR) &mips16_opcodes[i]);      if (retval != NULL)	as_fatal (_("internal: can't hash `%s': %s"),		  mips16_opcodes[i].name, retval);      do	{	  if (mips16_opcodes[i].pinfo != INSN_MACRO	      && ((mips16_opcodes[i].match & mips16_opcodes[i].mask)		  != mips16_opcodes[i].match))	    {	      fprintf (stderr, _("internal error: bad mips16 opcode: %s %s\n"),		       mips16_opcodes[i].name, mips16_opcodes[i].args);	      broken = 1;	    }	  ++i;	}      while (i < bfd_mips16_num_opcodes	     && strcmp (mips16_opcodes[i].name, name) == 0);    }  if (broken)    as_fatal (_("Broken assembler.  No assembly attempted."));  /* We add all the general register names to the symbol table.  This     helps us detect invalid uses of them.  */  for (i = 0; i < 32; i++)    {      char buf[5];      sprintf (buf, "$%d", i);      symbol_table_insert (symbol_new (buf, reg_section, i,				       &zero_address_frag));    }  symbol_table_insert (symbol_new ("$fp", reg_section, FP,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$sp", reg_section, SP,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$gp", reg_section, GP,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$at", reg_section, AT,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$kt0", reg_section, KT0,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$kt1", reg_section, KT1,				   &zero_address_frag));  symbol_table_insert (symbol_new ("$pc", reg_section, -1,				   &zero_address_frag));  mips_no_prev_insn (false);  mips_gprmask = 0;  mips_cprmask[0] = 0;  mips_cprmask[1] = 0;  mips_cprmask[2] = 0;  mips_cprmask[3] = 0;  /* set the default alignment for the text section (2**2) */  record_alignment (text_section, 2);  if (USE_GLOBAL_POINTER_OPT)    bfd_set_gp_size (stdoutput, g_switch_value);  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)    {      /* On a native system, sections must be aligned to 16 byte	 boundaries.  When configured for an embedded ELF target, we	 don't bother.  */      if (strcmp (TARGET_OS, "elf") != 0)	{	  (void) bfd_set_section_alignment (stdoutput, text_section, 4);	  (void) bfd_set_section_alignment (stdoutput, data_section, 4);	  (void) bfd_set_section_alignment (stdoutput, bss_section, 4);	}      /* Create a .reginfo section for register masks and a .mdebug	 section for debugging information.  */      {	segT seg;	subsegT subseg;	flagword flags;	segT sec;	seg = now_seg;	subseg = now_subseg;	/* The ABI says this section should be loaded so that the	   running program can access it.  However, we don't load it	   if we are configured for an embedded target */	flags = SEC_READONLY | SEC_DATA;	if (strcmp (TARGET_OS, "elf") != 0)	  flags |= SEC_ALLOC | SEC_LOAD;	if (! mips_64)	  {	    sec = subseg_new (".reginfo", (subsegT) 0);	    (void) bfd_set_section_flags (stdoutput, sec, flags);	    (void) bfd_set_section_alignment (stdoutput, sec, 2);	#ifdef OBJ_ELF	    mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));#endif	  }	else	  {	    /* The 64-bit ABI uses a .MIPS.options section rather than               .reginfo section.  */	    sec = subseg_new (".MIPS.options", (subsegT) 0);	    (void) bfd_set_section_flags (stdoutput, sec, flags);	    (void) bfd_set_section_alignment (stdoutput, sec, 3);#ifdef OBJ_ELF	    /* Set up the option header.  */	    {	      Elf_Internal_Options opthdr;	      char *f;	      opthdr.kind = ODK_REGINFO;	      opthdr.size = (sizeof (Elf_External_Options)			     + sizeof (Elf64_External_RegInfo));	      opthdr.section = 0;	      opthdr.info = 0;	      f = frag_more (sizeof (Elf_External_Options));	      bfd_mips_elf_swap_options_out (stdoutput, &opthdr,					     (Elf_External_Options *) f);	      mips_regmask_frag = frag_more (sizeof (Elf64_External_RegInfo));	    }#endif	  }	if (ECOFF_DEBUGGING)	  {	    sec = subseg_new (".mdebug", (subsegT) 0);	    (void) bfd_set_section_flags (stdoutput, sec,					  SEC_HAS_CONTENTS | SEC_READONLY);	    (void) bfd_set_section_alignment (stdoutput, sec, 2);	  }#ifdef MIPS_STABS_ELF	pdr_seg = subseg_new (".pdr", (subsegT) 0);	(void) bfd_set_section_flags (stdoutput, pdr_seg,			     SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);	(void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);#endif	subseg_set (seg, subseg);      }    }  if (! ECOFF_DEBUGGING)    md_obj_begin ();}voidmd_mips_end (){  if (! ECOFF_DEBUGGING)    md_obj_end ();}voidmd_assemble (str)     char *str;{  struct mips_cl_insn insn;  imm_expr.X_op = O_absent;  imm_reloc = BFD_RELOC_UNUSED;  imm_unmatched_hi = false;  offset_expr.X_op = O_absent;  offset_reloc = BFD_RELOC_UNUSED;  if (mips_opts.mips16)    mips16_ip (str, &insn);  else    {      mips_ip (str, &insn);      DBG((_("returned from mips_ip(%s) insn_opcode = 0x%x\n"), 		str, insn.insn_opcode));    }  if (insn_error)    {      as_bad ("%s `%s'", insn_error, str);      return;    }  if (insn.insn_mo->pinfo == INSN_MACRO)    {      if (mips_opts.mips16)	mips16_macro (&insn);      else	macro (&insn);    }  else    {      if (imm_expr.X_op != O_absent)	append_insn ((char *) NULL, &insn, &imm_expr, imm_reloc,		     imm_unmatched_hi);      else if (offset_expr.X_op != O_absent)	append_insn ((char *) NULL, &insn, &offset_expr, offset_reloc, false);      else	append_insn ((char *) NULL, &insn, NULL, BFD_RELOC_UNUSED, false);    }}/* See whether instruction IP reads register REG.  CLASS is the type   of register.  */static intinsn_uses_reg (ip, reg, class)     struct mips_cl_insn *ip;     unsigned int reg;     enum mips_regclass class;{  if (class == MIPS16_REG)    {      assert (mips_opts.mips16);      reg = mips16_to_32_reg_map[reg];      class = MIPS_GR_REG;    }  /* Don't report on general register 0, since it never changes.  */  if (class == MIPS_GR_REG && reg == 0)    return 0;  if (class == MIPS_FP_REG)    {      assert (! mips_opts.mips16);      /* If we are called with either $f0 or $f1, we must check $f0.	 This is not optimal, because it will introduce an unnecessary	 NOP between "lwc1 $f0" and "swc1 $f1".  To fix this we would	 need to distinguish reading both $f0 and $f1 or just one of	 them.  Note that we don't have to check the other way,	 because there is no instruction that sets both $f0 and $f1	 and requires a delay.  */      if ((ip->insn_mo->pinfo & INSN_READ_FPR_S)	  && ((((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS) &~(unsigned)1)	      == (reg &~ (unsigned) 1)))	return 1;      if ((ip->insn_mo->pinfo & INSN_READ_FPR_T)	  && ((((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT) &~(unsigned)1)	      == (reg &~ (unsigned) 1)))	return 1;    }  else if (! mips_opts.mips16)    {      if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)	  && ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS) == reg)	return 1;      if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)	  && ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT) == reg)	return 1;    }  else    {      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_X)	  && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RX)				    & MIPS16OP_MASK_RX)]	      == reg))	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Y)	  && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_RY)				    & MIPS16OP_MASK_RY)]	      == reg))	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Z)	  && (mips16_to_32_reg_map[((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)				    & MIPS16OP_MASK_MOVE32Z)]	      == reg))	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_T) && reg == TREG)	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_SP) && reg == SP)	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_31) && reg == RA)	return 1;      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_GPR_X)	  && ((ip->insn_opcode >> MIPS16OP_SH_REGR32)	      & MIPS16OP_MASK_REGR32) == reg)	return 1;    }  return 0;}/* This function returns true if modifying a register requires a   delay.  */static intreg_needs_delay (reg)     int reg;{  unsigned long prev_pinfo;  prev_pinfo = prev_insn.insn_mo->pinfo;  if (! mips_opts.noreorder      && ISA_HAS_COPROC_DELAYS (mips_opts.isa)      && ((prev_pinfo & INSN_LOAD_COPROC_DELAY)	  || (! gpr_interlocks	      && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))    {      /* A load from a coprocessor or from memory.  All load	 delays delay the use of general register rt for one	 instruction on the r3000.  The r6000 and r4000 use	 interlocks.  */      /* Itbl support may require additional care here. */      know (prev_pinfo & INSN_WRITE_GPR_T);      if (reg == ((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT))	return 1;    }  return 0;}/* Mark instruction labels in mips16 mode.  This permits the linker to   handle them specially, such as generating jalx instructions when   needed.  We also make them odd for the duration of the assembly, in   order to generate the right sort of code.  We will make them even   in the adjust_symtab routine, while leaving them marked.  This is   convenient for the debugger and the disassembler.  The linker knows   to make them odd again.  */static voidmips16_mark_labels (){  if (mips_opts.mips16)    {      struct insn_label_list *l;      for (l = insn_labels; l != NULL; l = l->next)	{#ifdef OBJ_ELF	  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)	    S_SET_OTHER (l->label, STO_MIPS16);#endif	  if ((S_GET_VALUE (l->label) & 1) == 0)	    S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);	}    }}/* Output an instruction.  PLACE is where to put the instruction; if   it is NULL, this uses frag_more to get room.  IP is the instruction   information.  ADDRESS_EXPR is an operand of the instruction to be   used with RELOC_TYPE.  */static voidappend_insn (place, ip, address_expr, reloc_type, unmatched_hi)     char *place;     struct mips_cl_insn *ip;     expressionS *address_expr;     bfd_reloc_code_real_type reloc_type;     boolean unmatched_hi;{  register unsigned long prev_pinfo, pinfo;  char *f;  fixS *fixp;  int nops = 0;  /* Mark instruction labels in mips16 mode.  */  if (mips_opts.mips16)    mips16_mark_labels ();  prev_pinfo = prev_insn.insn_mo->pinfo;  pinfo = ip->insn_mo->pinfo;  if (place == NULL && (! mips_opts.noreorder || prev_nop_frag != NULL))    {      int prev_prev_nop;      /* If the previous insn required any delay slots, see if we need	 to insert a NOP or two.  There are eight kinds of possible	 hazards, of which an instruction can have at most one type.	 (1) a load from memory delay	 (2) a load from a coprocessor delay	 (3) an unconditional branch delay	 (4) a conditional branch delay	 (5) a move to coprocessor register delay	 (6) a load coprocessor register from memory delay	 (7) a coprocessor condition code delay	 (8) a HI/LO special register delay	 There are a lot of optimizations we could do that we don't.	 In particular, we do not, in general, reorder instructions.	 If you use gcc with optimization, it will reorder	 instructions and generally do much more optimization then we	 do here; repeating all that work in the assembler would only	 benefit hand written assembly code, and does not seem worth	 it.  */      /* This is how a NOP is emitted.  */#define emit_nop()					\  (mips_opts.mips16					\   ? md_number_to_chars (frag_more (2), 0x6500, 2)	\   : md_number_to_chars (frag_more (4), 0, 4))      /* The previous insn might require a delay slot, depending upon	 the contents of the current insn.  */      if (! mips_opts.mips16	  && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	  && (((prev_pinfo & INSN_LOAD_COPROC_DELAY)               && ! cop_interlocks)	      || (! gpr_interlocks		  && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))))	{	  /* A load from a coprocessor or from memory.  All load	     delays delay the use of general register rt for one	     instruction on the r3000.  The r6000 and r4000 use	     interlocks.  */          /* Itbl support may require additional care here. */	  know (prev_pinfo & INSN_WRITE_GPR_T);	  if (mips_optimize == 0	      || insn_uses_reg (ip,				((prev_insn.insn_opcode >> OP_SH_RT)				 & OP_MASK_RT),				MIPS_GR_REG))	    ++nops;	}      else if (! mips_opts.mips16	       && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	       && (((prev_pinfo & INSN_COPROC_MOVE_DELAY)                    && ! cop_interlocks)		   || (mips_opts.isa == 1		       && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))))	{	  /* A generic coprocessor delay.  The previous instruction	     modified a coprocessor general or control register.  If	     it modified a control register, we need to avoid any	     coprocessor instruction (this is probably not always	     required, but it sometimes is).  If it modified a general	     register, we avoid using that register.	     On the r6000 and r4000 loading a coprocessor register	     from memory is interlocked, and does not require a delay.	     This case is not handled very well.  There is no special	     knowledge of CP0 handling, and the coprocessors other	     than the floating point unit are not distinguished at	     all.  */          /* Itbl support may require additional care here. FIXME!             Need to modify this to include knowledge about              user specified delays!  */	  if (prev_pinfo & INSN_WRITE_FPR_T)	    {	      if (mips_optimize == 0		  || insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_FT)				     & OP_MASK_FT),				    MIPS_FP_REG))		++nops;	    }	  else if (prev_pinfo & INSN_WRITE_FPR_S)	    {	      if (mips_optimize == 0		  || insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_FS)				     & OP_MASK_FS),				    MIPS_FP_REG))		++nops;	    }	  else	    {	      /* We don't know exactly what the previous instruction		 does.  If the current instruction uses a coprocessor		 register, we must insert a NOP.  If previous		 instruction may set the condition codes, and the		 current instruction uses them, we must insert two		 NOPS.  */              /* Itbl support may require additional care here. */	      if (mips_optimize == 0		  || ((prev_pinfo & INSN_WRITE_COND_CODE)		      && (pinfo & INSN_READ_COND_CODE)))		nops += 2;	      else if (pinfo & INSN_COP)		++nops;	    }	}      else if (! mips_opts.mips16	       && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	       && (prev_pinfo & INSN_WRITE_COND_CODE)               && ! cop_interlocks)	{	  /* The previous instruction sets the coprocessor condition	     codes, but does not require a general coprocessor delay	     (this means it is a floating point comparison	     instruction).  If this instruction uses the condition	     codes, we need to insert a single NOP.  */          /* Itbl support may require additional care here. */	  if (mips_optimize == 0	      || (pinfo & INSN_READ_COND_CODE))	    ++nops;	}      /* If we're fixing up mfhi/mflo for the r7000 and the	 previous insn was an mfhi/mflo and the current insn	 reads the register that the mfhi/mflo wrote to, then	 insert two nops.  */      else if (mips_7000_hilo_fix	       && MF_HILO_INSN (prev_pinfo)	       && insn_uses_reg (ip, ((prev_insn.insn_opcode >> OP_SH_RD)                                       & OP_MASK_RD),                                    MIPS_GR_REG))	{	  nops += 2;	}      /* If we're fixing up mfhi/mflo for the r7000 and the	 2nd previous insn was an mfhi/mflo and the current insn	 reads the register that the mfhi/mflo wrote to, then	 insert one nop.  */      else if (mips_7000_hilo_fix	       && MF_HILO_INSN (prev_prev_insn.insn_opcode)	       && insn_uses_reg (ip, ((prev_prev_insn.insn_opcode >> OP_SH_RD)                                       & OP_MASK_RD),                                    MIPS_GR_REG))     	{	  nops += 1;	}       else if (prev_pinfo & INSN_READ_LO)	{	  /* The previous instruction reads the LO register; if the	     current instruction writes to the LO register, we must	     insert two NOPS.  Some newer processors have interlocks. 	     Also the tx39's multiply instructions can be exectuted              immediatly after a read from HI/LO (without the delay),             though the tx39's divide insns still do require the 	     delay. */	  if (! (hilo_interlocks		 || (mips_cpu == 3900 && (pinfo & INSN_MULT)))	      && (mips_optimize == 0		  || (pinfo & INSN_WRITE_LO)))	    nops += 2;	  /* Most mips16 branch insns don't have a delay slot.	     If a read from LO is immediately followed by a branch	     to a write to LO we have a read followed by a write	     less than 2 insns away.  We assume the target of	     a branch might be a write to LO, and insert a nop	     between a read and an immediately following branch. */	  else if (mips_opts.mips16		   && (mips_optimize == 0		       || (pinfo & MIPS16_INSN_BRANCH)))	    nops += 1;	}      else if (prev_insn.insn_mo->pinfo & INSN_READ_HI)	{	  /* The previous instruction reads the HI register; if the	     current instruction writes to the HI register, we must	     insert a NOP.  Some newer processors have interlocks.	     Also the note tx39's multiply above. */	  if (! (hilo_interlocks		 || (mips_cpu == 3900 && (pinfo & INSN_MULT)))	      && (mips_optimize == 0		  || (pinfo & INSN_WRITE_HI)))	    nops += 2;	  /* Most mips16 branch insns don't have a delay slot.	     If a read from HI is immediately followed by a branch	     to a write to HI we have a read followed by a write	     less than 2 insns away.  We assume the target of	     a branch might be a write to HI, and insert a nop	     between a read and an immediately following branch. */	  else if (mips_opts.mips16		   && (mips_optimize == 0		       || (pinfo & MIPS16_INSN_BRANCH)))	    nops += 1;	}      /* If the previous instruction was in a noreorder section, then         we don't want to insert the nop after all.  */      /* Itbl support may require additional care here. */      if (prev_insn_unreordered)	nops = 0;      /* There are two cases which require two intervening	 instructions: 1) setting the condition codes using a move to	 coprocessor instruction which requires a general coprocessor	 delay and then reading the condition codes 2) reading the HI	 or LO register and then writing to it (except on processors	 which have interlocks).  If we are not already emitting a NOP	 instruction, we must check for these cases compared to the	 instruction previous to the previous instruction.  */      if ((! mips_opts.mips16	   && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	   && (prev_prev_insn.insn_mo->pinfo & INSN_COPROC_MOVE_DELAY)	   && (prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE)	   && (pinfo & INSN_READ_COND_CODE)	   && ! cop_interlocks)	  || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)	      && (pinfo & INSN_WRITE_LO)	      && ! (hilo_interlocks		    || (mips_cpu == 3900 && (pinfo & INSN_MULT))))	  || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)	      && (pinfo & INSN_WRITE_HI)	      && ! (hilo_interlocks		    || (mips_cpu == 3900 && (pinfo & INSN_MULT)))))	prev_prev_nop = 1;      else	prev_prev_nop = 0;      if (prev_prev_insn_unreordered)	prev_prev_nop = 0;      if (prev_prev_nop && nops == 0)	++nops;      /* If we are being given a nop instruction, don't bother with	 one of the nops we would otherwise output.  This will only	 happen when a nop instruction is used with mips_optimize set	 to 0.  */      if (nops > 0	  && ! mips_opts.noreorder	  && ip->insn_opcode == (mips_opts.mips16 ? 0x6500 : 0))	--nops;      /* Now emit the right number of NOP instructions.  */      if (nops > 0 && ! mips_opts.noreorder)	{	  fragS *old_frag;	  unsigned long old_frag_offset;	  int i;	  struct insn_label_list *l;	  old_frag = frag_now;	  old_frag_offset = frag_now_fix ();	  for (i = 0; i < nops; i++)	    emit_nop ();	  if (listing)	    {	      listing_prev_line ();	      /* We may be at the start of a variant frag.  In case we                 are, make sure there is enough space for the frag                 after the frags created by listing_prev_line.  The                 argument to frag_grow here must be at least as large                 as the argument to all other calls to frag_grow in                 this file.  We don't have to worry about being in the                 middle of a variant frag, because the variants insert                 all needed nop instructions themselves.  */	      frag_grow (40);	    }	  for (l = insn_labels; l != NULL; l = l->next)	    {	      assert (S_GET_SEGMENT (l->label) == now_seg);	      symbol_set_frag (l->label, frag_now);	      S_SET_VALUE (l->label, (valueT) frag_now_fix ());	      /* mips16 text labels are stored as odd.  */	      if (mips_opts.mips16)		S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);	    }#ifndef NO_ECOFF_DEBUGGING	  if (ECOFF_DEBUGGING)	    ecoff_fix_loc (old_frag, old_frag_offset);#endif	}      else if (prev_nop_frag != NULL)	{	  /* We have a frag holding nops we may be able to remove.  If             we don't need any nops, we can decrease the size of             prev_nop_frag by the size of one instruction.  If we do             need some nops, we count them in prev_nops_required. */	  if (prev_nop_frag_since == 0)	    {	      if (nops == 0)		{		  prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;		  --prev_nop_frag_holds;		}	      else		prev_nop_frag_required += nops;	    }	  else	    {	      if (prev_prev_nop == 0)		{		  prev_nop_frag->fr_fix -= mips_opts.mips16 ? 2 : 4;		  --prev_nop_frag_holds;		}	      else		++prev_nop_frag_required;	    }	  if (prev_nop_frag_holds <= prev_nop_frag_required)	    prev_nop_frag = NULL;	  ++prev_nop_frag_since;	  /* Sanity check: by the time we reach the second instruction             after prev_nop_frag, we should have used up all the nops             one way or another.  */	  assert (prev_nop_frag_since <= 1 || prev_nop_frag == NULL);	}    }  if (reloc_type > BFD_RELOC_UNUSED)    {      /* We need to set up a variant frag.  */      assert (mips_opts.mips16 && address_expr != NULL);      f = frag_var (rs_machine_dependent, 4, 0,		    RELAX_MIPS16_ENCODE (reloc_type - BFD_RELOC_UNUSED,					 mips16_small, mips16_ext,					 (prev_pinfo					  & INSN_UNCOND_BRANCH_DELAY),					 (prev_insn_reloc_type					  == BFD_RELOC_MIPS16_JMP)),		    make_expr_symbol (address_expr), (offsetT) 0,		    (char *) NULL);    }  else if (place != NULL)    f = place;  else if (mips_opts.mips16	   && ! ip->use_extend	   && reloc_type != BFD_RELOC_MIPS16_JMP)    {      /* Make sure there is enough room to swap this instruction with         a following jump instruction.  */      frag_grow (6);      f = frag_more (2);    }  else    {      if (mips_opts.mips16	  && mips_opts.noreorder	  && (prev_pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)	as_warn (_("extended instruction in delay slot"));      f = frag_more (4);    }  fixp = NULL;  if (address_expr != NULL && reloc_type < BFD_RELOC_UNUSED)    {      if (address_expr->X_op == O_constant)	{	  switch (reloc_type)	    {	    case BFD_RELOC_32:	      ip->insn_opcode |= address_expr->X_add_number;	      break;	    case BFD_RELOC_LO16:	      ip->insn_opcode |= address_expr->X_add_number & 0xffff;	      break;	    case BFD_RELOC_MIPS_JMP:	      if ((address_expr->X_add_number & 3) != 0)		as_bad (_("jump to misaligned address (0x%lx)"),			(unsigned long) address_expr->X_add_number);	      ip->insn_opcode |= (address_expr->X_add_number >> 2) & 0x3ffffff;	      break;	    case BFD_RELOC_MIPS16_JMP:	      if ((address_expr->X_add_number & 3) != 0)		as_bad (_("jump to misaligned address (0x%lx)"),			(unsigned long) address_expr->X_add_number);	      ip->insn_opcode |=		(((address_expr->X_add_number & 0x7c0000) << 3)		 | ((address_expr->X_add_number & 0xf800000) >> 7)		 | ((address_expr->X_add_number & 0x3fffc) >> 2));	      break;	    case BFD_RELOC_16_PCREL_S2:	      goto need_reloc;	    default:	      internalError ();	    }	}      else	{	need_reloc:	  /* Don't generate a reloc if we are writing into a variant	     frag.  */	  if (place == NULL)	    {	      fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4,				  address_expr,				  reloc_type == BFD_RELOC_16_PCREL_S2,				  reloc_type);	      if (unmatched_hi)		{		  struct mips_hi_fixup *hi_fixup;		  assert (reloc_type == BFD_RELOC_HI16_S);		  hi_fixup = ((struct mips_hi_fixup *)			      xmalloc (sizeof (struct mips_hi_fixup)));		  hi_fixup->fixp = fixp;		  hi_fixup->seg = now_seg;		  hi_fixup->next = mips_hi_fixup_list;		  mips_hi_fixup_list = hi_fixup;		}	    }	}    }  if (! mips_opts.mips16)    md_number_to_chars (f, ip->insn_opcode, 4);  else if (reloc_type == BFD_RELOC_MIPS16_JMP)    {      md_number_to_chars (f, ip->insn_opcode >> 16, 2);      md_number_to_chars (f + 2, ip->insn_opcode & 0xffff, 2);    }  else    {      if (ip->use_extend)	{	  md_number_to_chars (f, 0xf000 | ip->extend, 2);	  f += 2;	}      md_number_to_chars (f, ip->insn_opcode, 2);    }  /* Update the register mask information.  */  if (! mips_opts.mips16)    {      if (pinfo & INSN_WRITE_GPR_D)	mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD);      if ((pinfo & (INSN_WRITE_GPR_T | INSN_READ_GPR_T)) != 0)	mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RT) & OP_MASK_RT);      if (pinfo & INSN_READ_GPR_S)	mips_gprmask |= 1 << ((ip->insn_opcode >> OP_SH_RS) & OP_MASK_RS);      if (pinfo & INSN_WRITE_GPR_31)	mips_gprmask |= 1 << 31;      if (pinfo & INSN_WRITE_FPR_D)	mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FD) & OP_MASK_FD);      if ((pinfo & (INSN_WRITE_FPR_S | INSN_READ_FPR_S)) != 0)	mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FS) & OP_MASK_FS);      if ((pinfo & (INSN_WRITE_FPR_T | INSN_READ_FPR_T)) != 0)	mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FT) & OP_MASK_FT);      if ((pinfo & INSN_READ_FPR_R) != 0)	mips_cprmask[1] |= 1 << ((ip->insn_opcode >> OP_SH_FR) & OP_MASK_FR);      if (pinfo & INSN_COP)	{	  /* We don't keep enough information to sort these cases out. 	     The itbl support does keep this information however, although 	     we currently don't support itbl fprmats as part of the cop 	     instruction.  May want to add this support in the future. */	}      /* Never set the bit for $0, which is always zero.  */      mips_gprmask &=~ 1 << 0;    }  else    {      if (pinfo & (MIPS16_INSN_WRITE_X | MIPS16_INSN_READ_X))	mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RX)			      & MIPS16OP_MASK_RX);      if (pinfo & (MIPS16_INSN_WRITE_Y | MIPS16_INSN_READ_Y))	mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RY)			      & MIPS16OP_MASK_RY);      if (pinfo & MIPS16_INSN_WRITE_Z)	mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_RZ)			      & MIPS16OP_MASK_RZ);      if (pinfo & (MIPS16_INSN_WRITE_T | MIPS16_INSN_READ_T))	mips_gprmask |= 1 << TREG;      if (pinfo & (MIPS16_INSN_WRITE_SP | MIPS16_INSN_READ_SP))	mips_gprmask |= 1 << SP;      if (pinfo & (MIPS16_INSN_WRITE_31 | MIPS16_INSN_READ_31))	mips_gprmask |= 1 << RA;      if (pinfo & MIPS16_INSN_WRITE_GPR_Y)	mips_gprmask |= 1 << MIPS16OP_EXTRACT_REG32R (ip->insn_opcode);      if (pinfo & MIPS16_INSN_READ_Z)	mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_MOVE32Z)			      & MIPS16OP_MASK_MOVE32Z);      if (pinfo & MIPS16_INSN_READ_GPR_X)	mips_gprmask |= 1 << ((ip->insn_opcode >> MIPS16OP_SH_REGR32)			      & MIPS16OP_MASK_REGR32);    }  if (place == NULL && ! mips_opts.noreorder)    {      /* Filling the branch delay slot is more complex.  We try to	 switch the branch with the previous instruction, which we can	 do if the previous instruction does not set up a condition	 that the branch tests and if the branch is not itself the	 target of any branch.  */      if ((pinfo & INSN_UNCOND_BRANCH_DELAY)	  || (pinfo & INSN_COND_BRANCH_DELAY))	{	  if (mips_optimize < 2	      /* If we have seen .set volatile or .set nomove, don't		 optimize.  */	      || mips_opts.nomove != 0	      /* If we had to emit any NOP instructions, then we		 already know we can not swap.  */	      || nops != 0	      /* If we don't even know the previous insn, we can not		 swap. */	      || ! prev_insn_valid	      /* If the previous insn is already in a branch delay		 slot, then we can not swap.  */	      || prev_insn_is_delay_slot	      /* If the previous previous insn was in a .set		 noreorder, we can't swap.  Actually, the MIPS		 assembler will swap in this situation.  However, gcc		 configured -with-gnu-as will generate code like		   .set noreorder		   lw	$4,XXX		   .set	reorder		   INSN		   bne	$4,$0,foo		 in which we can not swap the bne and INSN.  If gcc is		 not configured -with-gnu-as, it does not output the		 .set pseudo-ops.  We don't have to check		 prev_insn_unreordered, because prev_insn_valid will		 be 0 in that case.  We don't want to use		 prev_prev_insn_valid, because we do want to be able		 to swap at the start of a function.  */	      || prev_prev_insn_unreordered	      /* If the branch is itself the target of a branch, we		 can not swap.  We cheat on this; all we check for is		 whether there is a label on this instruction.  If		 there are any branches to anything other than a		 label, users must use .set noreorder.  */	      || insn_labels != NULL	      /* If the previous instruction is in a variant frag, we		 can not do the swap.  This does not apply to the		 mips16, which uses variant frags for different		 purposes.  */	      || (! mips_opts.mips16		  && prev_insn_frag->fr_type == rs_machine_dependent)	      /* If the branch reads the condition codes, we don't		 even try to swap, because in the sequence		   ctc1 $X,$31		   INSN		   INSN		   bc1t LABEL		 we can not swap, and I don't feel like handling that		 case.  */	      || (! mips_opts.mips16		  && ISA_HAS_COPROC_DELAYS (mips_opts.isa)		  && (pinfo & INSN_READ_COND_CODE))	      /* We can not swap with an instruction that requires a		 delay slot, becase the target of the branch might		 interfere with that instruction.  */	      || (! mips_opts.mips16		  && ISA_HAS_COPROC_DELAYS (mips_opts.isa)		  && (prev_pinfo              /* Itbl support may require additional care here. */		      & (INSN_LOAD_COPROC_DELAY			 | INSN_COPROC_MOVE_DELAY			 | INSN_WRITE_COND_CODE)))	      || (! (hilo_interlocks		     || (mips_cpu == 3900 && (pinfo & INSN_MULT)))		  && (prev_pinfo		      & (INSN_READ_LO			 | INSN_READ_HI)))	      || (! mips_opts.mips16		  && ! gpr_interlocks		  && (prev_pinfo & INSN_LOAD_MEMORY_DELAY))	      || (! mips_opts.mips16		  && mips_opts.isa == 1                  /* Itbl support may require additional care here. */		  && (prev_pinfo & INSN_COPROC_MEMORY_DELAY))	      /* We can not swap with a branch instruction.  */	      || (prev_pinfo		  & (INSN_UNCOND_BRANCH_DELAY		     | INSN_COND_BRANCH_DELAY		     | INSN_COND_BRANCH_LIKELY))	      /* We do not swap with a trap instruction, since it		 complicates trap handlers to have the trap		 instruction be in a delay slot.  */	      || (prev_pinfo & INSN_TRAP)	      /* If the branch reads a register that the previous		 instruction sets, we can not swap.  */	      || (! mips_opts.mips16		  && (prev_pinfo & INSN_WRITE_GPR_T)		  && insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_RT)				     & OP_MASK_RT),				    MIPS_GR_REG))	      || (! mips_opts.mips16		  && (prev_pinfo & INSN_WRITE_GPR_D)		  && insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_RD)				     & OP_MASK_RD),				    MIPS_GR_REG))	      || (mips_opts.mips16		  && (((prev_pinfo & MIPS16_INSN_WRITE_X)		       && insn_uses_reg (ip,					 ((prev_insn.insn_opcode					   >> MIPS16OP_SH_RX)					  & MIPS16OP_MASK_RX),					 MIPS16_REG))		      || ((prev_pinfo & MIPS16_INSN_WRITE_Y)			  && insn_uses_reg (ip,					    ((prev_insn.insn_opcode					      >> MIPS16OP_SH_RY)					     & MIPS16OP_MASK_RY),					    MIPS16_REG))		      || ((prev_pinfo & MIPS16_INSN_WRITE_Z)			  && insn_uses_reg (ip,					    ((prev_insn.insn_opcode					      >> MIPS16OP_SH_RZ)					     & MIPS16OP_MASK_RZ),					    MIPS16_REG))		      || ((prev_pinfo & MIPS16_INSN_WRITE_T)			  && insn_uses_reg (ip, TREG, MIPS_GR_REG))		      || ((prev_pinfo & MIPS16_INSN_WRITE_31)			  && insn_uses_reg (ip, RA, MIPS_GR_REG))		      || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)			  && insn_uses_reg (ip,					    MIPS16OP_EXTRACT_REG32R (prev_insn.								     insn_opcode),					    MIPS_GR_REG))))	      /* If the branch writes a register that the previous		 instruction sets, we can not swap (we know that		 branches write only to RD or to $31).  */	      || (! mips_opts.mips16		  && (prev_pinfo & INSN_WRITE_GPR_T)		  && (((pinfo & INSN_WRITE_GPR_D)		       && (((prev_insn.insn_opcode >> OP_SH_RT) & OP_MASK_RT)			   == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))		      || ((pinfo & INSN_WRITE_GPR_31)			  && (((prev_insn.insn_opcode >> OP_SH_RT)			       & OP_MASK_RT)			      == 31))))	      || (! mips_opts.mips16		  && (prev_pinfo & INSN_WRITE_GPR_D)		  && (((pinfo & INSN_WRITE_GPR_D)		       && (((prev_insn.insn_opcode >> OP_SH_RD) & OP_MASK_RD)			   == ((ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD)))		      || ((pinfo & INSN_WRITE_GPR_31)			  && (((prev_insn.insn_opcode >> OP_SH_RD)			       & OP_MASK_RD)			      == 31))))	      || (mips_opts.mips16		  && (pinfo & MIPS16_INSN_WRITE_31)		  && ((prev_pinfo & MIPS16_INSN_WRITE_31)		      || ((prev_pinfo & MIPS16_INSN_WRITE_GPR_Y)			  && (MIPS16OP_EXTRACT_REG32R (prev_insn.insn_opcode)			      == RA))))	      /* If the branch writes a register that the previous		 instruction reads, we can not swap (we know that		 branches only write to RD or to $31).  */	      || (! mips_opts.mips16		  && (pinfo & INSN_WRITE_GPR_D)		  && insn_uses_reg (&prev_insn,				    ((ip->insn_opcode >> OP_SH_RD)				     & OP_MASK_RD),				    MIPS_GR_REG))	      || (! mips_opts.mips16		  && (pinfo & INSN_WRITE_GPR_31)		  && insn_uses_reg (&prev_insn, 31, MIPS_GR_REG))	      || (mips_opts.mips16		  && (pinfo & MIPS16_INSN_WRITE_31)		  && insn_uses_reg (&prev_insn, RA, MIPS_GR_REG))	      /* If we are generating embedded PIC code, the branch		 might be expanded into a sequence which uses $at, so		 we can't swap with an instruction which reads it.  */	      || (mips_pic == EMBEDDED_PIC		  && insn_uses_reg (&prev_insn, AT, MIPS_GR_REG))	      /* If the previous previous instruction has a load		 delay, and sets a register that the branch reads, we		 can not swap.  */	      || (! mips_opts.mips16		  && ISA_HAS_COPROC_DELAYS (mips_opts.isa)              /* Itbl support may require additional care here. */		  && ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)		      || (! gpr_interlocks			  && (prev_prev_insn.insn_mo->pinfo			      & INSN_LOAD_MEMORY_DELAY)))		  && insn_uses_reg (ip,				    ((prev_prev_insn.insn_opcode >> OP_SH_RT)				     & OP_MASK_RT),				    MIPS_GR_REG))	      /* If one instruction sets a condition code and the                 other one uses a condition code, we can not swap.  */	      || ((pinfo & INSN_READ_COND_CODE)		  && (prev_pinfo & INSN_WRITE_COND_CODE))	      || ((pinfo & INSN_WRITE_COND_CODE)		  && (prev_pinfo & INSN_READ_COND_CODE))	      /* If the previous instruction uses the PC, we can not                 swap.  */	      || (mips_opts.mips16		  && (prev_pinfo & MIPS16_INSN_READ_PC))	      /* If the previous instruction was extended, we can not                 swap.  */	      || (mips_opts.mips16 && prev_insn_extended)	      /* If the previous instruction had a fixup in mips16                 mode, we can not swap.  This normally means that the                 previous instruction was a 4 byte branch anyhow.  */	      || (mips_opts.mips16 && prev_insn_fixp)	      /* If the previous instruction is a sync, sync.l, or 		 sync.p, we can not swap. */	      || (prev_pinfo & INSN_SYNC))	    {	      /* We could do even better for unconditional branches to		 portions of this object file; we could pick up the		 instruction at the destination, put it in the delay		 slot, and bump the destination address.  */	      emit_nop ();	      /* Update the previous insn information.  */	      prev_prev_insn = *ip;	      prev_insn.insn_mo = &dummy_opcode;	    }	  else	    {	      /* It looks like we can actually do the swap.  */	      if (! mips_opts.mips16)		{		  char *prev_f;		  char temp[4];		  prev_f = prev_insn_frag->fr_literal + prev_insn_where;		  memcpy (temp, prev_f, 4);		  memcpy (prev_f, f, 4);		  memcpy (f, temp, 4);		  if (prev_insn_fixp)		    {		      prev_insn_fixp->fx_frag = frag_now;		      prev_insn_fixp->fx_where = f - frag_now->fr_literal;		    }		  if (fixp)		    {		      fixp->fx_frag = prev_insn_frag;		      fixp->fx_where = prev_insn_where;		    }		}	      else		{		  char *prev_f;		  char temp[2];		  assert (prev_insn_fixp == NULL);		  prev_f = prev_insn_frag->fr_literal + prev_insn_where;		  memcpy (temp, prev_f, 2);		  memcpy (prev_f, f, 2);		  if (reloc_type != BFD_RELOC_MIPS16_JMP)		    {		      assert (reloc_type == BFD_RELOC_UNUSED);		      memcpy (f, temp, 2);		    }		  else		    {		      memcpy (f, f + 2, 2);		      memcpy (f + 2, temp, 2);		    }		  if (fixp)		    {		      fixp->fx_frag = prev_insn_frag;		      fixp->fx_where = prev_insn_where;		    }		}	      /* Update the previous insn information; leave prev_insn		 unchanged.  */	      prev_prev_insn = *ip;	    }	  prev_insn_is_delay_slot = 1;	  /* If that was an unconditional branch, forget the previous	     insn information.  */	  if (pinfo & INSN_UNCOND_BRANCH_DELAY)	    {	      prev_prev_insn.insn_mo = &dummy_opcode;	      prev_insn.insn_mo = &dummy_opcode;	    }	  prev_insn_fixp = NULL;	  prev_insn_reloc_type = BFD_RELOC_UNUSED;	  prev_insn_extended = 0;	}      else if (pinfo & INSN_COND_BRANCH_LIKELY)	{	  /* We don't yet optimize a branch likely.  What we should do	     is look at the target, copy the instruction found there	     into the delay slot, and increment the branch to jump to	     the next instruction.  */	  emit_nop ();	  /* Update the previous insn information.  */	  prev_prev_insn = *ip;	  prev_insn.insn_mo = &dummy_opcode;	  prev_insn_fixp = NULL;	  prev_insn_reloc_type = BFD_RELOC_UNUSED;	  prev_insn_extended = 0;	}      else	{	  /* Update the previous insn information.  */	  if (nops > 0)	    prev_prev_insn.insn_mo = &dummy_opcode;	  else	    prev_prev_insn = prev_insn;	  prev_insn = *ip;	  /* Any time we see a branch, we always fill the delay slot	     immediately; since this insn is not a branch, we know it	     is not in a delay slot.  */	  prev_insn_is_delay_slot = 0;	  prev_insn_fixp = fixp;	  prev_insn_reloc_type = reloc_type;	  if (mips_opts.mips16)	    prev_insn_extended = (ip->use_extend				  || reloc_type > BFD_RELOC_UNUSED);	}      prev_prev_insn_unreordered = prev_insn_unreordered;      prev_insn_unreordered = 0;      prev_insn_frag = frag_now;      prev_insn_where = f - frag_now->fr_literal;      prev_insn_valid = 1;    }  else if (place == NULL)    {      /* We need to record a bit of information even when we are not         reordering, in order to determine the base address for mips16         PC relative relocs.  */      prev_prev_insn = prev_insn;      prev_insn = *ip;      prev_insn_reloc_type = reloc_type;      prev_prev_insn_unreordered = prev_insn_unreordered;      prev_insn_unreordered = 1;    }  /* We just output an insn, so the next one doesn't have a label.  */  mips_clear_insn_labels ();  /* We must ensure that a fixup associated with an unmatched %hi     reloc does not become a variant frag.  Otherwise, the     rearrangement of %hi relocs in frob_file may confuse     tc_gen_reloc.  */  if (unmatched_hi)    {      frag_wane (frag_now);      frag_new (0);    }}/* This function forgets that there was any previous instruction or   label.  If PRESERVE is non-zero, it remembers enough information to   know whether nops are needed before a noreorder section. */static voidmips_no_prev_insn (preserve)     int preserve;{  if (! preserve)    {      prev_insn.insn_mo = &dummy_opcode;      prev_prev_insn.insn_mo = &dummy_opcode;      prev_nop_frag = NULL;      prev_nop_frag_holds = 0;      prev_nop_frag_required = 0;      prev_nop_frag_since = 0;    }  prev_insn_valid = 0;  prev_insn_is_delay_slot = 0;  prev_insn_unreordered = 0;  prev_insn_extended = 0;  prev_insn_reloc_type = BFD_RELOC_UNUSED;  prev_prev_insn_unreordered = 0;  mips_clear_insn_labels ();}/* This function must be called whenever we turn on noreorder or emit   something other than instructions.  It inserts any NOPS which might   be needed by the previous instruction, and clears the information   kept for the previous instructions.  The INSNS parameter is true if   instructions are to follow. */static voidmips_emit_delays (insns)     boolean insns;{  if (! mips_opts.noreorder)    {      int nops;      nops = 0;      if ((! mips_opts.mips16	   && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	   && (! cop_interlocks               && (prev_insn.insn_mo->pinfo                   & (INSN_LOAD_COPROC_DELAY                      | INSN_COPROC_MOVE_DELAY                      | INSN_WRITE_COND_CODE))))	  || (! hilo_interlocks	      && (prev_insn.insn_mo->pinfo		  & (INSN_READ_LO		     | INSN_READ_HI)))	  || (! mips_opts.mips16	      && ! gpr_interlocks	      && (prev_insn.insn_mo->pinfo                   & INSN_LOAD_MEMORY_DELAY))	  || (! mips_opts.mips16	      && mips_opts.isa == 1	      && (prev_insn.insn_mo->pinfo		  & INSN_COPROC_MEMORY_DELAY)))	{          /* Itbl support may require additional care here. */	  ++nops;	  if ((! mips_opts.mips16	       && ISA_HAS_COPROC_DELAYS (mips_opts.isa)	       && (! cop_interlocks                   && prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))	      || (! hilo_interlocks		  && ((prev_insn.insn_mo->pinfo & INSN_READ_HI)		      || (prev_insn.insn_mo->pinfo & INSN_READ_LO))))	    ++nops;	  if (prev_insn_unreordered)	    nops = 0;	}      else if ((! mips_opts.mips16		&& ISA_HAS_COPROC_DELAYS (mips_opts.isa)		&& (! cop_interlocks                    && prev_prev_insn.insn_mo->pinfo & INSN_WRITE_COND_CODE))	       || (! hilo_interlocks		   && ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)		       || (prev_prev_insn.insn_mo->pinfo & INSN_READ_LO))))	{          /* Itbl support may require additional care here. */	  if (! prev_prev_insn_unreordered)	    ++nops;	}      if (nops > 0)	{	  struct insn_label_list *l;	  if (insns)	    {	      /* Record the frag which holds the nop instructions, so                 that we can remove them if we don't need them.  */	      frag_grow (mips_opts.mips16 ? nops * 2 : nops * 4);	      prev_nop_frag = frag_now;	      prev_nop_frag_holds = nops;	      prev_nop_frag_required = 0;	      prev_nop_frag_since = 0;	    }	  for (; nops > 0; --nops)	    emit_nop ();	  if (insns)	    {	      /* Move on to a new frag, so that it is safe to simply                 decrease the size of prev_nop_frag. */	      frag_wane (frag_now);	      frag_new (0);	    }	  for (l = insn_labels; l != NULL; l = l->next)	    {	      assert (S_GET_SEGMENT (l->label) == now_seg);	      symbol_set_frag (l->label, frag_now);	      S_SET_VALUE (l->label, (valueT) frag_now_fix ());	      /* mips16 text labels are stored as odd.  */	      if (mips_opts.mips16)		S_SET_VALUE (l->label, S_GET_VALUE (l->label) + 1);	    }	}    }  /* Mark instruction labels in mips16 mode.  */  if (mips_opts.mips16 && insns)    mips16_mark_labels ();  mips_no_prev_insn (insns);}/* Build an instruction created by a macro expansion.  This is passed   a pointer to the count of instructions created so far, an   expression, the name of the instruction to build, an operand format   string, and corresponding arguments.  */#ifdef USE_STDARGstatic voidmacro_build (char *place,	     int *counter,	     expressionS * ep,	     const char *name,	     const char *fmt,	     ...)#elsestatic voidmacro_build (place, counter, ep, name, fmt, va_alist)     char *place;     int *counter;     expressionS *ep;     const char *name;     const char *fmt;     va_dcl#endif{  struct mips_cl_insn insn;  bfd_reloc_code_real_type r;  va_list args;#ifdef USE_STDARG  va_start (args, fmt);#else  va_start (args);#endif  /*   * If the macro is about to expand into a second instruction,   * print a warning if needed. We need to pass ip as a parameter   * to generate a better warning message here...   */  if (mips_opts.warn_about_macros && place == NULL && *counter == 1)    as_warn (_("Macro instruction expanded into multiple instructions"));  if (place == NULL)    *counter += 1;		/* bump instruction counter */  if (mips_opts.mips16)    {      mips16_macro_build (place, counter, ep, name, fmt, args);      va_end (args);      return;    }  r = BFD_RELOC_UNUSED;  insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);  assert (insn.insn_mo);  assert (strcmp (name, insn.insn_mo->name) == 0);  /* Search until we get a match for NAME.  */  while (1)    {      if (strcmp (fmt, insn.insn_mo->args) == 0	  && insn.insn_mo->pinfo != INSN_MACRO	  && OPCODE_IS_MEMBER (insn.insn_mo, mips_opts.isa, mips_cpu, 			       mips_gp32)	  && (mips_cpu != 4650 || (insn.insn_mo->pinfo & FP_D) == 0))	break;      ++insn.insn_mo;      assert (insn.insn_mo->name);      assert (strcmp (name, insn.insn_mo->name) == 0);    }  insn.insn_opcode = insn.insn_mo->match;  for (;;)    {      switch (*fmt++)	{	case '\0':	  break;	case ',':	case '(':	case ')':	  continue;	case 't':	case 'w':	case 'E':	  insn.insn_opcode |= va_arg (args, int) << 16;	  continue;	case 'c':	case 'T':	case 'W':	  insn.insn_opcode |= va_arg (args, int) << 16;	  continue;	case 'd':	case 'G':	  insn.insn_opcode |= va_arg (args, int) << 11;	  continue;	case 'V':	case 'S':	  insn.insn_opcode |= va_arg (args, int) << 11;	  continue;	case 'z':	  continue;	case '<':	  insn.insn_opcode |= va_arg (args, int) << 6;	  continue;	case 'D':	  insn.insn_opcode |= va_arg (args, int) << 6;	  continue;	case 'B':	  insn.insn_opcode |= va_arg (args, int) << 6;	  continue;	case 'q':	  insn.insn_opcode |= va_arg (args, int) << 6;	  continue;	case 'b':	case 's':	case 'r':	case 'v':	  insn.insn_opcode |= va_arg (args, int) << 21;	  continue;	case 'i':	case 'j':	case 'o':	  r = (bfd_reloc_code_real_type) va_arg (args, int);	  assert (r == BFD_RELOC_MIPS_GPREL		  || r == BFD_RELOC_MIPS_LITERAL		  || r == BFD_RELOC_LO16		  || r == BFD_RELOC_MIPS_GOT16		  || r == BFD_RELOC_MIPS_CALL16		  || r == BFD_RELOC_MIPS_GOT_LO16		  || r == BFD_RELOC_MIPS_CALL_LO16		  || (ep->X_op == O_subtract		      && r == BFD_RELOC_PCREL_LO16));	  continue;	case 'u':	  r = (bfd_reloc_code_real_type) va_arg (args, int);	  assert (ep != NULL		  && (ep->X_op == O_constant		      || (ep->X_op == O_symbol			  && (r == BFD_RELOC_HI16_S			      || r == BFD_RELOC_HI16			      || r == BFD_RELOC_MIPS_GOT_HI16			      || r == BFD_RELOC_MIPS_CALL_HI16))		      || (ep->X_op == O_subtract			  && r == BFD_RELOC_PCREL_HI16_S)));	  if (ep->X_op == O_constant)	    {	      insn.insn_opcode |= (ep->X_add_number >> 16) & 0xffff;	      ep = NULL;	      r = BFD_RELOC_UNUSED;	    }	  continue;	case 'p':	  assert (ep != NULL);	  /*	   * This allows macro() to pass an immediate expression for	   * creating short branches without creating a symbol.	   * Note that the expression still might come from the assembly	   * input, in which case the value is not checked for range nor	   * is a relocation entry generated (yuck).	   */	  if (ep->X_op == O_constant)	    {	      insn.insn_opcode |= (ep->X_add_number >> 2) & 0xffff;	      ep = NULL;	    }	  else	    r = BFD_RELOC_16_PCREL_S2;	  continue;	case 'a':	  assert (ep != NULL);	  r = BFD_RELOC_MIPS_JMP;	  continue;	case 'C':	  insn.insn_opcode |= va_arg (args, unsigned long);	  continue;	default:	  internalError ();	}      break;    }  va_end (args);  assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);  append_insn (place, &insn, ep, r, false);}static voidmips16_macro_build (place, counter, ep, name, fmt, args)     char *place;     int *counter;     expressionS *ep;     const char *name;     const char *fmt;     va_list args;{  struct mips_cl_insn insn;  bfd_reloc_code_real_type r;  r = BFD_RELOC_UNUSED;  insn.insn_mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);  assert (insn.insn_mo);  assert (strcmp (name, insn.insn_mo->name) == 0);  while (strcmp (fmt, insn.insn_mo->args) != 0	 || insn.insn_mo->pinfo == INSN_MACRO)    {      ++insn.insn_mo;      assert (insn.insn_mo->name);      assert (strcmp (name, insn.insn_mo->name) == 0);    }  insn.insn_opcode = insn.insn_mo->match;  insn.use_extend = false;  for (;;)    {      int c;      c = *fmt++;      switch (c)	{	case '\0':	  break;	case ',':	case '(':	case ')':	  continue;	case 'y':	case 'w':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RY;	  continue;	case 'x':	case 'v':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RX;	  continue;	case 'z':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_RZ;	  continue;	case 'Z':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_MOVE32Z;	  continue;	case '0':	case 'S':	case 'P':	case 'R':	  continue;	case 'X':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_REGR32;	  continue;	case 'Y':	  {	    int regno;	    regno = va_arg (args, int);	    regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);	    insn.insn_opcode |= regno << MIPS16OP_SH_REG32R;	  }	  continue;	case '<':	case '>':	case '4':	case '5':	case 'H':	case 'W':	case 'D':	case 'j':	case '8':	case 'V':	case 'C':	case 'U':	case 'k':	case 'K':	case 'p':	case 'q':	  {	    assert (ep != NULL);	    if (ep->X_op != O_constant)	      r = BFD_RELOC_UNUSED + c;	    else	      {		mips16_immed ((char *) NULL, 0, c, ep->X_add_number, false,			      false, false, &insn.insn_opcode,			      &insn.use_extend, &insn.extend);		ep = NULL;		r = BFD_RELOC_UNUSED;	      }	  }	  continue;	case '6':	  insn.insn_opcode |= va_arg (args, int) << MIPS16OP_SH_IMM6;	  continue;	}      break;    }  assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);  append_insn (place, &insn, ep, r, false);}/* * Generate a "lui" instruction. */static voidmacro_build_lui (place, counter, ep, regnum)     char *place;     int *counter;     expressionS *ep;     int regnum;{  expressionS high_expr;  struct mips_cl_insn insn;  bfd_reloc_code_real_type r;  CONST char *name = "lui";  CONST char *fmt = "t,u";  assert (! mips_opts.mips16);  if (place == NULL)    high_expr = *ep;  else    {      high_expr.X_op = O_constant;      high_expr.X_add_number = ep->X_add_number;    }  if (high_expr.X_op == O_constant)    {      /* we can compute the instruction now without a relocation entry */      if (high_expr.X_add_number & 0x8000)	high_expr.X_add_number += 0x10000;      high_expr.X_add_number =	((unsigned long) high_expr.X_add_number >> 16) & 0xffff;      r = BFD_RELOC_UNUSED;    }  else    {      assert (ep->X_op == O_symbol);      /* _gp_disp is a special case, used from s_cpload.  */      assert (mips_pic == NO_PIC	      || strcmp (S_GET_NAME (ep->X_add_symbol), "_gp_disp") == 0);      r = BFD_RELOC_HI16_S;    }  /*   * If the macro is about to expand into a second instruction,   * print a warning if needed. We need to pass ip as a parameter   * to generate a better warning message here...   */  if (mips_opts.warn_about_macros && place == NULL && *counter == 1)    as_warn (_("Macro instruction expanded into multiple instructions"));  if (place == NULL)    *counter += 1;		/* bump instruction counter */  insn.insn_mo = (struct mips_opcode *) hash_find (op_hash, name);  assert (insn.insn_mo);  assert (strcmp (name, insn.insn_mo->name) == 0);  assert (strcmp (fmt, insn.insn_mo->args) == 0);  insn.insn_opcode = insn.insn_mo->match | (regnum << OP_SH_RT);  if (r == BFD_RELOC_UNUSED)    {      insn.insn_opcode |= high_expr.X_add_number;      append_insn (place, &insn, NULL, r, false);    }  else    append_insn (place, &insn, &high_expr, r, false);}/*			set_at() * Generates code to set the $at register to true (one) * if reg is less than the immediate expression. */static voidset_at (counter, reg, unsignedp)     int *counter;     int reg;     int unsignedp;{  if (imm_expr.X_op == O_constant      && imm_expr.X_add_number >= -0x8000      && imm_expr.X_add_number < 0x8000)    macro_build ((char *) NULL, counter, &imm_expr,		 unsignedp ? "sltiu" : "slti",		 "t,r,j", AT, reg, (int) BFD_RELOC_LO16);  else    {      load_register (counter, AT, &imm_expr, 0);      macro_build ((char *) NULL, counter, NULL,		   unsignedp ? "sltu" : "slt",		   "d,v,t", AT, reg, AT);    }}/* Warn if an expression is not a constant.  */static voidcheck_absolute_expr (ip, ex)     struct mips_cl_insn *ip;     expressionS *ex;{  if (ex->X_op == O_big)    as_bad (_("unsupported large constant"));  else if (ex->X_op != O_constant)    as_bad (_("Instruction %s requires absolute expression"), ip->insn_mo->name);}/* Count the leading zeroes by performing a binary chop. This is a   bulky bit of source, but performance is a LOT better for the   majority of values than a simple loop to count the bits:       for (lcnt = 0; (lcnt < 32); lcnt++)         if ((v) & (1 << (31 - lcnt)))           break;  However it is not code size friendly, and the gain will drop a bit  on certain cached systems.*/#define COUNT_TOP_ZEROES(v)             \  (((v) & ~0xffff) == 0                 \   ? ((v) & ~0xff) == 0                 \     ? ((v) & ~0xf) == 0                \       ? ((v) & ~0x3) == 0              \         ? ((v) & ~0x1) == 0            \           ? !(v)                       \             ? 32                       \             : 31                       \           : 30                         \         : ((v) & ~0x7) == 0            \           ? 29                         \           : 28                         \       : ((v) & ~0x3f) == 0             \         ? ((v) & ~0x1f) == 0           \           ? 27                         \           : 26                         \         : ((v) & ~0x7f) == 0           \           ? 25                         \           : 24                         \     : ((v) & ~0xfff) == 0              \       ? ((v) & ~0x3ff) == 0            \         ? ((v) & ~0x1ff) == 0          \           ? 23                         \           : 22                         \         : ((v) & ~0x7ff) == 0          \           ? 21                         \           : 20                         \       : ((v) & ~0x3fff) == 0           \         ? ((v) & ~0x1fff) == 0         \           ? 19                         \           : 18                         \         : ((v) & ~0x7fff) == 0         \           ? 17                         \           : 16                         \   : ((v) & ~0xffffff) == 0             \     ? ((v) & ~0xfffff) == 0            \       ? ((v) & ~0x3ffff) == 0          \         ? ((v) & ~0x1ffff) == 0        \           ? 15                         \           : 14                         \         : ((v) & ~0x7ffff) == 0        \           ? 13                         \           : 12                         \       : ((v) & ~0x3fffff) == 0         \         ? ((v) & ~0x1fffff) == 0       \           ? 11                         \           : 10                         \         : ((v) & ~0x7fffff) == 0       \           ? 9                          \           : 8                          \     : ((v) & ~0xfffffff) == 0          \       ? ((v) & ~0x3ffffff) == 0        \         ? ((v) & ~0x1ffffff) == 0      \           ? 7                          \           : 6                          \         : ((v) & ~0x7ffffff) == 0      \           ? 5                          \           : 4                          \       : ((v) & ~0x3fffffff) == 0       \         ? ((v) & ~0x1fffffff) == 0     \           ? 3                          \           : 2                          \         : ((v) & ~0x7fffffff) == 0     \           ? 1                          \           : 0)/*			load_register() *  This routine generates the least number of instructions neccessary to load *  an absolute expression value into a register. */static voidload_register (counter, reg, ep, dbl)     int *counter;     int reg;     expressionS *ep;     int dbl;{  int freg;  expressionS hi32, lo32;  if (ep->X_op != O_big)    {      assert (ep->X_op == O_constant);      if (ep->X_add_number < 0x8000	  && (ep->X_add_number >= 0	      || (ep->X_add_number >= -0x8000		  && (! dbl		      || ! ep->X_unsigned		      || sizeof (ep->X_add_number) > 4))))	{	  /* We can handle 16 bit signed values with an addiu to	     $zero.  No need to ever use daddiu here, since $zero and	     the result are always correct in 32 bit mode.  */	  macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,		       (int) BFD_RELOC_LO16);	  return;	}      else if (ep->X_add_number >= 0 && ep->X_add_number < 0x10000)	{	  /* We can handle 16 bit unsigned values with an ori to             $zero.  */	  macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, 0,		       (int) BFD_RELOC_LO16);	  return;	}      else if ((((ep->X_add_number &~ (offsetT) 0x7fffffff) == 0		 || ((ep->X_add_number &~ (offsetT) 0x7fffffff)		     == ~ (offsetT) 0x7fffffff))		&& (! dbl		    || ! ep->X_unsigned		    || sizeof (ep->X_add_number) > 4		    || (ep->X_add_number & 0x80000000) == 0))	       || ((! ISA_HAS_64BIT_REGS (mips_opts.isa) || ! dbl)		   && (ep->X_add_number &~ (offsetT) 0xffffffff) == 0)	       || (! ISA_HAS_64BIT_REGS (mips_opts.isa)		   && ! dbl		   && ((ep->X_add_number &~ (offsetT) 0xffffffff)		       == ~ (offsetT) 0xffffffff)))	{	  /* 32 bit values require an lui.  */	  macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,		       (int) BFD_RELOC_HI16);	  if ((ep->X_add_number & 0xffff) != 0)	    macro_build ((char *) NULL, counter, ep, "ori", "t,r,i", reg, reg,			 (int) BFD_RELOC_LO16);	  return;	}    }  /* The value is larger than 32 bits.  */  if (! ISA_HAS_64BIT_REGS (mips_opts.isa))    {      as_bad (_("Number larger than 32 bits"));      macro_build ((char *) NULL, counter, ep, "addiu", "t,r,j", reg, 0,		   (int) BFD_RELOC_LO16);      return;    }  if (ep->X_op != O_big)    {      hi32 = *ep;      hi32.X_add_number = (valueT) hi32.X_add_number >> 16;      hi32.X_add_number = (valueT) hi32.X_add_number >> 16;      hi32.X_add_number &= 0xffffffff;      lo32 = *ep;      lo32.X_add_number &= 0xffffffff;    }  else    {      assert (ep->X_add_number > 2);      if (ep->X_add_number == 3)	generic_bignum[3] = 0;      else if (ep->X_add_number > 4)	as_bad (_("Number larger than 64 bits"));      lo32.X_op = O_constant;      lo32.X_add_number = generic_bignum[0] + (generic_bignum[1] << 16);      hi32.X_op = O_constant;      hi32.X_add_number = generic_bignum[2] + (generic_bignum[3] << 16);    }  if (hi32.X_add_number == 0)    freg = 0;  else    {      int shift, bit;      unsigned long hi, lo;      if (hi32.X_add_number == 0xffffffff)        {          if ((lo32.X_add_number & 0xffff8000) == 0xffff8000)            {              macro_build ((char *) NULL, counter, &lo32, "addiu", "t,r,j",			   reg, 0, (int) BFD_RELOC_LO16);              return;            }          if (lo32.X_add_number & 0x80000000)            {              macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,                           (int) BFD_RELOC_HI16);	      if (lo32.X_add_number & 0xffff)		macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i",			     reg, reg, (int) BFD_RELOC_LO16);              return;            }        }      /* Check for 16bit shifted constant.  We know that hi32 is         non-zero, so start the mask on the first bit of the hi32         value.  */      shift = 17;      do       {	 unsigned long himask, lomask;	 if (shift < 32)	   {	     himask = 0xffff >> (32 - shift);	     lomask = (0xffff << shift) & 0xffffffff;	   }	 else	   {	     himask = 0xffff << (shift - 32);	     lomask = 0;	   }	 if ((hi32.X_add_number & ~ (offsetT) himask) == 0	     && (lo32.X_add_number & ~ (offsetT) lomask) == 0)	   {	     expressionS tmp;	     tmp.X_op = O_constant;	     if (shift < 32)	       tmp.X_add_number = ((hi32.X_add_number << (32 - shift))				   | (lo32.X_add_number >> shift));	     else	       tmp.X_add_number = hi32.X_add_number >> (shift - 32);	     macro_build ((char *) NULL, counter, &tmp, "ori", "t,r,i", reg, 0,			  (int) BFD_RELOC_LO16);	     macro_build ((char *) NULL, counter, NULL,			  (shift >= 32) ? "dsll32" : "dsll",			  "d,w,<", reg, reg,			  (shift >= 32) ? shift - 32 : shift);	     return;	   }         shift++;       } while (shift <= (64 - 16));      /* Find the bit number of the lowest one bit, and store the         shifted value in hi/lo.  */      hi = (unsigned long) (hi32.X_add_number & 0xffffffff);      lo = (unsigned long) (lo32.X_add_number & 0xffffffff);      if (lo != 0)	{	  bit = 0;	  while ((lo & 1) == 0)	    {	      lo >>= 1;	      ++bit;	    }	  lo |= (hi & (((unsigned long) 1 << bit) - 1)) << (32 - bit);	  hi >>= bit;	}      else	{	  bit = 32;	  while ((hi & 1) == 0)	    {	      hi >>= 1;	      ++bit;	    }	  lo = hi;	  hi = 0;	}      /* Optimize if the shifted value is a (power of 2) - 1.  */      if ((hi == 0 && ((lo + 1) & lo) == 0)	  || (lo == 0xffffffff && ((hi + 1) & hi) == 0))        {          shift = COUNT_TOP_ZEROES ((unsigned int) hi32.X_add_number);	  if (shift != 0)            {	      expressionS tmp;	      /* This instruction will set the register to be all                 ones.  */              tmp.X_op = O_constant;              tmp.X_add_number = (offsetT) -1;              macro_build ((char *) NULL, counter, &tmp, "addiu", "t,r,j",			   reg, 0, (int) BFD_RELOC_LO16);              if (bit != 0)                {                  bit += shift;                  macro_build ((char *) NULL, counter, NULL,                               (bit >= 32) ? "dsll32" : "dsll",                               "d,w,<", reg, reg,                               (bit >= 32) ? bit - 32 : bit);                }              macro_build ((char *) NULL, counter, NULL,			   (shift >= 32) ? "dsrl32" : "dsrl",                           "d,w,<", reg, reg,			   (shift >= 32) ? shift - 32 : shift);              return;            }        }      /* Sign extend hi32 before calling load_register, because we can         generally get better code when we load a sign extended value.  */      if ((hi32.X_add_number & 0x80000000) != 0)	hi32.X_add_number |= ~ (offsetT) 0xffffffff;      load_register (counter, reg, &hi32, 0);      freg = reg;    }  if ((lo32.X_add_number & 0xffff0000) == 0)    {      if (freg != 0)	{	  macro_build ((char *) NULL, counter, NULL, "dsll32", "d,w,<", reg,		       freg, 0);	  freg = reg;	}    }  else    {      expressionS mid16;      if ((freg == 0) && (lo32.X_add_number == 0xffffffff))        {	  macro_build ((char *) NULL, counter, &lo32, "lui", "t,u", reg,		       (int) BFD_RELOC_HI16);          macro_build ((char *) NULL, counter, NULL, "dsrl32", "d,w,<", reg,                       reg, 0);          return;        }      if (freg != 0)	{	  macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,		       freg, 16);	  freg = reg;	}      mid16 = lo32;      mid16.X_add_number >>= 16;      macro_build ((char *) NULL, counter, &mid16, "ori", "t,r,i", reg,		   freg, (int) BFD_RELOC_LO16);      macro_build ((char *) NULL, counter, NULL, "dsll", "d,w,<", reg,		   reg, 16);      freg = reg;    }  if ((lo32.X_add_number & 0xffff) != 0)    macro_build ((char *) NULL, counter, &lo32, "ori", "t,r,i", reg, freg,		 (int) BFD_RELOC_LO16);}/* Load an address into a register.  */static voidload_address (counter, reg, ep)     int *counter;     int reg;     expressionS *ep;{  char *p;  if (ep->X_op != O_constant      && ep->X_op != O_symbol)    {      as_bad (_("expression too complex"));      ep->X_op = O_constant;    }  if (ep->X_op == O_constant)    {      load_register (counter, reg, ep, 0);      return;    }  if (mips_pic == NO_PIC)    {      /* If this is a reference to a GP relative symbol, we want	   addiu	$reg,$gp,<sym>		(BFD_RELOC_MIPS_GPREL)	 Otherwise we want	   lui		$reg,<sym>		(BFD_RELOC_HI16_S)	   addiu	$reg,$reg,<sym>		(BFD_RELOC_LO16)	 If we have an addend, we always use the latter form.  */      if ((valueT) ep->X_add_number >= MAX_GPREL_OFFSET          || nopic_need_relax (ep->X_add_symbol, 1))	p = NULL;      else	{	  frag_grow (20);	  macro_build ((char *) NULL, counter, ep,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);	  p = frag_var (rs_machine_dependent, 8, 0,			RELAX_ENCODE (4, 8, 0, 4, 0,				      mips_opts.warn_about_macros),			ep->X_add_symbol, (offsetT) 0, (char *) NULL);	}      macro_build_lui (p, counter, ep, reg);      if (p != NULL)	p += 4;      macro_build (p, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "addiu" : "daddiu"),		   "t,r,j", reg, reg, (int) BFD_RELOC_LO16);    }  else if (mips_pic == SVR4_PIC && ! mips_big_got)    {      expressionS ex;      /* If this is a reference to an external symbol, we want	   lw		$reg,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	 Otherwise we want	   lw		$reg,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	   nop	   addiu	$reg,$reg,<sym>		(BFD_RELOC_LO16)	 If there is a constant, it must be added in after.  */      ex.X_add_number = ep->X_add_number;      ep->X_add_number = 0;      frag_grow (20);      macro_build ((char *) NULL, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "lw" : "ld"),		   "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);      macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", "");      p = frag_var (rs_machine_dependent, 4, 0,		    RELAX_ENCODE (0, 4, -8, 0, 0, mips_opts.warn_about_macros),		    ep->X_add_symbol, (offsetT) 0, (char *) NULL);      macro_build (p, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "addiu" : "daddiu"),		   "t,r,j", reg, reg, (int) BFD_RELOC_LO16);      if (ex.X_add_number != 0)	{	  if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  ex.X_op = O_constant;	  macro_build ((char *) NULL, counter, &ex,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", reg, reg, (int) BFD_RELOC_LO16);	}    }  else if (mips_pic == SVR4_PIC)    {      expressionS ex;      int off;      /* This is the large GOT case.  If this is a reference to an	 external symbol, we want	   lui		$reg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	   addu		$reg,$reg,$gp	   lw		$reg,<sym>($reg)	(BFD_RELOC_MIPS_GOT_LO16)	 Otherwise, for a reference to a local symbol, we want	   lw		$reg,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	   nop	   addiu	$reg,$reg,<sym>		(BFD_RELOC_LO16)	 If there is a constant, it must be added in after.  */      ex.X_add_number = ep->X_add_number;      ep->X_add_number = 0;      if (reg_needs_delay (GP))	off = 4;      else	off = 0;      frag_grow (32);      macro_build ((char *) NULL, counter, ep, "lui", "t,u", reg,		   (int) BFD_RELOC_MIPS_GOT_HI16);      macro_build ((char *) NULL, counter, (expressionS *) NULL,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "addu" : "daddu"),		   "d,v,t", reg, reg, GP);      macro_build ((char *) NULL, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "lw" : "ld"),		   "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT_LO16, reg);      p = frag_var (rs_machine_dependent, 12 + off, 0,		    RELAX_ENCODE (12, 12 + off, off, 8 + off, 0,				  mips_opts.warn_about_macros),		    ep->X_add_symbol, (offsetT) 0, (char *) NULL);      if (off > 0)	{	  /* We need a nop before loading from $gp.  This special             check is required because the lui which starts the main             instruction stream does not refer to $gp, and so will not             insert the nop which may be required.  */	  macro_build (p, counter, (expressionS *) NULL, "nop", "");	  p += 4;	}      macro_build (p, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "lw" : "ld"),		   "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP);      p += 4;      macro_build (p, counter, (expressionS *) NULL, "nop", "");      p += 4;      macro_build (p, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "addiu" : "daddiu"),		   "t,r,j", reg, reg, (int) BFD_RELOC_LO16);      if (ex.X_add_number != 0)	{	  if (ex.X_add_number < -0x8000 || ex.X_add_number >= 0x8000)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  ex.X_op = O_constant;	  macro_build ((char *) NULL, counter, &ex,		       ((bfd_arch_bits_per_address (stdoutput) == 32		         || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", reg, reg, (int) BFD_RELOC_LO16);	}    }  else if (mips_pic == EMBEDDED_PIC)    {      /* We always do	   addiu	$reg,$gp,<sym>		(BFD_RELOC_MIPS_GPREL)	 */      macro_build ((char *) NULL, counter, ep,		   ((bfd_arch_bits_per_address (stdoutput) == 32		     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		    ? "addiu" : "daddiu"),		   "t,r,j", reg, GP, (int) BFD_RELOC_MIPS_GPREL);    }  else    abort ();}/* *			Build macros *   This routine implements the seemingly endless macro or synthesized * instructions and addressing modes in the mips assembly language. Many * of these macros are simple and are similar to each other. These could * probably be handled by some kind of table or grammer aproach instead of * this verbose method. Others are not simple macros but are more like * optimizing code generation. *   One interesting optimization is when several store macros appear * consecutivly that would load AT with the upper half of the same address. * The ensuing load upper instructions are ommited. This implies some kind * of global optimization. We currently only optimize within a single macro. *   For many of the load and store macros if the address is specified as a * constant expression in the first 64k of memory (ie ld $2,0x4000c) we * first load register 'at' with zero and use it as the base register. The * mips assembler simply uses register $zero. Just one tiny optimization * we're missing. */static voidmacro (ip)     struct mips_cl_insn *ip;{  register int treg, sreg, dreg, breg;  int tempreg;  int mask;  int icnt = 0;  int used_at;  expressionS expr1;  const char *s;  const char *s2;  const char *fmt;  int likely = 0;  int dbl = 0;  int coproc = 0;  int lr = 0;  int imm = 0;  offsetT maxnum;  int off;  bfd_reloc_code_real_type r;  char *p;  int hold_mips_optimize;  assert (! mips_opts.mips16);  treg = (ip->insn_opcode >> 16) & 0x1f;  dreg = (ip->insn_opcode >> 11) & 0x1f;  sreg = breg = (ip->insn_opcode >> 21) & 0x1f;  mask = ip->insn_mo->mask;  expr1.X_op = O_constant;  expr1.X_op_symbol = NULL;  expr1.X_add_symbol = NULL;  expr1.X_add_number = 1;  switch (mask)    {    case M_DABS:      dbl = 1;    case M_ABS:      /* bgez $a0,.+12	 move v0,$a0	 sub v0,$zero,$a0	 */      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      expr1.X_add_number = 8;      macro_build ((char *) NULL, &icnt, &expr1, "bgez", "s,p", sreg);      if (dreg == sreg)	macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);      else	macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, sreg, 0);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dsub" : "sub",		   "d,v,t", dreg, 0, sreg);      --mips_opts.noreorder;      return;    case M_ADD_I:      s = "addi";      s2 = "add";      goto do_addi;    case M_ADDU_I:      s = "addiu";      s2 = "addu";      goto do_addi;    case M_DADD_I:      dbl = 1;      s = "daddi";      s2 = "dadd";      goto do_addi;    case M_DADDU_I:      dbl = 1;      s = "daddiu";      s2 = "daddu";    do_addi:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= -0x8000	  && imm_expr.X_add_number < 0x8000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,j", treg, sreg,		       (int) BFD_RELOC_LO16);	  return;	}      load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);      break;    case M_AND_I:      s = "andi";      s2 = "and";      goto do_bit;    case M_OR_I:      s = "ori";      s2 = "or";      goto do_bit;    case M_NOR_I:      s = "";      s2 = "nor";      goto do_bit;    case M_XOR_I:      s = "xori";      s2 = "xor";    do_bit:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= 0	  && imm_expr.X_add_number < 0x10000)	{	  if (mask != M_NOR_I)	    macro_build ((char *) NULL, &icnt, &imm_expr, s, "t,r,i", treg,			 sreg, (int) BFD_RELOC_LO16);	  else	    {	      macro_build ((char *) NULL, &icnt, &imm_expr, "ori", "t,r,i",			   treg, sreg, (int) BFD_RELOC_LO16);	      macro_build ((char *) NULL, &icnt, NULL, "nor", "d,v,t",			   treg, treg, 0);	    }	  return;	}      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, s2, "d,v,t", treg, sreg, AT);      break;    case M_BEQ_I:      s = "beq";      goto beq_i;    case M_BEQL_I:      s = "beql";      likely = 1;      goto beq_i;    case M_BNE_I:      s = "bne";      goto beq_i;    case M_BNEL_I:      s = "bnel";      likely = 1;    beq_i:      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg,		       0);	  return;	}      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, &offset_expr, s, "s,t,p", sreg, AT);      break;    case M_BGEL:      likely = 1;    case M_BGE:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgezl" : "bgez",		       "s,p", sreg);	  return;	}      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "blezl" : "blez",		       "s,p", treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BGTL_I:      likely = 1;    case M_BGT_I:      /* check for > max integer */      maxnum = 0x7fffffff;      if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)	{	  maxnum <<= 16;	  maxnum |= 0xffff;	  maxnum <<= 16;	  maxnum |= 0xffff;	}      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= maxnum	  && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))	{	do_false:	  /* result is always false */	  if (! likely)	    {	      as_warn (_("Branch %s is always false (nop)"), ip->insn_mo->name);	      macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);	    }	  else	    {	      as_warn (_("Branch likely %s is always false"), ip->insn_mo->name);	      macro_build ((char *) NULL, &icnt, &offset_expr, "bnel",			   "s,t,p", 0, 0);	    }	  return;	}      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number++;      /* FALLTHROUGH */    case M_BGE_I:    case M_BGEL_I:      if (mask == M_BGEL_I)	likely = 1;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgezl" : "bgez",		       "s,p", sreg);	  return;	}      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgtzl" : "bgtz",		       "s,p", sreg);	  return;	}      maxnum = 0x7fffffff;      if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)	{	  maxnum <<= 16;	  maxnum |= 0xffff;	  maxnum <<= 16;	  maxnum |= 0xffff;	}      maxnum = - maxnum - 1;      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number <= maxnum	  && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))	{	do_true:	  /* result is always true */	  as_warn (_("Branch %s is always true"), ip->insn_mo->name);	  macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");	  return;	}      set_at (&icnt, sreg, 0);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BGEUL:      likely = 1;    case M_BGEU:      if (treg == 0)	goto do_true;      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "beql" : "beq",		       "s,t,p", 0, treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,		   treg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BGTUL_I:      likely = 1;    case M_BGTU_I:      if (sreg == 0	  || (! ISA_HAS_64BIT_REGS (mips_opts.isa)	      && imm_expr.X_op == O_constant	      && imm_expr.X_add_number == 0xffffffff))	goto do_false;      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number++;      /* FALLTHROUGH */    case M_BGEU_I:    case M_BGEUL_I:      if (mask == M_BGEUL_I)	likely = 1;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	goto do_true;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bnel" : "bne",		       "s,t,p", sreg, 0);	  return;	}      set_at (&icnt, sreg, 1);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BGTL:      likely = 1;    case M_BGT:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgtzl" : "bgtz",		       "s,p", sreg);	  return;	}      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bltzl" : "bltz",		       "s,p", treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_BGTUL:      likely = 1;    case M_BGTU:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bnel" : "bne",		       "s,t,p", sreg, 0);	  return;	}      if (sreg == 0)	goto do_false;      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,		   sreg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_BLEL:      likely = 1;    case M_BLE:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "blezl" : "blez",		       "s,p", sreg);	  return;	}      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgezl" : "bgez",		       "s,p", treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, treg, sreg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BLEL_I:      likely = 1;    case M_BLE_I:      maxnum = 0x7fffffff;      if (ISA_HAS_64BIT_REGS (mips_opts.isa) && sizeof (maxnum) > 4)	{	  maxnum <<= 16;	  maxnum |= 0xffff;	  maxnum <<= 16;	  maxnum |= 0xffff;	}      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= maxnum	  && (! ISA_HAS_64BIT_REGS (mips_opts.isa) || sizeof (maxnum) > 4))	goto do_true;      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number++;      /* FALLTHROUGH */    case M_BLT_I:    case M_BLTL_I:      if (mask == M_BLTL_I)	likely = 1;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bltzl" : "bltz",		       "s,p", sreg);	  return;	}      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "blezl" : "blez",		       "s,p", sreg);	  return;	}      set_at (&icnt, sreg, 0);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_BLEUL:      likely = 1;    case M_BLEU:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "beql" : "beq",		       "s,t,p", sreg, 0);	  return;	}      if (sreg == 0)	goto do_true;      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, treg,		   sreg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "beql" : "beq",		   "s,t,p", AT, 0);      break;    case M_BLEUL_I:      likely = 1;    case M_BLEU_I:      if (sreg == 0	  || (! ISA_HAS_64BIT_REGS (mips_opts.isa)	      && imm_expr.X_op == O_constant	      && imm_expr.X_add_number == 0xffffffff))	goto do_true;      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number++;      /* FALLTHROUGH */    case M_BLTU_I:    case M_BLTUL_I:      if (mask == M_BLTUL_I)	likely = 1;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	goto do_false;      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "beql" : "beq",		       "s,t,p", sreg, 0);	  return;	}      set_at (&icnt, sreg, 1);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_BLTL:      likely = 1;    case M_BLT:      if (treg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bltzl" : "bltz",		       "s,p", sreg);	  return;	}      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bgtzl" : "bgtz",		       "s,p", treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", AT, sreg, treg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_BLTUL:      likely = 1;    case M_BLTU:      if (treg == 0)	goto do_false;      if (sreg == 0)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       likely ? "bnel" : "bne",		       "s,t,p", 0, treg);	  return;	}      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", AT, sreg,		   treg);      macro_build ((char *) NULL, &icnt, &offset_expr,		   likely ? "bnel" : "bne",		   "s,t,p", AT, 0);      break;    case M_DDIV_3:      dbl = 1;    case M_DIV_3:      s = "mflo";      goto do_div3;    case M_DREM_3:      dbl = 1;    case M_REM_3:      s = "mfhi";    do_div3:      if (treg == 0)	{	  as_warn (_("Divide by zero."));	  if (mips_trap)	    macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);	  else	      macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);	  return;	}      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      if (mips_trap)	{	  macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", treg, 0);	  macro_build ((char *) NULL, &icnt, NULL,		       dbl ? "ddiv" : "div",		       "z,s,t", sreg, treg);	}      else	{	  expr1.X_add_number = 8;	  macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);	  macro_build ((char *) NULL, &icnt, NULL,		       dbl ? "ddiv" : "div",		       "z,s,t", sreg, treg);	    macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);	}      expr1.X_add_number = -1;      macro_build ((char *) NULL, &icnt, &expr1,		   dbl ? "daddiu" : "addiu",		   "t,r,j", AT, 0, (int) BFD_RELOC_LO16);      expr1.X_add_number = mips_trap ? (dbl ? 12 : 8) : (dbl ? 20 : 16);      macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, AT);      if (dbl)	{	  expr1.X_add_number = 1;	  macro_build ((char *) NULL, &icnt, &expr1, "daddiu", "t,r,j", AT, 0,		       (int) BFD_RELOC_LO16);	  macro_build ((char *) NULL, &icnt, NULL, "dsll32", "d,w,<", AT, AT,		       31);	}      else	{	  expr1.X_add_number = 0x80000000;	  macro_build ((char *) NULL, &icnt, &expr1, "lui", "t,u", AT,		       (int) BFD_RELOC_HI16);	}      if (mips_trap)	{	  macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", sreg, AT);	  /* We want to close the noreorder block as soon as possible, so	     that later insns are available for delay slot filling.  */	  --mips_opts.noreorder;	}      else	{	  expr1.X_add_number = 8;	  macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", sreg, AT);	  macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);	  /* We want to close the noreorder block as soon as possible, so	     that later insns are available for delay slot filling.  */	  --mips_opts.noreorder;	    macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);	}      macro_build ((char *) NULL, &icnt, NULL, s, "d", dreg);      break;    case M_DIV_3I:      s = "div";      s2 = "mflo";      goto do_divi;    case M_DIVU_3I:      s = "divu";      s2 = "mflo";      goto do_divi;    case M_REM_3I:      s = "div";      s2 = "mfhi";      goto do_divi;    case M_REMU_3I:      s = "divu";      s2 = "mfhi";      goto do_divi;    case M_DDIV_3I:      dbl = 1;      s = "ddiv";      s2 = "mflo";      goto do_divi;    case M_DDIVU_3I:      dbl = 1;      s = "ddivu";      s2 = "mflo";      goto do_divi;    case M_DREM_3I:      dbl = 1;      s = "ddiv";      s2 = "mfhi";      goto do_divi;    case M_DREMU_3I:      dbl = 1;      s = "ddivu";      s2 = "mfhi";    do_divi:      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  as_warn (_("Divide by zero."));	  if (mips_trap)	    macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", 0, 0);	  else	      macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);	  return;	}      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 1)	{	  if (strcmp (s2, "mflo") == 0)	    macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg,			 sreg);	  else	    macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);	  return;	}      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number == -1	  && s[strlen (s) - 1] != 'u')	{	  if (strcmp (s2, "mflo") == 0)	    {	      if (dbl)		macro_build ((char *) NULL, &icnt, NULL, "dneg", "d,w", dreg,			     sreg);	      else		macro_build ((char *) NULL, &icnt, NULL, "neg", "d,w", dreg,			     sreg);	    }	  else	    macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);	  return;	}      load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, AT);      macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);      break;    case M_DIVU_3:      s = "divu";      s2 = "mflo";      goto do_divu3;    case M_REMU_3:      s = "divu";      s2 = "mfhi";      goto do_divu3;    case M_DDIVU_3:      s = "ddivu";      s2 = "mflo";      goto do_divu3;    case M_DREMU_3:      s = "ddivu";      s2 = "mfhi";    do_divu3:      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      if (mips_trap)	{	  macro_build ((char *) NULL, &icnt, NULL, "teq", "s,t", treg, 0);	  macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);	  /* We want to close the noreorder block as soon as possible, so	     that later insns are available for delay slot filling.  */	  --mips_opts.noreorder;	}      else	{	  expr1.X_add_number = 8;	  macro_build ((char *) NULL, &icnt, &expr1, "bne", "s,t,p", treg, 0);	  macro_build ((char *) NULL, &icnt, NULL, s, "z,s,t", sreg, treg);	  /* We want to close the noreorder block as soon as possible, so	     that later insns are available for delay slot filling.  */	  --mips_opts.noreorder;	    macro_build ((char *) NULL, &icnt, NULL, "break", "c", 7);	}      macro_build ((char *) NULL, &icnt, NULL, s2, "d", dreg);      return;    case M_DLA_AB:      dbl = 1;    case M_LA_AB:      /* Load the address of a symbol into a register.  If breg is not	 zero, we then add a base register to it.  */      /* When generating embedded PIC code, we permit expressions of	 the form	   la	$4,foo-bar	 where bar is an address in the current section.  These are used	 when getting the addresses of functions.  We don't permit	 X_add_number to be non-zero, because if the symbol is	 external the relaxing code needs to know that any addend is	 purely the offset to X_op_symbol.  */      if (mips_pic == EMBEDDED_PIC	  && offset_expr.X_op == O_subtract	  && (symbol_constant_p (offset_expr.X_op_symbol)	      ? S_GET_SEGMENT (offset_expr.X_op_symbol) == now_seg	      : (symbol_equated_p (offset_expr.X_op_symbol)		 && (S_GET_SEGMENT		     (symbol_get_value_expression (offset_expr.X_op_symbol)		      ->X_add_symbol)		     == now_seg)))	  && breg == 0	  && (offset_expr.X_add_number == 0	      || OUTPUT_FLAVOR == bfd_target_elf_flavour))	{	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",		       treg, (int) BFD_RELOC_PCREL_HI16_S);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32		         || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", treg, treg, (int) BFD_RELOC_PCREL_LO16);	  return;	}      if (offset_expr.X_op != O_symbol	  && offset_expr.X_op != O_constant)	{	  as_bad (_("expression too complex"));	  offset_expr.X_op = O_constant;	}      if (treg == breg)	{	  tempreg = AT;	  used_at = 1;	}      else	{	  tempreg = treg;	  used_at = 0;	}      if (offset_expr.X_op == O_constant)	load_register (&icnt, tempreg, &offset_expr, dbl);      else if (mips_pic == NO_PIC)	{	  /* If this is a reference to an GP relative symbol, we want	       addiu	$tempreg,$gp,<sym>	(BFD_RELOC_MIPS_GPREL)	     Otherwise we want	       lui	$tempreg,<sym>		(BFD_RELOC_HI16_S)	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)	     If we have a constant, we need two instructions anyhow,	     so we may as well always use the latter form.  */	  if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET	      || nopic_need_relax (offset_expr.X_add_symbol, 1))	    p = NULL;	  else	    {	      frag_grow (20);	      macro_build ((char *) NULL, &icnt, &offset_expr,			   ((bfd_arch_bits_per_address (stdoutput) == 32		     	     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);	      p = frag_var (rs_machine_dependent, 8, 0,			    RELAX_ENCODE (4, 8, 0, 4, 0,					  mips_opts.warn_about_macros),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	    }	  macro_build_lui (p, &icnt, &offset_expr, tempreg);	  if (p != NULL)	    p += 4;	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	}      else if (mips_pic == SVR4_PIC && ! mips_big_got)	{	  /* If this is a reference to an external symbol, and there	     is no constant, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	     For a local symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)	     If we have a small constant, and this is a reference to	     an external symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<constant>	     For a local symbol, we want the same instruction	     sequence, but we output a BFD_RELOC_LO16 reloc on the	     addiu instruction.	     If we have a large constant, and this is a reference to	     an external symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       lui	$at,<hiconstant>	       addiu	$at,$at,<loconstant>	       addu	$tempreg,$tempreg,$at	     For a local symbol, we want the same instruction	     sequence, but we output a BFD_RELOC_LO16 reloc on the	     addiu instruction.  */	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  frag_grow (32);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       dbl ? "ld" : "lw",		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);	  if (expr1.X_add_number == 0)	    {	      int off;	      if (breg == 0)		off = 0;	      else		{		  /* We're going to put in an addu instruction using		     tempreg, so we may as well insert the nop right		     now.  */		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       "nop", "");		  off = 4;		}	      p = frag_var (rs_machine_dependent, 8 - off, 0,			    RELAX_ENCODE (0, 8 - off, -4 - off, 4 - off, 0,					  (breg == 0					   ? mips_opts.warn_about_macros					   : 0)),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	      if (breg == 0)		{		  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");		  p += 4;		}	      macro_build (p, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	      /* FIXME: If breg == 0, and the next instruction uses		 $tempreg, then if this variant case is used an extra		 nop will be generated.  */	    }	  else if (expr1.X_add_number >= -0x8000		   && expr1.X_add_number < 0x8000)	    {	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   "nop", "");	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	      (void) frag_var (rs_machine_dependent, 0, 0,			       RELAX_ENCODE (0, 0, -12, -4, 0, 0),			       offset_expr.X_add_symbol, (offsetT) 0,			       (char *) NULL);	    }	  else	    {	      int off1;	      /* If we are going to add in a base register, and the		 target register and the base register are the same,		 then we are using AT as a temporary register.  Since		 we want to load the constant into AT, we add our		 current AT (from the global offset table) and the		 register into the register now, and pretend we were		 not using a base register.  */	      if (breg != treg)		off1 = 0;	      else		{		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       "nop", "");		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       ((bfd_arch_bits_per_address (stdoutput) == 32				 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))				? "addu" : "daddu"),			       "d,v,t", treg, AT, breg);		  breg = 0;		  tempreg = treg;		  off1 = -8;		}	      /* Set mips_optimize around the lui instruction to avoid		 inserting an unnecessary nop after the lw.  */	      hold_mips_optimize = mips_optimize;	      mips_optimize = 2;	      macro_build_lui ((char *) NULL, &icnt, &expr1, AT);	      mips_optimize = hold_mips_optimize;	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", AT, AT, (int) BFD_RELOC_LO16);	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", tempreg, tempreg, AT);	      (void) frag_var (rs_machine_dependent, 0, 0,			       RELAX_ENCODE (0, 0, -16 + off1, -8, 0, 0),			       offset_expr.X_add_symbol, (offsetT) 0,			       (char *) NULL);	      used_at = 1;	    }	}      else if (mips_pic == SVR4_PIC)	{	  int gpdel;	  /* This is the large GOT case.  If this is a reference to an	     external symbol, and there is no constant, we want	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	       addu	$tempreg,$tempreg,$gp	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)	     For a local symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)	     If we have a small constant, and this is a reference to	     an external symbol, we want	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	       addu	$tempreg,$tempreg,$gp	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)	       nop	       addiu	$tempreg,$tempreg,<constant>	     For a local symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<constant> (BFD_RELOC_LO16)	     If we have a large constant, and this is a reference to	     an external symbol, we want	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	       addu	$tempreg,$tempreg,$gp	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)	       lui	$at,<hiconstant>	       addiu	$at,$at,<loconstant>	       addu	$tempreg,$tempreg,$at	     For a local symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       lui	$at,<hiconstant>	       addiu	$at,$at,<loconstant>	(BFD_RELOC_LO16)	       addu	$tempreg,$tempreg,$at	     */	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  frag_grow (52);	  if (reg_needs_delay (GP))	    gpdel = 4;	  else	    gpdel = 0;	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",		       tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addu" : "daddu"),		       "d,v,t", tempreg, tempreg, GP);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       dbl ? "ld" : "lw",		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,		       tempreg);	  if (expr1.X_add_number == 0)	    {	      int off;	      if (breg == 0)		off = 0;	      else		{		  /* We're going to put in an addu instruction using		     tempreg, so we may as well insert the nop right		     now.  */		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       "nop", "");		  off = 4;		}	      p = frag_var (rs_machine_dependent, 12 + gpdel, 0,			    RELAX_ENCODE (12 + off, 12 + gpdel, gpdel,					  8 + gpdel, 0,					  (breg == 0					   ? mips_opts.warn_about_macros					   : 0)),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	    }	  else if (expr1.X_add_number >= -0x8000		   && expr1.X_add_number < 0x8000)	    {	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   "nop", "");	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	      p = frag_var (rs_machine_dependent, 12 + gpdel, 0,			    RELAX_ENCODE (20, 12 + gpdel, gpdel, 8 + gpdel, 0,					  (breg == 0					   ? mips_opts.warn_about_macros					   : 0)),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	    }	  else	    {	      int adj, dreg;	      /* If we are going to add in a base register, and the		 target register and the base register are the same,		 then we are using AT as a temporary register.  Since		 we want to load the constant into AT, we add our		 current AT (from the global offset table) and the		 register into the register now, and pretend we were		 not using a base register.  */	      if (breg != treg)		{		  adj = 0;		  dreg = tempreg;		}	      else		{		  assert (tempreg == AT);		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       "nop", "");		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       ((bfd_arch_bits_per_address (stdoutput) == 32				 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))				? "addu" : "daddu"),			       "d,v,t", treg, AT, breg);		  dreg = treg;		  adj = 8;		}	      /* Set mips_optimize around the lui instruction to avoid		 inserting an unnecessary nop after the lw.  */	      hold_mips_optimize = mips_optimize;	      mips_optimize = 2;	      macro_build_lui ((char *) NULL, &icnt, &expr1, AT);	      mips_optimize = hold_mips_optimize;	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", AT, AT, (int) BFD_RELOC_LO16);	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", dreg, dreg, AT);	      p = frag_var (rs_machine_dependent, 16 + gpdel + adj, 0,			    RELAX_ENCODE (24 + adj, 16 + gpdel + adj, gpdel,					  8 + gpdel, 0,					  (breg == 0					   ? mips_opts.warn_about_macros					   : 0)),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	      used_at = 1;	    }	  if (gpdel > 0)	    {	      /* This is needed because this instruction uses $gp, but                 the first instruction on the main stream does not.  */	      macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	      p += 4;	    }	  macro_build (p, &icnt, &offset_expr,		       dbl ? "ld" : "lw",		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);	  p += 4;	  if (expr1.X_add_number >= -0x8000	      && expr1.X_add_number < 0x8000)	    {	      macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	      p += 4;	      macro_build (p, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	      /* FIXME: If add_number is 0, and there was no base                 register, the external symbol case ended with a load,                 so if the symbol turns out to not be external, and                 the next instruction uses tempreg, an unnecessary nop                 will be inserted.  */	    }	  else	    {	      if (breg == treg)		{		  /* We must add in the base register now, as in the                     external symbol case.  */		  assert (tempreg == AT);		  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");		  p += 4;		  macro_build (p, &icnt, (expressionS *) NULL,			       ((bfd_arch_bits_per_address (stdoutput) == 32				 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))				? "addu" : "daddu"),			       "d,v,t", treg, AT, breg);		  p += 4;		  tempreg = treg;		  /* We set breg to 0 because we have arranged to add                     it in in both cases.  */		  breg = 0;		}	      macro_build_lui (p, &icnt, &expr1, AT);	      p += 4;	      macro_build (p, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addiu" : "daddiu"),			   "t,r,j", AT, AT, (int) BFD_RELOC_LO16);	      p += 4;	      macro_build (p, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", tempreg, tempreg, AT);	      p += 4;	    }	}      else if (mips_pic == EMBEDDED_PIC)	{	  /* We use	       addiu	$tempreg,$gp,<sym>	(BFD_RELOC_MIPS_GPREL)	     */	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", tempreg, GP, (int) BFD_RELOC_MIPS_GPREL);	}      else	abort ();      if (breg != 0)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     ((bfd_arch_bits_per_address (stdoutput) == 32		       || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		      ? "addu" : "daddu"),		     "d,v,t", treg, tempreg, breg);      if (! used_at)	return;      break;    case M_J_A:      /* The j instruction may not be used in PIC code, since it	 requires an absolute address.  We convert it to a b	 instruction.  */      if (mips_pic == NO_PIC)	macro_build ((char *) NULL, &icnt, &offset_expr, "j", "a");      else	macro_build ((char *) NULL, &icnt, &offset_expr, "b", "p");      return;      /* The jal instructions must be handled as macros because when	 generating PIC code they expand to multi-instruction	 sequences.  Normally they are simple instructions.  */    case M_JAL_1:      dreg = RA;      /* Fall through.  */    case M_JAL_2:      if (mips_pic == NO_PIC	  || mips_pic == EMBEDDED_PIC)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr",		     "d,s", dreg, sreg);      else if (mips_pic == SVR4_PIC)	{	  if (sreg != PIC_CALL_REG)	    as_warn (_("MIPS PIC call to register other than $25"));      	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "jalr",		       "d,s", dreg, sreg);	  if (mips_cprestore_offset < 0)	    as_warn (_("No .cprestore pseudo-op used in PIC code"));	  else	    {	      expr1.X_add_number = mips_cprestore_offset;	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "lw" : "ld"),			   "t,o(b)", GP, (int) BFD_RELOC_LO16, mips_frame_reg);	    }	}      else	abort ();      return;    case M_JAL_A:      if (mips_pic == NO_PIC)	macro_build ((char *) NULL, &icnt, &offset_expr, "jal", "a");      else if (mips_pic == SVR4_PIC)	{	  /* If this is a reference to an external symbol, and we are	     using a small GOT, we want	       lw	$25,<sym>($gp)		(BFD_RELOC_MIPS_CALL16)	       nop	       jalr	$25	       nop	       lw	$gp,cprestore($sp)	     The cprestore value is set using the .cprestore	     pseudo-op.  If we are using a big GOT, we want	       lui	$25,<sym>		(BFD_RELOC_MIPS_CALL_HI16)	       addu	$25,$25,$gp	       lw	$25,<sym>($25)		(BFD_RELOC_MIPS_CALL_LO16)	       nop	       jalr	$25	       nop	       lw	$gp,cprestore($sp)	     If the symbol is not external, we want	       lw	$25,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$25,$25,<sym>		(BFD_RELOC_LO16)	       jalr	$25	       nop	       lw $gp,cprestore($sp) */	  frag_grow (40);	  if (! mips_big_got)	    {	      macro_build ((char *) NULL, &icnt, &offset_expr,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "lw" : "ld"),			   "t,o(b)", PIC_CALL_REG,			   (int) BFD_RELOC_MIPS_CALL16, GP);	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   "nop", "");	      p = frag_var (rs_machine_dependent, 4, 0,			    RELAX_ENCODE (0, 4, -8, 0, 0, 0),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	    }	  else	    {	      int gpdel;	      if (reg_needs_delay (GP))		gpdel = 4;	      else		gpdel = 0;	      macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",			   PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL_HI16);	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", PIC_CALL_REG, PIC_CALL_REG, GP);	      macro_build ((char *) NULL, &icnt, &offset_expr,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "lw" : "ld"),			   "t,o(b)", PIC_CALL_REG,			   (int) BFD_RELOC_MIPS_CALL_LO16, PIC_CALL_REG);	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   "nop", "");	      p = frag_var (rs_machine_dependent, 12 + gpdel, 0,			    RELAX_ENCODE (16, 12 + gpdel, gpdel, 8 + gpdel,					  0, 0),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	      if (gpdel > 0)		{		  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");		  p += 4;		}	      macro_build (p, &icnt, &offset_expr,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "lw" : "ld"),			   "t,o(b)", PIC_CALL_REG,			   (int) BFD_RELOC_MIPS_GOT16, GP);	      p += 4;	      macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	      p += 4;	    }			   	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			? "addiu" : "daddiu"),		       "t,r,j", PIC_CALL_REG, PIC_CALL_REG,		       (int) BFD_RELOC_LO16);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		       "jalr", "s", PIC_CALL_REG);	  if (mips_cprestore_offset < 0)	    as_warn (_("No .cprestore pseudo-op used in PIC code"));	  else	    {	      if (mips_opts.noreorder)		macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			     "nop", "");	      expr1.X_add_number = mips_cprestore_offset;	      macro_build ((char *) NULL, &icnt, &expr1,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "lw" : "ld"),			   "t,o(b)", GP, (int) BFD_RELOC_LO16,			   mips_frame_reg);	    }	}      else if (mips_pic == EMBEDDED_PIC)	{	  macro_build ((char *) NULL, &icnt, &offset_expr, "bal", "p");	  /* The linker may expand the call to a longer sequence which	     uses $at, so we must break rather than return.  */	  break;	}      else	abort ();      return;    case M_LB_AB:      s = "lb";      goto ld;    case M_LBU_AB:      s = "lbu";      goto ld;    case M_LH_AB:      s = "lh";      goto ld;    case M_LHU_AB:      s = "lhu";      goto ld;    case M_LW_AB:      s = "lw";      goto ld;    case M_LWC0_AB:      s = "lwc0";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LWC1_AB:      s = "lwc1";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LWC2_AB:      s = "lwc2";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LWC3_AB:      s = "lwc3";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LWL_AB:      s = "lwl";      lr = 1;      goto ld;    case M_LWR_AB:      s = "lwr";      lr = 1;      goto ld;    case M_LDC1_AB:      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      s = "ldc1";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LDC2_AB:      s = "ldc2";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LDC3_AB:      s = "ldc3";      /* Itbl support may require additional care here. */      coproc = 1;      goto ld;    case M_LDL_AB:      s = "ldl";      lr = 1;      goto ld;    case M_LDR_AB:      s = "ldr";      lr = 1;      goto ld;    case M_LL_AB:      s = "ll";      goto ld;    case M_LLD_AB:      s = "lld";      goto ld;    case M_LWU_AB:      s = "lwu";    ld:      if (breg == treg || coproc || lr)	{	  tempreg = AT;	  used_at = 1;	}      else	{	  tempreg = treg;	  used_at = 0;	}      goto ld_st;    case M_SB_AB:      s = "sb";      goto st;    case M_SH_AB:      s = "sh";      goto st;    case M_SW_AB:      s = "sw";      goto st;    case M_SWC0_AB:      s = "swc0";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SWC1_AB:      s = "swc1";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SWC2_AB:      s = "swc2";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SWC3_AB:      s = "swc3";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SWL_AB:      s = "swl";      goto st;    case M_SWR_AB:      s = "swr";      goto st;    case M_SC_AB:      s = "sc";      goto st;    case M_SCD_AB:      s = "scd";      goto st;    case M_SDC1_AB:      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      s = "sdc1";      coproc = 1;      /* Itbl support may require additional care here. */      goto st;    case M_SDC2_AB:      s = "sdc2";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SDC3_AB:      s = "sdc3";      /* Itbl support may require additional care here. */      coproc = 1;      goto st;    case M_SDL_AB:      s = "sdl";      goto st;    case M_SDR_AB:      s = "sdr";    st:      tempreg = AT;      used_at = 1;    ld_st:      /* Itbl support may require additional care here. */      if (mask == M_LWC1_AB	  || mask == M_SWC1_AB	  || mask == M_LDC1_AB	  || mask == M_SDC1_AB	  || mask == M_L_DAB	  || mask == M_S_DAB)	fmt = "T,o(b)";      else if (coproc)	fmt = "E,o(b)";      else	fmt = "t,o(b)";      if (offset_expr.X_op != O_constant	  && offset_expr.X_op != O_symbol)	{	  as_bad (_("expression too complex"));	  offset_expr.X_op = O_constant;	}      /* A constant expression in PIC code can be handled just as it	 is in non PIC code.  */      if (mips_pic == NO_PIC	  || offset_expr.X_op == O_constant)	{	  /* If this is a reference to a GP relative symbol, and there	     is no base register, we want	       <op>	$treg,<sym>($gp)	(BFD_RELOC_MIPS_GPREL)	     Otherwise, if there is no base register, we want	       lui	$tempreg,<sym>		(BFD_RELOC_HI16_S)	       <op>	$treg,<sym>($tempreg)	(BFD_RELOC_LO16)	     If we have a constant, we need two instructions anyhow,	     so we always use the latter form.	     If we have a base register, and this is a reference to a	     GP relative symbol, we want	       addu	$tempreg,$breg,$gp	       <op>	$treg,<sym>($tempreg)	(BFD_RELOC_MIPS_GPREL)	     Otherwise we want	       lui	$tempreg,<sym>		(BFD_RELOC_HI16_S)	       addu	$tempreg,$tempreg,$breg	       <op>	$treg,<sym>($tempreg)	(BFD_RELOC_LO16)	     With a constant we always use the latter case.  */	  if (breg == 0)	    {	      if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET		  || nopic_need_relax (offset_expr.X_add_symbol, 1))		p = NULL;	      else		{		  frag_grow (20);		  macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			       treg, (int) BFD_RELOC_MIPS_GPREL, GP);		  p = frag_var (rs_machine_dependent, 8, 0,				RELAX_ENCODE (4, 8, 0, 4, 0,					      (mips_opts.warn_about_macros					       || (used_at						   && mips_opts.noat))),				offset_expr.X_add_symbol, (offsetT) 0,				(char *) NULL);		  used_at = 0;		}	      macro_build_lui (p, &icnt, &offset_expr, tempreg);	      if (p != NULL)		p += 4;	      macro_build (p, &icnt, &offset_expr, s, fmt, treg,			   (int) BFD_RELOC_LO16, tempreg);	    }	  else	    {	      if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET		  || nopic_need_relax (offset_expr.X_add_symbol, 1))		p = NULL;	      else		{		  frag_grow (28);		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       ((bfd_arch_bits_per_address (stdoutput) == 32				 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))				? "addu" : "daddu"),			       "d,v,t", tempreg, breg, GP);		  macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			       treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);		  p = frag_var (rs_machine_dependent, 12, 0,				RELAX_ENCODE (8, 12, 0, 8, 0, 0),				offset_expr.X_add_symbol, (offsetT) 0,				(char *) NULL);		}	      macro_build_lui (p, &icnt, &offset_expr, tempreg);	      if (p != NULL)		p += 4;	      macro_build (p, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", tempreg, tempreg, breg);	      if (p != NULL)		p += 4;	      macro_build (p, &icnt, &offset_expr, s, fmt, treg,			   (int) BFD_RELOC_LO16, tempreg);	    }	}      else if (mips_pic == SVR4_PIC && ! mips_big_got)	{	  /* If this is a reference to an external symbol, we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       <op>	$treg,0($tempreg)	     Otherwise we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)	       <op>	$treg,0($tempreg)	     If there is a base register, we add it to $tempreg before	     the <op>.  If there is a constant, we stick it in the	     <op> instruction.  We don't handle constants larger than	     16 bits, because we have no way to load the upper 16 bits	     (actually, we could handle them for the subset of cases	     in which we are not using $at).  */	  assert (offset_expr.X_op == O_symbol);	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  if (expr1.X_add_number < -0x8000	      || expr1.X_add_number >= 0x8000)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  frag_grow (20);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");	  p = frag_var (rs_machine_dependent, 4, 0, 			RELAX_ENCODE (0, 4, -8, 0, 0, 0),			offset_expr.X_add_symbol, (offsetT) 0,			(char *) NULL);	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	  if (breg != 0)	    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			 ((bfd_arch_bits_per_address (stdoutput) == 32			   || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			  ? "addu" : "daddu"),			 "d,v,t", tempreg, tempreg, breg);	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,		       (int) BFD_RELOC_LO16, tempreg);	}      else if (mips_pic == SVR4_PIC)	{	  int gpdel;	  /* If this is a reference to an external symbol, we want	       lui	$tempreg,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	       addu	$tempreg,$tempreg,$gp	       lw	$tempreg,<sym>($tempreg) (BFD_RELOC_MIPS_GOT_LO16)	       <op>	$treg,0($tempreg)	     Otherwise we want	       lw	$tempreg,<sym>($gp)	(BFD_RELOC_MIPS_GOT16)	       nop	       addiu	$tempreg,$tempreg,<sym>	(BFD_RELOC_LO16)	       <op>	$treg,0($tempreg)	     If there is a base register, we add it to $tempreg before	     the <op>.  If there is a constant, we stick it in the	     <op> instruction.  We don't handle constants larger than	     16 bits, because we have no way to load the upper 16 bits	     (actually, we could handle them for the subset of cases	     in which we are not using $at).  */	  assert (offset_expr.X_op == O_symbol);	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  if (expr1.X_add_number < -0x8000	      || expr1.X_add_number >= 0x8000)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  if (reg_needs_delay (GP))	    gpdel = 4;	  else	    gpdel = 0;	  frag_grow (36);	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",		       tempreg, (int) BFD_RELOC_MIPS_GOT_HI16);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addu" : "daddu"),		       "d,v,t", tempreg, tempreg, GP);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT_LO16,		       tempreg);	  p = frag_var (rs_machine_dependent, 12 + gpdel, 0,			RELAX_ENCODE (12, 12 + gpdel, gpdel, 8 + gpdel, 0, 0),			offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL);	  if (gpdel > 0)	    {	      macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	      p += 4;	    }	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP);	  p += 4;	  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	  p += 4;	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16);	  if (breg != 0)	    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			 ((bfd_arch_bits_per_address (stdoutput) == 32			   || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			  ? "addu" : "daddu"),			 "d,v,t", tempreg, tempreg, breg);	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt, treg,		       (int) BFD_RELOC_LO16, tempreg);	}      else if (mips_pic == EMBEDDED_PIC)	{	  /* If there is no base register, we want	       <op>	$treg,<sym>($gp)	(BFD_RELOC_MIPS_GPREL)	     If there is a base register, we want	       addu	$tempreg,$breg,$gp	       <op>	$treg,<sym>($tempreg)	(BFD_RELOC_MIPS_GPREL)	     */	  assert (offset_expr.X_op == O_symbol);	  if (breg == 0)	    {	      macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			   treg, (int) BFD_RELOC_MIPS_GPREL, GP);	      used_at = 0;	    }	  else	    {	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", tempreg, breg, GP);	      macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			   treg, (int) BFD_RELOC_MIPS_GPREL, tempreg);	    }	}      else	abort ();      if (! used_at)	return;      break;    case M_LI:    case M_LI_S:      load_register (&icnt, treg, &imm_expr, 0);      return;    case M_DLI:      load_register (&icnt, treg, &imm_expr, 1);      return;    case M_LI_SS:      if (imm_expr.X_op == O_constant)	{	  load_register (&icnt, AT, &imm_expr, 0);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		       "mtc1", "t,G", AT, treg);	  break;	}      else	{	  assert (offset_expr.X_op == O_symbol		  && strcmp (segment_name (S_GET_SEGMENT					   (offset_expr.X_add_symbol)),			     ".lit4") == 0		  && offset_expr.X_add_number == 0);	  macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",		       treg, (int) BFD_RELOC_MIPS_LITERAL, GP);	  return;	}    case M_LI_D:      /* If we have a constant in IMM_EXPR, then in mips3 mode it is         the entire value, and in mips1 mode it is the high order 32         bits of the value and the low order 32 bits are either zero         or in offset_expr.  */      if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)	{	  if (ISA_HAS_64BIT_REGS (mips_opts.isa))	    load_register (&icnt, treg, &imm_expr, 1);	  else	    {	      int hreg, lreg;	      if (target_big_endian)		{		  hreg = treg;		  lreg = treg + 1;		}	      else		{		  hreg = treg + 1;		  lreg = treg;		}	      if (hreg <= 31)		load_register (&icnt, hreg, &imm_expr, 0);	      if (lreg <= 31)		{		  if (offset_expr.X_op == O_absent)		    macro_build ((char *) NULL, &icnt, NULL, "move", "d,s",				 lreg, 0);		  else		    {		      assert (offset_expr.X_op == O_constant);		      load_register (&icnt, lreg, &offset_expr, 0);		    }		}	    }	  return;	}      /* We know that sym is in the .rdata section.  First we get the	 upper 16 bits of the address.  */      if (mips_pic == NO_PIC)	{	  /* FIXME: This won't work for a 64 bit address.  */	  macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);	}      else if (mips_pic == SVR4_PIC)	{	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);	}      else if (mips_pic == EMBEDDED_PIC)	{	  /* For embedded PIC we pick up the entire address off $gp in	     a single instruction.  */	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", AT, GP, (int) BFD_RELOC_MIPS_GPREL);	  offset_expr.X_op = O_constant;	  offset_expr.X_add_number = 0;	}      else	abort ();	      /* Now we load the register(s).  */      if (ISA_HAS_64BIT_REGS (mips_opts.isa))	macro_build ((char *) NULL, &icnt, &offset_expr, "ld", "t,o(b)",		     treg, (int) BFD_RELOC_LO16, AT);      else	{	  macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",		       treg, (int) BFD_RELOC_LO16, AT);	  if (treg != 31)	    {	      /* FIXME: How in the world do we deal with the possible		 overflow here?  */	      offset_expr.X_add_number += 4;	      macro_build ((char *) NULL, &icnt, &offset_expr, "lw", "t,o(b)",			   treg + 1, (int) BFD_RELOC_LO16, AT);	    }	}      /* To avoid confusion in tc_gen_reloc, we must ensure that this	 does not become a variant frag.  */      frag_wane (frag_now);      frag_new (0);      break;    case M_LI_DD:      /* If we have a constant in IMM_EXPR, then in mips3 mode it is         the entire value, and in mips1 mode it is the high order 32         bits of the value and the low order 32 bits are either zero         or in offset_expr.  */      if (imm_expr.X_op == O_constant || imm_expr.X_op == O_big)	{	  load_register (&icnt, AT, &imm_expr, ISA_HAS_64BIT_REGS (mips_opts.isa));	  if (ISA_HAS_64BIT_REGS (mips_opts.isa))	    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			 "dmtc1", "t,S", AT, treg);	  else	    {	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   "mtc1", "t,G", AT, treg + 1);	      if (offset_expr.X_op == O_absent)		macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			     "mtc1", "t,G", 0, treg);	      else		{		  assert (offset_expr.X_op == O_constant);		  load_register (&icnt, AT, &offset_expr, 0);		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       "mtc1", "t,G", AT, treg);		}	    }	  break;	}      assert (offset_expr.X_op == O_symbol	      && offset_expr.X_add_number == 0);      s = segment_name (S_GET_SEGMENT (offset_expr.X_add_symbol));      if (strcmp (s, ".lit8") == 0)	{	  if (mips_opts.isa != 1)	    {	      macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",			   "T,o(b)", treg, (int) BFD_RELOC_MIPS_LITERAL, GP);	      return;	    }	  breg = GP;	  r = BFD_RELOC_MIPS_LITERAL;	  goto dob;	}      else	{	  assert (strcmp (s, RDATA_SECTION_NAME) == 0);	  if (mips_pic == SVR4_PIC)	    macro_build ((char *) NULL, &icnt, &offset_expr,			 ((bfd_arch_bits_per_address (stdoutput) == 32			   || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			  ? "lw" : "ld"),			 "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);	  else	    {	      /* FIXME: This won't work for a 64 bit address.  */	      macro_build_lui ((char *) NULL, &icnt, &offset_expr, AT);	    }	      	  if (mips_opts.isa != 1)	    {	      macro_build ((char *) NULL, &icnt, &offset_expr, "ldc1",			   "T,o(b)", treg, (int) BFD_RELOC_LO16, AT);	      /* To avoid confusion in tc_gen_reloc, we must ensure		 that this does not become a variant frag.  */	      frag_wane (frag_now);	      frag_new (0);	      break;	    }	  breg = AT;	  r = BFD_RELOC_LO16;	  goto dob;	}    case M_L_DOB:      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      /* Even on a big endian machine $fn comes before $fn+1.  We have	 to adjust when loading from memory.  */      r = BFD_RELOC_LO16;    dob:      assert (mips_opts.isa == 1);      macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",		   target_big_endian ? treg + 1 : treg,		   (int) r, breg);      /* FIXME: A possible overflow which I don't know how to deal	 with.  */      offset_expr.X_add_number += 4;      macro_build ((char *) NULL, &icnt, &offset_expr, "lwc1", "T,o(b)",		   target_big_endian ? treg : treg + 1,		   (int) r, breg);      /* To avoid confusion in tc_gen_reloc, we must ensure that this	 does not become a variant frag.  */      frag_wane (frag_now);      frag_new (0);      if (breg != AT)	return;      break;    case M_L_DAB:      /*       * The MIPS assembler seems to check for X_add_number not       * being double aligned and generating:       *	lui	at,%hi(foo+1)       *	addu	at,at,v1       *	addiu	at,at,%lo(foo+1)       *	lwc1	f2,0(at)       *	lwc1	f3,4(at)       * But, the resulting address is the same after relocation so why       * generate the extra instruction?       */      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      /* Itbl support may require additional care here. */      coproc = 1;      if (mips_opts.isa != 1)	{	  s = "ldc1";	  goto ld;	}      s = "lwc1";      fmt = "T,o(b)";      goto ldd_std;    case M_S_DAB:      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      if (mips_opts.isa != 1)	{	  s = "sdc1";	  goto st;	}      s = "swc1";      fmt = "T,o(b)";      /* Itbl support may require additional care here. */      coproc = 1;      goto ldd_std;    case M_LD_AB:      if (ISA_HAS_64BIT_REGS (mips_opts.isa))	{	  s = "ld";	  goto ld;	}      s = "lw";      fmt = "t,o(b)";      goto ldd_std;    case M_SD_AB:      if (ISA_HAS_64BIT_REGS (mips_opts.isa))	{	  s = "sd";	  goto st;	}      s = "sw";      fmt = "t,o(b)";    ldd_std:      if (offset_expr.X_op != O_symbol	  && offset_expr.X_op != O_constant)	{	  as_bad (_("expression too complex"));	  offset_expr.X_op = O_constant;	}      /* Even on a big endian machine $fn comes before $fn+1.  We have	 to adjust when loading from memory.  We set coproc if we must	 load $fn+1 first.  */      /* Itbl support may require additional care here. */      if (! target_big_endian)	coproc = 0;      if (mips_pic == NO_PIC	  || offset_expr.X_op == O_constant)	{	  /* If this is a reference to a GP relative symbol, we want	       <op>	$treg,<sym>($gp)	(BFD_RELOC_MIPS_GPREL)	       <op>	$treg+1,<sym>+4($gp)	(BFD_RELOC_MIPS_GPREL)	     If we have a base register, we use this	       addu	$at,$breg,$gp	       <op>	$treg,<sym>($at)	(BFD_RELOC_MIPS_GPREL)	       <op>	$treg+1,<sym>+4($at)	(BFD_RELOC_MIPS_GPREL)	     If this is not a GP relative symbol, we want	       lui	$at,<sym>		(BFD_RELOC_HI16_S)	       <op>	$treg,<sym>($at)	(BFD_RELOC_LO16)	       <op>	$treg+1,<sym>+4($at)	(BFD_RELOC_LO16)	     If there is a base register, we add it to $at after the	     lui instruction.  If there is a constant, we always use	     the last case.  */	  if ((valueT) offset_expr.X_add_number >= MAX_GPREL_OFFSET	      || nopic_need_relax (offset_expr.X_add_symbol, 1))	    {	      p = NULL;	      used_at = 1;	    }	  else	    {	      int off;	      if (breg == 0)		{		  frag_grow (28);		  tempreg = GP;		  off = 0;		  used_at = 0;		}	      else		{		  frag_grow (36);		  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			       ((bfd_arch_bits_per_address (stdoutput) == 32				 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))				? "addu" : "daddu"),			       "d,v,t", AT, breg, GP);		  tempreg = AT;		  off = 4;		  used_at = 1;		}              /* Itbl support may require additional care here. */	      macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			   coproc ? treg + 1 : treg,			   (int) BFD_RELOC_MIPS_GPREL, tempreg);	      offset_expr.X_add_number += 4;	      /* Set mips_optimize to 2 to avoid inserting an                 undesired nop.  */	      hold_mips_optimize = mips_optimize;	      mips_optimize = 2;              /* Itbl support may require additional care here. */	      macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,			   coproc ? treg : treg + 1,			   (int) BFD_RELOC_MIPS_GPREL, tempreg);	      mips_optimize = hold_mips_optimize;	      p = frag_var (rs_machine_dependent, 12 + off, 0,			    RELAX_ENCODE (8 + off, 12 + off, 0, 4 + off, 1,					  used_at && mips_opts.noat),			    offset_expr.X_add_symbol, (offsetT) 0,			    (char *) NULL);	      /* We just generated two relocs.  When tc_gen_reloc		 handles this case, it will skip the first reloc and		 handle the second.  The second reloc already has an		 extra addend of 4, which we added above.  We must		 subtract it out, and then subtract another 4 to make		 the first reloc come out right.  The second reloc		 will come out right because we are going to add 4 to		 offset_expr when we build its instruction below.		 If we have a symbol, then we don't want to include		 the offset, because it will wind up being included		 when we generate the reloc.  */	      if (offset_expr.X_op == O_constant)		offset_expr.X_add_number -= 8;	      else		{		  offset_expr.X_add_number = -4;		  offset_expr.X_op = O_constant;		}	    }	  macro_build_lui (p, &icnt, &offset_expr, AT);	  if (p != NULL)	    p += 4;	  if (breg != 0)	    {	      macro_build (p, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", AT, breg, AT);	      if (p != NULL)		p += 4;	    }          /* Itbl support may require additional care here. */	  macro_build (p, &icnt, &offset_expr, s, fmt,		       coproc ? treg + 1 : treg,		       (int) BFD_RELOC_LO16, AT);	  if (p != NULL)	    p += 4;	  /* FIXME: How do we handle overflow here?  */	  offset_expr.X_add_number += 4;          /* Itbl support may require additional care here. */	  macro_build (p, &icnt, &offset_expr, s, fmt,		       coproc ? treg : treg + 1,		       (int) BFD_RELOC_LO16, AT);	}	        else if (mips_pic == SVR4_PIC && ! mips_big_got)	{	  int off;	  /* If this is a reference to an external symbol, we want	       lw	$at,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	       nop	       <op>	$treg,0($at)	       <op>	$treg+1,4($at)	     Otherwise we want	       lw	$at,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	       nop	       <op>	$treg,<sym>($at)	(BFD_RELOC_LO16)	       <op>	$treg+1,<sym>+4($at)	(BFD_RELOC_LO16)	     If there is a base register we add it to $at before the	     lwc1 instructions.  If there is a constant we include it	     in the lwc1 instructions.  */	  used_at = 1;	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  if (expr1.X_add_number < -0x8000	      || expr1.X_add_number >= 0x8000 - 4)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  if (breg == 0)	    off = 0;	  else	    off = 4;	  frag_grow (24 + off);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");	  if (breg != 0)	    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			 ((bfd_arch_bits_per_address (stdoutput) == 32			   || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			  ? "addu" : "daddu"),			 "d,v,t", AT, breg, AT);          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt,		       coproc ? treg + 1 : treg,		       (int) BFD_RELOC_LO16, AT);	  expr1.X_add_number += 4;	  /* Set mips_optimize to 2 to avoid inserting an undesired             nop.  */	  hold_mips_optimize = mips_optimize;	  mips_optimize = 2;          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt,		       coproc ? treg : treg + 1,		       (int) BFD_RELOC_LO16, AT);	  mips_optimize = hold_mips_optimize;	  (void) frag_var (rs_machine_dependent, 0, 0,			   RELAX_ENCODE (0, 0, -16 - off, -8, 1, 0),			   offset_expr.X_add_symbol, (offsetT) 0,			   (char *) NULL);	}      else if (mips_pic == SVR4_PIC)	{	  int gpdel, off;	  /* If this is a reference to an external symbol, we want	       lui	$at,<sym>		(BFD_RELOC_MIPS_GOT_HI16)	       addu	$at,$at,$gp	       lw	$at,<sym>($at)		(BFD_RELOC_MIPS_GOT_LO16)	       nop	       <op>	$treg,0($at)	       <op>	$treg+1,4($at)	     Otherwise we want	       lw	$at,<sym>($gp)		(BFD_RELOC_MIPS_GOT16)	       nop	       <op>	$treg,<sym>($at)	(BFD_RELOC_LO16)	       <op>	$treg+1,<sym>+4($at)	(BFD_RELOC_LO16)	     If there is a base register we add it to $at before the	     lwc1 instructions.  If there is a constant we include it	     in the lwc1 instructions.  */	  used_at = 1;	  expr1.X_add_number = offset_expr.X_add_number;	  offset_expr.X_add_number = 0;	  if (expr1.X_add_number < -0x8000	      || expr1.X_add_number >= 0x8000 - 4)	    as_bad (_("PIC code offset overflow (max 16 signed bits)"));	  if (reg_needs_delay (GP))	    gpdel = 4;	  else	    gpdel = 0;	  if (breg == 0)	    off = 0;	  else	    off = 4;	  frag_grow (56);	  macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",		       AT, (int) BFD_RELOC_MIPS_GOT_HI16);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addu" : "daddu"),		       "d,v,t", AT, AT, GP);	  macro_build ((char *) NULL, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT_LO16, AT);	  macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", "");	  if (breg != 0)	    macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			 ((bfd_arch_bits_per_address (stdoutput) == 32			   || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			  ? "addu" : "daddu"),			 "d,v,t", AT, breg, AT);          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt,		       coproc ? treg + 1 : treg,		       (int) BFD_RELOC_LO16, AT);	  expr1.X_add_number += 4;	  /* Set mips_optimize to 2 to avoid inserting an undesired             nop.  */	  hold_mips_optimize = mips_optimize;	  mips_optimize = 2;          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &expr1, s, fmt,		       coproc ? treg : treg + 1,		       (int) BFD_RELOC_LO16, AT);	  mips_optimize = hold_mips_optimize;	  expr1.X_add_number -= 4;	  p = frag_var (rs_machine_dependent, 16 + gpdel + off, 0,			RELAX_ENCODE (24 + off, 16 + gpdel + off, gpdel,				      8 + gpdel + off, 1, 0),			offset_expr.X_add_symbol, (offsetT) 0,			(char *) NULL);	  if (gpdel > 0)	    {	      macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	      p += 4;	    }	  macro_build (p, &icnt, &offset_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "lw" : "ld"),		       "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP);	  p += 4;	  macro_build (p, &icnt, (expressionS *) NULL, "nop", "");	  p += 4;	  if (breg != 0)	    {	      macro_build (p, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", AT, breg, AT);	      p += 4;	    }          /* Itbl support may require additional care here. */	  macro_build (p, &icnt, &expr1, s, fmt,		       coproc ? treg + 1 : treg,		       (int) BFD_RELOC_LO16, AT);	  p += 4;	  expr1.X_add_number += 4;	  /* Set mips_optimize to 2 to avoid inserting an undesired             nop.  */	  hold_mips_optimize = mips_optimize;	  mips_optimize = 2;          /* Itbl support may require additional care here. */	  macro_build (p, &icnt, &expr1, s, fmt,		       coproc ? treg : treg + 1,		       (int) BFD_RELOC_LO16, AT);	  mips_optimize = hold_mips_optimize;	}      else if (mips_pic == EMBEDDED_PIC)	{	  /* If there is no base register, we use	       <op>	$treg,<sym>($gp)	(BFD_RELOC_MIPS_GPREL)	       <op>	$treg+1,<sym>+4($gp)	(BFD_RELOC_MIPS_GPREL)	     If we have a base register, we use	       addu	$at,$breg,$gp	       <op>	$treg,<sym>($at)	(BFD_RELOC_MIPS_GPREL)	       <op>	$treg+1,<sym>+4($at)	(BFD_RELOC_MIPS_GPREL)	     */	  if (breg == 0)	    {	      tempreg = GP;	      used_at = 0;	    }	  else	    {	      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,			   ((bfd_arch_bits_per_address (stdoutput) == 32			     || ! ISA_HAS_64BIT_REGS (mips_opts.isa))			    ? "addu" : "daddu"),			   "d,v,t", AT, breg, GP);	      tempreg = AT;	      used_at = 1;	    }          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,		       coproc ? treg + 1 : treg,		       (int) BFD_RELOC_MIPS_GPREL, tempreg);	  offset_expr.X_add_number += 4;          /* Itbl support may require additional care here. */	  macro_build ((char *) NULL, &icnt, &offset_expr, s, fmt,		       coproc ? treg : treg + 1,		       (int) BFD_RELOC_MIPS_GPREL, tempreg);	}      else	abort ();      if (! used_at)	return;      break;    case M_LD_OB:      s = "lw";      goto sd_ob;    case M_SD_OB:      s = "sw";    sd_ob:      assert (bfd_arch_bits_per_address (stdoutput) == 32 	      || ! ISA_HAS_64BIT_REGS (mips_opts.isa));      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      offset_expr.X_add_number += 4;      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg + 1,		   (int) BFD_RELOC_LO16, breg);      return;   /* New code added to support COPZ instructions.      This code builds table entries out of the macros in mip_opcodes.      R4000 uses interlocks to handle coproc delays.      Other chips (like the R3000) require nops to be inserted for delays.      FIXME: Currently, we require that the user handle delays.      In order to fill delay slots for non-interlocked chips,      we must have a way to specify delays based on the coprocessor.      Eg. 4 cycles if load coproc reg from memory, 1 if in cache, etc.      What are the side-effects of the cop instruction?      What cache support might we have and what are its effects?      Both coprocessor & memory require delays. how long???      What registers are read/set/modified?       If an itbl is provided to interpret cop instructions,      this knowledge can be encoded in the itbl spec. */    case M_COP0:      s = "c0";      goto copz;    case M_COP1:      s = "c1";      goto copz;    case M_COP2:      s = "c2";      goto copz;    case M_COP3:      s = "c3";    copz:      /* For now we just do C (same as Cz).  The parameter will be         stored in insn_opcode by mips_ip.  */      macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s, "C",		   ip->insn_opcode);      return;#ifdef LOSING_COMPILER    default:      /* Try and see if this is a new itbl instruction.         This code builds table entries out of the macros in mip_opcodes.         FIXME: For now we just assemble the expression and pass it's         value along as a 32-bit immediate.         We may want to have the assembler assemble this value,          so that we gain the assembler's knowledge of delay slots,         symbols, etc.         Would it be more efficient to use mask (id) here? */      if (itbl_have_entries 	  && (immed_expr = itbl_assemble (ip->insn_mo->name, "")))        {	  s = ip->insn_mo->name;	  s2 = "cop3";	  coproc = ITBL_DECODE_PNUM (immed_expr);;	  macro_build ((char *) NULL, &icnt, &immed_expr, s, "C");	  return;        }      macro2 (ip);      return;    }  if (mips_opts.noat)    as_warn (_("Macro used $at after \".set noat\""));}          static voidmacro2 (ip)     struct mips_cl_insn *ip;{  register int treg, sreg, dreg, breg;  int tempreg;  int mask;  int icnt = 0;  int used_at;  expressionS expr1;  const char *s;  const char *s2;  const char *fmt;  int likely = 0;  int dbl = 0;  int coproc = 0;  int lr = 0;  int imm = 0;  int off;  offsetT maxnum;  bfd_reloc_code_real_type r;  char *p;            treg = (ip->insn_opcode >> 16) & 0x1f;  dreg = (ip->insn_opcode >> 11) & 0x1f;  sreg = breg = (ip->insn_opcode >> 21) & 0x1f;  mask = ip->insn_mo->mask;            expr1.X_op = O_constant;  expr1.X_op_symbol = NULL;  expr1.X_add_symbol = NULL;  expr1.X_add_number = 1;            switch (mask)    {#endif /* LOSING_COMPILER */    case M_DMUL:      dbl = 1;    case M_MUL:      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dmultu" : "multu",		   "s,t", sreg, treg);      macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);      return;    case M_DMUL_I:      dbl = 1;    case M_MUL_I:      /* The MIPS assembler some times generates shifts and adds.  I'm	 not trying to be that fancy. GCC should do this for us	 anyway.  */      load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dmult" : "mult",		   "s,t", sreg, AT);      macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);      break;    case M_DMULO_I:      dbl = 1;    case M_MULO_I:      imm = 1;      goto do_mulo;    case M_DMULO:      dbl = 1;    case M_MULO:    do_mulo:      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      if (imm)	load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dmult" : "mult",		   "s,t", sreg, imm ? AT : treg);      macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dsra32" : "sra",		   "d,w,<", dreg, dreg, 31);      macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);      if (mips_trap)	macro_build ((char *) NULL, &icnt, NULL, "tne", "s,t", dreg, AT);      else	{	  expr1.X_add_number = 8;	  macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", dreg, AT);	  macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);	    macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);	}      --mips_opts.noreorder;      macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);      break;    case M_DMULOU_I:      dbl = 1;    case M_MULOU_I:      imm = 1;      goto do_mulou;    case M_DMULOU:      dbl = 1;    case M_MULOU:    do_mulou:      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      if (imm)	load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dmultu" : "multu",		   "s,t", sreg, imm ? AT : treg);      macro_build ((char *) NULL, &icnt, NULL, "mfhi", "d", AT);      macro_build ((char *) NULL, &icnt, NULL, "mflo", "d", dreg);      if (mips_trap)	macro_build ((char *) NULL, &icnt, NULL, "tne", "s,t", AT, 0);      else	{	  expr1.X_add_number = 8;	  macro_build ((char *) NULL, &icnt, &expr1, "beq", "s,t,p", AT, 0);	  macro_build ((char *) NULL, &icnt, NULL, "nop", "", 0);	    macro_build ((char *) NULL, &icnt, NULL, "break", "c", 6);	}      --mips_opts.noreorder;      break;    case M_ROL:      macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);      macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", AT, sreg, AT);      macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", dreg, sreg,		   treg);      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);      break;    case M_ROL_I:      if (imm_expr.X_op != O_constant)	as_bad (_("rotate count too large"));      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", AT, sreg,		   (int) (imm_expr.X_add_number & 0x1f));      macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", dreg, sreg,		   (int) ((0 - imm_expr.X_add_number) & 0x1f));      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);      break;    case M_ROR:      macro_build ((char *) NULL, &icnt, NULL, "subu", "d,v,t", AT, 0, treg);      macro_build ((char *) NULL, &icnt, NULL, "sllv", "d,t,s", AT, sreg, AT);      macro_build ((char *) NULL, &icnt, NULL, "srlv", "d,t,s", dreg, sreg,		   treg);      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);      break;    case M_ROR_I:      if (imm_expr.X_op != O_constant)	as_bad (_("rotate count too large"));      macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, sreg,		   (int) (imm_expr.X_add_number & 0x1f));      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", dreg, sreg,		   (int) ((0 - imm_expr.X_add_number) & 0x1f));      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", dreg, dreg, AT);      break;    case M_S_DOB:      if (mips_cpu == 4650)	{	  as_bad (_("opcode not supported on this processor"));	  return;	}      assert (mips_opts.isa == 1);      /* Even on a big endian machine $fn comes before $fn+1.  We have	 to adjust when storing to memory.  */      macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",		   target_big_endian ? treg + 1 : treg,		   (int) BFD_RELOC_LO16, breg);      offset_expr.X_add_number += 4;      macro_build ((char *) NULL, &icnt, &offset_expr, "swc1", "T,o(b)",		   target_big_endian ? treg : treg + 1,		   (int) BFD_RELOC_LO16, breg);      return;    case M_SEQ:      if (sreg == 0)	macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,		     treg, (int) BFD_RELOC_LO16);      else if (treg == 0)	macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,		     sreg, (int) BFD_RELOC_LO16);      else	{	  macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,		       sreg, treg);	  macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,		       dreg, (int) BFD_RELOC_LO16);	}      return;    case M_SEQ_I:      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg,		       sreg, (int) BFD_RELOC_LO16);	  return;	}      if (sreg == 0)	{	  as_warn (_("Instruction %s: result is always false"),		   ip->insn_mo->name);	  macro_build ((char *) NULL, &icnt, NULL, "move", "d,s", dreg, 0);	  return;	}      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= 0	  && imm_expr.X_add_number < 0x10000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i", dreg,		       sreg, (int) BFD_RELOC_LO16);	  used_at = 0;	}      else if (imm_expr.X_op == O_constant	       && imm_expr.X_add_number > -0x8000	       && imm_expr.X_add_number < 0)	{	  imm_expr.X_add_number = -imm_expr.X_add_number;	  macro_build ((char *) NULL, &icnt, &imm_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", dreg, sreg,		       (int) BFD_RELOC_LO16);	  used_at = 0;	}      else	{	  load_register (&icnt, AT, &imm_expr, 0);	  macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,		       sreg, AT);	  used_at = 1;	}      macro_build ((char *) NULL, &icnt, &expr1, "sltiu", "t,r,j", dreg, dreg,		   (int) BFD_RELOC_LO16);      if (used_at)	break;      return;    case M_SGE:		/* sreg >= treg <==> not (sreg < treg) */      s = "slt";      goto sge;    case M_SGEU:      s = "sltu";    sge:      macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, sreg, treg);      macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,		   (int) BFD_RELOC_LO16);      return;    case M_SGE_I:		/* sreg >= I <==> not (sreg < I) */    case M_SGEU_I:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= -0x8000	  && imm_expr.X_add_number < 0x8000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr,		       mask == M_SGE_I ? "slti" : "sltiu",		       "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);	  used_at = 0;	}      else	{	  load_register (&icnt, AT, &imm_expr, 0);	  macro_build ((char *) NULL, &icnt, NULL,		       mask == M_SGE_I ? "slt" : "sltu",		       "d,v,t", dreg, sreg, AT);	  used_at = 1;	}      macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,		   (int) BFD_RELOC_LO16);      if (used_at)	break;      return;    case M_SGT:		/* sreg > treg  <==>  treg < sreg */      s = "slt";      goto sgt;    case M_SGTU:      s = "sltu";    sgt:      macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);      return;    case M_SGT_I:		/* sreg > I  <==>  I < sreg */      s = "slt";      goto sgti;    case M_SGTU_I:      s = "sltu";    sgti:      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);      break;    case M_SLE:		/* sreg <= treg  <==>  treg >= sreg  <==>  not (treg < sreg) */      s = "slt";      goto sle;    case M_SLEU:      s = "sltu";    sle:      macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, treg, sreg);      macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,		   (int) BFD_RELOC_LO16);      return;    case M_SLE_I:		/* sreg <= I <==> I >= sreg <==> not (I < sreg) */      s = "slt";      goto slei;    case M_SLEU_I:      s = "sltu";    slei:      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, s, "d,v,t", dreg, AT, sreg);      macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", dreg, dreg,		   (int) BFD_RELOC_LO16);      break;    case M_SLT_I:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= -0x8000	  && imm_expr.X_add_number < 0x8000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr, "slti", "t,r,j",		       dreg, sreg, (int) BFD_RELOC_LO16);	  return;	}      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, "slt", "d,v,t", dreg, sreg, AT);      break;    case M_SLTU_I:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= -0x8000	  && imm_expr.X_add_number < 0x8000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr, "sltiu", "t,r,j",		       dreg, sreg, (int) BFD_RELOC_LO16);	  return;	}      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, sreg,		   AT);      break;    case M_SNE:      if (sreg == 0)	macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,		     treg);      else if (treg == 0)	macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,		     sreg);      else	{	  macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,		       sreg, treg);	  macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,		       dreg);	}      return;    case M_SNE_I:      if (imm_expr.X_op == O_constant && imm_expr.X_add_number == 0)	{	  macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0,		       sreg);	  return;	}      if (sreg == 0)	{	  as_warn (_("Instruction %s: result is always true"),		   ip->insn_mo->name);	  macro_build ((char *) NULL, &icnt, &expr1,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", dreg, 0, (int) BFD_RELOC_LO16);	  return;	}      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number >= 0	  && imm_expr.X_add_number < 0x10000)	{	  macro_build ((char *) NULL, &icnt, &imm_expr, "xori", "t,r,i",		       dreg, sreg, (int) BFD_RELOC_LO16);	  used_at = 0;	}      else if (imm_expr.X_op == O_constant	       && imm_expr.X_add_number > -0x8000	       && imm_expr.X_add_number < 0)	{	  imm_expr.X_add_number = -imm_expr.X_add_number;	  macro_build ((char *) NULL, &icnt, &imm_expr,		       ((bfd_arch_bits_per_address (stdoutput) == 32			 || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		        ? "addiu" : "daddiu"),		       "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);	  used_at = 0;	}      else	{	  load_register (&icnt, AT, &imm_expr, 0);	  macro_build ((char *) NULL, &icnt, NULL, "xor", "d,v,t", dreg,		       sreg, AT);	  used_at = 1;	}      macro_build ((char *) NULL, &icnt, NULL, "sltu", "d,v,t", dreg, 0, dreg);      if (used_at)	break;      return;    case M_DSUB_I:      dbl = 1;    case M_SUB_I:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number > -0x8000	  && imm_expr.X_add_number <= 0x8000)	{	  imm_expr.X_add_number = -imm_expr.X_add_number;	  macro_build ((char *) NULL, &icnt, &imm_expr,		       dbl ? "daddi" : "addi",		       "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);	  return;	}      load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dsub" : "sub",		   "d,v,t", dreg, sreg, AT);      break;    case M_DSUBU_I:      dbl = 1;    case M_SUBU_I:      if (imm_expr.X_op == O_constant	  && imm_expr.X_add_number > -0x8000	  && imm_expr.X_add_number <= 0x8000)	{	  imm_expr.X_add_number = -imm_expr.X_add_number;	  macro_build ((char *) NULL, &icnt, &imm_expr,		       dbl ? "daddiu" : "addiu",		       "t,r,j", dreg, sreg, (int) BFD_RELOC_LO16);	  return;	}      load_register (&icnt, AT, &imm_expr, dbl);      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dsubu" : "subu",		   "d,v,t", dreg, sreg, AT);      break;    case M_TEQ_I:      s = "teq";      goto trap;    case M_TGE_I:      s = "tge";      goto trap;    case M_TGEU_I:      s = "tgeu";      goto trap;    case M_TLT_I:      s = "tlt";      goto trap;    case M_TLTU_I:      s = "tltu";      goto trap;    case M_TNE_I:      s = "tne";    trap:      load_register (&icnt, AT, &imm_expr, 0);      macro_build ((char *) NULL, &icnt, NULL, s, "s,t", sreg, AT);      break;    case M_TRUNCWD:    case M_TRUNCWS:      assert (mips_opts.isa == 1);      sreg = (ip->insn_opcode >> 11) & 0x1f;	/* floating reg */      dreg = (ip->insn_opcode >> 06) & 0x1f;	/* floating reg */      /*       * Is the double cfc1 instruction a bug in the mips assembler;       * or is there a reason for it?       */      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);      macro_build ((char *) NULL, &icnt, NULL, "cfc1", "t,G", treg, 31);      macro_build ((char *) NULL, &icnt, NULL, "nop", "");      expr1.X_add_number = 3;      macro_build ((char *) NULL, &icnt, &expr1, "ori", "t,r,i", AT, treg,		   (int) BFD_RELOC_LO16);      expr1.X_add_number = 2;      macro_build ((char *) NULL, &icnt, &expr1, "xori", "t,r,i", AT, AT,		     (int) BFD_RELOC_LO16);      macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", AT, 31);      macro_build ((char *) NULL, &icnt, NULL, "nop", "");      macro_build ((char *) NULL, &icnt, NULL,	      mask == M_TRUNCWD ? "cvt.w.d" : "cvt.w.s", "D,S", dreg, sreg);      macro_build ((char *) NULL, &icnt, NULL, "ctc1", "t,G", treg, 31);      macro_build ((char *) NULL, &icnt, NULL, "nop", "");      --mips_opts.noreorder;      break;    case M_ULH:      s = "lb";      goto ulh;    case M_ULHU:      s = "lbu";    ulh:      if (offset_expr.X_add_number >= 0x7fff)	as_bad (_("operand overflow"));      /* avoid load delay */      if (! target_big_endian)	offset_expr.X_add_number += 1;      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      if (! target_big_endian)	offset_expr.X_add_number -= 1;      else	offset_expr.X_add_number += 1;      macro_build ((char *) NULL, &icnt, &offset_expr, "lbu", "t,o(b)", AT,		   (int) BFD_RELOC_LO16, breg);      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg, treg, 8);      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg, treg, AT);      break;    case M_ULD:      s = "ldl";      s2 = "ldr";      off = 7;      goto ulw;    case M_ULW:      s = "lwl";      s2 = "lwr";      off = 3;    ulw:      if (offset_expr.X_add_number >= 0x8000 - off)	as_bad (_("operand overflow"));      if (! target_big_endian)	offset_expr.X_add_number += off;      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      if (! target_big_endian)	offset_expr.X_add_number -= off;      else	offset_expr.X_add_number += off;      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      return;    case M_ULD_A:      s = "ldl";      s2 = "ldr";      off = 7;      goto ulwa;    case M_ULW_A:      s = "lwl";      s2 = "lwr";      off = 3;    ulwa:      load_address (&icnt, AT, &offset_expr);      if (breg != 0)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     ((bfd_arch_bits_per_address (stdoutput) == 32		       || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		      ? "addu" : "daddu"),		     "d,v,t", AT, AT, breg);      if (! target_big_endian)	expr1.X_add_number = off;      else	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      if (! target_big_endian)	expr1.X_add_number = 0;      else	expr1.X_add_number = off;      macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      break;    case M_ULH_A:    case M_ULHU_A:      load_address (&icnt, AT, &offset_expr);      if (breg != 0)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     ((bfd_arch_bits_per_address (stdoutput) == 32		       || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		      ? "addu" : "daddu"),		     "d,v,t", AT, AT, breg);      if (target_big_endian)	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1,		   mask == M_ULH_A ? "lb" : "lbu", "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      if (target_big_endian)	expr1.X_add_number = 1;      else	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,		   (int) BFD_RELOC_LO16, AT);      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,		   treg, 8);      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,		   treg, AT);      break;    case M_USH:      if (offset_expr.X_add_number >= 0x7fff)	as_bad (_("operand overflow"));      if (target_big_endian)	offset_expr.X_add_number += 1;      macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", AT, treg, 8);      if (target_big_endian)	offset_expr.X_add_number -= 1;      else	offset_expr.X_add_number += 1;      macro_build ((char *) NULL, &icnt, &offset_expr, "sb", "t,o(b)", AT,		   (int) BFD_RELOC_LO16, breg);      break;    case M_USD:      s = "sdl";      s2 = "sdr";      off = 7;      goto usw;    case M_USW:      s = "swl";      s2 = "swr";      off = 3;    usw:      if (offset_expr.X_add_number >= 0x8000 - off)	as_bad (_("operand overflow"));      if (! target_big_endian)	offset_expr.X_add_number += off;      macro_build ((char *) NULL, &icnt, &offset_expr, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      if (! target_big_endian)	offset_expr.X_add_number -= off;      else	offset_expr.X_add_number += off;      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, breg);      return;    case M_USD_A:      s = "sdl";      s2 = "sdr";      off = 7;      goto uswa;    case M_USW_A:      s = "swl";      s2 = "swr";      off = 3;    uswa:      load_address (&icnt, AT, &offset_expr);      if (breg != 0)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     ((bfd_arch_bits_per_address (stdoutput) == 32		       || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		      ? "addu" : "daddu"),		     "d,v,t", AT, AT, breg);      if (! target_big_endian)	expr1.X_add_number = off;      else	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, s, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      if (! target_big_endian)	expr1.X_add_number = 0;      else	expr1.X_add_number = off;      macro_build ((char *) NULL, &icnt, &expr1, s2, "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      break;    case M_USH_A:      load_address (&icnt, AT, &offset_expr);      if (breg != 0)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     ((bfd_arch_bits_per_address (stdoutput) == 32		       || ! ISA_HAS_64BIT_REGS (mips_opts.isa))		      ? "addu" : "daddu"),		     "d,v,t", AT, AT, breg);      if (! target_big_endian)	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      macro_build ((char *) NULL, &icnt, NULL, "srl", "d,w,<", treg,		   treg, 8);      if (! target_big_endian)	expr1.X_add_number = 1;      else	expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, "sb", "t,o(b)", treg,		   (int) BFD_RELOC_LO16, AT);      if (! target_big_endian)	expr1.X_add_number = 0;      else	expr1.X_add_number = 1;      macro_build ((char *) NULL, &icnt, &expr1, "lbu", "t,o(b)", AT,		   (int) BFD_RELOC_LO16, AT);      macro_build ((char *) NULL, &icnt, NULL, "sll", "d,w,<", treg,		   treg, 8);      macro_build ((char *) NULL, &icnt, NULL, "or", "d,v,t", treg,		   treg, AT);      break;    default:      /* FIXME: Check if this is one of the itbl macros, since they	 are added dynamically. */      as_bad (_("Macro %s not implemented yet"), ip->insn_mo->name);      break;    }  if (mips_opts.noat)    as_warn (_("Macro used $at after \".set noat\""));}/* Implement macros in mips16 mode.  */static voidmips16_macro (ip)     struct mips_cl_insn *ip;{  int mask;  int xreg, yreg, zreg, tmp;  int icnt;  expressionS expr1;  int dbl;  const char *s, *s2, *s3;  mask = ip->insn_mo->mask;  xreg = (ip->insn_opcode >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;  yreg = (ip->insn_opcode >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY;  zreg = (ip->insn_opcode >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;  icnt = 0;  expr1.X_op = O_constant;  expr1.X_op_symbol = NULL;  expr1.X_add_symbol = NULL;  expr1.X_add_number = 1;  dbl = 0;  switch (mask)    {    default:      internalError ();    case M_DDIV_3:      dbl = 1;    case M_DIV_3:      s = "mflo";      goto do_div3;    case M_DREM_3:      dbl = 1;    case M_REM_3:      s = "mfhi";    do_div3:      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "ddiv" : "div",		   "0,x,y", xreg, yreg);      expr1.X_add_number = 2;      macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);	macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);            /* FIXME: The normal code checks for of -1 / -0x80000000 here,         since that causes an overflow.  We should do that as well,         but I don't see how to do the comparisons without a temporary         register.  */      --mips_opts.noreorder;      macro_build ((char *) NULL, &icnt, NULL, s, "x", zreg);      break;    case M_DIVU_3:      s = "divu";      s2 = "mflo";      goto do_divu3;    case M_REMU_3:      s = "divu";      s2 = "mfhi";      goto do_divu3;    case M_DDIVU_3:      s = "ddivu";      s2 = "mflo";      goto do_divu3;    case M_DREMU_3:      s = "ddivu";      s2 = "mfhi";    do_divu3:      mips_emit_delays (true);      ++mips_opts.noreorder;      mips_any_noreorder = 1;      macro_build ((char *) NULL, &icnt, NULL, s, "0,x,y", xreg, yreg);      expr1.X_add_number = 2;      macro_build ((char *) NULL, &icnt, &expr1, "bnez", "x,p", yreg);	macro_build ((char *) NULL, &icnt, NULL, "break", "6", 7);      --mips_opts.noreorder;      macro_build ((char *) NULL, &icnt, NULL, s2, "x", zreg);      break;    case M_DMUL:      dbl = 1;    case M_MUL:      macro_build ((char *) NULL, &icnt, NULL,		   dbl ? "dmultu" : "multu",		   "x,y", xreg, yreg);      macro_build ((char *) NULL, &icnt, NULL, "mflo", "x", zreg);      return;    case M_DSUBU_I:      dbl = 1;      goto do_subu;    case M_SUBU_I:    do_subu:      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number = -imm_expr.X_add_number;      macro_build ((char *) NULL, &icnt, &imm_expr,		   dbl ? "daddiu" : "addiu",		   "y,x,4", yreg, xreg);      break;    case M_SUBU_I_2:      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number = -imm_expr.X_add_number;      macro_build ((char *) NULL, &icnt, &imm_expr, "addiu",		   "x,k", xreg);      break;    case M_DSUBU_I_2:      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      imm_expr.X_add_number = -imm_expr.X_add_number;      macro_build ((char *) NULL, &icnt, &imm_expr, "daddiu",		   "y,j", yreg);      break;    case M_BEQ:      s = "cmp";      s2 = "bteqz";      goto do_branch;    case M_BNE:      s = "cmp";      s2 = "btnez";      goto do_branch;    case M_BLT:      s = "slt";      s2 = "btnez";      goto do_branch;    case M_BLTU:      s = "sltu";      s2 = "btnez";      goto do_branch;    case M_BLE:      s = "slt";      s2 = "bteqz";      goto do_reverse_branch;    case M_BLEU:      s = "sltu";      s2 = "bteqz";      goto do_reverse_branch;    case M_BGE:      s = "slt";      s2 = "bteqz";      goto do_branch;    case M_BGEU:      s = "sltu";      s2 = "bteqz";      goto do_branch;    case M_BGT:      s = "slt";      s2 = "btnez";      goto do_reverse_branch;    case M_BGTU:      s = "sltu";      s2 = "btnez";    do_reverse_branch:      tmp = xreg;      xreg = yreg;      yreg = tmp;    do_branch:      macro_build ((char *) NULL, &icnt, (expressionS *) NULL, s, "x,y",		   xreg, yreg);      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "p");      break;    case M_BEQ_I:      s = "cmpi";      s2 = "bteqz";      s3 = "x,U";      goto do_branch_i;    case M_BNE_I:      s = "cmpi";      s2 = "btnez";      s3 = "x,U";      goto do_branch_i;    case M_BLT_I:      s = "slti";      s2 = "btnez";      s3 = "x,8";      goto do_branch_i;    case M_BLTU_I:      s = "sltiu";      s2 = "btnez";      s3 = "x,8";      goto do_branch_i;    case M_BLE_I:      s = "slti";      s2 = "btnez";      s3 = "x,8";      goto do_addone_branch_i;    case M_BLEU_I:      s = "sltiu";      s2 = "btnez";      s3 = "x,8";      goto do_addone_branch_i;    case M_BGE_I:      s = "slti";      s2 = "bteqz";      s3 = "x,8";      goto do_branch_i;    case M_BGEU_I:      s = "sltiu";      s2 = "bteqz";      s3 = "x,8";      goto do_branch_i;    case M_BGT_I:      s = "slti";      s2 = "bteqz";      s3 = "x,8";      goto do_addone_branch_i;    case M_BGTU_I:      s = "sltiu";      s2 = "bteqz";      s3 = "x,8";    do_addone_branch_i:      if (imm_expr.X_op != O_constant)	as_bad (_("Unsupported large constant"));      ++imm_expr.X_add_number;    do_branch_i:      macro_build ((char *) NULL, &icnt, &imm_expr, s, s3, xreg);      macro_build ((char *) NULL, &icnt, &offset_expr, s2, "p");      break;    case M_ABS:      expr1.X_add_number = 0;      macro_build ((char *) NULL, &icnt, &expr1, "slti", "x,8",  yreg);      if (xreg != yreg)	macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		     "move", "y,X", xreg, yreg);      expr1.X_add_number = 2;      macro_build ((char *) NULL, &icnt, &expr1, "bteqz", "p");      macro_build ((char *) NULL, &icnt, (expressionS *) NULL,		   "neg", "x,w", xreg, xreg);    }}/* For consistency checking, verify that all bits are specified either   by the match/mask part of the instruction definition, or by the   operand list.  */static intvalidate_mips_insn (opc)     const struct mips_opcode *opc;{  const char *p = opc->args;  char c;  unsigned long used_bits = opc->mask;  if ((used_bits & opc->match) != opc->match)    {      as_bad (_("internal: bad mips opcode (mask error): %s %s"),	      opc->name, opc->args);      return 0;    }#define USE_BITS(mask,shift)	(used_bits |= ((mask) << (shift)))  while (*p)    switch (c = *p++)      {      case ',': break;      case '(': break;      case ')': break;      case '<': USE_BITS (OP_MASK_SHAMT,	OP_SH_SHAMT);	break;      case '>':	USE_BITS (OP_MASK_SHAMT,	OP_SH_SHAMT);	break;      case 'A': break;      case 'B':	USE_BITS (OP_MASK_SYSCALL,	OP_SH_SYSCALL);	break;      case 'C':	USE_BITS (OP_MASK_COPZ,		OP_SH_COPZ);	break;      case 'D':	USE_BITS (OP_MASK_FD,		OP_SH_FD);	break;      case 'E':	USE_BITS (OP_MASK_RT,		OP_SH_RT);	break;      case 'F': break;      case 'G':	USE_BITS (OP_MASK_RD,		OP_SH_RD);	break;      case 'I': break;      case 'L': break;      case 'M':	USE_BITS (OP_MASK_CCC,		OP_SH_CCC);	break;      case 'N':	USE_BITS (OP_MASK_BCC,		OP_SH_BCC);	break;      case 'R':	USE_BITS (OP_MASK_FR,		OP_SH_FR);	break;      case 'S':	USE_BITS (OP_MASK_FS,		OP_SH_FS);	break;      case 'T':	USE_BITS (OP_MASK_FT,		OP_SH_FT);	break;      case 'V':	USE_BITS (OP_MASK_FS,		OP_SH_FS);	break;      case 'W':	USE_BITS (OP_MASK_FT,		OP_SH_FT);	break;      case 'a':	USE_BITS (OP_MASK_TARGET,	OP_SH_TARGET);	break;      case 'b':	USE_BITS (OP_MASK_RS,		OP_SH_RS);	break;      case 'c':	USE_BITS (OP_MASK_CODE,		OP_SH_CODE);	break;      case 'd':	USE_BITS (OP_MASK_RD,		OP_SH_RD);	break;      case 'f': break;      case 'h':	USE_BITS (OP_MASK_PREFX,	OP_SH_PREFX);	break;      case 'i':	USE_BITS (OP_MASK_IMMEDIATE,	OP_SH_IMMEDIATE); break;      case 'j':	USE_BITS (OP_MASK_DELTA,	OP_SH_DELTA);	break;      case 'k':	USE_BITS (OP_MASK_CACHE,	OP_SH_CACHE);	break;      case 'l': break;      case 'o': USE_BITS (OP_MASK_DELTA,	OP_SH_DELTA);	break;      case 'p':	USE_BITS (OP_MASK_DELTA,	OP_SH_DELTA);	break;      case 'q':	USE_BITS (OP_MASK_CODE2,	OP_SH_CODE2);	break;      case 'r': USE_BITS (OP_MASK_RS,		OP_SH_RS);	break;      case 's':	USE_BITS (OP_MASK_RS,		OP_SH_RS);	break;      case 't':	USE_BITS (OP_MASK_RT,		OP_SH_RT);	break;      case 'u':	USE_BITS (OP_MASK_IMMEDIATE,	OP_SH_IMMEDIATE); break;      case 'v':	USE_BITS (OP_MASK_RS,		OP_SH_RS);	break;      case 'w':	USE_BITS (OP_MASK_RT,		OP_SH_RT);	break;      case 'x': break;      case 'z': break;      case 'P': USE_BITS (OP_MASK_PERFREG,	OP_SH_PERFREG);	break;      default:	as_bad (_("internal: bad mips opcode (unknown operand type `%c'): %s %s"),		c, opc->name, opc->args);	return 0;      }#undef USE_BITS  if (used_bits != 0xffffffff)    {      as_bad (_("internal: bad mips opcode (bits 0x%lx undefined): %s %s"),	      ~used_bits & 0xffffffff, opc->name, opc->args);      return 0;    }  return 1;}/* This routine assembles an instruction into its binary format.  As a   side effect, it sets one of the global variables imm_reloc or   offset_reloc to the type of relocation to do if one of the operands   is an address expression.  */static voidmips_ip (str, ip)     char *str;     struct mips_cl_insn *ip;{  char *s;  const char *args;  char c;  struct mips_opcode *insn;  char *argsStart;  unsigned int regno;  unsigned int lastregno = 0;  char *s_reset;  char save_c = 0;  int full_opcode_match = 1;  insn_error = NULL;  /* If the instruction contains a '.', we first try to match an instruction     including the '.'.  Then we try again without the '.'.  */  insn = NULL;  for (s = str; *s != '\0' && !isspace ((unsigned char) *s); ++s)    continue;  /* If we stopped on whitespace, then replace the whitespace with null for     the call to hash_find.  Save the character we replaced just in case we     have to re-parse the instruction.  */  if (isspace ((unsigned char) *s))    {      save_c = *s;      *s++ = '\0';    }	  insn = (struct mips_opcode *) hash_find (op_hash, str);  /* If we didn't find the instruction in the opcode table, try again, but     this time with just the instruction up to, but not including the     first '.'.  */  if (insn == NULL)    {      /* Restore the character we overwrite above (if any).  */       if (save_c)	*(--s) = save_c;      /* Scan up to the first '.' or whitespace.  */      for (s = str; *s != '\0' && *s != '.' && !isspace ((unsigned char) *s); ++s)	continue;      /* If we did not find a '.', then we can quit now.  */      if (*s != '.')	{	  insn_error = "unrecognized opcode";	  return;	}      /* Lookup the instruction in the hash table.  */      *s++ = '\0';      if ((insn = (struct mips_opcode *) hash_find (op_hash, str)) == NULL)	{	  insn_error = "unrecognized opcode";	  return;	}      full_opcode_match = 0;    }  argsStart = s;  for (;;)    {      boolean ok;      assert (strcmp (insn->name, str) == 0);      if (OPCODE_IS_MEMBER (insn, mips_opts.isa, mips_cpu, mips_gp32))	ok = true;      else 	ok = false;            if (insn->pinfo != INSN_MACRO)	{	  if (mips_cpu == 4650 && (insn->pinfo & FP_D) != 0)	    ok = false;	}      if (! ok)	{	  if (insn + 1 < &mips_opcodes[NUMOPCODES]	      && strcmp (insn->name, insn[1].name) == 0)	    {	      ++insn;	      continue;	    }	  else	    {	      static char buf[100];	      sprintf (buf, 		       _("opcode not supported on this processor: %d (MIPS%d)"),		       mips_cpu, mips_opts.isa);		       	      insn_error = buf;	      return;	    }	}      ip->insn_mo = insn;      ip->insn_opcode = insn->match;      for (args = insn->args;; ++args)	{	  if (*s == ' ')	    ++s;	  switch (*args)	    {	    case '\0':		/* end of args */	      if (*s == '\0')		return;	      break;	    case ',':	      if (*s++ == *args)		continue;	      s--;	      switch (*++args)		{		case 'r':		case 'v':		  ip->insn_opcode |= lastregno << 21;		  continue;		case 'w':		case 'W':		  ip->insn_opcode |= lastregno << 16;		  continue;		case 'V':		  ip->insn_opcode |= lastregno << 11;		  continue;		}	      break;	    case '(':	      /* Handle optional base register.		 Either the base register is omitted or		 we must have a left paren. */	      /* This is dependent on the next operand specifier		 is a base register specification.  */	      assert (args[1] == 'b' || args[1] == '5'		      || args[1] == '-' || args[1] == '4');	      if (*s == '\0')		return;	    case ')':		/* these must match exactly */	      if (*s++ == *args)		continue;	      break;	    case '<':		/* must be at least one digit */	      /*	       * According to the manual, if the shift amount is greater	       * than 31 or less than 0 the the shift amount should be	       * mod 32. In reality the mips assembler issues an error.	       * We issue a warning and mask out all but the low 5 bits.	       */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned long) imm_expr.X_add_number > 31)		{		  as_warn (_("Improper shift amount (%ld)"),			   (long) imm_expr.X_add_number);		  imm_expr.X_add_number = imm_expr.X_add_number & 0x1f;		}	      ip->insn_opcode |= imm_expr.X_add_number << 6;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case '>':		/* shift amount minus 32 */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned long) imm_expr.X_add_number < 32		  || (unsigned long) imm_expr.X_add_number > 63)		break;	      ip->insn_opcode |= (imm_expr.X_add_number - 32) << 6;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case 'k':		/* cache code */	    case 'h':		/* prefx code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned long) imm_expr.X_add_number > 31)		{		  as_warn (_("Invalid value for `%s' (%lu)"),			   ip->insn_mo->name,			   (unsigned long) imm_expr.X_add_number);		  imm_expr.X_add_number &= 0x1f;		}	      if (*args == 'k')		ip->insn_opcode |= imm_expr.X_add_number << OP_SH_CACHE;	      else		ip->insn_opcode |= imm_expr.X_add_number << OP_SH_PREFX;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case 'c':		/* break code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned) imm_expr.X_add_number > 1023)		{		  as_warn (_("Illegal break code (%ld)"),			   (long) imm_expr.X_add_number);		  imm_expr.X_add_number &= 0x3ff;		}	      ip->insn_opcode |= imm_expr.X_add_number << 16;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case 'q':		/* lower break code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned) imm_expr.X_add_number > 1023)		{		  as_warn (_("Illegal lower break code (%ld)"),			   (long) imm_expr.X_add_number);		  imm_expr.X_add_number &= 0x3ff;		}	      ip->insn_opcode |= imm_expr.X_add_number << 6;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case 'B':		/* syscall code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned) imm_expr.X_add_number > 0xfffff)		as_warn (_("Illegal syscall code (%ld)"),			 (long) imm_expr.X_add_number);	      ip->insn_opcode |= imm_expr.X_add_number << 6;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;            case 'C':           /* Coprocessor code */              my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);              if ((unsigned long) imm_expr.X_add_number >= (1<<25))		{                  as_warn (_("Coproccesor code > 25 bits (%ld)"),			   (long) imm_expr.X_add_number);                  imm_expr.X_add_number &= ((1<<25) - 1);		}              ip->insn_opcode |= imm_expr.X_add_number;              imm_expr.X_op = O_absent;              s = expr_end;              continue;	    case 'P':		/* Performance register */              my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);              if (imm_expr.X_add_number != 0 && imm_expr.X_add_number != 1)		{                  as_warn (_("Invalidate performance regster (%ld)"),			   (long) imm_expr.X_add_number);                  imm_expr.X_add_number &= 1;		}              ip->insn_opcode |= (imm_expr.X_add_number << 1);              imm_expr.X_op = O_absent;              s = expr_end;              continue;	    case 'b':		/* base register */	    case 'd':		/* destination register */	    case 's':		/* source register */	    case 't':		/* target register */	    case 'r':		/* both target and source */	    case 'v':		/* both dest and source */	    case 'w':		/* both dest and target */	    case 'E':		/* coprocessor target register */	    case 'G':		/* coprocessor destination register */	    case 'x':		/* ignore register name */	    case 'z':		/* must be zero register */	      s_reset = s;	      if (s[0] == '$')		{		  if (isdigit ((unsigned char) s[1]))		    {		      ++s;		      regno = 0;		      do			{			  regno *= 10;			  regno += *s - '0';			  ++s;			}		      while (isdigit ((unsigned char) *s));		      if (regno > 31)			as_bad (_("Invalid register number (%d)"), regno);		    }		  else if (*args == 'E' || *args == 'G')		    goto notreg;		  else		    {		      if (s[1] == 'f' && s[2] == 'p')			{			  s += 3;			  regno = FP;			}		      else if (s[1] == 's' && s[2] == 'p')			{			  s += 3;			  regno = SP;			}		      else if (s[1] == 'g' && s[2] == 'p')			{			  s += 3;			  regno = GP;			}		      else if (s[1] == 'a' && s[2] == 't')			{			  s += 3;			  regno = AT;			}		      else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')			{			  s += 4;			  regno = KT0;			}		      else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')			{			  s += 4;			  regno = KT1;			}		      else if (itbl_have_entries)			{			  char *p, *n;			  unsigned long r;			  p = s + 1; 	/* advance past '$' */			  n = itbl_get_field (&p);  /* n is name */			  /* See if this is a register defined in an			     itbl entry.  */			  if (itbl_get_reg_val (n, &r))			    {			      /* Get_field advances to the start of				 the next field, so we need to back				 rack to the end of the last field.  */			      if (p) 				s = p - 1;			      else 				s = strchr (s, '\0');			      regno = r;			    }			  else			    goto notreg;			  }		      else			goto notreg;		    }		  if (regno == AT		      && ! mips_opts.noat		      && *args != 'E'		      && *args != 'G')		    as_warn (_("Used $at without \".set noat\""));		  c = *args;		  if (*s == ' ')		    s++;		  if (args[1] != *s)		    {		      if (c == 'r' || c == 'v' || c == 'w')			{			  regno = lastregno;			  s = s_reset;			  args++;			}		    }		  /* 'z' only matches $0.  */		  if (c == 'z' && regno != 0)		    break;	/* Now that we have assembled one operand, we use the args string 	 * to figure out where it goes in the instruction. */		  switch (c)		    {		    case 'r':		    case 's':		    case 'v':		    case 'b':		      ip->insn_opcode |= regno << 21;		      break;		    case 'd':		    case 'G':		      ip->insn_opcode |= regno << 11;		      break;		    case 'w':		    case 't':		    case 'E':		      ip->insn_opcode |= regno << 16;		      break;		    case 'x':		      /* This case exists because on the r3000 trunc			 expands into a macro which requires a gp			 register.  On the r6000 or r4000 it is			 assembled into a single instruction which			 ignores the register.  Thus the insn version			 is MIPS_ISA2 and uses 'x', and the macro			 version is MIPS_ISA1 and uses 't'.  */		      break;		    case 'z':		      /* This case is for the div instruction, which			 acts differently if the destination argument			 is $0.  This only matches $0, and is checked			 outside the switch.  */		      break;		    case 'D':		      /* Itbl operand; not yet implemented. FIXME ?? */		      break;		      /* What about all other operands like 'i', which			 can be specified in the opcode table? */		    }		  lastregno = regno;		  continue;		}	    notreg:	      switch (*args++)		{		case 'r':		case 'v':		  ip->insn_opcode |= lastregno << 21;		  continue;		case 'w':		  ip->insn_opcode |= lastregno << 16;		  continue;		}	      break;	    case 'D':		/* floating point destination register */	    case 'S':		/* floating point source register */	    case 'T':		/* floating point target register */	    case 'R':		/* floating point source register */	    case 'V':	    case 'W':	      s_reset = s;	      if (s[0] == '$' && s[1] == 'f' && isdigit ((unsigned char) s[2]))		{		  s += 2;		  regno = 0;		  do		    {		      regno *= 10;		      regno += *s - '0';		      ++s;		    }		  while (isdigit ((unsigned char) *s));		  if (regno > 31)		    as_bad (_("Invalid float register number (%d)"), regno);		  if ((regno & 1) != 0		      && ! ISA_HAS_64BIT_REGS (mips_opts.isa)		      && ! (strcmp (str, "mtc1") == 0			    || strcmp (str, "mfc1") == 0			    || strcmp (str, "lwc1") == 0			    || strcmp (str, "swc1") == 0			    || strcmp (str, "l.s") == 0			    || strcmp (str, "s.s") == 0))		    as_warn (_("Float register should be even, was %d"),			     regno);		  c = *args;		  if (*s == ' ')		    s++;		  if (args[1] != *s)		    {		      if (c == 'V' || c == 'W')			{			  regno = lastregno;			  s = s_reset;			  args++;			}		    }		  switch (c)		    {		    case 'D':		      ip->insn_opcode |= regno << 6;		      break;		    case 'V':		    case 'S':		      ip->insn_opcode |= regno << 11;		      break;		    case 'W':		    case 'T':		      ip->insn_opcode |= regno << 16;		      break;		    case 'R':		      ip->insn_opcode |= regno << 21;		      break;		    }		  lastregno = regno;		  continue;		}	      switch (*args++)		{		case 'V':		  ip->insn_opcode |= lastregno << 11;		  continue;		case 'W':		  ip->insn_opcode |= lastregno << 16;		  continue;		}	      break;	    case 'I':	      my_getExpression (&imm_expr, s);	      if (imm_expr.X_op != O_big		  && imm_expr.X_op != O_constant)		insn_error = _("absolute expression required");	      s = expr_end;	      continue;	    case 'A':	      my_getExpression (&offset_expr, s);	      imm_reloc = BFD_RELOC_32;	      s = expr_end;	      continue;	    case 'F':	    case 'L':	    case 'f':	    case 'l':	      {		int f64;		char *save_in;		char *err;		unsigned char temp[8];		int len;		unsigned int length;		segT seg;		subsegT subseg;		char *p;		/* These only appear as the last operand in an		   instruction, and every instruction that accepts		   them in any variant accepts them in all variants.		   This means we don't have to worry about backing out		   any changes if the instruction does not match.		   The difference between them is the size of the		   floating point constant and where it goes.  For 'F'		   and 'L' the constant is 64 bits; for 'f' and 'l' it		   is 32 bits.  Where the constant is placed is based		   on how the MIPS assembler does things:		    F -- .rdata		    L -- .lit8		    f -- immediate value		    l -- .lit4		    The .lit4 and .lit8 sections are only used if		    permitted by the -G argument.		    When generating embedded PIC code, we use the		    .lit8 section but not the .lit4 section (we can do		    .lit4 inline easily; we need to put .lit8		    somewhere in the data segment, and using .lit8		    permits the linker to eventually combine identical		    .lit8 entries).  */		f64 = *args == 'F' || *args == 'L';		save_in = input_line_pointer;		input_line_pointer = s;		err = md_atof (f64 ? 'd' : 'f', (char *) temp, &len);		length = len;		s = input_line_pointer;		input_line_pointer = save_in;		if (err != NULL && *err != '\0')		  {		    as_bad (_("Bad floating point constant: %s"), err);		    memset (temp, '\0', sizeof temp);		    length = f64 ? 8 : 4;		  }		assert (length == (f64 ? 8 : 4));		if (*args == 'f'		    || (*args == 'l'			&& (! USE_GLOBAL_POINTER_OPT			    || mips_pic == EMBEDDED_PIC			    || g_switch_value < 4			    || (temp[0] == 0 && temp[1] == 0)			    || (temp[2] == 0 && temp[3] == 0))))		  {		    imm_expr.X_op = O_constant;		    if (! target_big_endian)		      imm_expr.X_add_number = bfd_getl32 (temp);		    else		      imm_expr.X_add_number = bfd_getb32 (temp);		  }		else if (length > 4			 && ((temp[0] == 0 && temp[1] == 0)			     || (temp[2] == 0 && temp[3] == 0))			 && ((temp[4] == 0 && temp[5] == 0)			     || (temp[6] == 0 && temp[7] == 0)))		  {		    /* The value is simple enough to load with a                       couple of instructions.  In mips1 mode, set                       imm_expr to the high order 32 bits and                       offset_expr to the low order 32 bits.                       Otherwise, set imm_expr to the entire 64 bit                       constant.  */		    if (! ISA_HAS_64BIT_REGS (mips_opts.isa))		      {			imm_expr.X_op = O_constant;			offset_expr.X_op = O_constant;			if (! target_big_endian)			  {			    imm_expr.X_add_number = bfd_getl32 (temp + 4);			    offset_expr.X_add_number = bfd_getl32 (temp);			  }			else			  {			    imm_expr.X_add_number = bfd_getb32 (temp);			    offset_expr.X_add_number = bfd_getb32 (temp + 4);			  }			if (offset_expr.X_add_number == 0)			  offset_expr.X_op = O_absent;		      }		    else if (sizeof (imm_expr.X_add_number) > 4)		      {			imm_expr.X_op = O_constant;			if (! target_big_endian)			  imm_expr.X_add_number = bfd_getl64 (temp);			else			  imm_expr.X_add_number = bfd_getb64 (temp);		      }		    else		      {			imm_expr.X_op = O_big;			imm_expr.X_add_number = 4;			if (! target_big_endian)			  {			    generic_bignum[0] = bfd_getl16 (temp);			    generic_bignum[1] = bfd_getl16 (temp + 2);			    generic_bignum[2] = bfd_getl16 (temp + 4);			    generic_bignum[3] = bfd_getl16 (temp + 6);			  }			else			  {			    generic_bignum[0] = bfd_getb16 (temp + 6);			    generic_bignum[1] = bfd_getb16 (temp + 4);			    generic_bignum[2] = bfd_getb16 (temp + 2);			    generic_bignum[3] = bfd_getb16 (temp);			  }		      }		  }		else		  {		    const char *newname;		    segT new_seg;		    /* Switch to the right section.  */		    seg = now_seg;		    subseg = now_subseg;		    switch (*args)		      {		      default: /* unused default case avoids warnings.  */		      case 'L':			newname = RDATA_SECTION_NAME;			if ((USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)			    || mips_pic == EMBEDDED_PIC)			  newname = ".lit8";			break;		      case 'F':			if (mips_pic == EMBEDDED_PIC)			  newname = ".lit8";			else			  newname = RDATA_SECTION_NAME;			break;		      case 'l':			assert (!USE_GLOBAL_POINTER_OPT				|| g_switch_value >= 4);			newname = ".lit4";			break;		      }		    new_seg = subseg_new (newname, (subsegT) 0);		    if (OUTPUT_FLAVOR == bfd_target_elf_flavour)		      bfd_set_section_flags (stdoutput, new_seg,					     (SEC_ALLOC					      | SEC_LOAD					      | SEC_READONLY					      | SEC_DATA));		    frag_align (*args == 'l' ? 2 : 3, 0, 0);		    if (OUTPUT_FLAVOR == bfd_target_elf_flavour			&& strcmp (TARGET_OS, "elf") != 0)		      record_alignment (new_seg, 4);		    else		      record_alignment (new_seg, *args == 'l' ? 2 : 3);		    if (seg == now_seg)		      as_bad (_("Can't use floating point insn in this section"));		    /* Set the argument to the current address in the		       section.  */		    offset_expr.X_op = O_symbol;		    offset_expr.X_add_symbol =		      symbol_new ("L0\001", now_seg,				  (valueT) frag_now_fix (), frag_now);		    offset_expr.X_add_number = 0;		    /* Put the floating point number into the section.  */		    p = frag_more ((int) length);		    memcpy (p, temp, length);		    /* Switch back to the original section.  */		    subseg_set (seg, subseg);		  }	      }	      continue;	    case 'i':		/* 16 bit unsigned immediate */	    case 'j':		/* 16 bit signed immediate */	      imm_reloc = BFD_RELOC_LO16;	      c = my_getSmallExpression (&imm_expr, s);	      if (c != '\0')		{		  if (c != 'l')		    {		      if (imm_expr.X_op == O_constant)			imm_expr.X_add_number =			  (imm_expr.X_add_number >> 16) & 0xffff;		      else if (c == 'h')			{			  imm_reloc = BFD_RELOC_HI16_S;			  imm_unmatched_hi = true;			}		      else			imm_reloc = BFD_RELOC_HI16;		    }		  else if (imm_expr.X_op == O_constant)		    imm_expr.X_add_number &= 0xffff;		}	      if (*args == 'i')		{		  if ((c == '\0' && imm_expr.X_op != O_constant)		      || ((imm_expr.X_add_number < 0                           || imm_expr.X_add_number >= 0x10000)                          && imm_expr.X_op == O_constant))		    {		      if (insn + 1 < &mips_opcodes[NUMOPCODES] &&			  !strcmp (insn->name, insn[1].name))			break;		      if (imm_expr.X_op != O_constant			  && imm_expr.X_op != O_big)			insn_error = _("absolute expression required");		      else			as_bad (_("16 bit expression not in range 0..65535"));		    }		}	      else		{		  int more;		  offsetT max;		  /* The upper bound should be 0x8000, but		     unfortunately the MIPS assembler accepts numbers		     from 0x8000 to 0xffff and sign extends them, and		     we want to be compatible.  We only permit this		     extended range for an instruction which does not		     provide any further alternates, since those		     alternates may handle other cases.  People should		     use the numbers they mean, rather than relying on		     a mysterious sign extension.  */		  more = (insn + 1 < &mips_opcodes[NUMOPCODES] &&			  strcmp (insn->name, insn[1].name) == 0);		  if (more)		    max = 0x8000;		  else		    max = 0x10000;		  if ((c == '\0' && imm_expr.X_op != O_constant)		      || ((imm_expr.X_add_number < -0x8000                           || imm_expr.X_add_number >= max)                          && imm_expr.X_op == O_constant)		      || (more			  && imm_expr.X_add_number < 0			  && ISA_HAS_64BIT_REGS (mips_opts.isa)			  && imm_expr.X_unsigned			  && sizeof (imm_expr.X_add_number) <= 4))		    {		      if (more)			break;		      if (imm_expr.X_op != O_constant			  && imm_expr.X_op != O_big)			insn_error = _("absolute expression required");		      else			as_bad (_("16 bit expression not in range -32768..32767"));		    }		}	      s = expr_end;	      continue;	    case 'o':		/* 16 bit offset */	      c = my_getSmallExpression (&offset_expr, s);	      /* If this value won't fit into a 16 bit offset, then go		 find a macro that will generate the 32 bit offset		 code pattern.  As a special hack, we accept the		 difference of two local symbols as a constant.  This		 is required to suppose embedded PIC switches, which		 use an instruction which looks like		     lw $4,$L12-$LS12($4)		 The problem with handling this in a more general		 fashion is that the macro function doesn't expect to		 see anything which can be handled in a single		 constant instruction.  */	      if (c == 0		  && (offset_expr.X_op != O_constant		      || offset_expr.X_add_number >= 0x8000		      || offset_expr.X_add_number < -0x8000)		  && (mips_pic != EMBEDDED_PIC		      || offset_expr.X_op != O_subtract		      || (S_GET_SEGMENT (offset_expr.X_op_symbol)			  != now_seg)))		break;	      if (c == 'h' || c == 'H')		{		  if (offset_expr.X_op != O_constant)		    break;		  offset_expr.X_add_number =		    (offset_expr.X_add_number >> 16) & 0xffff;		}	      offset_reloc = BFD_RELOC_LO16;	      s = expr_end;	      continue;	    case 'p':		/* pc relative offset */	      offset_reloc = BFD_RELOC_16_PCREL_S2;	      my_getExpression (&offset_expr, s);	      s = expr_end;	      continue;	    case 'u':		/* upper 16 bits */	      c = my_getSmallExpression (&imm_expr, s);	      imm_reloc = BFD_RELOC_LO16;	      if (c)		{		  if (c != 'l')		    {		      if (imm_expr.X_op == O_constant)			imm_expr.X_add_number =			  (imm_expr.X_add_number >> 16) & 0xffff;		      else if (c == 'h')			{			  imm_reloc = BFD_RELOC_HI16_S;			  imm_unmatched_hi = true;			}		      else			imm_reloc = BFD_RELOC_HI16;		    }		  else if (imm_expr.X_op == O_constant)		    imm_expr.X_add_number &= 0xffff;		}	      if (imm_expr.X_op == O_constant		  && (imm_expr.X_add_number < 0		      || imm_expr.X_add_number >= 0x10000))		as_bad (_("lui expression not in range 0..65535"));	      s = expr_end;	      continue;	    case 'a':		/* 26 bit address */	      my_getExpression (&offset_expr, s);	      s = expr_end;	      offset_reloc = BFD_RELOC_MIPS_JMP;	      continue;	    case 'N':		/* 3 bit branch condition code */	    case 'M':		/* 3 bit compare condition code */	      if (strncmp (s, "$fcc", 4) != 0)		break;	      s += 4;	      regno = 0;	      do		{		  regno *= 10;		  regno += *s - '0';		  ++s;		}	      while (isdigit ((unsigned char) *s));	      if (regno > 7)		as_bad (_("invalid condition code register $fcc%d"), regno);	      if (*args == 'N')		ip->insn_opcode |= regno << OP_SH_BCC;	      else		ip->insn_opcode |= regno << OP_SH_CCC;              continue;	    default:	      as_bad (_("bad char = '%c'\n"), *args);	      internalError ();	    }	  break;	}      /* Args don't match.  */      if (insn + 1 < &mips_opcodes[NUMOPCODES] &&	  !strcmp (insn->name, insn[1].name))	{	  ++insn;	  s = argsStart;	  continue;	}      insn_error = _("illegal operands");      return;    }}/* This routine assembles an instruction into its binary format when   assembling for the mips16.  As a side effect, it sets one of the   global variables imm_reloc or offset_reloc to the type of   relocation to do if one of the operands is an address expression.   It also sets mips16_small and mips16_ext if the user explicitly   requested a small or extended instruction.  */static voidmips16_ip (str, ip)     char *str;     struct mips_cl_insn *ip;{  char *s;  const char *args;  struct mips_opcode *insn;  char *argsstart;  unsigned int regno;  unsigned int lastregno = 0;  char *s_reset;  insn_error = NULL;  mips16_small = false;  mips16_ext = false;  for (s = str; islower ((unsigned char) *s); ++s)    ;  switch (*s)    {    case '\0':      break;    case ' ':      *s++ = '\0';      break;    case '.':      if (s[1] == 't' && s[2] == ' ')	{	  *s = '\0';	  mips16_small = true;	  s += 3;	  break;	}      else if (s[1] == 'e' && s[2] == ' ')	{	  *s = '\0';	  mips16_ext = true;	  s += 3;	  break;	}      /* Fall through.  */    default:      insn_error = _("unknown opcode");      return;    }  if (mips_opts.noautoextend && ! mips16_ext)    mips16_small = true;  if ((insn = (struct mips_opcode *) hash_find (mips16_op_hash, str)) == NULL)    {      insn_error = _("unrecognized opcode");      return;    }  argsstart = s;  for (;;)    {      assert (strcmp (insn->name, str) == 0);      ip->insn_mo = insn;      ip->insn_opcode = insn->match;      ip->use_extend = false;      imm_expr.X_op = O_absent;      imm_reloc = BFD_RELOC_UNUSED;      offset_expr.X_op = O_absent;      offset_reloc = BFD_RELOC_UNUSED;      for (args = insn->args; 1; ++args)	{	  int c;	  if (*s == ' ')	    ++s;	  /* In this switch statement we call break if we did not find             a match, continue if we did find a match, or return if we             are done.  */	  c = *args;	  switch (c)	    {	    case '\0':	      if (*s == '\0')		{		  /* Stuff the immediate value in now, if we can.  */		  if (imm_expr.X_op == O_constant		      && imm_reloc > BFD_RELOC_UNUSED		      && insn->pinfo != INSN_MACRO)		    {		      mips16_immed ((char *) NULL, 0,				    imm_reloc - BFD_RELOC_UNUSED,				    imm_expr.X_add_number, true, mips16_small,				    mips16_ext, &ip->insn_opcode,				    &ip->use_extend, &ip->extend);		      imm_expr.X_op = O_absent;		      imm_reloc = BFD_RELOC_UNUSED;		    }		  return;		}	      break;	    case ',':	      if (*s++ == c)		continue;	      s--;	      switch (*++args)		{		case 'v':		  ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;		  continue;		case 'w':		  ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;		  continue;		}	      break;	    case '(':	    case ')':	      if (*s++ == c)		continue;	      break;	    case 'v':	    case 'w':	      if (s[0] != '$')		{		  if (c == 'v')		    ip->insn_opcode |= lastregno << MIPS16OP_SH_RX;		  else		    ip->insn_opcode |= lastregno << MIPS16OP_SH_RY;		  ++args;		  continue;		}	      /* Fall through.  */	    case 'x':	    case 'y':	    case 'z':	    case 'Z':	    case '0':	    case 'S':	    case 'R':	    case 'X':	    case 'Y':	      if (s[0] != '$')		break;	      s_reset = s;	      if (isdigit ((unsigned char) s[1]))		{		  ++s;		  regno = 0;		  do		    {		      regno *= 10;		      regno += *s - '0';		      ++s;		    }		  while (isdigit ((unsigned char) *s));		  if (regno > 31)		    {		      as_bad (_("invalid register number (%d)"), regno);		      regno = 2;		    }		}	      else		{		  if (s[1] == 'f' && s[2] == 'p')		    {		      s += 3;		      regno = FP;		    }		  else if (s[1] == 's' && s[2] == 'p')		    {		      s += 3;		      regno = SP;		    }		  else if (s[1] == 'g' && s[2] == 'p')		    {		      s += 3;		      regno = GP;		    }		  else if (s[1] == 'a' && s[2] == 't')		    {		      s += 3;		      regno = AT;		    }		  else if (s[1] == 'k' && s[2] == 't' && s[3] == '0')		    {		      s += 4;		      regno = KT0;		    }		  else if (s[1] == 'k' && s[2] == 't' && s[3] == '1')		    {		      s += 4;		      regno = KT1;		    }		  else		    break;		}	      if (*s == ' ')		++s;	      if (args[1] != *s)		{		  if (c == 'v' || c == 'w')		    {		      regno = mips16_to_32_reg_map[lastregno];		      s = s_reset;		      args++;		    }		}	      switch (c)		{		case 'x':		case 'y':		case 'z':		case 'v':		case 'w':		case 'Z':		  regno = mips32_to_16_reg_map[regno];		  break;		case '0':		  if (regno != 0)		    regno = ILLEGAL_REG;		  break;		case 'S':		  if (regno != SP)		    regno = ILLEGAL_REG;		  break;		case 'R':		  if (regno != RA)		    regno = ILLEGAL_REG;		  break;		case 'X':		case 'Y':		  if (regno == AT && ! mips_opts.noat)		    as_warn (_("used $at without \".set noat\""));		  break;		default:		  internalError ();		}	      if (regno == ILLEGAL_REG)		break;	      switch (c)		{		case 'x':		case 'v':		  ip->insn_opcode |= regno << MIPS16OP_SH_RX;		  break;		case 'y':		case 'w':		  ip->insn_opcode |= regno << MIPS16OP_SH_RY;		  break;		case 'z':		  ip->insn_opcode |= regno << MIPS16OP_SH_RZ;		  break;		case 'Z':		  ip->insn_opcode |= regno << MIPS16OP_SH_MOVE32Z;		case '0':		case 'S':		case 'R':		  break;		case 'X':		  ip->insn_opcode |= regno << MIPS16OP_SH_REGR32;		  break;		case 'Y':		  regno = ((regno & 7) << 2) | ((regno & 0x18) >> 3);		  ip->insn_opcode |= regno << MIPS16OP_SH_REG32R;		  break;		default:		  internalError ();		}	      lastregno = regno;	      continue;	    case 'P':	      if (strncmp (s, "$pc", 3) == 0)		{		  s += 3;		  continue;		}	      break;	    case '<':	    case '>':	    case '[':	    case ']':	    case '4':	    case '5':	    case 'H':	    case 'W':	    case 'D':	    case 'j':	    case '8':	    case 'V':	    case 'C':	    case 'U':	    case 'k':	    case 'K':	      if (s[0] == '%'		  && strncmp (s + 1, "gprel(", sizeof "gprel(" - 1) == 0)		{		  /* This is %gprel(SYMBOL).  We need to read SYMBOL,                     and generate the appropriate reloc.  If the text                     inside %gprel is not a symbol name with an                     optional offset, then we generate a normal reloc                     and will probably fail later.  */		  my_getExpression (&imm_expr, s + sizeof "%gprel" - 1);		  if (imm_expr.X_op == O_symbol)		    {		      mips16_ext = true;		      imm_reloc = BFD_RELOC_MIPS16_GPREL;		      s = expr_end;		      ip->use_extend = true;		      ip->extend = 0;		      continue;		    }		}	      else		{		  /* Just pick up a normal expression.  */		  my_getExpression (&imm_expr, s);		}	      if (imm_expr.X_op == O_register)		{		  /* What we thought was an expression turned out to                     be a register.  */		  if (s[0] == '(' && args[1] == '(')		    {		      /* It looks like the expression was omitted			 before a register indirection, which means			 that the expression is implicitly zero.  We			 still set up imm_expr, so that we handle			 explicit extensions correctly.  */		      imm_expr.X_op = O_constant;		      imm_expr.X_add_number = 0;		      imm_reloc = (int) BFD_RELOC_UNUSED + c;		      continue;		    }		  break;		}	      /* We need to relax this instruction.  */	      imm_reloc = (int) BFD_RELOC_UNUSED + c;	      s = expr_end;	      continue;	    case 'p':	    case 'q':	    case 'A':	    case 'B':	    case 'E':	      /* We use offset_reloc rather than imm_reloc for the PC                 relative operands.  This lets macros with both                 immediate and address operands work correctly.  */	      my_getExpression (&offset_expr, s);	      if (offset_expr.X_op == O_register)		break;	      /* We need to relax this instruction.  */	      offset_reloc = (int) BFD_RELOC_UNUSED + c;	      s = expr_end;	      continue;	    case '6':		/* break code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned long) imm_expr.X_add_number > 63)		{		  as_warn (_("Invalid value for `%s' (%lu)"),			   ip->insn_mo->name,			   (unsigned long) imm_expr.X_add_number);		  imm_expr.X_add_number &= 0x3f;		}	      ip->insn_opcode |= imm_expr.X_add_number << MIPS16OP_SH_IMM6;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    case 'a':		/* 26 bit address */	      my_getExpression (&offset_expr, s);	      s = expr_end;	      offset_reloc = BFD_RELOC_MIPS16_JMP;	      ip->insn_opcode <<= 16;	      continue;	    case 'l':		/* register list for entry macro */	    case 'L':		/* register list for exit macro */	      {		int mask;		if (c == 'l')		  mask = 0;		else		  mask = 7 << 3;		while (*s != '\0')		  {		    int freg, reg1, reg2;		    while (*s == ' ' || *s == ',')		      ++s;		    if (*s != '$')		      {			as_bad (_("can't parse register list"));			break;		      }		    ++s;		    if (*s != 'f')		      freg = 0;		    else		      {			freg = 1;			++s;		      }		    reg1 = 0;		    while (isdigit ((unsigned char) *s))		      {			reg1 *= 10;			reg1 += *s - '0';			++s;		      }		    if (*s == ' ')		      ++s;		    if (*s != '-')		      reg2 = reg1;		    else		      {			++s;			if (*s != '$')			  break;			++s;			if (freg)			  {			    if (*s == 'f')			      ++s;			    else			      {				as_bad (_("invalid register list"));				break;			      }			  }			reg2 = 0;			while (isdigit ((unsigned char) *s))			  {			    reg2 *= 10;			    reg2 += *s - '0';			    ++s;			  }		      }		    if (freg && reg1 == 0 && reg2 == 0 && c == 'L')		      {			mask &= ~ (7 << 3);			mask |= 5 << 3;		      }		    else if (freg && reg1 == 0 && reg2 == 1 && c == 'L')		      {			mask &= ~ (7 << 3);			mask |= 6 << 3;		      }		    else if (reg1 == 4 && reg2 >= 4 && reg2 <= 7 && c != 'L')		      mask |= (reg2 - 3) << 3;		    else if (reg1 == 16 && reg2 >= 16 && reg2 <= 17)		      mask |= (reg2 - 15) << 1;		    else if (reg1 == 31 && reg2 == 31)		      mask |= 1;		    else		      {			as_bad (_("invalid register list"));			break;		      }		  }		/* The mask is filled in in the opcode table for the                   benefit of the disassembler.  We remove it before                   applying the actual mask.  */		ip->insn_opcode &= ~ ((7 << 3) << MIPS16OP_SH_IMM6);		ip->insn_opcode |= mask << MIPS16OP_SH_IMM6;	      }	    continue;	    case 'e':		/* extend code */	      my_getExpression (&imm_expr, s);	      check_absolute_expr (ip, &imm_expr);	      if ((unsigned long) imm_expr.X_add_number > 0x7ff)		{		  as_warn (_("Invalid value for `%s' (%lu)"),			   ip->insn_mo->name,			   (unsigned long) imm_expr.X_add_number);		  imm_expr.X_add_number &= 0x7ff;		}	      ip->insn_opcode |= imm_expr.X_add_number;	      imm_expr.X_op = O_absent;	      s = expr_end;	      continue;	    default:	      internalError ();	    }	  break;	}      /* Args don't match.  */      if (insn + 1 < &mips16_opcodes[bfd_mips16_num_opcodes] &&	  strcmp (insn->name, insn[1].name) == 0)	{	  ++insn;	  s = argsstart;	  continue;	}      insn_error = _("illegal operands");      return;    }}/* This structure holds information we know about a mips16 immediate   argument type.  */struct mips16_immed_operand{  /* The type code used in the argument string in the opcode table.  */  int type;  /* The number of bits in the short form of the opcode.  */  int nbits;  /* The number of bits in the extended form of the opcode.  */  int extbits;  /* The amount by which the short form is shifted when it is used;     for example, the sw instruction has a shift count of 2.  */  int shift;  /* The amount by which the short form is shifted when it is stored     into the instruction code.  */  int op_shift;  /* Non-zero if the short form is unsigned.  */  int unsp;  /* Non-zero if the extended form is unsigned.  */  int extu;  /* Non-zero if the value is PC relative.  */  int pcrel;};/* The mips16 immediate operand types.  */static const struct mips16_immed_operand mips16_immed_operands[] ={  { '<',  3,  5, 0, MIPS16OP_SH_RZ,   1, 1, 0 },  { '>',  3,  5, 0, MIPS16OP_SH_RX,   1, 1, 0 },  { '[',  3,  6, 0, MIPS16OP_SH_RZ,   1, 1, 0 },  { ']',  3,  6, 0, MIPS16OP_SH_RX,   1, 1, 0 },  { '4',  4, 15, 0, MIPS16OP_SH_IMM4, 0, 0, 0 },  { '5',  5, 16, 0, MIPS16OP_SH_IMM5, 1, 0, 0 },  { 'H',  5, 16, 1, MIPS16OP_SH_IMM5, 1, 0, 0 },  { 'W',  5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 0 },  { 'D',  5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 0 },  { 'j',  5, 16, 0, MIPS16OP_SH_IMM5, 0, 0, 0 },  { '8',  8, 16, 0, MIPS16OP_SH_IMM8, 1, 0, 0 },  { 'V',  8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 0 },  { 'C',  8, 16, 3, MIPS16OP_SH_IMM8, 1, 0, 0 },  { 'U',  8, 16, 0, MIPS16OP_SH_IMM8, 1, 1, 0 },  { 'k',  8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 0 },  { 'K',  8, 16, 3, MIPS16OP_SH_IMM8, 0, 0, 0 },  { 'p',  8, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },  { 'q', 11, 16, 0, MIPS16OP_SH_IMM8, 0, 0, 1 },  { 'A',  8, 16, 2, MIPS16OP_SH_IMM8, 1, 0, 1 },  { 'B',  5, 16, 3, MIPS16OP_SH_IMM5, 1, 0, 1 },  { 'E',  5, 16, 2, MIPS16OP_SH_IMM5, 1, 0, 1 }};#define MIPS16_NUM_IMMED \  (sizeof mips16_immed_operands / sizeof mips16_immed_operands[0])/* Handle a mips16 instruction with an immediate value.  This or's the   small immediate value into *INSN.  It sets *USE_EXTEND to indicate   whether an extended value is needed; if one is needed, it sets   *EXTEND to the value.  The argument type is TYPE.  The value is VAL.   If SMALL is true, an unextended opcode was explicitly requested.   If EXT is true, an extended opcode was explicitly requested.  If   WARN is true, warn if EXT does not match reality.  */static voidmips16_immed (file, line, type, val, warn, small, ext, insn, use_extend,	      extend)     char *file;     unsigned int line;     int type;     offsetT val;     boolean warn;     boolean small;     boolean ext;     unsigned long *insn;     boolean *use_extend;     unsigned short *extend;{  register const struct mips16_immed_operand *op;  int mintiny, maxtiny;  boolean needext;  op = mips16_immed_operands;  while (op->type != type)    {      ++op;      assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);    }  if (op->unsp)    {      if (type == '<' || type == '>' || type == '[' || type == ']')	{	  mintiny = 1;	  maxtiny = 1 << op->nbits;	}      else	{	  mintiny = 0;	  maxtiny = (1 << op->nbits) - 1;	}    }  else    {      mintiny = - (1 << (op->nbits - 1));      maxtiny = (1 << (op->nbits - 1)) - 1;    }  /* Branch offsets have an implicit 0 in the lowest bit.  */  if (type == 'p' || type == 'q')    val /= 2;  if ((val & ((1 << op->shift) - 1)) != 0      || val < (mintiny << op->shift)      || val > (maxtiny << op->shift))    needext = true;  else    needext = false;  if (warn && ext && ! needext)    as_warn_where (file, line, _("extended operand requested but not required"));  if (small && needext)    as_bad_where (file, line, _("invalid unextended operand value"));  if (small || (! ext && ! needext))    {      int insnval;      *use_extend = false;      insnval = ((val >> op->shift) & ((1 << op->nbits) - 1));      insnval <<= op->op_shift;      *insn |= insnval;    }  else    {      long minext, maxext;      int extval;      if (op->extu)	{	  minext = 0;	  maxext = (1 << op->extbits) - 1;	}      else	{	  minext = - (1 << (op->extbits - 1));	  maxext = (1 << (op->extbits - 1)) - 1;	}      if (val < minext || val > maxext)	as_bad_where (file, line,		      _("operand value out of range for instruction"));      *use_extend = true;      if (op->extbits == 16)	{	  extval = ((val >> 11) & 0x1f) | (val & 0x7e0);	  val &= 0x1f;	}      else if (op->extbits == 15)	{	  extval = ((val >> 11) & 0xf) | (val & 0x7f0);	  val &= 0xf;	}      else	{	  extval = ((val & 0x1f) << 6) | (val & 0x20);	  val = 0;	}      *extend = (unsigned short) extval;      *insn |= val;    }}#define LP '('#define RP ')'static intmy_getSmallExpression (ep, str)     expressionS *ep;     char *str;{  char *sp;  int c = 0;  if (*str == ' ')    str++;  if (*str == LP      || (*str == '%' &&	  ((str[1] == 'h' && str[2] == 'i')	   || (str[1] == 'H' && str[2] == 'I')	   || (str[1] == 'l' && str[2] == 'o'))	  && str[3] == LP))    {      if (*str == LP)	c = 0;      else	{	  c = str[1];	  str += 3;	}      /*       * A small expression may be followed by a base register.       * Scan to the end of this operand, and then back over a possible       * base register.  Then scan the small expression up to that       * point.  (Based on code in sparc.c...)       */      for (sp = str; *sp && *sp != ','; sp++)	;      if (sp - 4 >= str && sp[-1] == RP)	{	  if (isdigit ((unsigned char) sp[-2]))	    {	      for (sp -= 3; sp >= str && isdigit ((unsigned char) *sp); sp--)		;	      if (*sp == '$' && sp > str && sp[-1] == LP)		{		  sp--;		  goto do_it;		}	    }	  else if (sp - 5 >= str		   && sp[-5] == LP		   && sp[-4] == '$'		   && ((sp[-3] == 'f' && sp[-2] == 'p')		       || (sp[-3] == 's' && sp[-2] == 'p')		       || (sp[-3] == 'g' && sp[-2] == 'p')		       || (sp[-3] == 'a' && sp[-2] == 't')))	    {	      sp -= 5;	    do_it:	      if (sp == str)		{		  /* no expression means zero offset */		  if (c)		    {		      /* %xx(reg) is an error */		      ep->X_op = O_absent;		      expr_end = str - 3;		    }		  else		    {		      ep->X_op = O_constant;		      expr_end = sp;		    }		  ep->X_add_symbol = NULL;		  ep->X_op_symbol = NULL;		  ep->X_add_number = 0;		}	      else		{		  *sp = '\0';		  my_getExpression (ep, str);		  *sp = LP;		}	      return c;	    }	}    }  my_getExpression (ep, str);  return c;			/* => %hi or %lo encountered */}static voidmy_getExpression (ep, str)     expressionS *ep;     char *str;{  char *save_in;  save_in = input_line_pointer;  input_line_pointer = str;  expression (ep);  expr_end = input_line_pointer;  input_line_pointer = save_in;  /* If we are in mips16 mode, and this is an expression based on `.',     then we bump the value of the symbol by 1 since that is how other     text symbols are handled.  We don't bother to handle complex     expressions, just `.' plus or minus a constant.  */  if (mips_opts.mips16      && ep->X_op == O_symbol      && strcmp (S_GET_NAME (ep->X_add_symbol), FAKE_LABEL_NAME) == 0      && S_GET_SEGMENT (ep->X_add_symbol) == now_seg      && symbol_get_frag (ep->X_add_symbol) == frag_now      && symbol_constant_p (ep->X_add_symbol)      && S_GET_VALUE (ep->X_add_symbol) == frag_now_fix ())    S_SET_VALUE (ep->X_add_symbol, S_GET_VALUE (ep->X_add_symbol) + 1);}/* 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.  */char *md_atof (type, litP, sizeP)     int type;     char *litP;     int *sizeP;{  int prec;  LITTLENUM_TYPE words[4];  char *t;  int i;  switch (type)    {    case 'f':      prec = 2;      break;    case 'd':      prec = 4;      break;    default:      *sizeP = 0;      return _("bad call to md_atof");    }  t = atof_ieee (input_line_pointer, type, words);  if (t)    input_line_pointer = t;  *sizeP = prec * 2;  if (! target_big_endian)    {      for (i = prec - 1; i >= 0; i--)	{	  md_number_to_chars (litP, (valueT) words[i], 2);	  litP += 2;	}    }  else    {      for (i = 0; i < prec; i++)	{	  md_number_to_chars (litP, (valueT) words[i], 2);	  litP += 2;	}    }       return NULL;}voidmd_number_to_chars (buf, val, n)     char *buf;     valueT val;     int n;{  if (target_big_endian)    number_to_chars_bigendian (buf, val, n);  else    number_to_chars_littleendian (buf, val, n);}CONST char *md_shortopts = "O::g::G:";struct option md_longopts[] = {#define OPTION_MIPS1 (OPTION_MD_BASE + 1)  {"mips0", no_argument, NULL, OPTION_MIPS1},  {"mips1", no_argument, NULL, OPTION_MIPS1},#define OPTION_MIPS2 (OPTION_MD_BASE + 2)  {"mips2", no_argument, NULL, OPTION_MIPS2},#define OPTION_MIPS3 (OPTION_MD_BASE + 3)  {"mips3", no_argument, NULL, OPTION_MIPS3},#define OPTION_MIPS4 (OPTION_MD_BASE + 4)  {"mips4", no_argument, NULL, OPTION_MIPS4},#define OPTION_MCPU (OPTION_MD_BASE + 5)  {"mcpu", required_argument, NULL, OPTION_MCPU},#define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 6)  {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},#define OPTION_TRAP (OPTION_MD_BASE + 9)  {"trap", no_argument, NULL, OPTION_TRAP},  {"no-break", no_argument, NULL, OPTION_TRAP},#define OPTION_BREAK (OPTION_MD_BASE + 10)  {"break", no_argument, NULL, OPTION_BREAK},  {"no-trap", no_argument, NULL, OPTION_BREAK},#define OPTION_EB (OPTION_MD_BASE + 11)  {"EB", no_argument, NULL, OPTION_EB},#define OPTION_EL (OPTION_MD_BASE + 12)  {"EL", no_argument, NULL, OPTION_EL},#define OPTION_M4650 (OPTION_MD_BASE + 13)  {"m4650", no_argument, NULL, OPTION_M4650},#define OPTION_NO_M4650 (OPTION_MD_BASE + 14)  {"no-m4650", no_argument, NULL, OPTION_NO_M4650},#define OPTION_M4010 (OPTION_MD_BASE + 15)  {"m4010", no_argument, NULL, OPTION_M4010},#define OPTION_NO_M4010 (OPTION_MD_BASE + 16)  {"no-m4010", no_argument, NULL, OPTION_NO_M4010},#define OPTION_M4100 (OPTION_MD_BASE + 17)  {"m4100", no_argument, NULL, OPTION_M4100},#define OPTION_NO_M4100 (OPTION_MD_BASE + 18)  {"no-m4100", no_argument, NULL, OPTION_NO_M4100},#define OPTION_MIPS16 (OPTION_MD_BASE + 22)  {"mips16", no_argument, NULL, OPTION_MIPS16},#define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23)  {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},#define OPTION_M3900 (OPTION_MD_BASE + 26)  {"m3900", no_argument, NULL, OPTION_M3900},#define OPTION_NO_M3900 (OPTION_MD_BASE + 27)  {"no-m3900", no_argument, NULL, OPTION_NO_M3900},#define OPTION_MABI (OPTION_MD_BASE + 38)  {"mabi", required_argument, NULL, OPTION_MABI},#define OPTION_M7000_HILO_FIX (OPTION_MD_BASE + 39)  {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},#define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40)  {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX},#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)#define OPTION_XGOT (OPTION_MD_BASE + 19)#define OPTION_32 (OPTION_MD_BASE + 20)#define OPTION_64 (OPTION_MD_BASE + 21)#ifdef OBJ_ELF  {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},  {"xgot", no_argument, NULL, OPTION_XGOT},  {"call_shared", no_argument, NULL, OPTION_CALL_SHARED},  {"non_shared", no_argument, NULL, OPTION_NON_SHARED},  {"32", no_argument, NULL, OPTION_32},  {"64", no_argument, NULL, OPTION_64},#endif#define OPTION_GP32 (OPTION_MD_BASE + 41)#define OPTION_GP64 (OPTION_MD_BASE + 42)  {"mgp32", no_argument, NULL, OPTION_GP32},  {"mgp64", no_argument, NULL, OPTION_GP64},  {NULL, no_argument, NULL, 0}};size_t md_longopts_size = sizeof(md_longopts);intmd_parse_option (c, arg)     int c;     char *arg;{  switch (c)    {    case OPTION_TRAP:      mips_trap = 1;      break;    case OPTION_BREAK:      mips_trap = 0;      break;    case OPTION_EB:      target_big_endian = 1;      break;    case OPTION_EL:      target_big_endian = 0;      break;    case 'O':      if (arg && arg[1] == '0')	mips_optimize = 1;      else	mips_optimize = 2;      break;    case 'g':      if (arg == NULL)	mips_debug = 2;      else	mips_debug = atoi (arg);      /* When the MIPS assembler sees -g or -g2, it does not do         optimizations which limit full symbolic debugging.  We take         that to be equivalent to -O0.  */      if (mips_debug == 2)	mips_optimize = 1;      break;    case OPTION_MIPS1:      mips_opts.isa = 1;      break;    case OPTION_MIPS2:      mips_opts.isa = 2;      break;    case OPTION_MIPS3:      mips_opts.isa = 3;      break;    case OPTION_MIPS4:      mips_opts.isa = 4;      break;    case OPTION_MCPU:      {	char *p;	/* Identify the processor type */	p = arg;	if (strcmp (p, "default") == 0	    || strcmp (p, "DEFAULT") == 0)	  mips_cpu = -1;	else	  {	    int sv = 0;	    /* We need to cope with the various "vr" prefixes for the 4300	       processor.  */	    if (*p == 'v' || *p == 'V')	      {		sv = 1;		p++;	      }	    if (*p == 'r' || *p == 'R')	      p++;	    mips_cpu = -1;	    switch (*p)	      {	      case '1':		if (strcmp (p, "10000") == 0		    || strcmp (p, "10k") == 0		    || strcmp (p, "10K") == 0)		  mips_cpu = 10000;		break;	      case '2':		if (strcmp (p, "2000") == 0		    || strcmp (p, "2k") == 0		    || strcmp (p, "2K") == 0)		  mips_cpu = 2000;		break;	      case '3':		if (strcmp (p, "3000") == 0		    || strcmp (p, "3k") == 0		    || strcmp (p, "3K") == 0)		  mips_cpu = 3000;                else if (strcmp (p, "3900") == 0)                  mips_cpu = 3900;		break;	      case '4':		if (strcmp (p, "4000") == 0		    || strcmp (p, "4k") == 0		    || strcmp (p, "4K") == 0)		  mips_cpu = 4000;		else if (strcmp (p, "4100") == 0)                    mips_cpu = 4100;		else if (strcmp (p, "4111") == 0)                    mips_cpu = 4111;		else if (strcmp (p, "4300") == 0)		  mips_cpu = 4300;		else if (strcmp (p, "4400") == 0)		  mips_cpu = 4400;		else if (strcmp (p, "4600") == 0)		  mips_cpu = 4600;		else if (strcmp (p, "4650") == 0)		    mips_cpu = 4650;		else if (strcmp (p, "4010") == 0)                  mips_cpu = 4010;		break;	      case '5':		if (strcmp (p, "5000") == 0		    || strcmp (p, "5k") == 0		    || strcmp (p, "5K") == 0)		  mips_cpu = 5000;		break;	      case '6':		if (strcmp (p, "6000") == 0		    || strcmp (p, "6k") == 0		    || strcmp (p, "6K") == 0)		  mips_cpu = 6000;		break;	      case '8':		if (strcmp (p, "8000") == 0		    || strcmp (p, "8k") == 0		    || strcmp (p, "8K") == 0)		  mips_cpu = 8000;		break;	      case 'o':		if (strcmp (p, "orion") == 0)		  mips_cpu = 4600;		break;	      }	    if (sv		&& (mips_cpu != 4300		    && mips_cpu != 4100		    && mips_cpu != 4111		    && mips_cpu != 5000))	      {		as_bad (_("ignoring invalid leading 'v' in -mcpu=%s switch"), arg);		return 0;	      }	    if (mips_cpu == -1)	      {		as_bad (_("invalid architecture -mcpu=%s"), arg);		return 0;	      }	  }      }      break;    case OPTION_M4650:      mips_cpu = 4650;      break;    case OPTION_NO_M4650:      break;    case OPTION_M4010:      mips_cpu = 4010;      break;    case OPTION_NO_M4010:      break;    case OPTION_M4100:      mips_cpu = 4100;      break;    case OPTION_NO_M4100:      break;    case OPTION_M3900:      mips_cpu = 3900;      break;          case OPTION_NO_M3900:      break;    case OPTION_MIPS16:      mips_opts.mips16 = 1;      mips_no_prev_insn (false);      break;    case OPTION_NO_MIPS16:      mips_opts.mips16 = 0;      mips_no_prev_insn (false);      break;    case OPTION_MEMBEDDED_PIC:      mips_pic = EMBEDDED_PIC;      if (USE_GLOBAL_POINTER_OPT && g_switch_seen)	{	  as_bad (_("-G may not be used with embedded PIC code"));	  return 0;	}      g_switch_value = 0x7fffffff;      break;      /* When generating ELF code, we permit -KPIC and -call_shared to	 select SVR4_PIC, and -non_shared to select no PIC.  This is	 intended to be compatible with Irix 5.  */    case OPTION_CALL_SHARED:      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)	{	  as_bad (_("-call_shared is supported only for ELF format"));	  return 0;	}      mips_pic = SVR4_PIC;      if (g_switch_seen && g_switch_value != 0)	{	  as_bad (_("-G may not be used with SVR4 PIC code"));	  return 0;	}      g_switch_value = 0;      break;    case OPTION_NON_SHARED:      if (OUTPUT_FLAVOR != bfd_target_elf_flavour)	{	  as_bad (_("-non_shared is supported only for ELF format"));	  return 0;	}      mips_pic = NO_PIC;      break;      /* The -xgot option tells the assembler to use 32 offsets when         accessing the got in SVR4_PIC mode.  It is for Irix         compatibility.  */    case OPTION_XGOT:      mips_big_got = 1;      break;    case 'G':      if (! USE_GLOBAL_POINTER_OPT)	{	  as_bad (_("-G is not supported for this configuration"));	  return 0;	}      else if (mips_pic == SVR4_PIC || mips_pic == EMBEDDED_PIC)	{	  as_bad (_("-G may not be used with SVR4 or embedded PIC code"));	  return 0;	}      else	g_switch_value = atoi (arg);      g_switch_seen = 1;      break;      /* The -32 and -64 options tell the assembler to output the 32         bit or the 64 bit MIPS ELF format.  */    case OPTION_32:      mips_64 = 0;      break;    case OPTION_64:      {	const char **list, **l;	list = bfd_target_list ();	for (l = list; *l != NULL; l++)	  if (strcmp (*l, "elf64-bigmips") == 0	      || strcmp (*l, "elf64-littlemips") == 0)	    break;	if (*l == NULL)	  as_fatal (_("No compiled in support for 64 bit object file format"));	free (list);	mips_64 = 1;      }      break;    case OPTION_GP32:      mips_gp32 = 1;      mips_64 = 0;      /* We deliberately don't allow "-gp32" to set the MIPS_32BITMODE	 flag in object files because to do so would make it	 impossible to link with libraries compiled without "-gp32".	 This is unnecessarily restrictive.  	 We could solve this problem by adding "-gp32" multilibs to	 gcc, but to set this flag before gcc is built with such	 multilibs will break too many systems. *//*    mips_32bitmode = 1; */      break;    case OPTION_GP64:      mips_gp32 = 0;      mips_64 = 1;/*    mips_32bitmode = 0; */      break;    case OPTION_MABI:      if (strcmp (arg,"32") == 0	  || strcmp (arg,"n32") == 0	  || strcmp (arg,"64") == 0	  || strcmp (arg,"o64") == 0	  || strcmp (arg,"eabi") == 0)	mips_abi_string = arg;      break;    case OPTION_M7000_HILO_FIX:      mips_7000_hilo_fix = true;      break;    case OPTION_NO_M7000_HILO_FIX:      mips_7000_hilo_fix = false;      break;    default:      return 0;    }  return 1;}static voidshow (stream, string, col_p, first_p)     FILE *stream;     char *string;     int *col_p;     int *first_p;{  if (*first_p)    {      fprintf (stream, "%24s", "");      *col_p = 24;    }  else    {      fprintf (stream, ", ");      *col_p += 2;    }  if (*col_p + strlen (string) > 72)    {      fprintf (stream, "\n%24s", "");      *col_p = 24;    }  fprintf (stream, "%s", string);  *col_p += strlen (string);  *first_p = 0;}voidmd_show_usage (stream)     FILE *stream;{  int column, first;  fprintf(stream, _("\MIPS options:\n\-membedded-pic		generate embedded position independent code\n\-EB			generate big endian output\n\-EL			generate little endian output\n\-g, -g2			do not remove uneeded NOPs or swap branches\n\-G NUM			allow referencing objects up to NUM bytes\n\			implicitly with the gp register [default 8]\n"));  fprintf(stream, _("\-mips1			generate MIPS ISA I instructions\n\-mips2			generate MIPS ISA II instructions\n\-mips3			generate MIPS ISA III instructions\n\-mips4			generate MIPS ISA IV instructions\n\-mcpu=CPU		generate code for CPU, where CPU is one of:\n"));  first = 1;  show (stream, "2000", &column, &first);  show (stream, "3000", &column, &first);  show (stream, "3900", &column, &first);  show (stream, "4000", &column, &first);  show (stream, "4010", &column, &first);  show (stream, "4100", &column, &first);  show (stream, "4111", &column, &first);  show (stream, "4300", &column, &first);  show (stream, "4400", &column, &first);  show (stream, "4600", &column, &first);  show (stream, "4650", &column, &first);  show (stream, "5000", &column, &first);  show (stream, "6000", &column, &first);  show (stream, "8000", &column, &first);  show (stream, "10000", &column, &first);  fputc ('\n', stream);  fprintf (stream, _("\-mCPU			equivalent to -mcpu=CPU.\n\-no-mCPU		don't generate code specific to CPU.\n\			For -mCPU and -no-mCPU, CPU must be one of:\n"));  first = 1;  show (stream, "3900", &column, &first);  show (stream, "4010", &column, &first);  show (stream, "4100", &column, &first);  show (stream, "4650", &column, &first);  fputc ('\n', stream);  fprintf(stream, _("\-mips16			generate mips16 instructions\n\-no-mips16		do not generate mips16 instructions\n"));  fprintf(stream, _("\-O0			remove unneeded NOPs, do not swap branches\n\-O			remove unneeded NOPs and swap branches\n\--trap, --no-break	trap exception on div by 0 and mult overflow\n\--break, --no-trap	break exception on div by 0 and mult overflow\n"));#ifdef OBJ_ELF  fprintf(stream, _("\-KPIC, -call_shared	generate SVR4 position independent code\n\-non_shared		do not generate position independent code\n\-xgot			assume a 32 bit GOT\n\-32			create 32 bit object file (default)\n\-64			create 64 bit object file\n"));#endif}voidmips_init_after_args (){  /* initialize opcodes */  bfd_mips_num_opcodes = bfd_mips_num_builtin_opcodes;  mips_opcodes = (struct mips_opcode*) mips_builtin_opcodes;}longmd_pcrel_from (fixP)     fixS *fixP;{  if (OUTPUT_FLAVOR != bfd_target_aout_flavour      && fixP->fx_addsy != (symbolS *) NULL      && ! S_IS_DEFINED (fixP->fx_addsy))    {      /* This makes a branch to an undefined symbol be a branch to the	 current location.  */      return 4;    }  /* return the address of the delay slot */  return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;}/* This is called by emit_expr via TC_CONS_FIX_NEW when creating a   reloc for a cons.  We could use the definition there, except that   we want to handle 64 bit relocs specially.  */voidcons_fix_new_mips (frag, where, nbytes, exp)     fragS *frag;     int where;     unsigned int nbytes;     expressionS *exp;{#ifndef OBJ_ELF  /* If we are assembling in 32 bit mode, turn an 8 byte reloc into a     4 byte reloc.  */  if (nbytes == 8 && ! mips_64)    {      if (target_big_endian)	where += 4;      nbytes = 4;    }#endif  if (nbytes != 2 && nbytes != 4 && nbytes != 8)    as_bad (_("Unsupported reloc size %d"), nbytes);  fix_new_exp (frag_now, where, (int) nbytes, exp, 0,	       (nbytes == 2		? BFD_RELOC_16		: (nbytes == 4 ? BFD_RELOC_32 : BFD_RELOC_64)));}/* This is called before the symbol table is processed.  In order to   work with gcc when using mips-tfile, we must keep all local labels.   However, in other cases, we want to discard them.  If we were   called with -g, but we didn't see any debugging information, it may   mean that gcc is smuggling debugging information through to   mips-tfile, in which case we must generate all local labels.  */voidmips_frob_file_before_adjust (){#ifndef NO_ECOFF_DEBUGGING  if (ECOFF_DEBUGGING      && mips_debug != 0      && ! ecoff_debugging_seen)    flag_keep_locals = 1;#endif}/* Sort any unmatched HI16_S relocs so that they immediately precede   the corresponding LO reloc.  This is called before md_apply_fix and   tc_gen_reloc.  Unmatched HI16_S relocs can only be generated by   explicit use of the %hi modifier.  */voidmips_frob_file (){  struct mips_hi_fixup *l;  for (l = mips_hi_fixup_list; l != NULL; l = l->next)    {      segment_info_type *seginfo;      int pass;      assert (l->fixp->fx_r_type == BFD_RELOC_HI16_S);      /* Check quickly whether the next fixup happens to be a matching         %lo.  */      if (l->fixp->fx_next != NULL	  && l->fixp->fx_next->fx_r_type == BFD_RELOC_LO16	  && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy	  && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)	continue;      /* Look through the fixups for this segment for a matching %lo.         When we find one, move the %hi just in front of it.  We do         this in two passes.  In the first pass, we try to find a         unique %lo.  In the second pass, we permit multiple %hi         relocs for a single %lo (this is a GNU extension).  */      seginfo = seg_info (l->seg);      for (pass = 0; pass < 2; pass++)	{	  fixS *f, *prev;	  prev = NULL;	  for (f = seginfo->fix_root; f != NULL; f = f->fx_next)	    {	      /* Check whether this is a %lo fixup which matches l->fixp.  */	      if (f->fx_r_type == BFD_RELOC_LO16		  && f->fx_addsy == l->fixp->fx_addsy		  && f->fx_offset == l->fixp->fx_offset		  && (pass == 1		      || prev == NULL		      || prev->fx_r_type != BFD_RELOC_HI16_S		      || prev->fx_addsy != f->fx_addsy		      || prev->fx_offset !=  f->fx_offset))		{		  fixS **pf;		  /* Move l->fixp before f.  */		  for (pf = &seginfo->fix_root;		       *pf != l->fixp;		       pf = &(*pf)->fx_next)		    assert (*pf != NULL);		  *pf = l->fixp->fx_next;		  l->fixp->fx_next = f;		  if (prev == NULL)		    seginfo->fix_root = l->fixp;		  else		    prev->fx_next = l->fixp;		  break;		}	      prev = f;	    }	  if (f != NULL)	    break;#if 0 /* GCC code motion plus incomplete dead code elimination	 can leave a %hi without a %lo.  */	  if (pass == 1)	    as_warn_where (l->fixp->fx_file, l->fixp->fx_line,			   _("Unmatched %%hi reloc"));#endif	}    }}/* When generating embedded PIC code we need to use a special   relocation to represent the difference of two symbols in the .text   section (switch tables use a difference of this sort).  See   include/coff/mips.h for details.  This macro checks whether this   fixup requires the special reloc.  */#define SWITCH_TABLE(fixp) \  ((fixp)->fx_r_type == BFD_RELOC_32 \   && OUTPUT_FLAVOR != bfd_target_elf_flavour \   && (fixp)->fx_addsy != NULL \   && (fixp)->fx_subsy != NULL \   && S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \   && S_GET_SEGMENT ((fixp)->fx_subsy) == text_section)/* When generating embedded PIC code we must keep all PC relative   relocations, in case the linker has to relax a call.  We also need   to keep relocations for switch table entries.  *//*ARGSUSED*/intmips_force_relocation (fixp)     fixS *fixp;{  if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT      || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)    return 1;  return (mips_pic == EMBEDDED_PIC	  && (fixp->fx_pcrel	      || SWITCH_TABLE (fixp)	      || fixp->fx_r_type == BFD_RELOC_PCREL_HI16_S	      || fixp->fx_r_type == BFD_RELOC_PCREL_LO16));}/* Apply a fixup to the object file.  */intmd_apply_fix (fixP, valueP)     fixS *fixP;     valueT *valueP;{  unsigned char *buf;  long insn, value;  assert (fixP->fx_size == 4	  || fixP->fx_r_type == BFD_RELOC_16	  || fixP->fx_r_type == BFD_RELOC_64	  || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT	  || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY);  value = *valueP;  /* If we aren't adjusting this fixup to be against the section     symbol, we need to adjust the value.  */#ifdef OBJ_ELF  if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)    {    if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16         || S_IS_WEAK (fixP->fx_addsy)        || (symbol_used_in_reloc_p (fixP->fx_addsy)            && (((bfd_get_section_flags (stdoutput,                                         S_GET_SEGMENT (fixP->fx_addsy))                  & SEC_LINK_ONCE) != 0)                || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),                             ".gnu.linkonce",                             sizeof (".gnu.linkonce") - 1))))      {        value -= S_GET_VALUE (fixP->fx_addsy);        if (value != 0 && ! fixP->fx_pcrel)          {            /* In this case, the bfd_install_relocation routine will               incorrectly add the symbol value back in.  We just want               the addend to appear in the object file.  	       FIXME: If this makes VALUE zero, we're toast.  */            value -= S_GET_VALUE (fixP->fx_addsy);          }      }      /* This code was generated using trial and error and so is	 fragile and not trustworthy.  If you change it, you should	 rerun the elf-rel, elf-rel2, and empic testcases and ensure	 they still pass.  */      if (fixP->fx_pcrel || fixP->fx_subsy != NULL)	{	  value += fixP->fx_frag->fr_address + fixP->fx_where;	  /* BFD's REL handling, for MIPS, is _very_ weird.	     This gives the right results, but it can't possibly	     be the way things are supposed to work.  */	  if (fixP->fx_r_type != BFD_RELOC_16_PCREL_S2	      || S_GET_SEGMENT (fixP->fx_addsy) != undefined_section)	    value += fixP->fx_frag->fr_address + fixP->fx_where;	}    }#endif  fixP->fx_addnumber = value;	/* Remember value for tc_gen_reloc */  if (fixP->fx_addsy == NULL && ! fixP->fx_pcrel)    fixP->fx_done = 1;  switch (fixP->fx_r_type)    {    case BFD_RELOC_MIPS_JMP:    case BFD_RELOC_HI16:    case BFD_RELOC_HI16_S:    case BFD_RELOC_MIPS_GPREL:    case BFD_RELOC_MIPS_LITERAL:    case BFD_RELOC_MIPS_CALL16:    case BFD_RELOC_MIPS_GOT16:    case BFD_RELOC_MIPS_GPREL32:    case BFD_RELOC_MIPS_GOT_HI16:    case BFD_RELOC_MIPS_GOT_LO16:    case BFD_RELOC_MIPS_CALL_HI16:    case BFD_RELOC_MIPS_CALL_LO16:    case BFD_RELOC_MIPS16_GPREL:      if (fixP->fx_pcrel)	as_bad_where (fixP->fx_file, fixP->fx_line,		      _("Invalid PC relative reloc"));      /* Nothing needed to do. The value comes from the reloc entry */      break;    case BFD_RELOC_MIPS16_JMP:      /* We currently always generate a reloc against a symbol, which         means that we don't want an addend even if the symbol is         defined.  */      fixP->fx_addnumber = 0;      break;    case BFD_RELOC_PCREL_HI16_S:      /* The addend for this is tricky if it is internal, so we just	 do everything here rather than in bfd_install_relocation.  */      if (OUTPUT_FLAVOR == bfd_target_elf_flavour 	  && !fixP->fx_done	  && value != 0)	break;      if (fixP->fx_addsy	  && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)	{	  /* For an external symbol adjust by the address to make it	     pcrel_offset.  We use the address of the RELLO reloc	     which follows this one.  */	  value += (fixP->fx_next->fx_frag->fr_address		    + fixP->fx_next->fx_where);	}      if (value & 0x8000)	value += 0x10000;      value >>= 16;      buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;      if (target_big_endian)	buf += 2;      md_number_to_chars (buf, value, 2);      break;    case BFD_RELOC_PCREL_LO16:      /* The addend for this is tricky if it is internal, so we just	 do everything here rather than in bfd_install_relocation.  */      if (OUTPUT_FLAVOR == bfd_target_elf_flavour 	  && !fixP->fx_done	  && value != 0)	break;      if (fixP->fx_addsy	  && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)	value += fixP->fx_frag->fr_address + fixP->fx_where;      buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;      if (target_big_endian)	buf += 2;      md_number_to_chars (buf, value, 2);      break;    case BFD_RELOC_64:      /* This is handled like BFD_RELOC_32, but we output a sign         extended value if we are only 32 bits.  */      if (fixP->fx_done	  || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))	{	  if (8 <= sizeof (valueT))	    md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,				value, 8);	  else	    {	      long w1, w2;	      long hiv;	      w1 = w2 = fixP->fx_where;	      if (target_big_endian)		w1 += 4;	      else		w2 += 4;	      md_number_to_chars (fixP->fx_frag->fr_literal + w1, value, 4);	      if ((value & 0x80000000) != 0)		hiv = 0xffffffff;	      else		hiv = 0;	      md_number_to_chars (fixP->fx_frag->fr_literal + w2, hiv, 4);	    }	}      break;    case BFD_RELOC_RVA:    case BFD_RELOC_32:      /* If we are deleting this reloc entry, we must fill in the	 value now.  This can happen if we have a .word which is not	 resolved when it appears but is later defined.  We also need	 to fill in the value if this is an embedded PIC switch table	 entry.  */      if (fixP->fx_done	  || (mips_pic == EMBEDDED_PIC && SWITCH_TABLE (fixP)))	md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,			    value, 4);      break;    case BFD_RELOC_16:      /* If we are deleting this reloc entry, we must fill in the         value now.  */      assert (fixP->fx_size == 2);      if (fixP->fx_done)	md_number_to_chars (fixP->fx_frag->fr_literal + fixP->fx_where,			    value, 2);      break;    case BFD_RELOC_LO16:      /* When handling an embedded PIC switch statement, we can wind	 up deleting a LO16 reloc.  See the 'o' case in mips_ip.  */      if (fixP->fx_done)	{	  if (value < -0x8000 || value > 0x7fff)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  _("relocation overflow"));	  buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;	  if (target_big_endian)	    buf += 2;	  md_number_to_chars (buf, value, 2);	}      break;    case BFD_RELOC_16_PCREL_S2:      /*       * We need to save the bits in the instruction since fixup_segment()       * might be deleting the relocation entry (i.e., a branch within       * the current segment).       */      if ((value & 0x3) != 0)	as_bad_where (fixP->fx_file, fixP->fx_line,		      _("Branch to odd address (%lx)"), value);      if (!fixP->fx_done && value != 0)	break;      /* If 'value' is zero, the remaining reloc code won't actually	 do the store, so it must be done here.  This is probably	 a bug somewhere.  */      if (!fixP->fx_done)	value -= fixP->fx_frag->fr_address + fixP->fx_where;            value >>= 2;      /* update old instruction data */      buf = (unsigned char *) (fixP->fx_where + fixP->fx_frag->fr_literal);      if (target_big_endian)	insn = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];      else	insn = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];      if (value >= -0x8000 && value < 0x8000)	insn |= value & 0xffff;      else	{	  /* The branch offset is too large.  If this is an             unconditional branch, and we are not generating PIC code,             we can convert it to an absolute jump instruction.  */	  if (mips_pic == NO_PIC	      && fixP->fx_done	      && fixP->fx_frag->fr_address >= text_section->vma	      && (fixP->fx_frag->fr_address		  < text_section->vma + text_section->_raw_size)	      && ((insn & 0xffff0000) == 0x10000000	 /* beq $0,$0 */		  || (insn & 0xffff0000) == 0x04010000	 /* bgez $0 */		  || (insn & 0xffff0000) == 0x04110000)) /* bgezal $0 */	    {	      if ((insn & 0xffff0000) == 0x04110000)	 /* bgezal $0 */		insn = 0x0c000000;	/* jal */	      else		insn = 0x08000000;	/* j */	      fixP->fx_r_type = BFD_RELOC_MIPS_JMP;	      fixP->fx_done = 0;	      fixP->fx_addsy = section_symbol (text_section);	      fixP->fx_addnumber = (value << 2) + md_pcrel_from (fixP);	    }	  else	    {	      /* FIXME.  It would be possible in principle to handle                 conditional branches which overflow.  They could be                 transformed into a branch around a jump.  This would                 require setting up variant frags for each different                 branch type.  The native MIPS assembler attempts to                 handle these cases, but it appears to do it                 incorrectly.  */	      as_bad_where (fixP->fx_file, fixP->fx_line,			    _("Branch out of range"));	    }	}      md_number_to_chars ((char *) buf, (valueT) insn, 4);      break;    case BFD_RELOC_VTABLE_INHERIT:      fixP->fx_done = 0;      if (fixP->fx_addsy          && !S_IS_DEFINED (fixP->fx_addsy)          && !S_IS_WEAK (fixP->fx_addsy))        S_SET_WEAK (fixP->fx_addsy);      break;    case BFD_RELOC_VTABLE_ENTRY:      fixP->fx_done = 0;      break;    default:      internalError ();    }  return 1;}#if 0voidprintInsn (oc)     unsigned long oc;{  const struct mips_opcode *p;  int treg, sreg, dreg, shamt;  short imm;  const char *args;  int i;  for (i = 0; i < NUMOPCODES; ++i)    {      p = &mips_opcodes[i];      if (((oc & p->mask) == p->match) && (p->pinfo != INSN_MACRO))	{	  printf ("%08lx %s\t", oc, p->name);	  treg = (oc >> 16) & 0x1f;	  sreg = (oc >> 21) & 0x1f;	  dreg = (oc >> 11) & 0x1f;	  shamt = (oc >> 6) & 0x1f;	  imm = oc;	  for (args = p->args;; ++args)	    {	      switch (*args)		{		case '\0':		  printf ("\n");		  break;		case ',':		case '(':		case ')':		  printf ("%c", *args);		  continue;		case 'r':		  assert (treg == sreg);		  printf ("$%d,$%d", treg, sreg);		  continue;		case 'd':		case 'G':		  printf ("$%d", dreg);		  continue;		case 't':		case 'E':		  printf ("$%d", treg);		  continue;		case 'k':		  printf ("0x%x", treg);		  continue;		case 'b':		case 's':		  printf ("$%d", sreg);		  continue;		case 'a':		  printf ("0x%08lx", oc & 0x1ffffff);		  continue;		case 'i':		case 'j':		case 'o':		case 'u':		  printf ("%d", imm);		  continue;		case '<':		case '>':		  printf ("$%d", shamt);		  continue;		default:		  internalError ();		}	      break;	    }	  return;	}    }  printf (_("%08lx  UNDEFINED\n"), oc);}#endifstatic symbolS *get_symbol (){  int c;  char *name;  symbolS *p;  name = input_line_pointer;  c = get_symbol_end ();  p = (symbolS *) symbol_find_or_make (name);  *input_line_pointer = c;  return p;}