]>
Commit | Line | Data |
---|---|---|
036b1ba8 JB |
1 | /* Ada Ravenscar thread support. |
2 | ||
1d506c26 | 3 | Copyright (C) 2004-2024 Free Software Foundation, Inc. |
036b1ba8 JB |
4 | |
5 | This file is part of GDB. | |
6 | ||
7 | This program is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | This program is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #ifndef RAVENSCAR_THREAD_H | |
21 | #define RAVENSCAR_THREAD_H | |
22 | ||
23 | /* Architecture-specific hooks. */ | |
24 | ||
25 | struct ravenscar_arch_ops | |
26 | { | |
e73434e3 TT |
27 | ravenscar_arch_ops (gdb::array_view<const int> offsets_, |
28 | int first_stack = -1, | |
965b71a7 TT |
29 | int last_stack = -1, |
30 | int v_init = -1, | |
31 | int fpu_offset = -1, | |
32 | int first_fp = -1, | |
33 | int last_fp = -1) | |
e73434e3 TT |
34 | : offsets (offsets_), |
35 | first_stack_register (first_stack), | |
965b71a7 TT |
36 | last_stack_register (last_stack), |
37 | v_init_offset (v_init), | |
38 | fpu_context_offset (fpu_offset), | |
39 | first_fp_register (first_fp), | |
40 | last_fp_register (last_fp) | |
7657f14d | 41 | { |
e73434e3 TT |
42 | /* These must either both be -1 or both be valid. */ |
43 | gdb_assert ((first_stack_register == -1) == (last_stack_register == -1)); | |
44 | /* They must also be ordered. */ | |
45 | gdb_assert (last_stack_register >= first_stack_register); | |
965b71a7 TT |
46 | /* These must either all be -1 or all be valid. */ |
47 | gdb_assert ((v_init_offset == -1) == (fpu_context_offset == -1) | |
48 | && (fpu_context_offset == -1) == (first_fp_register == -1) | |
49 | && (first_fp_register == -1) == (last_fp_register == -1)); | |
7657f14d TT |
50 | } |
51 | ||
965b71a7 TT |
52 | /* Return true if this architecture implements on-demand floating |
53 | point. */ | |
54 | bool on_demand_fp () const | |
55 | { return v_init_offset != -1; } | |
56 | ||
57 | /* Return true if REGNUM is a floating-point register for this | |
58 | target. If this target does not use the on-demand FP scheme, | |
59 | this will always return false. */ | |
60 | bool is_fp_register (int regnum) const | |
61 | { | |
62 | return regnum >= first_fp_register && regnum <= last_fp_register; | |
63 | } | |
64 | ||
65 | /* Return the offset, in the current task context, of the byte | |
66 | indicating whether the FPU has been initialized for the task. | |
67 | This can only be called when the architecture implements | |
68 | on-demand floating-point. */ | |
69 | int get_v_init_offset () const | |
70 | { | |
71 | gdb_assert (on_demand_fp ()); | |
72 | return v_init_offset; | |
73 | } | |
74 | ||
75 | /* Return the offset, in the current task context, of the FPU | |
76 | context. This can only be called when the architecture | |
77 | implements on-demand floating-point. */ | |
78 | int get_fpu_context_offset () const | |
79 | { | |
80 | gdb_assert (on_demand_fp ()); | |
81 | return fpu_context_offset; | |
82 | } | |
83 | ||
84 | void fetch_register (struct regcache *recache, int regnum) const; | |
85 | void store_register (struct regcache *recache, int regnum) const; | |
e73434e3 TT |
86 | |
87 | private: | |
88 | ||
89 | /* An array where the indices are register numbers and the contents | |
90 | are offsets. The offsets are either in the thread descriptor or | |
91 | the stack, depending on the other fields. An offset of -1 means | |
92 | that the corresponding register is not stored. */ | |
93 | const gdb::array_view<const int> offsets; | |
94 | ||
95 | /* If these are -1, then all registers for this architecture are | |
96 | stored in the thread descriptor. Otherwise, these mark a range | |
97 | of registers that are stored on the stack. */ | |
98 | const int first_stack_register; | |
99 | const int last_stack_register; | |
100 | ||
965b71a7 TT |
101 | /* If these are -1, there is no special treatment for floating-point |
102 | registers -- they are handled, or not, just like all other | |
103 | registers. | |
104 | ||
105 | Otherwise, they must all not be -1, and the target is one that | |
106 | uses on-demand FP initialization. V_INIT_OFFSET is the offset of | |
107 | a boolean field in the context that indicates whether the FP | |
108 | registers have been initialized for this task. | |
109 | FPU_CONTEXT_OFFSET is the offset of the FPU context from the task | |
110 | context. (This is needed to check whether the FPU registers have | |
111 | been saved.) FIRST_FP_REGISTER and LAST_FP_REGISTER are the | |
112 | register numbers of the first and last (inclusive) floating point | |
113 | registers. */ | |
114 | const int v_init_offset; | |
115 | const int fpu_context_offset; | |
116 | const int first_fp_register; | |
117 | const int last_fp_register; | |
118 | ||
e73434e3 TT |
119 | /* Helper function to supply one register. */ |
120 | void supply_one_register (struct regcache *regcache, int regnum, | |
121 | CORE_ADDR descriptor, | |
122 | CORE_ADDR stack_base) const; | |
123 | /* Helper function to store one register. */ | |
124 | void store_one_register (struct regcache *regcache, int regnum, | |
125 | CORE_ADDR descriptor, | |
126 | CORE_ADDR stack_base) const; | |
127 | /* Helper function to find stack address where registers are stored. | |
128 | This must be called with the stack pointer already supplied in | |
129 | the register cache. */ | |
130 | CORE_ADDR get_stack_base (struct regcache *) const; | |
036b1ba8 JB |
131 | }; |
132 | ||
036b1ba8 | 133 | #endif /* !defined (RAVENSCAR_THREAD_H) */ |