/* Target-dependent code for the RISC-V architecture, for GDB.
- Copyright (C) 2018-2021 Free Software Foundation, Inc.
+ Copyright (C) 2018-2022 Free Software Foundation, Inc.
This file is part of GDB.
static const char *riscv_feature_name_virtual = "org.gnu.gdb.riscv.virtual";
static const char *riscv_feature_name_vector = "org.gnu.gdb.riscv.vector";
+/* The current set of options to be passed to the disassembler. */
+static char *riscv_disassembler_options;
+
/* Cached information about a frame. */
struct riscv_unwind_cache
case 4:
return ebreak;
default:
- gdb_assert_not_reached (_("unhandled breakpoint kind"));
+ gdb_assert_not_reached ("unhandled breakpoint kind");
}
}
case TYPE_CODE_RANGE:
case TYPE_CODE_ENUM:
case TYPE_CODE_PTR:
+ case TYPE_CODE_FIXED_POINT:
if (ainfo->length <= cinfo->xlen)
{
ainfo->type = builtin_type (gdbarch)->builtin_long;
break;
default:
- gdb_assert_not_reached (_("unknown argument location type"));
+ gdb_assert_not_reached ("unknown argument location type");
}
}
break;
default:
- gdb_assert_not_reached (_("unknown argument location type"));
+ gdb_assert_not_reached ("unknown argument location type");
}
if (second_arg_length > 0)
buffers of sufficient size. */
if (writebuf != nullptr)
{
- struct value *arg_val = value_from_contents (arg_type, writebuf);
- abi_val = value_cast (info.type, arg_val);
+ struct value *arg_val;
+
+ if (is_fixed_point_type (arg_type))
+ {
+ /* Convert the argument to the type used to pass
+ the return value, but being careful to preserve
+ the fact that the value needs to be returned
+ unscaled. */
+ gdb_mpz unscaled;
+
+ unscaled.read (gdb::make_array_view (writebuf,
+ TYPE_LENGTH (arg_type)),
+ type_byte_order (arg_type),
+ arg_type->is_unsigned ());
+ abi_val = allocate_value (info.type);
+ unscaled.write (value_contents_raw (abi_val),
+ type_byte_order (info.type),
+ info.type->is_unsigned ());
+ }
+ else
+ {
+ arg_val = value_from_contents (arg_type, writebuf);
+ abi_val = value_cast (info.type, arg_val);
+ }
writebuf = value_contents_raw (abi_val).data ();
}
else
comment at the head of this block for more details. */
if (readbuf != nullptr)
{
- struct value *arg_val = value_cast (arg_type, abi_val);
+ struct value *arg_val;
+
+ if (is_fixed_point_type (arg_type))
+ {
+ /* Convert abi_val to the actual return type, but
+ being careful to preserve the fact that abi_val
+ is unscaled. */
+ gdb_mpz unscaled;
+
+ unscaled.read (value_contents (abi_val),
+ type_byte_order (info.type),
+ info.type->is_unsigned ());
+ arg_val = allocate_value (arg_type);
+ unscaled.write (value_contents_raw (arg_val),
+ type_byte_order (arg_type),
+ arg_type->is_unsigned ());
+ }
+ else
+ arg_val = value_cast (arg_type, abi_val);
memcpy (old_readbuf, value_contents_raw (arg_val).data (),
TYPE_LENGTH (arg_type));
}
set_gdbarch_gcc_target_options (gdbarch, riscv_gcc_target_options);
set_gdbarch_gnu_triplet_regexp (gdbarch, riscv_gnu_triplet_regexp);
+ /* Disassembler options support. */
+ set_gdbarch_valid_disassembler_options (gdbarch,
+ disassembler_options_riscv ());
+ set_gdbarch_disassembler_options (gdbarch, &riscv_disassembler_options);
+
/* Hook in OS ABI-specific overrides, if they have been registered. */
gdbarch_init_osabi (info, gdbarch);