blob: 65381d0a85304946ab0a112080fe55b71b74d3ff [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
from typing import Optional, Tuple
from shared.insn_yaml import InsnsFile
from ..program import ProgInsn, Program
from ..model import Model
from ..snippet import Snippet
from ..snippet_gen import SnippetGen
class ECall(SnippetGen):
'''A generator that makes a snippet with a single ECALL instruction'''
def __init__(self, insns_file: InsnsFile) -> None:
ecall_insn = insns_file.mnemonic_to_insn.get('ecall')
if ecall_insn is None:
raise RuntimeError('No ECALL instruction in instructions file')
if ecall_insn.operands:
raise RuntimeError('ECALL instruction in instructions file '
'has a nonempty list of operands.')
if ecall_insn.lsu:
raise RuntimeError('ECALL instruction in instructions file '
'has unexpected LSU information.')
self.insn = ProgInsn(ecall_insn, [], None)
def gen(self,
size: int,
model: Model,
program: Program) -> Optional[Tuple[Snippet, bool, int]]:
snippet = Snippet([(model.pc, [self.insn])])
snippet.insert_into_program(program)
return (snippet, True, 0)
def pick_weight(self,
size: int,
model: Model,
program: Program) -> float:
# Choose small weights when size is large and large ones when it's
# small.
assert size > 0
return (1e-10 if size > 5
else 0.1 if size > 1
else 1e10)