RISC-V has a 128-bit ISA that is fairly developed, but not standardized fully yet.

Overview

128-bit RISC-V assembler

RISC-V has a 128-bit ISA that is fairly developed, but not standardized fully yet. I am maintaining a RISC-V userspace emulator library that is written in modern C++, and the ISA is actually specified as a template parameter when instantiating the machine. So, it felt natural to explore how much work it would be to change Machine to Machine .

Turns out, not too much work. The ISA is a bit unclear on some things, but I think I've got the gist of it. Unfortunately for me, I didn't have any way of using this .. very useful architecture. So naturally I had to write an assembler for it too.

Big assembler

The assembler is in the early stages, but it supports the most basic instructions. Enough to assemble the test assembly in the root folder, for now. The assembler is easy to expand on, but it lacks helpful hints when things are not correct. It also lacks many limit checks that would produce erroneous assembly.

It is written for C++17 (although currently does not use any fancy features, so should be C++11 compatible).

While there is no ELF format for 128-bit anything, this assembler outputs an ELFCLASS128 file that is a could-be 128-bit ELF format. It is loadable by libriscv, specifically the emu128 emulator project.

Simple one-pass

The assembler currently does a one-pass through the assembly, and corrects forward labels once they appear. This means that there may be potential inefficiencies. It is, however, very fast.

Example

.org 0x100000

.global _start
_start:             ;; Entry point label
	li sp, -16      ;; Stack at end of 128-bit

	li t0, 2        ;; Syscall 2 (print)
	sq t0, sp-0     ;; Store 128-bit value
	lq sp+0, a7     ;; Load 128-bit value

	la a0, hello_world ;; address of string
	ecall           ;; Execute syscall

exit:
	li a7, 1        ;; Syscall 1 (exit)
	li a0, 0x666    ;; Exit code (1st arg)
	ecall           ;; Execute syscall
	jmp exit

hello_world:        ;; String label
	.type hello_world, @object
	.string "Hello World!" ;; Zt-string

The store is pretty useless, but it shows how to do a SP-relative store.

Instructions and pseudo-instructions

  • my_label:
    • Create a new label named 'my_label' which can be jumped to.
  • li [reg], constant
    • Loads integer constant into register.
  • la [reg], label
    • Loads address at label into register.
  • lq [reg], [reg]+offset
    • Load 128-bit value from [reg]+offset memory address.
  • sq [reg]+offset, [reg]
    • Store 128-bit value into [reg]+offset memory address.
  • call label
    • Make a function call to 'label' which can be returned from.
  • farcall [reg], label
    • Make a function call to a far away 'label' which can be returned from. [reg] is used to build the full address.
  • ret
    • Return back from any function call.
  • jmp label
    • Jump directly to label.
  • scall
    • Perform system call from register A7. Arguments in A0-A6.
  • ebreak
    • Debugger breakpoint.
  • wfi
    • Wait for interrupts (stops the machine).

Branches:

  • beq [r1] [r2] label
    • Jump when r1 and r2 is equal.
  • bne [r1] [r2] label
    • Jump when r1 and r2 is not equal.
  • blt [r1] [r2] label
    • Jump when r1 is less than to r2.
  • bge [r1] [r2] label
    • Jump when r1 is greater or equal to r2.
  • bltu [r1] [r2] label
    • Jump when unsigned r1 is less than unsigned r2.
  • bgeu [r1] [r2] label
    • Jump when unsigned r1 is greater or equal to unsigned r2.

Arithmetic and logical operations:

  • add, sll, slt, sltu, srl, and, or, xor [reg] [reg or imm]

    • Operation on register with register or immediate.
  • sub, mul, div, divu, rem, remu [reg] [reg]

    • Subtraction, multiplication, division, unsigned division, remainder, unsigned remainder.
    • Operation on register with register.

Complete list of available instructions.

Pseudo-ops

  • db, dh, dw, dd, dq [constant]
    • Insert aligned constant of 8-, 16-, 32-, 64- or 128-bits into current position.
  • resb, resh, resw, resd, resq [times]
    • Reserve aligned 1, 2, 4, 8 or 16 bytes multiplied by constant.
  • incbin "file.name"
    • Inserts binary data taken from filename at current position.

