SYSTEM.ALIGN
Posted: Mon Nov 27, 2023 1:49 pm
I am having troubles using SYSTEM.ALIGN. My use case was this. Traps.mod contains several distinct exceptions handlers for the different MCU faults, such as Hard Fault, and some more for the M3, which are identical, mutatis mutandis the hard-coded fault number. Below is an attempt to use the same fault handler for all, which simply reads the ISPR to get the current exception number.
To access the ISPR, I use SYSTEM.EMIT to insert a 32 bit MRS instruction. Whether I actually need to align this code to a word boundary is another question (see below, and [2]), but for the discussion's sake here let's say I do. As the above code shows, I tried to use SYSTEM.ALIGN for this.
From the Astrobe docs:
... with line 13 being the SYSTEM.ALIGN instruction.
This code using SYSTEM.ALIGN() ...
... results in this compilation error:
Clearly I miss something about SYSTEM.ALIGN. How do I use it correctly?
Alignment required?
Regarding code alignment, the ARMv6-M Architecture Reference Manual says:
PS: replacing the different fault handlers by the "unified" one actually works nicely. :)
[1] reported and confirmed, will be fixed
[2] actually no need for alignment in this case
Code: Select all
MODULE TestAlign;
IMPORT SYSTEM;
CONST MRS_R8_IPSR = 0F3EF8801H; (* assembly instruction to store IPSR in register r8 *)
PROCEDURE IdentifyTrap(trapNo: INTEGER);
END IdentifyTrap;
PROCEDURE FaultTrap;
BEGIN
(* ... *)
SYSTEM.ALIGN;
SYSTEM.EMIT(MRS_R8_IPSR);
IdentifyTrap(SYSTEM.REG(8) + 0); (* '+0': work around compiler issue[1] *)
(* ... *)
WHILE TRUE DO END
END FaultTrap;
END TestAlign.
From the Astrobe docs:
On compilation, I get...ALIGN inserts a NOP instruction if necessary at the current code location to ensure that the next instruction is aligned on a word boundary.
Code: Select all
13 18 Error: not a procedure
This code using SYSTEM.ALIGN() ...
Code: Select all
MODULE TestAlign;
IMPORT SYSTEM;
CONST MRS_R8_IPSR = 0F3EF8801H; (* assembly instruction to store IPSR in register r8 *)
PROCEDURE IdentifyTrap(trapNo: INTEGER);
END IdentifyTrap;
PROCEDURE FaultTrap;
BEGIN
(* ... *)
SYSTEM.ALIGN();
SYSTEM.EMIT(MRS_R8_IPSR);
IdentifyTrap(SYSTEM.REG(8) + 0);
(* ... *)
WHILE TRUE DO END
END FaultTrap;
END TestAlign.
Code: Select all
13 19 Error: expression expected
14 11 Error: no )
Alignment required?
Regarding code alignment, the ARMv6-M Architecture Reference Manual says:
From the ARMv7-M Architecture Reference Manual:Instruction alignment and byte ordering
ARMv6-M enforces 16-bit alignment on all instructions. This means that 32-bit instructions are treated as two halfwords, hw1 and hw2 , with hw1 at the lower address.
When do I need to enforce word boundary alignment against this background, ie. when do I need to use SYSTEM.ALIGN? The compiler does not word-align the 32 bit bl.w instruction, but appears to do so for pop.Instruction alignment and byte ordering
Thumb instruction execution enforces 16-bit alignment on all instructions. This means that 32-bit instructions are treated as two halfwords, hw1 and hw2, with hw1 at the lower address
PS: replacing the different fault handlers by the "unified" one actually works nicely. :)
[1] reported and confirmed, will be fixed
[2] actually no need for alignment in this case