gnu/usr.bin/binutils-2.17/gas/config/tc-arm.c
/* Parse a directive saving core registers.  */
Parse a directive saving core registers.
Parse a directive saving core registers .
static void
s_arm_unwind_save_core (void)
{
  valueT op;
  long range;
  int n;
  range = parse_reg_list (&input_line_pointer);
  if (range == FAIL)
    {
      as_bad (_("expected register list"));
      ignore_rest_of_line ();
      return;
    }
  demand_empty_rest_of_line ();
  if (unwind.sp_restored && unwind.fp_reg == 12
      && (range & 0x3000) == 0x1000)
    {
      unwind.opcode_count--;
      unwind.sp_restored = 0;
      range = (range | 0x2000) & ~0x1000;
      unwind.pending_offset = 0;
    }
  if (range & 0xfff0)
    {
      for (n = 0; n < 8; n++)
	{
	  if ((range & (1 << (n + 4))) == 0)
	    break;
	}
      if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
	{
	  op = 0x8000 | ((range >> 4) & 0xfff);
	  add_unwind_opcode (op, 2);
	}
      else
	{
	  if (range & 0x4000)
	    op = 0xa8; 
	  else
	    op = 0xa0; 
	  op |= (n - 1);
	  add_unwind_opcode (op, 1);
	}
    }
  if (range & 0xf)
    {
      op = 0xb100 | (range & 0xf);
      add_unwind_opcode (op, 2);
    }
  for (n = 0; n < 16; n++)
    {
      if (range & (1 << n))
	unwind.frame_size += 4;
    }
}
static void s_arm_unwind_save_core ( void ) { valueT op ; long range ; int n ; range = parse_reg_list ( & input_line_pointer ) ; if ( range == FAIL ) { as_bad ( _ ( " " ) ) ; ignore_rest_of_line ( ) ; return ; } demand_empty_rest_of_line ( ) ; if ( unwind . sp_restored && unwind . fp_reg == 12 && ( range & 0x3000 ) == 0x1000 ) { unwind . opcode_count -- ; unwind . sp_restored = 0 ; range = ( range | 0x2000 ) & ~ 0x1000 ; unwind . pending_offset = 0 ; } if ( range & 0xfff0 ) { for ( n = 0 ; n < 8 ; n ++ ) { if ( ( range & ( 1 << ( n + 4 ) ) ) == 0 ) break ; } if ( n == 0 || ( range & ( 0xfff0 << n ) & 0xbff0 ) != 0 ) { op = 0x8000 | ( ( range >> 4 ) & 0xfff ) ; add_unwind_opcode ( op , 2 ) ; } else { if ( range & 0x4000 ) op = 0xa8 ; else op = 0xa0 ; op |= ( n - 1 ) ; add_unwind_opcode ( op , 1 ) ; } } if ( range & 0xf ) { op = 0xb100 | ( range & 0xf ) ; add_unwind_opcode ( op , 2 ) ; } for ( n = 0 ; n < 16 ; n ++ ) { if ( range & ( 1 << n ) ) unwind . frame_size += 4 ; } }
Parse a directive saving core registers.
Parse a directive saving core registers .
/* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
     into .unwind_save {..., sp...}.  We aren't bothered about the value of
     ip because it is clobbered by calls.  */ /* Pop r4-r15.  */ /* See if we can use the short opcodes.  These pop a block of up to 8
	 registers starting with r4, plus maybe r14.  */ /* Break at the first non-saved register.	 */ /* See if there are any other bits set.  */ /* Use the long form.  */ /* Use the short form.  */ /* Pop r14.	*/ /* Do not pop r14.  */ /* Pop r0-r3.	 */ /* Record the number of bytes pushed.	 */