[otbn] Move shift information from encoding to operand

Some operands get encoded with a "shift". For example, the following
line of assembly

    bn.mulqacc w30.1, w25.0, 64

has an acc_shift_imm operand of 64. This is actually encoded as 1: the
operand is shifted down by 6 bits before encoding.

This sort of thing is supported by the RISC-V instruction set too, and
their ISA specifies these shifts as part of the list of encoding
schemes. Until now, we did the same thing (copying them!)

In general, there are two jobs that need doing when converting from
the string representation in the assembly file to a number that can be
put in the encoding.

  - 2's complement encoding for signed immediates
  - Shifting down appropriately

Before this commit, the signedness information for an operand was
stored on the OperandType object and the shift was stored on the
EncSchemeField object. This is a bit silly: surely it would make more
sense to put them together! In fact, it's worse: we could specify a
register operand with a shift. With a shift of 1, you'd be able to
write x0, x2, x4 and x62(!) but not x1 or x3.

So this commit moves the shift to the OperandType object. Now our
OperandType.read_index function does both of the jobs above, and it is
the inverse operation of OperandType.render_val. Much nicer!

As a bonus, this now means it's easy for an operand's type to be more
precise about the range of values it supports. So acc_shift_imm used
to say "Valid range: 0..3". Now it says "Valid range: 0..196 in steps
of 64".

While writing this patch, I noticed that OperandType.read_index also
didn't support signed operands correctly, which this also fixes.

As a sanity check, I compared the assembled (and disassembled) code
snippet examples before and after this patch. The assembled snippets
are identical. The differences in the objdump disassembly are exactly
from fixing the rendering of shifted operands as in the example above.

Similarly, the only differences in generated documentation are from
the fixed ranges described above and a fixed text string for mulqacc's
acc_shift_imm operand.

Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
9 files changed
tree: dd035c3f1f69d6e4a6020349d9e3929375cfce2c
  1. .github/
  2. ci/
  3. doc/
  4. hw/
  5. site/
  6. sw/
  7. test/
  8. util/
  9. .clang-format
  10. .dockerignore
  11. .flake8
  12. .gitignore
  13. .style.yapf
  14. _index.md
  15. apt-requirements.txt
  16. azure-pipelines.yml
  17. check_tool_requirements.core
  18. CLA
  19. COMMITTERS
  20. CONTRIBUTING.md
  21. LICENSE
  22. meson.build
  23. meson_init.sh
  24. meson_options.txt
  25. python-requirements.txt
  26. README.md
  27. tool_requirements.py
  28. toolchain.txt
README.md

OpenTitan

OpenTitan logo

About the project

OpenTitan is an open source silicon Root of Trust (RoT) project. OpenTitan will make the silicon RoT design and implementation more transparent, trustworthy, and secure for enterprises, platform providers, and chip manufacturers. OpenTitan is administered by lowRISC CIC as a collaborative project to produce high quality, open IP for instantiation as a full-featured product. See the OpenTitan site and OpenTitan docs for more information about the project.

About this repository

This repository contains hardware, software and utilities written as part of the OpenTitan project. It is structured as monolithic repository, or “monorepo”, where all components live in one repository. It exists to enable collaboration across partners participating in the OpenTitan project.

Documentation

The project contains comprehensive documentation of all IPs and tools. You can access it online at docs.opentitan.org.

How to contribute

Have a look at CONTRIBUTING for guidelines on how to contribute code to this repository.

Licensing

Unless otherwise noted, everything in this repository is covered by the Apache License, Version 2.0 (see LICENSE for full text).