3. Logic and Shift#

3.1. and#

Compute bitwise AND operation.

Semantics:

dst = src0 & src1

Examples:

.reg .32b %dst, %src0, %src1;

// and of 32-bit elements
and.32b  %dst, %src0, %src1;

3.2. asr#

Perform an arithmetic right shift.

Semantics:

.type == .16bx2#
shiftl = unsigned(src1[5:0])
shifth = unsigned(src1[21:16])
dst[31:16] = src0[31:16] >> shifth
dst[15:0]  = src0[15:0]  >> shiftl
default#
shift = unsigned(src1[5:0])
dst = src0 >> shift

Examples:

.reg .32b %dst, %src0, %src1;

// arithmetic right shift of 32-bit element
asr.32b  %dst, %src0, %src1;
.reg .v2.16b %dst_packed, %src0_packed;
// element-wise arithmetic right shift of 2x16-bit packed value
asr.16bx2  %dst_packed, %src0_packed, %src1;

3.3. bfi#

Replace bits in src0 with bits from src1.

Semantics:

offset  = src3[4:0]  // starting bit position
width   = umin(src2[5:0], bitwidth(.type))           // requested number of bits
width   = umin(width, bitwidth(.type) - offset)      // clamp: ignore bits beyond the MSB

// build a mask of `width` ones starting at `offset`, i.e. 1s in [offset, offset+width)
mask_w  = width < bitwidth(.type) ? (1u << width) - 1u : ~0u;  // `width` low bits set
mask    = mask_w << offset;                                    // shift to position
dst     = (src0 & ~mask) | ((src1 << offset) & mask);

Examples:

.reg .32b %dst, %src0, %src1, %width, %offset;

// extract %width bits from %src1 and insert them at %offset into %src0
bfi.32b  %dst, %src0, %src1, %width, %offset;

3.4. bfn#

Perform an arbitrary bitwise operation.

Semantics:

dst = bfn[.operation](src0, src1, src2)

Notes:

The .operation encoding is derived by replacing each source with a corresponding constant and evaluating the desired boolean expression:

  • src0 = 0xaa

  • src1 = 0xcc

  • src2 = 0xf0

For example:

  • src0 | ~src1 & src20xaa | ~0xcc & 0xf0 = 0xba

  • (src0 ^ src2) & (src1 ^ src2)(0xaa ^ 0xf0) & (0xcc ^ 0xf0) = 0x18

Bfn Operations#

.operation

Logic Function

0x00 (invalid)

0x01

~src0 & ~src1 & ~src2

0x02

src0 & ~src1 & ~src2

0x03

~src1 & ~src2

0x04

~src0 & src1 & ~src2

0x05

~src0 & ~src2

0x06

(src0 ^ src1) & ~src2

0x07

(~src0 | ~src1) & ~src2

0x08

src0 & src1 & ~src2

0x09

(src0 ^ ~src1) & ~src2

0x0a

src0 & ~src2

0x0b

(src0 | ~src1) & ~src2

0x0c

src1 & ~src2

0x0d

(~src0 | src1) & ~src2

0x0e

(src0 | src1) & ~src2

0x0f

~src2

0x10

~src0 & ~src1 & src2

0x11

~src0 & ~src1

0x12

(src0 ^ src2) & ~src1

0x13

(~src0 | ~src2) & ~src1

0x14

~src0 & (src1 ^ src2)

0x15

~src0 & (~src1 | ~src2)

0x16

src0 ^ (src0 & src1 | src1 ^ src2)

0x17

~src0 & ~src1 | (~src0 | ~src1) & ~src2

0x18

(src0 ^ src2) & (src1 ^ src2)

0x19

src0 ^ (src0 & src2 | ~src1)

0x1a

src0 ^ (src0 | ~src1) & src2

0x1b

src0 & ~src2 | ~src0 & ~src1

0x1c

(src0 & src2 | src1) ^ src2

0x1d

~src0 & ~src1 | src1 & ~src2

0x1e

(src0 | src1) ^ src2

0x1f

~src0 & ~src1 | ~src2

0x20

src0 & ~src1 & src2

0x21

(src0 ^ ~src2) & ~src1

0x22

src0 & ~src1

0x23

(src0 | ~src2) & ~src1

0x24

(src0 ^ src1) & (src1 ^ src2)

0x25

src0 ^ (src0 & src1 | ~src2)

