I regret to inform you that the previous email was automatically rejected
by the Gem5 system due to a technical issue (Gem5 account issue). I resend
the email to ensure its successful delivery.
Hi Experts,
I hope this email finds you well. I am Y.F., an engineer from Google.
I'm reaching out because I recently encountered an issue with the exception
handling mechanism in the GEM5 ARM MINOR CPU model, specifically when
executing programs with Thumb instructions. Here's what I found:
Exception Return Address Handling:
In src/arch/arm/faults.cc, the next program counter (PC) after an exception
is retrieved from the linker register and then incremented by 4 bytes
(using thumbPcOffset(false)). However, I believe this might be incorrect.
Thumb instructions can be either 2 or 4 bytes long, so simply adding 4
might not always point to the correct next instruction. Additionally,
cur_pc already
holds the PC value of the next instruction, so I'm unsure why it needs to
be incremented again.
[image: image.png]
Instruction Decoding (IWNPC function):
In src/arch/arm/pcstate.hh, the instIWNPC function determines whether an
instruction is Arm or Thumb based on the least significant bit (bit-0) of
the instruction address. Since Thumb instructions can be 2 bytes long, this
approach might not be accurate. Shouldn't the checking bit be bit-1 instead
of bit-0?
[image: image.png]
Workaround and Questions:
As a temporary solution, I've been adding 1 to cur_pc when the program is
compiled with Thumb instructions, and this seems to work. However, I'd like
to understand this issue better:
[image: image.png]
I appreciate your insights and any information you can provide on this
matter.
Thanks,
Y.F.
Hi YF,
On 30/10/2024 08:49, YF Yeh wrote:
Exception Return Address Handling:
In src/arch/arm/faults.cc, the next program counter (PC) after an exception is retrieved from the linker register and then incremented by 4 bytes (using thumbPcOffset(false)). However, I believe this might be incorrect. Thumb instructions can be either 2 or 4 bytes long, so simply adding 4 might not always point to the correct next instruction. Additionally, cur_pc already holds the PC value of the next instruction, so I'm unsure why it needs to be incremented again.
[image.png]
Just to clarify, the logic you posted is not retrieving the next PC from link register (with the increment). It is actually the other way around: it is calculating the link register value from the current PC (when the exception happen) + an offset which is exception type dependent.
So it is not true that it always gets incremented by 4 bytes. The amount of increment depends on the exception type and you can check it in faults.cc 1 (in the line for UndefinedInstruction, the offset is 4 in Arm mode, and 2 in Thumb mode)
Instruction Decoding (IWNPC function):
In src/arch/arm/pcstate.hh, the instIWNPC function determines whether an instruction is Arm or Thumb based on the least significant bit (bit-0) of the instruction address. Since Thumb instructions can be 2 bytes long, this approach might not be accurate. Shouldn't the checking bit be bit-1 instead of bit-0?
[image.png]
There reason why the bit-0 is checked (and not bit-1) is because of how arm-thumb branch and exchange (BX) works.
Basically a BX instruction will check the LSB and it will switch CPU mode to T32 if it is set, to A32 otherwise. It has to be noted that the
BX address won't be the future PC: regardless of the next mode, the LSB will always be cleared to zero.
Workaround and Questions:
As a temporary solution, I've been adding 1 to cur_pc when the program is compiled with Thumb instructions, and this seems to work. However, I'd like to understand this issue better:
[image.png]
I appreciate your insights and any information you can provide on this matter.
I presume the reason why you are posting this is because you found a bug while executing some thumb code. I think the first step would be to understand (via gdb or dprintf) which is the exception being triggered.
But just so you know the logic you posted has nothing to do with the MinorCPU; it is actually shared by all CPU models in gem5. So if the error happens in MinorCPU only, it might be the issue is microrchitectural and not directly related to the architecture per se
Hope this helps! Let me know if this answers your questions
Giacomo
Thanks,
Y.F.
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.