last_insn = insn;
md_assemble (str)     char *str;{  char *toP;  int rsd;  know (str);  sparc_ip (str);  /* See if "set" operand is absolute and small; skip sethi if so. */  if (special_case == SPECIAL_CASE_SET      && the_insn.exp.X_op == O_constant)    {      if (the_insn.exp.X_add_number >= -(1 << 12)	  && the_insn.exp.X_add_number < (1 << 12))	{	  the_insn.opcode = 0x80102000	/* or %g0,imm,... */	    | (the_insn.opcode & 0x3E000000)	/* dest reg */	    | (the_insn.exp.X_add_number & 0x1FFF);	/* imm */	  special_case = 0;	/* No longer special */	  the_insn.reloc = BFD_RELOC_NONE;	/* No longer relocated */	}    }  toP = frag_more (4);  /* put out the opcode */  md_number_to_chars (toP, (valueT) the_insn.opcode, 4);  /* put out the symbol-dependent stuff */  if (the_insn.reloc != BFD_RELOC_NONE)    {      fix_new_exp (frag_now,	/* which frag */		   (toP - frag_now->fr_literal),	/* where */		   4,		/* size */		   &the_insn.exp,		   the_insn.pcrel,		   the_insn.reloc);    }  switch (special_case)    {    case SPECIAL_CASE_SET:      special_case = 0;      assert (the_insn.reloc == BFD_RELOC_HI22);      /* See if "set" operand has no low-order bits; skip OR if so. */      if (the_insn.exp.X_op == O_constant	  && ((the_insn.exp.X_add_number & 0x3FF) == 0))	return;      toP = frag_more (4);      rsd = (the_insn.opcode >> 25) & 0x1f;      the_insn.opcode = 0x80102000 | (rsd << 25) | (rsd << 14);      md_number_to_chars (toP, (valueT) the_insn.opcode, 4);      fix_new_exp (frag_now,	/* which frag */		   (toP - frag_now->fr_literal),	/* where */		   4,		/* size */		   &the_insn.exp,		   the_insn.pcrel,		   BFD_RELOC_LO10);      return;    case SPECIAL_CASE_FDIV:      /* According to information leaked from Sun, the "fdiv" instructions	 on early SPARC machines would produce incorrect results sometimes.	 The workaround is to add an fmovs of the destination register to	 itself just after the instruction.  This was true on machines	 with Weitek 1165 float chips, such as the Sun-4/260 and /280. */      special_case = 0;      assert (the_insn.reloc == BFD_RELOC_NONE);      toP = frag_more (4);      rsd = (the_insn.opcode >> 25) & 0x1f;      the_insn.opcode = 0x81A00020 | (rsd << 25) | rsd;	/* fmovs dest,dest */      md_number_to_chars (toP, (valueT) the_insn.opcode, 4);      return;    case 0:      return;    default:      as_fatal ("failed sanity check.");    }}