You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Fix ldp and stp encoding in the arm64 assembler ##arch - #27132
stp and ldp went through encode2regs , which puts the second register in the Rn field , and the base register was never encoded , so every pair load and store came out as a different instruction . pre and post index and the 32-bit forms were not handled at all :
input
before
after
ldp x0, x1, [sp, 16]
200041a9 = ldp x0, x0, [x1, 16]
e00741a9
stp x29, x30, [sp, -32]!
dd02fea9 = ldp x29, x0, [x22, -32]!
fd7bbea9
ldp x29, x30, [sp], 32
dd0342a9 = ldp x29, x0, [x30, 32]
fd7bc2a8
stp w0, w1, [x2, 16]
200001a9 = stp x0, x0, [x1, 16]
40040229
( decoded with llvm-mc )
so wa stp x29, x30, [sp, -0x20]! , the usual function prologue , wrote an ldp . stp now builds the word like adrp does and swaps it at the end : signed offset , [rn, imm]! and [rn], imm , x and w pairs with the offset scaled by 8 or 4 and checked against the 7-bit range , and ldp with the same register twice is still refused . a second commit adds s , d and q register pairs , which the parser did not know about , stp d8, d9, [sp, -0x10]! gave ldp xzr, xzr, [sp, -8]! before .
found by assembling the same text with rasm2 -a arm.nz and llvm-mc and decoding both . all 68 ldp / stp forms in that list now give the same bytes as llvm , none did before , and the ones llvm refuses ( ldp w0, w1, [sp, 504] ) are refused here too . the 14 new ad lines in db/asm/arm_64 fail before the change and round trip through the disassembler after . db/asm , db/tools/rasm2 , db/cmd/cmd_pa and db/cmd/write have no failures .
Did you test this for loading SIMD registers (i.e. (B|H|S|D|Q))? I think this would break them as it stands, since they're FPU registers instead of GPRs.
good catch , I had only tested the general purpose pairs . on master they were already wrong though : stp d8, d9, [sp, -0x10]! gave ffffffa9 , which is ldp xzr, xzr, [sp, -8]! , stp s0, s1, [x0, 8] gave stp x0, x0, [x0, 8] , and the ldp ones were refused , because the parser had no s , d or q registers at all and stp ignored the operand types . with the first commit they were refused instead .
ab0c734 adds them : the parser now reads s0-s31 , d0-d31 and q0-q31 as FP registers with their size , and stp / ldp use the SIMD&FP opcodes with the offset scaled by 4 , 8 or 16 . b and h have no pair load or store , so those are still refused , as are mixed pairs like stp d0, s1, [x0] .
checked against llvm-mc , all match : stp d8, d9, [sp, -16]!e827bf6d , ldp d8, d9, [sp], 16e827c16c , stp s0, s1, [x0, 8]0004012d , ldp q0, q1, [x0, 32]000441ad , stp q2, q3, [sp, -64]!e20fbead , ldp s30, s31, [x29, -256]be7f602d , stp q0, q1, [sp, 1008]e0871fad . five of them are new ad lines in db/asm/arm_64 , which is 688 OK , and every other instruction in my 3915 line arm64 list assembles to the same bytes as before this commit .
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
stpandldpwent throughencode2regs, which puts the second register in theRnfield , and the base register was never encoded , so every pair load and store came out as a different instruction . pre and post index and the 32-bit forms were not handled at all :ldp x0, x1, [sp, 16]200041a9=ldp x0, x0, [x1, 16]e00741a9stp x29, x30, [sp, -32]!dd02fea9=ldp x29, x0, [x22, -32]!fd7bbea9ldp x29, x30, [sp], 32dd0342a9=ldp x29, x0, [x30, 32]fd7bc2a8stp w0, w1, [x2, 16]200001a9=stp x0, x0, [x1, 16]40040229( decoded with llvm-mc )
so
wa stp x29, x30, [sp, -0x20]!, the usual function prologue , wrote anldp.stpnow builds the word likeadrpdoes and swaps it at the end : signed offset ,[rn, imm]!and[rn], imm, x and w pairs with the offset scaled by 8 or 4 and checked against the 7-bit range , andldpwith the same register twice is still refused . a second commit addss,dandqregister pairs , which the parser did not know about ,stp d8, d9, [sp, -0x10]!gaveldp xzr, xzr, [sp, -8]!before .found by assembling the same text with
rasm2 -a arm.nzandllvm-mcand decoding both . all 68ldp/stpforms in that list now give the same bytes as llvm , none did before , and the ones llvm refuses (ldp w0, w1, [sp, 504]) are refused here too . the 14 newadlines indb/asm/arm_64fail before the change and round trip through the disassembler after .db/asm,db/tools/rasm2,db/cmd/cmd_paanddb/cmd/writehave no failures .