-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[AVR] No cli for SPWRITE on XMEGA #147210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
✅ With the latest revision this PR passed the C/C++ code formatter. |
.addImm(0x3d) | ||
.addReg(SrcLoReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
// From the XMEGA series manual: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please give a link to this manual ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-8331-8-and-16-bit-AVR-Microcontroller-XMEGA-AU_Manual.pdf page 17 SPL description.
It is in every chip full manual in the section describing SPL
.addReg(SrcHiReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
|
||
buildMI(MBB, MBBI, AVR::OUTARr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why restore the interrupt state before writing to SPL ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is not my code. I wondered myself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, from SEI in the manual:
Sets the Global Interrupt Enable (I) bit in SREG (Status Register). The instruction following SEI will be executed
before any pending interrupts.
|
||
} else { // Disable interrupts for older devices (3 extra instructions) | ||
|
||
buildMI(MBB, MBBI, AVR::INRdA) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This two branches have common code, if would be better to be
if (not xmega)
disable interrupt.
common code;
if (not xmega)
restore interrupt.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The second branch is the unmodified original code. I can change it as suggested.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SPL and SPH order is also reversed, so I do not think this is possible, clear to read? EDIT: we could switch the order in the original code, that should not matter.
if (STI.getELFArch() >= 102) { // An XMEGA device | ||
|
||
buildMI(MBB, MBBI, AVR::OUTARr) | ||
.addImm(0x3d) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to use STI.getIORegSPL()
instead of fixed value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Original code, could change that
.addReg(SrcLoReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
|
||
buildMI(MBB, MBBI, AVR::OUTARr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to check if SPH is available here for devices with a small stack, for example
if (getIORegSPH() >= 0)
....
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Original code. EDIT: so the original code is broken for those devices and has always been that way?
// To prevent corruption when updating the stack pointer from software, | ||
// a write to SPL will automatically disable interrupts | ||
// for up to four instructions or until the next I/O memory write. | ||
if (STI.getELFArch() >= 102) { // An XMEGA device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it applicable to all upper devices? should xmega3 be excluded ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should apply to all
// To prevent corruption when updating the stack pointer from software, | ||
// a write to SPL will automatically disable interrupts | ||
// for up to four instructions or until the next I/O memory write. | ||
if (STI.getELFArch() >= 102) { // An XMEGA device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it applicable to all upper devices? should xmega3 be excluded ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Xmega3 is included, all new devices have this.
.addImm(0x3d) | ||
.addReg(SrcLoReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A unit test is needed for this change. Please see other tests for pseudo instructions at llvm/test/CodeGen/AVR/pseudo
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
None of those vary architecture?
.addImm(0x3d) | ||
.addReg(SrcLoReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not use git push -f
when updating a PR, I need to trace if all of my concerns are fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just use push
, more than one commits will be squashed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I never used push -f
in this PR, but did indeed in earlier ones.
.addImm(0x3d) | ||
.addReg(SrcLoReg, getKillRegState(SrcIsKill)) | ||
.setMIFlags(Flags); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just use push
, more than one commits will be squashed.
You are appreciated to give a link about how gcc handles this, would be better to gcc's source code lines. |
I prefer to not read GCC code in general, but regarding gcc output, compile any C fragment with many locals with gcc with eg -mmcu=attiny85 and -mmcu=attiny402 (an xmega cpu) and compare the prologue and epilogue of the different -S outputs.
loop.s:
versus with -mmcu=attiny402
Note that llvm allways generates the first variant. The same applies to the epilogue so the total difference is 6 extra instructions. |
From the XMEGA series manual:
To prevent corruption when updating the stack pointer from software,
a write to SPL will automatically disable interrupts
for up to four instructions or until the next I/O memory write.
This will save 6! instructions in every function with an FP on ALL Xmega devices and it
is compatible with gcc code generation for all those devices. It is also not very modern, because the first devices are from 2013. So this is really significant and it is a small change.
@benshi001 Note that I could not find any existing (SPWRITE) unit tests to which this variant could be added.