automated commit TP4 + Doc
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
"""
|
||||
This file defines the base class :py:class:`Allocator`
|
||||
and the naïve implementation :py:class:`NaiveAllocator`.
|
||||
"""
|
||||
|
||||
from Lib.Operands import Temporary, Operand, DataLocation, GP_REGS
|
||||
from Lib.Statement import Instruction
|
||||
from Lib.Errors import AllocationError
|
||||
from Lib.FunctionData import FunctionData
|
||||
from typing import Dict, List
|
||||
|
||||
|
||||
class Allocator():
|
||||
"""General base class for Naive, AllInMem and Smart Allocators.
|
||||
Replace all temporaries in the code with actual data locations.
|
||||
|
||||
Allocation is done in two steps:
|
||||
|
||||
- First, :py:meth:`prepare` is responsible for calling
|
||||
:py:meth:`Lib.Operands.TemporaryPool.set_temp_allocation`
|
||||
with a mapping from temporaries to where they should actually be stored
|
||||
(in registers or in memory).
|
||||
- Then, :py:meth:`replace` is called for each instruction in order to
|
||||
replace the temporary operands with the previously assigned locations
|
||||
(and possibly add some instructions before or after).
|
||||
Concretely, it returns a list of instructions that should replace the original
|
||||
instruction. The actual iteration over all the instructions is handled transparently
|
||||
by :py:meth:`Lib.LinearCode.LinearCode.iter_statements`.
|
||||
"""
|
||||
|
||||
_fdata: FunctionData
|
||||
|
||||
def __init__(self, fdata: FunctionData):
|
||||
self._fdata = fdata
|
||||
|
||||
def prepare(self) -> None: # pragma: no cover
|
||||
pass
|
||||
|
||||
def replace(self, instr: Instruction) -> List[Instruction]:
|
||||
"""Transform an instruction with temporaries into a list of instructions."""
|
||||
return [instr]
|
||||
|
||||
def rewriteCode(self, listcode) -> None:
|
||||
"""Modify the code to replace temporaries with
|
||||
registers or memory locations.
|
||||
"""
|
||||
listcode.iter_statements(self.replace)
|
||||
|
||||
|
||||
class NaiveAllocator(Allocator):
|
||||
"""Naive Allocator: try to assign a register to each temporary,
|
||||
fails if there are more temporaries than registers.
|
||||
"""
|
||||
|
||||
def replace(self, old_instr: Instruction) -> List[Instruction]:
|
||||
"""Replace Temporary operands with the corresponding allocated Register."""
|
||||
subst: Dict[Operand, Operand] = {}
|
||||
for arg in old_instr.args():
|
||||
if isinstance(arg, Temporary):
|
||||
subst[arg] = arg.get_alloced_loc()
|
||||
new_instr = old_instr.substitute(subst)
|
||||
return [new_instr]
|
||||
|
||||
def prepare(self) -> None:
|
||||
"""Allocate all temporaries to registers.
|
||||
Fail if there are too many temporaries."""
|
||||
regs = list(GP_REGS) # Get a writable copy
|
||||
temp_allocation: Dict[Temporary, DataLocation] = dict()
|
||||
for tmp in self._fdata._pool.get_all_temps():
|
||||
try:
|
||||
reg = regs.pop()
|
||||
except IndexError:
|
||||
raise AllocationError(
|
||||
"Too many temporaries ({}) for the naive allocation, sorry."
|
||||
.format(len(self._fdata._pool.get_all_temps())))
|
||||
temp_allocation[tmp] = reg
|
||||
self._fdata._pool.set_temp_allocation(temp_allocation)
|
||||
@@ -0,0 +1,179 @@
|
||||
"""
|
||||
This file defines the base class :py:class:`FunctionData`,
|
||||
containing metadata on a RiscV function, as well as utility
|
||||
functions common to the different intermediate representations.
|
||||
"""
|
||||
|
||||
from typing import (List, Callable, TypeVar)
|
||||
from Lib.Errors import AllocationError
|
||||
from Lib.Operands import (
|
||||
Offset, Temporary, TemporaryPool,
|
||||
S, T, FP)
|
||||
from Lib.Statement import (Statement, Instruction, Label, Comment)
|
||||
|
||||
|
||||
class FunctionData:
|
||||
"""
|
||||
Stores some metadata on a RiscV function:
|
||||
name of the function, label names, temporary variables
|
||||
(using :py:class:`Lib.Operands.TemporaryPool`),
|
||||
and div_by_zero label.
|
||||
|
||||
This class is usually used indirectly through the
|
||||
different intermediate representations we work with,
|
||||
such as :py:attr:`Lib.LinearCode.LinearCode.fdata`.
|
||||
"""
|
||||
|
||||
_nblabel: int
|
||||
_dec: int
|
||||
_pool: TemporaryPool
|
||||
_name: str
|
||||
_label_div_by_zero: Label
|
||||
|
||||
def __init__(self, name: str):
|
||||
self._nblabel = -1
|
||||
self._dec = 0
|
||||
self._pool = TemporaryPool()
|
||||
self._name = name
|
||||
self._label_div_by_zero = self.fresh_label("div_by_zero")
|
||||
|
||||
def get_name(self) -> str:
|
||||
"""Return the name of the function."""
|
||||
return self._name
|
||||
|
||||
def fresh_tmp(self) -> Temporary:
|
||||
"""
|
||||
Return a new fresh Temporary,
|
||||
which is added to the pool.
|
||||
"""
|
||||
return self._pool.fresh_tmp()
|
||||
|
||||
def fresh_offset(self) -> Offset:
|
||||
"""
|
||||
Return a new offset in the memory stack.
|
||||
Offsets are decreasing relative to FP.
|
||||
"""
|
||||
self._dec = self._dec + 1
|
||||
# For ld or sd, an offset on 12 signed bits is expected
|
||||
# Raise an error if the offset is too big
|
||||
if -8 * self._dec < - 2 ** 11:
|
||||
raise AllocationError(
|
||||
"Offset given by the allocation too big to be manipulated ({}), sorry."
|
||||
.format(self._dec))
|
||||
return Offset(FP, -8 * self._dec)
|
||||
|
||||
def get_offset(self) -> int:
|
||||
"""
|
||||
Return the current offset in the memory stack.
|
||||
"""
|
||||
return self._dec
|
||||
|
||||
def _fresh_label_name(self, name) -> str:
|
||||
"""
|
||||
Return a new unique label name based on the given string.
|
||||
"""
|
||||
self._nblabel = self._nblabel + 1
|
||||
return name + "_" + str(self._nblabel) + "_" + self._name
|
||||
|
||||
def fresh_label(self, name) -> Label:
|
||||
"""
|
||||
Return a new label, with a unique name based on the given string.
|
||||
"""
|
||||
return Label(self._fresh_label_name(name))
|
||||
|
||||
def get_label_div_by_zero(self) -> Label:
|
||||
return self._label_div_by_zero
|
||||
|
||||
|
||||
_T = TypeVar("_T", bound=Statement)
|
||||
|
||||
|
||||
def _iter_statements(
|
||||
listIns: List[_T], f: Callable[[_T], List[_T]]) -> List[_T | Comment]:
|
||||
"""Iterate over instructions.
|
||||
For each real instruction i (not label or comment), replace it
|
||||
with the list of instructions given by f(i).
|
||||
"""
|
||||
newListIns: List[_T | Comment] = []
|
||||
for old_i in listIns:
|
||||
# Do nothing for label or comment
|
||||
if not isinstance(old_i, Instruction):
|
||||
newListIns.append(old_i)
|
||||
continue
|
||||
new_i_list = f(old_i)
|
||||
# Otherwise, replace the instruction by the list
|
||||
# returned by f, with comments giving the replacement
|
||||
newListIns.append(Comment("Replaced " + str(old_i)))
|
||||
newListIns.extend(new_i_list)
|
||||
return newListIns
|
||||
|
||||
|
||||
def _print_code(listIns: List, fdata: FunctionData, output,
|
||||
init_label=None, fin_label=None, fin_div0=False, comment=None) -> None:
|
||||
"""
|
||||
Please use print_code from LinearCode or CFG, not directly this one.
|
||||
|
||||
Print the instructions from listIns, forming fdata, on output.
|
||||
If init_label is given, add an initial jump to it before the generated code.
|
||||
If fin_label is given, add it after the generated code.
|
||||
If fin_div0 is given equal to true, add the code for returning an
|
||||
error when dividing by 0, at the very end.
|
||||
"""
|
||||
# compute size for the local stack - do not forget to align by 16
|
||||
fo = fdata.get_offset() # allocate enough memory for stack
|
||||
cardoffset = 8 * (fo + (0 if fo % 2 == 0 else 1)) + 16
|
||||
output.write(
|
||||
"##Automatically generated RISCV code, MIF08 & CAP\n")
|
||||
if comment is not None:
|
||||
output.write("##{} version\n".format(comment))
|
||||
output.write("\n\n##prelude\n")
|
||||
# We put an li t0, cardoffset in case it is greater than 2**11
|
||||
# We use t0 because it is caller-saved
|
||||
output.write("""
|
||||
.text
|
||||
.globl {0}
|
||||
{0}:
|
||||
li t0, {1}
|
||||
sub sp, sp, t0
|
||||
sd ra, 0(sp)
|
||||
sd fp, 8(sp)
|
||||
add fp, sp, t0
|
||||
""".format(fdata.get_name(), cardoffset))
|
||||
# Stack in RiscV is managed with SP
|
||||
if init_label is not None:
|
||||
# Add a jump to init_label before the generated code.
|
||||
output.write("""
|
||||
j {0}
|
||||
""".format(init_label))
|
||||
output.write("\n\n##Generated Code\n")
|
||||
# Generated code
|
||||
for i in listIns:
|
||||
i.printIns(output)
|
||||
output.write("\n\n##postlude\n")
|
||||
if fin_label is not None:
|
||||
# Add fin_label after the generated code.
|
||||
output.write("""
|
||||
{0}:
|
||||
""".format(fin_label))
|
||||
# We put an li t0, cardoffset in case it is greater than 2**11
|
||||
# We use t0 because it is caller-saved
|
||||
output.write("""
|
||||
ld ra, 0(sp)
|
||||
ld fp, 8(sp)
|
||||
li t0, {0}
|
||||
add sp, sp, t0
|
||||
ret
|
||||
""".format(cardoffset))
|
||||
if fin_div0:
|
||||
# Add code for division by 0 at the end.
|
||||
output.write("""
|
||||
{0}:
|
||||
la a0, {0}_msg
|
||||
call println_string
|
||||
li a0, 1
|
||||
call exit
|
||||
""".format(fdata._label_div_by_zero))
|
||||
# Add the data for the message of the division by 0
|
||||
output.write("""
|
||||
{0}_msg: .string "Division by 0"
|
||||
""".format(fdata._label_div_by_zero))
|
||||
@@ -0,0 +1,101 @@
|
||||
"""
|
||||
CAP, CodeGeneration, LinearCode API
|
||||
Classes for a RiscV linear code.
|
||||
"""
|
||||
|
||||
from typing import List
|
||||
from Lib.Operands import (A0, Function, DataLocation)
|
||||
from Lib.Statement import (
|
||||
Instru3A, AbsoluteJump, ConditionalJump, Comment, Label
|
||||
)
|
||||
from Lib.RiscV import (mv, call)
|
||||
from Lib.FunctionData import (FunctionData, _iter_statements, _print_code)
|
||||
|
||||
|
||||
CodeStatement = Comment | Label | Instru3A | AbsoluteJump | ConditionalJump
|
||||
|
||||
|
||||
class LinearCode:
|
||||
"""
|
||||
Representation of a RiscV program as a list of instructions.
|
||||
|
||||
:py:meth:`add_instruction` is repeatedly called in the codegen visitor
|
||||
to build a complete list of RiscV instructions for the source program.
|
||||
|
||||
The :py:attr:`fdata` member variable contains some meta-information
|
||||
on the program, for instance to allocate a new temporary.
|
||||
See :py:class:`Lib.FunctionData.FunctionData`.
|
||||
|
||||
For debugging purposes, :py:meth:`print_code` allows to print
|
||||
the RiscV program to a file.
|
||||
"""
|
||||
|
||||
"""
|
||||
The :py:attr:`fdata` member variable contains some meta-information
|
||||
on the program, for instance to allocate a new temporary.
|
||||
See :py:class:`Lib.FunctionData.FunctionData`.
|
||||
"""
|
||||
fdata: FunctionData
|
||||
|
||||
_listIns: List[CodeStatement]
|
||||
|
||||
def __init__(self, name: str):
|
||||
self._listIns = []
|
||||
self.fdata = FunctionData(name)
|
||||
|
||||
def add_instruction(self, i: CodeStatement) -> None:
|
||||
"""
|
||||
Utility function to add an instruction in the program.
|
||||
|
||||
See also :py:mod:`Lib.RiscV` to generate relevant instructions.
|
||||
"""
|
||||
self._listIns.append(i)
|
||||
|
||||
def iter_statements(self, f) -> None:
|
||||
"""Iterate over instructions.
|
||||
For each real instruction (not label or comment), call f,
|
||||
which must return either None or a list of instruction. If it
|
||||
returns None, nothing happens. If it returns a list, then the
|
||||
instruction is replaced by this list.
|
||||
"""
|
||||
self._listIns = _iter_statements(self._listIns, f)
|
||||
|
||||
def get_instructions(self) -> List[CodeStatement]:
|
||||
"""Return the list of instructions of the program."""
|
||||
return self._listIns
|
||||
|
||||
# each instruction has its own "add in list" version
|
||||
def add_label(self, s: Label) -> None:
|
||||
"""Add a label in the program."""
|
||||
return self.add_instruction(s)
|
||||
|
||||
def add_comment(self, s: str) -> None:
|
||||
"""Add a comment in the program."""
|
||||
self.add_instruction(Comment(s))
|
||||
|
||||
def add_instruction_PRINTLN_INT(self, reg: DataLocation) -> None:
|
||||
"""Print integer value, with newline. (see Expand)"""
|
||||
# a print instruction generates the temp it prints.
|
||||
self.add_instruction(mv(A0, reg))
|
||||
self.add_instruction(call(Function('println_int')))
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join(map(str, self._listIns))
|
||||
|
||||
def print_code(self, output, comment=None) -> None:
|
||||
"""Outputs the RiscV program as text to a file at the given path."""
|
||||
_print_code(self._listIns, self.fdata, output, init_label=None,
|
||||
fin_label=None, fin_div0=True, comment=comment)
|
||||
|
||||
def print_dot(self, filename: str, DF=None, view=False) -> None: # pragma: no cover
|
||||
"""Outputs the RiscV program as graph to a file at the given path."""
|
||||
# import graphviz here so that students who don't have it can still work on lab4
|
||||
from graphviz import Digraph
|
||||
graph = Digraph()
|
||||
# nodes
|
||||
content = ""
|
||||
for i in self._listIns:
|
||||
content += str(i) + "\\l"
|
||||
graph.node("Code", label=content, shape='rectangle')
|
||||
# no edges
|
||||
graph.render(filename, view=view)
|
||||
@@ -0,0 +1,265 @@
|
||||
"""
|
||||
This file defines the base class :py:class:`Operand`
|
||||
and its subclasses for different operands: :py:class:`Condition`,
|
||||
:py:class:`DataLocation` and :py:class:`Function`.
|
||||
|
||||
The class :py:class:`DataLocation` itself has subclasses:
|
||||
:py:class:`Register`, :py:class:`Offset` for address in memory,
|
||||
:py:class:`Immediate` for constants and :py:class:`Temporary`
|
||||
for location not yet allocated.
|
||||
|
||||
This file also define shortcuts for registers in RISCV.
|
||||
"""
|
||||
|
||||
from typing import Dict, List
|
||||
from MiniCParser import MiniCParser
|
||||
from Lib.Errors import MiniCInternalError
|
||||
|
||||
|
||||
class Operand():
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# signed version for riscv
|
||||
all_ops = ['blt', 'bgt', 'beq', 'bne', 'ble', 'bge', 'beqz', 'bnez']
|
||||
opdict = {MiniCParser.LT: 'blt', MiniCParser.GT: 'bgt',
|
||||
MiniCParser.LTEQ: 'ble', MiniCParser.GTEQ: 'bge',
|
||||
MiniCParser.NEQ: 'bne', MiniCParser.EQ: 'beq'}
|
||||
opnot_dict = {'bgt': 'ble',
|
||||
'bge': 'blt',
|
||||
'blt': 'bge',
|
||||
'ble': 'bgt',
|
||||
'beq': 'bne',
|
||||
'bne': 'beq',
|
||||
'beqz': 'bnez',
|
||||
'bnez': 'beqz'}
|
||||
|
||||
|
||||
class Condition(Operand):
|
||||
"""Condition, i.e. comparison operand for a CondJump.
|
||||
|
||||
Example usage :
|
||||
|
||||
- Condition('beq') = branch if equal.
|
||||
- Condition(MiniCParser.LT) = branch if lower than.
|
||||
- ...
|
||||
|
||||
The constructor's argument shall be a string in the list all_ops, or a
|
||||
comparison operator in MiniCParser.LT, MiniCParser.GT, ... (one of the keys
|
||||
in opdict).
|
||||
|
||||
A 'negate' method allows getting the negation of this condition.
|
||||
"""
|
||||
|
||||
_op: str
|
||||
|
||||
def __init__(self, optype):
|
||||
if optype in opdict:
|
||||
self._op = opdict[optype]
|
||||
elif str(optype) in all_ops:
|
||||
self._op = str(optype)
|
||||
else:
|
||||
raise MiniCInternalError("Unsupported comparison operator %s", optype)
|
||||
|
||||
def negate(self) -> 'Condition':
|
||||
"""Return the opposite condition."""
|
||||
return Condition(opnot_dict[self._op])
|
||||
|
||||
def __str__(self):
|
||||
return self._op
|
||||
|
||||
|
||||
class Function(Operand):
|
||||
"""Operand for build-in function call."""
|
||||
|
||||
_name: str
|
||||
|
||||
def __init__(self, name: str):
|
||||
self._name = name
|
||||
|
||||
def __str__(self):
|
||||
return self._name
|
||||
|
||||
|
||||
class DataLocation(Operand):
|
||||
""" A Data Location is either a register, a temporary
|
||||
or a place in memory (offset).
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# map for register shortcuts
|
||||
reg_map = dict([(0, 'zero'), (1, 'ra'), (2, 'sp')] + # no (3, 'gp') nor (4, 'tp')
|
||||
[(i+5, 't'+str(i)) for i in range(3)] +
|
||||
[(8, 'fp'), (9, 's1')] +
|
||||
[(i+10, 'a'+str(i)) for i in range(8)] +
|
||||
[(i+18, 's'+str(i+2)) for i in range(10)] +
|
||||
[(i+28, 't'+str(i+3)) for i in range(4)])
|
||||
|
||||
|
||||
class Register(DataLocation):
|
||||
""" A (physical) register."""
|
||||
|
||||
_number: int
|
||||
|
||||
def __init__(self, number: int):
|
||||
self._number = number
|
||||
|
||||
def __repr__(self):
|
||||
if self._number not in reg_map:
|
||||
raise Exception("Register number %d should not be used", self._number)
|
||||
else:
|
||||
return ("{}".format(reg_map[self._number]))
|
||||
|
||||
def __eq__(self, other):
|
||||
return isinstance(other, Register) and self._number == other._number
|
||||
|
||||
def __hash__(self):
|
||||
return self._number
|
||||
|
||||
|
||||
# Shortcuts for registers in RISCV
|
||||
# Only integer registers
|
||||
ZERO = Register(0)
|
||||
RA = Register(1)
|
||||
SP = Register(2)
|
||||
GP = Register(3) # Register not used for this course
|
||||
TP = Register(4) # Register not used for this course
|
||||
A = tuple(Register(i + 10) for i in range(8))
|
||||
S = tuple(Register(i + 8) for i in range(2)) + tuple(Register(i + 18) for i in range(10))
|
||||
T = tuple(Register(i + 5) for i in range(3)) + tuple(Register(i + 28) for i in range(4))
|
||||
A0 = A[0] # function args/return Values: A0, A1
|
||||
A1 = A[1]
|
||||
FP = S[0] # Frame Pointer = Saved register 0
|
||||
|
||||
# General purpose registers, usable for the allocator
|
||||
GP_REGS = S[4:] + T # s0, s1, s2 and s3 are special
|
||||
|
||||
|
||||
class Offset(DataLocation):
|
||||
""" Offset = address in memory computed with base + offset."""
|
||||
|
||||
_basereg: Register
|
||||
_offset: int
|
||||
|
||||
def __init__(self, basereg: Register, offset: int):
|
||||
self._basereg = basereg
|
||||
self._offset = offset
|
||||
|
||||
def __repr__(self):
|
||||
return ("{}({})".format(self._offset, self._basereg))
|
||||
|
||||
def get_offset(self) -> int:
|
||||
"""Return the value of the offset."""
|
||||
return self._offset
|
||||
|
||||
|
||||
class Immediate(DataLocation):
|
||||
"""Immediate operand (integer)."""
|
||||
|
||||
_val: int
|
||||
|
||||
def __init__(self, val):
|
||||
self._val = val
|
||||
|
||||
def __str__(self):
|
||||
return str(self._val)
|
||||
|
||||
|
||||
class Temporary(DataLocation):
|
||||
"""Temporary, a location that has not been allocated yet.
|
||||
It will later be mapped to a physical register (Register) or to a memory location (Offset).
|
||||
"""
|
||||
|
||||
_number: int
|
||||
_pool: 'TemporaryPool'
|
||||
|
||||
def __init__(self, number: int, pool: 'TemporaryPool'):
|
||||
self._number = number
|
||||
self._pool = pool
|
||||
|
||||
def __repr__(self):
|
||||
return ("temp_{}".format(str(self._number)))
|
||||
|
||||
def get_alloced_loc(self) -> DataLocation:
|
||||
"""Return the DataLocation allocated to this Temporary."""
|
||||
return self._pool.get_alloced_loc(self)
|
||||
|
||||
|
||||
class TemporaryPool:
|
||||
"""Manage a pool of temporaries."""
|
||||
|
||||
_all_temps: List[Temporary]
|
||||
_current_num: int
|
||||
_allocation: Dict[Temporary, DataLocation]
|
||||
|
||||
def __init__(self):
|
||||
self._all_temps = []
|
||||
self._current_num = 0
|
||||
self._allocation = dict()
|
||||
|
||||
def get_all_temps(self) -> List[Temporary]:
|
||||
"""Return all the temporaries of the pool."""
|
||||
return self._all_temps
|
||||
|
||||
def get_alloced_loc(self, t: Temporary) -> DataLocation:
|
||||
"""Get the actual DataLocation allocated for the temporary t."""
|
||||
return self._allocation[t]
|
||||
|
||||
def add_tmp(self, t: Temporary):
|
||||
"""Add a temporary to the pool."""
|
||||
self._all_temps.append(t)
|
||||
self._allocation[t] = t # While no allocation, return the temporary itself
|
||||
|
||||
def set_temp_allocation(self, allocation: Dict[Temporary, DataLocation]) -> None:
|
||||
"""Give a mapping from temporaries to actual registers.
|
||||
The argument allocation must be a dict from Temporary to
|
||||
DataLocation other than Temporary (typically Register or Offset).
|
||||
Typing enforces that keys are Temporary and values are Datalocation.
|
||||
We check the values are indeed not Temporary.
|
||||
"""
|
||||
for v in allocation.values():
|
||||
assert not isinstance(v, Temporary), (
|
||||
"Incorrect allocation scheme: value " +
|
||||
str(v) + " is a Temporary.")
|
||||
self._allocation = allocation
|
||||
|
||||
def fresh_tmp(self) -> Temporary:
|
||||
"""Give a new fresh Temporary and add it to the pool."""
|
||||
t = Temporary(self._current_num, self)
|
||||
self._current_num += 1
|
||||
self.add_tmp(t)
|
||||
return t
|
||||
|
||||
|
||||
class Renamer:
|
||||
"""Manage a renaming of temporaries."""
|
||||
|
||||
_pool: TemporaryPool
|
||||
_env: Dict[Temporary, Temporary]
|
||||
|
||||
def __init__(self, pool: TemporaryPool):
|
||||
self._pool = pool
|
||||
self._env = dict()
|
||||
|
||||
def fresh(self, t: Temporary) -> Temporary:
|
||||
"""Give a fresh rename for a Temporary."""
|
||||
new_t = self._pool.fresh_tmp()
|
||||
self._env[t] = new_t
|
||||
return new_t
|
||||
|
||||
def replace(self, t: Temporary) -> Temporary:
|
||||
"""Give the rename for a Temporary (which is itself if it is not renamed)."""
|
||||
return self._env.get(t, t)
|
||||
|
||||
def defined(self, t: Temporary) -> bool:
|
||||
"""True if the Temporary is renamed."""
|
||||
return t in self._env
|
||||
|
||||
def copy(self):
|
||||
"""Give a copy of the Renamer."""
|
||||
r = Renamer(self._pool)
|
||||
r._env = self._env.copy()
|
||||
return r
|
||||
@@ -0,0 +1,89 @@
|
||||
"""
|
||||
MIF08, CAP, CodeGeneration, RiscV API
|
||||
Functions to define instructions.
|
||||
"""
|
||||
|
||||
from Lib.Errors import MiniCInternalError
|
||||
from Lib.Operands import (
|
||||
Condition, Immediate, Operand, Function, ZERO)
|
||||
from Lib.Statement import (Instru3A, AbsoluteJump, ConditionalJump, Label)
|
||||
|
||||
|
||||
def call(function: Function) -> Instru3A:
|
||||
"""Function call."""
|
||||
return Instru3A('call', function)
|
||||
|
||||
|
||||
def jump(label: Label) -> AbsoluteJump:
|
||||
"""Unconditional jump to label."""
|
||||
return AbsoluteJump(label)
|
||||
|
||||
|
||||
def conditional_jump(label: Label, op1: Operand, cond: Condition, op2: Operand):
|
||||
"""Add a conditional jump to the code.
|
||||
This is a wrapper around bge, bgt, beq, ... c is a Condition, like
|
||||
Condition('bgt'), Condition(MiniCParser.EQ), ...
|
||||
"""
|
||||
op2 = op2 if op2 != Immediate(0) else ZERO
|
||||
return ConditionalJump(cond=cond, op1=op1, op2=op2, label=label)
|
||||
|
||||
|
||||
def add(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
if isinstance(sr2orimm7, Immediate):
|
||||
return Instru3A("addi", dr, sr1, sr2orimm7)
|
||||
else:
|
||||
return Instru3A("add", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def mul(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
if isinstance(sr2orimm7, Immediate):
|
||||
raise MiniCInternalError("Cant multiply by an immediate")
|
||||
else:
|
||||
return Instru3A("mul", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def div(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
if isinstance(sr2orimm7, Immediate):
|
||||
raise MiniCInternalError("Cant divide by an immediate")
|
||||
else:
|
||||
return Instru3A("div", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def rem(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
if isinstance(sr2orimm7, Immediate):
|
||||
raise MiniCInternalError("Cant divide by an immediate")
|
||||
return Instru3A("rem", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def sub(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
if isinstance(sr2orimm7, Immediate):
|
||||
raise MiniCInternalError("Cant substract by an immediate")
|
||||
return Instru3A("sub", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def land(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
return Instru3A("and", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def lor(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||||
return Instru3A("or", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def xor(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A: # pragma: no cover
|
||||
return Instru3A("xor", dr, sr1, sr2orimm7)
|
||||
|
||||
|
||||
def li(dr: Operand, imm7: Immediate) -> Instru3A:
|
||||
return Instru3A("li", dr, imm7)
|
||||
|
||||
|
||||
def mv(dr: Operand, sr: Operand) -> Instru3A:
|
||||
return Instru3A("mv", dr, sr)
|
||||
|
||||
|
||||
def ld(dr: Operand, mem: Operand) -> Instru3A:
|
||||
return Instru3A("ld", dr, mem)
|
||||
|
||||
|
||||
def sd(sr: Operand, mem: Operand) -> Instru3A:
|
||||
return Instru3A("sd", sr, mem)
|
||||
@@ -0,0 +1,242 @@
|
||||
"""
|
||||
The base class for RISCV ASM statements is :py:class:`Statement`.
|
||||
It is inherited by :py:class:`Comment`, :py:class:`Label`
|
||||
and :py:class:`Instruction`. In turn, :py:class:`Instruction`
|
||||
is inherited by :py:class:`Instru3A`
|
||||
(for regular non-branching 3-address instructions),
|
||||
:py:class:`AbsoluteJump` and :py:class:`ConditionalJump`.
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import (List, Dict, TypeVar)
|
||||
from Lib.Operands import (Operand, Renamer, Temporary, Condition)
|
||||
from Lib.Errors import MiniCInternalError
|
||||
|
||||
|
||||
def regset_to_string(registerset):
|
||||
"""Utility function: pretty-prints a set of locations."""
|
||||
return "{" + ",".join(str(x) for x in registerset) + "}"
|
||||
|
||||
|
||||
# Temporary until we can use Typing.Self in python 3.11
|
||||
TStatement = TypeVar("TStatement", bound="Statement")
|
||||
|
||||
|
||||
@dataclass(unsafe_hash=True)
|
||||
class Statement:
|
||||
"""A Statement, which is an instruction, a comment or a label."""
|
||||
|
||||
def defined(self) -> List[Operand]:
|
||||
return []
|
||||
|
||||
def used(self) -> List[Operand]:
|
||||
return []
|
||||
|
||||
def substitute(self: TStatement, subst: Dict[Operand, Operand]) -> TStatement:
|
||||
raise Exception(
|
||||
"substitute: Operands {} are not present in instruction {}"
|
||||
.format(subst, self))
|
||||
|
||||
def printIns(self, stream):
|
||||
"""
|
||||
Print the statement on the output.
|
||||
Should never be called on the base class.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@dataclass(unsafe_hash=True)
|
||||
class Comment(Statement):
|
||||
"""A comment."""
|
||||
comment: str
|
||||
|
||||
def __str__(self): # use only for print_dot !
|
||||
return "# {}".format(self.comment)
|
||||
|
||||
def printIns(self, stream):
|
||||
print(' # ' + self.comment, file=stream)
|
||||
|
||||
|
||||
@dataclass(unsafe_hash=True)
|
||||
class Label(Statement, Operand):
|
||||
"""A label is both a Statement and an Operand."""
|
||||
name: str
|
||||
|
||||
def __str__(self):
|
||||
return ("lbl_{}".format(self.name))
|
||||
|
||||
def __repr__(self):
|
||||
return ("{}".format(self.name))
|
||||
|
||||
def printIns(self, stream):
|
||||
print(str(self) + ':', file=stream)
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class Instruction(Statement):
|
||||
ins: str
|
||||
_read_only: bool
|
||||
|
||||
def is_read_only(self):
|
||||
"""
|
||||
True if the instruction only reads from its operands.
|
||||
|
||||
Otherwise, the first operand is considered as the destination
|
||||
and others are source.
|
||||
"""
|
||||
return self._read_only
|
||||
|
||||
def rename(self, renamer: Renamer) -> None:
|
||||
raise NotImplementedError
|
||||
|
||||
def args(self) -> List[Operand]:
|
||||
raise NotImplementedError
|
||||
|
||||
def defined(self):
|
||||
if self.is_read_only():
|
||||
defs = []
|
||||
else:
|
||||
defs = [self.args()[0]]
|
||||
return defs
|
||||
|
||||
def used(self):
|
||||
if self.is_read_only():
|
||||
uses = self.args()
|
||||
else:
|
||||
uses = self.args()[1:]
|
||||
return uses
|
||||
|
||||
def __str__(self):
|
||||
s = self.ins
|
||||
first = True
|
||||
for arg in self.args():
|
||||
if first:
|
||||
s += ' ' + str(arg)
|
||||
first = False
|
||||
else:
|
||||
s += ', ' + str(arg)
|
||||
return s
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.ins, *self.args()))
|
||||
|
||||
def printIns(self, stream):
|
||||
"""Print the instruction on the output."""
|
||||
print(' ', str(self), file=stream)
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class Instru3A(Instruction):
|
||||
_args: List[Operand]
|
||||
|
||||
def __init__(self, ins, *args: Operand):
|
||||
# convention is to use lower-case in RISCV
|
||||
self.ins = ins.lower()
|
||||
self._args = list(args)
|
||||
self._read_only = (self.ins == "call"
|
||||
or self.ins == "ld"
|
||||
or self.ins == "lw"
|
||||
or self.ins == "lb")
|
||||
if (self.ins.startswith("b") or self.ins == "j"):
|
||||
raise MiniCInternalError
|
||||
|
||||
def args(self):
|
||||
return self._args
|
||||
|
||||
def rename(self, renamer: Renamer):
|
||||
old_replaced = dict()
|
||||
for i, arg in enumerate(self._args):
|
||||
if isinstance(arg, Temporary):
|
||||
if i == 0 and not self.is_read_only():
|
||||
old_replaced[arg] = renamer.replace(arg)
|
||||
new_t = renamer.fresh(arg)
|
||||
elif arg in old_replaced.keys():
|
||||
new_t = old_replaced[arg]
|
||||
else:
|
||||
new_t = renamer.replace(arg)
|
||||
self._args[i] = new_t
|
||||
|
||||
def substitute(self, subst: Dict[Operand, Operand]):
|
||||
for op in subst:
|
||||
if op not in self.args():
|
||||
raise Exception(
|
||||
"substitute: Operand {} is not present in instruction {}"
|
||||
.format(op, self))
|
||||
args = [subst.get(arg, arg)
|
||||
if isinstance(arg, Temporary) else arg
|
||||
for arg in self.args()]
|
||||
return Instru3A(self.ins, *args)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(super)
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class AbsoluteJump(Instruction):
|
||||
""" An Absolute Jump is a specific kind of instruction"""
|
||||
ins = "j"
|
||||
label: Label
|
||||
_read_only = True
|
||||
|
||||
def __init__(self, label: Label):
|
||||
self.label = label
|
||||
|
||||
def args(self):
|
||||
return [self.label]
|
||||
|
||||
def rename(self, renamer: Renamer):
|
||||
pass
|
||||
|
||||
def substitute(self, subst: Dict[Operand, Operand]):
|
||||
if subst != {}:
|
||||
raise Exception(
|
||||
"substitute: No possible substitution on instruction {}"
|
||||
.format(self))
|
||||
return self
|
||||
|
||||
def __hash__(self):
|
||||
return hash(super)
|
||||
|
||||
def targets(self) -> List[Label]:
|
||||
return [self.label]
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class ConditionalJump(Instruction):
|
||||
""" A Conditional Jump is a specific kind of instruction"""
|
||||
cond: Condition
|
||||
label: Label
|
||||
op1: Operand
|
||||
op2: Operand
|
||||
_read_only = True
|
||||
|
||||
def __init__(self, cond: Condition, op1: Operand, op2: Operand, label: Label):
|
||||
self.cond = cond
|
||||
self.label = label
|
||||
self.op1 = op1
|
||||
self.op2 = op2
|
||||
self.ins = str(self.cond)
|
||||
|
||||
def args(self):
|
||||
return [self.op1, self.op2, self.label]
|
||||
|
||||
def rename(self, renamer: Renamer):
|
||||
if isinstance(self.op1, Temporary):
|
||||
self.op1 = renamer.replace(self.op1)
|
||||
if isinstance(self.op2, Temporary):
|
||||
self.op2 = renamer.replace(self.op2)
|
||||
|
||||
def substitute(self, subst: Dict[Operand, Operand]):
|
||||
for op in subst:
|
||||
if op not in self.args():
|
||||
raise Exception(
|
||||
"substitute: Operand {} is not present in instruction {}"
|
||||
.format(op, self))
|
||||
op1 = subst.get(self.op1, self.op1) if isinstance(self.op1, Temporary) \
|
||||
else self.op1
|
||||
op2 = subst.get(self.op2, self.op2) if isinstance(self.op2, Temporary) \
|
||||
else self.op2
|
||||
return ConditionalJump(self.cond, op1, op2, self.label)
|
||||
|
||||
def __hash__(self):
|
||||
return hash(super)
|
||||
+12
-9
@@ -9,12 +9,9 @@ ifdef TEST_FILES
|
||||
export TEST_FILES
|
||||
endif
|
||||
|
||||
ifdef SSA
|
||||
MINICC_OPTS+=--ssa
|
||||
endif
|
||||
|
||||
ifdef SSA_OPTIM
|
||||
MINICC_OPTS+=--ssa-optim
|
||||
# code generation mode
|
||||
ifdef MODE
|
||||
MINICC_OPTS+=--mode $(MODE)
|
||||
endif
|
||||
|
||||
ifdef TYPECHECK_ONLY
|
||||
@@ -45,8 +42,8 @@ main-deps: MiniCLexer.py MiniCParser.py TP03/MiniCInterpretVisitor.py TP03/MiniC
|
||||
.PHONY: test test-interpret test-codegen clean clean-tests tar antlr
|
||||
|
||||
|
||||
test: test-interpret
|
||||
|
||||
test: test-interpret test-codegen
|
||||
|
||||
test-pyright: antlr
|
||||
pyright .
|
||||
@@ -57,10 +54,16 @@ test-interpret: test-pyright test_interpreter.py main-deps
|
||||
|
||||
# Test for naive allocator (also runs test_expect to check // EXPECTED directives):
|
||||
test-naive: test-pyright antlr
|
||||
ifndef MODE
|
||||
export MINICC_OPTS="${MINICC_OPTS} --mode codegen-linear"
|
||||
endif
|
||||
python3 -m pytest $(PYTEST_BASE_OPTS) $(PYTEST_OPTS) ./test_codegen.py -k 'naive or expect'
|
||||
|
||||
# Test for all but the smart allocator, i.e. everything that lab4 should pass:
|
||||
test-notsmart: test-pyright antlr
|
||||
test-lab4: test-pyright antlr
|
||||
ifndef MODE
|
||||
export MINICC_OPTS="${MINICC_OPTS} --mode codegen-linear"
|
||||
endif
|
||||
python3 -m pytest $(PYTEST_BASE_OPTS) $(PYTEST_OPTS) ./test_codegen.py -k 'not smart'
|
||||
|
||||
# Test just the smart allocator (quicker than tests)
|
||||
@@ -83,7 +86,7 @@ define CLEAN
|
||||
import glob
|
||||
import os
|
||||
for f in glob.glob("**/tests/**/*.c", recursive=True):
|
||||
for s in ("{}-{}.s".format(f[:-2], test) for test in ("naive", "smart", "gcc", "all_in_mem")):
|
||||
for s in ("{}-{}.s".format(f[:-2], test) for test in ("naive", "smart", "gcc", "all-in-mem")):
|
||||
try:
|
||||
os.remove(s)
|
||||
print("Removed {}".format(s))
|
||||
|
||||
+12
-12
@@ -1,8 +1,8 @@
|
||||
#! /usr/bin/env python3
|
||||
"""
|
||||
Code generation lab, main file. Code Generation with Smart IRs.
|
||||
Evaluation and code generation labs, main file.
|
||||
Usage:
|
||||
python3 MiniCC.py <filename>
|
||||
python3 MiniCC.py --mode <mode> <filename>
|
||||
python3 MiniCC.py --help
|
||||
"""
|
||||
import traceback
|
||||
@@ -58,7 +58,7 @@ def valid_modes():
|
||||
return modes
|
||||
|
||||
try:
|
||||
import TP05c.OptimSSA # type: ignore[import]
|
||||
import TPoptim.OptimSSA # type: ignore[import]
|
||||
modes.append('codegen-optim')
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -146,9 +146,9 @@ def main(inputname, reg_alloc, mode,
|
||||
from TP04.BuildCFG import build_cfg # type: ignore[import]
|
||||
from Lib.CFG import CFG # type: ignore[import]
|
||||
code = build_cfg(function)
|
||||
assert(isinstance(code, CFG))
|
||||
assert (isinstance(code, CFG))
|
||||
if debug_graphs:
|
||||
s = "{}.{}.dot".format(basename, code.fdata._name)
|
||||
s = "{}.{}.dot".format(basename, code.fdata.get_name())
|
||||
print("CFG:", s)
|
||||
code.print_dot(s, view=True)
|
||||
if mode.value >= Mode.SSA.value:
|
||||
@@ -157,14 +157,14 @@ def main(inputname, reg_alloc, mode,
|
||||
|
||||
DF = enter_ssa(cast(CFG, code), basename, debug, ssa_graphs)
|
||||
if ssa_graphs:
|
||||
s = "{}.{}.ssa.dot".format(basename, code.fdata._name)
|
||||
s = "{}.{}.ssa.dot".format(basename, code.fdata.get_name())
|
||||
print("SSA:", s)
|
||||
code.print_dot(s, DF, True)
|
||||
if mode == Mode.OPTIM:
|
||||
from TP05c.OptimSSA import OptimSSA # type: ignore[import]
|
||||
from TPoptim.OptimSSA import OptimSSA # type: ignore[import]
|
||||
OptimSSA(cast(CFG, code), debug=debug)
|
||||
if ssa_graphs:
|
||||
s = "{}.{}.optimssa.dot".format(basename, code.fdata._name)
|
||||
s = "{}.{}.optimssa.dot".format(basename, code.fdata.get_name())
|
||||
print("SSA after optim:", s)
|
||||
code.print_dot(s, view=True)
|
||||
allocator = None
|
||||
@@ -178,7 +178,7 @@ def main(inputname, reg_alloc, mode,
|
||||
comment = "all-in-memory allocation"
|
||||
elif reg_alloc == "smart":
|
||||
liveness = None
|
||||
if mode == Mode.SSA:
|
||||
if mode.value >= Mode.SSA.value:
|
||||
from TP05.LivenessSSA import LivenessSSA # type: ignore[import]
|
||||
try:
|
||||
from Lib.CFG import CFG # type: ignore[import]
|
||||
@@ -205,15 +205,15 @@ liveness file not found for {}.".format(form))
|
||||
raise ValueError("Invalid allocation strategy:" + reg_alloc)
|
||||
if allocator:
|
||||
allocator.prepare()
|
||||
if mode == Mode.SSA:
|
||||
if mode.value >= Mode.SSA.value:
|
||||
from Lib.CFG import CFG # type: ignore[import]
|
||||
from TP05.SSA import exit_ssa # type: ignore[import]
|
||||
exit_ssa(cast(CFG, code))
|
||||
comment += " with SSA"
|
||||
if allocator:
|
||||
allocator.rewriteCode(code)
|
||||
if mode == Mode.SSA and ssa_graphs:
|
||||
s = "{}.{}.exitssa.dot".format(basename, code.fdata._name)
|
||||
if mode.value >= Mode.SSA.value and ssa_graphs:
|
||||
s = "{}.{}.exitssa.dot".format(basename, code.fdata.get_name())
|
||||
print("CFG after SSA:", s)
|
||||
code.print_dot(s, view=True)
|
||||
code.print_code(output, comment=comment)
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# MiniC Compiler
|
||||
LAB4 (simple code generation), MIF08 / CAP 2022-23
|
||||
|
||||
# Authors
|
||||
|
||||
YOUR NAME HERE
|
||||
|
||||
# Contents
|
||||
|
||||
TODO for STUDENTS : Say a bit about the code infrastructure ...
|
||||
|
||||
# Test design
|
||||
|
||||
TODO: explain your tests
|
||||
|
||||
# Design choices
|
||||
|
||||
TODO: explain your choices. How did you implement boolean not? Did you implement an extension?
|
||||
|
||||
# Known bugs
|
||||
|
||||
TODO: Bugs and limitations.
|
||||
|
||||
# Checklists
|
||||
|
||||
A check ([X]) means that the feature is implemented
|
||||
and *tested* with appropriate test cases.
|
||||
|
||||
## Code generation
|
||||
|
||||
- [ ] Number Atom
|
||||
- [ ] Boolean Atom
|
||||
- [ ] Id Atom
|
||||
- [ ] Additive expression
|
||||
- [ ] Multiplicative expression
|
||||
- [ ] UnaryMinus expression
|
||||
- [ ] Or expression
|
||||
- [ ] And expression
|
||||
- [ ] Equality expression
|
||||
- [ ] Relational expression (! many cases -> many tests)
|
||||
- [ ] Not expression
|
||||
|
||||
## Statements
|
||||
|
||||
- [ ] Prog, assignements
|
||||
- [ ] While
|
||||
- [ ] Cond Block
|
||||
- [ ] If
|
||||
- [ ] Nested ifs
|
||||
- [ ] Nested whiles
|
||||
|
||||
## Allocation
|
||||
|
||||
- [ ] Naive allocation
|
||||
- [ ] All in memory allocation
|
||||
- [ ] Massive tests of memory allocation
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
from Lib import RiscV
|
||||
from Lib.Operands import Temporary, Operand, S
|
||||
from Lib.Statement import Instruction
|
||||
from Lib.Allocator import Allocator
|
||||
from typing import List, Dict
|
||||
|
||||
|
||||
class AllInMemAllocator(Allocator):
|
||||
|
||||
def replace(self, old_instr: Instruction) -> List[Instruction]:
|
||||
"""Replace Temporary operands with the corresponding allocated
|
||||
memory location. FP points to the stack."""
|
||||
numreg = 1
|
||||
before: List[Instruction] = []
|
||||
after: List[Instruction] = []
|
||||
subst: Dict[Operand, Operand] = {}
|
||||
# TODO (Exercise 7): compute before,after,args.
|
||||
# TODO (Exercise 7): iterate over old_args, check which argument
|
||||
# TODO (Exercise 7): is a temporary (e.g. isinstance(..., Temporary)),
|
||||
# TODO (Exercise 7): and if so, generate ld/sd accordingly. Replace the
|
||||
# TODO (Exercise 7): temporary with S[1], S[2] or S[3] physical registers.
|
||||
new_instr = old_instr.substitute(subst)
|
||||
return before + [new_instr] + after
|
||||
|
||||
def prepare(self):
|
||||
"""Allocate all temporaries to memory.
|
||||
Invariants:
|
||||
- Expanded instructions can use s2 and s3
|
||||
(to store the values of temporaries before the actual instruction).
|
||||
"""
|
||||
self._fdata._pool.set_temp_allocation(
|
||||
{temp: self._fdata.fresh_offset()
|
||||
for temp in self._fdata._pool.get_all_temps()})
|
||||
@@ -0,0 +1,194 @@
|
||||
from typing import List, Tuple
|
||||
from MiniCVisitor import MiniCVisitor
|
||||
from MiniCParser import MiniCParser
|
||||
from Lib.LinearCode import LinearCode
|
||||
from Lib import RiscV
|
||||
from Lib.RiscV import Condition
|
||||
from Lib import Operands
|
||||
from antlr4.tree.Trees import Trees
|
||||
from Lib.Errors import MiniCInternalError, MiniCUnsupportedError
|
||||
|
||||
"""
|
||||
CAP, MIF08, three-address code generation + simple alloc
|
||||
This visitor constructs an object of type "LinearCode".
|
||||
"""
|
||||
|
||||
|
||||
class MiniCCodeGen3AVisitor(MiniCVisitor):
|
||||
|
||||
_current_function: LinearCode
|
||||
|
||||
def __init__(self, debug, parser):
|
||||
super().__init__()
|
||||
self._parser = parser
|
||||
self._debug = debug
|
||||
self._functions = []
|
||||
self._lastlabel = ""
|
||||
|
||||
def get_functions(self) -> List[LinearCode]:
|
||||
return self._functions
|
||||
|
||||
def printSymbolTable(self): # pragma: no cover
|
||||
print("--variables to temporaries map--")
|
||||
for keys, values in self._symbol_table.items():
|
||||
print(keys + '-->' + str(values))
|
||||
|
||||
# handle variable decl
|
||||
|
||||
def visitVarDecl(self, ctx) -> None:
|
||||
type_str = ctx.typee().getText()
|
||||
vars_l = self.visit(ctx.id_l())
|
||||
for name in vars_l:
|
||||
if name in self._symbol_table:
|
||||
raise MiniCInternalError(
|
||||
"Variable {} has already been declared".format(name))
|
||||
else:
|
||||
tmp = self._current_function.fdata.fresh_tmp()
|
||||
self._symbol_table[name] = tmp
|
||||
if type_str not in ("int", "bool"):
|
||||
raise MiniCUnsupportedError("Unsupported type " + type_str)
|
||||
# Initialization to 0 or False, both represented with 0
|
||||
self._current_function.add_instruction(
|
||||
RiscV.li(tmp, Operands.Immediate(0)))
|
||||
|
||||
def visitIdList(self, ctx) -> Operands.Temporary:
|
||||
t = self.visit(ctx.id_l())
|
||||
t.append(ctx.ID().getText())
|
||||
return t
|
||||
|
||||
def visitIdListBase(self, ctx) -> List[str]:
|
||||
return [ctx.ID().getText()]
|
||||
|
||||
# expressions
|
||||
|
||||
def visitParExpr(self, ctx) -> Operands.Temporary:
|
||||
return self.visit(ctx.expr())
|
||||
|
||||
def visitIntAtom(self, ctx) -> Operands.Temporary:
|
||||
val = Operands.Immediate(int(ctx.getText()))
|
||||
dest_temp = self._current_function.fdata.fresh_tmp()
|
||||
self._current_function.add_instruction(RiscV.li(dest_temp, val))
|
||||
return dest_temp
|
||||
|
||||
def visitFloatAtom(self, ctx) -> Operands.Temporary:
|
||||
raise MiniCUnsupportedError("float literal")
|
||||
|
||||
def visitBooleanAtom(self, ctx) -> Operands.Temporary:
|
||||
# true is 1 false is 0
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
|
||||
def visitIdAtom(self, ctx) -> Operands.Temporary:
|
||||
try:
|
||||
# get the temporary associated to id
|
||||
return self._symbol_table[ctx.getText()]
|
||||
except KeyError: # pragma: no cover
|
||||
raise MiniCInternalError(
|
||||
"Undefined variable {}, this should have failed to typecheck."
|
||||
.format(ctx.getText())
|
||||
)
|
||||
|
||||
def visitStringAtom(self, ctx) -> Operands.Temporary:
|
||||
raise MiniCUnsupportedError("string atom")
|
||||
|
||||
# now visit expressions
|
||||
|
||||
def visitAtomExpr(self, ctx) -> Operands.Temporary:
|
||||
return self.visit(ctx.atom())
|
||||
|
||||
def visitAdditiveExpr(self, ctx) -> Operands.Temporary:
|
||||
assert ctx.myop is not None
|
||||
raise NotImplementedError() # TODO (Exercise 2)
|
||||
|
||||
def visitOrExpr(self, ctx) -> Operands.Temporary:
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
|
||||
def visitAndExpr(self, ctx) -> Operands.Temporary:
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
|
||||
def visitEqualityExpr(self, ctx) -> Operands.Temporary:
|
||||
return self.visitRelationalExpr(ctx)
|
||||
|
||||
def visitRelationalExpr(self, ctx) -> Operands.Temporary:
|
||||
assert ctx.myop is not None
|
||||
c = Condition(ctx.myop.type)
|
||||
if self._debug:
|
||||
print("relational expression:")
|
||||
print(Trees.toStringTree(ctx, None, self._parser))
|
||||
print("Condition:", c)
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
|
||||
def visitMultiplicativeExpr(self, ctx) -> Operands.Temporary:
|
||||
assert ctx.myop is not None
|
||||
div_by_zero_lbl = self._current_function.fdata.get_label_div_by_zero()
|
||||
raise NotImplementedError() # TODO (Exercise 8)
|
||||
|
||||
def visitNotExpr(self, ctx) -> Operands.Temporary:
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
|
||||
def visitUnaryMinusExpr(self, ctx) -> Operands.Temporary:
|
||||
raise NotImplementedError("unaryminusexpr") # TODO (Exercise 2)
|
||||
|
||||
def visitProgRule(self, ctx) -> None:
|
||||
self.visitChildren(ctx)
|
||||
|
||||
def visitFuncDef(self, ctx) -> None:
|
||||
funcname = ctx.ID().getText()
|
||||
self._current_function = LinearCode(funcname)
|
||||
self._symbol_table = dict()
|
||||
|
||||
self.visit(ctx.vardecl_l())
|
||||
self.visit(ctx.block())
|
||||
self._current_function.add_comment("Return at end of function:")
|
||||
# This skeleton doesn't deal properly with functions, and
|
||||
# hardcodes a "return 0;" at the end of function. Generate
|
||||
# code for this "return 0;".
|
||||
self._current_function.add_instruction(
|
||||
RiscV.li(Operands.A0, Operands.Immediate(0)))
|
||||
self._functions.append(self._current_function)
|
||||
del self._current_function
|
||||
|
||||
def visitAssignStat(self, ctx) -> None:
|
||||
if self._debug:
|
||||
print("assign statement, rightexpression is:")
|
||||
print(Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||
expr_temp = self.visit(ctx.expr())
|
||||
name = ctx.ID().getText()
|
||||
self._current_function.add_instruction(RiscV.mv(self._symbol_table[name], expr_temp))
|
||||
|
||||
def visitIfStat(self, ctx) -> None:
|
||||
if self._debug:
|
||||
print("if statement")
|
||||
end_if_label = self._current_function.fdata.fresh_label("end_if")
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
self._current_function.add_label(end_if_label)
|
||||
|
||||
def visitWhileStat(self, ctx) -> None:
|
||||
if self._debug:
|
||||
print("while statement, condition is:")
|
||||
print(Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||
print("and block is:")
|
||||
print(Trees.toStringTree(ctx.stat_block(), None, self._parser))
|
||||
raise NotImplementedError() # TODO (Exercise 5)
|
||||
# visit statements
|
||||
|
||||
def visitPrintlnintStat(self, ctx) -> None:
|
||||
expr_loc = self.visit(ctx.expr())
|
||||
if self._debug:
|
||||
print("print_int statement, expression is:")
|
||||
print(Trees.toStringTree(ctx.expr(), None, self._parser))
|
||||
self._current_function.add_instruction_PRINTLN_INT(expr_loc)
|
||||
|
||||
def visitPrintlnboolStat(self, ctx) -> None:
|
||||
expr_loc = self.visit(ctx.expr())
|
||||
self._current_function.add_instruction_PRINTLN_INT(expr_loc)
|
||||
|
||||
def visitPrintlnfloatStat(self, ctx) -> None:
|
||||
raise MiniCUnsupportedError("Unsupported type float")
|
||||
|
||||
def visitPrintlnstringStat(self, ctx) -> None:
|
||||
raise MiniCUnsupportedError("Unsupported type string")
|
||||
|
||||
def visitStatList(self, ctx) -> None:
|
||||
for stat in ctx.stat():
|
||||
self._current_function.add_comment(Trees.toStringTree(stat, None, self._parser))
|
||||
self.visit(stat)
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
println_int(42);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 42
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x,y;
|
||||
x=4;
|
||||
y=12+x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int a,n;
|
||||
n=1;
|
||||
a=n+12;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int n;
|
||||
n=6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
println_int(43);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 43
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x;
|
||||
x = 42;
|
||||
println_int(x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 42
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x;
|
||||
x = 42;
|
||||
println_int(x + x);
|
||||
println_int(x + 1);
|
||||
println_int(1 + x);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 84
|
||||
// 43
|
||||
// 43
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x, y;
|
||||
x = 42;
|
||||
y = 66;
|
||||
println_int(x + y);
|
||||
x = 1;
|
||||
println_int(x + y);
|
||||
y = 2;
|
||||
println_int(x + y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 108
|
||||
// 67
|
||||
// 3
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x,y;
|
||||
|
||||
x = 9;
|
||||
if (x < 2)
|
||||
y=7;
|
||||
else
|
||||
y=12;
|
||||
x = y;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int n;
|
||||
bool a,b;
|
||||
n=1;
|
||||
a=true;
|
||||
b=(a==(n<6));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x,y;
|
||||
x=3;
|
||||
if (x<5) {
|
||||
y=x+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x,y,z;
|
||||
x=2;
|
||||
if (x<3) {
|
||||
y=7;
|
||||
} else {
|
||||
y=8;
|
||||
}
|
||||
z=y+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int x,y,z,u;
|
||||
x=3;
|
||||
if (x < 4) {
|
||||
z=4;
|
||||
}
|
||||
else if ( x < 5) {
|
||||
z=5;
|
||||
}
|
||||
else {
|
||||
z=6 ;
|
||||
}
|
||||
u=z+1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
bool b;
|
||||
b = false;
|
||||
println_bool(b);
|
||||
b = true;
|
||||
println_bool(b);
|
||||
println_bool(true);
|
||||
println_bool(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 0
|
||||
// 1
|
||||
// 1
|
||||
// 0
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
println_bool(3 >= 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 1
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
if (10 == 10) {
|
||||
println_int(12);
|
||||
} else if (10 == 10) {
|
||||
println_int(15);
|
||||
} else {
|
||||
println_int(13);
|
||||
}
|
||||
println_int(14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 12
|
||||
// 14
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int n;
|
||||
|
||||
n = 9;
|
||||
while (n > 0) {
|
||||
n = n-1 ;
|
||||
println_int(n) ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 8
|
||||
// 7
|
||||
// 6
|
||||
// 5
|
||||
// 4
|
||||
// 3
|
||||
// 2
|
||||
// 1
|
||||
// 0
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "printlib.h"
|
||||
|
||||
int main() {
|
||||
|
||||
int a,n;
|
||||
|
||||
n = 1;
|
||||
a = 7;
|
||||
while (n < a) {
|
||||
n = n+1;
|
||||
}
|
||||
println_int(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EXPECTED
|
||||
// 7
|
||||
@@ -0,0 +1,9 @@
|
||||
int main() {
|
||||
float f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SKIP TEST EXPECTED
|
||||
// EXITCODE 5
|
||||
// EXPECTED
|
||||
// Unsupported type float
|
||||
@@ -0,0 +1,9 @@
|
||||
int main() {
|
||||
println_float(0.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SKIP TEST EXPECTED
|
||||
// EXITCODE 5
|
||||
// EXPECTED
|
||||
// Unsupported type float
|
||||
@@ -0,0 +1,9 @@
|
||||
int main() {
|
||||
println_string("Hello");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SKIP TEST EXPECTED
|
||||
// EXITCODE 5
|
||||
// EXPECTED
|
||||
// Unsupported type string
|
||||
@@ -0,0 +1,9 @@
|
||||
int main() {
|
||||
string b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SKIP TEST EXPECTED
|
||||
// EXITCODE 5
|
||||
// EXPECTED
|
||||
// Unsupported type string
|
||||
@@ -0,0 +1 @@
|
||||
Add your own tests in this directory.
|
||||
Binary file not shown.
@@ -0,0 +1,241 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
import glob
|
||||
import subprocess
|
||||
import re
|
||||
from test_expect_pragma import (
|
||||
TestExpectPragmas, cat, testinfo, env_str_variable
|
||||
)
|
||||
|
||||
"""
|
||||
Usage:
|
||||
python3 test_codegen.py
|
||||
(or make test)
|
||||
"""
|
||||
|
||||
"""
|
||||
MIF08 and CAP, 2019
|
||||
Unit test infrastructure for testing code generation:
|
||||
1) compare the actual output to the expected one (in comments)
|
||||
2) compare the actual output to the one obtained by simulation
|
||||
3) for different allocation algorithms
|
||||
"""
|
||||
|
||||
MINICC_OPTS = []
|
||||
if "MINICC_OPTS" in os.environ and os.environ["MINICC_OPTS"]:
|
||||
MINICC_OPTS = os.environ["MINICC_OPTS"].split()
|
||||
else:
|
||||
MINICC_OPTS = ["--mode=codegen-cfg"]
|
||||
|
||||
DISABLE_TYPECHECK = "--disable-typecheck" in MINICC_OPTS
|
||||
|
||||
HERE = os.path.dirname(os.path.realpath(__file__))
|
||||
if HERE == os.path.realpath('.'):
|
||||
HERE = '.'
|
||||
TEST_DIR = HERE
|
||||
IMPLEM_DIR = HERE
|
||||
MINIC_COMPILE = os.path.join(IMPLEM_DIR, 'MiniCC.py')
|
||||
|
||||
ALL_FILES = glob.glob(os.path.join(TEST_DIR, 'TP04/tests/**/[a-zA-Z]*.c'), recursive=True)
|
||||
|
||||
ALLOC_FILES = glob.glob(os.path.join(HERE, 'TP05/tests/**/*.c'), recursive=True)
|
||||
|
||||
ASM = 'riscv64-unknown-elf-gcc'
|
||||
SIMU = 'spike'
|
||||
|
||||
SKIP_NOT_IMPLEMENTED = False
|
||||
if 'SKIP_NOT_IMPLEMENTED' in os.environ:
|
||||
SKIP_NOT_IMPLEMENTED = True
|
||||
|
||||
if 'TEST_FILES' in os.environ:
|
||||
ALL_FILES = glob.glob(os.environ['TEST_FILES'], recursive=True)
|
||||
|
||||
MINIC_EVAL = os.path.join(
|
||||
HERE, '..', '..', 'TP03', 'MiniC-type-interpret', 'Main.py')
|
||||
|
||||
# if 'COMPIL_MINIC_EVAL' in os.environ:
|
||||
# MINIC_EVAL = os.environ['COMPIL_MINIC_EVAL']
|
||||
# else:
|
||||
# MINIC_EVAL = os.path.join(
|
||||
# HERE, '..', '..', 'TP03', 'MiniC-type-interpret', 'Main.py')
|
||||
|
||||
# Avoid duplicates
|
||||
ALL_IN_MEM_FILES = list(set(ALL_FILES) | set(ALLOC_FILES))
|
||||
ALL_IN_MEM_FILES.sort()
|
||||
ALL_FILES = list(set(ALL_FILES))
|
||||
ALL_FILES.sort()
|
||||
|
||||
if 'TEST_FILES' in os.environ:
|
||||
ALLOC_FILES = ALL_FILES
|
||||
ALL_IN_MEM_FILES = ALL_FILES
|
||||
|
||||
|
||||
class TestCodeGen(TestExpectPragmas):
|
||||
# Not in test_expect_pragma to get assertion rewritting
|
||||
def assert_equal(self, actual, expected):
|
||||
if DISABLE_TYPECHECK and expected.exitcode != 0:
|
||||
# Test should fail at typecheck, and we don't do
|
||||
# typechecking => nothing to check.
|
||||
pytest.skip("Test that doesn't typecheck with --disable-typecheck")
|
||||
if expected.output is not None and actual.output is not None:
|
||||
assert actual.output == expected.output, \
|
||||
"Output of the program is incorrect."
|
||||
assert actual.exitcode == expected.exitcode, \
|
||||
"Exit code of the compiler is incorrect"
|
||||
assert actual.execcode == expected.execcode, \
|
||||
"Exit code of the execution (spike) is incorrect"
|
||||
|
||||
def naive_alloc(self, file, info):
|
||||
return self.compile_and_simulate(file, info, reg_alloc='naive')
|
||||
|
||||
def all_in_mem(self, file, info):
|
||||
return self.compile_and_simulate(file, info, reg_alloc='all-in-mem')
|
||||
|
||||
def smart_alloc(self, file, info):
|
||||
return self.compile_and_simulate(file, info, reg_alloc='smart')
|
||||
|
||||
def run_with_gcc(self, file, info):
|
||||
return self.compile_and_simulate(file, info, reg_alloc='gcc', use_gcc=True)
|
||||
|
||||
def compile_with_gcc(self, file, output_name):
|
||||
print("Compiling with GCC...")
|
||||
result = self.run_command(
|
||||
[ASM, '-S', '-I./',
|
||||
'--output=' + output_name,
|
||||
'-Werror',
|
||||
'-Wno-div-by-zero', # We need to accept 1/0 at compile-time
|
||||
file])
|
||||
print(result.output)
|
||||
print("Compiling with GCC... DONE")
|
||||
return result
|
||||
|
||||
def compile_with_ours(self, file, output_name, reg_alloc):
|
||||
print("Compiling ...")
|
||||
self.remove(output_name)
|
||||
alloc_opt = '--reg-alloc=' + reg_alloc
|
||||
out_opt = '--output=' + output_name
|
||||
cmd = [sys.executable, MINIC_COMPILE,
|
||||
alloc_opt, out_opt]
|
||||
cmd += MINICC_OPTS
|
||||
cmd += [file]
|
||||
result = self.run_command(cmd)
|
||||
print(' '.join(cmd))
|
||||
print("Exited with status:", result.exitcode)
|
||||
print(result.output)
|
||||
if result.exitcode == 4:
|
||||
if "AllocationError" in result.output:
|
||||
if reg_alloc == 'naive':
|
||||
pytest.skip("Too big for the naive allocator")
|
||||
elif reg_alloc == 'all-in-mem':
|
||||
pytest.skip("Too big for the all in memory allocator")
|
||||
else:
|
||||
raise Exception("AllocationError should only happen "
|
||||
"for reg_alloc='naive' or reg_alloc='all_in_mem'")
|
||||
elif ("NotImplementedError" in result.output and
|
||||
SKIP_NOT_IMPLEMENTED):
|
||||
pytest.skip("Feature not implemented in this compiler")
|
||||
if result.exitcode != 0:
|
||||
# May either be a failing test or a test with expected
|
||||
# compilation failure (bad type, ...). Let the caller
|
||||
# do the assertion and decide:
|
||||
return result
|
||||
assert(os.path.isfile(output_name))
|
||||
print("Compiling ... OK")
|
||||
return result
|
||||
|
||||
def link_and_run(self, output_name, exec_name, info):
|
||||
self.remove(exec_name)
|
||||
cmd = [
|
||||
ASM, output_name, '../TP01/riscv/libprint.s',
|
||||
'-o', exec_name
|
||||
] + info.linkargs
|
||||
print(info)
|
||||
print("Assembling and linking " + output_name + ": " + ' '.join(cmd))
|
||||
try:
|
||||
subprocess.check_output(cmd, timeout=60, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print("Assembling failed:\n")
|
||||
print(e.output.decode())
|
||||
print("Assembler code below:\n")
|
||||
cat(output_name)
|
||||
pytest.fail()
|
||||
assert (os.path.isfile(exec_name))
|
||||
sys.stdout.write("Assembling and linking ... OK\n")
|
||||
try:
|
||||
result = self.run_command(
|
||||
[SIMU,
|
||||
'-m100', # Limit memory usage to 100MB, more than enough and
|
||||
# avoids crashing on a VM with <= 2GB RAM for example.
|
||||
'pk',
|
||||
exec_name],
|
||||
scope="runtime")
|
||||
output = re.sub(r'bbl loader\r?\n', '', result.output)
|
||||
return testinfo(execcode=result.execcode,
|
||||
exitcode=result.exitcode,
|
||||
output=output,
|
||||
linkargs=[],
|
||||
skip_test_expected=False)
|
||||
except subprocess.TimeoutExpired:
|
||||
pytest.fail("Timeout executing program. Infinite loop in generated code?")
|
||||
|
||||
def compile_and_simulate(self, file, info, reg_alloc, use_gcc=False):
|
||||
basename, _ = os.path.splitext(file)
|
||||
output_name = basename + '-' + reg_alloc + '.s'
|
||||
if use_gcc:
|
||||
result = self.compile_with_gcc(file, output_name)
|
||||
if result.exitcode != 0:
|
||||
# We don't consider the exact exitcode, and ignore the
|
||||
# output (our error messages may be different from
|
||||
# GCC's)
|
||||
return result._replace(exitcode=1,
|
||||
output=None)
|
||||
else:
|
||||
result = self.compile_with_ours(file, output_name, reg_alloc)
|
||||
if reg_alloc == 'none' or info.exitcode != 0 or result.exitcode != 0:
|
||||
# Either the result is meaningless, or we already failed
|
||||
# and don't need to go any further:
|
||||
return result
|
||||
# Only executable code past this point.
|
||||
exec_name = basename + '-' + reg_alloc + '.riscv'
|
||||
return self.link_and_run(output_name, exec_name, info)
|
||||
|
||||
@pytest.mark.parametrize('filename', ALL_FILES)
|
||||
def test_expect(self, filename):
|
||||
"""Test the EXPECTED annotations in test files by launching the
|
||||
program with GCC."""
|
||||
expect = self.get_expect(filename)
|
||||
if expect.skip_test_expected:
|
||||
pytest.skip("Skipping test because it contains SKIP TEST EXPECTED")
|
||||
if expect.exitcode != 0:
|
||||
# GCC is more permissive than us, so trying to compile an
|
||||
# incorrect program would bring us no information (it may
|
||||
# compile, or fail with a different message...)
|
||||
pytest.skip("Not testing the expected value for tests expecting exitcode!=0")
|
||||
gcc_result = self.run_with_gcc(filename, expect)
|
||||
self.assert_equal(gcc_result, expect)
|
||||
|
||||
@pytest.mark.parametrize('filename', ALL_FILES)
|
||||
def test_naive_alloc(self, filename):
|
||||
expect = self.get_expect(filename)
|
||||
naive = self.naive_alloc(filename, expect)
|
||||
self.assert_equal(naive, expect)
|
||||
|
||||
@pytest.mark.parametrize('filename', ALL_IN_MEM_FILES)
|
||||
def test_alloc_mem(self, filename):
|
||||
expect = self.get_expect(filename)
|
||||
actual = self.all_in_mem(filename, expect)
|
||||
self.assert_equal(actual, expect)
|
||||
|
||||
@pytest.mark.parametrize('filename', ALLOC_FILES)
|
||||
def test_smart_alloc(self, filename):
|
||||
"""Generate code with smart allocation."""
|
||||
expect = self.get_expect(filename)
|
||||
actual = self.smart_alloc(filename, expect)
|
||||
self.assert_equal(actual, expect)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main(sys.argv)
|
||||
+6
-2
@@ -60,8 +60,12 @@ _Academic first semester 2022-2023_
|
||||
|
||||
# Week 5:
|
||||
|
||||
- :hammer: Lab 3: Wednesday 5/10/2021, 10h15-12h15. Rooms A1 (Nicolas Chappe) & B2 (Rémi Di Guardia)
|
||||
- :hammer: Lab 3: Wednesday 05/10/2021, 10h15-12h15. Rooms A1 (Nicolas Chappe) & B2 (Rémi Di Guardia)
|
||||
|
||||
- :book: 5th Course session: Friday 7/10/2022, 10:15. Amphi B (Gabriel Radanne)
|
||||
* Syntax directed code generation [TP04](MiniC/TP04/tp4.pdf).
|
||||
* Code in [MiniC/TP04/](MiniC/TP04/).
|
||||
* Documentation [here](docs/index.html).
|
||||
|
||||
- :book: 5th Course session: Friday 70/10/2022, 10:15. Amphi B (Gabriel Radanne)
|
||||
|
||||
* CFG [slides in english](course/capmif_cours06_irs.pdf).
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
.globl println_int
|
||||
println_int:
|
||||
.globl println_bool
|
||||
println_bool:
|
||||
addi sp,sp,-8
|
||||
sd ra, 0(sp)
|
||||
call print_int
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Sphinx build info version 1
|
||||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||
config: 5e82a25c893d31ec6bcd8ba9118dfc91
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
@@ -0,0 +1,180 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Allocator — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.Allocator</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.Allocator</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">This file defines the base class :py:class:`Allocator`</span>
|
||||
<span class="sd">and the naïve implementation :py:class:`NaiveAllocator`.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="n">Temporary</span><span class="p">,</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">,</span> <span class="n">GP_REGS</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="n">Instruction</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">AllocationError</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.FunctionData</span> <span class="kn">import</span> <span class="n">FunctionData</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Allocator"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.Allocator">[docs]</a><span class="k">class</span> <span class="nc">Allocator</span><span class="p">():</span>
|
||||
<span class="sd">"""General base class for Naive, AllInMem and Smart Allocators.</span>
|
||||
<span class="sd"> Replace all temporaries in the code with actual data locations.</span>
|
||||
|
||||
<span class="sd"> Allocation is done in two steps:</span>
|
||||
|
||||
<span class="sd"> - First, :py:meth:`prepare` is responsible for calling</span>
|
||||
<span class="sd"> :py:meth:`Lib.Operands.TemporaryPool.set_temp_allocation`</span>
|
||||
<span class="sd"> with a mapping from temporaries to where they should actually be stored</span>
|
||||
<span class="sd"> (in registers or in memory).</span>
|
||||
<span class="sd"> - Then, :py:meth:`replace` is called for each instruction in order to</span>
|
||||
<span class="sd"> replace the temporary operands with the previously assigned locations</span>
|
||||
<span class="sd"> (and possibly add some instructions before or after).</span>
|
||||
<span class="sd"> Concretely, it returns a list of instructions that should replace the original</span>
|
||||
<span class="sd"> instruction. The actual iteration over all the instructions is handled transparently</span>
|
||||
<span class="sd"> by :py:meth:`Lib.LinearCode.LinearCode.iter_statements`.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_fdata</span><span class="p">:</span> <span class="n">FunctionData</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fdata</span><span class="p">:</span> <span class="n">FunctionData</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_fdata</span> <span class="o">=</span> <span class="n">fdata</span>
|
||||
|
||||
<div class="viewcode-block" id="Allocator.prepare"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.Allocator.prepare">[docs]</a> <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Allocator.replace"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.Allocator.replace">[docs]</a> <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">instr</span><span class="p">:</span> <span class="n">Instruction</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Instruction</span><span class="p">]:</span>
|
||||
<span class="sd">"""Transform an instruction with temporaries into a list of instructions."""</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="n">instr</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Allocator.rewriteCode"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.Allocator.rewriteCode">[docs]</a> <span class="k">def</span> <span class="nf">rewriteCode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">listcode</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Modify the code to replace temporaries with</span>
|
||||
<span class="sd"> registers or memory locations.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">listcode</span><span class="o">.</span><span class="n">iter_statements</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">replace</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="NaiveAllocator"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.NaiveAllocator">[docs]</a><span class="k">class</span> <span class="nc">NaiveAllocator</span><span class="p">(</span><span class="n">Allocator</span><span class="p">):</span>
|
||||
<span class="sd">"""Naive Allocator: try to assign a register to each temporary,</span>
|
||||
<span class="sd"> fails if there are more temporaries than registers.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<div class="viewcode-block" id="NaiveAllocator.replace"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.NaiveAllocator.replace">[docs]</a> <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">old_instr</span><span class="p">:</span> <span class="n">Instruction</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Instruction</span><span class="p">]:</span>
|
||||
<span class="sd">"""Replace Temporary operands with the corresponding allocated Register."""</span>
|
||||
<span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">old_instr</span><span class="o">.</span><span class="n">args</span><span class="p">():</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
||||
<span class="n">subst</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">=</span> <span class="n">arg</span><span class="o">.</span><span class="n">get_alloced_loc</span><span class="p">()</span>
|
||||
<span class="n">new_instr</span> <span class="o">=</span> <span class="n">old_instr</span><span class="o">.</span><span class="n">substitute</span><span class="p">(</span><span class="n">subst</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="n">new_instr</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="NaiveAllocator.prepare"><a class="viewcode-back" href="../../api/Lib.Allocator.html#Lib.Allocator.NaiveAllocator.prepare">[docs]</a> <span class="k">def</span> <span class="nf">prepare</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Allocate all temporaries to registers.</span>
|
||||
<span class="sd"> Fail if there are too many temporaries."""</span>
|
||||
<span class="n">regs</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">GP_REGS</span><span class="p">)</span> <span class="c1"># Get a writable copy</span>
|
||||
<span class="n">temp_allocation</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Temporary</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">]</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
<span class="k">for</span> <span class="n">tmp</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fdata</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">get_all_temps</span><span class="p">():</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">reg</span> <span class="o">=</span> <span class="n">regs</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="n">AllocationError</span><span class="p">(</span>
|
||||
<span class="s2">"Too many temporaries (</span><span class="si">{}</span><span class="s2">) for the naive allocation, sorry."</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_fdata</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">get_all_temps</span><span class="p">())))</span>
|
||||
<span class="n">temp_allocation</span><span class="p">[</span><span class="n">tmp</span><span class="p">]</span> <span class="o">=</span> <span class="n">reg</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_fdata</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">set_temp_allocation</span><span class="p">(</span><span class="n">temp_allocation</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,121 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Errors — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.Errors</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.Errors</h1><div class="highlight"><pre>
|
||||
<div class="viewcode-block" id="MiniCRuntimeError"><a class="viewcode-back" href="../../api/Lib.Errors.html#Lib.Errors.MiniCRuntimeError">[docs]</a><span></span><span class="k">class</span> <span class="nc">MiniCRuntimeError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="MiniCInternalError"><a class="viewcode-back" href="../../api/Lib.Errors.html#Lib.Errors.MiniCInternalError">[docs]</a><span class="k">class</span> <span class="nc">MiniCInternalError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="MiniCUnsupportedError"><a class="viewcode-back" href="../../api/Lib.Errors.html#Lib.Errors.MiniCUnsupportedError">[docs]</a><span class="k">class</span> <span class="nc">MiniCUnsupportedError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="MiniCTypeError"><a class="viewcode-back" href="../../api/Lib.Errors.html#Lib.Errors.MiniCTypeError">[docs]</a><span class="k">class</span> <span class="nc">MiniCTypeError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="AllocationError"><a class="viewcode-back" href="../../api/Lib.Errors.html#Lib.Errors.AllocationError">[docs]</a><span class="k">class</span> <span class="nc">AllocationError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,286 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.FunctionData — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.FunctionData</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.FunctionData</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">This file defines the base class :py:class:`FunctionData`,</span>
|
||||
<span class="sd">containing metadata on a RiscV function, as well as utility</span>
|
||||
<span class="sd">functions common to the different intermediate representations.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="p">(</span><span class="n">List</span><span class="p">,</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">TypeVar</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">AllocationError</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">Offset</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">,</span> <span class="n">TemporaryPool</span><span class="p">,</span>
|
||||
<span class="n">S</span><span class="p">,</span> <span class="n">T</span><span class="p">,</span> <span class="n">FP</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="p">(</span><span class="n">Statement</span><span class="p">,</span> <span class="n">Instruction</span><span class="p">,</span> <span class="n">Label</span><span class="p">,</span> <span class="n">Comment</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="FunctionData"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData">[docs]</a><span class="k">class</span> <span class="nc">FunctionData</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Stores some metadata on a RiscV function:</span>
|
||||
<span class="sd"> name of the function, label names, temporary variables</span>
|
||||
<span class="sd"> (using :py:class:`Lib.Operands.TemporaryPool`),</span>
|
||||
<span class="sd"> and div_by_zero label.</span>
|
||||
|
||||
<span class="sd"> This class is usually used indirectly through the</span>
|
||||
<span class="sd"> different intermediate representations we work with,</span>
|
||||
<span class="sd"> such as :py:attr:`Lib.LinearCode.LinearCode.fdata`.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_nblabel</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">_dec</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">_pool</span><span class="p">:</span> <span class="n">TemporaryPool</span>
|
||||
<span class="n">_name</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">_label_div_by_zero</span><span class="p">:</span> <span class="n">Label</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_nblabel</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_dec</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pool</span> <span class="o">=</span> <span class="n">TemporaryPool</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_label_div_by_zero</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fresh_label</span><span class="p">(</span><span class="s2">"div_by_zero"</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.get_name"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.get_name">[docs]</a> <span class="k">def</span> <span class="nf">get_name</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="sd">"""Return the name of the function."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.fresh_tmp"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.fresh_tmp">[docs]</a> <span class="k">def</span> <span class="nf">fresh_tmp</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Temporary</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Return a new fresh Temporary,</span>
|
||||
<span class="sd"> which is added to the pool.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">fresh_tmp</span><span class="p">()</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.fresh_offset"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.fresh_offset">[docs]</a> <span class="k">def</span> <span class="nf">fresh_offset</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Offset</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Return a new offset in the memory stack.</span>
|
||||
<span class="sd"> Offsets are decreasing relative to FP.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_dec</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dec</span> <span class="o">+</span> <span class="mi">1</span>
|
||||
<span class="c1"># For ld or sd, an offset on 12 signed bits is expected</span>
|
||||
<span class="c1"># Raise an error if the offset is too big</span>
|
||||
<span class="k">if</span> <span class="o">-</span><span class="mi">8</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dec</span> <span class="o"><</span> <span class="o">-</span> <span class="mi">2</span> <span class="o">**</span> <span class="mi">11</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="n">AllocationError</span><span class="p">(</span>
|
||||
<span class="s2">"Offset given by the allocation too big to be manipulated (</span><span class="si">{}</span><span class="s2">), sorry."</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dec</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="n">Offset</span><span class="p">(</span><span class="n">FP</span><span class="p">,</span> <span class="o">-</span><span class="mi">8</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dec</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.get_offset"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.get_offset">[docs]</a> <span class="k">def</span> <span class="nf">get_offset</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Return the current offset in the memory stack.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dec</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_fresh_label_name</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Return a new unique label name based on the given string.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_nblabel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_nblabel</span> <span class="o">+</span> <span class="mi">1</span>
|
||||
<span class="k">return</span> <span class="n">name</span> <span class="o">+</span> <span class="s2">"_"</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_nblabel</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"_"</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.fresh_label"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.fresh_label">[docs]</a> <span class="k">def</span> <span class="nf">fresh_label</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">-></span> <span class="n">Label</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Return a new label, with a unique name based on the given string.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="n">Label</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_fresh_label_name</span><span class="p">(</span><span class="n">name</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FunctionData.get_label_div_by_zero"><a class="viewcode-back" href="../../api/Lib.FunctionData.html#Lib.FunctionData.FunctionData.get_label_div_by_zero">[docs]</a> <span class="k">def</span> <span class="nf">get_label_div_by_zero</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Label</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_label_div_by_zero</span></div></div>
|
||||
|
||||
|
||||
<span class="n">_T</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s2">"_T"</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="n">Statement</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_iter_statements</span><span class="p">(</span>
|
||||
<span class="n">listIns</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">_T</span><span class="p">],</span> <span class="n">f</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[</span><span class="n">_T</span><span class="p">],</span> <span class="n">List</span><span class="p">[</span><span class="n">_T</span><span class="p">]])</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">_T</span> <span class="o">|</span> <span class="n">Comment</span><span class="p">]:</span>
|
||||
<span class="sd">"""Iterate over instructions.</span>
|
||||
<span class="sd"> For each real instruction i (not label or comment), replace it</span>
|
||||
<span class="sd"> with the list of instructions given by f(i).</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">newListIns</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">_T</span> <span class="o">|</span> <span class="n">Comment</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">old_i</span> <span class="ow">in</span> <span class="n">listIns</span><span class="p">:</span>
|
||||
<span class="c1"># Do nothing for label or comment</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">old_i</span><span class="p">,</span> <span class="n">Instruction</span><span class="p">):</span>
|
||||
<span class="n">newListIns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">old_i</span><span class="p">)</span>
|
||||
<span class="k">continue</span>
|
||||
<span class="n">new_i_list</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="n">old_i</span><span class="p">)</span>
|
||||
<span class="c1"># Otherwise, replace the instruction by the list</span>
|
||||
<span class="c1"># returned by f, with comments giving the replacement</span>
|
||||
<span class="n">newListIns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Comment</span><span class="p">(</span><span class="s2">"Replaced "</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">old_i</span><span class="p">)))</span>
|
||||
<span class="n">newListIns</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">new_i_list</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">newListIns</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_print_code</span><span class="p">(</span><span class="n">listIns</span><span class="p">:</span> <span class="n">List</span><span class="p">,</span> <span class="n">fdata</span><span class="p">:</span> <span class="n">FunctionData</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span>
|
||||
<span class="n">init_label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">fin_label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">fin_div0</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">comment</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Please use print_code from LinearCode or CFG, not directly this one.</span>
|
||||
|
||||
<span class="sd"> Print the instructions from listIns, forming fdata, on output.</span>
|
||||
<span class="sd"> If init_label is given, add an initial jump to it before the generated code.</span>
|
||||
<span class="sd"> If fin_label is given, add it after the generated code.</span>
|
||||
<span class="sd"> If fin_div0 is given equal to true, add the code for returning an</span>
|
||||
<span class="sd"> error when dividing by 0, at the very end.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># compute size for the local stack - do not forget to align by 16</span>
|
||||
<span class="n">fo</span> <span class="o">=</span> <span class="n">fdata</span><span class="o">.</span><span class="n">get_offset</span><span class="p">()</span> <span class="c1"># allocate enough memory for stack</span>
|
||||
<span class="c1"># BEGIN CUT</span>
|
||||
<span class="c1"># Room for S_i (except S_0 which is fp) and T_i backup</span>
|
||||
<span class="n">fo</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="n">T</span><span class="p">)</span>
|
||||
<span class="c1"># END CUT</span>
|
||||
<span class="n">cardoffset</span> <span class="o">=</span> <span class="mi">8</span> <span class="o">*</span> <span class="p">(</span><span class="n">fo</span> <span class="o">+</span> <span class="p">(</span><span class="mi">0</span> <span class="k">if</span> <span class="n">fo</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="mi">16</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span>
|
||||
<span class="s2">"##Automatically generated RISCV code, MIF08 & CAP</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">comment</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"##</span><span class="si">{}</span><span class="s2"> version</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">comment</span><span class="p">))</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"</span><span class="se">\n\n</span><span class="s2">##prelude</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="c1"># We put an li t0, cardoffset in case it is greater than 2**11</span>
|
||||
<span class="c1"># We use t0 because it is caller-saved</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="s2"> .text</span>
|
||||
<span class="s2"> .globl </span><span class="si">{0}</span><span class="s2"></span>
|
||||
<span class="si">{0}</span><span class="s2">:</span>
|
||||
<span class="s2"> li t0, </span><span class="si">{1}</span><span class="s2"></span>
|
||||
<span class="s2"> sub sp, sp, t0</span>
|
||||
<span class="s2"> sd ra, 0(sp)</span>
|
||||
<span class="s2"> sd fp, 8(sp)</span>
|
||||
<span class="s2"> add fp, sp, t0</span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fdata</span><span class="o">.</span><span class="n">get_name</span><span class="p">(),</span> <span class="n">cardoffset</span><span class="p">))</span>
|
||||
<span class="c1"># Stack in RiscV is managed with SP</span>
|
||||
<span class="k">if</span> <span class="n">init_label</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="c1"># Add a jump to init_label before the generated code.</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="s2"> j </span><span class="si">{0}</span><span class="s2"></span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">init_label</span><span class="p">))</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"</span><span class="se">\n\n</span><span class="s2">##Generated Code</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="c1"># Generated code</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">listIns</span><span class="p">:</span>
|
||||
<span class="n">i</span><span class="o">.</span><span class="n">printIns</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"</span><span class="se">\n\n</span><span class="s2">##postlude</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">fin_label</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="c1"># Add fin_label after the generated code.</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="si">{0}</span><span class="s2">:</span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fin_label</span><span class="p">))</span>
|
||||
<span class="c1"># We put an li t0, cardoffset in case it is greater than 2**11</span>
|
||||
<span class="c1"># We use t0 because it is caller-saved</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="s2"> ld ra, 0(sp)</span>
|
||||
<span class="s2"> ld fp, 8(sp)</span>
|
||||
<span class="s2"> li t0, </span><span class="si">{0}</span><span class="s2"></span>
|
||||
<span class="s2"> add sp, sp, t0</span>
|
||||
<span class="s2"> ret</span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">cardoffset</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">fin_div0</span><span class="p">:</span>
|
||||
<span class="c1"># Add code for division by 0 at the end.</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="si">{0}</span><span class="s2">:</span>
|
||||
<span class="s2"> la a0, </span><span class="si">{0}</span><span class="s2">_msg</span>
|
||||
<span class="s2"> call println_string</span>
|
||||
<span class="s2"> li a0, 1</span>
|
||||
<span class="s2"> call exit</span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fdata</span><span class="o">.</span><span class="n">_label_div_by_zero</span><span class="p">))</span>
|
||||
<span class="c1"># Add the data for the message of the division by 0</span>
|
||||
<span class="n">output</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"""</span>
|
||||
<span class="si">{0}</span><span class="s2">_msg: .string "Division by 0"</span>
|
||||
<span class="s2">"""</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">fdata</span><span class="o">.</span><span class="n">_label_div_by_zero</span><span class="p">))</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,204 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.LinearCode — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.LinearCode</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.LinearCode</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">CAP, CodeGeneration, LinearCode API</span>
|
||||
<span class="sd">Classes for a RiscV linear code.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="p">(</span><span class="n">A0</span><span class="p">,</span> <span class="n">Function</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">Instru3A</span><span class="p">,</span> <span class="n">AbsoluteJump</span><span class="p">,</span> <span class="n">ConditionalJump</span><span class="p">,</span> <span class="n">Comment</span><span class="p">,</span> <span class="n">Label</span>
|
||||
<span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.RiscV</span> <span class="kn">import</span> <span class="p">(</span><span class="n">mv</span><span class="p">,</span> <span class="n">call</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.FunctionData</span> <span class="kn">import</span> <span class="p">(</span><span class="n">FunctionData</span><span class="p">,</span> <span class="n">_iter_statements</span><span class="p">,</span> <span class="n">_print_code</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="n">CodeStatement</span> <span class="o">=</span> <span class="n">Comment</span> <span class="o">|</span> <span class="n">Label</span> <span class="o">|</span> <span class="n">Instru3A</span> <span class="o">|</span> <span class="n">AbsoluteJump</span> <span class="o">|</span> <span class="n">ConditionalJump</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="LinearCode"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode">[docs]</a><span class="k">class</span> <span class="nc">LinearCode</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Representation of a RiscV program as a list of instructions.</span>
|
||||
|
||||
<span class="sd"> :py:meth:`add_instruction` is repeatedly called in the codegen visitor</span>
|
||||
<span class="sd"> to build a complete list of RiscV instructions for the source program.</span>
|
||||
|
||||
<span class="sd"> The :py:attr:`fdata` member variable contains some meta-information</span>
|
||||
<span class="sd"> on the program, for instance to allocate a new temporary.</span>
|
||||
<span class="sd"> See :py:class:`Lib.FunctionData.FunctionData`.</span>
|
||||
|
||||
<span class="sd"> For debugging purposes, :py:meth:`print_code` allows to print</span>
|
||||
<span class="sd"> the RiscV program to a file.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> The :py:attr:`fdata` member variable contains some meta-information</span>
|
||||
<span class="sd"> on the program, for instance to allocate a new temporary.</span>
|
||||
<span class="sd"> See :py:class:`Lib.FunctionData.FunctionData`.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">fdata</span><span class="p">:</span> <span class="n">FunctionData</span>
|
||||
|
||||
<span class="n">_listIns</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">CodeStatement</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">fdata</span> <span class="o">=</span> <span class="n">FunctionData</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.add_instruction"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.add_instruction">[docs]</a> <span class="k">def</span> <span class="nf">add_instruction</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">:</span> <span class="n">CodeStatement</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Utility function to add an instruction in the program.</span>
|
||||
|
||||
<span class="sd"> See also :py:mod:`Lib.RiscV` to generate relevant instructions.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">i</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.iter_statements"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.iter_statements">[docs]</a> <span class="k">def</span> <span class="nf">iter_statements</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Iterate over instructions.</span>
|
||||
<span class="sd"> For each real instruction (not label or comment), call f,</span>
|
||||
<span class="sd"> which must return either None or a list of instruction. If it</span>
|
||||
<span class="sd"> returns None, nothing happens. If it returns a list, then the</span>
|
||||
<span class="sd"> instruction is replaced by this list.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span> <span class="o">=</span> <span class="n">_iter_statements</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.get_instructions"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.get_instructions">[docs]</a> <span class="k">def</span> <span class="nf">get_instructions</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">CodeStatement</span><span class="p">]:</span>
|
||||
<span class="sd">"""Return the list of instructions of the program."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span></div>
|
||||
|
||||
<span class="c1"># each instruction has its own "add in list" version</span>
|
||||
<div class="viewcode-block" id="LinearCode.add_label"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.add_label">[docs]</a> <span class="k">def</span> <span class="nf">add_label</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">s</span><span class="p">:</span> <span class="n">Label</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Add a label in the program."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">s</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.add_comment"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.add_comment">[docs]</a> <span class="k">def</span> <span class="nf">add_comment</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">s</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Add a comment in the program."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">Comment</span><span class="p">(</span><span class="n">s</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.add_instruction_PRINTLN_INT"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.add_instruction_PRINTLN_INT">[docs]</a> <span class="k">def</span> <span class="nf">add_instruction_PRINTLN_INT</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">reg</span><span class="p">:</span> <span class="n">DataLocation</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Print integer value, with newline. (see Expand)"""</span>
|
||||
<span class="c1"># a print instruction generates the temp it prints.</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">mv</span><span class="p">(</span><span class="n">A0</span><span class="p">,</span> <span class="n">reg</span><span class="p">))</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add_instruction</span><span class="p">(</span><span class="n">call</span><span class="p">(</span><span class="n">Function</span><span class="p">(</span><span class="s1">'println_int'</span><span class="p">)))</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="p">))</span>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.print_code"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.print_code">[docs]</a> <span class="k">def</span> <span class="nf">print_code</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">comment</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Outputs the RiscV program as text to a file at the given path."""</span>
|
||||
<span class="n">_print_code</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">fdata</span><span class="p">,</span> <span class="n">output</span><span class="p">,</span> <span class="n">init_label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">fin_label</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">fin_div0</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">comment</span><span class="o">=</span><span class="n">comment</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="LinearCode.print_dot"><a class="viewcode-back" href="../../api/Lib.LinearCode.html#Lib.LinearCode.LinearCode.print_dot">[docs]</a> <span class="k">def</span> <span class="nf">print_dot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">filename</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">DF</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
||||
<span class="sd">"""Outputs the RiscV program as graph to a file at the given path."""</span>
|
||||
<span class="c1"># import graphviz here so that students who don't have it can still work on lab4</span>
|
||||
<span class="kn">from</span> <span class="nn">graphviz</span> <span class="kn">import</span> <span class="n">Digraph</span>
|
||||
<span class="n">graph</span> <span class="o">=</span> <span class="n">Digraph</span><span class="p">()</span>
|
||||
<span class="c1"># nodes</span>
|
||||
<span class="n">content</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_listIns</span><span class="p">:</span>
|
||||
<span class="n">content</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\\</span><span class="s2">l"</span>
|
||||
<span class="n">graph</span><span class="o">.</span><span class="n">node</span><span class="p">(</span><span class="s2">"Code"</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">content</span><span class="p">,</span> <span class="n">shape</span><span class="o">=</span><span class="s1">'rectangle'</span><span class="p">)</span>
|
||||
<span class="c1"># no edges</span>
|
||||
<span class="n">graph</span><span class="o">.</span><span class="n">render</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="n">view</span><span class="o">=</span><span class="n">view</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,368 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Operands — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.Operands</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.Operands</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">This file defines the base class :py:class:`Operand`</span>
|
||||
<span class="sd">and its subclasses for different operands: :py:class:`Condition`,</span>
|
||||
<span class="sd">:py:class:`DataLocation` and :py:class:`Function`.</span>
|
||||
|
||||
<span class="sd">The class :py:class:`DataLocation` itself has subclasses:</span>
|
||||
<span class="sd">:py:class:`Register`, :py:class:`Offset` for address in memory,</span>
|
||||
<span class="sd">:py:class:`Immediate` for constants and :py:class:`Temporary`</span>
|
||||
<span class="sd">for location not yet allocated.</span>
|
||||
|
||||
<span class="sd">This file also define shortcuts for registers in RISCV.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span>
|
||||
<span class="kn">from</span> <span class="nn">MiniCParser</span> <span class="kn">import</span> <span class="n">MiniCParser</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Operand"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Operand">[docs]</a><span class="k">class</span> <span class="nc">Operand</span><span class="p">():</span>
|
||||
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<span class="c1"># signed version for riscv</span>
|
||||
<span class="n">all_ops</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'blt'</span><span class="p">,</span> <span class="s1">'bgt'</span><span class="p">,</span> <span class="s1">'beq'</span><span class="p">,</span> <span class="s1">'bne'</span><span class="p">,</span> <span class="s1">'ble'</span><span class="p">,</span> <span class="s1">'bge'</span><span class="p">,</span> <span class="s1">'beqz'</span><span class="p">,</span> <span class="s1">'bnez'</span><span class="p">]</span>
|
||||
<span class="n">opdict</span> <span class="o">=</span> <span class="p">{</span><span class="n">MiniCParser</span><span class="o">.</span><span class="n">LT</span><span class="p">:</span> <span class="s1">'blt'</span><span class="p">,</span> <span class="n">MiniCParser</span><span class="o">.</span><span class="n">GT</span><span class="p">:</span> <span class="s1">'bgt'</span><span class="p">,</span>
|
||||
<span class="n">MiniCParser</span><span class="o">.</span><span class="n">LTEQ</span><span class="p">:</span> <span class="s1">'ble'</span><span class="p">,</span> <span class="n">MiniCParser</span><span class="o">.</span><span class="n">GTEQ</span><span class="p">:</span> <span class="s1">'bge'</span><span class="p">,</span>
|
||||
<span class="n">MiniCParser</span><span class="o">.</span><span class="n">NEQ</span><span class="p">:</span> <span class="s1">'bne'</span><span class="p">,</span> <span class="n">MiniCParser</span><span class="o">.</span><span class="n">EQ</span><span class="p">:</span> <span class="s1">'beq'</span><span class="p">}</span>
|
||||
<span class="n">opnot_dict</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'bgt'</span><span class="p">:</span> <span class="s1">'ble'</span><span class="p">,</span>
|
||||
<span class="s1">'bge'</span><span class="p">:</span> <span class="s1">'blt'</span><span class="p">,</span>
|
||||
<span class="s1">'blt'</span><span class="p">:</span> <span class="s1">'bge'</span><span class="p">,</span>
|
||||
<span class="s1">'ble'</span><span class="p">:</span> <span class="s1">'bgt'</span><span class="p">,</span>
|
||||
<span class="s1">'beq'</span><span class="p">:</span> <span class="s1">'bne'</span><span class="p">,</span>
|
||||
<span class="s1">'bne'</span><span class="p">:</span> <span class="s1">'beq'</span><span class="p">,</span>
|
||||
<span class="s1">'beqz'</span><span class="p">:</span> <span class="s1">'bnez'</span><span class="p">,</span>
|
||||
<span class="s1">'bnez'</span><span class="p">:</span> <span class="s1">'beqz'</span><span class="p">}</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Condition"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Condition">[docs]</a><span class="k">class</span> <span class="nc">Condition</span><span class="p">(</span><span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="sd">"""Condition, i.e. comparison operand for a CondJump.</span>
|
||||
|
||||
<span class="sd"> Example usage :</span>
|
||||
|
||||
<span class="sd"> - Condition('beq') = branch if equal.</span>
|
||||
<span class="sd"> - Condition(MiniCParser.LT) = branch if lower than.</span>
|
||||
<span class="sd"> - ...</span>
|
||||
|
||||
<span class="sd"> The constructor's argument shall be a string in the list all_ops, or a</span>
|
||||
<span class="sd"> comparison operator in MiniCParser.LT, MiniCParser.GT, ... (one of the keys</span>
|
||||
<span class="sd"> in opdict).</span>
|
||||
|
||||
<span class="sd"> A 'negate' method allows getting the negation of this condition.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_op</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">optype</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">optype</span> <span class="ow">in</span> <span class="n">opdict</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_op</span> <span class="o">=</span> <span class="n">opdict</span><span class="p">[</span><span class="n">optype</span><span class="p">]</span>
|
||||
<span class="k">elif</span> <span class="nb">str</span><span class="p">(</span><span class="n">optype</span><span class="p">)</span> <span class="ow">in</span> <span class="n">all_ops</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_op</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">optype</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span><span class="s2">"Unsupported comparison operator </span><span class="si">%s</span><span class="s2">"</span><span class="p">,</span> <span class="n">optype</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="Condition.negate"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Condition.negate">[docs]</a> <span class="k">def</span> <span class="nf">negate</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="s1">'Condition'</span><span class="p">:</span>
|
||||
<span class="sd">"""Return the opposite condition."""</span>
|
||||
<span class="k">return</span> <span class="n">Condition</span><span class="p">(</span><span class="n">opnot_dict</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_op</span><span class="p">])</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_op</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Function"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Function">[docs]</a><span class="k">class</span> <span class="nc">Function</span><span class="p">(</span><span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="sd">"""Operand for build-in function call."""</span>
|
||||
|
||||
<span class="n">_name</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="DataLocation"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.DataLocation">[docs]</a><span class="k">class</span> <span class="nc">DataLocation</span><span class="p">(</span><span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="sd">""" A Data Location is either a register, a temporary</span>
|
||||
<span class="sd"> or a place in memory (offset).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<span class="c1"># map for register shortcuts</span>
|
||||
<span class="n">reg_map</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="mi">0</span><span class="p">,</span> <span class="s1">'zero'</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="s1">'ra'</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="s1">'sp'</span><span class="p">)]</span> <span class="o">+</span> <span class="c1"># no (3, 'gp') nor (4, 'tp')</span>
|
||||
<span class="p">[(</span><span class="n">i</span><span class="o">+</span><span class="mi">5</span><span class="p">,</span> <span class="s1">'t'</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">)]</span> <span class="o">+</span>
|
||||
<span class="p">[(</span><span class="mi">8</span><span class="p">,</span> <span class="s1">'fp'</span><span class="p">),</span> <span class="p">(</span><span class="mi">9</span><span class="p">,</span> <span class="s1">'s1'</span><span class="p">)]</span> <span class="o">+</span>
|
||||
<span class="p">[(</span><span class="n">i</span><span class="o">+</span><span class="mi">10</span><span class="p">,</span> <span class="s1">'a'</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">)]</span> <span class="o">+</span>
|
||||
<span class="p">[(</span><span class="n">i</span><span class="o">+</span><span class="mi">18</span><span class="p">,</span> <span class="s1">'s'</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">2</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)]</span> <span class="o">+</span>
|
||||
<span class="p">[(</span><span class="n">i</span><span class="o">+</span><span class="mi">28</span><span class="p">,</span> <span class="s1">'t'</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">3</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">)])</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Register"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Register">[docs]</a><span class="k">class</span> <span class="nc">Register</span><span class="p">(</span><span class="n">DataLocation</span><span class="p">):</span>
|
||||
<span class="sd">""" A (physical) register."""</span>
|
||||
|
||||
<span class="n">_number</span><span class="p">:</span> <span class="nb">int</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_number</span> <span class="o">=</span> <span class="n">number</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_number</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">reg_map</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"Register number </span><span class="si">%d</span><span class="s2"> should not be used"</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_number</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">reg_map</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_number</span><span class="p">]))</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">Register</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_number</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_number</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_number</span></div>
|
||||
|
||||
|
||||
<span class="c1"># Shortcuts for registers in RISCV</span>
|
||||
<span class="c1"># Only integer registers</span>
|
||||
<span class="n">ZERO</span> <span class="o">=</span> <span class="n">Register</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
|
||||
<span class="n">RA</span> <span class="o">=</span> <span class="n">Register</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="n">SP</span> <span class="o">=</span> <span class="n">Register</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
|
||||
<span class="n">GP</span> <span class="o">=</span> <span class="n">Register</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="c1"># Register not used for this course</span>
|
||||
<span class="n">TP</span> <span class="o">=</span> <span class="n">Register</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="c1"># Register not used for this course</span>
|
||||
<span class="n">A</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">Register</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">10</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">8</span><span class="p">))</span>
|
||||
<span class="n">S</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">Register</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">8</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span> <span class="o">+</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">Register</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">18</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
|
||||
<span class="n">T</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">Register</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">5</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">3</span><span class="p">))</span> <span class="o">+</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">Register</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">28</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">4</span><span class="p">))</span>
|
||||
<span class="n">A0</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># function args/return Values: A0, A1</span>
|
||||
<span class="n">A1</span> <span class="o">=</span> <span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
||||
<span class="n">FP</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># Frame Pointer = Saved register 0</span>
|
||||
|
||||
<span class="c1"># General purpose registers, usable for the allocator</span>
|
||||
<span class="n">GP_REGS</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="mi">4</span><span class="p">:]</span> <span class="o">+</span> <span class="n">T</span> <span class="c1"># s0, s1, s2 and s3 are special</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Offset"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Offset">[docs]</a><span class="k">class</span> <span class="nc">Offset</span><span class="p">(</span><span class="n">DataLocation</span><span class="p">):</span>
|
||||
<span class="sd">""" Offset = address in memory computed with base + offset."""</span>
|
||||
|
||||
<span class="n">_basereg</span><span class="p">:</span> <span class="n">Register</span>
|
||||
<span class="n">_offset</span><span class="p">:</span> <span class="nb">int</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">basereg</span><span class="p">:</span> <span class="n">Register</span><span class="p">,</span> <span class="n">offset</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_basereg</span> <span class="o">=</span> <span class="n">basereg</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_offset</span> <span class="o">=</span> <span class="n">offset</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2">(</span><span class="si">{}</span><span class="s2">)"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_offset</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_basereg</span><span class="p">))</span>
|
||||
|
||||
<div class="viewcode-block" id="Offset.get_offset"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Offset.get_offset">[docs]</a> <span class="k">def</span> <span class="nf">get_offset</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">int</span><span class="p">:</span>
|
||||
<span class="sd">"""Return the value of the offset."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_offset</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Immediate"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Immediate">[docs]</a><span class="k">class</span> <span class="nc">Immediate</span><span class="p">(</span><span class="n">DataLocation</span><span class="p">):</span>
|
||||
<span class="sd">"""Immediate operand (integer)."""</span>
|
||||
|
||||
<span class="n">_val</span><span class="p">:</span> <span class="nb">int</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_val</span> <span class="o">=</span> <span class="n">val</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_val</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Temporary"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Temporary">[docs]</a><span class="k">class</span> <span class="nc">Temporary</span><span class="p">(</span><span class="n">DataLocation</span><span class="p">):</span>
|
||||
<span class="sd">"""Temporary, a location that has not been allocated yet.</span>
|
||||
<span class="sd"> It will later be mapped to a physical register (Register) or to a memory location (Offset).</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">_number</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">_pool</span><span class="p">:</span> <span class="s1">'TemporaryPool'</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">number</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">pool</span><span class="p">:</span> <span class="s1">'TemporaryPool'</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_number</span> <span class="o">=</span> <span class="n">number</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pool</span> <span class="o">=</span> <span class="n">pool</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"temp_</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_number</span><span class="p">)))</span>
|
||||
|
||||
<div class="viewcode-block" id="Temporary.get_alloced_loc"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Temporary.get_alloced_loc">[docs]</a> <span class="k">def</span> <span class="nf">get_alloced_loc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">DataLocation</span><span class="p">:</span>
|
||||
<span class="sd">"""Return the DataLocation allocated to this Temporary."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">get_alloced_loc</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool">[docs]</a><span class="k">class</span> <span class="nc">TemporaryPool</span><span class="p">:</span>
|
||||
<span class="sd">"""Manage a pool of temporaries."""</span>
|
||||
|
||||
<span class="n">_all_temps</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Temporary</span><span class="p">]</span>
|
||||
<span class="n">_current_num</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">_allocation</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Temporary</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_all_temps</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_current_num</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_allocation</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool.get_all_temps"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool.get_all_temps">[docs]</a> <span class="k">def</span> <span class="nf">get_all_temps</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Temporary</span><span class="p">]:</span>
|
||||
<span class="sd">"""Return all the temporaries of the pool."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_all_temps</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool.get_alloced_loc"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool.get_alloced_loc">[docs]</a> <span class="k">def</span> <span class="nf">get_alloced_loc</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">:</span> <span class="n">Temporary</span><span class="p">)</span> <span class="o">-></span> <span class="n">DataLocation</span><span class="p">:</span>
|
||||
<span class="sd">"""Get the actual DataLocation allocated for the temporary t."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_allocation</span><span class="p">[</span><span class="n">t</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool.add_tmp"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool.add_tmp">[docs]</a> <span class="k">def</span> <span class="nf">add_tmp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">:</span> <span class="n">Temporary</span><span class="p">):</span>
|
||||
<span class="sd">"""Add a temporary to the pool."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_all_temps</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_allocation</span><span class="p">[</span><span class="n">t</span><span class="p">]</span> <span class="o">=</span> <span class="n">t</span> <span class="c1"># While no allocation, return the temporary itself</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool.set_temp_allocation"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool.set_temp_allocation">[docs]</a> <span class="k">def</span> <span class="nf">set_temp_allocation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">allocation</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Temporary</span><span class="p">,</span> <span class="n">DataLocation</span><span class="p">])</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="sd">"""Give a mapping from temporaries to actual registers.</span>
|
||||
<span class="sd"> The argument allocation must be a dict from Temporary to</span>
|
||||
<span class="sd"> DataLocation other than Temporary (typically Register or Offset).</span>
|
||||
<span class="sd"> Typing enforces that keys are Temporary and values are Datalocation.</span>
|
||||
<span class="sd"> We check the values are indeed not Temporary.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">allocation</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
||||
<span class="k">assert</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">),</span> <span class="p">(</span>
|
||||
<span class="s2">"Incorrect allocation scheme: value "</span> <span class="o">+</span>
|
||||
<span class="nb">str</span><span class="p">(</span><span class="n">v</span><span class="p">)</span> <span class="o">+</span> <span class="s2">" is a Temporary."</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_allocation</span> <span class="o">=</span> <span class="n">allocation</span></div>
|
||||
|
||||
<div class="viewcode-block" id="TemporaryPool.fresh_tmp"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.TemporaryPool.fresh_tmp">[docs]</a> <span class="k">def</span> <span class="nf">fresh_tmp</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">Temporary</span><span class="p">:</span>
|
||||
<span class="sd">"""Give a new fresh Temporary and add it to the pool."""</span>
|
||||
<span class="n">t</span> <span class="o">=</span> <span class="n">Temporary</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_current_num</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_current_num</span> <span class="o">+=</span> <span class="mi">1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">add_tmp</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">t</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Renamer"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Renamer">[docs]</a><span class="k">class</span> <span class="nc">Renamer</span><span class="p">:</span>
|
||||
<span class="sd">"""Manage a renaming of temporaries."""</span>
|
||||
|
||||
<span class="n">_pool</span><span class="p">:</span> <span class="n">TemporaryPool</span>
|
||||
<span class="n">_env</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Temporary</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pool</span><span class="p">:</span> <span class="n">TemporaryPool</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pool</span> <span class="o">=</span> <span class="n">pool</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_env</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
|
||||
<div class="viewcode-block" id="Renamer.fresh"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Renamer.fresh">[docs]</a> <span class="k">def</span> <span class="nf">fresh</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">:</span> <span class="n">Temporary</span><span class="p">)</span> <span class="o">-></span> <span class="n">Temporary</span><span class="p">:</span>
|
||||
<span class="sd">"""Give a fresh rename for a Temporary."""</span>
|
||||
<span class="n">new_t</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pool</span><span class="o">.</span><span class="n">fresh_tmp</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_env</span><span class="p">[</span><span class="n">t</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_t</span>
|
||||
<span class="k">return</span> <span class="n">new_t</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Renamer.replace"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Renamer.replace">[docs]</a> <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">:</span> <span class="n">Temporary</span><span class="p">)</span> <span class="o">-></span> <span class="n">Temporary</span><span class="p">:</span>
|
||||
<span class="sd">"""Give the rename for a Temporary (which is itself if it is not renamed)."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_env</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="n">t</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Renamer.defined"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Renamer.defined">[docs]</a> <span class="k">def</span> <span class="nf">defined</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">t</span><span class="p">:</span> <span class="n">Temporary</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
||||
<span class="sd">"""True if the Temporary is renamed."""</span>
|
||||
<span class="k">return</span> <span class="n">t</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_env</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Renamer.copy"><a class="viewcode-back" href="../../api/Lib.Operands.html#Lib.Operands.Renamer.copy">[docs]</a> <span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Give a copy of the Renamer."""</span>
|
||||
<span class="n">r</span> <span class="o">=</span> <span class="n">Renamer</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_pool</span><span class="p">)</span>
|
||||
<span class="n">r</span><span class="o">.</span><span class="n">_env</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_env</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">r</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.RiscV — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.RiscV</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.RiscV</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">MIF08, CAP, CodeGeneration, RiscV API</span>
|
||||
<span class="sd">Functions to define instructions.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">Condition</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">,</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">Function</span><span class="p">,</span> <span class="n">ZERO</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Statement</span> <span class="kn">import</span> <span class="p">(</span><span class="n">Instru3A</span><span class="p">,</span> <span class="n">AbsoluteJump</span><span class="p">,</span> <span class="n">ConditionalJump</span><span class="p">,</span> <span class="n">Label</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="call"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.call">[docs]</a><span class="k">def</span> <span class="nf">call</span><span class="p">(</span><span class="n">function</span><span class="p">:</span> <span class="n">Function</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="sd">"""Function call."""</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s1">'call'</span><span class="p">,</span> <span class="n">function</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="jump"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.jump">[docs]</a><span class="k">def</span> <span class="nf">jump</span><span class="p">(</span><span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">)</span> <span class="o">-></span> <span class="n">AbsoluteJump</span><span class="p">:</span>
|
||||
<span class="sd">"""Unconditional jump to label."""</span>
|
||||
<span class="k">return</span> <span class="n">AbsoluteJump</span><span class="p">(</span><span class="n">label</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="conditional_jump"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.conditional_jump">[docs]</a><span class="k">def</span> <span class="nf">conditional_jump</span><span class="p">(</span><span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">,</span> <span class="n">op1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">cond</span><span class="p">:</span> <span class="n">Condition</span><span class="p">,</span> <span class="n">op2</span><span class="p">:</span> <span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="sd">"""Add a conditional jump to the code.</span>
|
||||
<span class="sd"> This is a wrapper around bge, bgt, beq, ... c is a Condition, like</span>
|
||||
<span class="sd"> Condition('bgt'), Condition(MiniCParser.EQ), ...</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">op2</span> <span class="o">=</span> <span class="n">op2</span> <span class="k">if</span> <span class="n">op2</span> <span class="o">!=</span> <span class="n">Immediate</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="k">else</span> <span class="n">ZERO</span>
|
||||
<span class="k">return</span> <span class="n">ConditionalJump</span><span class="p">(</span><span class="n">cond</span><span class="o">=</span><span class="n">cond</span><span class="p">,</span> <span class="n">op1</span><span class="o">=</span><span class="n">op1</span><span class="p">,</span> <span class="n">op2</span><span class="o">=</span><span class="n">op2</span><span class="p">,</span> <span class="n">label</span><span class="o">=</span><span class="n">label</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="add"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.add">[docs]</a><span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"addi"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"add"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="mul"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.mul">[docs]</a><span class="k">def</span> <span class="nf">mul</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span><span class="s2">"Cant multiply by an immediate"</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"mul"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="div"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.div">[docs]</a><span class="k">def</span> <span class="nf">div</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span><span class="s2">"Cant divide by an immediate"</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"div"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="rem"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.rem">[docs]</a><span class="k">def</span> <span class="nf">rem</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span><span class="s2">"Cant divide by an immediate"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"rem"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="sub"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.sub">[docs]</a><span class="k">def</span> <span class="nf">sub</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">sr2orimm7</span><span class="p">,</span> <span class="n">Immediate</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span><span class="p">(</span><span class="s2">"Cant substract by an immediate"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"sub"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="land"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.land">[docs]</a><span class="k">def</span> <span class="nf">land</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"and"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="lor"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.lor">[docs]</a><span class="k">def</span> <span class="nf">lor</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"or"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="xor"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.xor">[docs]</a><span class="k">def</span> <span class="nf">xor</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span> <span class="c1"># pragma: no cover</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"xor"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr1</span><span class="p">,</span> <span class="n">sr2orimm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="li"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.li">[docs]</a><span class="k">def</span> <span class="nf">li</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">imm7</span><span class="p">:</span> <span class="n">Immediate</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"li"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">imm7</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="mv"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.mv">[docs]</a><span class="k">def</span> <span class="nf">mv</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">sr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"mv"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">sr</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ld"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.ld">[docs]</a><span class="k">def</span> <span class="nf">ld</span><span class="p">(</span><span class="n">dr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">mem</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"ld"</span><span class="p">,</span> <span class="n">dr</span><span class="p">,</span> <span class="n">mem</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="sd"><a class="viewcode-back" href="../../api/Lib.RiscV.html#Lib.RiscV.sd">[docs]</a><span class="k">def</span> <span class="nf">sd</span><span class="p">(</span><span class="n">sr</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">mem</span><span class="p">:</span> <span class="n">Operand</span><span class="p">)</span> <span class="o">-></span> <span class="n">Instru3A</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="s2">"sd"</span><span class="p">,</span> <span class="n">sr</span><span class="p">,</span> <span class="n">mem</span><span class="p">)</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,345 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Statement — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../../index.html" class="icon icon-home"></a> »</li>
|
||||
<li><a href="../index.html">Module code</a> »</li>
|
||||
<li>Lib.Statement</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>Source code for Lib.Statement</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">The base class for RISCV ASM statements is :py:class:`Statement`.</span>
|
||||
<span class="sd">It is inherited by :py:class:`Comment`, :py:class:`Label`</span>
|
||||
<span class="sd">and :py:class:`Instruction`. In turn, :py:class:`Instruction`</span>
|
||||
<span class="sd">is inherited by :py:class:`Instru3A`</span>
|
||||
<span class="sd">(for regular non-branching 3-address instructions),</span>
|
||||
<span class="sd">:py:class:`AbsoluteJump` and :py:class:`ConditionalJump`.</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="p">(</span><span class="n">List</span><span class="p">,</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">TypeVar</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Operands</span> <span class="kn">import</span> <span class="p">(</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Renamer</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">,</span> <span class="n">Condition</span><span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">Lib.Errors</span> <span class="kn">import</span> <span class="n">MiniCInternalError</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="regset_to_string"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.regset_to_string">[docs]</a><span class="k">def</span> <span class="nf">regset_to_string</span><span class="p">(</span><span class="n">registerset</span><span class="p">):</span>
|
||||
<span class="sd">"""Utility function: pretty-prints a set of locations."""</span>
|
||||
<span class="k">return</span> <span class="s2">"{"</span> <span class="o">+</span> <span class="s2">","</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">registerset</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"}"</span></div>
|
||||
|
||||
|
||||
<span class="c1"># Temporary until we can use Typing.Self in python 3.11</span>
|
||||
<span class="n">TStatement</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s2">"TStatement"</span><span class="p">,</span> <span class="n">bound</span><span class="o">=</span><span class="s2">"Statement"</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Statement"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Statement">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">unsafe_hash</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">Statement</span><span class="p">:</span>
|
||||
<span class="sd">"""A Statement, which is an instruction, a comment or a label."""</span>
|
||||
|
||||
<div class="viewcode-block" id="Statement.defined"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Statement.defined">[docs]</a> <span class="k">def</span> <span class="nf">defined</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Statement.used"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Statement.used">[docs]</a> <span class="k">def</span> <span class="nf">used</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Statement.substitute"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Statement.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">:</span> <span class="n">TStatement</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">])</span> <span class="o">-></span> <span class="n">TStatement</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
||||
<span class="s2">"substitute: Operands </span><span class="si">{}</span><span class="s2"> are not present in instruction </span><span class="si">{}</span><span class="s2">"</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">subst</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Statement.printIns"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Statement.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Print the statement on the output.</span>
|
||||
<span class="sd"> Should never be called on the base class.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Comment"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Comment">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">unsafe_hash</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">Comment</span><span class="p">(</span><span class="n">Statement</span><span class="p">):</span>
|
||||
<span class="sd">"""A comment."""</span>
|
||||
<span class="n">comment</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c1"># use only for print_dot !</span>
|
||||
<span class="k">return</span> <span class="s2">"# </span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">comment</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="Comment.printIns"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Comment.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">' # '</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">comment</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">stream</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Label"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Label">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">unsafe_hash</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">Label</span><span class="p">(</span><span class="n">Statement</span><span class="p">,</span> <span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="sd">"""A label is both a Statement and an Operand."""</span>
|
||||
<span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"lbl_</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="s2">"</span><span class="si">{}</span><span class="s2">"</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">))</span>
|
||||
|
||||
<div class="viewcode-block" id="Label.printIns"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Label.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">+</span> <span class="s1">':'</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">stream</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Instruction"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">Instruction</span><span class="p">(</span><span class="n">Statement</span><span class="p">):</span>
|
||||
<span class="n">ins</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">_read_only</span><span class="p">:</span> <span class="nb">bool</span>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.is_read_only"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.is_read_only">[docs]</a> <span class="k">def</span> <span class="nf">is_read_only</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> True if the instruction only reads from its operands.</span>
|
||||
|
||||
<span class="sd"> Otherwise, the first operand is considered as the destination</span>
|
||||
<span class="sd"> and others are source.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_only</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.rename"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.args"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.args">[docs]</a> <span class="k">def</span> <span class="nf">args</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]:</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.defined"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.defined">[docs]</a> <span class="k">def</span> <span class="nf">defined</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_read_only</span><span class="p">():</span>
|
||||
<span class="n">defs</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">defs</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
|
||||
<span class="k">return</span> <span class="n">defs</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.used"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.used">[docs]</a> <span class="k">def</span> <span class="nf">used</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_read_only</span><span class="p">():</span>
|
||||
<span class="n">uses</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">uses</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">()[</span><span class="mi">1</span><span class="p">:]</span>
|
||||
<span class="k">return</span> <span class="n">uses</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">ins</span>
|
||||
<span class="n">first</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">():</span>
|
||||
<span class="k">if</span> <span class="n">first</span><span class="p">:</span>
|
||||
<span class="n">s</span> <span class="o">+=</span> <span class="s1">' '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
||||
<span class="n">first</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">s</span> <span class="o">+=</span> <span class="s1">', '</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">s</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">ins</span><span class="p">,</span> <span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">()))</span>
|
||||
|
||||
<div class="viewcode-block" id="Instruction.printIns"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instruction.printIns">[docs]</a> <span class="k">def</span> <span class="nf">printIns</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">stream</span><span class="p">):</span>
|
||||
<span class="sd">"""Print the instruction on the output."""</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="s1">' '</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">),</span> <span class="n">file</span><span class="o">=</span><span class="n">stream</span><span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="Instru3A"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instru3A">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">Instru3A</span><span class="p">(</span><span class="n">Instruction</span><span class="p">):</span>
|
||||
<span class="n">_args</span><span class="p">:</span> <span class="n">List</span><span class="p">[</span><span class="n">Operand</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ins</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">:</span> <span class="n">Operand</span><span class="p">):</span>
|
||||
<span class="c1"># convention is to use lower-case in RISCV</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">=</span> <span class="n">ins</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_read_only</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">==</span> <span class="s2">"call"</span>
|
||||
<span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">==</span> <span class="s2">"ld"</span>
|
||||
<span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">==</span> <span class="s2">"lw"</span>
|
||||
<span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">==</span> <span class="s2">"lb"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ins</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s2">"b"</span><span class="p">)</span> <span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">==</span> <span class="s2">"j"</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="n">MiniCInternalError</span>
|
||||
|
||||
<div class="viewcode-block" id="Instru3A.args"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instru3A.args">[docs]</a> <span class="k">def</span> <span class="nf">args</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_args</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instru3A.rename"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instru3A.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">):</span>
|
||||
<span class="n">old_replaced</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
<span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_args</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_read_only</span><span class="p">():</span>
|
||||
<span class="n">old_replaced</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
||||
<span class="n">new_t</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">fresh</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">old_replaced</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
|
||||
<span class="n">new_t</span> <span class="o">=</span> <span class="n">old_replaced</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">new_t</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_args</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">new_t</span></div>
|
||||
|
||||
<div class="viewcode-block" id="Instru3A.substitute"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.Instru3A.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]):</span>
|
||||
<span class="k">for</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">subst</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">op</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">():</span>
|
||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
||||
<span class="s2">"substitute: Operand </span><span class="si">{}</span><span class="s2"> is not present in instruction </span><span class="si">{}</span><span class="s2">"</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span>
|
||||
<span class="n">args</span> <span class="o">=</span> <span class="p">[</span><span class="n">subst</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">)</span> <span class="k">else</span> <span class="n">arg</span>
|
||||
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">()]</span>
|
||||
<span class="k">return</span> <span class="n">Instru3A</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ins</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">super</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="AbsoluteJump"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.AbsoluteJump">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">AbsoluteJump</span><span class="p">(</span><span class="n">Instruction</span><span class="p">):</span>
|
||||
<span class="sd">""" An Absolute Jump is a specific kind of instruction"""</span>
|
||||
<span class="n">ins</span> <span class="o">=</span> <span class="s2">"j"</span>
|
||||
<span class="n">label</span><span class="p">:</span> <span class="n">Label</span>
|
||||
<span class="n">_read_only</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="n">label</span>
|
||||
|
||||
<div class="viewcode-block" id="AbsoluteJump.args"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.AbsoluteJump.args">[docs]</a> <span class="k">def</span> <span class="nf">args</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="AbsoluteJump.rename"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.AbsoluteJump.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="AbsoluteJump.substitute"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.AbsoluteJump.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]):</span>
|
||||
<span class="k">if</span> <span class="n">subst</span> <span class="o">!=</span> <span class="p">{}:</span>
|
||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
||||
<span class="s2">"substitute: No possible substitution on instruction </span><span class="si">{}</span><span class="s2">"</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="bp">self</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">super</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="AbsoluteJump.targets"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.AbsoluteJump.targets">[docs]</a> <span class="k">def</span> <span class="nf">targets</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">Label</span><span class="p">]:</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">]</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ConditionalJump"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.ConditionalJump">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">init</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">ConditionalJump</span><span class="p">(</span><span class="n">Instruction</span><span class="p">):</span>
|
||||
<span class="sd">""" A Conditional Jump is a specific kind of instruction"""</span>
|
||||
<span class="n">cond</span><span class="p">:</span> <span class="n">Condition</span>
|
||||
<span class="n">label</span><span class="p">:</span> <span class="n">Label</span>
|
||||
<span class="n">op1</span><span class="p">:</span> <span class="n">Operand</span>
|
||||
<span class="n">op2</span><span class="p">:</span> <span class="n">Operand</span>
|
||||
<span class="n">_read_only</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cond</span><span class="p">:</span> <span class="n">Condition</span><span class="p">,</span> <span class="n">op1</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">op2</span><span class="p">:</span> <span class="n">Operand</span><span class="p">,</span> <span class="n">label</span><span class="p">:</span> <span class="n">Label</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">cond</span> <span class="o">=</span> <span class="n">cond</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">label</span> <span class="o">=</span> <span class="n">label</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">op1</span> <span class="o">=</span> <span class="n">op1</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">op2</span> <span class="o">=</span> <span class="n">op2</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">ins</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cond</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="ConditionalJump.args"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.ConditionalJump.args">[docs]</a> <span class="k">def</span> <span class="nf">args</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">]</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ConditionalJump.rename"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.ConditionalJump.rename">[docs]</a> <span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">renamer</span><span class="p">:</span> <span class="n">Renamer</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">op1</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">op2</span> <span class="o">=</span> <span class="n">renamer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ConditionalJump.substitute"><a class="viewcode-back" href="../../api/Lib.Statement.html#Lib.Statement.ConditionalJump.substitute">[docs]</a> <span class="k">def</span> <span class="nf">substitute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">subst</span><span class="p">:</span> <span class="n">Dict</span><span class="p">[</span><span class="n">Operand</span><span class="p">,</span> <span class="n">Operand</span><span class="p">]):</span>
|
||||
<span class="k">for</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">subst</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">op</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">():</span>
|
||||
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span>
|
||||
<span class="s2">"substitute: Operand </span><span class="si">{}</span><span class="s2"> is not present in instruction </span><span class="si">{}</span><span class="s2">"</span>
|
||||
<span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">op</span><span class="p">,</span> <span class="bp">self</span><span class="p">))</span>
|
||||
<span class="n">op1</span> <span class="o">=</span> <span class="n">subst</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op1</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">)</span> \
|
||||
<span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">op1</span>
|
||||
<span class="n">op2</span> <span class="o">=</span> <span class="n">subst</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">)</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">op2</span><span class="p">,</span> <span class="n">Temporary</span><span class="p">)</span> \
|
||||
<span class="k">else</span> <span class="bp">self</span><span class="o">.</span><span class="n">op2</span>
|
||||
<span class="k">return</span> <span class="n">ConditionalJump</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cond</span><span class="p">,</span> <span class="n">op1</span><span class="p">,</span> <span class="n">op2</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">label</span><span class="p">)</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">hash</span><span class="p">(</span><span class="nb">super</span><span class="p">)</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Overview: module code — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../api/Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Overview: module code</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<h1>All modules for which code is available</h1>
|
||||
<ul><li><a href="Lib/Allocator.html">Lib.Allocator</a></li>
|
||||
<li><a href="Lib/Errors.html">Lib.Errors</a></li>
|
||||
<li><a href="Lib/FunctionData.html">Lib.FunctionData</a></li>
|
||||
<li><a href="Lib/LinearCode.html">Lib.LinearCode</a></li>
|
||||
<li><a href="Lib/Operands.html">Lib.Operands</a></li>
|
||||
<li><a href="Lib/RiscV.html">Lib.RiscV</a></li>
|
||||
<li><a href="Lib/Statement.html">Lib.Statement</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.Allocator module
|
||||
====================
|
||||
|
||||
.. automodule:: Lib.Allocator
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.Errors module
|
||||
=================
|
||||
|
||||
.. automodule:: Lib.Errors
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.FunctionData module
|
||||
=======================
|
||||
|
||||
.. automodule:: Lib.FunctionData
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.LinearCode module
|
||||
=====================
|
||||
|
||||
.. automodule:: Lib.LinearCode
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.Operands module
|
||||
===================
|
||||
|
||||
.. automodule:: Lib.Operands
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.RiscV module
|
||||
================
|
||||
|
||||
.. automodule:: Lib.RiscV
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
Lib.Statement module
|
||||
====================
|
||||
|
||||
.. automodule:: Lib.Statement
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,24 @@
|
||||
Lib package
|
||||
===========
|
||||
|
||||
Submodules
|
||||
----------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
Lib.Allocator
|
||||
Lib.Errors
|
||||
Lib.FunctionData
|
||||
Lib.LinearCode
|
||||
Lib.Operands
|
||||
Lib.RiscV
|
||||
Lib.Statement
|
||||
|
||||
Module contents
|
||||
---------------
|
||||
|
||||
.. automodule:: Lib
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,7 @@
|
||||
MiniC
|
||||
=====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
Lib
|
||||
@@ -0,0 +1,54 @@
|
||||
.. MiniC documentation master file, created by
|
||||
sphinx-quickstart on Thu Feb 3 16:47:38 2022.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to MiniC's documentation!
|
||||
=================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
:caption: Contents:
|
||||
|
||||
Base library - Errors <api/Lib.Errors>
|
||||
Base library - Statement <api/Lib.Statement>
|
||||
Base library - RISC-V instructions <api/Lib.RiscV>
|
||||
Base library - Operands <api/Lib.Operands>
|
||||
Base library - Function data <api/Lib.FunctionData>
|
||||
Linear intermediate representation <api/Lib.LinearCode>
|
||||
Temporary allocation <api/Lib.Allocator>
|
||||
|
||||
These pages document the various Python sources in the Lib/
|
||||
folder of MiniC. You should not have to edit them *at all*.
|
||||
|
||||
Base library
|
||||
------------
|
||||
|
||||
The :doc:`api/Lib.Statement` defines various classes that represent
|
||||
RISC-V assembly statements, such as labels or 3-address instructions.
|
||||
|
||||
We won't create objects of these classes directly very often.
|
||||
Instead, to easily create such statements for standard RISC-V assembly instructions
|
||||
and pseudo-instructions, we give you the :doc:`api/Lib.RiscV`.
|
||||
|
||||
RISC-V instructions take arguments of various kinds,
|
||||
as defined in the :doc:`api/Lib.Operands`.
|
||||
|
||||
Linear Intermediate representation
|
||||
----------------------------------
|
||||
|
||||
The :doc:`api/Lib.LinearCode` allows to work with assembly source code
|
||||
modeled as a list of statements.
|
||||
|
||||
Temporary allocation
|
||||
--------------------
|
||||
|
||||
Before implementing the all-in-memory allocator of lab 4a,
|
||||
you should understand the naive allocator in the :doc:`api/Lib.Allocator`.
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* _sphinx_javascript_frameworks_compat.js
|
||||
* ~~~~~~~~~~
|
||||
*
|
||||
* Compatability shim for jQuery and underscores.js.
|
||||
*
|
||||
* WILL BE REMOVED IN Sphinx 6.0
|
||||
* xref RemovedInSphinx60Warning
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* select a different prefix for underscore
|
||||
*/
|
||||
$u = _.noConflict();
|
||||
|
||||
|
||||
/**
|
||||
* small helper function to urldecode strings
|
||||
*
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL
|
||||
*/
|
||||
jQuery.urldecode = function(x) {
|
||||
if (!x) {
|
||||
return x
|
||||
}
|
||||
return decodeURIComponent(x.replace(/\+/g, ' '));
|
||||
};
|
||||
|
||||
/**
|
||||
* small helper function to urlencode strings
|
||||
*/
|
||||
jQuery.urlencode = encodeURIComponent;
|
||||
|
||||
/**
|
||||
* This function returns the parsed url parameters of the
|
||||
* current request. Multiple values per key are supported,
|
||||
* it will always return arrays of strings for the value parts.
|
||||
*/
|
||||
jQuery.getQueryParameters = function(s) {
|
||||
if (typeof s === 'undefined')
|
||||
s = document.location.search;
|
||||
var parts = s.substr(s.indexOf('?') + 1).split('&');
|
||||
var result = {};
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var tmp = parts[i].split('=', 2);
|
||||
var key = jQuery.urldecode(tmp[0]);
|
||||
var value = jQuery.urldecode(tmp[1]);
|
||||
if (key in result)
|
||||
result[key].push(value);
|
||||
else
|
||||
result[key] = [value];
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a jquery object by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
jQuery.fn.highlightText = function(text, className) {
|
||||
function highlight(node, addItems) {
|
||||
if (node.nodeType === 3) {
|
||||
var val = node.nodeValue;
|
||||
var pos = val.toLowerCase().indexOf(text);
|
||||
if (pos >= 0 &&
|
||||
!jQuery(node.parentNode).hasClass(className) &&
|
||||
!jQuery(node.parentNode).hasClass("nohighlight")) {
|
||||
var span;
|
||||
var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.className = className;
|
||||
}
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
node.parentNode.insertBefore(span, node.parentNode.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling));
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
if (isInSVG) {
|
||||
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
||||
var bbox = node.parentElement.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute('class', className);
|
||||
addItems.push({
|
||||
"parent": node.parentNode,
|
||||
"target": rect});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!jQuery(node).is("button, select, textarea")) {
|
||||
jQuery.each(node.childNodes, function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
}
|
||||
}
|
||||
var addItems = [];
|
||||
var result = this.each(function() {
|
||||
highlight(this, addItems);
|
||||
});
|
||||
for (var i = 0; i < addItems.length; ++i) {
|
||||
jQuery(addItems[i].parent).before(addItems[i].target);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/*
|
||||
* backward compatibility for jQuery.browser
|
||||
* This will be supported until firefox bug is fixed.
|
||||
*/
|
||||
if (!jQuery.browser) {
|
||||
jQuery.uaMatch = function(ua) {
|
||||
ua = ua.toLowerCase();
|
||||
|
||||
var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(webkit)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
|
||||
/(msie) ([\w.]+)/.exec(ua) ||
|
||||
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
|
||||
[];
|
||||
|
||||
return {
|
||||
browser: match[ 1 ] || "",
|
||||
version: match[ 2 ] || "0"
|
||||
};
|
||||
};
|
||||
jQuery.browser = {};
|
||||
jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
|
||||
}
|
||||
Vendored
+899
@@ -0,0 +1,899 @@
|
||||
/*
|
||||
* basic.css
|
||||
* ~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- basic theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.section::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap : break-word;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox form.search {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="text"] {
|
||||
float: left;
|
||||
width: 80%;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
||||
float: left;
|
||||
width: 20%;
|
||||
border-left: none;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li p.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
table.indextable > tbody > tr > td > ul {
|
||||
padding-left: 0em;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
div.genindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* -- domain module index --------------------------------------------------- */
|
||||
|
||||
table.modindextable td {
|
||||
padding: 2px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
div.body {
|
||||
min-width: 360px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
a.brackets:before,
|
||||
span.brackets > a:before{
|
||||
content: "[";
|
||||
}
|
||||
|
||||
a.brackets:after,
|
||||
span.brackets > a:after {
|
||||
content: "]";
|
||||
}
|
||||
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink,
|
||||
caption:hover > a.headerlink,
|
||||
p.caption:hover > a.headerlink,
|
||||
div.code-block-caption:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.body p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.body td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.align-left, figure.align-left, .figure.align-left, object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
img.align-right, figure.align-right, .figure.align-right, object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
img.align-center, figure.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
img.align-default, figure.align-default, .figure.align-default {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-default {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar,
|
||||
aside.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
clear: right;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
div.admonition, div.topic, blockquote {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.body p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- content of sidebars/topics/admonitions -------------------------------- */
|
||||
|
||||
div.sidebar > :last-child,
|
||||
aside.sidebar > :last-child,
|
||||
div.topic > :last-child,
|
||||
div.admonition > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sidebar::after,
|
||||
aside.sidebar::after,
|
||||
div.topic::after,
|
||||
div.admonition::after,
|
||||
blockquote::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-default {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table caption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table caption span.caption-text {
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
table.citation td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
th > :first-child,
|
||||
td > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
th > :last-child,
|
||||
td > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* -- figures --------------------------------------------------------------- */
|
||||
|
||||
div.figure, figure {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div.figure p.caption, figcaption {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-number,
|
||||
figcaption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-text,
|
||||
figcaption span.caption-text {
|
||||
}
|
||||
|
||||
/* -- field list styles ----------------------------------------------------- */
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
/* -- hlist styles ---------------------------------------------------------- */
|
||||
|
||||
table.hlist {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
table.hlist td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -- object description styles --------------------------------------------- */
|
||||
|
||||
.sig {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
}
|
||||
|
||||
.sig-name, code.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sig-name {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
code.descname {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.sig-prename, code.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.sig-paren {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.sig-param.n {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* C++ specific styling */
|
||||
|
||||
.sig-inline.c-texpr,
|
||||
.sig-inline.cpp-texpr {
|
||||
font-family: unset;
|
||||
}
|
||||
|
||||
.sig.c .k, .sig.c .kt,
|
||||
.sig.cpp .k, .sig.cpp .kt {
|
||||
color: #0033B3;
|
||||
}
|
||||
|
||||
.sig.c .m,
|
||||
.sig.cpp .m {
|
||||
color: #1750EB;
|
||||
}
|
||||
|
||||
.sig.c .s, .sig.c .sc,
|
||||
.sig.cpp .s, .sig.cpp .sc {
|
||||
color: #067D17;
|
||||
}
|
||||
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha;
|
||||
}
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha;
|
||||
}
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman;
|
||||
}
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:first-child > :first-child,
|
||||
:not(li) > ul > li:first-child > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:last-child > :last-child,
|
||||
:not(li) > ul > li:last-child > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ol.simple ol p,
|
||||
ol.simple ul p,
|
||||
ul.simple ol p,
|
||||
ul.simple ul p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple > li:not(:first-child) > p,
|
||||
ul.simple > li:not(:first-child) > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple p,
|
||||
ul.simple p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
dl.footnote > dt,
|
||||
dl.citation > dt {
|
||||
float: left;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
dl.footnote > dd,
|
||||
dl.citation > dd {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl.footnote > dd:after,
|
||||
dl.citation > dd:after {
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
dl.field-list {
|
||||
display: grid;
|
||||
grid-template-columns: fit-content(30%) auto;
|
||||
}
|
||||
|
||||
dl.field-list > dt {
|
||||
font-weight: bold;
|
||||
word-break: break-word;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 5px;
|
||||
}
|
||||
dl.field-list > dt:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
|
||||
dl.field-list > dd {
|
||||
padding-left: 0.5em;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dl > dd:last-child,
|
||||
dl > dd:last-child > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt:target, span.highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
rect.highlighted {
|
||||
fill: #fbe54e;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.guilabel, .menuselection {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.accelerator {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.classifier {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.classifier:before {
|
||||
font-style: normal;
|
||||
margin: 0 0.5em;
|
||||
content: ":";
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
abbr, acronym {
|
||||
border-bottom: dotted 1px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
||||
}
|
||||
|
||||
pre, div[class*="highlight-"] {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
span.pre {
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
hyphens: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div[class*="highlight-"] {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td.code {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.highlight pre,
|
||||
table.highlighttable pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption + div {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption {
|
||||
margin-top: 1em;
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.code-block-caption code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos,
|
||||
span.linenos,
|
||||
div.highlight span.gp { /* gp: Generic.Prompt */
|
||||
user-select: none;
|
||||
-webkit-user-select: text; /* Safari fallback only */
|
||||
-webkit-user-select: none; /* Chrome/Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE10+ */
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-number {
|
||||
padding: 0.1em 0.3em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-text {
|
||||
}
|
||||
|
||||
div.literal-block-wrapper {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
code.xref, a code {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.body div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.eqno a.headerlink {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
div.math:hover a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* -- printout stylesheet --------------------------------------------------- */
|
||||
|
||||
@media print {
|
||||
div.document,
|
||||
div.documentwrapper,
|
||||
div.bodywrapper {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar,
|
||||
div.related,
|
||||
div.footer,
|
||||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
+2671
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 434 KiB |
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+4
File diff suppressed because one or more lines are too long
Vendored
+264
@@ -0,0 +1,264 @@
|
||||
/*
|
||||
* doctools.js
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* Base JavaScript utilities for all Sphinx HTML documentation.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
const _ready = (callback) => {
|
||||
if (document.readyState !== "loading") {
|
||||
callback();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", callback);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* highlight a given string on a node by wrapping it in
|
||||
* span elements with the given class name.
|
||||
*/
|
||||
const _highlight = (node, addItems, text, className) => {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const val = node.nodeValue;
|
||||
const parent = node.parentNode;
|
||||
const pos = val.toLowerCase().indexOf(text);
|
||||
if (
|
||||
pos >= 0 &&
|
||||
!parent.classList.contains(className) &&
|
||||
!parent.classList.contains("nohighlight")
|
||||
) {
|
||||
let span;
|
||||
|
||||
const closestNode = parent.closest("body, svg, foreignObject");
|
||||
const isInSVG = closestNode && closestNode.matches("svg");
|
||||
if (isInSVG) {
|
||||
span = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
|
||||
} else {
|
||||
span = document.createElement("span");
|
||||
span.classList.add(className);
|
||||
}
|
||||
|
||||
span.appendChild(document.createTextNode(val.substr(pos, text.length)));
|
||||
parent.insertBefore(
|
||||
span,
|
||||
parent.insertBefore(
|
||||
document.createTextNode(val.substr(pos + text.length)),
|
||||
node.nextSibling
|
||||
)
|
||||
);
|
||||
node.nodeValue = val.substr(0, pos);
|
||||
|
||||
if (isInSVG) {
|
||||
const rect = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"rect"
|
||||
);
|
||||
const bbox = parent.getBBox();
|
||||
rect.x.baseVal.value = bbox.x;
|
||||
rect.y.baseVal.value = bbox.y;
|
||||
rect.width.baseVal.value = bbox.width;
|
||||
rect.height.baseVal.value = bbox.height;
|
||||
rect.setAttribute("class", className);
|
||||
addItems.push({ parent: parent, target: rect });
|
||||
}
|
||||
}
|
||||
} else if (node.matches && !node.matches("button, select, textarea")) {
|
||||
node.childNodes.forEach((el) => _highlight(el, addItems, text, className));
|
||||
}
|
||||
};
|
||||
const _highlightText = (thisNode, text, className) => {
|
||||
let addItems = [];
|
||||
_highlight(thisNode, addItems, text, className);
|
||||
addItems.forEach((obj) =>
|
||||
obj.parent.insertAdjacentElement("beforebegin", obj.target)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Small JavaScript module for the documentation.
|
||||
*/
|
||||
const Documentation = {
|
||||
init: () => {
|
||||
Documentation.highlightSearchWords();
|
||||
Documentation.initDomainIndexTable();
|
||||
Documentation.initOnKeyListeners();
|
||||
},
|
||||
|
||||
/**
|
||||
* i18n support
|
||||
*/
|
||||
TRANSLATIONS: {},
|
||||
PLURAL_EXPR: (n) => (n === 1 ? 0 : 1),
|
||||
LOCALE: "unknown",
|
||||
|
||||
// gettext and ngettext don't access this so that the functions
|
||||
// can safely bound to a different name (_ = Documentation.gettext)
|
||||
gettext: (string) => {
|
||||
const translated = Documentation.TRANSLATIONS[string];
|
||||
switch (typeof translated) {
|
||||
case "undefined":
|
||||
return string; // no translation
|
||||
case "string":
|
||||
return translated; // translation exists
|
||||
default:
|
||||
return translated[0]; // (singular, plural) translation tuple exists
|
||||
}
|
||||
},
|
||||
|
||||
ngettext: (singular, plural, n) => {
|
||||
const translated = Documentation.TRANSLATIONS[singular];
|
||||
if (typeof translated !== "undefined")
|
||||
return translated[Documentation.PLURAL_EXPR(n)];
|
||||
return n === 1 ? singular : plural;
|
||||
},
|
||||
|
||||
addTranslations: (catalog) => {
|
||||
Object.assign(Documentation.TRANSLATIONS, catalog.messages);
|
||||
Documentation.PLURAL_EXPR = new Function(
|
||||
"n",
|
||||
`return (${catalog.plural_expr})`
|
||||
);
|
||||
Documentation.LOCALE = catalog.locale;
|
||||
},
|
||||
|
||||
/**
|
||||
* highlight the search words provided in the url in the text
|
||||
*/
|
||||
highlightSearchWords: () => {
|
||||
const highlight =
|
||||
new URLSearchParams(window.location.search).get("highlight") || "";
|
||||
const terms = highlight.toLowerCase().split(/\s+/).filter(x => x);
|
||||
if (terms.length === 0) return; // nothing to do
|
||||
|
||||
// There should never be more than one element matching "div.body"
|
||||
const divBody = document.querySelectorAll("div.body");
|
||||
const body = divBody.length ? divBody[0] : document.querySelector("body");
|
||||
window.setTimeout(() => {
|
||||
terms.forEach((term) => _highlightText(body, term, "highlighted"));
|
||||
}, 10);
|
||||
|
||||
const searchBox = document.getElementById("searchbox");
|
||||
if (searchBox === null) return;
|
||||
searchBox.appendChild(
|
||||
document
|
||||
.createRange()
|
||||
.createContextualFragment(
|
||||
'<p class="highlight-link">' +
|
||||
'<a href="javascript:Documentation.hideSearchWords()">' +
|
||||
Documentation.gettext("Hide Search Matches") +
|
||||
"</a></p>"
|
||||
)
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to hide the search marks again
|
||||
*/
|
||||
hideSearchWords: () => {
|
||||
document
|
||||
.querySelectorAll("#searchbox .highlight-link")
|
||||
.forEach((el) => el.remove());
|
||||
document
|
||||
.querySelectorAll("span.highlighted")
|
||||
.forEach((el) => el.classList.remove("highlighted"));
|
||||
const url = new URL(window.location);
|
||||
url.searchParams.delete("highlight");
|
||||
window.history.replaceState({}, "", url);
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to focus on search bar
|
||||
*/
|
||||
focusSearchBar: () => {
|
||||
document.querySelectorAll("input[name=q]")[0]?.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialise the domain index toggle buttons
|
||||
*/
|
||||
initDomainIndexTable: () => {
|
||||
const toggler = (el) => {
|
||||
const idNumber = el.id.substr(7);
|
||||
const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`);
|
||||
if (el.src.substr(-9) === "minus.png") {
|
||||
el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = "none"));
|
||||
} else {
|
||||
el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`;
|
||||
toggledRows.forEach((el) => (el.style.display = ""));
|
||||
}
|
||||
};
|
||||
|
||||
const togglerElements = document.querySelectorAll("img.toggler");
|
||||
togglerElements.forEach((el) =>
|
||||
el.addEventListener("click", (event) => toggler(event.currentTarget))
|
||||
);
|
||||
togglerElements.forEach((el) => (el.style.display = ""));
|
||||
if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler);
|
||||
},
|
||||
|
||||
initOnKeyListeners: () => {
|
||||
// only install a listener if it is really needed
|
||||
if (
|
||||
!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS &&
|
||||
!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS
|
||||
)
|
||||
return;
|
||||
|
||||
const blacklistedElements = new Set([
|
||||
"TEXTAREA",
|
||||
"INPUT",
|
||||
"SELECT",
|
||||
"BUTTON",
|
||||
]);
|
||||
document.addEventListener("keydown", (event) => {
|
||||
if (blacklistedElements.has(document.activeElement.tagName)) return; // bail for input elements
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) return; // bail with special keys
|
||||
|
||||
if (!event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case "ArrowLeft":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const prevLink = document.querySelector('link[rel="prev"]');
|
||||
if (prevLink && prevLink.href) {
|
||||
window.location.href = prevLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "ArrowRight":
|
||||
if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break;
|
||||
|
||||
const nextLink = document.querySelector('link[rel="next"]');
|
||||
if (nextLink && nextLink.href) {
|
||||
window.location.href = nextLink.href;
|
||||
event.preventDefault();
|
||||
}
|
||||
break;
|
||||
case "Escape":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.hideSearchWords();
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
// some keyboard layouts may need Shift to get /
|
||||
switch (event.key) {
|
||||
case "/":
|
||||
if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break;
|
||||
Documentation.focusSearchBar();
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
// quick alias for translations
|
||||
const _ = Documentation.gettext;
|
||||
|
||||
_ready(Documentation.init);
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '',
|
||||
LANGUAGE: 'en',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
FILE_SUFFIX: '.html',
|
||||
LINK_SUFFIX: '.html',
|
||||
HAS_SOURCE: true,
|
||||
SOURCELINK_SUFFIX: '.txt',
|
||||
NAVIGATION_WITH_KEYS: false,
|
||||
SHOW_SEARCH_SUMMARY: true,
|
||||
ENABLE_SEARCH_SHORTCUTS: true,
|
||||
};
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 286 B |
Vendored
+10881
File diff suppressed because it is too large
Load Diff
Vendored
+2
File diff suppressed because one or more lines are too long
Vendored
+1
@@ -0,0 +1 @@
|
||||
!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=4)}({4:function(e,t,r){}});
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @preserve HTML5 Shiv 3.7.3-pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=y.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=y.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),y.elements=c+" "+a,j(b)}function f(a){var b=x[a[v]];return b||(b={},w++,a[v]=w,x[w]=b),b}function g(a,c,d){if(c||(c=b),q)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():u.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||t.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),q)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return y.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(y,b.frag)}function j(a){a||(a=b);var d=f(a);return!y.shivCSS||p||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),q||i(a,d),a}function k(a){for(var b,c=a.getElementsByTagName("*"),e=c.length,f=RegExp("^(?:"+d().join("|")+")$","i"),g=[];e--;)b=c[e],f.test(b.nodeName)&&g.push(b.applyElement(l(b)));return g}function l(a){for(var b,c=a.attributes,d=c.length,e=a.ownerDocument.createElement(A+":"+a.nodeName);d--;)b=c[d],b.specified&&e.setAttribute(b.nodeName,b.nodeValue);return e.style.cssText=a.style.cssText,e}function m(a){for(var b,c=a.split("{"),e=c.length,f=RegExp("(^|[\\s,>+~])("+d().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),g="$1"+A+"\\:$2";e--;)b=c[e]=c[e].split("}"),b[b.length-1]=b[b.length-1].replace(f,g),c[e]=b.join("}");return c.join("{")}function n(a){for(var b=a.length;b--;)a[b].removeNode()}function o(a){function b(){clearTimeout(g._removeSheetTimer),d&&d.removeNode(!0),d=null}var d,e,g=f(a),h=a.namespaces,i=a.parentWindow;return!B||a.printShived?a:("undefined"==typeof h[A]&&h.add(A),i.attachEvent("onbeforeprint",function(){b();for(var f,g,h,i=a.styleSheets,j=[],l=i.length,n=Array(l);l--;)n[l]=i[l];for(;h=n.pop();)if(!h.disabled&&z.test(h.media)){try{f=h.imports,g=f.length}catch(o){g=0}for(l=0;g>l;l++)n.push(f[l]);try{j.push(h.cssText)}catch(o){}}j=m(j.reverse().join("")),e=k(a),d=c(a,j)}),i.attachEvent("onafterprint",function(){n(e),clearTimeout(g._removeSheetTimer),g._removeSheetTimer=setTimeout(b,500)}),a.printShived=!0,a)}var p,q,r="3.7.3",s=a.html5||{},t=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,u=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,v="_html5shiv",w=0,x={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",p="hidden"in a,q=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){p=!0,q=!0}}();var y={elements:s.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:r,shivCSS:s.shivCSS!==!1,supportsUnknownElements:q,shivMethods:s.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=y,j(b);var z=/^$|\b(?:all|print)\b/,A="html5shiv",B=!q&&function(){var c=b.documentElement;return!("undefined"==typeof b.namespaces||"undefined"==typeof b.parentWindow||"undefined"==typeof c.applyElement||"undefined"==typeof c.removeNode||"undefined"==typeof a.attachEvent)}();y.type+=" print",y.shivPrint=o,o(b),"object"==typeof module&&module.exports&&(module.exports=y)}("undefined"!=typeof window?window:this,document);
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
*/
|
||||
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3-pre",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+199
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* language_data.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This script contains the language-specific data used by searchtools.js,
|
||||
* namely the list of stopwords, stemmer, scorer and splitter.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"];
|
||||
|
||||
|
||||
/* Non-minified version is copied as a separate JS file, is available */
|
||||
|
||||
/**
|
||||
* Porter Stemmer
|
||||
*/
|
||||
var Stemmer = function() {
|
||||
|
||||
var step2list = {
|
||||
ational: 'ate',
|
||||
tional: 'tion',
|
||||
enci: 'ence',
|
||||
anci: 'ance',
|
||||
izer: 'ize',
|
||||
bli: 'ble',
|
||||
alli: 'al',
|
||||
entli: 'ent',
|
||||
eli: 'e',
|
||||
ousli: 'ous',
|
||||
ization: 'ize',
|
||||
ation: 'ate',
|
||||
ator: 'ate',
|
||||
alism: 'al',
|
||||
iveness: 'ive',
|
||||
fulness: 'ful',
|
||||
ousness: 'ous',
|
||||
aliti: 'al',
|
||||
iviti: 'ive',
|
||||
biliti: 'ble',
|
||||
logi: 'log'
|
||||
};
|
||||
|
||||
var step3list = {
|
||||
icate: 'ic',
|
||||
ative: '',
|
||||
alize: 'al',
|
||||
iciti: 'ic',
|
||||
ical: 'ic',
|
||||
ful: '',
|
||||
ness: ''
|
||||
};
|
||||
|
||||
var c = "[^aeiou]"; // consonant
|
||||
var v = "[aeiouy]"; // vowel
|
||||
var C = c + "[^aeiouy]*"; // consonant sequence
|
||||
var V = v + "[aeiou]*"; // vowel sequence
|
||||
|
||||
var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0
|
||||
var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1
|
||||
var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1
|
||||
var s_v = "^(" + C + ")?" + v; // vowel in stem
|
||||
|
||||
this.stemWord = function (w) {
|
||||
var stem;
|
||||
var suffix;
|
||||
var firstch;
|
||||
var origword = w;
|
||||
|
||||
if (w.length < 3)
|
||||
return w;
|
||||
|
||||
var re;
|
||||
var re2;
|
||||
var re3;
|
||||
var re4;
|
||||
|
||||
firstch = w.substr(0,1);
|
||||
if (firstch == "y")
|
||||
w = firstch.toUpperCase() + w.substr(1);
|
||||
|
||||
// Step 1a
|
||||
re = /^(.+?)(ss|i)es$/;
|
||||
re2 = /^(.+?)([^s])s$/;
|
||||
|
||||
if (re.test(w))
|
||||
w = w.replace(re,"$1$2");
|
||||
else if (re2.test(w))
|
||||
w = w.replace(re2,"$1$2");
|
||||
|
||||
// Step 1b
|
||||
re = /^(.+?)eed$/;
|
||||
re2 = /^(.+?)(ed|ing)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(fp[1])) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1];
|
||||
re2 = new RegExp(s_v);
|
||||
if (re2.test(stem)) {
|
||||
w = stem;
|
||||
re2 = /(at|bl|iz)$/;
|
||||
re3 = new RegExp("([^aeiouylsz])\\1$");
|
||||
re4 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re2.test(w))
|
||||
w = w + "e";
|
||||
else if (re3.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
else if (re4.test(w))
|
||||
w = w + "e";
|
||||
}
|
||||
}
|
||||
|
||||
// Step 1c
|
||||
re = /^(.+?)y$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(s_v);
|
||||
if (re.test(stem))
|
||||
w = stem + "i";
|
||||
}
|
||||
|
||||
// Step 2
|
||||
re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step2list[suffix];
|
||||
}
|
||||
|
||||
// Step 3
|
||||
re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
suffix = fp[2];
|
||||
re = new RegExp(mgr0);
|
||||
if (re.test(stem))
|
||||
w = stem + step3list[suffix];
|
||||
}
|
||||
|
||||
// Step 4
|
||||
re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/;
|
||||
re2 = /^(.+?)(s|t)(ion)$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
if (re.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
else if (re2.test(w)) {
|
||||
var fp = re2.exec(w);
|
||||
stem = fp[1] + fp[2];
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re2.test(stem))
|
||||
w = stem;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
re = /^(.+?)e$/;
|
||||
if (re.test(w)) {
|
||||
var fp = re.exec(w);
|
||||
stem = fp[1];
|
||||
re = new RegExp(mgr1);
|
||||
re2 = new RegExp(meq1);
|
||||
re3 = new RegExp("^" + C + v + "[^aeiouwxy]$");
|
||||
if (re.test(stem) || (re2.test(stem) && !(re3.test(stem))))
|
||||
w = stem;
|
||||
}
|
||||
re = /ll$/;
|
||||
re2 = new RegExp(mgr1);
|
||||
if (re.test(w) && re2.test(w)) {
|
||||
re = /.$/;
|
||||
w = w.replace(re,"");
|
||||
}
|
||||
|
||||
// and turn initial Y back to y
|
||||
if (firstch == "y")
|
||||
w = firstch.toLowerCase() + w.substr(1);
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 90 B |
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 90 B |
Vendored
+74
@@ -0,0 +1,74 @@
|
||||
pre { line-height: 125%; }
|
||||
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||
.highlight .hll { background-color: #ffffcc }
|
||||
.highlight { background: #f8f8f8; }
|
||||
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||
.highlight .err { border: 1px solid #FF0000 } /* Error */
|
||||
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
|
||||
.highlight .o { color: #666666 } /* Operator */
|
||||
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
|
||||
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
|
||||
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
|
||||
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
|
||||
.highlight .gd { color: #A00000 } /* Generic.Deleted */
|
||||
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||
.highlight .gr { color: #E40000 } /* Generic.Error */
|
||||
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
.highlight .gi { color: #008400 } /* Generic.Inserted */
|
||||
.highlight .go { color: #717171 } /* Generic.Output */
|
||||
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
.highlight .gt { color: #0044DD } /* Generic.Traceback */
|
||||
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
|
||||
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
.highlight .kt { color: #B00040 } /* Keyword.Type */
|
||||
.highlight .m { color: #666666 } /* Literal.Number */
|
||||
.highlight .s { color: #BA2121 } /* Literal.String */
|
||||
.highlight .na { color: #687822 } /* Name.Attribute */
|
||||
.highlight .nb { color: #008000 } /* Name.Builtin */
|
||||
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
.highlight .no { color: #880000 } /* Name.Constant */
|
||||
.highlight .nd { color: #AA22FF } /* Name.Decorator */
|
||||
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||
.highlight .nf { color: #0000FF } /* Name.Function */
|
||||
.highlight .nl { color: #767600 } /* Name.Label */
|
||||
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
.highlight .nv { color: #19177C } /* Name.Variable */
|
||||
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||
.highlight .mb { color: #666666 } /* Literal.Number.Bin */
|
||||
.highlight .mf { color: #666666 } /* Literal.Number.Float */
|
||||
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
|
||||
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
|
||||
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
|
||||
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
|
||||
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
|
||||
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
|
||||
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
|
||||
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
|
||||
.highlight .sx { color: #008000 } /* Literal.String.Other */
|
||||
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
|
||||
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
|
||||
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
.highlight .fm { color: #0000FF } /* Name.Function.Magic */
|
||||
.highlight .vc { color: #19177C } /* Name.Variable.Class */
|
||||
.highlight .vg { color: #19177C } /* Name.Variable.Global */
|
||||
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
|
||||
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
|
||||
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
Vendored
+530
@@ -0,0 +1,530 @@
|
||||
/*
|
||||
* searchtools.js
|
||||
* ~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* Sphinx JavaScript utilities for the full-text search.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Simple result scoring code.
|
||||
*/
|
||||
if (typeof Scorer === "undefined") {
|
||||
var Scorer = {
|
||||
// Implement the following function to further tweak the score for each result
|
||||
// The function takes a result array [docname, title, anchor, descr, score, filename]
|
||||
// and returns the new score.
|
||||
/*
|
||||
score: result => {
|
||||
const [docname, title, anchor, descr, score, filename] = result
|
||||
return score
|
||||
},
|
||||
*/
|
||||
|
||||
// query matches the full name of an object
|
||||
objNameMatch: 11,
|
||||
// or matches in the last dotted part of the object name
|
||||
objPartialMatch: 6,
|
||||
// Additive scores depending on the priority of the object
|
||||
objPrio: {
|
||||
0: 15, // used to be importantResults
|
||||
1: 5, // used to be objectResults
|
||||
2: -5, // used to be unimportantResults
|
||||
},
|
||||
// Used when the priority is not in the mapping.
|
||||
objPrioDefault: 0,
|
||||
|
||||
// query found in title
|
||||
title: 15,
|
||||
partialTitle: 7,
|
||||
// query found in terms
|
||||
term: 5,
|
||||
partialTerm: 2,
|
||||
};
|
||||
}
|
||||
|
||||
const _removeChildren = (element) => {
|
||||
while (element && element.lastChild) element.removeChild(element.lastChild);
|
||||
};
|
||||
|
||||
/**
|
||||
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping
|
||||
*/
|
||||
const _escapeRegExp = (string) =>
|
||||
string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
|
||||
|
||||
const _displayItem = (item, highlightTerms, searchTerms) => {
|
||||
const docBuilder = DOCUMENTATION_OPTIONS.BUILDER;
|
||||
const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT;
|
||||
const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX;
|
||||
const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX;
|
||||
const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY;
|
||||
|
||||
const [docName, title, anchor, descr] = item;
|
||||
|
||||
let listItem = document.createElement("li");
|
||||
let requestUrl;
|
||||
let linkUrl;
|
||||
if (docBuilder === "dirhtml") {
|
||||
// dirhtml builder
|
||||
let dirname = docName + "/";
|
||||
if (dirname.match(/\/index\/$/))
|
||||
dirname = dirname.substring(0, dirname.length - 6);
|
||||
else if (dirname === "index/") dirname = "";
|
||||
requestUrl = docUrlRoot + dirname;
|
||||
linkUrl = requestUrl;
|
||||
} else {
|
||||
// normal html builders
|
||||
requestUrl = docUrlRoot + docName + docFileSuffix;
|
||||
linkUrl = docName + docLinkSuffix;
|
||||
}
|
||||
const params = new URLSearchParams();
|
||||
params.set("highlight", [...highlightTerms].join(" "));
|
||||
let linkEl = listItem.appendChild(document.createElement("a"));
|
||||
linkEl.href = linkUrl + "?" + params.toString() + anchor;
|
||||
linkEl.innerHTML = title;
|
||||
if (descr)
|
||||
listItem.appendChild(document.createElement("span")).innerHTML =
|
||||
" (" + descr + ")";
|
||||
else if (showSearchSummary)
|
||||
fetch(requestUrl)
|
||||
.then((responseData) => responseData.text())
|
||||
.then((data) => {
|
||||
if (data)
|
||||
listItem.appendChild(
|
||||
Search.makeSearchSummary(data, searchTerms, highlightTerms)
|
||||
);
|
||||
});
|
||||
Search.output.appendChild(listItem);
|
||||
};
|
||||
const _finishSearch = (resultCount) => {
|
||||
Search.stopPulse();
|
||||
Search.title.innerText = _("Search Results");
|
||||
if (!resultCount)
|
||||
Search.status.innerText = Documentation.gettext(
|
||||
"Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories."
|
||||
);
|
||||
else
|
||||
Search.status.innerText = _(
|
||||
`Search finished, found ${resultCount} page(s) matching the search query.`
|
||||
);
|
||||
};
|
||||
const _displayNextItem = (
|
||||
results,
|
||||
resultCount,
|
||||
highlightTerms,
|
||||
searchTerms
|
||||
) => {
|
||||
// results left, load the summary and display it
|
||||
// this is intended to be dynamic (don't sub resultsCount)
|
||||
if (results.length) {
|
||||
_displayItem(results.pop(), highlightTerms, searchTerms);
|
||||
setTimeout(
|
||||
() => _displayNextItem(results, resultCount, highlightTerms, searchTerms),
|
||||
5
|
||||
);
|
||||
}
|
||||
// search finished, update title and status message
|
||||
else _finishSearch(resultCount);
|
||||
};
|
||||
|
||||
/**
|
||||
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a
|
||||
* custom function per language.
|
||||
*
|
||||
* The regular expression works by splitting the string on consecutive characters
|
||||
* that are not Unicode letters, numbers, underscores, or emoji characters.
|
||||
* This is the same as ``\W+`` in Python, preserving the surrogate pair area.
|
||||
*/
|
||||
if (typeof splitQuery === "undefined") {
|
||||
var splitQuery = (query) => query
|
||||
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu)
|
||||
.filter(term => term) // remove remaining empty strings
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Module
|
||||
*/
|
||||
const Search = {
|
||||
_index: null,
|
||||
_queued_query: null,
|
||||
_pulse_status: -1,
|
||||
|
||||
htmlToText: (htmlString) => {
|
||||
const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html');
|
||||
htmlElement.querySelectorAll(".headerlink").forEach((el) => { el.remove() });
|
||||
const docContent = htmlElement.querySelector('[role="main"]');
|
||||
if (docContent !== undefined) return docContent.textContent;
|
||||
console.warn(
|
||||
"Content block not found. Sphinx search tries to obtain it via '[role=main]'. Could you check your theme or template."
|
||||
);
|
||||
return "";
|
||||
},
|
||||
|
||||
init: () => {
|
||||
const query = new URLSearchParams(window.location.search).get("q");
|
||||
document
|
||||
.querySelectorAll('input[name="q"]')
|
||||
.forEach((el) => (el.value = query));
|
||||
if (query) Search.performSearch(query);
|
||||
},
|
||||
|
||||
loadIndex: (url) =>
|
||||
(document.body.appendChild(document.createElement("script")).src = url),
|
||||
|
||||
setIndex: (index) => {
|
||||
Search._index = index;
|
||||
if (Search._queued_query !== null) {
|
||||
const query = Search._queued_query;
|
||||
Search._queued_query = null;
|
||||
Search.query(query);
|
||||
}
|
||||
},
|
||||
|
||||
hasIndex: () => Search._index !== null,
|
||||
|
||||
deferQuery: (query) => (Search._queued_query = query),
|
||||
|
||||
stopPulse: () => (Search._pulse_status = -1),
|
||||
|
||||
startPulse: () => {
|
||||
if (Search._pulse_status >= 0) return;
|
||||
|
||||
const pulse = () => {
|
||||
Search._pulse_status = (Search._pulse_status + 1) % 4;
|
||||
Search.dots.innerText = ".".repeat(Search._pulse_status);
|
||||
if (Search._pulse_status >= 0) window.setTimeout(pulse, 500);
|
||||
};
|
||||
pulse();
|
||||
},
|
||||
|
||||
/**
|
||||
* perform a search for something (or wait until index is loaded)
|
||||
*/
|
||||
performSearch: (query) => {
|
||||
// create the required interface elements
|
||||
const searchText = document.createElement("h2");
|
||||
searchText.textContent = _("Searching");
|
||||
const searchSummary = document.createElement("p");
|
||||
searchSummary.classList.add("search-summary");
|
||||
searchSummary.innerText = "";
|
||||
const searchList = document.createElement("ul");
|
||||
searchList.classList.add("search");
|
||||
|
||||
const out = document.getElementById("search-results");
|
||||
Search.title = out.appendChild(searchText);
|
||||
Search.dots = Search.title.appendChild(document.createElement("span"));
|
||||
Search.status = out.appendChild(searchSummary);
|
||||
Search.output = out.appendChild(searchList);
|
||||
|
||||
const searchProgress = document.getElementById("search-progress");
|
||||
// Some themes don't use the search progress node
|
||||
if (searchProgress) {
|
||||
searchProgress.innerText = _("Preparing search...");
|
||||
}
|
||||
Search.startPulse();
|
||||
|
||||
// index already loaded, the browser was quick!
|
||||
if (Search.hasIndex()) Search.query(query);
|
||||
else Search.deferQuery(query);
|
||||
},
|
||||
|
||||
/**
|
||||
* execute search (requires search index to be loaded)
|
||||
*/
|
||||
query: (query) => {
|
||||
// stem the search terms and add them to the correct list
|
||||
const stemmer = new Stemmer();
|
||||
const searchTerms = new Set();
|
||||
const excludedTerms = new Set();
|
||||
const highlightTerms = new Set();
|
||||
const objectTerms = new Set(splitQuery(query.toLowerCase().trim()));
|
||||
splitQuery(query.trim()).forEach((queryTerm) => {
|
||||
const queryTermLower = queryTerm.toLowerCase();
|
||||
|
||||
// maybe skip this "word"
|
||||
// stopwords array is from language_data.js
|
||||
if (
|
||||
stopwords.indexOf(queryTermLower) !== -1 ||
|
||||
queryTerm.match(/^\d+$/)
|
||||
)
|
||||
return;
|
||||
|
||||
// stem the word
|
||||
let word = stemmer.stemWord(queryTermLower);
|
||||
// select the correct list
|
||||
if (word[0] === "-") excludedTerms.add(word.substr(1));
|
||||
else {
|
||||
searchTerms.add(word);
|
||||
highlightTerms.add(queryTermLower);
|
||||
}
|
||||
});
|
||||
|
||||
// console.debug("SEARCH: searching for:");
|
||||
// console.info("required: ", [...searchTerms]);
|
||||
// console.info("excluded: ", [...excludedTerms]);
|
||||
|
||||
// array of [docname, title, anchor, descr, score, filename]
|
||||
let results = [];
|
||||
_removeChildren(document.getElementById("search-progress"));
|
||||
|
||||
// lookup as object
|
||||
objectTerms.forEach((term) =>
|
||||
results.push(...Search.performObjectSearch(term, objectTerms))
|
||||
);
|
||||
|
||||
// lookup as search terms in fulltext
|
||||
results.push(...Search.performTermsSearch(searchTerms, excludedTerms));
|
||||
|
||||
// let the scorer override scores with a custom scoring function
|
||||
if (Scorer.score) results.forEach((item) => (item[4] = Scorer.score(item)));
|
||||
|
||||
// now sort the results by score (in opposite order of appearance, since the
|
||||
// display function below uses pop() to retrieve items) and then
|
||||
// alphabetically
|
||||
results.sort((a, b) => {
|
||||
const leftScore = a[4];
|
||||
const rightScore = b[4];
|
||||
if (leftScore === rightScore) {
|
||||
// same score: sort alphabetically
|
||||
const leftTitle = a[1].toLowerCase();
|
||||
const rightTitle = b[1].toLowerCase();
|
||||
if (leftTitle === rightTitle) return 0;
|
||||
return leftTitle > rightTitle ? -1 : 1; // inverted is intentional
|
||||
}
|
||||
return leftScore > rightScore ? 1 : -1;
|
||||
});
|
||||
|
||||
// remove duplicate search results
|
||||
// note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept
|
||||
let seen = new Set();
|
||||
results = results.reverse().reduce((acc, result) => {
|
||||
let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(',');
|
||||
if (!seen.has(resultStr)) {
|
||||
acc.push(result);
|
||||
seen.add(resultStr);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
results = results.reverse();
|
||||
|
||||
// for debugging
|
||||
//Search.lastresults = results.slice(); // a copy
|
||||
// console.info("search results:", Search.lastresults);
|
||||
|
||||
// print the results
|
||||
_displayNextItem(results, results.length, highlightTerms, searchTerms);
|
||||
},
|
||||
|
||||
/**
|
||||
* search for object names
|
||||
*/
|
||||
performObjectSearch: (object, objectTerms) => {
|
||||
const filenames = Search._index.filenames;
|
||||
const docNames = Search._index.docnames;
|
||||
const objects = Search._index.objects;
|
||||
const objNames = Search._index.objnames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const results = [];
|
||||
|
||||
const objectSearchCallback = (prefix, match) => {
|
||||
const name = match[4]
|
||||
const fullname = (prefix ? prefix + "." : "") + name;
|
||||
const fullnameLower = fullname.toLowerCase();
|
||||
if (fullnameLower.indexOf(object) < 0) return;
|
||||
|
||||
let score = 0;
|
||||
const parts = fullnameLower.split(".");
|
||||
|
||||
// check for different match types: exact matches of full name or
|
||||
// "last name" (i.e. last dotted part)
|
||||
if (fullnameLower === object || parts.slice(-1)[0] === object)
|
||||
score += Scorer.objNameMatch;
|
||||
else if (parts.slice(-1)[0].indexOf(object) > -1)
|
||||
score += Scorer.objPartialMatch; // matches in last name
|
||||
|
||||
const objName = objNames[match[1]][2];
|
||||
const title = titles[match[0]];
|
||||
|
||||
// If more than one term searched for, we require other words to be
|
||||
// found in the name/title/description
|
||||
const otherTerms = new Set(objectTerms);
|
||||
otherTerms.delete(object);
|
||||
if (otherTerms.size > 0) {
|
||||
const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase();
|
||||
if (
|
||||
[...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0)
|
||||
)
|
||||
return;
|
||||
}
|
||||
|
||||
let anchor = match[3];
|
||||
if (anchor === "") anchor = fullname;
|
||||
else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname;
|
||||
|
||||
const descr = objName + _(", in ") + title;
|
||||
|
||||
// add custom score for some objects according to scorer
|
||||
if (Scorer.objPrio.hasOwnProperty(match[2]))
|
||||
score += Scorer.objPrio[match[2]];
|
||||
else score += Scorer.objPrioDefault;
|
||||
|
||||
results.push([
|
||||
docNames[match[0]],
|
||||
fullname,
|
||||
"#" + anchor,
|
||||
descr,
|
||||
score,
|
||||
filenames[match[0]],
|
||||
]);
|
||||
};
|
||||
Object.keys(objects).forEach((prefix) =>
|
||||
objects[prefix].forEach((array) =>
|
||||
objectSearchCallback(prefix, array)
|
||||
)
|
||||
);
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* search for full-text terms in the index
|
||||
*/
|
||||
performTermsSearch: (searchTerms, excludedTerms) => {
|
||||
// prepare search
|
||||
const terms = Search._index.terms;
|
||||
const titleTerms = Search._index.titleterms;
|
||||
const docNames = Search._index.docnames;
|
||||
const filenames = Search._index.filenames;
|
||||
const titles = Search._index.titles;
|
||||
|
||||
const scoreMap = new Map();
|
||||
const fileMap = new Map();
|
||||
|
||||
// perform the search on the required terms
|
||||
searchTerms.forEach((word) => {
|
||||
const files = [];
|
||||
const arr = [
|
||||
{ files: terms[word], score: Scorer.term },
|
||||
{ files: titleTerms[word], score: Scorer.title },
|
||||
];
|
||||
// add support for partial matches
|
||||
if (word.length > 2) {
|
||||
const escapedWord = _escapeRegExp(word);
|
||||
Object.keys(terms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !terms[word])
|
||||
arr.push({ files: terms[term], score: Scorer.partialTerm });
|
||||
});
|
||||
Object.keys(titleTerms).forEach((term) => {
|
||||
if (term.match(escapedWord) && !titleTerms[word])
|
||||
arr.push({ files: titleTerms[word], score: Scorer.partialTitle });
|
||||
});
|
||||
}
|
||||
|
||||
// no match but word was a required one
|
||||
if (arr.every((record) => record.files === undefined)) return;
|
||||
|
||||
// found search word in contents
|
||||
arr.forEach((record) => {
|
||||
if (record.files === undefined) return;
|
||||
|
||||
let recordFiles = record.files;
|
||||
if (recordFiles.length === undefined) recordFiles = [recordFiles];
|
||||
files.push(...recordFiles);
|
||||
|
||||
// set score for the word in each file
|
||||
recordFiles.forEach((file) => {
|
||||
if (!scoreMap.has(file)) scoreMap.set(file, {});
|
||||
scoreMap.get(file)[word] = record.score;
|
||||
});
|
||||
});
|
||||
|
||||
// create the mapping
|
||||
files.forEach((file) => {
|
||||
if (fileMap.has(file) && fileMap.get(file).indexOf(word) === -1)
|
||||
fileMap.get(file).push(word);
|
||||
else fileMap.set(file, [word]);
|
||||
});
|
||||
});
|
||||
|
||||
// now check if the files don't contain excluded terms
|
||||
const results = [];
|
||||
for (const [file, wordList] of fileMap) {
|
||||
// check if all requirements are matched
|
||||
|
||||
// as search terms with length < 3 are discarded
|
||||
const filteredTermCount = [...searchTerms].filter(
|
||||
(term) => term.length > 2
|
||||
).length;
|
||||
if (
|
||||
wordList.length !== searchTerms.size &&
|
||||
wordList.length !== filteredTermCount
|
||||
)
|
||||
continue;
|
||||
|
||||
// ensure that none of the excluded terms is in the search result
|
||||
if (
|
||||
[...excludedTerms].some(
|
||||
(term) =>
|
||||
terms[term] === file ||
|
||||
titleTerms[term] === file ||
|
||||
(terms[term] || []).includes(file) ||
|
||||
(titleTerms[term] || []).includes(file)
|
||||
)
|
||||
)
|
||||
break;
|
||||
|
||||
// select one (max) score for the file.
|
||||
const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w]));
|
||||
// add result to the result list
|
||||
results.push([
|
||||
docNames[file],
|
||||
titles[file],
|
||||
"",
|
||||
null,
|
||||
score,
|
||||
filenames[file],
|
||||
]);
|
||||
}
|
||||
return results;
|
||||
},
|
||||
|
||||
/**
|
||||
* helper function to return a node containing the
|
||||
* search summary for a given text. keywords is a list
|
||||
* of stemmed words, highlightWords is the list of normal, unstemmed
|
||||
* words. the first one is used to find the occurrence, the
|
||||
* latter for highlighting it.
|
||||
*/
|
||||
makeSearchSummary: (htmlText, keywords, highlightWords) => {
|
||||
const text = Search.htmlToText(htmlText);
|
||||
if (text === "") return null;
|
||||
|
||||
const textLower = text.toLowerCase();
|
||||
const actualStartPosition = [...keywords]
|
||||
.map((k) => textLower.indexOf(k.toLowerCase()))
|
||||
.filter((i) => i > -1)
|
||||
.slice(-1)[0];
|
||||
const startWithContext = Math.max(actualStartPosition - 120, 0);
|
||||
|
||||
const top = startWithContext === 0 ? "" : "...";
|
||||
const tail = startWithContext + 240 < text.length ? "..." : "";
|
||||
|
||||
let summary = document.createElement("p");
|
||||
summary.classList.add("context");
|
||||
summary.textContent = top + text.substr(startWithContext, 240).trim() + tail;
|
||||
|
||||
highlightWords.forEach((highlightWord) =>
|
||||
_highlightText(summary, highlightWord, "highlighted")
|
||||
);
|
||||
|
||||
return summary;
|
||||
},
|
||||
};
|
||||
|
||||
_ready(Search.init);
|
||||
Vendored
+2042
File diff suppressed because it is too large
Load Diff
Vendored
+6
File diff suppressed because one or more lines are too long
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Allocator module — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="prev" title="Lib.LinearCode module" href="Lib.LinearCode.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Lib.Allocator module</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
<a href="../_sources/api/Lib.Allocator.rst.txt" rel="nofollow"> View page source</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<section id="module-Lib.Allocator">
|
||||
<span id="lib-allocator-module"></span><h1>Lib.Allocator module<a class="headerlink" href="#module-Lib.Allocator" title="Permalink to this heading"></a></h1>
|
||||
<p>This file defines the base class <a class="reference internal" href="#Lib.Allocator.Allocator" title="Lib.Allocator.Allocator"><code class="xref py py-class docutils literal notranslate"><span class="pre">Allocator</span></code></a>
|
||||
and the naïve implementation <a class="reference internal" href="#Lib.Allocator.NaiveAllocator" title="Lib.Allocator.NaiveAllocator"><code class="xref py py-class docutils literal notranslate"><span class="pre">NaiveAllocator</span></code></a>.</p>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.Allocator">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Allocator.</span></span><span class="sig-name descname"><span class="pre">Allocator</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">fdata</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><span class="pre">FunctionData</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Allocator.html#Allocator"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.Allocator" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
<p>General base class for Naive, AllInMem and Smart Allocators.
|
||||
Replace all temporaries in the code with actual data locations.</p>
|
||||
<p>Allocation is done in two steps:</p>
|
||||
<ul class="simple">
|
||||
<li><p>First, <a class="reference internal" href="#Lib.Allocator.Allocator.prepare" title="Lib.Allocator.Allocator.prepare"><code class="xref py py-meth docutils literal notranslate"><span class="pre">prepare()</span></code></a> is responsible for calling
|
||||
<a class="reference internal" href="Lib.Operands.html#Lib.Operands.TemporaryPool.set_temp_allocation" title="Lib.Operands.TemporaryPool.set_temp_allocation"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Lib.Operands.TemporaryPool.set_temp_allocation()</span></code></a>
|
||||
with a mapping from temporaries to where they should actually be stored
|
||||
(in registers or in memory).</p></li>
|
||||
<li><p>Then, <a class="reference internal" href="#Lib.Allocator.Allocator.replace" title="Lib.Allocator.Allocator.replace"><code class="xref py py-meth docutils literal notranslate"><span class="pre">replace()</span></code></a> is called for each instruction in order to
|
||||
replace the temporary operands with the previously assigned locations
|
||||
(and possibly add some instructions before or after).
|
||||
Concretely, it returns a list of instructions that should replace the original
|
||||
instruction. The actual iteration over all the instructions is handled transparently
|
||||
by <a class="reference internal" href="Lib.LinearCode.html#Lib.LinearCode.LinearCode.iter_statements" title="Lib.LinearCode.LinearCode.iter_statements"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Lib.LinearCode.LinearCode.iter_statements()</span></code></a>.</p></li>
|
||||
</ul>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.Allocator.prepare">
|
||||
<span class="sig-name descname"><span class="pre">prepare</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/Allocator.html#Allocator.prepare"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.Allocator.prepare" title="Permalink to this definition"></a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.Allocator.replace">
|
||||
<span class="sig-name descname"><span class="pre">replace</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">instr</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instruction" title="Lib.Statement.Instruction"><span class="pre">Instruction</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instruction" title="Lib.Statement.Instruction"><span class="pre">Instruction</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/Allocator.html#Allocator.replace"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.Allocator.replace" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Transform an instruction with temporaries into a list of instructions.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.Allocator.rewriteCode">
|
||||
<span class="sig-name descname"><span class="pre">rewriteCode</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">listcode</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/Allocator.html#Allocator.rewriteCode"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.Allocator.rewriteCode" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Modify the code to replace temporaries with
|
||||
registers or memory locations.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.NaiveAllocator">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Allocator.</span></span><span class="sig-name descname"><span class="pre">NaiveAllocator</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">fdata</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><span class="pre">FunctionData</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Allocator.html#NaiveAllocator"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.NaiveAllocator" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Allocator.Allocator" title="Lib.Allocator.Allocator"><code class="xref py py-class docutils literal notranslate"><span class="pre">Allocator</span></code></a></p>
|
||||
<p>Naive Allocator: try to assign a register to each temporary,
|
||||
fails if there are more temporaries than registers.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.NaiveAllocator.prepare">
|
||||
<span class="sig-name descname"><span class="pre">prepare</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/Allocator.html#NaiveAllocator.prepare"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.NaiveAllocator.prepare" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Allocate all temporaries to registers.
|
||||
Fail if there are too many temporaries.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Allocator.NaiveAllocator.replace">
|
||||
<span class="sig-name descname"><span class="pre">replace</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">old_instr</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instruction" title="Lib.Statement.Instruction"><span class="pre">Instruction</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instruction" title="Lib.Statement.Instruction"><span class="pre">Instruction</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/Allocator.html#NaiveAllocator.replace"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Allocator.NaiveAllocator.replace" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Replace Temporary operands with the corresponding allocated Register.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||
<a href="Lib.LinearCode.html" class="btn btn-neutral float-left" title="Lib.LinearCode module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,141 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Errors module — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Lib.Statement module" href="Lib.Statement.html" />
|
||||
<link rel="prev" title="Welcome to MiniC’s documentation!" href="../index.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Lib.Errors module</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
<a href="../_sources/api/Lib.Errors.rst.txt" rel="nofollow"> View page source</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<section id="module-Lib.Errors">
|
||||
<span id="lib-errors-module"></span><h1>Lib.Errors module<a class="headerlink" href="#module-Lib.Errors" title="Permalink to this heading"></a></h1>
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="Lib.Errors.AllocationError">
|
||||
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Errors.</span></span><span class="sig-name descname"><span class="pre">AllocationError</span></span><a class="reference internal" href="../_modules/Lib/Errors.html#AllocationError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Errors.AllocationError" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="Lib.Errors.MiniCInternalError">
|
||||
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Errors.</span></span><span class="sig-name descname"><span class="pre">MiniCInternalError</span></span><a class="reference internal" href="../_modules/Lib/Errors.html#MiniCInternalError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Errors.MiniCInternalError" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="Lib.Errors.MiniCRuntimeError">
|
||||
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Errors.</span></span><span class="sig-name descname"><span class="pre">MiniCRuntimeError</span></span><a class="reference internal" href="../_modules/Lib/Errors.html#MiniCRuntimeError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Errors.MiniCRuntimeError" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="Lib.Errors.MiniCTypeError">
|
||||
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Errors.</span></span><span class="sig-name descname"><span class="pre">MiniCTypeError</span></span><a class="reference internal" href="../_modules/Lib/Errors.html#MiniCTypeError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Errors.MiniCTypeError" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py exception">
|
||||
<dt class="sig sig-object py" id="Lib.Errors.MiniCUnsupportedError">
|
||||
<em class="property"><span class="pre">exception</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Errors.</span></span><span class="sig-name descname"><span class="pre">MiniCUnsupportedError</span></span><a class="reference internal" href="../_modules/Lib/Errors.html#MiniCUnsupportedError"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Errors.MiniCUnsupportedError" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">Exception</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||
<a href="../index.html" class="btn btn-neutral float-left" title="Welcome to MiniC’s documentation!" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||
<a href="Lib.Statement.html" class="btn btn-neutral float-right" title="Lib.Statement module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,164 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.FunctionData module — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Lib.LinearCode module" href="Lib.LinearCode.html" />
|
||||
<link rel="prev" title="Lib.Operands module" href="Lib.Operands.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Lib.FunctionData module</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
<a href="../_sources/api/Lib.FunctionData.rst.txt" rel="nofollow"> View page source</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<section id="module-Lib.FunctionData">
|
||||
<span id="lib-functiondata-module"></span><h1>Lib.FunctionData module<a class="headerlink" href="#module-Lib.FunctionData" title="Permalink to this heading"></a></h1>
|
||||
<p>This file defines the base class <a class="reference internal" href="#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><code class="xref py py-class docutils literal notranslate"><span class="pre">FunctionData</span></code></a>,
|
||||
containing metadata on a RiscV function, as well as utility
|
||||
functions common to the different intermediate representations.</p>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.FunctionData.</span></span><span class="sig-name descname"><span class="pre">FunctionData</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
<p>Stores some metadata on a RiscV function:
|
||||
name of the function, label names, temporary variables
|
||||
(using <a class="reference internal" href="Lib.Operands.html#Lib.Operands.TemporaryPool" title="Lib.Operands.TemporaryPool"><code class="xref py py-class docutils literal notranslate"><span class="pre">Lib.Operands.TemporaryPool</span></code></a>),
|
||||
and div_by_zero label.</p>
|
||||
<p>This class is usually used indirectly through the
|
||||
different intermediate representations we work with,
|
||||
such as <a class="reference internal" href="Lib.LinearCode.html#Lib.LinearCode.LinearCode.fdata" title="Lib.LinearCode.LinearCode.fdata"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Lib.LinearCode.LinearCode.fdata</span></code></a>.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.fresh_label">
|
||||
<span class="sig-name descname"><span class="pre">fresh_label</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.fresh_label"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.fresh_label" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return a new label, with a unique name based on the given string.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.fresh_offset">
|
||||
<span class="sig-name descname"><span class="pre">fresh_offset</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="Lib.Operands.html#Lib.Operands.Offset" title="Lib.Operands.Offset"><span class="pre">Offset</span></a></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.fresh_offset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.fresh_offset" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return a new offset in the memory stack.
|
||||
Offsets are decreasing relative to FP.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.fresh_tmp">
|
||||
<span class="sig-name descname"><span class="pre">fresh_tmp</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="Lib.Operands.html#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.fresh_tmp"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.fresh_tmp" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return a new fresh Temporary,
|
||||
which is added to the pool.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.get_label_div_by_zero">
|
||||
<span class="sig-name descname"><span class="pre">get_label_div_by_zero</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.get_label_div_by_zero"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.get_label_div_by_zero" title="Permalink to this definition"></a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.get_name">
|
||||
<span class="sig-name descname"><span class="pre">get_name</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">str</span></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.get_name"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.get_name" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the name of the function.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.FunctionData.FunctionData.get_offset">
|
||||
<span class="sig-name descname"><span class="pre">get_offset</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">int</span></span></span><a class="reference internal" href="../_modules/Lib/FunctionData.html#FunctionData.get_offset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.FunctionData.FunctionData.get_offset" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the current offset in the memory stack.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||
<a href="Lib.Operands.html" class="btn btn-neutral float-left" title="Lib.Operands module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||
<a href="Lib.LinearCode.html" class="btn btn-neutral float-right" title="Lib.LinearCode module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,185 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.LinearCode module — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Lib.Allocator module" href="Lib.Allocator.html" />
|
||||
<link rel="prev" title="Lib.FunctionData module" href="Lib.FunctionData.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Operands.html">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Lib.LinearCode module</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
<a href="../_sources/api/Lib.LinearCode.rst.txt" rel="nofollow"> View page source</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<section id="module-Lib.LinearCode">
|
||||
<span id="lib-linearcode-module"></span><h1>Lib.LinearCode module<a class="headerlink" href="#module-Lib.LinearCode" title="Permalink to this heading"></a></h1>
|
||||
<p>CAP, CodeGeneration, LinearCode API
|
||||
Classes for a RiscV linear code.</p>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.LinearCode.</span></span><span class="sig-name descname"><span class="pre">LinearCode</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
<p>Representation of a RiscV program as a list of instructions.</p>
|
||||
<p><a class="reference internal" href="#Lib.LinearCode.LinearCode.add_instruction" title="Lib.LinearCode.LinearCode.add_instruction"><code class="xref py py-meth docutils literal notranslate"><span class="pre">add_instruction()</span></code></a> is repeatedly called in the codegen visitor
|
||||
to build a complete list of RiscV instructions for the source program.</p>
|
||||
<p>The <a class="reference internal" href="#Lib.LinearCode.LinearCode.fdata" title="Lib.LinearCode.LinearCode.fdata"><code class="xref py py-attr docutils literal notranslate"><span class="pre">fdata</span></code></a> member variable contains some meta-information
|
||||
on the program, for instance to allocate a new temporary.
|
||||
See <a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><code class="xref py py-class docutils literal notranslate"><span class="pre">Lib.FunctionData.FunctionData</span></code></a>.</p>
|
||||
<p>For debugging purposes, <a class="reference internal" href="#Lib.LinearCode.LinearCode.print_code" title="Lib.LinearCode.LinearCode.print_code"><code class="xref py py-meth docutils literal notranslate"><span class="pre">print_code()</span></code></a> allows to print
|
||||
the RiscV program to a file.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.add_comment">
|
||||
<span class="sig-name descname"><span class="pre">add_comment</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">s</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.add_comment"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.add_comment" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Add a comment in the program.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.add_instruction">
|
||||
<span class="sig-name descname"><span class="pre">add_instruction</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">i</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Comment" title="Lib.Statement.Comment"><span class="pre">Lib.Statement.Comment</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Lib.Statement.Label</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instru3A" title="Lib.Statement.Instru3A"><span class="pre">Lib.Statement.Instru3A</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><span class="pre">Lib.Statement.AbsoluteJump</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.ConditionalJump" title="Lib.Statement.ConditionalJump"><span class="pre">Lib.Statement.ConditionalJump</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.add_instruction"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.add_instruction" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Utility function to add an instruction in the program.</p>
|
||||
<p>See also <a class="reference internal" href="Lib.RiscV.html#module-Lib.RiscV" title="Lib.RiscV"><code class="xref py py-mod docutils literal notranslate"><span class="pre">Lib.RiscV</span></code></a> to generate relevant instructions.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.add_instruction_PRINTLN_INT">
|
||||
<span class="sig-name descname"><span class="pre">add_instruction_PRINTLN_INT</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">reg</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Operands.html#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><span class="pre">DataLocation</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.add_instruction_PRINTLN_INT"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.add_instruction_PRINTLN_INT" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Print integer value, with newline. (see Expand)</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.add_label">
|
||||
<span class="sig-name descname"><span class="pre">add_label</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">s</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Label</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.add_label"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.add_label" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Add a label in the program.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py attribute">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.fdata">
|
||||
<span class="sig-name descname"><span class="pre">fdata</span></span><em class="property"><span class="p"><span class="pre">:</span></span><span class="w"> </span><a class="reference internal" href="Lib.FunctionData.html#Lib.FunctionData.FunctionData" title="Lib.FunctionData.FunctionData"><span class="pre">FunctionData</span></a></em><a class="headerlink" href="#Lib.LinearCode.LinearCode.fdata" title="Permalink to this definition"></a></dt>
|
||||
<dd></dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.get_instructions">
|
||||
<span class="sig-name descname"><span class="pre">get_instructions</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Comment" title="Lib.Statement.Comment"><span class="pre">Lib.Statement.Comment</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Label" title="Lib.Statement.Label"><span class="pre">Lib.Statement.Label</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.Instru3A" title="Lib.Statement.Instru3A"><span class="pre">Lib.Statement.Instru3A</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.AbsoluteJump" title="Lib.Statement.AbsoluteJump"><span class="pre">Lib.Statement.AbsoluteJump</span></a><span class="w"> </span><span class="p"><span class="pre">|</span></span><span class="w"> </span><a class="reference internal" href="Lib.Statement.html#Lib.Statement.ConditionalJump" title="Lib.Statement.ConditionalJump"><span class="pre">Lib.Statement.ConditionalJump</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.get_instructions"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.get_instructions" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the list of instructions of the program.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.iter_statements">
|
||||
<span class="sig-name descname"><span class="pre">iter_statements</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">f</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.iter_statements"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.iter_statements" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Iterate over instructions.
|
||||
For each real instruction (not label or comment), call f,
|
||||
which must return either None or a list of instruction. If it
|
||||
returns None, nothing happens. If it returns a list, then the
|
||||
instruction is replaced by this list.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.print_code">
|
||||
<span class="sig-name descname"><span class="pre">print_code</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">output</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">comment</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.print_code"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.print_code" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Outputs the RiscV program as text to a file at the given path.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.LinearCode.LinearCode.print_dot">
|
||||
<span class="sig-name descname"><span class="pre">print_dot</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">DF</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">view</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">False</span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/LinearCode.html#LinearCode.print_dot"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.LinearCode.LinearCode.print_dot" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Outputs the RiscV program as graph to a file at the given path.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||
<a href="Lib.FunctionData.html" class="btn btn-neutral float-left" title="Lib.FunctionData module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||
<a href="Lib.Allocator.html" class="btn btn-neutral float-right" title="Lib.Allocator module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,276 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="writer-html5" lang="en" >
|
||||
<head>
|
||||
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lib.Operands module — MiniC documentation</title>
|
||||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../_static/css/theme.css" type="text/css" />
|
||||
<!--[if lt IE 9]>
|
||||
<script src="../_static/js/html5shiv.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/js/theme.js"></script>
|
||||
<link rel="index" title="Index" href="../genindex.html" />
|
||||
<link rel="search" title="Search" href="../search.html" />
|
||||
<link rel="next" title="Lib.FunctionData module" href="Lib.FunctionData.html" />
|
||||
<link rel="prev" title="Lib.RiscV module" href="Lib.RiscV.html" />
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<div class="wy-grid-for-nav">
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-scroll">
|
||||
<div class="wy-side-nav-search" >
|
||||
<a href="../index.html" class="icon icon-home"> MiniC
|
||||
</a>
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
|
||||
<p class="caption" role="heading"><span class="caption-text">Contents:</span></p>
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Errors.html">Base library - Errors</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Statement.html">Base library - Statement</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.RiscV.html">Base library - RISC-V instructions</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#">Base library - Operands</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.FunctionData.html">Base library - Function data</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.LinearCode.html">Linear intermediate representation</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="Lib.Allocator.html">Temporary allocation</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="../index.html">MiniC</a>
|
||||
</nav>
|
||||
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
<div role="navigation" aria-label="Page navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="../index.html" class="icon icon-home"></a> »</li>
|
||||
<li>Lib.Operands module</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
<a href="../_sources/api/Lib.Operands.rst.txt" rel="nofollow"> View page source</a>
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
|
||||
<div itemprop="articleBody">
|
||||
|
||||
<section id="module-Lib.Operands">
|
||||
<span id="lib-operands-module"></span><h1>Lib.Operands module<a class="headerlink" href="#module-Lib.Operands" title="Permalink to this heading"></a></h1>
|
||||
<p>This file defines the base class <a class="reference internal" href="#Lib.Operands.Operand" title="Lib.Operands.Operand"><code class="xref py py-class docutils literal notranslate"><span class="pre">Operand</span></code></a>
|
||||
and its subclasses for different operands: <a class="reference internal" href="#Lib.Operands.Condition" title="Lib.Operands.Condition"><code class="xref py py-class docutils literal notranslate"><span class="pre">Condition</span></code></a>,
|
||||
<a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a> and <a class="reference internal" href="#Lib.Operands.Function" title="Lib.Operands.Function"><code class="xref py py-class docutils literal notranslate"><span class="pre">Function</span></code></a>.</p>
|
||||
<p>The class <a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a> itself has subclasses:
|
||||
<a class="reference internal" href="#Lib.Operands.Register" title="Lib.Operands.Register"><code class="xref py py-class docutils literal notranslate"><span class="pre">Register</span></code></a>, <a class="reference internal" href="#Lib.Operands.Offset" title="Lib.Operands.Offset"><code class="xref py py-class docutils literal notranslate"><span class="pre">Offset</span></code></a> for address in memory,
|
||||
<a class="reference internal" href="#Lib.Operands.Immediate" title="Lib.Operands.Immediate"><code class="xref py py-class docutils literal notranslate"><span class="pre">Immediate</span></code></a> for constants and <a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><code class="xref py py-class docutils literal notranslate"><span class="pre">Temporary</span></code></a>
|
||||
for location not yet allocated.</p>
|
||||
<p>This file also define shortcuts for registers in RISCV.</p>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Condition">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Condition</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">optype</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Condition"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Condition" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.Operand" title="Lib.Operands.Operand"><code class="xref py py-class docutils literal notranslate"><span class="pre">Operand</span></code></a></p>
|
||||
<p>Condition, i.e. comparison operand for a CondJump.</p>
|
||||
<p>Example usage :</p>
|
||||
<ul class="simple">
|
||||
<li><p>Condition(‘beq’) = branch if equal.</p></li>
|
||||
<li><p>Condition(MiniCParser.LT) = branch if lower than.</p></li>
|
||||
<li><p>…</p></li>
|
||||
</ul>
|
||||
<p>The constructor’s argument shall be a string in the list all_ops, or a
|
||||
comparison operator in MiniCParser.LT, MiniCParser.GT, … (one of the keys
|
||||
in opdict).</p>
|
||||
<p>A ‘negate’ method allows getting the negation of this condition.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Condition.negate">
|
||||
<span class="sig-name descname"><span class="pre">negate</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.Condition" title="Lib.Operands.Condition"><span class="pre">Condition</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Condition.negate"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Condition.negate" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the opposite condition.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.DataLocation">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">DataLocation</span></span><a class="reference internal" href="../_modules/Lib/Operands.html#DataLocation"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.DataLocation" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.Operand" title="Lib.Operands.Operand"><code class="xref py py-class docutils literal notranslate"><span class="pre">Operand</span></code></a></p>
|
||||
<p>A Data Location is either a register, a temporary
|
||||
or a place in memory (offset).</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Function">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Function</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">name</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">str</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Function"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Function" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.Operand" title="Lib.Operands.Operand"><code class="xref py py-class docutils literal notranslate"><span class="pre">Operand</span></code></a></p>
|
||||
<p>Operand for build-in function call.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Immediate">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Immediate</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">val</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Immediate"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Immediate" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a></p>
|
||||
<p>Immediate operand (integer).</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Offset">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Offset</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">basereg</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Register" title="Lib.Operands.Register"><span class="pre">Register</span></a></span></em>, <em class="sig-param"><span class="n"><span class="pre">offset</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Offset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Offset" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a></p>
|
||||
<p>Offset = address in memory computed with base + offset.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Offset.get_offset">
|
||||
<span class="sig-name descname"><span class="pre">get_offset</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">int</span></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Offset.get_offset"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Offset.get_offset" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the value of the offset.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Operand">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Operand</span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Operand"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Operand" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Register">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Register</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">number</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Register"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Register" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a></p>
|
||||
<p>A (physical) register.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Renamer">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Renamer</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">pool</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.TemporaryPool" title="Lib.Operands.TemporaryPool"><span class="pre">TemporaryPool</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Renamer"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Renamer" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
<p>Manage a renaming of temporaries.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Renamer.copy">
|
||||
<span class="sig-name descname"><span class="pre">copy</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Renamer.copy"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Renamer.copy" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Give a copy of the Renamer.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Renamer.defined">
|
||||
<span class="sig-name descname"><span class="pre">defined</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">t</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">bool</span></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Renamer.defined"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Renamer.defined" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>True if the Temporary is renamed.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Renamer.fresh">
|
||||
<span class="sig-name descname"><span class="pre">fresh</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">t</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Renamer.fresh"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Renamer.fresh" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Give a fresh rename for a Temporary.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Renamer.replace">
|
||||
<span class="sig-name descname"><span class="pre">replace</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">t</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Renamer.replace"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Renamer.replace" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Give the rename for a Temporary (which is itself if it is not renamed).</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Temporary">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">Temporary</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">number</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">int</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">pool</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.TemporaryPool" title="Lib.Operands.TemporaryPool"><span class="pre">TemporaryPool</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#Temporary"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Temporary" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><code class="xref py py-class docutils literal notranslate"><span class="pre">DataLocation</span></code></a></p>
|
||||
<p>Temporary, a location that has not been allocated yet.
|
||||
It will later be mapped to a physical register (Register) or to a memory location (Offset).</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.Temporary.get_alloced_loc">
|
||||
<span class="sig-name descname"><span class="pre">get_alloced_loc</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><span class="pre">DataLocation</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#Temporary.get_alloced_loc"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.Temporary.get_alloced_loc" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return the DataLocation allocated to this Temporary.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">Lib.Operands.</span></span><span class="sig-name descname"><span class="pre">TemporaryPool</span></span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Bases: <code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></p>
|
||||
<p>Manage a pool of temporaries.</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool.add_tmp">
|
||||
<span class="sig-name descname"><span class="pre">add_tmp</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">t</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></em><span class="sig-paren">)</span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool.add_tmp"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool.add_tmp" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Add a temporary to the pool.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool.fresh_tmp">
|
||||
<span class="sig-name descname"><span class="pre">fresh_tmp</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool.fresh_tmp"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool.fresh_tmp" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Give a new fresh Temporary and add it to the pool.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool.get_all_temps">
|
||||
<span class="sig-name descname"><span class="pre">get_all_temps</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">List</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a><span class="p"><span class="pre">]</span></span></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool.get_all_temps"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool.get_all_temps" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Return all the temporaries of the pool.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool.get_alloced_loc">
|
||||
<span class="sig-name descname"><span class="pre">get_alloced_loc</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">t</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><span class="pre">DataLocation</span></a></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool.get_alloced_loc"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool.get_alloced_loc" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Get the actual DataLocation allocated for the temporary t.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="Lib.Operands.TemporaryPool.set_temp_allocation">
|
||||
<span class="sig-name descname"><span class="pre">set_temp_allocation</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">allocation</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Dict</span><span class="p"><span class="pre">[</span></span><a class="reference internal" href="#Lib.Operands.Temporary" title="Lib.Operands.Temporary"><span class="pre">Temporary</span></a><span class="p"><span class="pre">,</span></span><span class="w"> </span><a class="reference internal" href="#Lib.Operands.DataLocation" title="Lib.Operands.DataLocation"><span class="pre">DataLocation</span></a><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">None</span></span></span><a class="reference internal" href="../_modules/Lib/Operands.html#TemporaryPool.set_temp_allocation"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#Lib.Operands.TemporaryPool.set_temp_allocation" title="Permalink to this definition"></a></dt>
|
||||
<dd><p>Give a mapping from temporaries to actual registers.
|
||||
The argument allocation must be a dict from Temporary to
|
||||
DataLocation other than Temporary (typically Register or Offset).
|
||||
Typing enforces that keys are Temporary and values are Datalocation.
|
||||
We check the values are indeed not Temporary.</p>
|
||||
</dd></dl>
|
||||
|
||||
</dd></dl>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
|
||||
<a href="Lib.RiscV.html" class="btn btn-neutral float-left" title="Lib.RiscV module" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
|
||||
<a href="Lib.FunctionData.html" class="btn btn-neutral float-right" title="Lib.FunctionData module" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div role="contentinfo">
|
||||
<p>© Copyright 2022, compil-lyon.</p>
|
||||
</div>
|
||||
|
||||
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
|
||||
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
|
||||
provided by <a href="https://readthedocs.org">Read the Docs</a>.
|
||||
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.Navigation.enable(true);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user