gnu/usr.bin/binutils-2.17/gas/config/tc-arm.c
/* inst.reloc.exp describes an "=expr" load pseudo-operation.
   Determine whether it can be performed with a move instruction; if
   it can, convert inst.instruction to that move instruction and
   return 1; if it can't, convert inst.instruction to a literal-pool
   load and return 0.  If this is not a valid thing to do in the
   current context, set inst.error and return 1.

   inst.operands[i] describes the destination register.	 */
inst.reloc.exp describes an "=expr" load pseudo-operation.
Determine whether it can be performed with a move instruction; if
it can, convert inst.instruction to that move instruction and
return 1; if it can't, convert inst.instruction to a literal-pool
load and return 0.  If this is not a valid thing to do in the
current context, set inst.error and return 1.

inst.operands[i] describes the destination register.
inst . reloc . exp describes an " = expr " load pseudo - operation . Determine whether it can be performed with a move instruction ; if it can convert inst . instruction to that move instruction and return 1 ; if it can ' t convert inst . instruction to a literal - pool load and return 0 . If this is not a valid thing to do in the current context set inst . error and return 1 . inst . operands [ i ] describes the destination register .
static int
move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
{
  unsigned long tbit;
  if (thumb_p)
    tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
  else
    tbit = LOAD_BIT;
  if ((inst.instruction & tbit) == 0)
    {
      inst.error = _("invalid pseudo operation");
      return 1;
    }
  if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol)
    {
      inst.error = _("constant expression expected");
      return 1;
    }
  if (inst.reloc.exp.X_op == O_constant)
    {
      if (thumb_p)
	{
	  if (!unified_syntax && (inst.reloc.exp.X_add_number & ~0xFF) == 0)
	    {
	      inst.instruction	= T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
	      inst.instruction |= inst.reloc.exp.X_add_number;
	      return 1;
	    }
	}
      else
	{
	  int value = encode_arm_immediate (inst.reloc.exp.X_add_number);
	  if (value != FAIL)
	    {
	      inst.instruction &= LITERAL_MASK;
	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
	      inst.instruction |= value & 0xfff;
	      return 1;
	    }
	  value = encode_arm_immediate (~inst.reloc.exp.X_add_number);
	  if (value != FAIL)
	    {
	      inst.instruction &= LITERAL_MASK;
	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
	      inst.instruction |= value & 0xfff;
	      return 1;
	    }
	}
    }
  if (add_to_lit_pool () == FAIL)
    {
      inst.error = _("literal pool insertion failed");
      return 1;
    }
  inst.operands[1].reg = REG_PC;
  inst.operands[1].isreg = 1;
  inst.operands[1].preind = 1;
  inst.reloc.pc_rel = 1;
  inst.reloc.type = (thumb_p
		     ? BFD_RELOC_ARM_THUMB_OFFSET
		     : (mode_3
			? BFD_RELOC_ARM_HWLITERAL
			: BFD_RELOC_ARM_LITERAL));
  return 0;
}
static int move_or_literal_pool ( int i , bfd_boolean thumb_p , bfd_boolean mode_3 ) { unsigned long tbit ; if ( thumb_p ) tbit = ( inst . instruction > 0xffff ) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT ; else tbit = LOAD_BIT ; if ( ( inst . instruction & tbit ) == 0 ) { inst . error = _ ( " " ) ; return 1 ; } if ( inst . reloc . exp . X_op != O_constant && inst . reloc . exp . X_op != O_symbol ) { inst . error = _ ( " " ) ; return 1 ; } if ( inst . reloc . exp . X_op == O_constant ) { if ( thumb_p ) { if ( ! unified_syntax && ( inst . reloc . exp . X_add_number & ~ 0xFF ) == 0 ) { inst . instruction = T_OPCODE_MOV_I8 | ( inst . operands [ i ] . reg << 8 ) ; inst . instruction |= inst . reloc . exp . X_add_number ; return 1 ; } } else { int value = encode_arm_immediate ( inst . reloc . exp . X_add_number ) ; if ( value != FAIL ) { inst . instruction &= LITERAL_MASK ; inst . instruction |= INST_IMMEDIATE | ( OPCODE_MOV << DATA_OP_SHIFT ) ; inst . instruction |= value & 0xfff ; return 1 ; } value = encode_arm_immediate ( ~ inst . reloc . exp . X_add_number ) ; if ( value != FAIL ) { inst . instruction &= LITERAL_MASK ; inst . instruction |= INST_IMMEDIATE | ( OPCODE_MVN << DATA_OP_SHIFT ) ; inst . instruction |= value & 0xfff ; return 1 ; } } } if ( add_to_lit_pool ( ) == FAIL ) { inst . error = _ ( " " ) ; return 1 ; } inst . operands [ 1 ] . reg = REG_PC ; inst . operands [ 1 ] . isreg = 1 ; inst . operands [ 1 ] . preind = 1 ; inst . reloc . pc_rel = 1 ; inst . reloc . type = ( thumb_p ? BFD_RELOC_ARM_THUMB_OFFSET : ( mode_3 ? BFD_RELOC_ARM_HWLITERAL : BFD_RELOC_ARM_LITERAL ) ) ; return 0 ; }
inst.reloc.exp describes an "=expr" load pseudo-operation.
inst . reloc . exp describes an " = expr " load pseudo - operation .
/* This can be done with a mov(1) instruction.  */ /* This can be done with a mov instruction.  */ /* This can be done with a mvn instruction.  */