0x26

src0 ^ (src0 | ~src2) & src1

0x27

src0 & ~src1 | ~src0 & ~src2

0x28

src0 & (src1 ^ src2)

0x29

src0 ^ (src0 | ~src1) & (src1 ^ ~src2)

0x2a

src0 & (~src1 | ~src2)

0x2b

src0 & ~src1 | (src0 | ~src1) & ~src2

0x2c

(~src0 & src2 | src1) ^ src2

0x2d

(~src0 | src1) ^ src2

0x2e

src0 & ~src1 | src1 & ~src2

0x2f

src0 & ~src1 | ~src2

0x30

~src1 & src2

0x31

(~src0 | src2) & ~src1

0x32

(src0 | src2) & ~src1

0x33

~src1

0x34

(src0 & src1 | src2) ^ src1

0x35

~src0 & ~src2 | ~src1 & src2

0x36

(src0 | src2) ^ src1

0x37

~src0 & ~src2 | ~src1

0x38

(~src0 & src1 | src2) ^ src1

0x39

(~src0 | src2) ^ src1

0x3a

src0 & ~src2 | ~src1 & src2

0x3b

src0 & ~src2 | ~src1

0x3c

src1 ^ src2

0x3d

~src0 & ~src1 | src1 ^ src2

0x3e

src0 & ~src1 | src1 ^ src2

0x3f

~src1 | ~src2

0x40

~src0 & src1 & src2

0x41

~src0 & (src1 ^ ~src2)

0x42

(src0 ^ src1) & (src1 ^ ~src2)

0x43

(src0 & src1 | ~src2) ^ src1

0x44

~src0 & src1

0x45

~src0 & (src1 | ~src2)

0x46

src0 ^ (src0 & src2 | src1)

0x47

~src0 & src1 | ~src1 & ~src2

0x48

(src0 ^ src2) & src1

0x49

src0 ^ (src0 & src2 | src1 ^ ~src2)

0x4a

src0 ^ (src0 | src1) & src2

0x4b

(src0 | ~src1) ^ src2

0x4c

(~src0 | ~src2) & src1

0x4d

~src0 & src1 | (~src0 | src1) & ~src2

0x4e

src0 & ~src2 | ~src0 & src1

0x4f

~src0 & src1 | ~src2

0x50

~src0 & src2

0x51

~src0 & (~src1 | src2)

0x52

src0 ^ (src0 & src1 | src2)

0x53

~src0 & src2 | ~src1 & ~src2

0x54

~src0 & (src1 | src2)

0x55

~src0

0x56

src0 ^ (src1 | src2)

0x57

~src0 | ~src1 & ~src2

0x58

src0 ^ (src0 & ~src1 | src2)

0x59

src0 ^ (~src1 | src2)

0x5a

src0 ^ src2

0x5b

src0 ^ src2 | ~src0 & ~src1

0x5c

~src0 & src2 | src1 & ~src2

0x5d

~src0 | src1 & ~src2

0x5e

src0 ^ src2 | src1 & ~src2

0x5f

~src0 | ~src2

0x60

(src0 ^ src1) & src2

0x61

src0 ^ (src0 & src1 | src1 ^ ~src2)

0x62

src0 ^ (src0 | src2) & src1

0x63

(src0 | ~src2) ^ src1

0x64

src0 ^ (src0 & ~src2 | src1)

0x65

src0 ^ (src1 | ~src2)

0x66

src0 ^ src1

0x67

src0 ^ src1 | ~src0 & ~src2

0x68

src0 ^ (src0 | src1) & (src1 ^ ~src2)

0x69

src0 ^ src1 ^ ~src2

0x6a

src0 ^ src1 & src2

0x6b

src0 ^ src1 & src2 | ~src1 & ~src2

0x6c

(~src0 | ~src2) ^ ~src1

0x6d

src0 ^ (src1 | ~src2) | src1 & ~src2

0x6e

src0 ^ src1 | src0 & ~src2

0x6f

src0 ^ src1 | ~src2

0x70

(~src0 | ~src1) & src2

0x71

~src0 & src2 | (~src0 | src2) & ~src1

0x72

src0 & ~src1 | ~src0 & src2

0x73

~src0 & src2 | ~src1

0x74

~src0 & src1 | ~src1 & src2

0x75

~src0 | ~src1 & src2

0x76

