when swi instruction is executed at that time it is said that pc is not updated yet so it is pointing to instruction next to swi instruction for example
addr code
0x0000 swi 1000x0004 mov r1,r20x0008 mov r2,r3
so in this code when swi instruction is being executed at that time value of PC is 0x0004 so that value will be copied to R14_SVC while going to swi handler.means value in PC in not address of instruction being executed +8 but +4 as can be seen.
but when following code is run i.e
0x0000 mov R1,R150x0004 mov r2,r10x0008 mov r4,r5
so when first instruction is being executed means value of R15 goes to R1 that is 0x0008 so how pc is updated in this case means pc pointing to instruction being executed + 8 instead of +4.
why so?
SWI corrects the PC, whereas "mov" doesn't. For the "why" you might have to ask Sophie Wilson :-)
in documents of arm ,it is written that while instruction is being executed PC will not be updated but PC will be updated once execution of current instruction is completed and that is true in case of swi,fiq,irq,data abort,prefetch abort but mov is being executed and still i am getting updated value of PC ,why?
and its not that swi corrects PC,it just take value of PC what ever PC containing at particular time?
take for example "bl" it loads the LR with the PC of the _next_ instruction.Somov lr,pcb label
equals
bl label
When you read the PC (R15) by way of a "MOV" instruction, you're right the program counter is 8 bytes ahead of the current instruction. That's simply an artefact from early Arm implementations with a 3-stage pipeline (Fetch, Decode, Execute). At each Fetch, the PC is incremented by 4 bytes. So, by the time you execute, you've passed +0 (the one you're executing), +4 (the one currently in Decode) and +8 (the one currently in Fetch).
When you take an exception, as the 'SVC' instruction causes, R14_mode is updated with the preferred return address plus an offset, which is the implementation adjusting the address based on that legacy 3-stage pipeline - for SVC it subtracts 4 from the PC+8 value you'd normally see as a result of moving the PC into another GPR.
Table G1-10 in the Arm v8 Architecture Reference Manual (issue B.a, which is the current at the time of writing) shows the offsets and the obvious implication that if you design an architecture around a very specific implementation behavior, just to save a few gates, that you'll be stuck with it for 25 years or more.. every 32-bit Arm processor and every 64-bit Arm processor executing in 32-bit state absolutely must maintain the illusion, even though it has many more stages, out of order and 4 or 5 issue per cycle behavior, or older software built around that illusion will just not work.
Ta,
Matt
so when use mov it give +8 offset and why when use swi it gives +4 offset and resone told in manual is that while swi is being executed pc is not updated to +8 so how can pc get updated in case of mov and not in case of swi?
you are saying that it subtracts 4 from +8 in case of svc instruction but in manual it is said that pc is not updated to +8 while svc(swi) is being executed so can you explain me that?
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.