I read this on ARM community website but i got confused:
"Imagine your 3-stage pipeline like this:
PC - FETCH - PC+4 -> DEC - PC+4 -> EXECUTE ||
Exceptions are generated (pended) at the end of each stage and taken at the end of EXECUTE. So an error in FETCH will take the value PC and carry it through to the end of the pipeline so it can be taken when the current instruction finishes.
An error or exception-causing instruction in decode (SVC et al.) will sample PC and carry it to EXECUTE but FETCH has incremented it by +4. For SVC this is good because it then automatically points at the instruction after SVC. For UNDEF exceptions you need to subtract 4 if you want to re-execute that instruction.
an error in EXECUTE (say a failed load or store) already has the PC incremented by +4 again, so data aborts the value sampled is PC+8. Hence the need to subtract before exception return.
EXECUTE can also not fail and in this case any instruction that reads R15 will see PC+8 because it's already incremented by +4 at FETCH and +4 in DECODE before EXECUTE. Hence you always see the PC 8 bytes ahead of the current instruction as a result of MOV Rx, PC.
LR_SVC will reflect PC+4 at exception handler but the most common case is to return to the next instruction. Therefore to see the PC value of the SVC instruction itself YOU have to subtract 4. The exception is taken at EXECUTE even though we pended it in DECODE, so while executing it we can either do one of two things; use PC+4 carries with the pended exception or just use the PC at EXECUTE and the core will subtract 4. Or any other method - how you route execution data around the pipeline is a problem for pipeline designers.
It doesn't REALLY matter since Cortex-A modern pipelines don't look like that. It's all fake to maintain compatibility with software that MUST reflect old behavior. Which is, again, a problem for pipeline designers.
as a software developer wondering why the PC is the value it is or why the LR_SVC value is the value it is, you just need to read the documentation and do what it tells you to expect"
If the PC incrementation occurs at the end of both the fetch and decode stages, and exceptions are pending at the end of each stage, does this imply that for SVC, the sampled PC holds PC + 8? The logic seems to align with prefetch abort and data abort, where the PC is incremented by 4 in the case of a prefetch abort. Therefore, the sampled PC becomes PC + 4.
Now, for the handling of prefetch aborts, given that exceptions are generated at the end of each stage, the PC is incremented by 4. Consequently, the sampled PC is PC + 4. If the handler intends to re-execute the faulty instruction, it should go back to LR - 4, which makes sense. This applies similarly to data aborts.
However, consider an instruction being an SVC instruction progressing through the pipeline. It is fetched without a problem, and then the PC is incremented by 4. Upon decoding, an exception is generated, leading to another increment of PC by 4. This results in the sampled PC being PC + 8. Consequently, the processor puts PC + 8 into LR. To return to the next instruction following the SVC, one must subtract 4 from LR; Right?