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 c009e6a191
commit e42cf58d14
16 changed files with 824 additions and 861 deletions

View File

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
*
* This file is part of GNU Mes.
*
@ -28,6 +29,10 @@
* #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
#ifndef SYS_exit
#define SYS_exit 93

View File

@ -1,6 +1,7 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* 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.
*
@ -46,7 +47,13 @@ open (char const *file_name, int flags, ...)
va_list ap;
va_start (ap, flags);
int mask = va_arg (ap, int);
#if defined (SYS_open)
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);
if (r > 2)
__ungetc_clear (r);

View File

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

View File

@ -2,6 +2,7 @@
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
* Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
*
* This file is part of GNU Mes.
*
@ -24,10 +25,10 @@
void
_write (int filedes, void const *buffer, size_t size)
{
asm ("ld_____%a0,-0x08(%fp)");
asm ("ld_____%a1,-0x10(%fp)");
asm ("ld_____%a2,-0x18(%fp)");
asm ("li_____%a7,SYS_write");
asm ("rd_a0 rs1_fp !-8 ld");
asm ("rd_a1 rs1_fp !-16 ld");
asm ("rd_a2 rs1_fp !-24 ld");
asm ("rd_a7 !64 addi # SYS_write");
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) 2023 Janneke Nieuwenhuizen <janneke@gnu.org>
## Copyright © 2023 Andrius Štikonas <andrius@stikonas.eu>
##
## This file is part of stage0.
##
@ -17,58 +18,36 @@
## along with stage0. If not, see <http://www.gnu.org/licenses/>.
:_start
RD_FP RS1_SP MV ; Protect stack pointer
rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv
RD_A0 RS1_FP !8 ADDI ; ARGV_address = FP + 8
RD_SP RS1_SP !-8 ADDI
RS1_SP RS2_A0 SD ; Put argv on the stack
rd_a0 rs1_fp !8 addi ; ARGV_address = FP + 8
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put argv on the stack
; Prepare envp
RD_A0 RS1_FP MV ; Address we need to load from
RD_A0 RS1_A0 LD ; Get ARGC
RD_A0 RS1_A0 !2 ADDI ; OFFSET = ARGC + 2
RD_A0 RS1_A0 RS2_X3 SLLI ; OFFSET = OFFSET * WORDSIZE
RD_A0 RS1_FP RS2_A0 ADD ; ENVP_address = RSP + OFFSET
RD_SP RS1_SP !-8 ADDI
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)
rd_a0 rs1_fp mv ; Address we need to load from
rd_a0 rs1_a0 ld ; Get ARGC
rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put envp on the stack
; Stack offset
RD_FP RS1_FP !8 ADDI
rd_fp rs1_fp !8 addi
; Init libc
RD_RA $FUNCTION___init_io JAL
; Init libc
rd_ra $FUNCTION___init_io jal
; Call main function
RD_RA $FUNCTION_main JAL
rd_ra $FUNCTION_main jal
; Put return value on the stack so that _exit gets it
RD_SP RS1_SP !-16 ADDI
RS1_SP RS2_A0 SD
rd_sp rs1_sp !-16 addi
rs1_sp rs2_a0 sd
; Exit to kernel
RD_A0 RS1_SP LD
RD_A7 !93 ADDI ; Syscall for exit
ECALL ; Exit with code in a0
rd_a0 rs1_sp ld
rd_a7 !93 addi ; Syscall for exit
ecall ; Exit with code in a0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -19,219 +19,222 @@ DEFINE NULL 0000000000000000
;; Opcodes
;; RV32I Base Instruction Set
DEFINE LUI 37000000
DEFINE AUIPC 17000000
DEFINE JAL 6F000000
DEFINE JALR 67000000
DEFINE BEQ 63000000
DEFINE BNE 63100000
DEFINE BLT 63400000
DEFINE BGE 63500000
DEFINE BLTU 63600000
DEFINE BGEU 63700000
DEFINE LB 03000000
DEFINE LH 03100000
DEFINE LW 03200000
DEFINE LBU 03400000
DEFINE LHU 03500000
DEFINE SB 23000000
DEFINE SH 23100000
DEFINE SW 23200000
DEFINE ADDI 13000000
DEFINE SLTI 13200000
DEFINE SLTIU 13300000
DEFINE XORI 13400000
DEFINE ORI 13600000
DEFINE ANDI 13700000
DEFINE SLLI 13100000
DEFINE SRLI 13500000
DEFINE SRAI 13500040
DEFINE ADD 33000000
DEFINE SUB 33000040
DEFINE SLL 33100000
DEFINE SLT 33200000
DEFINE SLTU 33300000
DEFINE XOR 33400000
DEFINE SRL 33500000
DEFINE SRA 33500040
DEFINE OR 33600000
DEFINE AND 33700000
DEFINE ECALL 73000000
DEFINE lui 37000000
DEFINE auipc 17000000
DEFINE jal 6F000000
DEFINE jalr 67000000
DEFINE beq 63000000
DEFINE bne 63100000
DEFINE blt 63400000
DEFINE bge 63500000
DEFINE bltu 63600000
DEFINE bgeu 63700000
DEFINE lb 03000000
DEFINE lh 03100000
DEFINE lw 03200000
DEFINE lbu 03400000
DEFINE lhu 03500000
DEFINE sb 23000000
DEFINE sh 23100000
DEFINE sw 23200000
DEFINE addi 13000000
DEFINE slti 13200000
DEFINE sltiu 13300000
DEFINE xori 13400000
DEFINE ori 13600000
DEFINE andi 13700000
DEFINE slli 13100000
DEFINE srli 13500000
DEFINE srai 13500040
DEFINE add 33000000
DEFINE sub 33000040
DEFINE sll 33100000
DEFINE slt 33200000
DEFINE sltu 33300000
DEFINE xor 33400000
DEFINE srl 33500000
DEFINE sra 33500040
DEFINE or 33600000
DEFINE and 33700000
DEFINE ecall 73000000
DEFINE ebreak 73001000
;; RV64I Base Instruction set
DEFINE LWU 03600000
DEFINE LD 03300000
DEFINE SD 23300000
DEFINE ADDIW 1B000000
DEFINE SLLIW 1B100000
DEFINE SRLIW 1B500000
DEFINE SRAIW 1B500040
DEFINE ADDW 3B000000
DEFINE SUBW 3B000040
DEFINE SLLW 3B100000
DEFINE SRLW 3B500000
DEFINE SRAW 3B500040
DEFINE lwu 03600000
DEFINE ld 03300000
DEFINE sd 23300000
DEFINE addiw 1B000000
DEFINE slliw 1B100000
DEFINE srliw 1B500000
DEFINE sraiw 1B500040
DEFINE addw 3B000000
DEFINE subw 3B000040
DEFINE sllw 3B100000
DEFINE srlw 3B500000
DEFINE sraw 3B500040
;; RV32M Standard Extensions
DEFINE MUL 33000002
DEFINE MULH 33100002
DEFINE MULHSU 33200002
DEFINE MULHU 33300002
DEFINE DIV 33400002
DEFINE DIVU 33500002
DEFINE REM 33600002
DEFINE REMU 33700002
DEFINE mul 33000002
DEFINE mulh 33100002
DEFINE mulhsu 33200002
DEFINE mulhu 33300002
DEFINE div 33400002
DEFINE divu 33500002
DEFINE rem 33600002
DEFINE remu 33700002
;; RV64M Standard Extensions
DEFINE MULW 3B000002
DEFINE DIVW 3B400002
DEFINE DIVUW 3B500002
DEFINE REMW 3B600002
DEFINE REMUW 3B700002
DEFINE mulw 3B000002
DEFINE divw 3B400002
DEFINE divuw 3B500002
DEFINE remw 3B600002
DEFINE remuw 3B700002
;; Pseudoinstructions
DEFINE NOP 13000000 # ADDI
DEFINE MV 13000000 # ADDI
DEFINE NOT 1340F0FF # XORI, RD, RS, -1
DEFINE BEQZ 63000000 # BEQ
DEFINE BNEZ 63100000 # BNE
DEFINE BLTZ 63400000 # BLT
DEFINE RETURN 67800000 # RS1_RA JALR
DEFINE nop 13000000 # addi
DEFINE mv 13000000 # addi
DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE beqz 63000000 # beq
DEFINE bnez 63100000 # bne
DEFINE bltz 63400000 # blt
DEFINE ret 67800000 # rs1_ra jalr
;; Destination registers
;; register_number << 7
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
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
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 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 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
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

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

