riscv64: Port to word based mescc-tools.

* module/mescc/M1.scm (riscv:i-format, riscv:j-format, riscv:u-format):
New procedures for RISC-V instruction formats.
(info->M1): Use them to switch from !0xAB to M1
weird strings 'AB'.
* module/mescc/riscv64/as.scm,
lib/linux/riscv64-mes-m2/_exit.c
ib/linux/riscv64-mes-m2/_write.c,.
lib/linux/riscv64-mes-m2/crt1.M1,.
lib/linux/riscv64-mes-m2/syscall.c,.
lib/linux/riscv64-mes-mescc/_exit.c,.
lib/linux/riscv64-mes-mescc/_write.c,.
lib/linux/riscv64-mes-mescc/crt1.c,.
lib/linux/riscv64-mes-mescc/syscall-internal.c,.
lib/linux/riscv64-mes-mescc/syscall.c,.
lib/m2/riscv64/riscv64_defs.M1,.
lib/riscv64-mes-mescc/setjmp.c,.
lib/riscv64-mes/riscv64.M1: Switch to riscv64 word-based macros.
* lib/linux/open.c (open)[!SYS_open]: Add support using openat syscall.
* include/linux/riscv64/syscall.h (MAKESTRING, MAKESTRING2,
RISCV_SYSCALL): New macros.
This commit is contained in:
Andrius Štikonas 2023-05-19 21:51:46 +01:00 committed by Janneke Nieuwenhuizen
parent e5c556699c
commit 16f4fc3263
16 changed files with 824 additions and 861 deletions

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -28,6 +29,10 @@
* #define __ARCH_WANT_SYS_CLONE3 * #define __ARCH_WANT_SYS_CLONE3
*/ */
#define MAKESTRING(s) #s
#define MAKESTRING2(s) MAKESTRING (rd_a7 ! ## s addi)
#define RISCV_SYSCALL(s) MAKESTRING2 (s)
// libc-mini // libc-mini
#ifndef SYS_exit #ifndef SYS_exit
#define SYS_exit 93 #define SYS_exit 93

View file