Complete list of available pseudo-ops.

Directives

  • .org 0x10000
    • Set the base address of the binary, which now starts at 0x10000.
  • .align 4
    • Align memory to the given power-of-two.
  • .string "String here!"
    • Insert a zero-terminated string.

Complete list of available directives.

Comments
  • Symbol and string tables

    Symbol and string tables

    There are no ELF inspection tools that accept 128-bit ELFs right now, but if there were it would be nice if we could export global symbols and a symbol table. This requires a section header, a .shstrtab for section header names and a .symtab/.strtab combo.

    The assembler already has the concept of globals as well as a way to translate a symbol name into an address. All that is required is building the right structures in the ELF.

    enhancement 
    opened by fwsGonzo 1
  • Alignment with labels

    Alignment with labels

    A label before an unaligned instruction will point to the wrong address. Label should use the inherent alignment of the next line instead of the alignment of the previous line.

    db 0x11
    
    label:
         wfi
    

    The label will be misaligned and cannot be jumped to.

    bug 
    opened by fwsGonzo 1
  • Alignment operations relies on sections being properly aligned

    Alignment operations relies on sections being properly aligned

    Alignment will stop working if sections are misaligned to begin with. This was a deliberate design decision that deserves some documentation to highlight the possible issues that can arise.

    documentation 
    opened by fwsGonzo 0
  • Arithmetic and constant-chains

    Arithmetic and constant-chains

    It should be possible to calculate values from constants and dependent symbols automatically. We also need to support parenthesis and various bit-operations. It's a rather big feature, but necessary for any serious work.

    Step 1: Parse tokens. Any parenthesis is treated as a calculation that could be optimized leaving only constants and labels.

    OK: (label + 0x44)
    Wrong. label + 0x44
    

    The tokenizer is not smart enough for the second one yet.

    Step 2: Any constant used that contains symbols should be automatically solved by scheduling it for when the symbol value is revealed.

    Step 3: When calling the scheduled ops, the constant will be resolved and written into the binary from a lambda that has all the necessary context.

    This method avoids re-parsing the assembly, but perhaps it's better to rethink the strategy.

    enhancement 
    opened by fwsGonzo 0
  • Covering 128-bits of address space with immediates and labels

    Covering 128-bits of address space with immediates and labels

    Right now there are special pseudo-instructions meant to help with:

    1. Loading large integer into register
    2. Loading large addresses into register
    3. Calling large address using JALR by building address in register

    These helpful functions right now cover only 32-bits of address space, however they should cover up to 128-bits. It's a bit hard to see right now how this should be done without using a lot of unnecessary registers.

    One note about the farcall instruction is that it avoids loading the integer, because it uses the immedate of the JALR instruction to build the 32-bit value, saving an instruction.

    If nothing else, maybe we can solve this by just adding la64 and la128 variants that assume you know the distance is great.

    enhancement 
    opened by fwsGonzo 1
Owner
Alf-André Walla
Senior Operating Systems Architect, likes Procedural World Generators & Signals theory
Alf-André Walla
zx spectrum 128 emulator on single esp32

spectrum128_esp32_usb_host_pal_tv zx spectrum 128 emulator on single esp32 Single esp32 lolin32mini spectrum 128 emulator with direct gpio 2 HID LS us

Samsonov Dima 35 Nov 17, 2022
Command line tool for offline shader ISA inspection.

Intel Shader Analyzer Intel Shader Analyzer is a tool for offline static analysis of shaders for Intel GPU Architectures. It allows a user to compile

null 114 Nov 18, 2022
RISCAL is a 32-bit reduced instruction-set computer (RISC) designed for learning and research purposes. It is named after my dog, Rascal.

RISCAL CPU RISCAL is a 32-bit custom instruction set architecture virtual machine. It is intended to be used for learning/research purposes. In a nuts

null 3 Dec 23, 2021
An 8-bit minicomputer with a fully custom architecture