View File

@ -1,362 +1,240 @@
### GNU Mes --- Maxwell Equations of Software
### Copyright © 2017,2018,2020,2023 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
### Copyright © 2019,2020 Danny Milosavljevic <dannym@scratchpost.org>
### Copyright © 2021 W. J. van der Laan <laanwj@protonmail.com>
###
### This file is part of GNU Mes.
###
### Mes is free software; you can redistribute it and/or modify it
### under the terms of the GNU General Public License as published by
### the Free Software Foundation; either version 3 of the License, or (at
### your option) any later version.
###
### GNU Mes is distributed in the hope that it will be useful, but
### WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### 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/>.
## Copyright (C) 2021 Andrius Štikonas
## This file is part of M2-Planet.
##
## 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
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## M2-Planet is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
## Multi-instruction macros
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
DEFINE NULL 0000000000000000
## Immediate values
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
;; Opcodes
## Immediate adds
DEFINE addi___%sp,%sp,$i32 970f000083af0f013301f1016f008000 # auipc t6,0x0; lw t6,16(t6); add sp,sp,t6; j 8
DEFINE addi___%sp,%sp,$i64 1701000003310101330121006f00c000 # auipc sp,0x0; ld sp,16(sp); add sp,sp,sp; j 12
DEFINE addi___%t0,%t0,$i32 970f000083af0f01b382f2016f008000 # auipc t6,0x0; lw t6,16(t6); add t0,t0,t6; j 8
DEFINE addi___%t0,%t0,$i64 9702000083b20201b38252006f00c000 # auipc t0,0x0; ld t0,16(t0); add t0,t0,t0; j 12
DEFINE addi___%t1,%t1,$i32 970f000083af0f013303f3016f008000 # auipc t6,0x0; lw t6,16(t6); add t1,t1,t6; j 8
DEFINE addi___%t1,%t1,$i64 1703000003330301330363006f00c000 # auipc t1,0x0; ld t1,16(t1); add t1,t1,t1; j 12
DEFINE addi___%t5,%t5,$i32 970f000083af0f01330fff016f008000 # auipc t6,0x0; lw t6,16(t6); add t5,t5,t6; j 8
DEFINE addi___%t5,%t5,$i64 170f0000033f0f01330fef016f00c000 # auipc t5,0x0; ld t5,16(t5); add t5,t5,t5; j 12
DEFINE addi___%t4,%t4,$i32 970f000083af0f01b38efe016f008000 # auipc t6,0x0; lw t6,16(t6); add t4,t4,t6; j 8
DEFINE addi___%t4,%t4,$i64 970e000083be0e01b38ede016f00c000 # auipc t4,0x0; ld t4,16(t4); add t4,t4,t4; j 12
DEFINE addi___%t0,%t0,-1 9382f2ff
DEFINE addi___%t0,%t0,1 93821200
DEFINE addi___%t0,%t0,$i8_0 938202
DEFINE addi___%t0,%t0,$i8_8 938282
DEFINE addi___%t1,%t1,-1 1303f3ff
DEFINE addi___%t1,%t1,1 13031300
DEFINE addi___%t1,%t1,$i8_0 130303
DEFINE addi___%t1,%t1,$i8_8 130383
DEFINE addi___%sp,%sp,-1 1301f1ff
DEFINE addi___%sp,%sp,1 13011100
DEFINE addi___%sp,%sp,$i8_0 130101
DEFINE addi___%sp,%sp,$i8_8 130181
DEFINE addi___%t5,%t5,-1 130fffff
DEFINE addi___%t5,%t5,1 130f1f00
DEFINE addi___%t5,%t5,$i8_0 130f0f
DEFINE addi___%t5,%t5,$i8_8 130f8f
DEFINE addi___%t4,%t4,-1 938efeff
DEFINE addi___%t4,%t4,1 938e1e00
DEFINE addi___%t4,%t4,$i8_0 938e0e
DEFINE addi___%t4,%t4,$i8_8 938e8e
DEFINE addi___%t5,%fp,$i32 970f000083af0f01330ff4016f008000 # auipc t6,0x0; lw t6,16(t6); add t5,fp,t6; j 8
DEFINE addi___%t5,%fp,$i8_0 130f04
DEFINE addi___%t5,%fp,$i8_8 130f84
## Condition flags and jumps emulation
DEFINE cond.nz 330dbd41133d1d00930d0000 # sub s10,s10,s11; seqz s10,s10; mv s11,x0
DEFINE jeq.a__$i32 631abd01970f000083efcf0067800f00 # bne s10,s11,20; auipc t6,0x0; lwu t6,12(t6); jr t6
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
;; RV32I Base Instruction Set
DEFINE lui 37000000
DEFINE auipc 17000000
DEFINE jal 6F000000
DEFINE jalr 67000000
DEFINE beq 63000000
DEFINE bne 63100000
DEFINE blt 63400000
DEFINE bge 63500000
DEFINE bltu 63600000
DEFINE bgeu 63700000
DEFINE lb 03000000
DEFINE lh 03100000
DEFINE lw 03200000
DEFINE lbu 03400000
DEFINE lhu 03500000
DEFINE sb 23000000
DEFINE sh 23100000
DEFINE sw 23200000
DEFINE addi 13000000
DEFINE slti 13200000
DEFINE sltiu 13300000
DEFINE xori 13400000
DEFINE ori 13600000
DEFINE andi 13700000
DEFINE slli 13100000
DEFINE srli 13500000
DEFINE srai 13500040
DEFINE add 33000000
DEFINE sub 33000040
DEFINE sll 33100000
DEFINE slt 33200000
DEFINE sltu 33300000
DEFINE xor 33400000
DEFINE srl 33500000
DEFINE sra 33500040
DEFINE or 33600000
DEFINE and 33700000
DEFINE ecall 73000000
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
DEFINE ld_____%a0,0x18(%fp) 03358401
DEFINE ld_____%a1,0x20(%fp) 83350402
DEFINE ld_____%a2,0x28(%fp) 03368402
DEFINE ld_____%a3,0x30(%fp) 83360403
DEFINE ld_____%a4,0x38(%fp) 03378403
DEFINE ld_____%a0,0x10(%fp) 03350401
DEFINE ld_____%a1,0x18(%fp) 83358401
DEFINE ld_____%a2,0x20(%fp) 03360402
;; RV64I Base Instruction set
DEFINE lwu 03600000
DEFINE ld 03300000
DEFINE sd 23300000
DEFINE addiw 1B000000
DEFINE slliw 1B100000
DEFINE srliw 1B500000
DEFINE sraiw 1B500040
DEFINE addw 3B000000
DEFINE subw 3B000040
DEFINE sllw 3B100000
DEFINE srlw 3B500000
DEFINE sraw 3B500040
DEFINE ld_____%a0,-0x08(%fp) 033584ff
DEFINE ld_____%a1,-0x10(%fp) 833504ff
DEFINE ld_____%a2,-0x18(%fp) 033684fe
;; RV32M Standard Extensions
DEFINE mul 33000002
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
DEFINE ld_____%a0,-0x10(%fp) 033504ff
DEFINE ld_____%a1,-0x18(%fp) 833584fe
DEFINE ld_____%a2,-0x20(%fp) 033604fe
DEFINE ld_____%a3,-0x28(%fp) 833684fd
DEFINE ld_____%a4,-0x30(%fp) 033704fd
;; RV64M Standard Extensions
DEFINE mulw 3B000002
DEFINE divw 3B400002
DEFINE divuw 3B500002
DEFINE remw 3B600002
DEFINE remuw 3B700002
DEFINE ld_____%fp,0x10(%fp) 03340401
DEFINE ld_____%t0,0x8(%fp) 83328400
DEFINE ld_____%sp,0x10(%fp) 03310401
DEFINE ld_____%fp,0x0(%fp) 03340400
DEFINE jr_____%t0 67800200
DEFINE jalr___%t0 e7800200
DEFINE jr_____%t1 67000300
DEFINE jalr___%t1 e7000300
;; Pseudoinstructions
DEFINE nop 13000000 # addi
DEFINE mv 13000000 # addi
DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE beqz 63000000 # beq
DEFINE bnez 63100000 # bne
DEFINE bltz 63400000 # blt
DEFINE ret 67800000 # rs1_ra jalr
## System call values (libc-mini, crt0)
DEFINE li_____%a7,SYS_write 93080004
DEFINE li_____%a7,SYS_exit 9308d005
;; Destination registers
;; register_number << 7
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
;;; 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.
;;;
@ -96,6 +97,16 @@
" %" (if (< o 0) "-1"
(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 ""))
(let loop ((o o))
(when (pair? o)
@ -132,11 +143,11 @@
((char? o) (text->M1 (char->integer o)))
((string? o) o)
((symbol? o) (symbol->string o))
((number? o) (let ((o (if (< o #x80) o (- o #x100))))
(if hex? (string-append "!0x"
(if (and (>= o 0) (< o 16)) "0" "")
(number->string o 16))
(string-append "!" (number->string o)))))
((number? o) (if hex? (string-append
"'" (if (and (>= o 0) (< o 16)) "0" "")
(number->string o 16) "'")
;; non hex mode would be broken on RISC-V
(string-append "!" (number->string o))))
((and (pair? o) (keyword? (car o)))
(pmatch o
;; FIXME
@ -184,6 +195,48 @@
((#:immediate2 ,immediate2) (hex2:immediate2 immediate2))
((#:immediate4 ,immediate4) (hex2:immediate4 immediate4))
((#: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))))
((pair? o) (string-join (map text->M1 o)))
(#t (error "no such text:" o))))

View File

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