Architecture

The arch contains processor architecture descriptions.

class ppci.arch.arch.Architecture(options=None, register_classes=())

Base class for all targets

between_blocks(frame)

Generate any instructions here if needed between two blocks

determine_arg_locations(arg_types)

Determine argument location for a given function

determine_rv_location(ret_type)

Determine the location of a return value of a function given the type of return value

epilogue(frame)

Generate instructions for the epilogue of a frame

gen_call(value)

Generate a sequence of instructions for a call to a label. The actual call instruction is not yet used until the end of the code generation at which time the live variables are known.

gen_copy_rv(res_type, res_var)

Generate a sequence of instructions for copying the result of a function to the correct variable. Override this function when needed. The basic implementation simply moves the result.

gen_fill_arguments(arg_types, args, live)

Generate a sequence of instructions that puts the arguments of a function to the right place.

get_compiler_rt_lib()

Gets the runtime for the compiler. Returns an object with the compiler runtime for this architecture

get_reg_class(bitsize=None, ty=None)

Look for a register class

get_reloc(name)

Retrieve a relocation identified by a name

get_size(typ)

Get type of ir type

has_option(name)

Check for an option setting selected

make_call(frame, vcall)

Actual call instruction implementation

make_id_str()

Return a string uniquely identifying this machine

move(dst, src)

Generate a move from src to dst

new_frame(frame_name, function)

Create a new frame with name frame_name for an ir-function

prologue(frame)

Generate instructions for the epilogue of a frame

runtime

Gets the runtime for the compiler. Returns an object with the compiler runtime for this architecture

value_classes

Get a mapping from ir-type to the proper register class

class ppci.arch.arch.Frame(name, arg_locs, live_in, rv, live_out)

Activation record abstraction. This class contains a flattened function. Instructions are selected and scheduled at this stage. Frames differ per machine. The only thing left to do for a frame is register allocation.

add_constant(value)

Add constant literal to constant pool

alloc(size)

Allocate space on the stack frame and return the offset

emit(ins)

Append an abstract instruction to the end of this frame

insert_code_after(instruction, code)

Insert a code sequence after an instruction

insert_code_before(instruction, code)

Insert a code sequence before an instruction

live_ranges(vreg)

Determine the live range of some register

live_regs_over(instruction)

Determine what registers are live along an instruction. Useful to determine if registers must be saved when making a call

new_label()

Generate a unique new label

new_name(salt)

Generate a new unique name

new_reg(cls, twain='')

Retrieve a new virtual register

class ppci.arch.isa.Isa

Container type for an instruction set. Contains a list of instructions, mappings from intermediate code to instructions.

Isa’s can be merged into new isa’s which can be used to define target. For example the arm without FPU can be combined with the FPU isa to expand the supported functions.

add_instruction(i)

Register an instruction into this ISA

pattern(non_term, tree, condition=None, size=1, cycles=1, energy=1)

Decorator function that adds a pattern.

peephole(function)

Add a peephole optimization function

register_pattern(pattern)

Add a pattern to this isa

register_relocation(relocation)

Register a relocation into this isa

class ppci.arch.isa.Register(name, num=None, aliases=())

Baseclass of all registers types

is_colored

Determine whether the register is colored

class ppci.arch.isa.Instruction(*args, **kwargs)

Base instruction class. Instructions are automatically added to an isa object. Instructions are created in the following ways:

  • From python code, by using the instruction directly: self.stream.emit(Mov(r1, r2))
  • By the assembler. This is done via a generated parser.
  • By the instruction selector. This is done via pattern matching rules

Instructions can then be emitted to output streams.

An instruction can be colored or not. When all its used registers are colored, the instruction is also colored.

classmethod decode(data)

Decode data into an instruction of this class

defined_registers

Return a set of all defined registers

encode()

Encode the instruction into binary form, returns bytes for this instruction.

is_colored

Determine whether all registers of this instruction are colored

reads_register(register)

Check if this instruction reads the given register

registers

Determine all registers used by this instruction

replace_register(old, new)

Replace a register usage with another register

set_all_patterns()

Look for all patterns and apply them to the tokens

used_registers

Return a set of all registers used by this instruction

writes_register(register)

Check if this instruction writes the given register