src0 ^ src1 | ~src0 & src2

0x77

~src0 | ~src1

0x78

(~src0 | ~src1) ^ ~src2

0x79

src0 ^ (~src1 | src2) | ~src1 & src2

0x7a

src0 ^ src2 | src0 & ~src1

0x7b

src0 ^ src2 | ~src1

0x7c

~src0 & src1 | src1 ^ src2

0x7d

~src0 | src1 ^ src2

0x7e

src0 ^ src1 | src1 ^ src2

0x7f

~src0 | ~src1 | ~src2

0x80

src0 & src1 & src2

0x81

(src0 ^ ~src1) & (src1 ^ ~src2)

0x82

src0 & (src1 ^ ~src2)

0x83

(~src0 & src1 | ~src2) ^ src1

0x84

(src0 ^ ~src2) & src1

0x85

src0 ^ (src0 & ~src1 | ~src2)

0x86

src0 ^ (src0 | src1) & (src1 ^ src2)

0x87

(~src0 | ~src1) ^ src2

0x88

src0 & src1

0x89

src0 ^ (src0 | ~src2) & ~src1

0x8a

src0 & (src1 | ~src2)

0x8b

src0 & src1 | ~src1 & ~src2

0x8c

(src0 | ~src2) & src1

0x8d

src0 & src1 | ~src0 & ~src2

0x8e

src0 & src1 | (src0 | src1) & ~src2

0x8f

src0 & src1 | ~src2

0x90

(src0 ^ ~src1) & src2

0x91

src0 ^ (src0 & ~src2 | ~src1)

0x92

src0 ^ (src0 | src2) & (src1 ^ src2)

0x93

(~src0 | ~src2) ^ src1

0x94

src0 ^ (src0 & ~src1 | src1 ^ src2)

0x95

src0 ^ (~src1 | ~src2)

0x96

src0 ^ src1 ^ src2

0x97

src0 ^ (~src1 | ~src2) | ~src1 & ~src2

0x98

src0 ^ (src0 | src2) & ~src1

0x99

src0 ^ ~src1

0x9a

src0 ^ ~src1 & src2

0x9b

src0 ^ ~src1 | src0 & ~src2

0x9c

(src0 | ~src2) ^ ~src1

0x9d

src0 ^ ~src1 | src1 & ~src2

0x9e

src0 ^ ~src1 & src2 | src1 & ~src2

0x9f

src0 ^ ~src1 | ~src2

0xa0

src0 & src2

0xa1

src0 ^ (src0 | ~src1) & ~src2

0xa2

src0 & (~src1 | src2)

0xa3

src0 & src2 | ~src1 & ~src2

0xa4

src0 ^ (src0 | src1) & ~src2

0xa5

src0 ^ ~src2

0xa6

src0 ^ src1 & ~src2

0xa7

src0 ^ ~src2 | src0 & ~src1

0xa8

src0 & (src1 | src2)

0xa9

src0 ^ ~src1 & ~src2

0xaa

src0

0xab

src0 | ~src1 & ~src2

0xac

src0 & src2 | src1 & ~src2

0xad

src0 ^ ~src2 | src0 & src1

0xae

src0 | src1 & ~src2

0xaf

src0 | ~src2

0xb0

(src0 | ~src1) & src2

0xb1

src0 & src2 | ~src0 & ~src1

0xb2

src0 & src2 | (src0 | src2) & ~src1

0xb3

src0 & src2 | ~src1

0xb4

(src0 | ~src1) ^ ~src2

0xb5

src0 ^ ~src2 | ~src0 & ~src1

0xb6

src0 ^ src1 & ~src2 | ~src1 & src2

0xb7

src0 ^ ~src2 | ~src1

0xb8

src0 & src1 | ~src1 & src2

0xb9

src0 ^ ~src1 | src0 & src2

0xba

src0 | ~src1 & src2

0xbb

src0 | ~src1

0xbc

src0 & src1 | src1 ^ src2

0xbd

src0 ^ ~src1 | src1 ^ src2

0xbe

src0 | src1 ^ src2

0xbf

src0 | ~src1 | ~src2

0xc0

src1 & src2

0xc1

(src0 & ~src1 | src2) ^ ~src1

0xc2

(~src0 & ~src1 | src2) ^ ~src1

0xc3

src1 ^ ~src2

0xc4

