fixp = fix_new_exp (frag_now, f - frag_now->fr_literal, 4, address_expr, reloc_type == BFD_RELOC_16_PCREL_S2, reloc_type);
{ 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; } }
append_insn (place, ip, address_expr, reloc_type)     char *place;     struct mips_cl_insn *ip;     expressionS *address_expr;     bfd_reloc_code_real_type reloc_type;{  register unsigned long prev_pinfo, pinfo;  char *f;  fixS *fixp;  int nops = 0;  prev_pinfo = prev_insn.insn_mo->pinfo;  pinfo = ip->insn_mo->pinfo;  if (place == NULL && ! mips_noreorder)    {      /* 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() 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_isa < 4	  && ((prev_pinfo & INSN_LOAD_COPROC_DELAY)	      || (mips_isa < 2		  && (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.  */	  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),				0))	    ++nops;	}      else if (mips_isa < 4	       && ((prev_pinfo & INSN_COPROC_MOVE_DELAY)		   || (mips_isa < 2		       && (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.  */	  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),				    1))		++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),				    1))		++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.  */	      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_isa < 4	       && (prev_pinfo & INSN_WRITE_COND_CODE))	{	  /* 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.  */	  if (mips_optimize == 0	      || (pinfo & INSN_READ_COND_CODE))	    ++nops;	}      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.  The R4650 and VR4100 have interlocks.  */	  if (! interlocks	      && (mips_optimize == 0		  || (pinfo & INSN_WRITE_LO)))	    nops += 2;	}      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.  The R4650 and VR4100 have interlocks.  */	  if (! interlocks	      && (mips_optimize == 0		  || (pinfo & INSN_WRITE_HI)))	    nops += 2;	}      /* 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 the R4650,	 and VR4100 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 (nops == 0	  && ((mips_isa < 4	       && (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))	      || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_LO)		  && (pinfo & INSN_WRITE_LO)		  && ! interlocks)	      || ((prev_prev_insn.insn_mo->pinfo & INSN_READ_HI)		  && (pinfo & INSN_WRITE_HI)		  && ! interlocks)))	++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 && ip->insn_opcode == 0)	--nops;      /* Now emit the right number of NOP instructions.  */      if (nops > 0)	{	  int i;	  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);	    }	  if (insn_label != NULL)	    {	      assert (S_GET_SEGMENT (insn_label) == now_seg);	      insn_label->sy_frag = frag_now;	      S_SET_VALUE (insn_label, (valueT) frag_now_fix ());	    }	}    }    if (place == NULL)    f = frag_more (4);  else    f = place;  fixp = NULL;  if (address_expr != NULL)    {      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:	    case BFD_RELOC_16_PCREL_S2:	      goto need_reloc;	    default:	      internalError ();	    }	}      else	{	  assert (reloc_type != BFD_RELOC_UNUSED);	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);	}    }  md_number_to_chars (f, ip->insn_opcode, 4);  /* Update the register mask information.  */  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.  */    }  /* Never set the bit for $0, which is always zero.  */  mips_gprmask &=~ 1 << 0;  if (place == NULL && ! mips_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_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_label != NULL	      /* If the previous instruction is in a variant frag, we		 can not do the swap.  */	      || 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_isa < 4		  && (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_isa < 4		  && (prev_pinfo		      & (INSN_LOAD_COPROC_DELAY			 | INSN_COPROC_MOVE_DELAY			 | INSN_WRITE_COND_CODE)))	      || (! interlocks		  && (prev_pinfo		      & (INSN_READ_LO			 | INSN_READ_HI)))	      || (mips_isa < 2		  && (prev_pinfo		      & (INSN_LOAD_MEMORY_DELAY			 | 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.  */	      || ((prev_pinfo & INSN_WRITE_GPR_T)		  && insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_RT)				     & OP_MASK_RT),				    0))	      || ((prev_pinfo & INSN_WRITE_GPR_D)		  && insn_uses_reg (ip,				    ((prev_insn.insn_opcode >> OP_SH_RD)				     & OP_MASK_RD),				    0))	      /* 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).  */	      || ((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))))	      || ((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))))	      /* 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).  */	      || ((pinfo & INSN_WRITE_GPR_D)		  && insn_uses_reg (&prev_insn,				    ((ip->insn_opcode >> OP_SH_RD)				     & OP_MASK_RD),				    0))	      || ((pinfo & INSN_WRITE_GPR_31)		  && insn_uses_reg (&prev_insn, 31, 0))	      /* 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, 0))	      /* If the previous previous instruction has a load		 delay, and sets a register that the branch reads, we		 can not swap.  */	      || (mips_isa < 4		  && ((prev_prev_insn.insn_mo->pinfo & INSN_LOAD_COPROC_DELAY)		      || (mips_isa < 2			  && (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),				    0)))	    {	      /* 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	    {	      char *prev_f;	      char temp[4];	      /* It looks like we can actually do the swap.  */	      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;		}	      /* 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;	    }	}      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;	}      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_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_fixp = fixp;      prev_insn_valid = 1;    }  /* We just output an insn, so the next one doesn't have a label.  */  insn_label = NULL;}