27
27
// struct iovec definition
28
28
#include < sys/uio.h>
29
29
30
- #define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
30
+ #ifndef NT_LOONGARCH_LSX
31
+ #define NT_LOONGARCH_LSX 0xa02 /* LoongArch SIMD eXtension registers */
32
+ #endif
33
+
34
+ #ifndef NT_LOONGARCH_LASX
35
+ #define NT_LOONGARCH_LASX \
36
+ 0xa03 /* LoongArch Advanced SIMD eXtension registers */
37
+ #endif
38
+
39
+ #define REG_CONTEXT_SIZE \
40
+ (GetGPRSize() + GetFPRSize() + sizeof (m_lsx) + sizeof (m_lasx))
31
41
32
42
using namespace lldb ;
33
43
using namespace lldb_private ;
@@ -62,6 +72,8 @@ NativeRegisterContextLinux_loongarch64::NativeRegisterContextLinux_loongarch64(
62
72
NativeRegisterContextLinux(native_thread) {
63
73
::memset (&m_fpr, 0 , sizeof (m_fpr));
64
74
::memset (&m_gpr, 0 , sizeof (m_gpr));
75
+ ::memset (&m_lsx, 0 , sizeof (m_lsx));
76
+ ::memset (&m_lasx, 0 , sizeof (m_lasx));
65
77
66
78
::memset (&m_hwp_regs, 0 , sizeof (m_hwp_regs));
67
79
::memset (&m_hbp_regs, 0 , sizeof (m_hbp_regs));
@@ -75,6 +87,8 @@ NativeRegisterContextLinux_loongarch64::NativeRegisterContextLinux_loongarch64(
75
87
76
88
m_gpr_is_valid = false ;
77
89
m_fpu_is_valid = false ;
90
+ m_lsx_is_valid = false ;
91
+ m_lasx_is_valid = false ;
78
92
}
79
93
80
94
const RegisterInfoPOSIX_loongarch64 &
@@ -135,6 +149,22 @@ Status NativeRegisterContextLinux_loongarch64::ReadRegister(
135
149
offset = CalculateFprOffset (reg_info);
136
150
assert (offset < GetFPRSize ());
137
151
src = (uint8_t *)GetFPRBuffer () + offset;
152
+ } else if (IsLSX (reg)) {
153
+ error = ReadLSX ();
154
+ if (error.Fail ())
155
+ return error;
156
+
157
+ offset = CalculateLsxOffset (reg_info);
158
+ assert (offset < sizeof (m_lsx));
159
+ src = (uint8_t *)&m_lsx + offset;
160
+ } else if (IsLASX (reg)) {
161
+ error = ReadLASX ();
162
+ if (error.Fail ())
163
+ return error;
164
+
165
+ offset = CalculateLasxOffset (reg_info);
166
+ assert (offset < sizeof (m_lasx));
167
+ src = (uint8_t *)&m_lasx + offset;
138
168
} else
139
169
return Status::FromErrorString (
140
170
" failed - register wasn't recognized to be a GPR or an FPR, "
@@ -184,6 +214,28 @@ Status NativeRegisterContextLinux_loongarch64::WriteRegister(
184
214
::memcpy (dst, reg_value.GetBytes(), reg_info->byte_size);
185
215
186
216
return WriteFPR ();
217
+ } else if (IsLSX (reg)) {
218
+ error = ReadLSX ();
219
+ if (error.Fail ())
220
+ return error;
221
+
222
+ offset = CalculateLsxOffset (reg_info);
223
+ assert (offset < sizeof (m_lsx));
224
+ dst = (uint8_t *)&m_lsx + offset;
225
+ ::memcpy (dst, reg_value.GetBytes(), reg_info->byte_size);
226
+
227
+ return WriteLSX ();
228
+ } else if (IsLASX (reg)) {
229
+ error = ReadLASX ();
230
+ if (error.Fail ())
231
+ return error;
232
+
233
+ offset = CalculateLasxOffset (reg_info);
234
+ assert (offset < sizeof (m_lasx));
235
+ dst = (uint8_t *)&m_lasx + offset;
236
+ ::memcpy (dst, reg_value.GetBytes(), reg_info->byte_size);
237
+
238
+ return WriteLASX ();
187
239
}
188
240
189
241
return Status::FromErrorString (" Failed to write register value" );
@@ -203,10 +255,22 @@ Status NativeRegisterContextLinux_loongarch64::ReadAllRegisterValues(
203
255
if (error.Fail ())
204
256
return error;
205
257
258
+ error = ReadLSX ();
259
+ if (error.Fail ())
260
+ return error;
261
+
262
+ error = ReadLASX ();
263
+ if (error.Fail ())
264
+ return error;
265
+
206
266
uint8_t *dst = data_sp->GetBytes ();
207
267
::memcpy (dst, GetGPRBuffer(), GetGPRSize());
208
268
dst += GetGPRSize ();
209
269
::memcpy (dst, GetFPRBuffer(), GetFPRSize());
270
+ dst += GetFPRSize ();
271
+ ::memcpy (dst, &m_lsx, sizeof (m_lsx));
272
+ dst += sizeof (m_lsx);
273
+ ::memcpy (dst, &m_lasx, sizeof (m_lasx));
210
274
211
275
return error;
212
276
}
@@ -247,11 +311,27 @@ Status NativeRegisterContextLinux_loongarch64::WriteAllRegisterValues(
247
311
248
312
src += GetRegisterInfoInterface ().GetGPRSize ();
249
313
::memcpy (GetFPRBuffer(), src, GetFPRSize());
250
-
314
+ m_fpu_is_valid = true ;
251
315
error = WriteFPR ();
252
316
if (error.Fail ())
253
317
return error;
254
318
319
+ // Currently, we assume that LoongArch always support LASX.
320
+ // TODO: check whether LSX/LASX exists.
321
+ src += GetFPRSize ();
322
+ ::memcpy (&m_lsx, src, sizeof (m_lsx));
323
+ m_lsx_is_valid = true ;
324
+ error = WriteLSX ();
325
+ if (error.Fail ())
326
+ return error;
327
+
328
+ src += sizeof (m_lsx);
329
+ ::memcpy (&m_lasx, src, sizeof (m_lasx));
330
+ m_lasx_is_valid = true ;
331
+ error = WriteLASX ();
332
+ if (error.Fail ())
333
+ return error;
334
+
255
335
return error;
256
336
}
257
337
@@ -265,6 +345,16 @@ bool NativeRegisterContextLinux_loongarch64::IsFPR(unsigned reg) const {
265
345
RegisterInfoPOSIX_loongarch64::FPRegSet;
266
346
}
267
347
348
+ bool NativeRegisterContextLinux_loongarch64::IsLSX (unsigned reg) const {
349
+ return GetRegisterInfo ().GetRegisterSetFromRegisterIndex (reg) ==
350
+ RegisterInfoPOSIX_loongarch64::LSXRegSet;
351
+ }
352
+
353
+ bool NativeRegisterContextLinux_loongarch64::IsLASX (unsigned reg) const {
354
+ return GetRegisterInfo ().GetRegisterSetFromRegisterIndex (reg) ==
355
+ RegisterInfoPOSIX_loongarch64::LASXRegSet;
356
+ }
357
+
268
358
Status NativeRegisterContextLinux_loongarch64::ReadGPR () {
269
359
Status error;
270
360
@@ -325,20 +415,102 @@ Status NativeRegisterContextLinux_loongarch64::WriteFPR() {
325
415
ioVec.iov_len = GetFPRSize ();
326
416
327
417
m_fpu_is_valid = false ;
418
+ m_lsx_is_valid = false ;
419
+ m_lasx_is_valid = false ;
328
420
329
421
return WriteRegisterSet (&ioVec, GetFPRSize (), NT_FPREGSET);
330
422
}
331
423
424
+ Status NativeRegisterContextLinux_loongarch64::ReadLSX () {
425
+ Status error;
426
+
427
+ if (m_lsx_is_valid)
428
+ return error;
429
+
430
+ struct iovec ioVec;
431
+ ioVec.iov_base = &m_lsx;
432
+ ioVec.iov_len = sizeof (m_lsx);
433
+
434
+ error = ReadRegisterSet (&ioVec, sizeof (m_lsx), NT_LOONGARCH_LSX);
435
+
436
+ if (error.Success ())
437
+ m_lsx_is_valid = true ;
438
+
439
+ return error;
440
+ }
441
+
442
+ Status NativeRegisterContextLinux_loongarch64::WriteLSX () {
443
+ Status error = ReadLSX ();
444
+ if (error.Fail ())
445
+ return error;
446
+
447
+ struct iovec ioVec;
448
+ ioVec.iov_base = &m_lsx;
449
+ ioVec.iov_len = sizeof (m_lsx);
450
+
451
+ m_fpu_is_valid = false ;
452
+ m_lsx_is_valid = false ;
453
+ m_lasx_is_valid = false ;
454
+
455
+ return WriteRegisterSet (&ioVec, sizeof (m_lsx), NT_LOONGARCH_LSX);
456
+ }
457
+
458
+ Status NativeRegisterContextLinux_loongarch64::ReadLASX () {
459
+ Status error;
460
+
461
+ if (m_lasx_is_valid)
462
+ return error;
463
+
464
+ struct iovec ioVec;
465
+ ioVec.iov_base = &m_lasx;
466
+ ioVec.iov_len = sizeof (m_lasx);
467
+
468
+ error = ReadRegisterSet (&ioVec, sizeof (m_lasx), NT_LOONGARCH_LASX);
469
+
470
+ if (error.Success ())
471
+ m_lasx_is_valid = true ;
472
+
473
+ return error;
474
+ }
475
+
476
+ Status NativeRegisterContextLinux_loongarch64::WriteLASX () {
477
+ Status error = ReadLASX ();
478
+ if (error.Fail ())
479
+ return error;
480
+
481
+ struct iovec ioVec;
482
+ ioVec.iov_base = &m_lasx;
483
+ ioVec.iov_len = sizeof (m_lasx);
484
+
485
+ m_fpu_is_valid = false ;
486
+ m_lsx_is_valid = false ;
487
+ m_lasx_is_valid = false ;
488
+
489
+ return WriteRegisterSet (&ioVec, sizeof (m_lasx), NT_LOONGARCH_LASX);
490
+ }
491
+
332
492
void NativeRegisterContextLinux_loongarch64::InvalidateAllRegisters () {
333
493
m_gpr_is_valid = false ;
334
494
m_fpu_is_valid = false ;
495
+ m_lsx_is_valid = false ;
496
+ m_lasx_is_valid = false ;
335
497
}
336
498
337
499
uint32_t NativeRegisterContextLinux_loongarch64::CalculateFprOffset (
338
500
const RegisterInfo *reg_info) const {
339
501
return reg_info->byte_offset - GetGPRSize ();
340
502
}
341
503
504
+ uint32_t NativeRegisterContextLinux_loongarch64::CalculateLsxOffset (
505
+ const RegisterInfo *reg_info) const {
506
+ return reg_info->byte_offset - GetGPRSize () - sizeof (m_fpr);
507
+ }
508
+
509
+ uint32_t NativeRegisterContextLinux_loongarch64::CalculateLasxOffset (
510
+ const RegisterInfo *reg_info) const {
511
+ return reg_info->byte_offset - GetGPRSize () - sizeof (m_fpr) - sizeof (m_lsx);
512
+ }
513
+
342
514
std::vector<uint32_t >
343
515
NativeRegisterContextLinux_loongarch64::GetExpeditedRegisters (
344
516
ExpeditedRegs expType) const {
0 commit comments