CAP/MiniC/Lib/RiscV.py
2024-10-06 19:58:11 +02:00

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)