(~src0 | src2) & src1

0xc5

~src0 & ~src2 | src1 & src2

0xc6

(~src0 | src2) ^ ~src1

0xc7

~src0 & src1 | src1 ^ ~src2

0xc8

(src0 | src2) & src1

0xc9

(src0 | src2) ^ ~src1

0xca

src0 & ~src2 | src1 & src2

0xcb

src0 & src1 | src1 ^ ~src2

0xcc

src1

0xcd

~src0 & ~src2 | src1

0xce

src0 & ~src2 | src1

0xcf

src1 | ~src2

0xd0

(~src0 | src1) & src2

0xd1

~src0 & ~src1 | src1 & src2

0xd2

(~src0 | src1) ^ ~src2

0xd3

~src0 & src2 | src1 ^ ~src2

0xd4

~src0 & src1 | (~src0 | src1) & src2

0xd5

~src0 | src1 & src2

0xd6

src0 ^ (src1 | src2) | src1 & src2

0xd7

~src0 | src1 ^ ~src2

0xd8

src0 & src1 | ~src0 & src2

0xd9

src0 ^ ~src1 | src1 & src2

0xda

src0 ^ src2 | src0 & src1

0xdb

src0 ^ src2 | src1 ^ ~src2

0xdc

~src0 & src2 | src1

0xdd

~src0 | src1

0xde

src0 ^ src2 | src1

0xdf

~src0 | src1 | ~src2

0xe0

(src0 | src1) & src2

0xe1

(src0 | src1) ^ ~src2

0xe2

src0 & ~src1 | src1 & src2

0xe3

src0 & src2 | src1 ^ ~src2

0xe4

src0 & src2 | ~src0 & src1

0xe5

src0 ^ ~src2 | src1 & src2

0xe6

src0 ^ src1 | src0 & src2

0xe7

src0 ^ src1 | src1 ^ ~src2

0xe8

src0 & src1 | (src0 | src1) & src2

0xe9

src0 ^ ~src1 & ~src2 | src1 & src2

0xea

src0 | src1 & src2

0xeb

src0 | src1 ^ ~src2

0xec

src0 & src2 | src1

0xed

src0 ^ ~src2 | src1

0xee

src0 | src1

0xef

src0 | src1 | ~src2

0xf0

src2

0xf1

~src0 & ~src1 | src2

0xf2

src0 & ~src1 | src2

0xf3

~src1 | src2

0xf4

~src0 & src1 | src2

0xf5

~src0 | src2

0xf6

src0 ^ src1 | src2

0xf7

~src0 | ~src1 | src2

0xf8

src0 & src1 | src2

0xf9

src0 ^ ~src1 | src2

0xfa

src0 | src2

0xfb

src0 | ~src1 | src2

0xfc

src1 | src2

0xfd

~src0 | src1 | src2

0xfe

src0 | src1 | src2

0xff (invalid)

Examples:

.reg .32b %dst, %src0, %src1, %src2;

// calculate src0 | ~src1 & src2
bfn.0xba.32b  %dst, %src0, %src1, %src2;
// calculate src0 ^ ~src1 & ~src2 | src1 & src2
bfn.0xe9.32b  %dst, %src0, %src1, %src2;

3.5. bfrev#

Reverse bits in a source value.

Semantics:

width = bitwidth(.type)
for (i = 0; i < width; ++i) {
   dst[i] = src0[width - i - 1]
}

Examples:

.reg .32b %dst, %src0;

// reverse bits in a 32-bit element
bfrev.32b  %dst, %src0;

3.6. cbit#

Count the number of set bits.

Semantics:

dst = 0
for (i = 0; i < bitwidth(.type); ++i) {
  if (src0 & (1 << i))
    dst++
}

Examples:

.reg .32b %dst, %src0;

// count bits in a 32-bit element
cbit.32b  %dst, %src0;

3.7. fbh#

Find the first bit set from the MSB side.

Semantics:

if (src0 == 0) {
  dst = ~src0
} else {
  for (dst = 0; dst < bitwidth(.type); ++dst) {
    if (src0 & (1 << (bitwidth(.type) - 1 - dst)))
      break
  }
}

Examples:

.reg .32b %dst, %src0;

// find first bit set (MSB) in a 32-bit element
fbh.32b  %dst, %src0;

3.8. fbl#

Find the first bit set from the LSB side.

Semantics:

if (src0 == 0) {
  dst = ~src0
} else {
  for (dst = 0; dst < bitwidth(.type); ++dst) {
    if (src0 & (1 << dst))
      break
  }
}

Examples:

.reg .32b %dst, %src0;

// find first bit set (LSB) in a 32-bit element
fbl.32b  %dst, %src0;

3.9. not#

Compute bitwise NOT operation.

Semantics:

dst = ~src0

Examples:

.reg .32b %dst, %src0;

// not of 32-bit element
not.32b  %dst, %src0;

3.10. or#

Compute bitwise OR operation.

Semantics:

dst = src0 | src1

Examples:

.reg .32b %dst, %src0, %src1;

// or of 32-bit elements
or.32b  %dst, %src0, %src1;

3.11. sbfe#

Extract and sign-extend bits.

Semantics:

offset  = src2[4:0]  // starting bit position
width   = umin(src1[5:0], bitwidth(.type)) // number of bits to extract
lastpos = umin(offset + width, bitwidth(.type)) // ignore bits beyond the MSB
width   = lastpos - offset // effective width

if (width == 0) {
  dst = 0
} else {
  dst = signed(src0 << (bitwidth(.type) - lastpos)) >> (bitwidth(.type) - width)
}

Notes:

Any bits specified in (offset + width) beyond 32 bits are ignored.

Examples:

.reg .32b %dst, %src0, %width, %offset;

// extract %width bits from %src0 at %offset
sbfe.32b  %dst, %src0, %width, %offset;

3.12. shr#

Perform a logical right shift.

Semantics:

.type == .16bx2#
shiftl = unsigned(src1[5:0])
shifth = unsigned(src1[21:16])
dst[31:16] = src0[31:16] >> shifth
dst[15:0]  = src0[15:0]  >> shiftl
default#
shift = unsigned(src1[5:0])
dst = src0 >> shift

Examples:

.reg .32b %dst, %src0, %src1;

// logical right shift of 32-bit element
shr.32b  %dst, %src0, %src1;
.reg .v2.16b %dst_packed, %src0_packed;
shr.16bx2  %dst_packed, %src0_packed, %src1;

3.13. shl#

Perform a logical left shift.

Semantics:

.type == .16bx2#
shiftl = unsigned(src1[5:0])
shifth = unsigned(src1[21:16])
dst[31:16] = src0[31:16] << shifth
dst[15:0]  = src0[15:0]  << shiftl
default#
shift = unsigned(src1[5:0])
dst = src0 << shift

Examples:

.reg .32b %dst, %src0, %src1;

// logical left shift of 32-bit element
shl.32b  %dst, %src0, %src1;
.reg .v2.16b %dst_packed, %src0_packed;
shl.16bx2  %dst_packed, %src0_packed, %src1;

3.14. shf#

Perform a funnel shift operation.

Semantics:

int64_t num = (src0 << 32) | src1
shift = unsigned(src2[4:0])
if (.dir == .l)
  dst = (num << shift) >> 32
else
  dst = num >> shift

Notes:

Funnel shift can be used to implement rotate by duplicating same variable in both src0 and src1.

Examples:

.reg .32b %dst, %src0, %src1, %src2;

// funnel left shift
shf.l.32b  %dst, %src0, %src1, %src2;
// funnel right shift
shf.r.32b  %dst, %src0, %src1, %src2;

3.15. ubfe#

Extract and zero-extend bits.

Semantics:

offset  = src2[4:0]  // starting bit position
width   = umin(src1[5:0], bitwidth(.type)) // number of bits to extract
lastpos = umin(offset + width, bitwidth(.type)) // ignore bits beyond the MSB
width   = lastpos - offset // effective width

if (width == 0) {
  dst = 0
} else {
  dst = unsigned(src0 << (bitwidth(.type) - lastpos)) >> (bitwidth(.type) - width)
}

Notes:

Any bits specified in (offset + width) beyond 32 bits are ignored.

Examples:

.reg .32b %dst, %src0, %width, %offset;

// extract %width bits from %src0 at %offset
ubfe.32b  %dst, %src0, %width, %offset;

3.16. xor#

Compute bitwise XOR operation.

Semantics:

dst = src0 ^ src1

Examples:

.reg .32b %dst, %src0, %src1;

// xor of 32-bit elements
xor.32b  %dst, %src0, %src1;