xref: /netbsd/external/gpl3/gdb/dist/gdb/arch/arm.c (revision 1424dfb3)
1c03b94e9Schristos /* Common target dependent code for GDB on ARM systems.
2c03b94e9Schristos 
3*1424dfb3Schristos    Copyright (C) 1988-2020 Free Software Foundation, Inc.
4c03b94e9Schristos 
5c03b94e9Schristos    This file is part of GDB.
6c03b94e9Schristos 
7c03b94e9Schristos    This program is free software; you can redistribute it and/or modify
8c03b94e9Schristos    it under the terms of the GNU General Public License as published by
9c03b94e9Schristos    the Free Software Foundation; either version 3 of the License, or
10c03b94e9Schristos    (at your option) any later version.
11c03b94e9Schristos 
12c03b94e9Schristos    This program is distributed in the hope that it will be useful,
13c03b94e9Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
14c03b94e9Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15c03b94e9Schristos    GNU General Public License for more details.
16c03b94e9Schristos 
17c03b94e9Schristos    You should have received a copy of the GNU General Public License
18c03b94e9Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19c03b94e9Schristos 
20*1424dfb3Schristos #include "gdbsupport/common-defs.h"
21*1424dfb3Schristos #include "gdbsupport/common-regcache.h"
22c03b94e9Schristos #include "arm.h"
23c03b94e9Schristos 
24*1424dfb3Schristos #include "../features/arm/arm-core.c"
25*1424dfb3Schristos #include "../features/arm/arm-vfpv2.c"
26*1424dfb3Schristos #include "../features/arm/arm-vfpv3.c"
27*1424dfb3Schristos #include "../features/arm/xscale-iwmmxt.c"
28*1424dfb3Schristos #include "../features/arm/arm-m-profile.c"
29*1424dfb3Schristos #include "../features/arm/arm-m-profile-with-fpa.c"
30*1424dfb3Schristos 
31c03b94e9Schristos /* See arm.h.  */
32c03b94e9Schristos 
33c03b94e9Schristos int
thumb_insn_size(unsigned short inst1)34c03b94e9Schristos thumb_insn_size (unsigned short inst1)
35c03b94e9Schristos {
36c03b94e9Schristos   if ((inst1 & 0xe000) == 0xe000 && (inst1 & 0x1800) != 0)
37c03b94e9Schristos     return 4;
38c03b94e9Schristos   else
39c03b94e9Schristos     return 2;
40c03b94e9Schristos }
41c03b94e9Schristos 
42c03b94e9Schristos /* See arm.h.  */
43c03b94e9Schristos 
44c03b94e9Schristos int
condition_true(unsigned long cond,unsigned long status_reg)45c03b94e9Schristos condition_true (unsigned long cond, unsigned long status_reg)
46c03b94e9Schristos {
47c03b94e9Schristos   if (cond == INST_AL || cond == INST_NV)
48c03b94e9Schristos     return 1;
49c03b94e9Schristos 
50c03b94e9Schristos   switch (cond)
51c03b94e9Schristos     {
52c03b94e9Schristos     case INST_EQ:
53c03b94e9Schristos       return ((status_reg & FLAG_Z) != 0);
54c03b94e9Schristos     case INST_NE:
55c03b94e9Schristos       return ((status_reg & FLAG_Z) == 0);
56c03b94e9Schristos     case INST_CS:
57c03b94e9Schristos       return ((status_reg & FLAG_C) != 0);
58c03b94e9Schristos     case INST_CC:
59c03b94e9Schristos       return ((status_reg & FLAG_C) == 0);
60c03b94e9Schristos     case INST_MI:
61c03b94e9Schristos       return ((status_reg & FLAG_N) != 0);
62c03b94e9Schristos     case INST_PL:
63c03b94e9Schristos       return ((status_reg & FLAG_N) == 0);
64c03b94e9Schristos     case INST_VS:
65c03b94e9Schristos       return ((status_reg & FLAG_V) != 0);
66c03b94e9Schristos     case INST_VC:
67c03b94e9Schristos       return ((status_reg & FLAG_V) == 0);
68c03b94e9Schristos     case INST_HI:
69c03b94e9Schristos       return ((status_reg & (FLAG_C | FLAG_Z)) == FLAG_C);
70c03b94e9Schristos     case INST_LS:
71c03b94e9Schristos       return ((status_reg & (FLAG_C | FLAG_Z)) != FLAG_C);
72c03b94e9Schristos     case INST_GE:
73c03b94e9Schristos       return (((status_reg & FLAG_N) == 0) == ((status_reg & FLAG_V) == 0));
74c03b94e9Schristos     case INST_LT:
75c03b94e9Schristos       return (((status_reg & FLAG_N) == 0) != ((status_reg & FLAG_V) == 0));
76c03b94e9Schristos     case INST_GT:
77c03b94e9Schristos       return (((status_reg & FLAG_Z) == 0)
78c03b94e9Schristos 	      && (((status_reg & FLAG_N) == 0)
79c03b94e9Schristos 		  == ((status_reg & FLAG_V) == 0)));
80c03b94e9Schristos     case INST_LE:
81c03b94e9Schristos       return (((status_reg & FLAG_Z) != 0)
82c03b94e9Schristos 	      || (((status_reg & FLAG_N) == 0)
83c03b94e9Schristos 		  != ((status_reg & FLAG_V) == 0)));
84c03b94e9Schristos     }
85c03b94e9Schristos   return 1;
86c03b94e9Schristos }
87c03b94e9Schristos 
88c03b94e9Schristos 
89c03b94e9Schristos /* See arm.h.  */
90c03b94e9Schristos 
91c03b94e9Schristos int
thumb_advance_itstate(unsigned int itstate)92c03b94e9Schristos thumb_advance_itstate (unsigned int itstate)
93c03b94e9Schristos {
94c03b94e9Schristos   /* Preserve IT[7:5], the first three bits of the condition.  Shift
95c03b94e9Schristos      the upcoming condition flags left by one bit.  */
96c03b94e9Schristos   itstate = (itstate & 0xe0) | ((itstate << 1) & 0x1f);
97c03b94e9Schristos 
98c03b94e9Schristos   /* If we have finished the IT block, clear the state.  */
99c03b94e9Schristos   if ((itstate & 0x0f) == 0)
100c03b94e9Schristos     itstate = 0;
101c03b94e9Schristos 
102c03b94e9Schristos   return itstate;
103c03b94e9Schristos }
104c03b94e9Schristos 
105c03b94e9Schristos /* See arm.h.  */
106c03b94e9Schristos 
107c03b94e9Schristos int
arm_instruction_changes_pc(uint32_t this_instr)108c03b94e9Schristos arm_instruction_changes_pc (uint32_t this_instr)
109c03b94e9Schristos {
110c03b94e9Schristos   if (bits (this_instr, 28, 31) == INST_NV)
111c03b94e9Schristos     /* Unconditional instructions.  */
112c03b94e9Schristos     switch (bits (this_instr, 24, 27))
113c03b94e9Schristos       {
114c03b94e9Schristos       case 0xa:
115c03b94e9Schristos       case 0xb:
116c03b94e9Schristos 	/* Branch with Link and change to Thumb.  */
117c03b94e9Schristos 	return 1;
118c03b94e9Schristos       case 0xc:
119c03b94e9Schristos       case 0xd:
120c03b94e9Schristos       case 0xe:
121c03b94e9Schristos 	/* Coprocessor register transfer.  */
122c03b94e9Schristos         if (bits (this_instr, 12, 15) == 15)
123c03b94e9Schristos 	  error (_("Invalid update to pc in instruction"));
124c03b94e9Schristos 	return 0;
125c03b94e9Schristos       default:
126c03b94e9Schristos 	return 0;
127c03b94e9Schristos       }
128c03b94e9Schristos   else
129c03b94e9Schristos     switch (bits (this_instr, 25, 27))
130c03b94e9Schristos       {
131c03b94e9Schristos       case 0x0:
132c03b94e9Schristos 	if (bits (this_instr, 23, 24) == 2 && bit (this_instr, 20) == 0)
133c03b94e9Schristos 	  {
134c03b94e9Schristos 	    /* Multiplies and extra load/stores.  */
135c03b94e9Schristos 	    if (bit (this_instr, 4) == 1 && bit (this_instr, 7) == 1)
136c03b94e9Schristos 	      /* Neither multiplies nor extension load/stores are allowed
137c03b94e9Schristos 		 to modify PC.  */
138c03b94e9Schristos 	      return 0;
139c03b94e9Schristos 
140c03b94e9Schristos 	    /* Otherwise, miscellaneous instructions.  */
141c03b94e9Schristos 
142c03b94e9Schristos 	    /* BX <reg>, BXJ <reg>, BLX <reg> */
143c03b94e9Schristos 	    if (bits (this_instr, 4, 27) == 0x12fff1
144c03b94e9Schristos 		|| bits (this_instr, 4, 27) == 0x12fff2
145c03b94e9Schristos 		|| bits (this_instr, 4, 27) == 0x12fff3)
146c03b94e9Schristos 	      return 1;
147c03b94e9Schristos 
148c03b94e9Schristos 	    /* Other miscellaneous instructions are unpredictable if they
149c03b94e9Schristos 	       modify PC.  */
150c03b94e9Schristos 	    return 0;
151c03b94e9Schristos 	  }
15207163879Schristos 	/* Data processing instruction.  */
15307163879Schristos 	/* Fall through.  */
154c03b94e9Schristos 
155c03b94e9Schristos       case 0x1:
156c03b94e9Schristos 	if (bits (this_instr, 12, 15) == 15)
157c03b94e9Schristos 	  return 1;
158c03b94e9Schristos 	else
159c03b94e9Schristos 	  return 0;
160c03b94e9Schristos 
161c03b94e9Schristos       case 0x2:
162c03b94e9Schristos       case 0x3:
163c03b94e9Schristos 	/* Media instructions and architecturally undefined instructions.  */
164c03b94e9Schristos 	if (bits (this_instr, 25, 27) == 3 && bit (this_instr, 4) == 1)
165c03b94e9Schristos 	  return 0;
166c03b94e9Schristos 
167c03b94e9Schristos 	/* Stores.  */
168c03b94e9Schristos 	if (bit (this_instr, 20) == 0)
169c03b94e9Schristos 	  return 0;
170c03b94e9Schristos 
171c03b94e9Schristos 	/* Loads.  */
172c03b94e9Schristos 	if (bits (this_instr, 12, 15) == ARM_PC_REGNUM)
173c03b94e9Schristos 	  return 1;
174c03b94e9Schristos 	else
175c03b94e9Schristos 	  return 0;
176c03b94e9Schristos 
177c03b94e9Schristos       case 0x4:
178c03b94e9Schristos 	/* Load/store multiple.  */
179c03b94e9Schristos 	if (bit (this_instr, 20) == 1 && bit (this_instr, 15) == 1)
180c03b94e9Schristos 	  return 1;
181c03b94e9Schristos 	else
182c03b94e9Schristos 	  return 0;
183c03b94e9Schristos 
184c03b94e9Schristos       case 0x5:
185c03b94e9Schristos 	/* Branch and branch with link.  */
186c03b94e9Schristos 	return 1;
187c03b94e9Schristos 
188c03b94e9Schristos       case 0x6:
189c03b94e9Schristos       case 0x7:
190c03b94e9Schristos 	/* Coprocessor transfers or SWIs can not affect PC.  */
191c03b94e9Schristos 	return 0;
192c03b94e9Schristos 
193c03b94e9Schristos       default:
194c03b94e9Schristos 	internal_error (__FILE__, __LINE__, _("bad value in switch"));
195c03b94e9Schristos       }
196c03b94e9Schristos }
197c03b94e9Schristos 
198c03b94e9Schristos /* See arm.h.  */
199c03b94e9Schristos 
200c03b94e9Schristos int
thumb_instruction_changes_pc(unsigned short inst)201c03b94e9Schristos thumb_instruction_changes_pc (unsigned short inst)
202c03b94e9Schristos {
203c03b94e9Schristos   if ((inst & 0xff00) == 0xbd00)	/* pop {rlist, pc} */
204c03b94e9Schristos     return 1;
205c03b94e9Schristos 
206c03b94e9Schristos   if ((inst & 0xf000) == 0xd000)	/* conditional branch */
207c03b94e9Schristos     return 1;
208c03b94e9Schristos 
209c03b94e9Schristos   if ((inst & 0xf800) == 0xe000)	/* unconditional branch */
210c03b94e9Schristos     return 1;
211c03b94e9Schristos 
212c03b94e9Schristos   if ((inst & 0xff00) == 0x4700)	/* bx REG, blx REG */
213c03b94e9Schristos     return 1;
214c03b94e9Schristos 
215c03b94e9Schristos   if ((inst & 0xff87) == 0x4687)	/* mov pc, REG */
216c03b94e9Schristos     return 1;
217c03b94e9Schristos 
218c03b94e9Schristos   if ((inst & 0xf500) == 0xb100)	/* CBNZ or CBZ.  */
219c03b94e9Schristos     return 1;
220c03b94e9Schristos 
221c03b94e9Schristos   return 0;
222c03b94e9Schristos }
223c03b94e9Schristos 
224c03b94e9Schristos 
225c03b94e9Schristos /* See arm.h.  */
226c03b94e9Schristos 
227c03b94e9Schristos int
thumb2_instruction_changes_pc(unsigned short inst1,unsigned short inst2)228c03b94e9Schristos thumb2_instruction_changes_pc (unsigned short inst1, unsigned short inst2)
229c03b94e9Schristos {
230c03b94e9Schristos   if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000)
231c03b94e9Schristos     {
232c03b94e9Schristos       /* Branches and miscellaneous control instructions.  */
233c03b94e9Schristos 
234c03b94e9Schristos       if ((inst2 & 0x1000) != 0 || (inst2 & 0xd001) == 0xc000)
235c03b94e9Schristos 	{
236c03b94e9Schristos 	  /* B, BL, BLX.  */
237c03b94e9Schristos 	  return 1;
238c03b94e9Schristos 	}
239c03b94e9Schristos       else if (inst1 == 0xf3de && (inst2 & 0xff00) == 0x3f00)
240c03b94e9Schristos 	{
241c03b94e9Schristos 	  /* SUBS PC, LR, #imm8.  */
242c03b94e9Schristos 	  return 1;
243c03b94e9Schristos 	}
244c03b94e9Schristos       else if ((inst2 & 0xd000) == 0x8000 && (inst1 & 0x0380) != 0x0380)
245c03b94e9Schristos 	{
246c03b94e9Schristos 	  /* Conditional branch.  */
247c03b94e9Schristos 	  return 1;
248c03b94e9Schristos 	}
249c03b94e9Schristos 
250c03b94e9Schristos       return 0;
251c03b94e9Schristos     }
252c03b94e9Schristos 
253c03b94e9Schristos   if ((inst1 & 0xfe50) == 0xe810)
254c03b94e9Schristos     {
255c03b94e9Schristos       /* Load multiple or RFE.  */
256c03b94e9Schristos 
257c03b94e9Schristos       if (bit (inst1, 7) && !bit (inst1, 8))
258c03b94e9Schristos 	{
259c03b94e9Schristos 	  /* LDMIA or POP */
260c03b94e9Schristos 	  if (bit (inst2, 15))
261c03b94e9Schristos 	    return 1;
262c03b94e9Schristos 	}
263c03b94e9Schristos       else if (!bit (inst1, 7) && bit (inst1, 8))
264c03b94e9Schristos 	{
265c03b94e9Schristos 	  /* LDMDB */
266c03b94e9Schristos 	  if (bit (inst2, 15))
267c03b94e9Schristos 	    return 1;
268c03b94e9Schristos 	}
269c03b94e9Schristos       else if (bit (inst1, 7) && bit (inst1, 8))
270c03b94e9Schristos 	{
271c03b94e9Schristos 	  /* RFEIA */
272c03b94e9Schristos 	  return 1;
273c03b94e9Schristos 	}
274c03b94e9Schristos       else if (!bit (inst1, 7) && !bit (inst1, 8))
275c03b94e9Schristos 	{
276c03b94e9Schristos 	  /* RFEDB */
277c03b94e9Schristos 	  return 1;
278c03b94e9Schristos 	}
279c03b94e9Schristos 
280c03b94e9Schristos       return 0;
281c03b94e9Schristos     }
282c03b94e9Schristos 
283c03b94e9Schristos   if ((inst1 & 0xffef) == 0xea4f && (inst2 & 0xfff0) == 0x0f00)
284c03b94e9Schristos     {
285c03b94e9Schristos       /* MOV PC or MOVS PC.  */
286c03b94e9Schristos       return 1;
287c03b94e9Schristos     }
288c03b94e9Schristos 
289c03b94e9Schristos   if ((inst1 & 0xff70) == 0xf850 && (inst2 & 0xf000) == 0xf000)
290c03b94e9Schristos     {
291c03b94e9Schristos       /* LDR PC.  */
292c03b94e9Schristos       if (bits (inst1, 0, 3) == 15)
293c03b94e9Schristos 	return 1;
294c03b94e9Schristos       if (bit (inst1, 7))
295c03b94e9Schristos 	return 1;
296c03b94e9Schristos       if (bit (inst2, 11))
297c03b94e9Schristos 	return 1;
298c03b94e9Schristos       if ((inst2 & 0x0fc0) == 0x0000)
299c03b94e9Schristos 	return 1;
300c03b94e9Schristos 
301c03b94e9Schristos       return 0;
302c03b94e9Schristos     }
303c03b94e9Schristos 
304c03b94e9Schristos   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf000)
305c03b94e9Schristos     {
306c03b94e9Schristos       /* TBB.  */
307c03b94e9Schristos       return 1;
308c03b94e9Schristos     }
309c03b94e9Schristos 
310c03b94e9Schristos   if ((inst1 & 0xfff0) == 0xe8d0 && (inst2 & 0xfff0) == 0xf010)
311c03b94e9Schristos     {
312c03b94e9Schristos       /* TBH.  */
313c03b94e9Schristos       return 1;
314c03b94e9Schristos     }
315c03b94e9Schristos 
316c03b94e9Schristos   return 0;
317c03b94e9Schristos }
318c03b94e9Schristos 
319c03b94e9Schristos /* See arm.h.  */
320c03b94e9Schristos 
321c03b94e9Schristos unsigned long
shifted_reg_val(struct regcache * regcache,unsigned long inst,int carry,unsigned long pc_val,unsigned long status_reg)322c03b94e9Schristos shifted_reg_val (struct regcache *regcache, unsigned long inst,
323c03b94e9Schristos 		 int carry, unsigned long pc_val, unsigned long status_reg)
324c03b94e9Schristos {
325c03b94e9Schristos   unsigned long res, shift;
326c03b94e9Schristos   int rm = bits (inst, 0, 3);
327c03b94e9Schristos   unsigned long shifttype = bits (inst, 5, 6);
328c03b94e9Schristos 
329c03b94e9Schristos   if (bit (inst, 4))
330c03b94e9Schristos     {
331c03b94e9Schristos       int rs = bits (inst, 8, 11);
332c03b94e9Schristos       shift = (rs == 15
333c03b94e9Schristos 	       ? pc_val + 8
334c03b94e9Schristos 	       : regcache_raw_get_unsigned (regcache, rs)) & 0xFF;
335c03b94e9Schristos     }
336c03b94e9Schristos   else
337c03b94e9Schristos     shift = bits (inst, 7, 11);
338c03b94e9Schristos 
339c03b94e9Schristos   res = (rm == ARM_PC_REGNUM
340c03b94e9Schristos 	 ? (pc_val + (bit (inst, 4) ? 12 : 8))
341c03b94e9Schristos 	 : regcache_raw_get_unsigned (regcache, rm));
342c03b94e9Schristos 
343c03b94e9Schristos   switch (shifttype)
344c03b94e9Schristos     {
345c03b94e9Schristos     case 0:			/* LSL */
346c03b94e9Schristos       res = shift >= 32 ? 0 : res << shift;
347c03b94e9Schristos       break;
348c03b94e9Schristos 
349c03b94e9Schristos     case 1:			/* LSR */
350c03b94e9Schristos       res = shift >= 32 ? 0 : res >> shift;
351c03b94e9Schristos       break;
352c03b94e9Schristos 
353c03b94e9Schristos     case 2:			/* ASR */
354c03b94e9Schristos       if (shift >= 32)
355c03b94e9Schristos 	shift = 31;
356c03b94e9Schristos       res = ((res & 0x80000000L)
357c03b94e9Schristos 	     ? ~((~res) >> shift) : res >> shift);
358c03b94e9Schristos       break;
359c03b94e9Schristos 
360c03b94e9Schristos     case 3:			/* ROR/RRX */
361c03b94e9Schristos       shift &= 31;
362c03b94e9Schristos       if (shift == 0)
363c03b94e9Schristos 	res = (res >> 1) | (carry ? 0x80000000L : 0);
364c03b94e9Schristos       else
365c03b94e9Schristos 	res = (res >> shift) | (res << (32 - shift));
366c03b94e9Schristos       break;
367c03b94e9Schristos     }
368c03b94e9Schristos 
369c03b94e9Schristos   return res & 0xffffffff;
370c03b94e9Schristos }
371*1424dfb3Schristos 
372*1424dfb3Schristos /* See arch/arm.h.  */
373*1424dfb3Schristos 
374*1424dfb3Schristos target_desc *
arm_create_target_description(arm_fp_type fp_type)375*1424dfb3Schristos arm_create_target_description (arm_fp_type fp_type)
376*1424dfb3Schristos {
377*1424dfb3Schristos   target_desc *tdesc = allocate_target_description ();
378*1424dfb3Schristos 
379*1424dfb3Schristos #ifndef IN_PROCESS_AGENT
380*1424dfb3Schristos   if (fp_type == ARM_FP_TYPE_IWMMXT)
381*1424dfb3Schristos     set_tdesc_architecture (tdesc, "iwmmxt");
382*1424dfb3Schristos   else
383*1424dfb3Schristos     set_tdesc_architecture (tdesc, "arm");
384*1424dfb3Schristos #endif
385*1424dfb3Schristos 
386*1424dfb3Schristos   long regnum = 0;
387*1424dfb3Schristos 
388*1424dfb3Schristos   regnum = create_feature_arm_arm_core (tdesc, regnum);
389*1424dfb3Schristos 
390*1424dfb3Schristos   switch (fp_type)
391*1424dfb3Schristos     {
392*1424dfb3Schristos     case ARM_FP_TYPE_NONE:
393*1424dfb3Schristos       break;
394*1424dfb3Schristos 
395*1424dfb3Schristos     case ARM_FP_TYPE_VFPV2:
396*1424dfb3Schristos       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
397*1424dfb3Schristos       break;
398*1424dfb3Schristos 
399*1424dfb3Schristos     case ARM_FP_TYPE_VFPV3:
400*1424dfb3Schristos       regnum = create_feature_arm_arm_vfpv3 (tdesc, regnum);
401*1424dfb3Schristos       break;
402*1424dfb3Schristos 
403*1424dfb3Schristos     case ARM_FP_TYPE_IWMMXT:
404*1424dfb3Schristos       regnum = create_feature_arm_xscale_iwmmxt (tdesc, regnum);
405*1424dfb3Schristos       break;
406*1424dfb3Schristos 
407*1424dfb3Schristos     default:
408*1424dfb3Schristos       error (_("Invalid Arm FP type: %d"), fp_type);
409*1424dfb3Schristos     }
410*1424dfb3Schristos 
411*1424dfb3Schristos   return tdesc;
412*1424dfb3Schristos }
413*1424dfb3Schristos 
414*1424dfb3Schristos /* See arch/arm.h.  */
415*1424dfb3Schristos 
416*1424dfb3Schristos target_desc *
arm_create_mprofile_target_description(arm_m_profile_type m_type)417*1424dfb3Schristos arm_create_mprofile_target_description (arm_m_profile_type m_type)
418*1424dfb3Schristos {
419*1424dfb3Schristos   target_desc *tdesc = allocate_target_description ();
420*1424dfb3Schristos 
421*1424dfb3Schristos #ifndef IN_PROCESS_AGENT
422*1424dfb3Schristos   set_tdesc_architecture (tdesc, "arm");
423*1424dfb3Schristos #endif
424*1424dfb3Schristos 
425*1424dfb3Schristos   long regnum = 0;
426*1424dfb3Schristos 
427*1424dfb3Schristos   switch (m_type)
428*1424dfb3Schristos     {
429*1424dfb3Schristos     case ARM_M_TYPE_M_PROFILE:
430*1424dfb3Schristos       regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
431*1424dfb3Schristos       break;
432*1424dfb3Schristos 
433*1424dfb3Schristos     case ARM_M_TYPE_VFP_D16:
434*1424dfb3Schristos       regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
435*1424dfb3Schristos       regnum = create_feature_arm_arm_vfpv2 (tdesc, regnum);
436*1424dfb3Schristos       break;
437*1424dfb3Schristos 
438*1424dfb3Schristos     case ARM_M_TYPE_WITH_FPA:
439*1424dfb3Schristos       regnum = create_feature_arm_arm_m_profile_with_fpa (tdesc, regnum);
440*1424dfb3Schristos       break;
441*1424dfb3Schristos 
442*1424dfb3Schristos     default:
443*1424dfb3Schristos       error (_("Invalid Arm M type: %d"), m_type);
444*1424dfb3Schristos     }
445*1424dfb3Schristos 
446*1424dfb3Schristos   return tdesc;
447*1424dfb3Schristos }
448