diff --git a/gdb/features/arm/arm-core.c b/gdb/features/arm/arm-core.c
index e401411fc5e7..7eb8d4de0923 100644
--- a/gdb/features/arm/arm-core.c
+++ b/gdb/features/arm/arm-core.c
@@ -9,6 +9,41 @@ create_feature_arm_arm_core (struct target_desc *result, long regnum)
   struct tdesc_feature *feature;
 
   feature = tdesc_create_feature (result, "org.gnu.gdb.arm.core");
+  tdesc_type_with_fields *type_with_fields;
+  type_with_fields = tdesc_create_enum (feature, "pe_mode", 1);
+  tdesc_add_enum_value (type_with_fields, 16, "user");
+  tdesc_add_enum_value (type_with_fields, 17, "FIQ");
+  tdesc_add_enum_value (type_with_fields, 18, "IRQ");
+  tdesc_add_enum_value (type_with_fields, 19, "supervisor");
+  tdesc_add_enum_value (type_with_fields, 22, "monitor");
+  tdesc_add_enum_value (type_with_fields, 23, "abort");
+  tdesc_add_enum_value (type_with_fields, 26, "hyp");
+  tdesc_add_enum_value (type_with_fields, 27, "undefined");
+  tdesc_add_enum_value (type_with_fields, 31, "system");
+
+  type_with_fields = tdesc_create_enum (feature, "endianness", 1);
+  tdesc_add_enum_value (type_with_fields, 0, "little");
+  tdesc_add_enum_value (type_with_fields, 1, "big");
+
+  type_with_fields = tdesc_create_flags (feature, "cpsr_flags", 4);
+  tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "pe_mode");
+  tdesc_add_typed_bitfield (type_with_fields, "M", 0, 4, field_type);
+  tdesc_add_flag (type_with_fields, 6, "F");
+  tdesc_add_flag (type_with_fields, 7, "I");
+  tdesc_add_flag (type_with_fields, 8, "A");
+  field_type = tdesc_named_type (feature, "endianness");
+  tdesc_add_typed_bitfield (type_with_fields, "E", 9, 9, field_type);
+  tdesc_add_bitfield (type_with_fields, "GE", 16, 19);
+  tdesc_add_flag (type_with_fields, 21, "DIT");
+  tdesc_add_flag (type_with_fields, 22, "PAN");
+  tdesc_add_flag (type_with_fields, 23, "SSBS");
+  tdesc_add_flag (type_with_fields, 27, "Q");
+  tdesc_add_flag (type_with_fields, 28, "V");
+  tdesc_add_flag (type_with_fields, 29, "C");
+  tdesc_add_flag (type_with_fields, 30, "Z");
+  tdesc_add_flag (type_with_fields, 31, "N");
+
   tdesc_create_reg (feature, "r0", regnum++, 1, NULL, 32, "uint32");
   tdesc_create_reg (feature, "r1", regnum++, 1, NULL, 32, "uint32");
   tdesc_create_reg (feature, "r2", regnum++, 1, NULL, 32, "uint32");
@@ -26,6 +61,6 @@ create_feature_arm_arm_core (struct target_desc *result, long regnum)
   tdesc_create_reg (feature, "lr", regnum++, 1, NULL, 32, "int");
   tdesc_create_reg (feature, "pc", regnum++, 1, NULL, 32, "code_ptr");
   regnum = 25;
-  tdesc_create_reg (feature, "cpsr", regnum++, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "cpsr", regnum++, 1, NULL, 32, "cpsr_flags");
   return regnum;
 }
diff --git a/gdb/features/arm/arm-core.xml b/gdb/features/arm/arm-core.xml
index 498aee1f8595..52edc66045a2 100644
--- a/gdb/features/arm/arm-core.xml
+++ b/gdb/features/arm/arm-core.xml
@@ -24,8 +24,58 @@
   <reg name="lr" bitsize="32"/>
   <reg name="pc" bitsize="32" type="code_ptr"/>
 
+  <enum id="pe_mode" size="1">
+    <evalue name="user" value="0x10"/>
+    <evalue name="FIQ" value="0x11"/>
+    <evalue name="IRQ" value="0x12"/>
+    <evalue name="supervisor" value="0x13"/>
+    <evalue name="monitor" value="0x16"/>
+    <evalue name="abort" value="0x17"/>
+    <evalue name="hyp" value="0x1A"/>
+    <evalue name="undefined" value="0x1B"/>
+    <evalue name="system" value="0x1F"/>
+  </enum>
+  <enum id="endianness" size="1">
+    <evalue name="little" value="0"/>
+    <evalue name="big" value="1"/>
+  </enum>
+  <flags id="cpsr_flags" size="4">
+    <!-- Current mode of the PE.  -->
+    <field name="M" start="0" end="4" type="pe_mode"/>
+
+    <!-- FIQ interrupt mask.  -->
+    <field name="F" start="6" end="6"/>
+    <!-- IRQ interrupt mask.  -->
+    <field name="I" start="7" end="7"/>
+    <!-- SError interrupt mask.  -->
+    <field name="A" start="8" end="8"/>
+    <!-- Endianness of data accesses.  -->
+    <field name="E" start="9" end="9" type="endianness"/>
+
+    <!-- Greater than or equal flags.  -->
+    <field name="GE" start="16" end="19"/>
+
+    <!-- ARMv8.4-A: Data Independent Timing.  -->
+    <field name="DIT" start="21" end="21"/>
+    <!-- ARMv8.1-A: Privileged Access Never.  -->
+    <field name="PAN" start="22" end="22"/>
+    <!-- ARMv8.5-A: Speculative Store Bypass Safe.  -->
+    <field name="SSBS" start="23" end="23"/>
+
+    <!-- Overflow or saturation flag.  -->
+    <field name="Q" start="27" end="27"/>
+
+    <!-- Overflow Condition flag.  -->
+    <field name="V" start="28" end="28"/>
+    <!-- Carry Condition flag.  -->
+    <field name="C" start="29" end="29"/>
+    <!-- Zero Condition flag.  -->
+    <field name="Z" start="30" end="30"/>
+    <!-- Negative Condition flag.  -->
+    <field name="N" start="31" end="31"/>
+  </flags>
   <!-- The CPSR is register 25, rather than register 16, because
        the FPA registers historically were placed between the PC
        and the CPSR in the "g" packet.  -->
-  <reg name="cpsr" bitsize="32" regnum="25"/>
+  <reg name="cpsr" bitsize="32" type="cpsr_flags" regnum="25"/>
 </feature>
