0004-add-intial-rvv-support-to-display-rvv-registers.patch 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628
  1. From 6793d19defcc4baba2879006e5e2ce89396e3afc Mon Sep 17 00:00:00 2001
  2. From: "max.ma" <max.ma@starfivetech.com>
  3. Date: Tue, 1 Nov 2022 19:50:38 -0700
  4. Subject: [PATCH 4/7] add intial rvv support to display rvv registers
  5. ---
  6. gdb/arch/riscv.c | 12 ++-
  7. gdb/features/riscv/vpu.c | 66 +++++++++++++++++
  8. gdb/nat/riscv-linux-tdesc.c | 46 +++++++++++-
  9. gdb/nat/riscv-linux-tdesc.h | 18 +++++
  10. gdb/riscv-linux-nat.c | 139 +++++++++++++++++++++++++++++++++++
  11. gdb/riscv-tdep.c | 45 +++++++++++-
  12. gdb/riscv-tdep.h | 5 ++
  13. gdbserver/linux-riscv-low.cc | 58 +++++++++++++++
  14. include/elf/common.h | 4 +
  15. 9 files changed, 388 insertions(+), 5 deletions(-)
  16. create mode 100644 gdb/features/riscv/vpu.c
  17. diff --git a/gdb/arch/riscv.c b/gdb/arch/riscv.c
  18. index 030c2cfdd9..03fcf7360f 100644
  19. --- a/gdb/arch/riscv.c
  20. +++ b/gdb/arch/riscv.c
  21. @@ -25,6 +25,8 @@
  22. #include "../features/riscv/32bit-fpu.c"
  23. #include "../features/riscv/64bit-fpu.c"
  24. #include "../features/riscv/rv32e-xregs.c"
  25. +#include "../features/riscv/vpu.c"
  26. +
  27. #ifndef GDBSERVER
  28. #define STATIC_IN_GDB static
  29. @@ -61,6 +63,9 @@ riscv_create_target_description (const struct riscv_gdbarch_features features)
  30. arch_name.append ("d");
  31. else if (features.flen == 16)
  32. arch_name.append ("q");
  33. +
  34. + if (features.vlen > 0)
  35. + arch_name.append ("v");
  36. set_tdesc_architecture (tdesc.get (), arch_name.c_str ());
  37. #endif
  38. @@ -88,7 +93,12 @@ riscv_create_target_description (const struct riscv_gdbarch_features features)
  39. targets. We don't support creating vector features on native targets
  40. (yet). */
  41. if (features.vlen != 0)
  42. - error (_("unable to create vector feature"));
  43. + {
  44. + if (features.xlen == 4)
  45. + create_feature_riscv_vpu (tdesc.get (), 32, features.vlen);
  46. + else if (features.xlen == 8)
  47. + create_feature_riscv_vpu (tdesc.get (), 64, features.vlen);
  48. + }
  49. return tdesc;
  50. }
  51. diff --git a/gdb/features/riscv/vpu.c b/gdb/features/riscv/vpu.c
  52. new file mode 100644
  53. index 0000000000..fe45f37b4c
  54. --- /dev/null
  55. +++ b/gdb/features/riscv/vpu.c
  56. @@ -0,0 +1,66 @@
  57. +#include "gdbsupport/tdesc.h"
  58. +
  59. +static int
  60. +create_feature_riscv_vpu (struct target_desc *result, int arch, int vlen)
  61. +{
  62. + struct tdesc_feature *feature;
  63. + tdesc_type *element_type, *field_type;
  64. + tdesc_type_with_fields *type_with_fields;
  65. + int i, regnum;
  66. + char regname[10];
  67. + printf("create_feature_riscv_vpu\n ");
  68. +
  69. + feature = tdesc_create_feature (result, "org.gnu.gdb.riscv.vector");
  70. +
  71. + if (vlen >= 16)
  72. + {
  73. + element_type = tdesc_named_type (feature, "uint128");
  74. + tdesc_create_vector (feature, "v_quads", element_type, (vlen * 8)/128);
  75. + }
  76. + if (vlen >= 8)
  77. + {
  78. + element_type = tdesc_named_type (feature, "uint64");
  79. + tdesc_create_vector (feature, "v_longs", element_type, (vlen * 8)/64);
  80. + }
  81. + element_type = tdesc_named_type (feature, "uint32");
  82. + tdesc_create_vector (feature, "v_words", element_type, (vlen * 8)/32);
  83. + element_type = tdesc_named_type (feature, "uint16");
  84. + tdesc_create_vector (feature, "v_shorts", element_type, (vlen * 8)/32);
  85. + element_type = tdesc_named_type (feature, "uint8");
  86. + tdesc_create_vector (feature, "v_bytes", element_type, vlen);
  87. +
  88. + type_with_fields = tdesc_create_union (feature, "riscv_vector");
  89. + if (vlen >= 16)
  90. + {
  91. + field_type = tdesc_named_type (feature, "v_quads");
  92. + tdesc_add_field (type_with_fields, "q", field_type);
  93. + }
  94. + if (vlen >= 8)
  95. + {
  96. + field_type = tdesc_named_type (feature, "v_longs");
  97. + tdesc_add_field (type_with_fields, "l", field_type);
  98. + }
  99. + field_type = tdesc_named_type (feature, "v_words");
  100. + tdesc_add_field (type_with_fields, "w", field_type);
  101. + field_type = tdesc_named_type (feature, "v_shorts");
  102. + tdesc_add_field (type_with_fields, "s", field_type);
  103. + field_type = tdesc_named_type (feature, "v_bytes");
  104. + tdesc_add_field (type_with_fields, "b", field_type);
  105. +
  106. + tdesc_create_reg (feature, "vstart", 73, 1, NULL, arch, "int");
  107. + tdesc_create_reg (feature, "vcsr", 80, 1, NULL, arch, "int");
  108. + tdesc_create_reg (feature, "vl", 3169, 1, NULL, arch, "int");
  109. + tdesc_create_reg (feature, "vtype", 3170, 1, NULL, arch, "int");
  110. +
  111. + regnum = 4162;
  112. +
  113. + for (i = 0; i < 32; i++)
  114. + {
  115. + memset(regname, 0, sizeof(regname));
  116. + sprintf(regname, "v%d", i);
  117. + tdesc_create_reg (feature, regname, regnum++, 1,
  118. + NULL, vlen * 8, "riscv_vector");
  119. + }
  120. +
  121. + return regnum;
  122. +}
  123. diff --git a/gdb/nat/riscv-linux-tdesc.c b/gdb/nat/riscv-linux-tdesc.c
  124. index 07b49c0f16..b349035d9a 100644
  125. --- a/gdb/nat/riscv-linux-tdesc.c
  126. +++ b/gdb/nat/riscv-linux-tdesc.c
  127. @@ -23,7 +23,7 @@
  128. #include "elf/common.h"
  129. #include "nat/gdb_ptrace.h"
  130. #include "nat/riscv-linux-tdesc.h"
  131. -
  132. +#include "nat/linux-ptrace.h"
  133. #include <sys/uio.h>
  134. /* Work around glibc header breakage causing ELF_NFPREG not to be usable. */
  135. @@ -31,6 +31,26 @@
  136. # define NFPREG 33
  137. #endif
  138. +#ifndef CSR_VLENB
  139. +#define CSR_VLENB 0xC22
  140. +#endif
  141. +
  142. +#ifdef __ASSEMBLY__
  143. +#define __ASM_STR(x) x
  144. +#else
  145. +#define __ASM_STR(x) #x
  146. +#endif
  147. +
  148. +
  149. +#define csr_read(csr) \
  150. +({ \
  151. + register unsigned long __v; \
  152. + __asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \
  153. + : "=r" (__v) : \
  154. + : "memory"); \
  155. + __v; \
  156. +})
  157. +
  158. /* See nat/riscv-linux-tdesc.h. */
  159. struct riscv_gdbarch_features
  160. @@ -78,6 +98,30 @@ riscv_linux_read_features (int tid)
  161. features.flen = flen;
  162. break;
  163. }
  164. +
  165. + struct __riscv_v_state rv_state;
  166. + struct iovec iov;
  167. + iov.iov_base = &rv_state;
  168. + iov.iov_len = sizeof(rv_state);
  169. +
  170. + if (ptrace (PTRACE_GETREGSET, tid, NT_RISCV_VECTOR,
  171. + (PTRACE_TYPE_ARG3) &iov) == -1)
  172. + {
  173. + switch (errno)
  174. + {
  175. + case EINVAL:
  176. + break;
  177. + case EIO:
  178. + break;
  179. + default:
  180. + perror_with_name (_("Couldn't get registers"));
  181. + break;
  182. + }
  183. + }
  184. + else
  185. + {
  186. + features.vlen = csr_read(CSR_VLENB);
  187. + }
  188. return features;
  189. }
  190. diff --git a/gdb/nat/riscv-linux-tdesc.h b/gdb/nat/riscv-linux-tdesc.h
  191. index 4f476aed5c..092ee7d29b 100644
  192. --- a/gdb/nat/riscv-linux-tdesc.h
  193. +++ b/gdb/nat/riscv-linux-tdesc.h
  194. @@ -21,6 +21,24 @@
  195. #include "arch/riscv.h"
  196. +/* Work around glibc header breakage causing ELF_NFPREG not to be usable. */
  197. +#ifndef NFPREG
  198. +# define NFPREG 33
  199. +#endif
  200. +
  201. +#ifndef NVREG
  202. +#define NVREG 32
  203. +#endif
  204. +
  205. +#define csr_read(csr) \
  206. +({ \
  207. + register unsigned long __v; \
  208. + __asm__ __volatile__ ("csrr %0, " csr \
  209. + : "=r" (__v) : \
  210. + : "memory"); \
  211. + __v; \
  212. +})
  213. +
  214. /* Determine XLEN and FLEN for the LWP identified by TID, and return a
  215. corresponding features object. */
  216. struct riscv_gdbarch_features riscv_linux_read_features (int tid);
  217. diff --git a/gdb/riscv-linux-nat.c b/gdb/riscv-linux-nat.c
  218. index 7063494148..0e24cbcb86 100644
  219. --- a/gdb/riscv-linux-nat.c
  220. +++ b/gdb/riscv-linux-nat.c
  221. @@ -34,6 +34,10 @@
  222. # define NFPREG 33
  223. #endif
  224. +#ifndef ELF_NVREG
  225. +#define ELF_NVREG 32
  226. +#endif
  227. +
  228. /* RISC-V Linux native additions to the default linux support. */
  229. class riscv_linux_nat_target final : public linux_nat_target
  230. @@ -196,6 +200,90 @@ fill_fpregset (const struct regcache *regcache, prfpregset_t *fpregs,
  231. }
  232. }
  233. +/* Copy vector register REGNUM (or all vector regs if REGNUM == -1)
  234. + from regset vregs into REGCACHE. */
  235. +
  236. +static void
  237. +supply_vregset_regnum (struct regcache *regcache, char *vregs,
  238. + int regnum)
  239. +{
  240. + int i;
  241. + int vlen = riscv_isa_vlen(regcache->arch());
  242. + __riscv_v_state *vstate = (__riscv_v_state*)vregs;
  243. + vregs += sizeof(__riscv_v_state);
  244. +
  245. + if (regnum == -1)
  246. + {
  247. + regcache->raw_supply (RISCV_CSR_VSTART_REGNUM, &vstate->vstart);
  248. + regcache->raw_supply (RISCV_CSR_VCSR_REGNUM, &vstate->vcsr);
  249. + regcache->raw_supply (RISCV_CSR_VL_REGNUM, &vstate->vl);
  250. + regcache->raw_supply (RISCV_CSR_VTYPE_REGNUM, &vstate->vtype);
  251. +
  252. + for (i = RISCV_V0_REGNUM;
  253. + i <= RISCV_V31_REGNUM;
  254. + i++, vregs += vlen)
  255. + regcache->raw_supply (i, vregs);
  256. + }
  257. + else if (regnum >= RISCV_V0_REGNUM && regnum <= RISCV_V31_REGNUM)
  258. + {
  259. + vregs += (regnum - RISCV_V0_REGNUM) * vlen;
  260. + regcache->raw_supply (regnum, vregs);
  261. + }
  262. + else if (regnum == RISCV_CSR_VSTART_REGNUM)
  263. + regcache->raw_supply (regnum, &vstate->vstart);
  264. + else if (regnum == RISCV_CSR_VCSR_REGNUM)
  265. + regcache->raw_supply (regnum, &vstate->vcsr);
  266. + else if (regnum == RISCV_CSR_VL_REGNUM)
  267. + regcache->raw_supply (regnum, &vstate->vl);
  268. + else if (regnum == RISCV_CSR_VTYPE_REGNUM)
  269. + regcache->raw_supply (regnum, &vstate->vtype);
  270. +}
  271. +
  272. +
  273. +/* Copy all vector registers from regset vregs into REGCACHE. */
  274. +
  275. +void
  276. +supply_vregset (struct regcache *regcache, const void *vregs)
  277. +{
  278. + supply_vregset_regnum (regcache, (char *)vregs, -1);
  279. +}
  280. +
  281. +/* Copy vector register REGNUM (or all fp regs if REGNUM == -1)
  282. + from REGCACHE into regset FPREGS. */
  283. +void
  284. +fill_vregset (struct regcache *regcache, char *vregs,
  285. + int regnum)
  286. +{
  287. + int i;
  288. + int vlen = riscv_isa_vlen(regcache->arch());
  289. + __riscv_v_state *vstate = (__riscv_v_state*)vregs;
  290. + if (regnum == -1)
  291. + {
  292. + regcache->raw_collect (RISCV_CSR_VSTART_REGNUM, &vstate->vstart);
  293. + regcache->raw_collect (RISCV_CSR_VCSR_REGNUM, &vstate->vcsr);
  294. + regcache->raw_collect (RISCV_CSR_VL_REGNUM, &vstate->vl);
  295. + regcache->raw_collect (RISCV_CSR_VTYPE_REGNUM, &vstate->vtype);
  296. +
  297. + for (i = RISCV_V0_REGNUM;
  298. + i <= RISCV_V31_REGNUM;
  299. + i++, vregs += vlen)
  300. + regcache->raw_collect (i, vregs);
  301. + }
  302. + else if (regnum >= RISCV_V0_REGNUM && regnum <= RISCV_V31_REGNUM)
  303. + {
  304. + vregs += (regnum - RISCV_V0_REGNUM) * vlen;
  305. + regcache->raw_collect (regnum, vregs);
  306. + }
  307. + else if (regnum == RISCV_CSR_VSTART_REGNUM)
  308. + regcache->raw_collect (regnum, &vstate->vstart);
  309. + else if (regnum == RISCV_CSR_VCSR_REGNUM)
  310. + regcache->raw_collect (regnum, &vstate->vcsr);
  311. + else if (regnum == RISCV_CSR_VL_REGNUM)
  312. + regcache->raw_supply (regnum, &vstate->vl);
  313. + else if (regnum == RISCV_CSR_VTYPE_REGNUM)
  314. + regcache->raw_supply (regnum, &vstate->vl);
  315. +}
  316. +
  317. /* Return a target description for the current target. */
  318. const struct target_desc *
  319. @@ -252,6 +340,31 @@ riscv_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
  320. supply_fpregset_regnum (regcache, &regs, regnum);
  321. }
  322. + if ((regnum >= RISCV_V0_REGNUM
  323. + && regnum <= RISCV_V31_REGNUM)
  324. + || (regnum == RISCV_CSR_VSTART_REGNUM)
  325. + || (regnum == RISCV_CSR_VCSR_REGNUM)
  326. + || (regnum == RISCV_CSR_VL_REGNUM)
  327. + || (regnum == RISCV_CSR_VTYPE_REGNUM)
  328. + || (regnum == -1))
  329. + {
  330. + struct iovec iov;
  331. + iov.iov_len = sizeof(__riscv_v_state) +
  332. + ELF_NVREG * riscv_isa_vlen(regcache->arch());
  333. +
  334. + iov.iov_base = malloc(iov.iov_len);
  335. + char * buf = (char *)iov.iov_base + sizeof(__riscv_v_state);
  336. + gdb_assert (iov.iov_base != NULL);
  337. +
  338. + if (ptrace (PTRACE_GETREGSET, tid, NT_RISCV_VECTOR,
  339. + (PTRACE_TYPE_ARG3) &iov) == -1)
  340. + perror_with_name (_("Couldn't get vector registers"));
  341. + else
  342. + supply_vregset_regnum (regcache, (char *)(iov.iov_base), regnum);
  343. +
  344. + free(iov.iov_base);
  345. + }
  346. +
  347. if ((regnum == RISCV_CSR_MISA_REGNUM)
  348. || (regnum == -1))
  349. {
  350. @@ -321,6 +434,32 @@ riscv_linux_nat_target::store_registers (struct regcache *regcache, int regnum)
  351. }
  352. }
  353. + if ((regnum >= RISCV_V0_REGNUM
  354. + && regnum <= RISCV_V31_REGNUM)
  355. + || (regnum == RISCV_CSR_VSTART_REGNUM)
  356. + || (regnum == RISCV_CSR_VCSR_REGNUM)
  357. + || (regnum == RISCV_CSR_VL_REGNUM)
  358. + || (regnum == RISCV_CSR_VTYPE_REGNUM)
  359. + || (regnum == -1))
  360. + {
  361. + struct iovec iov;
  362. + iov.iov_len = sizeof(__riscv_v_state) +
  363. + ELF_NVREG * riscv_isa_vlen(regcache->arch ());
  364. + iov.iov_base = malloc(iov.iov_len);
  365. + gdb_assert (iov.iov_base != NULL);
  366. +
  367. + if (ptrace (PTRACE_GETREGSET, tid, NT_RISCV_VECTOR,
  368. + (PTRACE_TYPE_ARG3) &iov) == -1)
  369. + perror_with_name (_("Couldn't get vector registers"));
  370. + else
  371. + {
  372. + fill_vregset (regcache, (char *)(iov.iov_base), regnum);
  373. + if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET,
  374. + (PTRACE_TYPE_ARG3) &iov) == -1)
  375. + perror_with_name (_("Couldn't set vector registers"));
  376. + }
  377. + free(iov.iov_base);
  378. + }
  379. /* Access to CSRs has potential security issues, don't support them for
  380. now. */
  381. }
  382. diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
  383. index 886996ce5b..44ce340f39 100644
  384. --- a/gdb/riscv-tdep.c
  385. +++ b/gdb/riscv-tdep.c
  386. @@ -619,16 +619,21 @@ struct riscv_vector_feature : public riscv_register_feature
  387. { RISCV_V0_REGNUM + 29, { "v29" } },
  388. { RISCV_V0_REGNUM + 30, { "v30" } },
  389. { RISCV_V0_REGNUM + 31, { "v31" } },
  390. +
  391. + { RISCV_CSR_VSTART_REGNUM, { "vstart" } },
  392. + { RISCV_CSR_VCSR_REGNUM, { "vcsr" } },
  393. + { RISCV_CSR_VL_REGNUM, { "vl" } },
  394. + { RISCV_CSR_VTYPE_REGNUM, { "vtype" } },
  395. };
  396. }
  397. /* Return the preferred name for the register with gdb register number
  398. REGNUM, which must be in the inclusive range RISCV_V0_REGNUM to
  399. - RISCV_V0_REGNUM + 31. */
  400. + RISCV_V31_REGNUM. */
  401. const char *register_name (int regnum) const
  402. {
  403. gdb_assert (regnum >= RISCV_V0_REGNUM
  404. - && regnum <= RISCV_V0_REGNUM + 31);
  405. + && regnum <= RISCV_V31_REGNUM);
  406. regnum -= RISCV_V0_REGNUM;
  407. return m_registers[regnum].names[0];
  408. }
  409. @@ -663,6 +668,12 @@ struct riscv_vector_feature : public riscv_register_feature
  410. int vector_bitsize = -1;
  411. for (const auto &reg : m_registers)
  412. {
  413. + if (reg.regnum == RISCV_CSR_VSTART_REGNUM ||
  414. + reg.regnum == RISCV_CSR_VCSR_REGNUM ||
  415. + reg.regnum == RISCV_CSR_VL_REGNUM ||
  416. + reg.regnum == RISCV_CSR_VTYPE_REGNUM
  417. + )
  418. + continue;
  419. int reg_bitsize = -1;
  420. for (const char *name : reg.names)
  421. {
  422. @@ -737,6 +748,16 @@ riscv_isa_xlen (struct gdbarch *gdbarch)
  423. return tdep->isa_features.xlen;
  424. }
  425. +/* See riscv-tdep.h. */
  426. +
  427. +int
  428. +riscv_isa_vlen (struct gdbarch *gdbarch)
  429. +{
  430. + riscv_gdbarch_tdep *tdep = (riscv_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  431. + return tdep->isa_features.vlen;
  432. +}
  433. +
  434. +
  435. /* See riscv-tdep.h. */
  436. int
  437. @@ -781,6 +802,13 @@ riscv_has_fp_regs (struct gdbarch *gdbarch)
  438. return (riscv_isa_flen (gdbarch) > 0);
  439. }
  440. +/* Return true if the target for GDBARCH has vector hardware. */
  441. +static bool
  442. +riscv_has_v_regs (struct gdbarch *gdbarch)
  443. +{
  444. + return (riscv_isa_vlen (gdbarch) > 0);
  445. +}
  446. +
  447. /* Return true if GDBARCH is using any of the floating point hardware ABIs. */
  448. static bool
  449. @@ -873,7 +901,7 @@ riscv_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
  450. /* Implement the register_name gdbarch method. This is used instead of
  451. the function supplied by calling TDESC_USE_REGISTERS so that we can
  452. - ensure the preferred names are offered for x-regs and f-regs. */
  453. + ensure the preferred names are offered for x-regs,f-regs and v-regs. */
  454. static const char *
  455. riscv_register_name (struct gdbarch *gdbarch, int regnum)
  456. @@ -902,6 +930,14 @@ riscv_register_name (struct gdbarch *gdbarch, int regnum)
  457. return NULL;
  458. }
  459. + if (regnum >= RISCV_V0_REGNUM && regnum <= RISCV_LAST_REGNUM)
  460. + {
  461. + if (riscv_has_v_regs (gdbarch))
  462. + return riscv_vector_feature.register_name (regnum);
  463. + else
  464. + return NULL;
  465. + }
  466. +
  467. /* Some targets (QEMU) are reporting these three registers twice, once
  468. in the FPU feature, and once in the CSR feature. Both of these read
  469. the same underlying state inside the target, but naming the register
  470. @@ -3545,6 +3581,7 @@ riscv_gcc_target_options (struct gdbarch *gdbarch)
  471. {
  472. int isa_xlen = riscv_isa_xlen (gdbarch);
  473. int isa_flen = riscv_isa_flen (gdbarch);
  474. + int isa_vlen = riscv_isa_vlen (gdbarch);
  475. int abi_xlen = riscv_abi_xlen (gdbarch);
  476. int abi_flen = riscv_abi_flen (gdbarch);
  477. std::string target_options;
  478. @@ -3560,6 +3597,8 @@ riscv_gcc_target_options (struct gdbarch *gdbarch)
  479. target_options += "imafc";
  480. else
  481. target_options += "imac";
  482. + if (isa_vlen)
  483. + target_options += "v"; /* change to zvl zve later */
  484. target_options += " -mabi=";
  485. if (abi_xlen == 8)
  486. diff --git a/gdb/riscv-tdep.h b/gdb/riscv-tdep.h
  487. index ac4b4b7144..913c5f1724 100644
  488. --- a/gdb/riscv-tdep.h
  489. +++ b/gdb/riscv-tdep.h
  490. @@ -139,6 +139,11 @@ extern int riscv_abi_xlen (struct gdbarch *gdbarch);
  491. with RISCV_ISA_FLEN. */
  492. extern int riscv_abi_flen (struct gdbarch *gdbarch);
  493. +/* Return the width in bytes of the hardware vector registers for
  494. + GDBARCH. If this architecture has no vector registers, then
  495. + return 0. Possible values are 32, 64, 128, ...2pow(16) */
  496. +extern int riscv_isa_vlen(struct gdbarch *gdbarch);
  497. +
  498. /* Return true if GDBARCH is using the embedded x-regs abi, that is the
  499. target only has 16 x-registers, which includes a reduced number of
  500. argument registers. */
  501. diff --git a/gdbserver/linux-riscv-low.cc b/gdbserver/linux-riscv-low.cc
  502. index 6b2902e422..54444f9883 100644
  503. --- a/gdbserver/linux-riscv-low.cc
  504. +++ b/gdbserver/linux-riscv-low.cc
  505. @@ -30,6 +30,17 @@
  506. # define NFPREG 33
  507. #endif
  508. +#ifndef NVREG
  509. +#define NVREG 32
  510. +#endif
  511. +
  512. +/* In RVV spec, the register width must be no greater than 2exp(16).
  513. + We set the max width to 1024 for now.
  514. +*/
  515. +#ifndef VREG_MAX_LEN
  516. +#define VREG_MAX_LEN 1024
  517. +#endif
  518. +
  519. /* Linux target op definitions for the RISC-V architecture. */
  520. class riscv_target : public linux_process_target
  521. @@ -158,6 +169,50 @@ riscv_store_fpregset (struct regcache *regcache, const void *buf)
  522. supply_register_by_name (regcache, "fcsr", regbuf);
  523. }
  524. +
  525. +/* Collect VRs from REGCACHE into BUF. */
  526. +
  527. +static void
  528. +riscv_fill_vregset (struct regcache *regcache, void *buf)
  529. +{
  530. + int i;
  531. + const struct target_desc *tdesc = regcache->tdesc;
  532. + int regno = find_regno (tdesc, "v0");
  533. + int vlen = register_size (regcache->tdesc, regno);
  534. + __riscv_v_state *vstate = (__riscv_v_state *)buf;
  535. + buf += sizeof(__riscv_v_state);
  536. +
  537. + for (i = 0; i < NVREG; i++, buf += vlen)
  538. + collect_register (regcache, regno + i, buf);
  539. +
  540. + collect_register_by_name (regcache, "vstart", &vstate->vstart);
  541. + collect_register_by_name (regcache, "vl", &vstate->vl);
  542. + collect_register_by_name (regcache, "vtype", &vstate->vtype);
  543. + collect_register_by_name (regcache, "vcsr", &vstate->vcsr);
  544. +}
  545. +
  546. +/* Supply VECRs from BUF into REGCACHE. */
  547. +
  548. +static void
  549. +riscv_store_vregset (struct regcache *regcache, const void *buf)
  550. +{
  551. + const struct target_desc *tdesc = regcache->tdesc;
  552. + struct __riscv_v_state *vstate = (__riscv_v_state *)buf;
  553. + buf += sizeof(__riscv_v_state);
  554. + int regno = find_regno (tdesc, "v0");
  555. + int vlen = register_size (regcache->tdesc, regno);
  556. + int i;
  557. +
  558. + for (i = 0; i < NVREG; i++, buf += vlen)
  559. + supply_register (regcache, regno + i, buf);
  560. +
  561. + supply_register_by_name (regcache, "vstart", &vstate->vstart);
  562. + supply_register_by_name (regcache, "vl", &vstate->vl);
  563. + supply_register_by_name (regcache, "vtype", &vstate->vtype);
  564. + supply_register_by_name (regcache, "vcsr", &vstate->vcsr); ;
  565. +}
  566. +
  567. +
  568. /* RISC-V/Linux regsets. FPRs are optional and come in different sizes,
  569. so define multiple regsets for them marking them all as OPTIONAL_REGS
  570. rather than FP_REGS, so that "regsets_fetch_inferior_registers" picks
  571. @@ -175,6 +230,9 @@ static struct regset_info riscv_regsets[] = {
  572. { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET,
  573. sizeof (struct __riscv_mc_f_ext_state), OPTIONAL_REGS,
  574. riscv_fill_fpregset, riscv_store_fpregset },
  575. + { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_RISCV_VECTOR,
  576. + sizeof (struct __riscv_v_state) + NVREG * VREG_MAX_LEN, EXTENDED_REGS,
  577. + riscv_fill_vregset, riscv_store_vregset},
  578. NULL_REGSET
  579. };
  580. diff --git a/include/elf/common.h b/include/elf/common.h
  581. index 70d63e3299..2662e767ba 100644
  582. --- a/include/elf/common.h
  583. +++ b/include/elf/common.h
  584. @@ -690,6 +690,10 @@
  585. /* note name must be "LINUX". */
  586. #define NT_ARM_PAC_ENABLED_KEYS 0x40a /* AArch64 pointer authentication
  587. enabled keys (prctl()) */
  588. +
  589. + /* note name must be "LINUX". */
  590. +#define NT_RISCV_VECTOR 0x900 /* RISC-V vector registers */
  591. +
  592. /* note name must be "LINUX". */
  593. #define NT_ARC_V2 0x600 /* ARC HS accumulator/extra registers. */
  594. /* note name must be "LINUX". */
  595. --
  596. 2.25.1