diff --git a/abstract-machine/Makefile b/abstract-machine/Makefile index 3a5d60a..1377857 100644 --- a/abstract-machine/Makefile +++ b/abstract-machine/Makefile @@ -47,33 +47,32 @@ endif ### Create the destination directory (`build/$ARCH`) WORK_DIR = $(shell pwd) -DST_DIR = $(WORK_DIR)/build/$(ARCH) +BUILD_DIR ?= $(WORK_DIR)/build +DST_DIR = $(BUILD_DIR)/$(ARCH) $(shell mkdir -p $(DST_DIR)) ### Compilation targets (a binary image or archive) -IMAGE_REL = build/$(NAME)-$(ARCH) +IMAGE_REL = $(DST_DIR)/$(NAME)-$(ARCH) IMAGE = $(abspath $(IMAGE_REL)) -ARCHIVE = $(WORK_DIR)/build/$(NAME)-$(ARCH).a +ARCHIVE = $(BUILD_DIR)/$(NAME)-$(ARCH).a ### Collect the files to be linked: object files (`.o`) and libraries (`.a`) OBJS = $(addprefix $(DST_DIR)/, $(addsuffix .o, $(basename $(SRCS)))) LIBS := $(sort $(LIBS) am klib) # lazy evaluation ("=") causes infinite recursions LINKAGE = $(OBJS) \ - $(addsuffix -$(ARCH).a, $(join \ - $(addsuffix /build/, $(addprefix $(AM_HOME)/, $(LIBS))), \ - $(LIBS) )) + $(addsuffix -$(ARCH).a, $(addprefix $(BUILD_DIR)/, $(LIBS))) ## 3. General Compilation Flags ### (Cross) compilers, e.g., mips-linux-gnu-g++ -AS = $(CROSS_COMPILE)gcc -CC = $(CROSS_COMPILE)gcc -CXX = $(CROSS_COMPILE)g++ -LD = $(CROSS_COMPILE)ld -AR = $(CROSS_COMPILE)ar -OBJDUMP = $(CROSS_COMPILE)objdump -OBJCOPY = $(CROSS_COMPILE)objcopy -READELF = $(CROSS_COMPILE)readelf +AS ?= $(CROSS_COMPILE)gcc +CC ?= $(CROSS_COMPILE)gcc +CXX ?= $(CROSS_COMPILE)g++ +LD ?= $(CROSS_COMPILE)ld +AR ?= $(CROSS_COMPILE)ar +OBJDUMP ?= $(CROSS_COMPILE)objdump +OBJCOPY ?= $(CROSS_COMPILE)objcopy +READELF ?= $(CROSS_COMPILE)readelf ### Compilation flags INC_PATH += $(WORK_DIR)/include $(addsuffix /include/, $(addprefix $(AM_HOME)/, $(LIBS))) diff --git a/flake.nix b/flake.nix index 824a31d..69b4884 100644 --- a/flake.nix +++ b/flake.nix @@ -18,19 +18,48 @@ in { packages.nemu = pkgs.callPackage ./nemu {}; - - devShells.am-kernels = crossPkgs.mkShell { - inputsFrom = [ - self.packages.${system}.nemu - ]; - packages = [ - pkgs.stdenv.cc - ]; - shellHook = '' - export PROJECT_ROOT=/home/xin/repo/ysyx-workbench - export AM_HOME=$PROJECT_ROOT/abstract-machine; - export NEMU_HOME=$PROJECT_ROOT/nemu; + + packages.am-kernels = crossPkgs.stdenv.mkDerivation rec { + pname = "am-kernels"; + version = "2024.02.18"; + + src = pkgs.fetchFromGitHub { + owner = "NJU-ProjectN"; + repo = "am-kernels"; + rev = "bb725d6f8223dd7de831c3b692e8c4531e9d01af"; + hash = "sha256-ZHdrw28TN8cMvhhzM469OV7cp0Yp+8yao855HP4+P4A="; + }; + + AM_HOME = pkgs.fetchFromGitHub { + owner = "xinyangli"; + repo = "abstract-machine"; + rev = "788595aac61c6b2f3b78ca8aa7d08dc33911bca4"; + hash = "sha256-YvWHIBP9tz3HL2TyibftvvQrpkWUDPnviCF4oyLmdjg="; + }; + + ARCH = "riscv32-nemu"; + + patchPhase = '' + sed -i 's/\/bin\/echo/echo/' tests/cpu-tests/Makefile ''; + + buildPhase = '' + AS=$CC make -C tests/cpu-tests BUILD_DIR=$(pwd)/build ARCH=$ARCH + ''; + + installPhase = '' + mkdir -p $out/share/images $out/share/dump + cp build/riscv32-nemu/*.bin $out/share/images + cp build/riscv32-nemu/*.txt $out/share/dump + ''; + + dontFixup = true; + }; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + gdb + ] ++ builtins.attrValues self.packages.${system}; }; } ); diff --git a/nemu/default.nix b/nemu/default.nix index 3368ee0..ee02064 100644 --- a/nemu/default.nix +++ b/nemu/default.nix @@ -9,7 +9,6 @@ stdenv.mkDerivation rec { src = ./.; - NEMU_HOME = "/build/nemu"; nativeBuildInputs = with pkgs; [ gnumake flex @@ -23,7 +22,7 @@ stdenv.mkDerivation rec { ]; configurePhase = '' - echo pwd=$(pwd) + export NEMU_HOME=$(pwd) make alldefconfig ''; diff --git a/nemu/src/isa/riscv32/inst.c b/nemu/src/isa/riscv32/inst.c index cb0c44e..39e0e08 100644 --- a/nemu/src/isa/riscv32/inst.c +++ b/nemu/src/isa/riscv32/inst.c @@ -23,7 +23,7 @@ #define Mw vaddr_write enum { - TYPE_I, TYPE_U, TYPE_S, + TYPE_R, TYPE_I, TYPE_U, TYPE_S, TYPE_J, TYPE_N, // none }; @@ -32,6 +32,7 @@ enum { #define immI() do { *imm = SEXT(BITS(i, 31, 20), 12); } while(0) #define immU() do { *imm = SEXT(BITS(i, 31, 12), 20) << 12; } while(0) #define immS() do { *imm = (SEXT(BITS(i, 31, 25), 7) << 5) | BITS(i, 11, 7); } while(0) +#define immJ() do { *imm = (SEXT(BITS(i, 31, 30), 1) << 20) | BITS(i, 30, 21) << 1 | BITS(i, 21, 20) << 11 | BITS(i, 19, 12) << 12; } while(0) static void decode_operand(Decode *s, int *rd, word_t *src1, word_t *src2, word_t *imm, int type) { uint32_t i = s->isa.inst.val; @@ -39,8 +40,10 @@ static void decode_operand(Decode *s, int *rd, word_t *src1, word_t *src2, word_ int rs2 = BITS(i, 24, 20); *rd = BITS(i, 11, 7); switch (type) { + case TYPE_R: src1R(); src2R(); break; case TYPE_I: src1R(); immI(); break; case TYPE_U: immU(); break; + case TYPE_J: immJ(); break; case TYPE_S: src1R(); src2R(); immS(); break; } } @@ -57,9 +60,14 @@ static int decode_exec(Decode *s) { } INSTPAT_START(); + INSTPAT("??????? ????? ????? ??? ????? 01101 11", lui , U, R(rd) = imm); INSTPAT("??????? ????? ????? ??? ????? 00101 11", auipc , U, R(rd) = s->pc + imm); + // INSTPAT("??????? ????? ????? ??? ????? 11011 11", jal, , J, do {s->dnpc = s->pc + imm; R(rd) = s->pc + 4; } while(0)); + // INSTPAT("??????? ????? ????? ??? ????? 11001 11", jalr , I, do {s->dnpc = s->pc + src1; R(rd) = s->pc + 4); } while(0); INSTPAT("??????? ????? ????? 100 ????? 00000 11", lbu , I, R(rd) = Mr(src1 + imm, 1)); INSTPAT("??????? ????? ????? 000 ????? 01000 11", sb , S, Mw(src1 + imm, 1, src2)); + INSTPAT("??????? ????? ????? 000 ????? 00100 11", addi , I, R(rd) = src1 + (sword_t)imm); + INSTPAT("0000000 ????? ????? 000 ????? 01100 11", add , R, R(rd) = src1 + src2); INSTPAT("0000000 00001 00000 000 00000 11100 11", ebreak , N, NEMUTRAP(s->pc, R(10))); // R(10) is $a0 INSTPAT("??????? ????? ????? ??? ????? ????? ??", inv , N, INV(s->pc)); diff --git a/result b/result index b299d6f..172ba27 120000 --- a/result +++ b/result @@ -1 +1 @@ -/nix/store/3x5nz7zcwq0zhcff1d3l9lpmvmnmx2i5-nemu-2024-03-02 \ No newline at end of file +/nix/store/d0jlcjdrgsb5pis8flyy5ihifdnfhms5-am-kernels-riscv32-none-elf-2024.02.18 \ No newline at end of file