93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
|
"""
|
||
|
MIF08, CAP, CodeGeneration, RiscV API
|
||
|
Functions to define instructions.
|
||
|
"""
|
||
|
|
||
|
from Lib.Errors import MiniCInternalError
|
||
|
from Lib.Operands import (Condition, Immediate, Operand, Function)
|
||
|
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), ...
|
||
|
"""
|
||
|
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:
|
||
|
"""And instruction (cannot be called `and` due to Python and)."""
|
||
|
return Instru3A("and", dr, sr1, sr2orimm7)
|
||
|
|
||
|
|
||
|
def lor(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A:
|
||
|
"""Or instruction (cannot be called `or` due to Python or)."""
|
||
|
return Instru3A("or", dr, sr1, sr2orimm7)
|
||
|
|
||
|
|
||
|
def xor(dr: Operand, sr1: Operand, sr2orimm7: Operand) -> Instru3A: # pragma: no cover
|
||
|
if isinstance(sr2orimm7, Immediate):
|
||
|
return Instru3A("xori", dr, sr1, sr2orimm7)
|
||
|
else:
|
||
|
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)
|