3 ms·
On removal in ARM64: Do LDP and STP load and store fixed pair of registers? e.g. (r0, r1), (r2, r3) ..
by nly 6y ago
On removal in ARM64: Do LDP and STP load and store fixed pair of registers? e.g. (r0, r1), (r2, r3) ..
- progval 6y agoAccording to https://developer.arm.com/architectures/learn-the-architecture/aarch64-instruction-set-architecture/loads-and-stores-load-pair-and-store-pair https://developer.arm.com/architectures/learn-the-architectu... , it looks like it can be any two registers
- nly 6y agoSeems like a step backward. If the constraint was the number of bits in the mask then each bit could have represented a register pair.
- roca 6y agoLimiting the registers to be specific pairs is awful if you're implementing a register allocator.
- pjc50 6y agoIs it? These are stack management instructions; you know in advance from the platform ABI which registers are "scratch" and which are "save", so if you allocate any of the "save" registers in your function you emit the corresponding push/pop pairs in the start and end of the function. At worst you push/pop a register you don't need to - but in ARM64, the stack has to be 128-bit aligned, so you have to push/pop pairs.
- pm215 6y agoThen your allocator would need to know that if it's already decided to use one register of a pair that the other half of the pair gets the save/restore for 'free' and is now better than using a different callee-saves register. I suspect that unless your allocator was designed from the start to be able to deal with that kind of "my choice of register here affects costs and thus my decisions about allocation for a completely different value over there" it's not going to be able to do a great job under that kind of constraint.
- brandmeyer 6y agoCallee-saved registers are saved on function entry, all at once. There is no interaction other than the register allocation step choosing how many values need to be preserved across function calls.
- roca 6y agoOK, but that only works for prologue/epilogue --- it's better if you can use the instructions elsewhere too.
- Tuna-Fish 6y agoThe constraint absolutely was not that, it was that they don't want to have an instruction that can load more than two cache lines worth of data, or that can write to more than two registers.
- deleted 6y ago[deleted]
- monocasa 6y agoLDM/STM are awful for modern cores, and was even microcoded on at least early ARM cores despite them being, you know, RISC. As for why it's awful, it's the amount of loads and stores that can be in flight associated with a single instruction when an exception is taken, and how the instruction is restarted afterwards. ARM-M cores make this a little better by exposing "I've executed this many loads so far in the LDM" in architectural state so it can be restarted without going back and reissuing loads (so it can be used in MMIO ranges), but the instruction really only shines in simple, in order designs. They're almost as bad to implement on modern cores as the load indirect instructions you see on some older CISC chips. Additionally, LDM/STM really shined in either cache-less or cache-poor designs where instruction fetch is competing for memory bandwidth with the transfer itself. That doesn't really apply to these modern cores with fairly harvard looking memory access patterns. Therefore, getting rid of these instructions isn't the biggest deal in the world. So to answer your question, they absolutely could have done that, but chose to use the transition to AArch64 to remove pariahs like LDM/STM from around their neck because they're more trouble than they're worth from a hardware perspective on modern OoO cores. The LDP/STP instructions are the bone they throw you to improve instruction density versus memory bandwidth to/from the registers, but they don't really want each instruction being responsible for more than a single memory transfer for core internal bookkeeping reasons.
- duskwuff 6y agoLDM/STM were also the source of some really wacky hardware bugs on some STM32 microcontrollers, such as: > If an interrupt occurs during an CPU AHB burst read access to an end of SDRAM row, it may result in wrong data read from the next row if all the conditions below are met: > • The SDRAM data bus is 16-bit or 8-bit wide. 32-bit SDRAM mode is not affected. > • RBURST bit is reset in the FMC_SDCR1 register (read FIFO disabled). > • An interrupt occurs while CPU is performing an AHB incrementing bursts read access of unspecified length (using LDM = Load Multiple instruction). > • The address of the burst operation includes the end of an SDRAM row. (https://www.st.com/resource/en/errata_sheet/dm00068628-stm32f427437-and-stm32f429439-line-limitations-stmicroelectronics.pdf https://www.st.com/resource/en/errata_sheet/dm00068628-stm32..., section 2.3.5) Admittedly, this was a silicon bug in ST's memory controller. But it was a bug which was only triggered by LDM/STM instructions!