gdb/alpha: Redefine fpcr with fpcr_flags type

This commit adds fpcr_flags and dyn_rm_enum types to define the fpcr.

For details on the floating-point control register (fpcr), please see
the Alpha Architecture Reference Manual, 4th Ed. [1]; in brief, it
consists of a 64-bit bitfield with most bits reserved/unused. All but a
pair of the used bits are boolean flags; the exception, DYN_RM, is a
2-bit enum indicating the IEEE rounding mode and is defined as a
dyn_rm_enum type in the target description annex.

[1] https://archive.org/details/dec-alpha_arch_ref

Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Iea54c9e201faae6147a03de124b0368752bce060
diff --git a/gdb/features/alpha-core.xml b/gdb/features/alpha-core.xml
index 9b4d71c..c9e12f4 100644
--- a/gdb/features/alpha-core.xml
+++ b/gdb/features/alpha-core.xml
@@ -7,6 +7,54 @@
 
 <!DOCTYPE feature SYSTEM "gdb-target.dtd">
 <feature name="org.gnu.gdb.alpha.core">
+  <!-- IEEE rounding mode values -->
+  <enum id="dyn_rm_enum" size="8">
+    <!-- Chopped rounding mode -->
+    <evalue name="chop" value="0"/>
+    <!-- Minus infinity -->
+    <evalue name="-inf" value="1"/>
+    <!-- Normal rounding -->
+    <evalue name="norm" value="2"/>
+    <!-- Plus infinity -->
+    <evalue name="+inf" value="3"/>
+  </enum>
+
+  <!-- Floating-Point Control Register Flags -->
+  <flags id="fpcr_flags" size="8">
+    <!-- Denormal Operand Exception Disable -->
+    <field name="DNOD"   start="47" end="47"/>
+    <!-- Denormal Operands to Zero -->
+    <field name="DNZ"    start="48" end="48"/>
+    <!-- Invalid Operation Disable -->
+    <field name="INVD"   start="49" end="49"/>
+    <!-- Division by Zero Disable -->
+    <field name="DZED"   start="50" end="50"/>
+    <!-- Overflow Disable -->
+    <field name="OVFD"   start="51" end="51"/>
+    <!-- Invalid Operation -->
+    <field name="INV"    start="52" end="52"/>
+    <!-- Division by Zero -->
+    <field name="DZE"    start="53" end="53"/>
+    <!-- Overflow -->
+    <field name="OVF"    start="54" end="54"/>
+    <!-- Underflow -->
+    <field name="UNF"    start="55" end="55"/>
+    <!-- Inexact Result -->
+    <field name="INE"    start="56" end="56"/>
+    <!-- Integer Overflow -->
+    <field name="IOV"    start="57" end="57"/>
+    <!-- Dynamic Rounding Mode -->
+    <field name="DYN_RM" start="58" end="59" type="dyn_rm_enum"/>
+    <!-- Underflow to Zero -->
+    <field name="UNDZ"   start="60" end="60"/>
+    <!-- Underflow Disable -->
+    <field name="UNFD"   start="61" end="61"/>
+    <!-- Inexact Disable -->
+    <field name="INED"   start="62" end="62"/>
+    <!-- Summary Bit -->
+    <field name="SUM"    start="63" end="63"/>
+  </flags>
+
   <!-- Integer Registers -->
   <reg name="v0"   bitsize="64" type="int64"/>
   <reg name="t0"   bitsize="64" type="int64"/>
@@ -75,7 +123,7 @@
   <reg name="f30" bitsize="64" type="float" group="float"/>
 
   <!-- Floating-Point Control Register -->
-  <reg name="fpcr" bitsize="64" type="int64" group="float"/>
+  <reg name="fpcr" bitsize="64" type="fpcr_flags" group="float"/>
 
   <!-- Program Counter -->
   <reg name="pc" bitsize="64" type="code_ptr"/>
diff --git a/gdb/features/alpha.c b/gdb/features/alpha.c
index 051ded8..35f12fc 100644
--- a/gdb/features/alpha.c
+++ b/gdb/features/alpha.c
@@ -12,6 +12,33 @@ initialize_tdesc_alpha (void)
   struct tdesc_feature *feature;
 
   feature = tdesc_create_feature (result.get (), "org.gnu.gdb.alpha.core");
+  tdesc_type_with_fields *type_with_fields;
+  type_with_fields = tdesc_create_enum (feature, "dyn_rm_enum", 8);
+  tdesc_add_enum_value (type_with_fields, 0, "chop");
+  tdesc_add_enum_value (type_with_fields, 1, "-inf");
+  tdesc_add_enum_value (type_with_fields, 2, "norm");
+  tdesc_add_enum_value (type_with_fields, 3, "+inf");
+
+  type_with_fields = tdesc_create_flags (feature, "fpcr_flags", 8);
+  tdesc_add_flag (type_with_fields, 47, "DNOD");
+  tdesc_add_flag (type_with_fields, 48, "DNZ");
+  tdesc_add_flag (type_with_fields, 49, "INVD");
+  tdesc_add_flag (type_with_fields, 50, "DZED");
+  tdesc_add_flag (type_with_fields, 51, "OVFD");
+  tdesc_add_flag (type_with_fields, 52, "INV");
+  tdesc_add_flag (type_with_fields, 53, "DZE");
+  tdesc_add_flag (type_with_fields, 54, "OVF");
+  tdesc_add_flag (type_with_fields, 55, "UNF");
+  tdesc_add_flag (type_with_fields, 56, "INE");
+  tdesc_add_flag (type_with_fields, 57, "IOV");
+  tdesc_type *field_type;
+  field_type = tdesc_named_type (feature, "dyn_rm_enum");
+  tdesc_add_typed_bitfield (type_with_fields, "DYN_RM", 58, 59, field_type);
+  tdesc_add_flag (type_with_fields, 60, "UNDZ");
+  tdesc_add_flag (type_with_fields, 61, "UNFD");
+  tdesc_add_flag (type_with_fields, 62, "INED");
+  tdesc_add_flag (type_with_fields, 63, "SUM");
+
   tdesc_create_reg (feature, "v0", 0, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "t0", 1, 1, NULL, 64, "int64");
   tdesc_create_reg (feature, "t1", 2, 1, NULL, 64, "int64");
@@ -75,7 +102,7 @@ initialize_tdesc_alpha (void)
   tdesc_create_reg (feature, "f28", 60, 1, "float", 64, "float");
   tdesc_create_reg (feature, "f29", 61, 1, "float", 64, "float");
   tdesc_create_reg (feature, "f30", 62, 1, "float", 64, "float");
-  tdesc_create_reg (feature, "fpcr", 63, 1, "float", 64, "int64");
+  tdesc_create_reg (feature, "fpcr", 63, 1, "float", 64, "fpcr_flags");
   tdesc_create_reg (feature, "pc", 64, 1, NULL, 64, "code_ptr");
   tdesc_create_reg (feature, "", 65, 0, NULL, 64, "int64");
   tdesc_create_reg (feature, "unique", 66, 1, "system", 64, "int64");