Add disassembly support for the following bitmask immediate
instructions: orr, mov, ands, tst, and, eor.
Details
- In this PR you can find my test scenarios of bitmask instructions with logical imm
https://github.com/toor1245/freebsd-src/pull/4/files, all possible <imm> for ORR to test
arm64_disasm_bitmask in ddb.
- Compared all expected immediate values with arm64_disasm_bitmask
https://github.com/toor1245/freebsd-arm64-disasm-bitmask
compare result: https://github.com/toor1245/freebsd-arm64-disasm-bitmask/blob/main/compare.txt
Diff Detail
- Repository
- rG FreeBSD src repository
- Lint
Lint Passed - Unit
No Test Coverage - Build Status
Buildable 59699 Build 56585: arc lint + arc unit
Event Timeline
refs to review:
ORR (immedaite) and aliases:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/ORR--immediate---Bitwise-OR--immediate--?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/MOV--bitmask-immediate---Move--bitmask-immediate---an-alias-of-ORR--immediate--?lang=en
ANDS (immediate) and aliases:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/ANDS--immediate---Bitwise-AND--immediate---setting-flags-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/TST--immediate---Test-bits--immediate---an-alias-of-ANDS--immediate--?lang=en
AND (immediate):
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/AND--immediate---Bitwise-AND--immediate--?lang=en
EOR (immedaite):
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/EOR--immediate---Bitwise-Exclusive-OR--immediate--?lang=en
Arm64 DecodeBitMasks:
https://developer.arm.com/documentation/ddi0596/2020-12/Shared-Pseudocode/AArch64-Instrs?lang=en#impl-aarch64.DecodeBitMasks.4
These are instructions with decoding of bitmask will be used as separate patches:
BFM and aliases:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BFM--Bitfield-Move-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BFC--Bitfield-Clear--an-alias-of-BFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BFI--Bitfield-Insert--an-alias-of-BFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BFXIL--Bitfield-extract-and-insert-at-low-end--an-alias-of-BFM-?lang=en
SBFM and aliases:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SBFM--Signed-Bitfield-Move-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/ASR--immediate---Arithmetic-Shift-Right--immediate---an-alias-of-SBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SBFIZ--Signed-Bitfield-Insert-in-Zero--an-alias-of-SBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SBFX--Signed-Bitfield-Extract--an-alias-of-SBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SXTB--Signed-Extend-Byte--an-alias-of-SBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SXTH--Sign-Extend-Halfword--an-alias-of-SBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/SXTW--Sign-Extend-Word--an-alias-of-SBFM-?lang=en
UBFM and aliases:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/UBFM--Unsigned-Bitfield-Move-
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/LSL--immediate---Logical-Shift-Left--immediate---an-alias-of-UBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/LSR--immediate---Logical-Shift-Right--immediate---an-alias-of-UBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/UBFIZ--Unsigned-Bitfield-Insert-in-Zero--an-alias-of-UBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/UBFX--Unsigned-Bitfield-Extract--an-alias-of-UBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/UXTB--Unsigned-Extend-Byte--an-alias-of-UBFM-?lang=en
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/UXTH--Unsigned-Extend-Halfword--an-alias-of-UBFM-?lang=en
Since it is not logical immediate instructions and there are basic patterns (SBFM, BFM, UBFM) that have OP <RD>, <RN>, #<immr>, #<imms> and aliases with evaluation like this:
BFC <Wd>, #<lsb>, #<width> is equivalent to BFM <Wd>, WZR, #(-<lsb> MOD 32), #(<width>-1)
sys/arm64/arm64/disassem.c | ||
---|---|---|
456–469 | Actually, Armv8-A and Armv8-R profiles (both 64 bit, Armv8-M only T32 ) support CLZ/CLS as A64 base instructions. ID_ISAR0_EL1, AArch32 Instruction Set Attribute Register 0 BitCount, bits [7:4] Indicates the implemented Bit Counting instructions. Defined values are: 0b0000 None implemented. 0b0001 Adds CLZ. All other values are reserved. In Armv8-A, the only permitted value is 0b0001. Armv8-M, see D1.2.129 https://developer.arm.com/documentation/ddi0553/latest/ // HaveMainExt() // ============= // Check whether the Main Extension is implemented. boolean HaveMainExt(); CLZ if !HaveMainExt() then UNDEFINED; if Rm != Rm2 then UNPREDICTABLE; d = UInt(Rd); m = UInt(Rm); m2 = UInt(Rm2); if d IN {13,15} || m IN {13,15} || m2 IN {13,15} then UNPREDICTABLE; C2.4.37 ID_ISAR0, Instruction Set Attribute Register 0 BitCount, bits [7:4] Bit count. Indicates the supported bit count instructions. The possible values of this field are: 0b0001 CLZ supported. All other values are reserved. This field reads as 0b0001. so it looks like it might be safe to use this instruction. Also, I see that in libkernel.h there is flsl, what do you think to use it instead of arm64_highest_set_bit? |
sys/arm64/arm64/disassem.c | ||
---|---|---|
456–469 | You should definitely use flsl(). It will be emitted as a CLZ instruction, if appropriate. Just beware that the function is 1-indexed, and a return value of zero means "not set". |
I looked through most of it, but there are a lot of small details here. So I am putting trust in the testing you have performed :)
I think with the addition of TYPE_05, it is probably time to thinking about splitting disasm() into sub-functions. Most likely one for each case statement. It doesn't need to happen before this change.
sys/arm64/arm64/disassem.c | ||
---|---|---|
566 | When will logical_imm be false? | |
633–636 | I want to find a simpler way to express this, and eliminate the helper function (it is only used once). I looked at the MoveWidePreferred pseudocode [1], what do you think of this? (I am unsure if this is the correct operation for immN:imms) | |
723 | Suggested shorter name | |
727 | Suggested shorter name | |
1006 | I hesitate at the strcmp, but I am not sure if there is any better way to do this. | |
1010–1014 |
- arm64/disassem.c: use flsl and fix move_wide_preferred check
- arm64/disassem.c: Remove arm64_is_bit_set helper function
- arm64/disassem.c: simplify variable names
sys/arm64/arm64/disassem.c | ||
---|---|---|
566 | In this patch I added definitions only for case when logical_imm is true and I did function according to pseudocode aarch64/instrs/integer/bitmasks/DecodeBitMasks https://developer.arm.com/documentation/ddi0596/2020-12/Shared-Pseudocode/AArch64-Instrs?lang=en For the next patches I plan to reuse this function and use logical_imm as false. There are basic patterns (SBFM, BFM, UBFM) that have OP <RD>, <RN>, #<immr>, #<imms> and aliases with evaluation like this: BFC <Wd>, #<lsb>, #<width> ... R = UInt(immr); (wmask, tmask) = DecodeBitMasks(N, imms, immr, FALSE); is equivalent to BFM <Wd>, WZR, #(-<lsb> MOD 32), #(<width>-1) | |
633–636 | Removed helper function and simplified. immN:imms is combination of values, for example: So, if we have immN = 0b1 and imms = 0b001010, result will be: immN:imms = 0b1001010 |
sys/arm64/arm64/disassem.c | ||
---|---|---|
1000–1004 | Don't really need decoded. I should have noticed the first time :) |
sys/arm64/arm64/disassem.c | ||
---|---|---|
1006 | I checked Arm architecture reference manual, there are decode group/instruction page, (see C4.1 A64 instruction set encoding, https://developer.arm.com/documentation/ddi0487/latest/) There is group - "Data Processing -- Immediate" (see C4.1.92 Data Processing -- Immediate) This patch adds support for Logical (immediate), see instruction page - C4.1.92.5 Logical (immediate). {F97924285} |
sys/arm64/arm64/disassem.c | ||
---|---|---|
1006 | It is definitely preferable to extract and check the extra field from the instruction. |