Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
relibc
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
redox-os
relibc
Commits
9a7cfaea
Verified
Commit
9a7cfaea
authored
8 months ago
by
Jacob Lorentzon
Browse files
Options
Downloads
Patches
Plain Diff
Simplify aarch64 asm slightly.
parent
e860a19e
No related branches found
No related tags found
1 merge request
!493
Implement realtime signals and remaining signal.h APIs
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
redox-rt/src/arch/aarch64.rs
+63
-36
63 additions, 36 deletions
redox-rt/src/arch/aarch64.rs
with
63 additions
and
36 deletions
redox-rt/src/arch/aarch64.rs
+
63
−
36
View file @
9a7cfaea
...
@@ -26,7 +26,8 @@ pub struct SigArea {
...
@@ -26,7 +26,8 @@ pub struct SigArea {
pub
pctl
:
usize
,
// TODO: remove
pub
pctl
:
usize
,
// TODO: remove
pub
last_sig_was_restart
:
bool
,
pub
last_sig_was_restart
:
bool
,
pub
last_sigstack
:
Option
<
NonNull
<
SigStack
>>
,
pub
last_sigstack
:
Option
<
NonNull
<
SigStack
>>
,
pub
tmp_inf
:
RtSigInfo
,
pub
tmp_rt_inf
:
RtSigInfo
,
pub
tmp_id_inf
:
u64
,
}
}
#[repr(C)]
#[repr(C)]
#[derive(Debug,
Default)]
#[derive(Debug,
Default)]
...
@@ -176,65 +177,73 @@ asmfunction!(__relibc_internal_sigentry: ["
...
@@ -176,65 +177,73 @@ asmfunction!(__relibc_internal_sigentry: ["
ldr x6, [x0, #{tcb_sa_off} + {sa_pctl}]
ldr x6, [x0, #{tcb_sa_off} + {sa_pctl}]
1:
1:
// Load x1 and x2 with each signal group's bits (tearing between x1 and x2 can occur) with
// Load x1 with the thread's bits
// acquire ordering
add x5, x0, #{tcb_sc_off} + {sc_word}
add x2, x0, #{tcb_sc_off} + {sc_word}
ldaxr x1, [x5]
ldaxp x1, x2, [x2]
// First check if there are standard thread signals,
// First check if there are standard thread signals,
and x4, x1, x1, lsr #32 // x4 := x1 & (x1 >> 32)
and x4, x1, x1, lsr #32 // x4 := x1 & (x1 >> 32)
cbnz x4, 3f // jump if x4 != 0
cbnz x4, 3f // jump if x4 != 0
clrex
// and if not, load process pending bitset.
// and if not, load process pending bitset.
add x
3
, x6, #{pctl_pending}
add x
1
, x6, #{pctl_pending}
ldaxr x
3
, [x
3
]
ldaxr x
2
, [x
1
]
// Check if there are standard proc signals:
// Check if there are standard proc signals:
lsr x
4
, x1, #32 // mask
lsr x
3
, x1, #32 // mask
and w
4
, w
4
, w3 // pending unblocked proc
and w
3
, w
3
, w3 // pending unblocked proc
cbz w
4
, 4f // skip 'fetch_andn' step if zero
cbz w
3
, 4f // skip 'fetch_andn' step if zero
// If there was one, find which one, and try clearing the bit (last value in x3, addr in x6)
// If there was one, find which one, and try clearing the bit (last value in x3, addr in x6)
// this picks the MSB rather than the LSB, unlike x86. POSIX does not require any specific
// this picks the MSB rather than the LSB, unlike x86. POSIX does not require any specific
// ordering though.
// ordering though.
clz x4, x4
clz x3, x3
mov x5, #32
mov x4, #32
sub x4, x5, x4
sub x3, x4, x3
// x3 now contains the sig_idx
mov x
5
, #1
mov x
4
, #1
lsl x
5
, x
5
, x
4
// bit to remove
lsl x
4
, x
4
, x
3
// bit to remove
sub x5, x3, x5 // bit was certainly set, so sub is allowed
sub x4, x2, x4 // bit was certainly set, so sub is allowed
add x3, x6, #{pctl_pending}
// x4 is now the new mask to be set
add x5, x6, #{pctl_pending}
// Try clearing the bit, retrying on failure.
// Try clearing the bit, retrying on failure.
add x3, x6, #{pctl_pending}
stxr w1, x4, [x1] // try setting pending set to x4, set w1 := 0 on success
stxr w1, x5, [x3] // try setting [x3] to x5, set x5 := 0 on success
cbnz x1, 1b // retry everything if this fails
cbnz x1, 1b
mov x1, x3
mov x1, x4
b 2f
b 2f
4:
4:
// Check for realtime signals, thread/proc.
x1 is now free real estate (but needs to contain
// Check for realtime signals, thread/proc.
// the selected signal number when entering Rust).
clrex
b .
// Load the pending set again. TODO: optimize this?
add x1, x6, #{pctl_pending}
ldaxr x2, [x1]
lsr x2, x2, #32
mov w1, w2
add x5, x0, #{tcb_sc_off} + {sc_word} + 8
orr w1, w1, w3
ldar x1, [x5]
and x1, x1, x1, lsr #32
rbit x1, x1
orr x2, x1, x2
clz x1, x1
and x2, x2, x2, lsr #32
mov x2, #32
sub x1, x2, x1
rbit x3, x2
mov x2, #1
clz x3, x3
lsl x2, x2, x1
mov x4, #32
sub x2, x4, x3
// x2 now contains sig_idx - 32
// If realtime signal was directed at thread, handle it as an idempotent signal.
tbnz x1, x2, 5f
mov x5, x0
mov x5, x0
mov x4, x8
mov x4, x8
mov x8, {SYS_SIGDEQUEUE}
mov x8, {SYS_SIGDEQUEUE}
// x1 contains signal
// x1 contains signal
add x2, x0, #{tcb_sa_off} + {sa_tmp_inf}
add x2, x0, #{tcb_sa_off} + {sa_tmp_
rt_
inf}
svc 0
svc 0
cbnz x0, 1b
cbnz x0, 1b
mov x0, x5
mov x0, x5
...
@@ -254,10 +263,26 @@ asmfunction!(__relibc_internal_sigentry: ["
...
@@ -254,10 +263,26 @@ asmfunction!(__relibc_internal_sigentry: ["
// skip sigaltstack step if SA_ONSTACK is clear
// skip sigaltstack step if SA_ONSTACK is clear
// tbz x2, #{SA_ONSTACK_BIT}, 2f
// tbz x2, #{SA_ONSTACK_BIT}, 2f
b 2f
5:
add x1, x2, 32
b 3b
3:
3:
// A signal was sent to this thread, try clearing its bit.
clz x1, x1
clz x1, x1
mov x2, #32
+ 64
mov x2, #32
sub x1, x2, x1
sub x1, x2, x1
add x2, x0, #{tcb_sc_off} + {sc_sender_infos}
add x2, x2, w1, utxb #3
ldar x2, [x2]
stxr w3, x1, [x5]
cbnz w3, 1b
str x3, [x0, #{tcb_sa_off} + {sa_tmp_id_inf}]
add x1, x1, #64
b 2f
2:
2:
ldr x2, [x0, #{tcb_sc_off} + {sc_saved_pc}]
ldr x2, [x0, #{tcb_sc_off} + {sc_saved_pc}]
ldr x3, [x0, #{tcb_sc_off} + {sc_saved_x0}]
ldr x3, [x0, #{tcb_sc_off} + {sc_saved_x0}]
...
@@ -325,10 +350,12 @@ asmfunction!(__relibc_internal_sigentry: ["
...
@@ -325,10 +350,12 @@ asmfunction!(__relibc_internal_sigentry: ["
sa_tmp_x3_x4
=
const
offset_of!
(
SigArea
,
tmp_x3_x4
),
sa_tmp_x3_x4
=
const
offset_of!
(
SigArea
,
tmp_x3_x4
),
sa_tmp_x5_x6
=
const
offset_of!
(
SigArea
,
tmp_x5_x6
),
sa_tmp_x5_x6
=
const
offset_of!
(
SigArea
,
tmp_x5_x6
),
sa_tmp_sp
=
const
offset_of!
(
SigArea
,
tmp_sp
),
sa_tmp_sp
=
const
offset_of!
(
SigArea
,
tmp_sp
),
sa_tmp_inf
=
const
offset_of!
(
SigArea
,
tmp_inf
),
sa_tmp_rt_inf
=
const
offset_of!
(
SigArea
,
tmp_rt_inf
),
sa_tmp_id_inf
=
const
offset_of!
(
SigArea
,
tmp_id_inf
),
sa_pctl
=
const
offset_of!
(
SigArea
,
pctl
),
sa_pctl
=
const
offset_of!
(
SigArea
,
pctl
),
sc_saved_pc
=
const
offset_of!
(
Sigcontrol
,
saved_ip
),
sc_saved_pc
=
const
offset_of!
(
Sigcontrol
,
saved_ip
),
sc_saved_x0
=
const
offset_of!
(
Sigcontrol
,
saved_archdep_reg
),
sc_saved_x0
=
const
offset_of!
(
Sigcontrol
,
saved_archdep_reg
),
sc_sender_infos
=
const
offset_of!
(
Sigcontrol
,
sender_infos
),
sc_word
=
const
offset_of!
(
Sigcontrol
,
word
),
sc_word
=
const
offset_of!
(
Sigcontrol
,
word
),
inner
=
sym
inner_c
,
inner
=
sym
inner_c
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment