else if (insn & DW_CFA_offset)
else if ((insn & 0xc0) == DW_CFA_offset)
execute_cfa_program (const unsigned char *insn_ptr,		     const unsigned char *insn_end,		     struct _Unwind_Context *context,		     _Unwind_FrameState *fs){  struct frame_state_reg_info *unused_rs = NULL;  /* Don't allow remember/restore between CIE and FDE programs.  */  fs->regs.prev = NULL;  while (insn_ptr < insn_end && fs->pc < context->ra)    {      unsigned char insn = *insn_ptr++;      _Unwind_Word reg;      _Unwind_Sword offset;      _Unwind_Ptr ptrtmp;      if (insn & DW_CFA_advance_loc)	fs->pc += (insn & 0x3f) * fs->code_align;      else if (insn & DW_CFA_offset)	{	  reg = insn & 0x3f;	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  offset = ptrtmp * fs->data_align;	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;	  fs->regs.reg[reg].loc.offset = offset;	}      else if (insn & DW_CFA_restore)	{	  reg = insn & 0x3f;	  fs->regs.reg[reg].how = REG_UNSAVED;	}      else switch (insn)	{	case DW_CFA_set_loc:	  insn_ptr = read_encoded_value (context, fs->fde_encoding,					 insn_ptr, (_Unwind_Ptr *) &fs->pc);	  break;	case DW_CFA_advance_loc1:	  fs->pc += read_1u (insn_ptr) * fs->code_align;	  insn_ptr += 1;	  break;	case DW_CFA_advance_loc2:	  fs->pc += read_2u (insn_ptr) * fs->code_align;	  insn_ptr += 2;	  break;	case DW_CFA_advance_loc4:	  fs->pc += read_4u (insn_ptr) * fs->code_align;	  insn_ptr += 4;	  break;	case DW_CFA_offset_extended:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  offset = ptrtmp * fs->data_align;	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;	  fs->regs.reg[reg].loc.offset = offset;	  break;	case DW_CFA_restore_extended:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	  fs->regs.reg[reg].how = REG_UNSAVED;	  break;	case DW_CFA_undefined:	case DW_CFA_same_value:	case DW_CFA_nop:	  break;	case DW_CFA_register:	  {	    _Unwind_Word reg2;	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	    insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg2 = ptrtmp;	    fs->regs.reg[reg].how = REG_SAVED_REG;	    fs->regs.reg[reg].loc.reg = reg2;	  }	  break;      	case DW_CFA_remember_state:	  {	    struct frame_state_reg_info *new_rs;	    if (unused_rs)	      {		new_rs = unused_rs;		unused_rs = unused_rs->prev;	      }	    else	      new_rs = alloca (sizeof (struct frame_state_reg_info));	    *new_rs = fs->regs;	    fs->regs.prev = new_rs;	  }	  break;	case DW_CFA_restore_state:	  {	    struct frame_state_reg_info *old_rs = fs->regs.prev;	    fs->regs = *old_rs;	    old_rs->prev = unused_rs;	    unused_rs = old_rs;	  }	  break;	case DW_CFA_def_cfa:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_reg = ptrtmp;	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_offset = ptrtmp;	  fs->cfa_how = CFA_REG_OFFSET;	  break;	case DW_CFA_def_cfa_register:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_reg = ptrtmp;	  fs->cfa_how = CFA_REG_OFFSET;	  break;	case DW_CFA_def_cfa_offset:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_offset = ptrtmp;	  /* cfa_how deliberately not set.  */	  break;	case DW_CFA_def_cfa_expression:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_exp = insn_ptr;	  fs->cfa_how = CFA_EXP;	  insn_ptr += ptrtmp;	  break;	case DW_CFA_expression:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->regs.reg[reg].how = REG_SAVED_EXP;	  fs->regs.reg[reg].loc.exp = insn_ptr;	  insn_ptr += ptrtmp;	  break;	  /* From the 2.1 draft.  */	case DW_CFA_offset_extended_sf:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);	  offset = (saddr)ptrtmp * fs->data_align;	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;	  fs->regs.reg[reg].loc.offset = offset;	  break;	  	case DW_CFA_def_cfa_sf:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_reg = ptrtmp;	  insn_ptr = read_sleb128 (insn_ptr, &ptrtmp);	  fs->cfa_offset = (saddr)ptrtmp;	  fs->cfa_how = CFA_REG_OFFSET;	  break;	case DW_CFA_def_cfa_offset_sf:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  fs->cfa_offset = ptrtmp;	  /* cfa_how deliberately not set.  */	  break;	case DW_CFA_GNU_window_save:	  /* ??? Hardcoded for SPARC register window configuration.  */	  for (reg = 16; reg < 32; ++reg)	    {	      fs->regs.reg[reg].how = REG_SAVED_OFFSET;	      fs->regs.reg[reg].loc.offset = (reg - 16) * sizeof (void *);	    }	  break;	case DW_CFA_GNU_args_size:	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  context->args_size = ptrtmp;	  break;	case DW_CFA_GNU_negative_offset_extended:	  /* Obsoleted by DW_CFA_offset_extended_sf, but used by	     older PowerPC code.  */	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp); reg = ptrtmp;	  insn_ptr = read_uleb128 (insn_ptr, &ptrtmp);	  offset = ptrtmp * fs->data_align;	  fs->regs.reg[reg].how = REG_SAVED_OFFSET;	  fs->regs.reg[reg].loc.offset = -offset;	  break;	default:	  abort ();	}    }}