@ -1,6 +1,7 @@
/* -*-comment-start: "//";comment-end:""-*- /* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2016,2017,2018,2019,2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -46,7 +47,13 @@ open (char const *file_name, int flags, ...)
va_list ap; va_list ap;
va_start (ap, flags); va_start (ap, flags);
int mask = va_arg (ap, int); int mask = va_arg (ap, int);
#if defined (SYS_open)
int r = _sys_call3 (SYS_open, (long) file_name, flags, mask); int r = _sys_call3 (SYS_open, (long) file_name, flags, mask);
#elif defined (SYS_openat)
int r = _sys_call4 (SYS_openat, AT_FDCWD, (long) file_name, flags, mask);
#else
#error No usable open syscall
#endif
va_end (ap); va_end (ap);
if (r > 2) if (r > 2)
__ungetc_clear (r); __ungetc_clear (r);

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -24,8 +25,8 @@
void void
_exit (int status) _exit (int status)
{ {
asm ("ld_____%a0,-0x08(%fp)"); asm ("rd_a0 rs1_fp !-8 ld");
asm ("li_____%a7,SYS_exit"); asm ("rd_a7 !93 addi # SYS_exit");
asm ("ecall"); asm ("ecall");
// no need to read return value // no need to read return value
} }

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -24,10 +25,10 @@
void void
_write (int filedes, void const *buffer, size_t size) _write (int filedes, void const *buffer, size_t size)
{ {
asm ("ld_____%a0,-0x08(%fp)"); asm ("rd_a0 rs1_fp !-8 ld");
asm ("ld_____%a1,-0x10(%fp)"); asm ("rd_a1 rs1_fp !-16 ld");
asm ("ld_____%a2,-0x18(%fp)"); asm ("rd_a2 rs1_fp !-24 ld");
asm ("li_____%a7,SYS_write"); asm ("rd_a7 !64 addi # SYS_write");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }

View file

@ -1,5 +1,6 @@
## Copyright (C) 2021 Andrius Štikonas ## Copyright (C) 2021 Andrius Štikonas
## Copyright (C) 2023 Janneke Nieuwenhuizen <janneke@gnu.org> ## Copyright (C) 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
## Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
## ##
## This file is part of stage0. ## This file is part of stage0.
## ##
@ -17,58 +18,36 @@
## along with stage0. If not, see <http://www.gnu.org/licenses/>. ## along with stage0. If not, see <http://www.gnu.org/licenses/>.
:_start :_start
RD_FP RS1_SP MV ; Protect stack pointer rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv ; Prepare argv
RD_A0 RS1_FP !8 ADDI ; ARGV_address = FP + 8 rd_a0 rs1_fp !8 addi ; ARGV_address = FP + 8
RD_SP RS1_SP !-8 ADDI rd_sp rs1_sp !-8 addi
RS1_SP RS2_A0 SD ; Put argv on the stack rs1_sp rs2_a0 sd ; Put argv on the stack
; Prepare envp ; Prepare envp
RD_A0 RS1_FP MV ; Address we need to load from rd_a0 rs1_fp mv ; Address we need to load from
RD_A0 RS1_A0 LD ; Get ARGC rd_a0 rs1_a0 ld ; Get ARGC
RD_A0 RS1_A0 !2 ADDI ; OFFSET = ARGC + 2 rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
RD_A0 RS1_A0 RS2_X3 SLLI ; OFFSET = OFFSET * WORDSIZE rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
RD_A0 RS1_FP RS2_A0 ADD ; ENVP_address = RSP + OFFSET rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
RD_SP RS1_SP !-8 ADDI rd_sp rs1_sp !-8 addi
RS1_SP RS2_A0 SD ; Put envp on the stack rs1_sp rs2_a0 sd ; Put envp on the stack
# AAARG, this also does not work!?
# pop____%t0 ; envp
# push___%t0
# li_____%t0,$i32 &GLOBAL_environ
# li_____%t0,$i16_0000 @0
# XXX avoid Illegal instruction
# li_____%t1,$i32 &GLOBAL___stdin
# sw_____%t0,0(%t1)
# li_____%t0,$i16_0000 @1
# srai___%t0,16
# li_____%t1,$i32 &GLOBAL___stdout
# sw_____%t0,0(%t1)
# li_____%t0,$i16_0000 @2
# XXX avoid Segmentation fault
# srai___%t0,16
# li_____%t1,$i32 &GLOBAL___stderr
# sw_____%t0,0(%t1)
; Stack offset ; Stack offset
RD_FP RS1_FP !8 ADDI rd_fp rs1_fp !8 addi
; Init libc ; Init libc
RD_RA $FUNCTION___init_io JAL rd_ra $FUNCTION___init_io jal
; Call main function ; Call main function
RD_RA $FUNCTION_main JAL rd_ra $FUNCTION_main jal
; Put return value on the stack so that _exit gets it ; Put return value on the stack so that _exit gets it
RD_SP RS1_SP !-16 ADDI rd_sp rs1_sp !-16 addi
RS1_SP RS2_A0 SD rs1_sp rs2_a0 sd
; Exit to kernel ; Exit to kernel
rd_a0 rs1_sp ld
RD_A0 RS1_SP LD rd_a7 !93 addi ; Syscall for exit
RD_A7 !93 ADDI ; Syscall for exit ecall ; Exit with code in a0
ECALL ; Exit with code in a0

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2016,2017,2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -25,76 +26,76 @@
long long
__sys_call (long sys_call) __sys_call (long sys_call)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call1 (long sys_call, long one) __sys_call1 (long sys_call, long one)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ld_____%a0,-0x10(%fp)"); asm ("rd_a0 rs1_fp !-16 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call2 (long sys_call, long one, long two) __sys_call2 (long sys_call, long one, long two)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ld_____%a0,-0x10(%fp)"); asm ("rd_a0 rs1_fp !-16 ld");
asm ("ld_____%a1,-0x18(%fp)"); asm ("rd_a1 rs1_fp !-24 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call3 (long sys_call, long one, long two, long three) __sys_call3 (long sys_call, long one, long two, long three)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ld_____%a0,-0x10(%fp)"); asm ("rd_a0 rs1_fp !-16 ld");
asm ("ld_____%a1,-0x18(%fp)"); asm ("rd_a1 rs1_fp !-24 ld");
asm ("ld_____%a2,-0x20(%fp)"); asm ("rd_a2 rs1_fp !-32 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call4 (long sys_call, long one, long two, long three, long four) __sys_call4 (long sys_call, long one, long two, long three, long four)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ld_____%a0,-0x10(%fp)"); asm ("rd_a0 rs1_fp !-16 ld");
asm ("ld_____%a1,-0x18(%fp)"); asm ("rd_a1 rs1_fp !-24 ld");
asm ("ld_____%a2,-0x20(%fp)"); asm ("rd_a2 rs1_fp !-32 ld");
asm ("ld_____%a3,-0x28(%fp)"); asm ("rd_a3 rs1_fp !-40 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call5 (long sys_call, long one, long two, long three, long four, long five) __sys_call5 (long sys_call, long one, long two, long three, long four, long five)
{ {
asm ("ld_____%a7,-0x08(%fp)"); asm ("rd_a7 rs1_fp !-8 ld");
asm ("ld_____%a0,-0x10(%fp)"); asm ("rd_a0 rs1_fp !-16 ld");
asm ("ld_____%a1,-0x18(%fp)"); asm ("rd_a1 rs1_fp !-24 ld");
asm ("ld_____%a2,-0x20(%fp)"); asm ("rd_a2 rs1_fp !-32 ld");
asm ("ld_____%a3,-0x28(%fp)"); asm ("rd_a3 rs1_fp !-40 ld");
asm ("ld_____%a4,-0x30(%fp)"); asm ("rd_a4 rs1_fp !-48 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -20,12 +21,13 @@
*/ */
#include "mes/lib-mini.h" #include "mes/lib-mini.h"
#include "linux/riscv64/syscall.h"
void void
_exit (int status) _exit (int status)
{ {
asm ("ld_____%a0,0x10(%fp)"); asm ("rd_a0 rs1_fp !16 ld");
asm ("li_____%a7,SYS_exit"); asm (RISCV_SYSCALL(SYS_exit));
asm ("ecall"); asm ("ecall");
// no need to read return value // no need to read return value
} }

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -20,14 +21,15 @@
*/ */
#include "mes/lib-mini.h" #include "mes/lib-mini.h"
#include "linux/riscv64/syscall.h"
void void
_write (int filedes, void const *buffer, size_t size) _write (int filedes, void const *buffer, size_t size)
{ {
asm ("ld_____%a0,0x10(%fp)"); asm ("rd_a0 rs1_fp !16 ld");
asm ("ld_____%a1,0x18(%fp)"); asm ("rd_a1 rs1_fp !24 ld");
asm ("ld_____%a2,0x20(%fp)"); asm ("rd_a2 rs1_fp !32 ld");
asm ("li_____%a7,SYS_write"); asm (RISCV_SYSCALL(SYS_write));
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2018,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -20,6 +21,8 @@
*/ */
#include "mes/lib-mini.h" #include "mes/lib-mini.h"
#include "linux/riscv64/syscall.h"
int main (int argc, char *argv[], char *envp[]); int main (int argc, char *argv[], char *envp[]);
/* mesc will generate the following preamble: /* mesc will generate the following preamble:
@ -30,27 +33,28 @@ int main (int argc, char *argv[], char *envp[]);
int int
_start () _start ()
{ {
// environ is &argv[argc + 1] asm ("rd_t1 rs1_fp mv");
asm ("mv_____%t1,%fp"); asm ("rd_t1 rs1_t1 !0x18 addi"); // 0x10 to skip over pushed fp+ra, 0x8 to skip over argc
asm ("addi___%t1,%t1,$i8_8 !0x1"); // 0x10 to skip over pushed fp+ra, 0x8 to skip over argc asm ("rd_t5 rs1_fp !0x10 addi"); // 0x10 to skip over pushed fp+ra
asm ("addi___%t5,%fp,$i8_0 !0x1"); // 0x10 to skip over pushed fp+ra asm ("rd_t0 rs1_t5 ld");
asm ("ld_____%t0,0(%t5)"); asm ("rd_t0 rs1_t0 !1 addi");
asm ("addi___%t0,%t0,1"); asm ("rd_t5 !3 addi"); // skip over all arguments and the final NULL
asm ("li_____%t5,$i32 %0x3"); // skip over all arguments and the final NULL asm ("rd_t0 rs1_t0 rs2_t5 sll");
asm ("sll____%t0,%t0,%t5"); asm ("rd_t0 rs1_t0 rs2_t1 add");
asm ("add____%t0,%t0,%t1"); asm ("rd_sp rs1_sp !-8 addi"); // push envp onto stack
asm ("push___%t0"); // envp asm ("rs1_sp rs2_t0 sd");
asm ("push___%t1"); // argv asm ("rd_sp rs1_sp !-8 addi"); // push argv onto stack
asm ("sd_____%t0,0(%t1)"); asm ("rs1_sp rs2_t1 sd");
asm ("addi___%t5,%fp,$i8_0 !0x1"); // 0x10 to skip over pushed fp+ra asm ("rd_t5 rs1_fp !0x10 addi"); // 0x10 to skip over pushed fp+ra
asm ("ld_____%t0,0(%t5)"); asm ("rd_t0 rs1_t5 ld");
asm ("push___%t0"); // argc asm ("rd_sp rs1_sp !-8 addi"); // push argc onto stack
asm ("rs1_sp rs2_t0 sd");
__init_io (); __init_io ();
main (); main ();
asm ("mv_____%a0,%t0"); asm ("rd_a0 rs1_t0 mv");
asm ("li_____%a7,SYS_exit"); asm (RISCV_SYSCALL(SYS_exit));
asm ("ecall"); asm ("ecall");
asm ("ebreak"); asm ("ebreak");
} }

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -25,23 +26,23 @@
static long static long
__sys_call_internal (long sys_call) __sys_call_internal (long sys_call)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
static long static long
__sys_call2_internal (long sys_call, long one, long two) __sys_call2_internal (long sys_call, long one, long two)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ld_____%a1,0x20(%fp)"); asm ("rd_a1 rs1_fp !32 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
/* Return < 0 on error (errno-like value from kernel), or 0 on success */ /* Return < 0 on error (errno-like value from kernel), or 0 on success */

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -25,76 +26,76 @@
long long
__sys_call (long sys_call) __sys_call (long sys_call)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call1 (long sys_call, long one) __sys_call1 (long sys_call, long one)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call2 (long sys_call, long one, long two) __sys_call2 (long sys_call, long one, long two)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ld_____%a1,0x20(%fp)"); asm ("rd_a1 rs1_fp !32 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call3 (long sys_call, long one, long two, long three) __sys_call3 (long sys_call, long one, long two, long three)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ld_____%a1,0x20(%fp)"); asm ("rd_a1 rs1_fp !32 ld");
asm ("ld_____%a2,0x28(%fp)"); asm ("rd_a2 rs1_fp !40 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call4 (long sys_call, long one, long two, long three, long four) __sys_call4 (long sys_call, long one, long two, long three, long four)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ld_____%a1,0x20(%fp)"); asm ("rd_a1 rs1_fp !32 ld");
asm ("ld_____%a2,0x28(%fp)"); asm ("rd_a2 rs1_fp !40 ld");
asm ("ld_____%a3,0x30(%fp)"); asm ("rd_a3 rs1_fp !48 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long
__sys_call5 (long sys_call, long one, long two, long three, long four, long five) __sys_call5 (long sys_call, long one, long two, long three, long four, long five)
{ {
asm ("ld_____%a7,0x10(%fp)"); asm ("rd_a7 rs1_fp !16 ld");
asm ("ld_____%a0,0x18(%fp)"); asm ("rd_a0 rs1_fp !24 ld");
asm ("ld_____%a1,0x20(%fp)"); asm ("rd_a1 rs1_fp !32 ld");
asm ("ld_____%a2,0x28(%fp)"); asm ("rd_a2 rs1_fp !40 ld");
asm ("ld_____%a3,0x30(%fp)"); asm ("rd_a3 rs1_fp !48 ld");
asm ("ld_____%a4,0x38(%fp)"); asm ("rd_a4 rs1_fp !56 ld");
asm ("ecall"); asm ("ecall");
asm ("mv_____%t0,%a0"); asm ("rd_t0 rs1_a0 mv");
} }
long long

View file

@ -19,219 +19,222 @@ DEFINE NULL 0000000000000000
;; Opcodes ;; Opcodes
;; RV32I Base Instruction Set ;; RV32I Base Instruction Set
DEFINE LUI 37000000 DEFINE lui 37000000
DEFINE AUIPC 17000000 DEFINE auipc 17000000
DEFINE JAL 6F000000 DEFINE jal 6F000000
DEFINE JALR 67000000 DEFINE jalr 67000000
DEFINE BEQ 63000000 DEFINE beq 63000000
DEFINE BNE 63100000 DEFINE bne 63100000
DEFINE BLT 63400000 DEFINE blt 63400000
DEFINE BGE 63500000 DEFINE bge 63500000
DEFINE BLTU 63600000 DEFINE bltu 63600000
DEFINE BGEU 63700000 DEFINE bgeu 63700000
DEFINE LB 03000000 DEFINE lb 03000000
DEFINE LH 03100000 DEFINE lh 03100000
DEFINE LW 03200000 DEFINE lw 03200000
DEFINE LBU 03400000 DEFINE lbu 03400000
DEFINE LHU 03500000 DEFINE lhu 03500000
DEFINE SB 23000000 DEFINE sb 23000000
DEFINE SH 23100000 DEFINE sh 23100000
DEFINE SW 23200000 DEFINE sw 23200000
DEFINE ADDI 13000000 DEFINE addi 13000000
DEFINE SLTI 13200000 DEFINE slti 13200000
DEFINE SLTIU 13300000 DEFINE sltiu 13300000
DEFINE XORI 13400000 DEFINE xori 13400000
DEFINE ORI 13600000 DEFINE ori 13600000
DEFINE ANDI 13700000 DEFINE andi 13700000
DEFINE SLLI 13100000 DEFINE slli 13100000
DEFINE SRLI 13500000 DEFINE srli 13500000
DEFINE SRAI 13500040 DEFINE srai 13500040
DEFINE ADD 33000000 DEFINE add 33000000
DEFINE SUB 33000040 DEFINE sub 33000040
DEFINE SLL 33100000 DEFINE sll 33100000
DEFINE SLT 33200000 DEFINE slt 33200000
DEFINE SLTU 33300000 DEFINE sltu 33300000
DEFINE XOR 33400000 DEFINE xor 33400000
DEFINE SRL 33500000 DEFINE srl 33500000
DEFINE SRA 33500040 DEFINE sra 33500040
DEFINE OR 33600000 DEFINE or 33600000
DEFINE AND 33700000 DEFINE and 33700000
DEFINE ECALL 73000000 DEFINE ecall 73000000
DEFINE ebreak 73001000
;; RV64I Base Instruction set ;; RV64I Base Instruction set
DEFINE LWU 03600000 DEFINE lwu 03600000
DEFINE LD 03300000 DEFINE ld 03300000
DEFINE SD 23300000 DEFINE sd 23300000
DEFINE ADDIW 1B000000 DEFINE addiw 1B000000
DEFINE SLLIW 1B100000 DEFINE slliw 1B100000
DEFINE SRLIW 1B500000 DEFINE srliw 1B500000
DEFINE SRAIW 1B500040 DEFINE sraiw 1B500040
DEFINE ADDW 3B000000 DEFINE addw 3B000000
DEFINE SUBW 3B000040 DEFINE subw 3B000040
DEFINE SLLW 3B100000 DEFINE sllw 3B100000
DEFINE SRLW 3B500000 DEFINE srlw 3B500000
DEFINE SRAW 3B500040 DEFINE sraw 3B500040
;; RV32M Standard Extensions ;; RV32M Standard Extensions
DEFINE MUL 33000002 DEFINE mul 33000002
DEFINE MULH 33100002 DEFINE mulh 33100002
DEFINE MULHSU 33200002 DEFINE mulhsu 33200002
DEFINE MULHU 33300002 DEFINE mulhu 33300002
DEFINE DIV 33400002 DEFINE div 33400002
DEFINE DIVU 33500002 DEFINE divu 33500002
DEFINE REM 33600002 DEFINE rem 33600002
DEFINE REMU 33700002 DEFINE remu 33700002
;; RV64M Standard Extensions ;; RV64M Standard Extensions
DEFINE MULW 3B000002 DEFINE mulw 3B000002
DEFINE DIVW 3B400002 DEFINE divw 3B400002
DEFINE DIVUW 3B500002 DEFINE divuw 3B500002
DEFINE REMW 3B600002 DEFINE remw 3B600002
DEFINE REMUW 3B700002 DEFINE remuw 3B700002
;; Pseudoinstructions ;; Pseudoinstructions
DEFINE NOP 13000000 # ADDI DEFINE nop 13000000 # addi
DEFINE MV 13000000 # ADDI DEFINE mv 13000000 # addi
DEFINE NOT 1340F0FF # XORI, RD, RS, -1 DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE BEQZ 63000000 # BEQ DEFINE beqz 63000000 # beq
DEFINE BNEZ 63100000 # BNE DEFINE bnez 63100000 # bne
DEFINE BLTZ 63400000 # BLT DEFINE bltz 63400000 # blt
DEFINE RETURN 67800000 # RS1_RA JALR DEFINE ret 67800000 # rs1_ra jalr
;; Destination registers ;; Destination registers
;; register_number << 7 ;; register_number << 7
DEFINE RD_RA .80000000 DEFINE rd_ra .80000000
DEFINE RD_SP .00010000 DEFINE rd_sp .00010000
DEFINE RD_GP .80010000 DEFINE rd_gp .80010000
DEFINE RD_TP .00020000 DEFINE rd_tp .00020000
DEFINE RD_T0 .80020000 DEFINE rd_t0 .80020000
DEFINE RD_T1 .00030000 DEFINE rd_t1 .00030000
DEFINE RD_T2 .80030000 DEFINE rd_t2 .80030000
DEFINE RD_S0 .00040000 DEFINE rd_s0 .00040000
DEFINE RD_FP .00040000 DEFINE rd_fp .00040000
DEFINE RD_S1 .80040000 DEFINE rd_s1 .80040000
DEFINE RD_A0 .00050000 DEFINE rd_a0 .00050000
DEFINE RD_A1 .80050000 DEFINE rd_a1 .80050000
DEFINE RD_A2 .00060000 DEFINE rd_a2 .00060000
DEFINE RD_A3 .80060000 DEFINE rd_a3 .80060000
DEFINE RD_A4 .00070000 DEFINE rd_a4 .00070000
DEFINE RD_A5 .80070000 DEFINE rd_a5 .80070000
DEFINE RD_A6 .00080000 DEFINE rd_a6 .00080000
DEFINE RD_A7 .80080000 DEFINE rd_a7 .80080000
DEFINE RD_S2 .00090000 DEFINE rd_s2 .00090000
DEFINE RD_S3 .80090000 DEFINE rd_s3 .80090000
DEFINE RD_S4 .000A0000 DEFINE rd_s4 .000A0000
DEFINE RD_S5 .800A0000 DEFINE rd_s5 .800A0000
DEFINE RD_S6 .000B0000 DEFINE rd_s6 .000B0000
DEFINE RD_S7 .800B0000 DEFINE rd_s7 .800B0000
DEFINE RD_S8 .000C0000 DEFINE rd_s8 .000C0000
DEFINE RD_S9 .800C0000 DEFINE rd_s9 .800C0000
DEFINE RD_S10 .000D0000 DEFINE rd_s10 .000D0000
DEFINE RD_S11 .800D0000 DEFINE rd_s11 .800D0000
DEFINE RD_T3 .000E0000 DEFINE rd_t3 .000E0000
DEFINE RD_T4 .800E0000 DEFINE rd_t4 .800E0000
DEFINE RD_T5 .000F0000 DEFINE rd_t5 .000F0000
DEFINE RD_T6 .800F0000 DEFINE rd_t6 .800F0000
;; First source registers ;; First source registers
;; register_number << 15 ;; register_number << 15
DEFINE RS1_RA .00800000 DEFINE rs1_ra .00800000
DEFINE RS1_SP .00000100 DEFINE rs1_sp .00000100
DEFINE RS1_GP .00800100 DEFINE rs1_gp .00800100
DEFINE RS1_TP .00000200 DEFINE rs1_tp .00000200
DEFINE RS1_T0 .00800200 DEFINE rs1_t0 .00800200
DEFINE RS1_T1 .00000300 DEFINE rs1_t1 .00000300
DEFINE RS1_T2 .00800300 DEFINE rs1_t2 .00800300
DEFINE RS1_S0 .00000400 DEFINE rs1_s0 .00000400
DEFINE RS1_FP .00000400 DEFINE rs1_fp .00000400
DEFINE RS1_S1 .00800400 DEFINE rs1_s1 .00800400
DEFINE RS1_A0 .00000500 DEFINE rs1_a0 .00000500
DEFINE RS1_A1 .00800500 DEFINE rs1_a1 .00800500
DEFINE RS1_A2 .00000600 DEFINE rs1_a2 .00000600
DEFINE RS1_A3 .00800600 DEFINE rs1_a3 .00800600
DEFINE RS1_A4 .00000700 DEFINE rs1_a4 .00000700
DEFINE RS1_A5 .00800700 DEFINE rs1_a5 .00800700
DEFINE RS1_A6 .00000800 DEFINE rs1_a6 .00000800
DEFINE RS1_A7 .00800800 DEFINE rs1_a7 .00800800
DEFINE RS1_S2 .00000900 DEFINE rs1_s2 .00000900
DEFINE RS1_S3 .00800900 DEFINE rs1_s3 .00800900
DEFINE RS1_S4 .00000A00 DEFINE rs1_s4 .00000A00
DEFINE RS1_S5 .00800A00 DEFINE rs1_s5 .00800A00
DEFINE RS1_S6 .00000B00 DEFINE rs1_s6 .00000B00
DEFINE RS1_S7 .00800B00 DEFINE rs1_s7 .00800B00
DEFINE RS1_S8 .00000C00 DEFINE rs1_s8 .00000C00
DEFINE RS1_S9 .00800C00 DEFINE rs1_s9 .00800C00
DEFINE RS1_S10 .00000D00 DEFINE rs1_s10 .00000D00
DEFINE RS1_S11 .00800D00 DEFINE rs1_s11 .00800D00
DEFINE RS1_T3 .00000E00 DEFINE rs1_t3 .00000E00
DEFINE RS1_T4 .00800E00 DEFINE rs1_t4 .00800E00
DEFINE RS1_T5 .00000F00 DEFINE rs1_t5 .00000F00
DEFINE RS1_T6 .00800F00 DEFINE rs1_t6 .00800F00
;; Second source registers ;; Second source registers
;; register_number << 20 ;; register_number << 20
DEFINE RS2_RA .00001000 DEFINE rs2_ra .00001000
DEFINE RS2_SP .00002000 DEFINE rs2_sp .00002000
DEFINE RS2_GP .00003000 DEFINE rs2_gp .00003000
DEFINE RS2_TP .00004000 DEFINE rs2_tp .00004000
DEFINE RS2_T0 .00005000 DEFINE rs2_t0 .00005000
DEFINE RS2_T1 .00006000 DEFINE rs2_t1 .00006000
DEFINE RS2_T2 .00007000 DEFINE rs2_t2 .00007000
DEFINE RS2_S0 .00008000 DEFINE rs2_s0 .00008000
DEFINE RS2_FP .00008000 DEFINE rs2_fp .00008000
DEFINE RS2_S1 .00009000 DEFINE rs2_s1 .00009000
DEFINE RS2_A0 .0000A000 DEFINE rs2_a0 .0000A000
DEFINE RS2_A1 .0000B000 DEFINE rs2_a1 .0000B000
DEFINE RS2_A2 .0000C000 DEFINE rs2_a2 .0000C000
DEFINE RS2_A3 .0000D000 DEFINE rs2_a3 .0000D000
DEFINE RS2_A4 .0000E000 DEFINE rs2_a4 .0000E000
DEFINE RS2_A5 .0000F000 DEFINE rs2_a5 .0000F000
DEFINE RS2_A6 .00000001 DEFINE rs2_a6 .00000001
DEFINE RS2_A7 .00001001 DEFINE rs2_a7 .00001001
DEFINE RS2_S2 .00002001 DEFINE rs2_s2 .00002001
DEFINE RS2_S3 .00003001 DEFINE rs2_s3 .00003001
DEFINE RS2_S4 .00004001 DEFINE rs2_s4 .00004001
DEFINE RS2_S5 .00005001 DEFINE rs2_s5 .00005001
DEFINE RS2_S6 .00006001 DEFINE rs2_s6 .00006001
DEFINE RS2_S7 .00007001 DEFINE rs2_s7 .00007001
DEFINE RS2_S8 .00008001 DEFINE rs2_s8 .00008001
DEFINE RS2_S9 .00009001 DEFINE rs2_s9 .00009001
DEFINE RS2_S10 .0000A001 DEFINE rs2_s10 .0000A001
DEFINE RS2_S11 .0000B001 DEFINE rs2_s11 .0000B001
DEFINE RS2_T3 .0000C001 DEFINE rs2_t3 .0000C001
DEFINE RS2_T4 .0000D001 DEFINE rs2_t4 .0000D001
DEFINE RS2_T5 .0000E001 DEFINE rs2_t5 .0000E001
DEFINE RS2_T6 .0000F001 DEFINE rs2_t6 .0000F001
DEFINE RS2_X0 .00000000 DEFINE rs1_x0 .00000000
DEFINE RS2_X1 .00001000
DEFINE RS2_X2 .00002000 DEFINE rs2_x0 .00000000
DEFINE RS2_X3 .00003000 DEFINE rs2_x1 .00001000
DEFINE RS2_X4 .00004000 DEFINE rs2_x2 .00002000
DEFINE RS2_X5 .00005000 DEFINE rs2_x3 .00003000
DEFINE RS2_X6 .00006000 DEFINE rs2_x4 .00004000
DEFINE RS2_X7 .00007000 DEFINE rs2_x5 .00005000
DEFINE RS2_X8 .00008000 DEFINE rs2_x6 .00006000
DEFINE RS2_X9 .00009000 DEFINE rs2_x7 .00007000
DEFINE RS2_X10 .0000A000 DEFINE rs2_x8 .00008000
DEFINE RS2_X11 .0000B000 DEFINE rs2_x9 .00009000
DEFINE RS2_X12 .0000C000 DEFINE rs2_x10 .0000A000
DEFINE RS2_X13 .0000D000 DEFINE rs2_x11 .0000B000
DEFINE RS2_X14 .0000E000 DEFINE rs2_x12 .0000C000
DEFINE RS2_X15 .0000F000 DEFINE rs2_x13 .0000D000
DEFINE RS2_X16 .00000001 DEFINE rs2_x14 .0000E000
DEFINE RS2_X17 .00001001 DEFINE rs2_x15 .0000F000
DEFINE RS2_X18 .00002001 DEFINE rs2_x16 .00000001
DEFINE RS2_X19 .00003001 DEFINE rs2_x17 .00001001
DEFINE RS2_X20 .00004001 DEFINE rs2_x18 .00002001
DEFINE RS2_X21 .00005001 DEFINE rs2_x19 .00003001
DEFINE RS2_X22 .00006001 DEFINE rs2_x20 .00004001
DEFINE RS2_X23 .00007001 DEFINE rs2_x21 .00005001
DEFINE RS2_X24 .00008001 DEFINE rs2_x22 .00006001
DEFINE RS2_X25 .00009001 DEFINE rs2_x23 .00007001
DEFINE RS2_X26 .0000A001 DEFINE rs2_x24 .00008001
DEFINE RS2_X27 .0000B001 DEFINE rs2_x25 .00009001
DEFINE RS2_X28 .0000C001 DEFINE rs2_x26 .0000A001
DEFINE RS2_X29 .0000D001 DEFINE rs2_x27 .0000B001
DEFINE RS2_X30 .0000E001 DEFINE rs2_x28 .0000C001
DEFINE RS2_X31 .0000F001 DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001

View file

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software * GNU Mes --- Maxwell Equations of Software
* Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> * Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
* *
* This file is part of GNU Mes. * This file is part of GNU Mes.
* *
@ -26,12 +27,12 @@ void
longjmp (jmp_buf env, int val) longjmp (jmp_buf env, int val)
{ {
val = val == 0 ? 1 : val; val = val == 0 ? 1 : val;
asm ("ld_____%fp,0x10(%fp)"); // env* asm ("rd_fp rs1_fp !16 ld"); // env*
asm ("ld_____%t0,0x8(%fp)"); // env.__pc asm ("rd_t0 rs1_fp !8 ld"); // env.__pc
asm ("ld_____%sp,0x10(%fp)"); // env.__sp asm ("rd_sp rs1_fp !16 ld"); // env.__sp
asm ("ld_____%fp,0x0(%fp)"); // env.__bp asm ("rd_fp rs1_fp ld"); // env.__bp
asm ("jr_____%t0"); asm ("rs1_t0 jalr");
// not reached // not reached
exit (42); exit (42);
} }

View file

@ -1,362 +1,240 @@
### GNU Mes --- Maxwell Equations of Software ## Copyright (C) 2021 Andrius Štikonas
### Copyright © 2017,2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ## This file is part of M2-Planet.
### Copyright © 2019,2020 Danny Milosavljevic <dannym@scratchpost.org> ##
### Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> ## M2-Planet is free software: you can redistribute it and/or modify
### ## it under the terms of the GNU General Public License as published by
### This file is part of GNU Mes. ## the Free Software Foundation, either version 3 of the License, or
### ## (at your option) any later version.
### Mes is free software; you can redistribute it and/or modify it ##
### under the terms of the GNU General Public License as published by ## M2-Planet is distributed in the hope that it will be useful,
### the Free Software Foundation; either version 3 of the License, or (at ## but WITHOUT ANY WARRANTY; without even the implied warranty of
### your option) any later version. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### ## GNU General Public License for more details.
### GNU Mes is distributed in the hope that it will be useful, but ##
### WITHOUT ANY WARRANTY; without even the implied warranty of ## You should have received a copy of the GNU General Public License
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
## Multi-instruction macros DEFINE NULL 0000000000000000
DEFINE j.a____$i32 970f000083efcf0067800f00 # auipc t6,0x0; lwu t6,12(t6); jr t6
DEFINE jal.a__$i32 970f000093804f0183ef0f0167800f00 # auipc t6,0x0; addi ra,t6,20; lwu t6,16(t6); jr t6
DEFINE push___%t0 130181ff23305100 # addi sp,sp,-0x8; sd t0,0(sp)
DEFINE push___%t1 130181ff23306100 # addi sp,sp,-0x8; sd t1,0(sp)
DEFINE push___%fp 130181ff23308100 # addi sp,sp,-0x8; sd fp,0(sp)
DEFINE push___%ra 130181ff23301100 # addi sp,sp,-0x8; sd ra,0(sp)
DEFINE push___%t5 130181ff2330e101 # addi sp,sp,-0x8; sd t5,0(sp)
DEFINE pop____%t0 8332010013018100 # ld t0,0(sp); addi sp,sp,0x8
DEFINE pop____%t1 0333010013018100 # ld t1,0(sp); addi sp,sp,0x8
DEFINE pop____%fp 0334010013018100 # ld fp,0(sp); addi sp,sp,0x8
DEFINE pop____%ra 8330010013018100 # ld ra,0(sp); addi sp,sp,0x8
## Immediate values ;; Opcodes
DEFINE li_____%t0,$i32 9702000083a2c2006f008000 # auipc t0,0x0; lw t0,12(t0); j 8
DEFINE li_____%t1,$i32 170300000323c3006f008000 # auipc t1,0x0; lw t1,12(t1); j 8
DEFINE li_____%a0,$i32 170500000325c5006f008000 # auipc a0,0x0; lw a0,12(a0); j 8
DEFINE li_____%a1,$i32 9705000083a5c5006f008000 # auipc a1,0x0; lw a1,12(a1); j 8
DEFINE li_____%a2,$i32 170600000326c6006f008000 # auipc a2,0x0; lw a2,12(a2); j 8
DEFINE li_____%a3,$i32 9706000083a6c6006f008000 # auipc a3,0x0; lw a3,12(a3); j 8
DEFINE li_____%a4,$i32 170700000327c7006f008000 # auipc a4,0x0; lw a4,12(a4); j 8
DEFINE li_____%a5,$i32 9707000083a7c7006f008000 # auipc a5,0x0; lw a5,12(a5); j 8
DEFINE li_____%a7,$i32 9708000083a8c8006f008000 # auipc a7,0x0; lw a7,12(a7); j 8
DEFINE li_____%t5,$i32 170f0000032fcf006f008000 # auipc t5,0x0; lw t5,12(t5); j 8
DEFINE li_____%s10,$i32 170d0000032dcd006f008000 # auipc s10,0x0; lw s10,12(s10); j 8
DEFINE li_____%s11,$i32 970d000083adcd006f008000 # auipc s11,0x0; lw s11,12(s11); j 8
DEFINE li_____%t0,$i64 9702000083b2c2006f00c000 # auipc t0,0x0; ld t0,12(t0); j 12
DEFINE li_____%t1,$i64 170300000333c3006f00c000 # auipc t1,0x0; ld t1,12(t1); j 12
DEFINE li_____%t5,$i64 170f0000033fcf006f00c000 # auipc t5,0x0; ld t5,12(t5); j 12
DEFINE li_____%s10,$i64 170d0000033dcd006f00c000 # auipc s10,0x0; ld s10,12(s10); j 12
DEFINE li_____%s11,$i64 970d000083bdcd006f00c000 # auipc s11,0x0; ld s11,12(s11); j 12
DEFINE li_____%t0,$i16_0000 b702 # lui t0,0
DEFINE srai___%t0,16 93d20241
DEFINE li_____%t1,$i16_0000 3703 # lui t1,0
DEFINE srai___%t1,16 13530341
DEFINE li_____%t5,$i16_0000 370f # lui t5,0
DEFINE srai___%t5,16 135f0f41
DEFINE li_____%t4,$i16_0000 b70e # lui t4,0
DEFINE srai___%t4,16 93de0e41
DEFINE li_____%s10,$i16_0000 370d # lui s10,0
DEFINE srai___%s10,16 135d0d41
DEFINE li_____%s11,$i16_0000 b70d # lui s11,0
DEFINE srai___%s11,16 93dd0d41
## Immediate adds ;; RV32I Base Instruction Set
DEFINE addi___%sp,%sp,$i32 970f000083af0f013301f1016f008000 # auipc t6,0x0; lw t6,16(t6); add sp,sp,t6; j 8 DEFINE lui 37000000
DEFINE addi___%sp,%sp,$i64 1701000003310101330121006f00c000 # auipc sp,0x0; ld sp,16(sp); add sp,sp,sp; j 12 DEFINE auipc 17000000
DEFINE addi___%t0,%t0,$i32 970f000083af0f01b382f2016f008000 # auipc t6,0x0; lw t6,16(t6); add t0,t0,t6; j 8 DEFINE jal 6F000000
DEFINE addi___%t0,%t0,$i64 9702000083b20201b38252006f00c000 # auipc t0,0x0; ld t0,16(t0); add t0,t0,t0; j 12 DEFINE jalr 67000000
DEFINE addi___%t1,%t1,$i32 970f000083af0f013303f3016f008000 # auipc t6,0x0; lw t6,16(t6); add t1,t1,t6; j 8 DEFINE beq 63000000
DEFINE addi___%t1,%t1,$i64 1703000003330301330363006f00c000 # auipc t1,0x0; ld t1,16(t1); add t1,t1,t1; j 12 DEFINE bne 63100000
DEFINE addi___%t5,%t5,$i32 970f000083af0f01330fff016f008000 # auipc t6,0x0; lw t6,16(t6); add t5,t5,t6; j 8 DEFINE blt 63400000
DEFINE addi___%t5,%t5,$i64 170f0000033f0f01330fef016f00c000 # auipc t5,0x0; ld t5,16(t5); add t5,t5,t5; j 12 DEFINE bge 63500000
DEFINE addi___%t4,%t4,$i32 970f000083af0f01b38efe016f008000 # auipc t6,0x0; lw t6,16(t6); add t4,t4,t6; j 8 DEFINE bltu 63600000
DEFINE addi___%t4,%t4,$i64 970e000083be0e01b38ede016f00c000 # auipc t4,0x0; ld t4,16(t4); add t4,t4,t4; j 12 DEFINE bgeu 63700000
DEFINE addi___%t0,%t0,-1 9382f2ff DEFINE lb 03000000
DEFINE addi___%t0,%t0,1 93821200 DEFINE lh 03100000
DEFINE addi___%t0,%t0,$i8_0 938202 DEFINE lw 03200000
DEFINE addi___%t0,%t0,$i8_8 938282 DEFINE lbu 03400000
DEFINE addi___%t1,%t1,-1 1303f3ff DEFINE lhu 03500000
DEFINE addi___%t1,%t1,1 13031300 DEFINE sb 23000000
DEFINE addi___%t1,%t1,$i8_0 130303 DEFINE sh 23100000
DEFINE addi___%t1,%t1,$i8_8 130383 DEFINE sw 23200000
DEFINE addi___%sp,%sp,-1 1301f1ff DEFINE addi 13000000
DEFINE addi___%sp,%sp,1 13011100 DEFINE slti 13200000
DEFINE addi___%sp,%sp,$i8_0 130101 DEFINE sltiu 13300000
DEFINE addi___%sp,%sp,$i8_8 130181 DEFINE xori 13400000
DEFINE addi___%t5,%t5,-1 130fffff DEFINE ori 13600000
DEFINE addi___%t5,%t5,1 130f1f00 DEFINE andi 13700000
DEFINE addi___%t5,%t5,$i8_0 130f0f DEFINE slli 13100000
DEFINE addi___%t5,%t5,$i8_8 130f8f DEFINE srli 13500000
DEFINE addi___%t4,%t4,-1 938efeff DEFINE srai 13500040
DEFINE addi___%t4,%t4,1 938e1e00 DEFINE add 33000000
DEFINE addi___%t4,%t4,$i8_0 938e0e DEFINE sub 33000040
DEFINE addi___%t4,%t4,$i8_8 938e8e DEFINE sll 33100000
DEFINE addi___%t5,%fp,$i32 970f000083af0f01330ff4016f008000 # auipc t6,0x0; lw t6,16(t6); add t5,fp,t6; j 8 DEFINE slt 33200000
DEFINE addi___%t5,%fp,$i8_0 130f04 DEFINE sltu 33300000
DEFINE addi___%t5,%fp,$i8_8 130f84 DEFINE xor 33400000
DEFINE srl 33500000
## Condition flags and jumps emulation DEFINE sra 33500040
DEFINE cond.nz 330dbd41133d1d00930d0000 # sub s10,s10,s11; seqz s10,s10; mv s11,x0 DEFINE or 33600000
DEFINE jeq.a__$i32 631abd01970f000083efcf0067800f00 # bne s10,s11,20; auipc t6,0x0; lwu t6,12(t6); jr t6 DEFINE and 33700000
DEFINE jne.a__$i32 630abd01970f000083efcf0067800f00 # beq s10,s11,20; auipc t6,0x0; lwu t6,12(t6); jr t6
DEFINE seq____%t0 b302bd4193b21200 # sub t0,s10,s11; seqz t0,t0
DEFINE sne____%t0 b302bd41b3325000 # sub t0,s10,s11; snez t0,t0
DEFINE sge____%t0 b322bd0193b21200 # slt t0,s10,s11; seqz t0,t0
DEFINE slt____%t0 b322bd01
DEFINE sgt____%t0 b3a2ad01 # slt t0,s11,s10
DEFINE sle____%t0 b3a2ad0193b21200 # slt t0,s11,s10; seqz t0,t0
DEFINE sgeu___%t0 b332bd0193b21200 # sltu t0,s10,s11; seqz t0,t0
DEFINE sltu___%t0 b332bd01
DEFINE sgtu___%t0 b3b2ad01 # sltu t0,s11,s10
DEFINE sleu___%t0 b3b2ad0193b21200 # sltu t0,s11,s10; seqz t0,t0
DEFINE seq____%t1 3303bd4113331300 # sub t1,s10,s11; seqz t1,t1
DEFINE sne____%t1 3303bd4133336000 # sub t1,s10,s11; snez t1,t1
DEFINE sge____%t1 3323bd0113331300 # slt t1,s10,s11; seqz t1,t1
DEFINE slt____%t1 3323bd01
DEFINE sgt____%t1 33a3ad01 # slt t1,s11,s10
DEFINE sle____%t1 33a3ad0113331300 # slt t1,s11,s10; seqz t1,t1
DEFINE sgeu___%t1 3333bd0113331300 # sltu t1,s10,s11; seqz t1,t1
DEFINE sltu___%t1 3333bd01
DEFINE sgtu___%t1 33b3ad01 # sltu t1,s11,s10
DEFINE sleu___%t1 33b3ad0113331300 # sltu t1,s11,s10; seqz t1,t1
## Sign extension
DEFINE ext.b__%t0 93f2f20f # andi t0,t0,255
DEFINE ext.b__%t1 1373f30f # andi t1,t1,255
DEFINE sext.b_%t0 9392820393d28243 # slli t0,t0,56; srai t0,t0,56
DEFINE sext.b_%t1 1313830313538343 # slli t1,t1,56; srai t1,t1,56
DEFINE ext.h__%t0 b70f0100938fffffb3f2f201 # li t6,65535; and t0,t0,t6
DEFINE ext.h__%t1 b70f0100938fffff3373f301 # li t6,65535; and t1,t1,t6
DEFINE sext.h_%t0 9392020393d20243 # slli t0,t0,48; srai t0,t0,48
DEFINE sext.h_%t1 1313030313530343 # slli t1,t1,48; srai t1,t1,48
DEFINE ext.w__%t0 9b0ff0ffb3f2f201 # li t6,4294967295; and t0,t0,t6
DEFINE ext.w__%t1 9b0ff0ff3373f301 # li t6,4294967295; and t1,t1,t6
DEFINE sext.w_%t0 9b820200
DEFINE sext.w_%t1 1b030300
## Simple instructions
DEFINE ecall 73000000 DEFINE ecall 73000000
DEFINE ebreak 73001000 DEFINE ebreak 73001000
DEFINE ret 67800000
DEFINE nop 13000000
DEFINE add____%t0,%t0,%t0 b3825200
DEFINE add____%t0,%t0,%t1 b3826200
DEFINE add____%t1,%t1,%t0 33035300
DEFINE add____%t1,%t1,%t1 33036300
DEFINE sub____%t0,%t0,%t0 b3825240
DEFINE sub____%t0,%t0,%t1 b3826240
DEFINE sub____%t1,%t1,%t0 33035340
DEFINE sub____%t1,%t1,%t1 33036340
DEFINE and____%t0,%t0,%t0 b3f25200
DEFINE and____%t0,%t0,%t1 b3f26200
DEFINE and____%t1,%t1,%t0 33735300
DEFINE and____%t1,%t1,%t1 33736300
DEFINE or_____%t0,%t0,%t0 b3e25200
DEFINE or_____%t0,%t0,%t1 b3e26200
DEFINE or_____%t1,%t1,%t0 33635300
DEFINE or_____%t1,%t1,%t1 33636300
DEFINE xor____%t0,%t0,%t0 b3c25200
DEFINE xor____%t0,%t0,%t1 b3c26200
DEFINE xor____%t1,%t1,%t0 33435300
DEFINE xor____%t1,%t1,%t1 33436300
DEFINE mul____%t0,%t0,%t0 b3825202
DEFINE mul____%t0,%t0,%t1 b3826202
DEFINE mul____%t1,%t1,%t0 33035302
DEFINE mul____%t1,%t1,%t1 33036302
DEFINE div____%t0,%t0,%t0 b3c25202
DEFINE div____%t0,%t0,%t1 b3c26202
DEFINE div____%t1,%t1,%t0 33435302
DEFINE div____%t1,%t1,%t1 33436302
DEFINE rem____%t0,%t0,%t0 b3e25202
DEFINE rem____%t0,%t0,%t1 b3e26202
DEFINE rem____%t1,%t1,%t0 33635302
DEFINE rem____%t1,%t1,%t1 33636302
DEFINE sll____%t0,%t0,%t0 b3925200
DEFINE sll____%t0,%t0,%t1 b3926200
DEFINE sll____%t1,%t1,%t0 33135300
DEFINE sll____%t1,%t1,%t1 33136300
DEFINE srl____%t0,%t0,%t0 b3d25200
DEFINE srl____%t0,%t0,%t1 b3d26200
DEFINE srl____%t1,%t1,%t0 33535300
DEFINE srl____%t1,%t1,%t1 33536300
DEFINE sra____%t0,%t0,%t0 b3d25240
DEFINE sra____%t0,%t0,%t1 b3d26240
DEFINE sra____%t1,%t1,%t0 33535340
DEFINE sra____%t1,%t1,%t1 33536340
DEFINE not____%t0,%t0 93c2f2ff
DEFINE not____%t0,%t1 9342f3ff
DEFINE not____%t1,%t0 13c3f2ff
DEFINE not____%t1,%t1 1343f3ff
DEFINE sll____%t0,%t0,%t5 b392e201
DEFINE sll____%t1,%t1,%t5 3313e301
DEFINE and____%t0,%t0,%t5 b3f2e201
DEFINE and____%t1,%t1,%t5 3373e301
DEFINE add____%t5,%t5,%fp 330f8f00
DEFINE sb_____%t0,0(%t0) 23805200
DEFINE lb_____%t0,0(%t0) 83820200
DEFINE sh_____%t0,0(%t0) 23905200
DEFINE lh_____%t0,0(%t0) 83920200
DEFINE sw_____%t0,0(%t0) 23a05200
DEFINE lw_____%t0,0(%t0) 83a20200
DEFINE sd_____%t0,0(%t0) 23b05200
DEFINE ld_____%t0,0(%t0) 83b20200
DEFINE sb_____%t1,0(%t1) 23006300
DEFINE lb_____%t1,0(%t1) 03030300
DEFINE sh_____%t1,0(%t1) 23106300
DEFINE lh_____%t1,0(%t1) 03130300
DEFINE sw_____%t1,0(%t1) 23206300
DEFINE lw_____%t1,0(%t1) 03230300
DEFINE sd_____%t1,0(%t1) 23306300
DEFINE ld_____%t1,0(%t1) 03330300
DEFINE sb_____%t0,0(%t1) 23005300
DEFINE lb_____%t0,0(%t1) 83020300
DEFINE sh_____%t0,0(%t1) 23105300
DEFINE lh_____%t0,0(%t1) 83120300
DEFINE sw_____%t0,0(%t1) 23205300
DEFINE lw_____%t0,0(%t1) 83220300
DEFINE sd_____%t0,0(%t1) 23305300
DEFINE ld_____%t0,0(%t1) 83320300
DEFINE sb_____%t1,0(%t0) 23806200
DEFINE lb_____%t1,0(%t0) 03830200
DEFINE sh_____%t1,0(%t0) 23906200
DEFINE lh_____%t1,0(%t0) 03930200
DEFINE sw_____%t1,0(%t0) 23a06200
DEFINE lw_____%t1,0(%t0) 03a30200
DEFINE sd_____%t1,0(%t0) 23b06200
DEFINE ld_____%t1,0(%t0) 03b30200
DEFINE sb_____%t0,0(%t5) 23005f00
DEFINE lb_____%t0,0(%t5) 83020f00
DEFINE sh_____%t0,0(%t5) 23105f00
DEFINE lh_____%t0,0(%t5) 83120f00
DEFINE sw_____%t0,0(%t5) 23205f00
DEFINE lw_____%t0,0(%t5) 83220f00
DEFINE sd_____%t0,0(%t5) 23305f00
DEFINE ld_____%t0,0(%t5) 83320f00
DEFINE sb_____%t1,0(%t5) 23006f00
DEFINE lb_____%t1,0(%t5) 03030f00
DEFINE sh_____%t1,0(%t5) 23106f00
DEFINE lh_____%t1,0(%t5) 03130f00
DEFINE sw_____%t1,0(%t5) 23206f00
DEFINE lw_____%t1,0(%t5) 03230f00
DEFINE sd_____%t1,0(%t5) 23306f00
DEFINE ld_____%t1,0(%t5) 03330f00
DEFINE sb_____%t5,0(%t0) 2380e201
DEFINE lb_____%t5,0(%t0) 038f0200
DEFINE sh_____%t5,0(%t0) 2390e201
DEFINE lh_____%t5,0(%t0) 039f0200
DEFINE sw_____%t5,0(%t0) 23a0e201
DEFINE lw_____%t5,0(%t0) 03af0200
DEFINE sd_____%t5,0(%t0) 23b0e201
DEFINE ld_____%t5,0(%t0) 03bf0200
DEFINE sb_____%t5,0(%t1) 2300e301
DEFINE lb_____%t5,0(%t1) 030f0300
DEFINE sh_____%t5,0(%t1) 2310e301
DEFINE lh_____%t5,0(%t1) 031f0300
DEFINE sw_____%t5,0(%t1) 2320e301
DEFINE lw_____%t5,0(%t1) 032f0300
DEFINE sd_____%t5,0(%t1) 2330e301
DEFINE ld_____%t5,0(%t1) 033f0300
DEFINE sb_____%t0,0(%sp) 23005100
DEFINE lb_____%t0,0(%sp) 83020100
DEFINE sh_____%t0,0(%sp) 23105100
DEFINE lh_____%t0,0(%sp) 83120100
DEFINE sw_____%t0,0(%sp) 23205100
DEFINE lw_____%t0,0(%sp) 83220100
DEFINE sd_____%t0,0(%sp) 23305100
DEFINE ld_____%t0,0(%sp) 83320100
DEFINE sb_____%t1,0(%sp) 23006100
DEFINE lb_____%t1,0(%sp) 03030100
DEFINE sh_____%t1,0(%sp) 23106100
DEFINE lh_____%t1,0(%sp) 03130100
DEFINE sw_____%t1,0(%sp) 23206100
DEFINE lw_____%t1,0(%sp) 03230100
DEFINE sd_____%t1,0(%sp) 23306100
DEFINE ld_____%t1,0(%sp) 03330100
DEFINE sb_____%t5,0(%sp) 2300e101
DEFINE lb_____%t5,0(%sp) 030f0100
DEFINE sh_____%t5,0(%sp) 2310e101
DEFINE lh_____%t5,0(%sp) 031f0100
DEFINE sw_____%t5,0(%sp) 2320e101
DEFINE lw_____%t5,0(%sp) 032f0100
DEFINE sd_____%t5,0(%sp) 2330e101
DEFINE ld_____%t5,0(%sp) 033f0100
DEFINE sb_____%t4,0(%t5) 2300df01
DEFINE lb_____%t4,0(%t5) 830e0f00
DEFINE sh_____%t4,0(%t5) 2310df01
DEFINE lh_____%t4,0(%t5) 831e0f00
DEFINE sw_____%t4,0(%t5) 2320df01
DEFINE lw_____%t4,0(%t5) 832e0f00
DEFINE sd_____%t4,0(%t5) 2330df01
DEFINE ld_____%t4,0(%t5) 833e0f00
DEFINE sb_____%t0,0(%t5) 23005f00
DEFINE lb_____%t0,0(%t5) 83020f00
DEFINE sh_____%t0,0(%t5) 23105f00
DEFINE lh_____%t0,0(%t5) 83120f00
DEFINE sw_____%t0,0(%t5) 23205f00
DEFINE lw_____%t0,0(%t5) 83220f00
DEFINE sd_____%t0,0(%t5) 23305f00
DEFINE ld_____%t0,0(%t5) 83320f00
DEFINE lbu____%t0,0(%t0) 83c20200
DEFINE lhu____%t0,0(%t0) 83d20200
DEFINE lwu____%t0,0(%t0) 83e20200
DEFINE lbu____%t1,0(%t1) 03430300
DEFINE lhu____%t1,0(%t1) 03530300
DEFINE lwu____%t1,0(%t1) 03630300
DEFINE mv_____%sp,%fp 13010400
DEFINE mv_____%fp,%sp 13040100
DEFINE mv_____%t0,%fp 93020400
DEFINE mv_____%t1,%fp 13030400
DEFINE mv_____%t5,%t0 138f0200
DEFINE mv_____%t5,%t1 130f0300
DEFINE mv_____%t5,%x0 130f0000
DEFINE mv_____%t0,%t5 93020f00
DEFINE mv_____%t1,%t5 13030f00
DEFINE mv_____%t0,%t1 93020300
DEFINE mv_____%t1,%t0 13830200
DEFINE mv_____%a0,%t0 13850200
DEFINE mv_____%a0,%t1 13050300
DEFINE mv_____%t0,%a0 93020500
DEFINE mv_____%t0,%x0 93020000
DEFINE mv_____%t1,%x0 13030000
DEFINE mv_____%s10,%t0 138d0200
DEFINE mv_____%s10,%t1 130d0300
DEFINE mv_____%s10,%x0 130d0000
DEFINE mv_____%s11,%t0 938d0200
DEFINE mv_____%s11,%t1 930d0300
DEFINE mv_____%s11,%x0 930d0000
DEFINE ld_____%a7,0x10(%fp) 83380401 ;; RV64I Base Instruction set
DEFINE ld_____%a0,0x18(%fp) 03358401 DEFINE lwu 03600000
DEFINE ld_____%a1,0x20(%fp) 83350402 DEFINE ld 03300000
DEFINE ld_____%a2,0x28(%fp) 03368402 DEFINE sd 23300000
DEFINE ld_____%a3,0x30(%fp) 83360403 DEFINE addiw 1B000000
DEFINE ld_____%a4,0x38(%fp) 03378403 DEFINE slliw 1B100000
DEFINE ld_____%a0,0x10(%fp) 03350401 DEFINE srliw 1B500000
DEFINE ld_____%a1,0x18(%fp) 83358401 DEFINE sraiw 1B500040
DEFINE ld_____%a2,0x20(%fp) 03360402 DEFINE addw 3B000000
DEFINE subw 3B000040
DEFINE sllw 3B100000
DEFINE srlw 3B500000
DEFINE sraw 3B500040
DEFINE ld_____%a0,-0x08(%fp) 033584ff ;; RV32M Standard Extensions
DEFINE ld_____%a1,-0x10(%fp) 833504ff DEFINE mul 33000002
DEFINE ld_____%a2,-0x18(%fp) 033684fe DEFINE mulh 33100002
DEFINE mulhsu 33200002
DEFINE mulhu 33300002
DEFINE div 33400002
DEFINE divu 33500002
DEFINE rem 33600002
DEFINE remu 33700002
DEFINE ld_____%a7,-0x08(%fp) 833884ff ;; RV64M Standard Extensions
DEFINE ld_____%a0,-0x10(%fp) 033504ff DEFINE mulw 3B000002
DEFINE ld_____%a1,-0x18(%fp) 833584fe DEFINE divw 3B400002
DEFINE ld_____%a2,-0x20(%fp) 033604fe DEFINE divuw 3B500002
DEFINE ld_____%a3,-0x28(%fp) 833684fd DEFINE remw 3B600002
DEFINE ld_____%a4,-0x30(%fp) 033704fd DEFINE remuw 3B700002
DEFINE ld_____%fp,0x10(%fp) 03340401 ;; Pseudoinstructions
DEFINE ld_____%t0,0x8(%fp) 83328400 DEFINE nop 13000000 # addi
DEFINE ld_____%sp,0x10(%fp) 03310401 DEFINE mv 13000000 # addi
DEFINE ld_____%fp,0x0(%fp) 03340400 DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE jr_____%t0 67800200 DEFINE beqz 63000000 # beq
DEFINE jalr___%t0 e7800200 DEFINE bnez 63100000 # bne
DEFINE jr_____%t1 67000300 DEFINE bltz 63400000 # blt
DEFINE jalr___%t1 e7000300 DEFINE ret 67800000 # rs1_ra jalr
## System call values (libc-mini, crt0) ;; Destination registers
DEFINE li_____%a7,SYS_write 93080004 ;; register_number << 7
DEFINE li_____%a7,SYS_exit 9308d005 DEFINE rd_ra .80000000
DEFINE rd_sp .00010000
DEFINE rd_gp .80010000
DEFINE rd_tp .00020000
DEFINE rd_t0 .80020000
DEFINE rd_t1 .00030000
DEFINE rd_t2 .80030000
DEFINE rd_s0 .00040000
DEFINE rd_fp .00040000
DEFINE rd_s1 .80040000
DEFINE rd_a0 .00050000
DEFINE rd_a1 .80050000
DEFINE rd_a2 .00060000
DEFINE rd_a3 .80060000
DEFINE rd_a4 .00070000
DEFINE rd_a5 .80070000
DEFINE rd_a6 .00080000
DEFINE rd_a7 .80080000
DEFINE rd_s2 .00090000
DEFINE rd_s3 .80090000
DEFINE rd_s4 .000A0000
DEFINE rd_s5 .800A0000
DEFINE rd_s6 .000B0000
DEFINE rd_s7 .800B0000
DEFINE rd_s8 .000C0000
DEFINE rd_s9 .800C0000
DEFINE rd_s10 .000D0000
DEFINE rd_s11 .800D0000
DEFINE rd_t3 .000E0000
DEFINE rd_t4 .800E0000
DEFINE rd_t5 .000F0000
DEFINE rd_t6 .800F0000
;; First source registers
;; register_number << 15
DEFINE rs1_ra .00800000
DEFINE rs1_sp .00000100
DEFINE rs1_gp .00800100
DEFINE rs1_tp .00000200
DEFINE rs1_t0 .00800200
DEFINE rs1_t1 .00000300
DEFINE rs1_t2 .00800300
DEFINE rs1_s0 .00000400
DEFINE rs1_fp .00000400
DEFINE rs1_s1 .00800400
DEFINE rs1_a0 .00000500
DEFINE rs1_a1 .00800500
DEFINE rs1_a2 .00000600
DEFINE rs1_a3 .00800600
DEFINE rs1_a4 .00000700
DEFINE rs1_a5 .00800700
DEFINE rs1_a6 .00000800
DEFINE rs1_a7 .00800800
DEFINE rs1_s2 .00000900
DEFINE rs1_s3 .00800900
DEFINE rs1_s4 .00000A00
DEFINE rs1_s5 .00800A00
DEFINE rs1_s6 .00000B00
DEFINE rs1_s7 .00800B00
DEFINE rs1_s8 .00000C00
DEFINE rs1_s9 .00800C00
DEFINE rs1_s10 .00000D00
DEFINE rs1_s11 .00800D00
DEFINE rs1_t3 .00000E00
DEFINE rs1_t4 .00800E00
DEFINE rs1_t5 .00000F00
DEFINE rs1_t6 .00800F00
;; Second source registers
;; register_number << 20
DEFINE rs2_ra .00001000
DEFINE rs2_sp .00002000
DEFINE rs2_gp .00003000
DEFINE rs2_tp .00004000
DEFINE rs2_t0 .00005000
DEFINE rs2_t1 .00006000
DEFINE rs2_t2 .00007000
DEFINE rs2_s0 .00008000
DEFINE rs2_fp .00008000
DEFINE rs2_s1 .00009000
DEFINE rs2_a0 .0000A000
DEFINE rs2_a1 .0000B000
DEFINE rs2_a2 .0000C000
DEFINE rs2_a3 .0000D000
DEFINE rs2_a4 .0000E000
DEFINE rs2_a5 .0000F000
DEFINE rs2_a6 .00000001
DEFINE rs2_a7 .00001001
DEFINE rs2_s2 .00002001
DEFINE rs2_s3 .00003001
DEFINE rs2_s4 .00004001
DEFINE rs2_s5 .00005001
DEFINE rs2_s6 .00006001
DEFINE rs2_s7 .00007001
DEFINE rs2_s8 .00008001
DEFINE rs2_s9 .00009001
DEFINE rs2_s10 .0000A001
DEFINE rs2_s11 .0000B001
DEFINE rs2_t3 .0000C001
DEFINE rs2_t4 .0000D001
DEFINE rs2_t5 .0000E001
DEFINE rs2_t6 .0000F001
DEFINE rs1_x0 .00000000
DEFINE rs2_x0 .00000000
DEFINE rs2_x1 .00001000
DEFINE rs2_x2 .00002000
DEFINE rs2_x3 .00003000
DEFINE rs2_x4 .00004000
DEFINE rs2_x5 .00005000
DEFINE rs2_x6 .00006000
DEFINE rs2_x7 .00007000
DEFINE rs2_x8 .00008000
DEFINE rs2_x9 .00009000
DEFINE rs2_x10 .0000A000
DEFINE rs2_x11 .0000B000
DEFINE rs2_x12 .0000C000
DEFINE rs2_x13 .0000D000
DEFINE rs2_x14 .0000E000
DEFINE rs2_x15 .0000F000
DEFINE rs2_x16 .00000001
DEFINE rs2_x17 .00001001
DEFINE rs2_x18 .00002001
DEFINE rs2_x19 .00003001
DEFINE rs2_x20 .00004001
DEFINE rs2_x21 .00005001
DEFINE rs2_x22 .00006001
DEFINE rs2_x23 .00007001
DEFINE rs2_x24 .00008001
DEFINE rs2_x25 .00009001
DEFINE rs2_x26 .0000A001
DEFINE rs2_x27 .0000B001
DEFINE rs2_x28 .0000C001
DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001

View file

@ -1,5 +1,6 @@
;;; GNU Mes --- Maxwell Equations of Software ;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © 2016,2017,2018,2020 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
;;; ;;;
;;; This file is part of GNU Mes. ;;; This file is part of GNU Mes.
;;; ;;;
@ -96,6 +97,16 @@
" %" (if (< o 0) "-1" " %" (if (< o 0) "-1"
(number->string (dec->hex (quotient o #x100000000))))))) (number->string (dec->hex (quotient o #x100000000)))))))
;; RISC-V instruction formats
(define (riscv:i-format o)
(string-append "!" o))
(define (riscv:j-format o)
(string-append "$" o))
(define (riscv:u-format o)
(string-append "~" o))
(define* (display-join o #:optional (sep "")) (define* (display-join o #:optional (sep ""))
(let loop ((o o)) (let loop ((o o))
(when (pair? o) (when (pair? o)
@ -132,11 +143,11 @@
((char? o) (text->M1 (char->integer o))) ((char? o) (text->M1 (char->integer o)))
((string? o) o) ((string? o) o)
((symbol? o) (symbol->string o)) ((symbol? o) (symbol->string o))
((number? o) (let ((o (if (< o #x80) o (- o #x100)))) ((number? o) (if hex? (string-append
(if hex? (string-append "!0x" "'" (if (and (>= o 0) (< o 16)) "0" "")
(if (and (>= o 0) (< o 16)) "0" "") (number->string o 16) "'")
(number->string o 16)) ;; non hex mode would be broken on RISC-V
(string-append "!" (number->string o))))) (string-append "!" (number->string o))))
((and (pair? o) (keyword? (car o))) ((and (pair? o) (keyword? (car o)))
(pmatch o (pmatch o
;; FIXME ;; FIXME
@ -184,6 +195,48 @@
((#:immediate2 ,immediate2) (hex2:immediate2 immediate2)) ((#:immediate2 ,immediate2) (hex2:immediate2 immediate2))
((#:immediate4 ,immediate4) (hex2:immediate4 immediate4)) ((#:immediate4 ,immediate4) (hex2:immediate4 immediate4))
((#:immediate8 ,immediate8) (hex2:immediate8 immediate8)) ((#:immediate8 ,immediate8) (hex2:immediate8 immediate8))
;; RISC-V instruction formats
((#:i-format (#:string ,string))
(riscv:i-format (string->label `(#:string ,string))))
((#:i-format (#:address ,address)) (guard (string? address))
(riscv:i-format address))
((#:i-format ,function) (guard (function? function))
(riscv:i-format (function->string function)))
((#:i-format (#:address ,global)) (guard (global? global))
(riscv:i-format (global->string global)))
((#:i-format ,number) (guard (number? number))
(riscv:i-format (number->string number)))
((#:j-format (#:string ,string))
(riscv:j-format (string->label `(#:string ,string))))
((#:j-format (#:address ,address)) (guard (string? address))
(riscv:j-format address))
((#:j-format ,function) (guard (function? function))
(riscv:j-format (function->string function)))
((#:j-format (#:address ,global)) (guard (global? global))
(riscv:j-format (global->string global)))
((#:u-format (#:string ,string))
(riscv:u-format (string->label `(#:string ,string))))
((#:u-format (#:address ,address)) (guard (string? address))
(riscv:u-format address))
((#:u-format ,function) (guard (function? function))
(riscv:u-format (function->string function)))
((#:u-format (#:address ,global)) (guard (global? global))
(riscv:u-format (global->string global)))
((#:i-format ,address) (guard (string? address))
(riscv:i-format address))
((#:i-format ,global) (guard (global? global))
(riscv:i-format (global->string global)))
((#:j-format ,address) (guard (string? address))
(riscv:j-format address))
((#:j-format ,global) (guard (global? global))
(riscv:j-format (global->string global)))
((#:u-format ,address) (guard (string? address))
(riscv:u-format address))
((#:u-format ,global) (guard (global? global))
(riscv:u-format (global->string global)))
(_ (error "text->M1 no match o" o)))) (_ (error "text->M1 no match o" o))))
((pair? o) (string-join (map text->M1 o))) ((pair? o) (string-join (map text->M1 o)))
(#t (error "no such text:" o)))) (#t (error "no such text:" o))))

View file

@ -1,6 +1,7 @@
;;; GNU Mes --- Maxwell Equations of Software ;;; GNU Mes --- Maxwell Equations of Software
;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org> ;;; Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com> ;;; Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
;;; Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
;;; ;;;
;;; This file is part of GNU Mes. ;;; This file is part of GNU Mes.
;;; ;;;
@ -33,59 +34,66 @@
)) ))
;;; reserved temporary intermediate registers ;;; reserved temporary intermediate registers
; t6 is used internally by M1 sequences ;;; t6 is used internally by M1 sequences
; t4 and t5 are scratch registers for code generation here ;;; t4 and t5 are scratch registers for code generation here
(define %tmpreg1 "t5") (define %tmpreg1 "t5")
(define %tmpreg2 "t4") (define %tmpreg2 "t4")
; registers for condition flags emulation ;;; registers for condition flags emulation
(define %condregx "s10") (define %condregx "s10")
(define %condregy "s11") (define %condregy "s11")
;;; register for return values ;;; register for return values
(define %retreg "t0") (define %retreg "t0")
(define %zero "x0")
;;; internal: return instruction to load an intermediate value into a register ;;; internal: return instruction to load an intermediate value into a register
(define (riscv64:li r v) (define (riscv64:li r v)
(cond (riscv64:addi r %zero v))
((= v 0)
`(,(string-append "mv_____%" r ",%x0")))
((and (>= v (- #x8000)) (<= v #x7fff))
`(,(string-append "li_____%" r ",$i16_0000") (#:immediate2 ,v)
,(string-append "srai___%" r ",16")))
((and (>= v (- #x80000000)) (<= v #x7fffffff))
`(,(string-append "li_____%" r ",$i32") (#:immediate ,v)))
(else
`(,(string-append "li_____%" r ",$i64") (#:immediate8 ,v)))))
;;; internal: return instruction to add an intermediate value into a register ;;; internal: return instruction to add an intermediate value into a register
(define (riscv64:addi r0 r1 v) (define (riscv64:addi r0 r1 v)
(cond (cond
((= v 0) ((= v 0)
`(,(string-append "; addi___%" r0 ",%" r1 ",0"))) ; nothing to do `(,(string-append "rd_" r0 " rs1_" r1 " addi"))) ; nothing to do
((= v 1) ((and (>= v (- #x800)) (<= v #x7ff))
`(,(string-append "addi___%" r0 ",%" r1 ",1"))) `(,(string-append "rd_" r0 " rs1_" r1 " !" (number->string v) " addi")))
((= v -1) ((and (>= v (- #x80000000)) (<= v #x7fffffff))
`(,(string-append "addi___%" r0 ",%" r1 ",-1"))) `(,(string-append "rd_t6 auipc\n\t"
((and (>= v (- #x800)) (<= v #x7ff) (= (logand v 15) 0)) "rd_t6 rs1_t6 !16 lw\n\t"
`(,(string-append "addi___%" r0 ",%" r1 ",$i8_0") (#:immediate1 ,(ash v -4)))) "rd_" r0 " rs1_" r1 " rs2_t6 add\n\t"
((and (>= v (- #x800)) (<= v #x7ff) (= (logand v 15) 8)) "!8 jal\n\t") (#:immediate ,v)))
`(,(string-append "addi___%" r0 ",%" r1 ",$i8_8") (#:immediate1 ,(ash v -4)))) (else
((and (>= v (- #x80000000)) (<= v #x7fffffff)) `(,(string-append "rd_" r0 " auipc\n\t"
`(,(string-append "addi___%" r0 ",%" r1 ",$i32") (#:immediate ,v))) "rd_" r0 " rs1_" r0 " !16 ld\n\t"
(else "rd_" r0 " rs1_" r0 " rs2_" r1 " add\n\t"
`(,(string-append "addi___%" r0 ",%" r1 ",$i64") (#:immediate8 ,v))))) "!12 jal\n\t") (#:immediate8 ,v)))))
;;; internal: return instruction to save address of the label into register
(define (riscv64:label_address r label)
`((,(string-append "rd_" r) (#:u-format ,label) "auipc\n\t")
,(string-append "rd_" r " rs1_" r) (#:i-format ,label) "addiw"))
(define (riscv64:push r)
(string-append "rd_sp rs1_sp !-8 addi
rs1_sp rs2_" r " sd"))
(define (riscv64:pop r)
(string-append "rd_" r " rs1_sp ld
rd_sp rs1_sp !8 addi"))
;;; the preamble of every function ;;; the preamble of every function
(define (riscv64:function-preamble info . rest) (define (riscv64:function-preamble info . rest)
`(("push___%ra") `(("rd_sp rs1_sp !-8 addi
("push___%fp") rs1_sp rs2_ra sd") ; push ra to stack
("mv_____%fp,%sp"))) ("rd_sp rs1_sp !-8 addi
rs1_sp rs2_fp sd") ; push fp to stack
("rd_fp rs1_sp mv")))
;;; allocate function locals ;;; allocate function locals
(define (riscv64:function-locals . rest) (define (riscv64:function-locals . rest)
`( `(
,(riscv64:addi "sp" "sp" (- (+ (* 4 1025) (* 20 8)))) ,(riscv64:addi "sp" "sp" (- (+ (* 8 1025) (* 20 8))))
)) ; 4*1024 buf, 20 local vars )) ; 8*1024 buf, 20 local vars
;;; immediate value to register ;;; immediate value to register
(define (riscv64:value->r info v) (define (riscv64:value->r info v)
@ -100,9 +108,9 @@
;;; function epilogue ;;; function epilogue
(define (riscv64:ret . rest) (define (riscv64:ret . rest)
'(("mv_____%sp,%fp") `(("rd_sp rs1_fp mv")
("pop____%fp") (,(riscv64:pop "fp"))
("pop____%ra") (,(riscv64:pop "ra"))
("ret"))) ("ret")))
;;; stack local to register ;;; stack local to register
@ -110,41 +118,40 @@
(let ((r (car (if (pair? (.allocated info)) (.allocated info) (.registers info)))) (let ((r (car (if (pair? (.allocated info)) (.allocated info) (.registers info))))
(n (- 0 (* 8 n)))) (n (- 0 (* 8 n))))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "ld_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rd_" r " rs1_" %tmpreg1 " ld")))))
;;; call a function through a label ;;; call a function through a label
(define (riscv64:call-label info label n) (define (riscv64:call-label info label n)
`(("jal.a__$i32" (#:address ,label)) `(("rd_ra" (#:j-format ,label) "jal")
,(riscv64:addi "sp" "sp" (* n 8)) ,(riscv64:addi "sp" "sp" (* n 8))))
))
;;; call function pointer in register ;;; call function pointer in register
(define (riscv64:call-r info n) (define (riscv64:call-r info n)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "jalr___%" r)) `((,(string-append "rd_ra rs1_" r " jalr"))
,(riscv64:addi "sp" "sp" (* n 8))))) ,(riscv64:addi "sp" "sp" (* n 8)))))
;;; register to function argument. ;;; register to function argument.
(define (riscv64:r->arg info i) (define (riscv64:r->arg info i)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "push___%" r))))) `((,(riscv64:push r)))))
;;; label to function argument ;;; label to function argument
(define (riscv64:label->arg info label i) (define (riscv64:label->arg info label i)
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "push___%" %tmpreg1)))) ; FIXME 64bit (,(riscv64:push %tmpreg1))))
;;; ALU: r0 := r0 + r1 ;;; ALU: r0 := r0 + r1
(define (riscv64:r0+r1 info) (define (riscv64:r0+r1 info)
(let ((r1 (get-r1 info)) (let ((r1 (get-r1 info))
(r0 (get-r0 info))) (r0 (get-r0 info)))
`((,(string-append "add____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " add")))))
;;; ALU: r0 := r0 - r1 ;;; ALU: r0 := r0 - r1
(define (riscv64:r0-r1 info) (define (riscv64:r0-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sub____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " sub")))))
;;; add immediate value to r0 ;;; add immediate value to r0
(define (riscv64:r0+value info v) (define (riscv64:r0+value info v)
@ -154,88 +161,94 @@
;;; add immediate to contents of 8-bit word addressed by register ;;; add immediate to contents of 8-bit word addressed by register
(define (riscv64:r-byte-mem-add info v) (define (riscv64:r-byte-mem-add info v)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lb_____%" %tmpreg1 ",0(%" r ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r " lb"))
,(riscv64:addi %tmpreg1 %tmpreg1 v) ,(riscv64:addi %tmpreg1 %tmpreg1 v)
(,(string-append "sb_____%" %tmpreg1 ",0(%" r ")"))))) (,(string-append "rs1_" r " rs2_" %tmpreg1 " sb")))))
;;; add immediate to contents of 16-bit word addressed by register ;;; add immediate to contents of 16-bit word addressed by register
(define (riscv64:r-word-mem-add info v) (define (riscv64:r-word-mem-add info v)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lh_____%" %tmpreg1 ",0(%" r ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r " lh"))
,(riscv64:addi %tmpreg1 %tmpreg1 v) ,(riscv64:addi %tmpreg1 %tmpreg1 v)
(,(string-append "sh_____%" %tmpreg1 ",0(%" r ")"))))) (,(string-append "rs1_" r " rs2_" %tmpreg1 " sh")))))
;;; add immediate to contents of 32-bit word addressed by register ;;; add immediate to contents of 32-bit word addressed by register
(define (riscv64:r-long-mem-add info v) (define (riscv64:r-long-mem-add info v)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lw_____%" %tmpreg1 ",0(%" r ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r " lw"))
,(riscv64:addi %tmpreg1 %tmpreg1 v) ,(riscv64:addi %tmpreg1 %tmpreg1 v)
(,(string-append "sw_____%" %tmpreg1 ",0(%" r ")"))))) (,(string-append "rs1_" r " rs2_" %tmpreg1 " sw")))))
;;; add immediate to contents of 64-bit word addressed by register ;;; add immediate to contents of 64-bit word addressed by register
(define (riscv64:r-mem-add info v) (define (riscv64:r-mem-add info v)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ld_____%" %tmpreg1 ",0(%" r ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r " ld"))
,(riscv64:addi %tmpreg1 %tmpreg1 v) ,(riscv64:addi %tmpreg1 %tmpreg1 v)
(,(string-append "sd_____%" %tmpreg1 ",0(%" r ")"))))) (,(string-append "rs1_" r " rs2_" %tmpreg1 " sd")))))
;;; compute address of local variable and write result into register ;;; compute address of local variable and write result into register
(define (riscv64:local-ptr->r info n) (define (riscv64:local-ptr->r info n)
(let ((r (get-r info)) (let ((r (get-r info))
(n (- 0 (* 8 n)))) (n (- 0 (* 8 n))))
`((,(string-append "mv_____%" r ",%fp")) `((,(string-append "rd_" r " rs1_fp mv"))
,(riscv64:addi r r n)))) ,(riscv64:addi r r n))))
;;; label address into register ;;; label address into register
(define (riscv64:label->r info label) (define (riscv64:label->r info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" r ",$i32") (#:address ,label))))) ;; FIXME 64bit `(,(riscv64:label_address r label))))
;;; copy register r0 to register r1 (see also r1->r0) ;;; copy register r0 to register r1 (see also r1->r0)
(define (riscv64:r0->r1 info) (define (riscv64:r0->r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "mv_____%" r1 ",%" r0))))) `((,(string-append "rd_" r1 " rs1_" r0 " mv")))))
;;; copy register r1 to register r0 (see also r0->r1) ;;; copy register r1 to register r0 (see also r0->r1)
(define (riscv64:r1->r0 info) (define (riscv64:r1->r0 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "mv_____%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r1 " mv")))))
;;; zero-extend 8-bit in register r ;;; zero-extend 8-bit in register r
(define (riscv64:byte-r info) (define (riscv64:byte-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ext.b__%" r))))) `((,(string-append "rd_" r " rs1_" r " !0xFF andi")))))
;;; sign-extend 8-bit in register r ;;; sign-extend 8-bit in register r
(define (riscv64:byte-signed-r info) (define (riscv64:byte-signed-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sext.b_%" r))))) `((,(riscv64:li %tmpreg1 56)
,(string-append "\n\trd_" r " rs1_" r " rs2_" %tmpreg1 " sll\n\t")
,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " sra")))))
;;; zero-extend 16-bit in register r ;;; zero-extend 16-bit in register r
(define (riscv64:word-r info) (define (riscv64:word-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ext.h__%" r))))) `((,(riscv64:li %tmpreg1 #xffff)
,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " and")))))
;;; sign-extend 16-bit in register r ;;; sign-extend 16-bit in register r
(define (riscv64:word-signed-r info) (define (riscv64:word-signed-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sext.h_%" r))))) `((,(riscv64:li %tmpreg1 48)
,(string-append "\n\trd_" r " rs1_" r " rs2_" %tmpreg1 " sll\n\t")
,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " sra")))))
;;; zero-extend 32-bit in register r ;;; zero-extend 32-bit in register r
(define (riscv64:long-r info) (define (riscv64:long-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ext.w__%" r))))) `((,(riscv64:li %tmpreg1 #xffffffff)
,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " and")))))
;;; sign-extend 32-bit in register r ;;; sign-extend 32-bit in register r
(define (riscv64:long-signed-r info) (define (riscv64:long-signed-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sext.w_%" r))))) `((,(string-append "rd_" r " rs1_" r " addiw")))))
;;; unconditional jump to label ;;; unconditional jump to label
(define (riscv64:jump info label) (define (riscv64:jump info label)
`(("j.a____$i32 " (#:address ,label)))) `(((#:j-format ,label) "jal")))
;;;; Flag setters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Flag setters ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -243,7 +256,7 @@
;;; see also test-r ;;; see also test-r
(define (riscv64:r-zero? info) (define (riscv64:r-zero? info)
(let ((r (car (if (pair? (.allocated info)) (.allocated info) (.registers info))))) (let ((r (car (if (pair? (.allocated info)) (.allocated info) (.registers info)))))
`((,(string-append "mv_____%" %condregx ",%" r)) `((,(string-append "rd_" %condregx " rs1_" r " mv"))
,(riscv64:li %condregy 0)))) ,(riscv64:li %condregy 0))))
;;; test register r against 0 and set flags ;;; test register r against 0 and set flags
@ -253,83 +266,94 @@
;;; a ae b be (unsigned) ;;; a ae b be (unsigned)
(define (riscv64:test-r info) (define (riscv64:test-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "mv_____%" %condregx ",%" r)) `((,(string-append "rd_" %condregx " rs1_" r " mv"))
,(riscv64:li %condregy 0)))) ,(riscv64:li %condregy 0))))
;;; negate zero flag ;;; negate zero flag
(define (riscv64:xor-zf info) (define (riscv64:xor-zf info)
'(("cond.nz"))) `((,(string-append "rd_" %condregx " rs1_" %condregx " rs2_" %condregy " sub\n\t"
"rd_" %condregx " rs1_" %condregx) (#:i-format 1) "sltiu\n\t"
,(string-append "rd_" %condregy " addi"))))
;;; compare register to immediate value and set flags (see test-r) ;;; compare register to immediate value and set flags (see test-r)
(define (riscv64:r-cmp-value info v) (define (riscv64:r-cmp-value info v)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "mv_____%" %condregx ",%" r)) `((,(string-append "rd_" %condregx " rs1_" r " mv"))
,(riscv64:li %condregy v)))) ,(riscv64:li %condregy v))))
;;; compare register to another register and set flags (see test-r) ;;; compare register to another register and set flags (see test-r)
(define (riscv64:r0-cmp-r1 info) (define (riscv64:r0-cmp-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "mv_____%" %condregx ",%" r0)) `((,(string-append "rd_" %condregx " rs1_" r0 " mv"))
(,(string-append "mv_____%" %condregy ",%" r1))))) (,(string-append "rd_" %condregy " rs1_" r1 " mv")))))
;;;; Flag users ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;; Flag users ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; flag-based conditional jumps (equality) ;;; flag-based conditional jumps (equality)
(define (riscv64:jump-nz info label) (define (riscv64:jump-nz info label)
`(("jne.a__$i32" (#:address ,label)))) `((,(string-append "rs1_" %condregx " rs2_" %condregy " @8 beq\n\t")
(#:j-format ,label) "jal")))
(define (riscv64:jump-z info label) (define (riscv64:jump-z info label)
`(("jeq.a__$i32" (#:address ,label)))) `((,(string-append "rs1_" %condregx " rs2_" %condregy " @8 bne\n\t")
(#:j-format ,label) "jal")))
; assuming the result was properly zero/sign-extended, this is the same as a ; assuming the result was properly zero/sign-extended, this is the same as a
; normal jump-z ; normal jump-z
(define (riscv64:jump-byte-z info label) (define (riscv64:jump-byte-z info label)
`(("jeq.a__$i32" (#:address ,label)))) `((,(string-append "rs1_" %condregx " rs2_" %condregy " @8 bne\n\t")
(#:j-format ,label) "jal")))
;;; zero flag to register ;;; zero flag to register
(define (riscv64:zf->r info) (define (riscv64:zf->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "seq____%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " sub\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
;;; boolean: r := !e ;;; boolean: r := !e
(define (riscv64:r-negate info) (define (riscv64:r-negate info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "seq____%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " sub\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
;; flag-based conditional setters (signed) ;; flag-based conditional setters (signed)
(define (riscv64:g?->r info) (define (riscv64:g?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sgt____%" r))))) `((,(string-append "rd_" r " rs1_" %condregy " rs2_" %condregx " slt")))))
(define (riscv64:ge?->r info) (define (riscv64:ge?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sge____%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " slt\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
(define (riscv64:l?->r info) (define (riscv64:l?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "slt____%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " slt")))))
(define (riscv64:le?->r info) (define (riscv64:le?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sle____%" r))))) `((,(string-append "rd_" r " rs1_" %condregy " rs2_" %condregx " slt\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
;; flag-based conditional setters (unsigned) ;; flag-based conditional setters (unsigned)
(define (riscv64:a?->r info) (define (riscv64:a?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sgtu___%" r))))) `((,(string-append "rd_" r " rs1_" %condregy " rs2_" %condregx " sltu")))))
(define (riscv64:ae?->r info) (define (riscv64:ae?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sgeu___%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " sltu\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
(define (riscv64:b?->r info) (define (riscv64:b?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sltu___%" r))))) `((,(string-append "rd_" r " rs1_" %condregx " rs2_" %condregy " sltu")))))
(define (riscv64:be?->r info) (define (riscv64:be?->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "sleu___%" r))))) `((,(string-append "rd_" r " rs1_" %condregy " rs2_" %condregx " sltu\n\t"
"rd_" r " rs1_" r) (#:i-format 1) "sltiu"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -337,47 +361,47 @@
(define (riscv64:byte-r0->r1-mem info) (define (riscv64:byte-r0->r1-mem info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sb_____%" r0 ",0(%" r1 ")"))))) `((,(string-append "rs1_" r1 " rs2_" r0 " sb")))))
;;; load word at label into register r ;;; load word at label into register r
(define (riscv64:label-mem->r info label) (define (riscv64:label-mem->r info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "ld_____%" r ",0(%" %tmpreg1 ")"))))) ;; FIXME 64bit (,(string-append "rd_" r " rs1_" %tmpreg1 " ld")))))
;;; read 8-bit (and zero-extend) from address in register r into register r ;;; read 8-bit (and zero-extend) from address in register r into register r
(define (riscv64:byte-mem->r info) (define (riscv64:byte-mem->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lbu____%" r ",0(%" r ")"))))) `((,(string-append "rd_" r " rs1_" r " lbu")))))
;;; read 16-bit (and zero-extend) from address in register r into register r ;;; read 16-bit (and zero-extend) from address in register r into register r
(define (riscv64:word-mem->r info) (define (riscv64:word-mem->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lhu____%" r ",0(%" r ")"))))) `((,(string-append "rd_" r " rs1_" r " lhu")))))
;;; read 32-bit (and zero-extend) from address in register r into register r ;;; read 32-bit (and zero-extend) from address in register r into register r
(define (riscv64:long-mem->r info) (define (riscv64:long-mem->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "lwu____%" r ",0(%" r ")"))))) `((,(string-append "rd_" r " rs1_" r " lwu")))))
;;; read 64-bit from address in register r into register r ;;; read 64-bit from address in register r into register r
(define (riscv64:mem->r info) (define (riscv64:mem->r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ld_____%" r ",0(%" r ")"))))) `((,(string-append "rd_" r " rs1_" r " ld")))))
(define (riscv64:local-add info n v) (define (riscv64:local-add info n v)
(let ((n (- 0 (* 8 n)))) (let ((n (- 0 (* 8 n))))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:immediate ,n)) `(,(riscv64:li %tmpreg1 n)
(,(string-append "add____%" %tmpreg1 ",%" %tmpreg1 ",%fp")) (,(string-append "rd_" %tmpreg1 " rs1_" %tmpreg1 " rs2_fp add"))
(,(string-append "ld_____%" %tmpreg2 ",0(%" %tmpreg1 ")")) (,(string-append "rd_" %tmpreg2 " rs1_" %tmpreg1 " ld"))
,(riscv64:addi %tmpreg2 %tmpreg2 v) ,(riscv64:addi %tmpreg2 %tmpreg2 v)
(,(string-append "sd_____%" %tmpreg2 ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" %tmpreg2 " sd")))))
(define (riscv64:label-mem-add info label v) (define (riscv64:label-mem-add info label v)
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "ld_____%" %tmpreg2 ",0(%" %tmpreg1 ")")) (,(string-append "rd_" %tmpreg2 " rs1_" %tmpreg1 " ld"))
,(riscv64:addi %tmpreg2 %tmpreg2 v) ,(riscv64:addi %tmpreg2 %tmpreg2 v)
(,(string-append "sd_____%" %tmpreg2 ",0(%" %tmpreg1 ")")))) (,(string-append "rs1_" %tmpreg1 " rs2_" %tmpreg2 " sd"))))
;; no-operation ;; no-operation
(define (riscv64:nop info) (define (riscv64:nop info)
@ -387,93 +411,93 @@
(define (riscv64:swap-r0-r1 info) (define (riscv64:swap-r0-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "mv_____%" %tmpreg1 ",%" r1)) `((,(string-append "rd_" %tmpreg1 " rs1_" r1 " mv"))
(,(string-append "mv_____%" r1 ",%" r0)) (,(string-append "rd_" r1 " rs1_" r0 " mv"))
(,(string-append "mv_____%" r0 ",%" %tmpreg1))))) (,(string-append "rd_" r0 " rs1_" %tmpreg1 " mv")))))
;;; write 8-bit from register r to memory at the label ;;; write 8-bit from register r to memory at the label
(define (riscv64:r->byte-label info label) (define (riscv64:r->byte-label info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "sb_____%" r ",0(%" %tmpreg1 ")"))))) ;; FIXME 64bit (,(string-append "rs1_" %tmpreg1 " rs2_" r " sb")))))
;;; write 16-bit from register r to memory at the label ;;; write 16-bit from register r to memory at the label
(define (riscv64:r->word-label info label) (define (riscv64:r->word-label info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "sh_____%" r ",0(%" %tmpreg1 ")"))))) ;; FIXME 64bit (,(string-append "rs1_" %tmpreg1 " rs2_" r " sh")))))
;;; write 32-bit from register r to memory at the label ;;; write 32-bit from register r to memory at the label
(define (riscv64:r->long-label info label) (define (riscv64:r->long-label info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "sw_____%" r ",0(%" %tmpreg1 ")"))))) ;; FIXME 64bit (,(string-append "rs1_" %tmpreg1 " rs2_" r " sw")))))
;;; write 64-bit from register r to memory at the label ;;; write 64-bit from register r to memory at the label
(define (riscv64:r->label info label) (define (riscv64:r->label info label)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "li_____%" %tmpreg1 ",$i32") (#:address ,label)) `(,(riscv64:label_address %tmpreg1 label)
(,(string-append "sd_____%" r ",0(%" %tmpreg1 ")"))))) ;; FIXME 64bit (,(string-append "rs1_" %tmpreg1 " rs2_" r " sd")))))
;;; ALU r0 := r0 * r1 ;;; ALU r0 := r0 * r1
(define (riscv64:r0*r1 info) (define (riscv64:r0*r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "mul____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " mul")))))
;;; bitwise r0 := r0 << r1 ;;; bitwise r0 := r0 << r1
(define (riscv64:r0<<r1 info) (define (riscv64:r0<<r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sll____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " sll")))))
;;; bitwise r0 := r0 << imm ;;; bitwise r0 := r0 << imm
(define (riscv64:shl-r info n) (define (riscv64:shl-r info n)
(let ((r (get-r info))) (let ((r (get-r info)))
`(,(riscv64:li %tmpreg1 n) `(,(riscv64:li %tmpreg1 n)
(,(string-append "sll____%" r ",%" r ",%" %tmpreg1))))) (,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " sll")))))
;;; bitwise r0 := r0 >> r1 (logical, so shift in zero bits) ;;; bitwise r0 := r0 >> r1 (logical, so shift in zero bits)
(define (riscv64:r0>>r1 info) (define (riscv64:r0>>r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "srl____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " srl")))))
;;; bitwise r0 := r0 & r1 ;;; bitwise r0 := r0 & r1
(define (riscv64:r0-and-r1 info) (define (riscv64:r0-and-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "and____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " and")))))
;;; bitwise r0 := r0 | r1 ;;; bitwise r0 := r0 | r1
(define (riscv64:r0-or-r1 info) (define (riscv64:r0-or-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "or_____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " or")))))
;;; bitwise r := r & imm ;;; bitwise r := r & imm
(define (riscv64:r-and info n) (define (riscv64:r-and info n)
(let ((r (get-r info))) (let ((r (get-r info)))
`(,(riscv64:li %tmpreg1 n) `(,(riscv64:li %tmpreg1 n)
(,(string-append "and____%" r ",%" r ",%" %tmpreg1))))) (,(string-append "rd_" r " rs1_" r " rs2_" %tmpreg1 " and")))))
;;; bitwise r0 := r0 ^ r1 ;;; bitwise r0 := r0 ^ r1
(define (riscv64:r0-xor-r1 info) (define (riscv64:r0-xor-r1 info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "xor____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " xor")))))
;;; ALU r0 := r0 / r1 ;;; ALU r0 := r0 / r1
(define (riscv64:r0/r1 info signed?) (define (riscv64:r0/r1 info signed?)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "div____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " div")))))
;;; ALU r0 := r0 % r1 ;;; ALU r0 := r0 % r1
(define (riscv64:r0%r1 info signed?) (define (riscv64:r0%r1 info signed?)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "rem____%" r0 ",%" r0 ",%" r1))))) `((,(string-append "rd_" r0 " rs1_" r0 " rs2_" r1 " rem")))))
;;; ALU r0 := r0 + imm ;;; ALU r0 := r0 + imm
(define (riscv64:r+value info v) (define (riscv64:r+value info v)
@ -484,139 +508,139 @@
(define (riscv64:byte-r0->r1-mem info) (define (riscv64:byte-r0->r1-mem info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sb_____%" r0 ",0(%" r1 ")"))))) `((,(string-append "rs1_" r1 " rs2_" r0 " sb")))))
;;; store 16-bit r0 into address ported by r1 ;;; store 16-bit r0 into address ported by r1
(define (riscv64:word-r0->r1-mem info) (define (riscv64:word-r0->r1-mem info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sh_____%" r0 ",0(%" r1 ")"))))) `((,(string-append "rs1_" r1 " rs2_" r0 " sh")))))
;;; store 32-bit r0 into address ported by r1 ;;; store 32-bit r0 into address ported by r1
(define (riscv64:long-r0->r1-mem info) (define (riscv64:long-r0->r1-mem info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sw_____%" r0 ",0(%" r1 ")"))))) `((,(string-append "rs1_" r1 " rs2_" r0 " sw")))))
;;; store 64-bit r0 into address ported by r1 ;;; store 64-bit r0 into address ported by r1
(define (riscv64:r0->r1-mem info) (define (riscv64:r0->r1-mem info)
(let ((r0 (get-r0 info)) (let ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "sd_____%" r0 ",0(%" r1 ")"))))) `((,(string-append "rs1_" r1 " rs2_" r0 " sd")))))
;;; push register to stack ;;; push register to stack
(define (riscv64:push-register info r) (define (riscv64:push-register info r)
`((,(string-append "push___%" r)))) `((,(riscv64:push r))))
;;; push register r0 to stack (see also push-register) ;;; push register r0 to stack (see also push-register)
(define (riscv64:push-r0 info) (define (riscv64:push-r0 info)
(let ((r0 (get-r0 info))) (let ((r0 (get-r0 info)))
`((,(string-append "push___%" r0))))) `((,(riscv64:push r0)))))
;;; pop register from stack ;;; pop register from stack
(define (riscv64:pop-register info r) (define (riscv64:pop-register info r)
`((,(string-append "pop____%" r)))) `((,(riscv64:pop r))))
;;; pop register r0 from stack (see also pop-register) ;;; pop register r0 from stack (see also pop-register)
(define (riscv64:pop-r0 info) (define (riscv64:pop-r0 info)
(let ((r0 (get-r0 info))) (let ((r0 (get-r0 info)))
`((,(string-append "pop____%" r0))))) `((,(riscv64:pop r0)))))
;;; get function return value ;;; get function return value
(define (riscv64:return->r info) (define (riscv64:return->r info)
(let ((r (car (.allocated info)))) (let ((r (car (.allocated info))))
(if (equal? r %retreg) '() (if (equal? r %retreg) '()
`((,(string-append "mv_____%" r ",%" %retreg)))))) `((,(string-append "rd_" r " rs1_" %retreg " mv"))))))
;;; bitwise r := r + r (doubling) ;;; bitwise r := r + r (doubling)
(define (riscv64:r+r info) (define (riscv64:r+r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "add____%" r ",%" r ",%" r))))) `((,(string-append "rd_" r " rs1_" r " rs2_" r " add")))))
;;; bitwise r := ~r ;;; bitwise r := ~r
(define (riscv64:not-r info) (define (riscv64:not-r info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "not____%" r ",%" r))))) `((,(string-append "rd_" r " rs1_" r " not")))))
;;; load 8-bit at address r0, store to address r1 ;;; load 8-bit at address r0, store to address r1
(define (riscv64:byte-r0-mem->r1-mem info) (define (riscv64:byte-r0-mem->r1-mem info)
(let* ((r0 (get-r0 info)) (let* ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "lb_____%" %tmpreg1 ",0(%" r0 ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r0 " lb"))
(,(string-append "sb_____%" %tmpreg1 ",0(%" r1 ")"))))) (,(string-append "rs1_" r1 " rs2_" %tmpreg1 " sb")))))
;;; load 16-bit at address r0, store to address r1 ;;; load 16-bit at address r0, store to address r1
(define (riscv64:word-r0-mem->r1-mem info) (define (riscv64:word-r0-mem->r1-mem info)
(let* ((r0 (get-r0 info)) (let* ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "lh_____%" %tmpreg1 ",0(%" r0 ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r0 " lh"))
(,(string-append "sh_____%" %tmpreg1 ",0(%" r1 ")"))))) (,(string-append "rs1_" r1 " rs2_" %tmpreg1 " sh")))))
;;; load 32-bit at address r0, store to address r1 ;;; load 32-bit at address r0, store to address r1
(define (riscv64:long-r0-mem->r1-mem info) (define (riscv64:long-r0-mem->r1-mem info)
(let* ((r0 (get-r0 info)) (let* ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "lw_____%" %tmpreg1 ",0(%" r0 ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r0 " lw"))
(,(string-append "sw_____%" %tmpreg1 ",0(%" r1 ")"))))) (,(string-append "rs1_" r1 " rs2_" %tmpreg1 " sw")))))
;;; load 64-bit at address r0, store to address r1 ;;; load 64-bit at address r0, store to address r1
(define (riscv64:r0-mem->r1-mem info) (define (riscv64:r0-mem->r1-mem info)
(let* ((r0 (get-r0 info)) (let* ((r0 (get-r0 info))
(r1 (get-r1 info))) (r1 (get-r1 info)))
`((,(string-append "ld_____%" %tmpreg1 ",0(%" r0 ")")) `((,(string-append "rd_" %tmpreg1 " rs1_" r0 " ld"))
(,(string-append "sd_____%" %tmpreg1 ",0(%" r1 ")"))))) (,(string-append "rs1_" r1 " rs2_" %tmpreg1 " sd")))))
;;; register (8-bit) to stack local ;;; register (8-bit) to stack local
(define (riscv64:byte-r->local+n info id n) (define (riscv64:byte-r->local+n info id n)
(let ((n (+ (- 0 (* 8 id)) n)) (let ((n (+ (- 0 (* 8 id)) n))
(r (get-r info))) (r (get-r info)))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "sb_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" r " sb")))))
;;; register (16-bit) to stack local ;;; register (16-bit) to stack local
(define (riscv64:word-r->local+n info id n) (define (riscv64:word-r->local+n info id n)
(let ((n (+ (- 0 (* 8 id)) n)) (let ((n (+ (- 0 (* 8 id)) n))
(r (get-r info))) (r (get-r info)))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "sh_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" r " sh")))))
;;; register (32-bit) to stack local ;;; register (32-bit) to stack local
(define (riscv64:long-r->local+n info id n) (define (riscv64:long-r->local+n info id n)
(let ((n (+ (- 0 (* 8 id)) n)) (let ((n (+ (- 0 (* 8 id)) n))
(r (get-r info))) (r (get-r info)))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "sw_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" r " sw")))))
;;; register (64-bit) to stack local ;;; register (64-bit) to stack local
(define (riscv64:r->local info n) (define (riscv64:r->local info n)
(let ((r (get-r info)) (let ((r (get-r info))
(n (- 0 (* 8 n)))) (n (- 0 (* 8 n))))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "sd_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" r " sd")))))
;;; register (64-bit) to stack local (how does this differ from r->local ?) ;;; register (64-bit) to stack local (how does this differ from r->local ?)
;;; n is computed differently ;;; n is computed differently
(define (riscv64:r->local+n info id n) (define (riscv64:r->local+n info id n)
(let ((n (+ (- 0 (* 8 id)) n)) (let ((n (+ (- 0 (* 8 id)) n))
(r (get-r info))) (r (get-r info)))
`(,(riscv64:addi %tmpreg1 "fp" n) `(,(riscv64:addi %tmpreg1 "fp" n)
(,(string-append "sd_____%" r ",0(%" %tmpreg1 ")"))))) (,(string-append "rs1_" %tmpreg1 " rs2_" r " sd")))))
;;; swap value of register r with the top word of the stack ;;; swap value of register r with the top word of the stack
;; seems unused ;; seems unused
(define (riscv64:swap-r-stack info) (define (riscv64:swap-r-stack info)
(let ((r (get-r info))) (let ((r (get-r info)))
`((,(string-append "ld_____%" %tmpreg1 ",0(%sp)")) `((,(string-append "rd_" %tmpreg1 " rs1_sp ld"))
(,(string-append "sd_____%" r ",0(%sp)")) (,(string-append "rs1_sp rs2_" r " sd"))
(,(string-append "mv_____%" r ",%" %tmpreg1))))) (,(string-append "rd_" r " rs1_" %tmpreg1 " mv")))))
;;; swap value of register r0 (not r1) with the top word of the stack ;;; swap value of register r0 (not r1) with the top word of the stack
;; used in expr->arg ;; used in expr->arg
(define (riscv64:swap-r1-stack info) (define (riscv64:swap-r1-stack info)
(let ((r0 (get-r0 info))) (let ((r0 (get-r0 info)))
`((,(string-append "ld_____%" %tmpreg1 ",0(%sp)")) `((,(string-append "rd_" %tmpreg1 " rs1_sp ld"))
(,(string-append "sd_____%" r0 ",0(%sp)")) (,(string-append "rs1_sp rs2_" r0 " sd"))
(,(string-append "mv_____%" r0 ",%" %tmpreg1))))) (,(string-append "rd_" r0 " rs1_" %tmpreg1 " mv")))))
;;; not entirely sure what this is supposed to do ;;; not entirely sure what this is supposed to do
;;; i guess the idea would be to copy register r2 to r1, but what is the pop/push about? ;;; i guess the idea would be to copy register r2 to r1, but what is the pop/push about?
@ -626,9 +650,9 @@
(allocated (.allocated info))) (allocated (.allocated info)))
(if (> (length allocated) 2) (if (> (length allocated) 2)
(let ((r2 (cadddr allocated))) (let ((r2 (cadddr allocated)))
`((,(string-append "mv_____%" r1 ",%" r2)))) `((,(string-append "rd_" r1 " rs1_" r2 " mv"))))
`((,(string-append "pop____%" r0)) `((,(riscv64:pop r0))
(,(string-append "push___%" r0)))))) (,(riscv64:push r0))))))
(define riscv64:instructions (define riscv64:instructions
`( `(
@ -649,15 +673,15 @@
(g?->r . ,riscv64:g?->r) (g?->r . ,riscv64:g?->r)
(ge?->r . ,riscv64:ge?->r) (ge?->r . ,riscv64:ge?->r)
(jump . ,riscv64:jump) (jump . ,riscv64:jump)
; (jump-a . ,riscv64:jump-a) ;; (jump-a . ,riscv64:jump-a)
; (jump-ae . ,riscv64:jump-ae) ;; (jump-ae . ,riscv64:jump-ae)
; (jump-b . ,riscv64:jump-b) ;; (jump-b . ,riscv64:jump-b)
; (jump-be . ,riscv64:jump-be) ;; (jump-be . ,riscv64:jump-be)
(jump-byte-z . ,riscv64:jump-byte-z) (jump-byte-z . ,riscv64:jump-byte-z)
; (jump-g . , riscv64:jump-g) ;; (jump-g . , riscv64:jump-g)
; (jump-ge . , riscv64:jump-ge) ;; (jump-ge . , riscv64:jump-ge)
; (jump-l . ,riscv64:jump-l) ;; (jump-l . ,riscv64:jump-l)
; (jump-le . ,riscv64:jump-le) ;; (jump-le . ,riscv64:jump-le)
(jump-nz . ,riscv64:jump-nz) (jump-nz . ,riscv64:jump-nz)
(jump-z . ,riscv64:jump-z) (jump-z . ,riscv64:jump-z)
(l?->r . ,riscv64:l?->r) (l?->r . ,riscv64:l?->r)