JDH-8 An fully custom 8-bit minicomputer with a unique architecture and the express goal of playing PONG. The program above is running in the emulator

jdh 1k Nov 17, 2022
Implementation of the (not yet written) std::experimental::rational proposal.

Rational Implementation of the (not yet written) std::experimental::rational proposal. Getting started Copy include/std/experimental/rational.hpp to y

Ali Can Demiralp 9 Nov 18, 2022
"the French term for a watch movement that is not completely assembled yet."

Chablon "the French term for a watch movement that is not completely assembled yet." Today it's a program to draw rectangles on the display of a PineT

Daniel Barlow 3 Jan 3, 2022
SomeSmile - a free, open source and not yet cross-platform

SomeSmile - a free, open source and not yet cross-platform Table Of Contents For What? Structure Start Usage Guide How To Build Screenshots End For Wh

SonicTheHedgehog 3 Aug 3, 2022
A video input (V4L2) to NDI converter that works with Raspberry Pi (32-bit and 64-bit), and Intel/AMD CPUs

V4L2 to NDI V4L2 to NDI is an application that connects to attached V4L2 devices and encodes the video signal into NDI It uses the NDI library, allowi

Luke Plassman 49 Nov 12, 2022
This repo does not contain any skins that work by themselves, but rather addons to already existing skins like CakeOS and Polybar

Rainmeter-addons ⚠ This repo does not contain any skins that work by themselves, but rather addons to already existing skins like CakeOS and Polybar E

null 3 Nov 3, 2022
A sketch that not only parses NMEA sentences, but also allows sending UBX commands and decrypt answers from the ublox module

RAK4631-ublox-Commander This is a tokenizer and parser for raw NMEA sentences. This is not intended (yet anyway) for production, but as an exercice in

Kongduino 2 May 29, 2022
Any one can add their programs here ,but program should not be repeated.

Hactoberfest2021 To All the Beginners Guys Don't Forget to give star to this repo. Any one can add their programs here ,but program should not be repe

Varun.py 22 Nov 4, 2022
A prototype, not playable but runnable

Game developed by Dave Jornales, Masayuki Retuerma, Angelene Balais, Cleo Alcanzo, and Arsenic Salangsang Copyright (c) 2021 Dave Jornales (@AkagamiDe

Dave Jornales 2 Dec 10, 2021
Just another short video app (not tiktok) but 3 in 1.

Short videos app - India Another short videos app for Hindi audience. Made with 3 different apis: Moj app Josh app Chingari app Authetication No authe

Not Your Surya 2 Jan 6, 2022
General repository for all software (emulators, dev tools, etc) related to Vircon32 but not running on console itself

Vircon32: Computer software This is a general repository containing source code related to Vircon32 implementation, this is, software that does NOT ru

Vircon32 12 Nov 15, 2022
Tiny FEL tools for allwinner SOC, support RISC-V D1 chip

XFEL Tiny FEL tools for allwinner SOC, support RISC-V D1 chip. How to build The xfel tools depends on the libusb-1.0 library, you need to install libu

xboot.org 125 Nov 27, 2022
A Pipelined RISC-V RV32I Core in Verilog

Toast-RV32i Toast is a RISC-V soft core written in Verilog that implements a subset of the RV32I ISA version 2.2. Documentation: https://toast-core.re

George Yu 27 Nov 2, 2022
Port of MIT's xv6 OS to the Nezha RISC-V board with Allwinner D1 SoC

xv6 is a re-implementation of Dennis Ritchie's and Ken Thompson's Unix Version 6 (v6). xv6 loosely follows the structure and style of v6, but is impl

Michael Engel 60 Nov 22, 2022
Crappy RISC-V CPU and fancy peripherals designed to be useful.

Crappy RISC-V CPU and fancy peripherals designed to be useful. Always half-baked. Prioritize compatibility over performance.

Peter Gu 22 Nov 18, 2022
Newlib for Xuantie RISC-V CPU, a lightweight C library for embedded systems.

README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, d

T-Head Semiconductor Co., Ltd. 5 Sep 9, 2022