"shift expression is too large");
_("shift expression is too large"));
md_apply_fix3 (fixP, val, seg)     fixS *fixP;     valueT *val;     segT seg;{  offsetT value = *val;  offsetT newval, temp;  int sign;  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;  arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;  assert (fixP->fx_r_type < BFD_RELOC_UNUSED);  /* Note whether this will delete the relocation.  */  if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)    fixP->fx_done = 1;  /* If this symbol is in a different section then we need to leave it for     the linker to deal with.  Unfortunately, md_pcrel_from can't tell,     so we have to undo it's effects here.  */  if (fixP->fx_pcrel)    {      if (S_IS_DEFINED (fixP->fx_addsy)	  && S_GET_SEGMENT (fixP->fx_addsy) != seg)	value += md_pcrel_from (fixP);    }  fixP->fx_addnumber = value;	/* Remember value for emit_reloc */  switch (fixP->fx_r_type)    {    case BFD_RELOC_ARM_IMMEDIATE:      newval = validate_immediate (value);      temp = md_chars_to_number (buf, INSN_SIZE);      /* If the instruction will fail, see if we can fix things up by	 changing the opcode.  */      if (newval == FAIL	  && (newval = negate_data_op (&temp, value)) == FAIL)	{	  as_bad_where (fixP->fx_file, fixP->fx_line,			"invalid constant after fixup\n");	  break;	}      newval |= (temp & 0xfffff000);      md_number_to_chars (buf, newval, INSN_SIZE);      break;     case BFD_RELOC_ARM_OFFSET_IMM:      sign = value >= 0;      if ((value = validate_offset_imm (value, 0)) == FAIL)        {          as_bad ("bad immediate value for offset (%d)", val);          break;        }      if (value < 0)	value = -value;      newval = md_chars_to_number (buf, INSN_SIZE);      newval &= 0xff7ff000;      newval |= value | (sign ? INDEX_UP : 0);      md_number_to_chars (buf, newval, INSN_SIZE);      break;     case BFD_RELOC_ARM_OFFSET_IMM8:     case BFD_RELOC_ARM_HWLITERAL:      sign = value >= 0;      if ((value = validate_offset_imm (value, 1)) == FAIL)        {          if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)	    as_bad_where (fixP->fx_file, fixP->fx_line, 			"invalid literal constant: pool needs to be closer\n");          else            as_bad ("bad immediate value for offset (%d)", value);          break;        }      if (value < 0)	value = -value;      newval = md_chars_to_number (buf, INSN_SIZE);      newval &= 0xff7ff0f0;      newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);      md_number_to_chars (buf, newval, INSN_SIZE);      break;    case BFD_RELOC_ARM_LITERAL:      sign = value >= 0;      if (value < 0)	value = -value;      if ((value = validate_offset_imm (value, 0)) == FAIL)	{	  as_bad_where (fixP->fx_file, fixP->fx_line, 			"invalid literal constant: pool needs to be closer\n");	  break;	}      newval = md_chars_to_number (buf, INSN_SIZE);      newval &= 0xff7ff000;      newval |= value | (sign ? INDEX_UP : 0);      md_number_to_chars (buf, newval, INSN_SIZE);      break;    case BFD_RELOC_ARM_SHIFT_IMM:      newval = md_chars_to_number (buf, INSN_SIZE);      if (((unsigned long) value) > 32	  || (value == 32 	      && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))	{	  as_bad_where (fixP->fx_file, fixP->fx_line,			"shift expression is too large");	  break;	}      if (value == 0)	newval &= ~0x60;	/* Shifts of zero must be done as lsl */      else if (value == 32)	value = 0;      newval &= 0xfffff07f;      newval |= (value & 0x1f) << 7;      md_number_to_chars (buf, newval , INSN_SIZE);      break;    case BFD_RELOC_ARM_SWI:      if (arm_data->thumb_mode)	{	  if (((unsigned long) value) > 0xff)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid swi expression");	  newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;	  newval |= value;	  md_number_to_chars (buf, newval, THUMB_SIZE);	}      else	{	  if (((unsigned long) value) > 0x00ffffff)	    as_bad_where (fixP->fx_file, fixP->fx_line, 			  "Invalid swi expression");	  newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;	  newval |= value;	  md_number_to_chars (buf, newval , INSN_SIZE);	}      break;    case BFD_RELOC_ARM_MULTI:      if (((unsigned long) value) > 0xffff)	as_bad_where (fixP->fx_file, fixP->fx_line,		      "Invalid expression in load/store multiple");      newval = value | md_chars_to_number (buf, INSN_SIZE);      md_number_to_chars (buf, newval, INSN_SIZE);      break;    case BFD_RELOC_ARM_PCREL_BRANCH:      if (arm_data->thumb_mode)	{	  unsigned long newval2;	  newval = md_chars_to_number (buf, THUMB_SIZE);	  if (fixP->fx_size == 4)	    {	      unsigned long diff;	      newval2 = md_chars_to_number (buf, THUMB_SIZE);	      diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);	      if (diff & 0x400000)		diff |= ~0x3fffff;	      value += diff;	      if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))		as_bad_where (fixP->fx_file, fixP->fx_line,			      "Branch with link out of range");	      newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);	      newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);	      md_number_to_chars (buf, newval, THUMB_SIZE);	      md_number_to_chars (buf, newval2, THUMB_SIZE);	    }	  else	    {	      if (newval == T_OPCODE_BRANCH)		{		  unsigned long diff = (newval & 0x7ff) << 1;		  if (diff & 0x800)		    diff |= ~0x7ff;		  value += diff;		  if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))		    as_bad_where (fixP->fx_file, fixP->fx_line,				  "Branch out of range");		  newval = (newval & 0xf800) | ((value & 0xfff) >> 1);		}	      else		{		  unsigned long diff = (newval & 0xff) << 1;		  if (diff & 0x100)		    diff |= ~0xff;		  value += diff;		  if ((value & 0x100) && ((value & ~0xff) != ~0xff))		    as_bad_where (fixP->fx_file, fixP->fx_line,				  "Branch out of range");		  newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);		}	      md_number_to_chars (buf, newval, THUMB_SIZE);	    }	}      else	{	  value = (value >> 2) & 0x00ffffff;	  newval = md_chars_to_number (buf, INSN_SIZE);	  value = (value + (newval & 0x00ffffff)) & 0x00ffffff;	  newval = value | (newval & 0xff000000);	  md_number_to_chars (buf, newval, INSN_SIZE);	}      break;    case BFD_RELOC_8:      if (fixP->fx_done || fixP->fx_pcrel)	md_number_to_chars (buf, value, 1);      break;    case BFD_RELOC_16:      if (fixP->fx_done || fixP->fx_pcrel)	md_number_to_chars (buf, value, 2);      break;    case BFD_RELOC_RVA:    case BFD_RELOC_32:      if (fixP->fx_done || fixP->fx_pcrel)	md_number_to_chars (buf, value, 4);      break;    case BFD_RELOC_ARM_CP_OFF_IMM:      sign = value >= 0;      if (value < -1023 || value > 1023 || (value & 3))	as_bad_where (fixP->fx_file, fixP->fx_line,		      "Illegal value for co-processor offset");      if (value < 0)	value = -value;      newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;      newval |= (value >> 2) | (sign ?  INDEX_UP : 0);      md_number_to_chars (buf, newval , INSN_SIZE);      break;    case BFD_RELOC_ARM_THUMB_OFFSET:      newval = md_chars_to_number (buf, THUMB_SIZE);      /* Exactly what ranges, and where the offset is inserted depends on	 the type of instruction, we can establish this from the top 4 bits */      switch (newval >> 12)	{	case 4: /* PC load */	  /* PC loads are somewhat odd, bit 2 of the PC is forced to zero	     for these loads, so we may need to round up the offset if the	     instruction is not word aligned since the final address must	     be.   */	  if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset, target not word aligned");	  if ((value + 2) & ~0x3fe)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset");	   /* Round up, since pc will be rounded down.  */	  newval |= (value + 2) >> 2;	  break;	case 9: /* SP load/store */	  if (value & ~0x3fc)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset");	  newval |= value >> 2;	  break;	case 6: /* Word load/store */	  if (value & ~0x7c)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset");	  newval |= value << 4; /* 6 - 2 */	  break;	case 7: /* Byte load/store */	  if (value & ~0x1f)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset");	  newval |= value << 6;	  break;	case 8: /* Halfword load/store */	  if (value & ~0x3e)	    as_bad_where (fixP->fx_file, fixP->fx_line,			  "Invalid offset");	  newval |= value << 5; /* 6 - 1 */	  break;	default:	  abort ();	}      md_number_to_chars (buf, newval, THUMB_SIZE);      break;    case BFD_RELOC_ARM_THUMB_ADD:      /* This is a complicated relocation, since we use it for all of         the following immediate relocations:            3bit ADD/SUB            8bit ADD/SUB            9bit ADD/SUB SP word-aligned           10bit ADD PC/SP word-aligned         The type of instruction being processed is encoded in the         instruction field:           0x8000  SUB           0x00F0  Rd           0x000F  Rs      */      newval = md_chars_to_number (buf, THUMB_SIZE);      {        int rd = (newval >> 4) & 0xf;        int rs = newval & 0xf;        int subtract = newval & 0x8000;        if (rd == REG_SP)          {            if (value & ~0x1fc)              as_bad_where (fixP->fx_file, fixP->fx_line,                            "Invalid immediate for stack address calculation");            newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;            newval |= value >> 2;          }        else if (rs == REG_PC || rs == REG_SP)          {            if (subtract ||                value & ~0x3fc)              as_bad_where (fixP->fx_file, fixP->fx_line,                            "Invalid immediate for address calculation (value = 0x%08X)", value);            newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);            newval |= value >> 2;          }        else if (rs == rd)          {            if (value & ~0xff)              as_bad_where (fixP->fx_file, fixP->fx_line,                            "Invalid 8bit immediate");            newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;            newval |= (rd << 8) | value;          }        else          {            if (value & ~0x7)              as_bad_where (fixP->fx_file, fixP->fx_line,                            "Invalid 3bit immediate");            newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;            newval |= rd | (rs << 3) | (value << 6);          }      }      md_number_to_chars (buf, newval , THUMB_SIZE);      break;    case BFD_RELOC_ARM_THUMB_IMM:      newval = md_chars_to_number (buf, THUMB_SIZE);      switch (newval >> 11)        {        case 0x04: /* 8bit immediate MOV */        case 0x05: /* 8bit immediate CMP */          if (value < 0 || value > 255)            as_bad_where (fixP->fx_file, fixP->fx_line,                          "Invalid immediate: %d is too large", value);          newval |= value;          break;        default:          abort ();        }      md_number_to_chars (buf, newval , THUMB_SIZE);      break;    case BFD_RELOC_ARM_THUMB_SHIFT:      /* 5bit shift value (0..31) */      if (value < 0 || value > 31)	as_bad_where (fixP->fx_file, fixP->fx_line,		      "Illegal Thumb shift value: %d", value);      newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;      newval |= value << 6;      md_number_to_chars (buf, newval , THUMB_SIZE);      break;    case BFD_RELOC_NONE:    default:      as_bad_where (fixP->fx_file, fixP->fx_line,		    "Bad relocation fixup type (%d)\n", fixP->fx_r_type);    }  return 1;}