public static void AddVectorFeature(ref List <GDBFeatureDescriptor> features, uint registerWidth) { var vectorGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.vector"); var riscvVectorTypeFields = new List <GDBTypeField>(); if (registerWidth / 128 > 0) { var vu128TypeID = $"vector_u128_{registerWidth / 128}"; var vu128Type = GDBCustomType.Vector(vu128TypeID, "uint128", registerWidth / 128); vectorGroup.Types.Add(vu128Type); riscvVectorTypeFields.Add(new GDBTypeField("q", vu128TypeID)); } if (registerWidth / 64 > 0) { var vu64TypeID = $"vector_u64_{registerWidth / 64}"; var vu64Type = GDBCustomType.Vector(vu64TypeID, "uint64", registerWidth / 64); vectorGroup.Types.Add(vu64Type); riscvVectorTypeFields.Add(new GDBTypeField("l", vu64TypeID)); } if (registerWidth / 32 > 0) { var vu32TypeID = $"vector_u32_{registerWidth / 32}"; var vu32Type = GDBCustomType.Vector(vu32TypeID, "uint32", registerWidth / 32); vectorGroup.Types.Add(vu32Type); riscvVectorTypeFields.Add(new GDBTypeField("w", vu32TypeID)); } if (registerWidth / 16 > 0) { var vu16TypeID = $"vector_u16_{registerWidth / 16}"; var vu16Type = GDBCustomType.Vector(vu16TypeID, "uint16", registerWidth / 16); vectorGroup.Types.Add(vu16Type); riscvVectorTypeFields.Add(new GDBTypeField("s", vu16TypeID)); } if (registerWidth / 8 > 0) { var vu8TypeID = $"vector_u8_{registerWidth / 8}"; var vu8Type = GDBCustomType.Vector(vu8TypeID, "uint8", registerWidth / 8); vectorGroup.Types.Add(vu8Type); riscvVectorTypeFields.Add(new GDBTypeField("b", vu8TypeID)); } var riscvVectorType = GDBCustomType.Union("riscv_vector", riscvVectorTypeFields); vectorGroup.Types.Add(riscvVectorType); for (var index = 0u; index < NumberOfVRegisters; ++index) { vectorGroup.Registers.Add(new GDBRegisterDescriptor(StartOfVRegisters + index, registerWidth, $"v{index}", "riscv_vector", "vector")); } features.Add(vectorGroup); }
public static void AddFpuFeature(ref List <GDBFeatureDescriptor> features, uint registerWidth, bool extensionH, bool extensionF, bool extensionD, bool extensionQ) { if (!(extensionH || extensionF || extensionD || extensionQ)) { return; } var fpuGroup = new GDBFeatureDescriptor("org.gnu.gdb.riscv.fpu"); var intType = $"uint{registerWidth}"; var fWidth = 0u; var types = new List <string>(); if (extensionH) { fWidth = 16u; types.Add("half"); var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("sign", 15, 15, "uint16")); fields.Add(new GDBTypeBitField("exponent", 10, 14, "uint16")); fields.Add(new GDBTypeBitField("fraction", 0, 9, "uint16")); var half = GDBCustomType.Struct("half", fWidth / 8, fields); fpuGroup.Types.Add(half); } if (extensionF) { fWidth = 32u; types.Add("single"); } if (extensionD) { fWidth = 64u; types.Add("double"); } if (extensionQ) { fWidth = 128u; types.Add("quad"); var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("sign", 127, 127, "uint128")); fields.Add(new GDBTypeBitField("exponent", 112, 126, "uint128")); fields.Add(new GDBTypeBitField("fraction", 0, 111, "uint128")); var quad = GDBCustomType.Struct("quad", fWidth / 8, fields); fpuGroup.Types.Add(quad); } var floatType = $"ieee_{types[0]}"; // If there's more than one float type then they're combined with union // narrower type is in the lowest part of the wider ones, specification calls it NaN-boxing model. if (types.Count > 1) { floatType = "nan_boxed_float"; var fields = new List <GDBTypeField>(); foreach (var type in types) { fields.Add(new GDBTypeField(type, $"ieee_{type}")); } var nanBoxedFloat = GDBCustomType.Union(floatType, fields); fpuGroup.Types.Add(nanBoxedFloat); } for (var index = 0u; index < NumberOfFRegisters; ++index) { fpuGroup.Registers.Add(new GDBRegisterDescriptor((uint)RiscV32Registers.F0 + index, fWidth, $"f{index}", floatType, "float")); } // fflags, frm and fcsr are not implemented but are required for architecture description var fflagsIndex = (uint)RiscV32Registers.F0 + NumberOfFRegisters; fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex, registerWidth, "fflags", "", "float")); fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex + 1, registerWidth, "frm", "", "float")); fpuGroup.Registers.Add(new GDBRegisterDescriptor(fflagsIndex + 2, registerWidth, "fcsr", "", "float")); { var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("NX", 0, 0, "bool")); fields.Add(new GDBTypeBitField("UF", 1, 1, "bool")); fields.Add(new GDBTypeBitField("OF", 2, 2, "bool")); fields.Add(new GDBTypeBitField("DZ", 3, 3, "bool")); fields.Add(new GDBTypeBitField("NV", 4, 4, "bool")); var fflagsFlagsType = GDBCustomType.Flags("fflags_flags_type", 1, fields); fpuGroup.Types.Add(fflagsFlagsType); } { var fields = new List <GDBTypeEnumValue>(); fields.Add(new GDBTypeEnumValue("RNE", 0b000)); fields.Add(new GDBTypeEnumValue("RTZ", 0b001)); fields.Add(new GDBTypeEnumValue("RDN", 0b010)); fields.Add(new GDBTypeEnumValue("RUP", 0b011)); fields.Add(new GDBTypeEnumValue("RMM", 0b100)); fields.Add(new GDBTypeEnumValue("DYN", 0b111)); var frmEnumType = GDBCustomType.Enum("frm_enum_type", 1, fields); fpuGroup.Types.Add(frmEnumType); } { var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("value", 0, 4, "fflags_flags_type")); var fflagsType = GDBCustomType.Struct("fflags_type", registerWidth / 8, fields); fpuGroup.Types.Add(fflagsType); } { var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("value", 0, 5, "frm_enum_type")); var frmType = GDBCustomType.Struct("frm_type", registerWidth / 8, fields); fpuGroup.Types.Add(frmType); } { var fields = new List <GDBTypeBitField>(); fields.Add(new GDBTypeBitField("flags", 0, 4, "fflags_flags_type")); fields.Add(new GDBTypeBitField("rm", 5, 7, "frm_enum_type")); var fcsrType = GDBCustomType.Struct("fcsr_type", registerWidth / 8, fields); fpuGroup.Types.Add(fcsrType); } features.Add(fpuGroup); }