Page MenuHomeFreeBSD

arm64/disassem.c: add bitwise or (immediate) instructions
AcceptedPublic

Authored by koliagogsadze_gmail.com on Aug 2 2023, 10:04 PM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Apr 1, 1:14 PM
Unknown Object (File)
Mar 9 2024, 10:26 AM
Unknown Object (File)
Jan 19 2024, 12:21 PM
Unknown Object (File)
Dec 26 2023, 1:51 PM
Unknown Object (File)
Dec 20 2023, 3:03 AM
Unknown Object (File)
Dec 12 2023, 10:14 AM
Unknown Object (File)
Dec 12 2023, 9:40 AM
Unknown Object (File)
Dec 9 2023, 12:52 PM
Subscribers

Details

Reviewers
mhorne
andrew
manu
Summary

Add disassembly support for the following bitmask immediate
instructions: orr, mov, ands, tst, and, eor.

Test Plan
  1. 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.

  1. 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 55436
Build 52325: 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.
Armv8-R, see D1-48 (CLZ unchanged): https://developer.arm.com/documentation/ddi0568/a-c/?lang=en
Armv8-A, see C6.2.58 :https://developer.arm.com/documentation/ddi0487/ja/?lang=en

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".

  • arm64/disassem.c: use flsl and fix move_wide_preferred check

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)

[1] https://developer.arm.com/documentation/ddi0596/2020-12/Shared-Pseudocode/AArch64-Instrs?lang=en#impl-aarch64.MoveWidePreferred.4

723

Suggested shorter name

727

Suggested shorter name

1008

I hesitate at the strcmp, but I am not sure if there is any better way to do this.

1012–1016
  • 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)

ref:
https://developer.arm.com/documentation/ddi0596/2020-12/Base-Instructions/BFM--Bitfield-Move-?lang=en

633–636

Removed helper function and simplified.

immN:imms is combination of values, for example:
immN is 1 bit value
imms is 6 bits value

So, if we have immN = 0b1 and imms = 0b001010, result will be:

immN:imms = 0b1001010

mhorne added inline comments.
sys/arm64/arm64/disassem.c
1002–1006

Don't really need decoded. I should have noticed the first time :)

This revision is now accepted and ready to land.Feb 2 2024, 7:00 PM