def main(argv: List[str]) -> int: files, other_args, flags = parse_positionals(argv) files = files or ['--'] just_translate = '--otbn-translate' in flags # files is now a nonempty list of input files. Rather unusually, '--' # (rather than '-') denotes standard input. try: insns_file = load_insns_yaml() except RuntimeError as err: sys.stderr.write('{}\n'.format(err)) return 1 # A list of instructions that have "glued operations" (which means their # syntax doesn't require a space between the mnemonic and the first # operation). Ordered from longest to shortest mnemonic, so that you can # find a maximal prefix by linearly searching through the list and calling # startswith. glued_insns_dec_len = [] for insn in insns_file.insns: if insn.glued_ops: glued_insns_dec_len.append(insn) glued_insns_dec_len.sort(key=lambda insn: len(insn.mnemonic), reverse=True) # Check that any instruction that claims to have a Python pseudo-op # assembler really does. for insn in insns_file.insns: if insn.python_pseudo_op: if insn.mnemonic not in _PSEUDO_OP_ASSEMBLERS: sys.stderr.write( "Instruction {!r} has python-pseudo-op true, " "but otbn_as.py doesn't have a custom assembler " "for it.\n".format(insn.mnemonic)) return 1 # Try to match up OTBN instruction encodings with .insn schemes (as stored # in RISCV_FORMATS). mnem_to_rve = find_insn_schemes(insns_file.mnemonic_to_insn) with tempfile.TemporaryDirectory(suffix='.otbn-as') as tmpdir: try: transformed = transform_inputs(tmpdir, files, insns_file, mnem_to_rve, glued_insns_dec_len, just_translate) except RuntimeError as err: sys.stderr.write('{}\n'.format(err)) return 1 if just_translate: # transform_inputs already printed out the translated code. We're # done. return 0 return run_binutils_as(transformed, other_args)
def main() -> int: args = sys.argv[1:] has_disasm = snoop_disasm_flags(args) objdump = find_tool('objdump') try: if not has_disasm: cmd = [objdump] + args return subprocess.run(cmd).returncode else: cmd = [objdump, '-M', 'numeric,no-aliases'] + args proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) if proc.returncode: # Dump any lines that objdump wrote before it died sys.stderr.write(proc.stderr) sys.stdout.write(proc.stdout) return proc.returncode except FileNotFoundError: sys.stderr.write('Unknown command: {!r}.\n'.format(objdump)) return 127 try: insns_file = load_insns_yaml() except RuntimeError as err: sys.stderr.write('{}\n'.format(err)) return 1 # If we get here, we think we're disassembling something, objdump ran # successfully and we have its results in proc.stdout for line in proc.stdout.split('\n'): transformed = transform_disasm_line(line, insns_file) sys.stdout.write(transformed + '\n') return 0
# Licensed under the Apache License, Version 2.0, see LICENSE for details. # SPDX-License-Identifier: Apache-2.0 import sys from typing import Dict, Optional, Tuple from shared.insn_yaml import Insn, load_insns_yaml from .state import OTBNState # Load the insns.yml file at module load time: we'll use its data while # declaring the classes. The point is that an OTBNInsn below is an instance of # a particular Insn object from shared.insn_yaml, so we want a class variable # on the OTBNInsn that points at the corresponding Insn. try: _INSNS_FILE = load_insns_yaml() except RuntimeError as err: sys.stderr.write('{}\n'.format(err)) sys.exit(1) class DecodeError(Exception): '''An error raised when trying to decode malformed instruction bits''' def __init__(self, msg: str): self.msg = msg def __str__(self) -> str: return 'DecodeError: {}'.format(self.msg) class DummyInsn(Insn):