# Ethereum Virtual Machine (EVM) Bitwise Instructions

## Introduction

Implementations of the EVM bitwise instructions.

## Module Contents

### Functions

 bitwise_and Bitwise AND operation of the top 2 elements of the stack. Pushes the bitwise_or Bitwise OR operation of the top 2 elements of the stack. Pushes the bitwise_xor Bitwise XOR operation of the top 2 elements of the stack. Pushes the bitwise_not Bitwise NOT operation of the top element of the stack. Pushes the get_byte For a word (defined by next top element of the stack), retrieve the bitwise_shl Logical shift left (SHL) operation of the top 2 elements of the stack. bitwise_shr Logical shift right (SHR) operation of the top 2 elements of the stack. bitwise_sar Arithmetic shift right (SAR) operation of the top 2 elements of the stack.

## Module Details

### bitwise_and

bitwise_and(evm)

Bitwise AND operation of the top 2 elements of the stack. Pushes the result back on the stack.

Parameters

evm – The current EVM frame.

def bitwise_and(evm: Evm) -> None:
# STACK
x = pop(evm.stack)
y = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
push(evm.stack, x & y)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_or

bitwise_or(evm)

Bitwise OR operation of the top 2 elements of the stack. Pushes the result back on the stack.

Parameters

evm – The current EVM frame.

def bitwise_or(evm: Evm) -> None:
# STACK
x = pop(evm.stack)
y = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
push(evm.stack, x | y)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_xor

bitwise_xor(evm)

Bitwise XOR operation of the top 2 elements of the stack. Pushes the result back on the stack.

Parameters

evm – The current EVM frame.

def bitwise_xor(evm: Evm) -> None:
# STACK
x = pop(evm.stack)
y = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
push(evm.stack, x ^ y)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_not

bitwise_not(evm)

Bitwise NOT operation of the top element of the stack. Pushes the result back on the stack.

Parameters

evm – The current EVM frame.

def bitwise_not(evm: Evm) -> None:
# STACK
x = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
push(evm.stack, ~x)

# PROGRAM COUNTER
evm.pc += 1

### get_byte

get_byte(evm)

For a word (defined by next top element of the stack), retrieve the Nth byte (0-indexed and defined by top element of stack) from the left (most significant) to right (least significant).

Parameters

evm – The current EVM frame.

def get_byte(evm: Evm) -> None:
# STACK
byte_index = pop(evm.stack)
word = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
if byte_index >= 32:
result = U256(0)
else:
extra_bytes_to_right = 31 - byte_index
# Remove the extra bytes in the right
word = word >> (extra_bytes_to_right * 8)
# Remove the extra bytes in the left
word = word & 0xFF
result = U256(word)

push(evm.stack, result)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_shl

bitwise_shl(evm)

Logical shift left (SHL) operation of the top 2 elements of the stack. Pushes the result back on the stack. :param evm: The current EVM frame.

def bitwise_shl(evm: Evm) -> None:
# STACK
shift = pop(evm.stack)
value = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
if shift < 256:
result = U256((value << shift) % U256_CEIL_VALUE)
else:
result = U256(0)

push(evm.stack, result)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_shr

bitwise_shr(evm)

Logical shift right (SHR) operation of the top 2 elements of the stack. Pushes the result back on the stack. :param evm: The current EVM frame.

def bitwise_shr(evm: Evm) -> None:
# STACK
shift = pop(evm.stack)
value = pop(evm.stack)

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
if shift < 256:
result = value >> shift
else:
result = U256(0)

push(evm.stack, result)

# PROGRAM COUNTER
evm.pc += 1

### bitwise_sar

bitwise_sar(evm)

Arithmetic shift right (SAR) operation of the top 2 elements of the stack. Pushes the result back on the stack. :param evm: The current EVM frame.

def bitwise_sar(evm: Evm) -> None:
# STACK
shift = pop(evm.stack)
signed_value = pop(evm.stack).to_signed()

# GAS
charge_gas(evm, GAS_VERY_LOW)

# OPERATION
if shift < 256:
result = U256.from_signed(signed_value >> shift)
elif signed_value >= 0:
result = U256(0)
else:
result = U256.MAX_VALUE

push(evm.stack, result)

# PROGRAM COUNTER
evm.pc += 1