slothy.targets.riscv.riscv

Partial SLOTHY architecture model for RISCV

Module Contents

Classes

RegisterType

Enum of all register types

AddiLoop

Loop ending in an addition and a branch.

AddiStashLoop

Loop ending in an addition and a branch.

BranchLoop

More general loop type that just considers the branch instruction as part of the boundary. This can help to improve performance as the instructions that belong to handling the loop can be considered by SLOTHY as well.

Functions

iter_riscv_instructions

find_class

lookup_multidict

Multidict lookup.

Data

arch_name

llvm_mca_arch

llvm_mc_arch

llvm_mc_attr

unicorn_arch

unicorn_mode

API

slothy.targets.riscv.riscv.arch_name = 'RISCV'
slothy.targets.riscv.riscv.llvm_mca_arch = 'aarch64'
slothy.targets.riscv.riscv.llvm_mc_arch = None
slothy.targets.riscv.riscv.llvm_mc_attr = None
slothy.targets.riscv.riscv.unicorn_arch = None
slothy.targets.riscv.riscv.unicorn_mode = None
class slothy.targets.riscv.riscv.RegisterType(*args, **kwds)

Bases: enum.Enum

Enum of all register types

Initialization

BASE_INT = 1
VECT = 2
CSR = 3
__str__()
__repr__()
_spillable()
spillable = 'staticmethod(...)'
_list_registers(only_extra=False, only_normal=False, with_variants=False)

Return the list of all registers of a given type

list_registers = 'staticmethod(...)'
static find_type(r)

Find type of architectural register

static is_renamed(ty)

Indicate if register type should be subject to renaming

static from_string(string)

Find register type from string

static default_reserved()

Return the list of registers that should be reserved by default

static default_aliases()

Register aliases used by the architecture

class slothy.targets.riscv.riscv.AddiLoop(lbl=None, lbl_start=None, lbl_end=None, loop_init=None)

Bases: slothy.helper.Loop

Loop ending in an addition and a branch.

Example:

loop_lbl:
    {code}
    addi <cnt>, <cnt>, -<imm>
    (beq|bne|bge|blt|bgt|ble|bltu|bgtu|bleu|bgeu) <cnt>, <end>, loop_lbl

Initialization

start(loop_cnt, indentation=0, fixup=0, unroll=1, jump_if_empty=None, preamble_code=None, body_code=None, postamble_code=None, register_aliases=None)

Emit starting instruction(s) and jump label for loop

end(other, indentation=0)

Emit compare-and-branch at the end of the loop

class slothy.targets.riscv.riscv.AddiStashLoop(lbl=None, lbl_start=None, lbl_end=None, loop_init=None)

Bases: slothy.helper.Loop

Loop ending in an addition and a branch.

Example:

loop_lbl:
    {code}
    ld <cnt>, <offset>(<ptr>)
    addi <cnt>, <cnt>, -<imm>
    sd <cnt>, <offset>(<ptr>)
    (bne|bge) <cnt>, <end>, loop_lbl

Initialization

start(loop_cnt, indentation=0, fixup=0, unroll=1, jump_if_empty=None, preamble_code=None, body_code=None, postamble_code=None, register_aliases=None)

Emit starting instruction(s) and jump label for loop

end(other, indentation=0)

Emit compare-and-branch at the end of the loop

class slothy.targets.riscv.riscv.BranchLoop(lbl='lbl', lbl_start='1', lbl_end='2', loop_init='lr')

Bases: slothy.helper.Loop

More general loop type that just considers the branch instruction as part of the boundary. This can help to improve performance as the instructions that belong to handling the loop can be considered by SLOTHY as well.

Note

This loop type is still rather experimental. It has a lot of logic inside as it needs to be able to “understand” a variety of different ways to express loops, e.g., how counters get incremented, how registers marking the end of the loop need to be modified in case of software pipelining etc.

Example:

loop_lbl:
    {code}
    bltu <cnt>, <end>, loop_lbl

where cnt is the loop counter that gets incremented within the loop body.

Initialization

start(loop_cnt, indentation=0, fixup=0, unroll=1, jump_if_empty=None, preamble_code=None, body_code=None, postamble_code=None, register_aliases=None)

Emit starting instruction(s) and jump label for loop

end(other, indentation=0)

Nothing to do here - the branch instruction is already part of the body

slothy.targets.riscv.riscv.iter_riscv_instructions()
slothy.targets.riscv.riscv.find_class(src)
slothy.targets.riscv.riscv.lookup_multidict(d: any, inst: any, default: any = None) any

Multidict lookup.

Multidict entries can be the following:

  • An instruction class. It matches any instruction of that class.

  • A callable. It matches any instruction returning True when passed to the callable.

  • A tuple of instruction classes or callables. It matches any instruction which matches at least one element in the tuple.

Parameters:
  • d (any) – dictionary

  • inst (any)

  • default (any)

Returns:

Return type:

any

Raises:

UnknownInstruction – Couldn’t find instruction class for instruction