Skip to content

Commit a3c01a7

Browse files
committed
Harmonise exception handlers
* Move .section down to under the function comment * Ensure all routines are assembled as Arm, not Thumb * Save an instruction by doing the AND directly on the SP register
1 parent cbbd032 commit a3c01a7

File tree

8 files changed

+20
-31
lines changed

8 files changed

+20
-31
lines changed

aarch32-rt/src/arch_v4/abort.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ core::arch::global_asm!(
55
// Work around https://github.com/rust-lang/rust/issues/127269
66
.fpu vfp2
77
8-
98
// Called from the vector table when we have an undefined exception.
109
// Saves state and calls a C-compatible handler like
1110
// `extern "C" fn _data_abort_handler(addr: usize);`
@@ -18,8 +17,7 @@ core::arch::global_asm!(
1817
push {{ r12 }} // Save preserved register R12 - can now use it
1918
mrs r12, spsr // grab SPSR
2019
push {{ r12 }} // save SPSR value
21-
mov r12, sp // align SP down to eight byte boundary using R12
22-
and r12, r12, 7 //
20+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2321
sub sp, r12 // SP now aligned - only push 64-bit values from here
2422
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
2523
"#,
@@ -46,7 +44,6 @@ core::arch::global_asm!(
4644
// Work around https://github.com/rust-lang/rust/issues/127269
4745
.fpu vfp2
4846
49-
5047
// Called from the vector table when we have a prefetch abort.
5148
// Saves state and calls a C-compatible handler like
5249
// `extern "C" fn _prefetch_abort_handler(addr: usize);`
@@ -59,8 +56,7 @@ core::arch::global_asm!(
5956
push {{ r12 }} // Save preserved register R12 - can now use it
6057
mrs r12, spsr // grab SPSR
6158
push {{ r12 }} // save SPSR value
62-
mov r12, sp // align SP down to eight byte boundary using R12
63-
and r12, r12, 7 //
59+
and r12, sp, 7 // align SP down to eight byte boundary using R12
6460
sub sp, r12 // SP now aligned - only push 64-bit values from here
6561
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
6662
"#,

aarch32-rt/src/arch_v4/interrupt.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ core::arch::global_asm!(
2525
push {{ lr }} // save it to IRQ stack using LR
2626
msr cpsr_c, {sys_mode} // switch to system mode so we can handle another interrupt (because if we interrupt irq mode we trash our own shadow registers)
2727
push {{ lr }} // Save LR of system mode before using it for stack alignment
28-
mov lr, sp // align SP down to eight byte boundary using LR
29-
and lr, lr, 7 //
28+
and lr, sp, 7 // align SP down to eight byte boundary using LR
3029
sub sp, lr // SP now aligned - only push 64-bit values from here
3130
push {{ r0-r3, r12, lr }} // push alignment amount (in LR) and preserved registers
3231
"#,

aarch32-rt/src/arch_v4/svc.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ core::arch::global_asm!(
66
// Work around https://github.com/rust-lang/rust/issues/127269
77
.fpu vfp2
88
9-
109
// Called from the vector table when we have an software interrupt.
1110
// Saves state and calls a C-compatible handler like
1211
// `extern "C" fn _svc_handler(arg: u32, frame: &Frame) -> u32;`
@@ -18,8 +17,7 @@ core::arch::global_asm!(
1817
push {{ r12, lr }} // save LR and R12 - can now use R12 (but leave LR alone for SVC code lookup)
1918
mrs r12, spsr // grab SPSR using R12
2019
push {{ r12 }} // save SPSR value
21-
mov r12, sp // align SP down to eight byte boundary using R12
22-
and r12, r12, 7 //
20+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2321
sub sp, r12 // SP now aligned - only push 64-bit values from here
2422
push {{ r0-r6, r12 }} // push alignment amount, and stacked SVC argument registers (must be even number of regs for alignment)
2523
mov r12, sp // save SP for integer frame

aarch32-rt/src/arch_v4/undefined.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ core::arch::global_asm!(
55
r#"
66
// Work around https://github.com/rust-lang/rust/issues/127269
77
.fpu vfp2
8-
8+
99
// Called from the vector table when we have an undefined exception.
1010
// Saves state and calls a C-compatible handler like
1111
// `extern "C" fn _undefined_handler(addr: usize) -> usize;`
@@ -23,8 +23,7 @@ core::arch::global_asm!(
2323
ite eq // Adjust LR to point to faulting instruction - see p.1206 of the ARMv7-A architecture manual.
2424
subeq lr, lr, #4 // Subtract 4 in Arm Mode
2525
subne lr, lr, #2 // Subtract 2 in Thumb Mode
26-
mov r12, sp // align SP down to eight byte boundary using R12
27-
and r12, r12, 7 //
26+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2827
sub sp, r12 // SP now aligned - only push 64-bit values from here
2928
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
3029
"#,

aarch32-rt/src/arch_v7/abort.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ core::arch::global_asm!(
55
// Work around https://github.com/rust-lang/rust/issues/127269
66
.fpu vfp3
77
8-
.section .text._asm_default_data_abort_handler
98
109
// Called from the vector table when we have an undefined exception.
1110
// Saves state and calls a C-compatible handler like
1211
// `extern "C" fn _data_abort_handler(addr: usize);`
12+
.section .text._asm_default_data_abort_handler
13+
.arm
1314
.global _asm_default_data_abort_handler
1415
.type _asm_default_data_abort_handler, %function
1516
_asm_default_data_abort_handler:
1617
sub lr, lr, #8 // Subtract 8 from LR, see p.1214 of the ARMv7-A architecture manual.
1718
srsfd sp!, #{abt_mode} // store return state to ABT stack
1819
push {{ r12 }} // Save preserved register R12 - can now use it
19-
mov r12, sp // align SP down to eight byte boundary using R12
20-
and r12, r12, 7 //
20+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2121
sub sp, r12 // SP now aligned - only push 64-bit values from here
2222
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
2323
"#,
@@ -43,20 +43,19 @@ core::arch::global_asm!(
4343
r#"
4444
// Work around https://github.com/rust-lang/rust/issues/127269
4545
.fpu vfp3
46-
.section .text._asm_default_prefetch_abort_handler
47-
46+
4847
// Called from the vector table when we have a prefetch abort.
4948
// Saves state and calls a C-compatible handler like
5049
// `extern "C" fn _prefetch_abort_handler(addr: usize);`
51-
.global _asm_default_prefetch_abort_handler
50+
.section .text._asm_default_prefetch_abort_handler
5251
.arm
52+
.global _asm_default_prefetch_abort_handler
5353
.type _asm_default_prefetch_abort_handler, %function
5454
_asm_default_prefetch_abort_handler:
5555
sub lr, lr, #4 // Subtract 8 from LR, see p.1212 of the ARMv7-A architecture manual.
5656
srsfd sp!, #{abt_mode} // store return state to ABT stack
5757
push {{ r12 }} // save R12 - can now use it
58-
mov r12, sp // align SP down to eight byte boundary using R12
59-
and r12, r12, 7 //
58+
and r12, sp, 7 // align SP down to eight byte boundary using R12
6059
sub sp, r12 // SP now aligned - only push 64-bit values from here
6160
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
6261
"#,

aarch32-rt/src/arch_v7/interrupt.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,22 @@ core::arch::global_asm!(
66
// Work around https://github.com/rust-lang/rust/issues/127269
77
.fpu vfp3
88
9-
.section .text._asm_default_irq_handler
10-
119
// Called from the vector table when we have an interrupt.
1210
// Saves state and calls a C-compatible handler like
1311
// `extern "C" fn _irq_handler();`
1412
//
1513
// See https://developer.arm.com/documentation/dui0203/j/handling-processor-exceptions/armv6-and-earlier--armv7-a-and-armv7-r-profiles/interrupt-handlers
1614
// for details on how we need to save LR_irq, SPSR_irq and LR_sys.
15+
.section .text._asm_default_irq_handler
16+
.arm
1717
.global _asm_default_irq_handler
1818
.type _asm_default_irq_handler, %function
1919
_asm_default_irq_handler:
2020
sub lr, lr, 4 // make sure we jump back to the right place
2121
srsfd sp!, #{sys_mode} // store return state to SYS stack
2222
cps #{sys_mode} // switch to system mode so we can handle another interrupt (because if we interrupt irq mode we trash our own shadow registers)
2323
push {{ lr }} // save adjusted LR to SYS stack
24-
mov lr, sp // align SP down to eight byte boundary using LR
25-
and lr, lr, 7 //
24+
and lr, sp, 7 // align SP down to eight byte boundary using LR
2625
sub sp, lr // SP now aligned - only push 64-bit values from here
2726
push {{ r0-r3, r12, lr }} // push alignment amount (in LR) and preserved registers
2827
"#,

aarch32-rt/src/arch_v7/svc.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ core::arch::global_asm!(
55
r#"
66
// Work around https://github.com/rust-lang/rust/issues/127269
77
.fpu vfp3
8-
8+
99
// Called from the vector table when we have an software interrupt.
1010
// Saves state and calls a C-compatible handler like
1111
// `extern "C" fn _svc_handler(arg: u32, frame: &Frame) -> u32;`
@@ -16,8 +16,7 @@ core::arch::global_asm!(
1616
_asm_default_svc_handler:
1717
srsfd sp!, #{svc_mode} // store return state to SVC stack
1818
push {{ r12, lr }} // save LR and R12 - can now use R12 (but leave LR alone for SVC code lookup)
19-
mov r12, sp // align SP down to eight byte boundary using R12
20-
and r12, r12, 7 //
19+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2120
sub sp, r12 // SP now aligned - only push 64-bit values from here
2221
push {{ r0-r6, r12 }} // push alignment amount, and stacked SVC argument registers (must be even number of regs for alignment)
2322
mov r12, sp // save SP for integer frame

aarch32-rt/src/arch_v7/undefined.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ core::arch::global_asm!(
1212
// or
1313
// `extern "C" fn _undefined_handler(addr: usize) -> !;`
1414
.section .text._asm_default_undefined_handler
15+
.arm
1516
.global _asm_default_undefined_handler
1617
.type _asm_default_undefined_handler, %function
1718
_asm_default_undefined_handler:
@@ -22,8 +23,7 @@ core::arch::global_asm!(
2223
ite eq // Adjust LR to point to faulting instruction - see p.1206 of the ARMv7-A architecture manual.
2324
subeq lr, lr, #4 // Subtract 4 in Arm Mode
2425
subne lr, lr, #2 // Subtract 2 in Thumb Mode
25-
mov r12, sp // align SP down to eight byte boundary using R12
26-
and r12, r12, 7 //
26+
and r12, sp, 7 // align SP down to eight byte boundary using R12
2727
sub sp, r12 // SP now aligned - only push 64-bit values from here
2828
push {{ r0-r4, r12 }} // push alignment amount, and preserved registers - can now use R0-R3 (R4 is just padding)
2929
"#,

0 commit comments

Comments
 (0)