comeback(?)

Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2024-06-11 22:46:48 +05:30
parent 174008f60c
commit 028c80f6cb
17 changed files with 97 additions and 129 deletions

2
.gitignore vendored
View File

@@ -3,5 +3,5 @@ result
build/ build/
.cache/ .cache/
*~ *~
#*# \#*\#
.#* .#*

View File

@@ -5,18 +5,21 @@ But if you are curious (probably not), read ahead
# Dependencies # Dependencies
## Tested toolchains ## Tested toolchains
- LLVM 16.0.6 - LLVM 18.1.7
- GCC 12.3.0 - GCC 14.1.0
In theory, any toolchain supporting at least the C++20 standard should work. In theory, any toolchain supporting at least the c++23 standard should work.
I am using LLVM's clang and libcxx as the primary toolchain. I am using LLVM's clang and libcxx as the primary toolchain.
## Static libraries ## Static libraries
| Name | Version | Required? | | Name | Version | Required? |
|:------:|:----------|:---------:| |:------:|:----------|:---------:|
| fmt | >= 10.1.1 | yes |
| catch2 | >= 3.4 | for tests | | catch2 | >= 3.4 | for tests |
This goes without saying but using a different toolchain to compile these libraries before linking probably won't work. This goes without saying but using a different toolchain to compile these libraries before linking probably won't work.
I will add meson wrap support once LLVM 17 is out, since I want to get rid of fmt.
-----
# LOG
- June 11, 2024: After almost an year, I have come back to this silly abandoned project, will probably complete it soon.

30
flake.lock generated
View File

@@ -5,11 +5,11 @@
"nixpkgs-lib": "nixpkgs-lib" "nixpkgs-lib": "nixpkgs-lib"
}, },
"locked": { "locked": {
"lastModified": 1693611461, "lastModified": 1717285511,
"narHash": "sha256-aPODl8vAgGQ0ZYFIRisxYG5MOGSkIczvu2Cd8Gb9+1Y=", "narHash": "sha256-iKzJcpdXih14qYVcZ9QC9XuZYnPc6T8YImb6dX166kw=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "7f53fdb7bdc5bb237da7fefef12d099e4fd611ca", "rev": "2a55567fcf15b1b1c7ed712a2c6fadaec7412ea8",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -20,11 +20,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1695806987, "lastModified": 1717868076,
"narHash": "sha256-fX5kGs66NZIxCMcpAGIpxuftajHL8Hil1vjHmjjl118=", "narHash": "sha256-c83Y9t815Wa34khrux81j8K8ET94ESmCuwORSKm2bQY=",
"owner": "nixos", "owner": "nixos",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "f3dab3509afca932f3f4fd0908957709bb1c1f57", "rev": "cd18e2ae9ab8e2a0a8d715b60c91b54c0ac35ff9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@@ -36,20 +36,14 @@
}, },
"nixpkgs-lib": { "nixpkgs-lib": {
"locked": { "locked": {
"dir": "lib", "lastModified": 1717284937,
"lastModified": 1693471703, "narHash": "sha256-lIbdfCsf8LMFloheeE6N31+BMIeixqyQWbSr2vk79EQ=",
"narHash": "sha256-0l03ZBL8P1P6z8MaSDS/MvuU8E75rVxe5eE1N6gxeTo=", "type": "tarball",
"owner": "NixOS", "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
"repo": "nixpkgs",
"rev": "3e52e76b70d5508f3cec70b882a29199f4d1ee85",
"type": "github"
}, },
"original": { "original": {
"dir": "lib", "type": "tarball",
"owner": "NixOS", "url": "https://github.com/NixOS/nixpkgs/archive/eb9ceca17df2ea50a250b6b27f7bf6ab0186f198.tar.gz"
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
} }
}, },
"root": { "root": {

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <fmt/ostream.h>
namespace matar { namespace matar {
enum class ShiftType { enum class ShiftType {

View File

@@ -2,7 +2,7 @@
#include "cpu/alu.hh" #include "cpu/alu.hh"
#include "cpu/psr.hh" #include "cpu/psr.hh"
#include <cstdint> #include <cstdint>
#include <fmt/ostream.h> #include <string>
#include <variant> #include <variant>
namespace matar { namespace matar {
@@ -215,7 +215,7 @@ struct Instruction {
Instruction(uint32_t insn); Instruction(uint32_t insn);
Instruction(Condition condition, InstructionData data) Instruction(Condition condition, InstructionData data)
: condition(condition) : condition(condition)
, data(data){}; , data(data) {};
void exec(Cpu& cpu); void exec(Cpu& cpu);

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include <cstdint> #include <cstdint>
#include <fmt/ostream.h>
namespace matar { namespace matar {
enum class Mode { enum class Mode {

View File

@@ -3,7 +3,7 @@
#include "cpu/alu.hh" #include "cpu/alu.hh"
#include "cpu/psr.hh" #include "cpu/psr.hh"
#include <cstdint> #include <cstdint>
#include <fmt/ostream.h> #include <string>
#include <variant> #include <variant>
namespace matar { namespace matar {

View File

@@ -4,28 +4,11 @@ project('matar', 'cpp',
default_options : ['warning_level=3', default_options : ['warning_level=3',
'werror=true', 'werror=true',
'optimization=3', 'optimization=3',
'cpp_std=c++20', 'cpp_std=c++23',
'default_library=static']) 'default_library=static'])
compiler = meson.get_compiler('cpp') compiler = meson.get_compiler('cpp')
'''
TODO: use <print> and <format> instead of libfmt once LLVM 17 is out
if compiler.has_argument('-std=c++2c')
add_global_arguments('-std=c++2c', language: 'cpp')
elif compiler.has_argument('-std=c++23')
add_global_arguments('-std=c++23', language: 'cpp')
elif compiler.has_argument('-std=c++2b')
add_global_arguments('-std=c++2b', language: 'cpp')
elif compiler.has_argument('-std=c++20')
add_global_arguments('-std=c++20', language: 'cpp')
else
error(compiler.get_id() + ' ' + compiler.version() + 'does not meet the compiler requirements')
endif
'''
subdir('include') subdir('include')
subdir('src') subdir('src')
subdir('apps') subdir('apps')

View File

@@ -1,17 +1,10 @@
{ ... }: { { ... }: {
perSystem = { pkgs, src, ... }: perSystem = { pkgs, src, ... }:
let let
llvm = pkgs.llvmPackages_16; llvm = pkgs.llvmPackages_18;
stdenv = llvm.libcxxStdenv; stdenv = llvm.libcxxStdenv;
libraries = with pkgs; [ libraries = with pkgs; [
((pkgs.fmt.override {
inherit stdenv;
enableShared = false;
}).overrideAttrs (oa: {
cmakeFlags = oa.cmakeFlags ++ [ "-DFMT_TEST=off" ];
})).dev
(catch2_3.override { inherit stdenv; }).out (catch2_3.override { inherit stdenv; }).out
]; ];
in in
@@ -19,7 +12,7 @@
packages.matar-clang = pkgs.callPackage ./build.nix { inherit src libraries stdenv; }; packages.matar-clang = pkgs.callPackage ./build.nix { inherit src libraries stdenv; };
devShells.matar-clang = pkgs.callPackage ./shell.nix { devShells.matar-clang = pkgs.callPackage ./shell.nix {
inherit libraries stdenv; inherit libraries stdenv;
tools = with pkgs; [ (clang-tools_16.override { enableLibcxx = true; }) ]; tools = with pkgs; [ (clang-tools_18.override { enableLibcxx = true; }) ];
}; };
}; };
} }

View File

@@ -1,13 +1,14 @@
{ ... }: { { ... }: {
perSystem = { pkgs, src, ... }: perSystem = { pkgs, src, ... }:
let let
stdenv = pkgs.gcc14Stdenv;
libraries = with pkgs; [ libraries = with pkgs; [
(pkgs.fmt.override { enableShared = false; }).dev (catch2_3.override { inherit stdenv; }).out
catch2_3.out
]; ];
in in
{ {
packages.matar = pkgs.callPackage ./build.nix { inherit src libraries; }; packages.matar = pkgs.callPackage ./build.nix { inherit src libraries stdenv; };
devShells.matar = pkgs.callPackage ./shell.nix { inherit libraries; }; devShells.matar = pkgs.callPackage ./shell.nix { inherit libraries stdenv; };
}; };
} }

View File

@@ -1,5 +1,6 @@
#include "cpu/alu.hh" #include "cpu/alu.hh"
#include "util/bits.hh" #include "util/bits.hh"
#include <bit>
namespace matar { namespace matar {
uint32_t uint32_t

View File

@@ -1,5 +1,7 @@
#include "cpu/arm/instruction.hh" #include "cpu/arm/instruction.hh"
#include "util/bits.hh" #include "util/bits.hh"
#include <format>
#include <string>
namespace matar::arm { namespace matar::arm {
std::string std::string
@@ -9,15 +11,15 @@ Instruction::disassemble() {
return std::visit( return std::visit(
overloaded{ overloaded{
[condition](BranchAndExchange& data) { [condition](BranchAndExchange& data) {
return fmt::format("BX{} R{:d}", condition, data.rn); return std::format("BX{} R{:d}", condition, data.rn);
}, },
[condition](Branch& data) { [condition](Branch& data) {
return fmt::format( return std::format(
"B{}{} 0x{:06X}", (data.link ? "L" : ""), condition, data.offset); "B{}{} 0x{:06X}", (data.link ? "L" : ""), condition, data.offset);
}, },
[condition](Multiply& data) { [condition](Multiply& data) {
if (data.acc) { if (data.acc) {
return fmt::format("MLA{}{} R{:d},R{:d},R{:d},R{:d}", return std::format("MLA{}{} R{:d},R{:d},R{:d},R{:d}",
condition, condition,
(data.set ? "S" : ""), (data.set ? "S" : ""),
data.rd, data.rd,
@@ -25,7 +27,7 @@ Instruction::disassemble() {
data.rs, data.rs,
data.rn); data.rn);
} else { } else {
return fmt::format("MUL{}{} R{:d},R{:d},R{:d}", return std::format("MUL{}{} R{:d},R{:d},R{:d}",
condition, condition,
(data.set ? "S" : ""), (data.set ? "S" : ""),
data.rd, data.rd,
@@ -34,7 +36,7 @@ Instruction::disassemble() {
} }
}, },
[condition](MultiplyLong& data) { [condition](MultiplyLong& data) {
return fmt::format("{}{}{}{} R{:d},R{:d},R{:d},R{:d}", return std::format("{}{}{}{} R{:d},R{:d},R{:d},R{:d}",
(data.uns ? 'U' : 'S'), (data.uns ? 'U' : 'S'),
(data.acc ? "MLAL" : "MULL"), (data.acc ? "MLAL" : "MULL"),
condition, condition,
@@ -46,7 +48,7 @@ Instruction::disassemble() {
}, },
[](Undefined) { return std::string("UND"); }, [](Undefined) { return std::string("UND"); },
[condition](SingleDataSwap& data) { [condition](SingleDataSwap& data) {
return fmt::format("SWP{}{} R{:d},R{:d},[R{:d}]", return std::format("SWP{}{} R{:d},R{:d},[R{:d}]",
condition, condition,
(data.byte ? "B" : ""), (data.byte ? "B" : ""),
data.rd, data.rd,
@@ -62,18 +64,18 @@ Instruction::disassemble() {
expression = ""; expression = "";
} else { } else {
expression = expression =
fmt::format(",{}#{:d}", (data.up ? '+' : '-'), *offset); std::format(",{}#{:d}", (data.up ? '+' : '-'), *offset);
} }
} else if (const Shift* shift = std::get_if<Shift>(&data.offset)) { } else if (const Shift* shift = std::get_if<Shift>(&data.offset)) {
// Shifts are always immediate in single data transfer // Shifts are always immediate in single data transfer
expression = fmt::format(",{}R{:d},{} #{:d}", expression = std::format(",{}R{:d},{} #{:d}",
(data.up ? '+' : '-'), (data.up ? '+' : '-'),
shift->rm, shift->rm,
stringify(shift->data.type), stringify(shift->data.type),
shift->data.operand); shift->data.operand);
} }
return fmt::format( return std::format(
"{}{}{}{} R{:d},[R{:d}{}]{}", "{}{}{}{} R{:d},[R{:d}{}]{}",
(data.load ? "LDR" : "STR"), (data.load ? "LDR" : "STR"),
condition, condition,
@@ -91,15 +93,15 @@ Instruction::disassemble() {
if (data.offset == 0) { if (data.offset == 0) {
expression = ""; expression = "";
} else { } else {
expression = fmt::format( expression = std::format(
",{}#{:d}", (data.up ? '+' : '-'), data.offset); ",{}#{:d}", (data.up ? '+' : '-'), data.offset);
} }
} else { } else {
expression = expression =
fmt::format(",{}R{:d}", (data.up ? '+' : '-'), data.offset); std::format(",{}R{:d}", (data.up ? '+' : '-'), data.offset);
} }
return fmt::format( return std::format(
"{}{}{}{} R{:d},[R{:d}{}]{}", "{}{}{}{} R{:d},[R{:d}{}]{}",
(data.load ? "LDR" : "STR"), (data.load ? "LDR" : "STR"),
condition, condition,
@@ -115,12 +117,12 @@ Instruction::disassemble() {
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < 16; i++) {
if (get_bit(data.regs, i)) if (get_bit(data.regs, i))
fmt::format_to(std::back_inserter(regs), "R{:d},", i); std::format_to(std::back_inserter(regs), "R{:d},", i);
}; };
regs.pop_back(); regs.pop_back();
return fmt::format("{}{}{}{} R{:d}{},{{{}}}{}", return std::format("{}{}{}{} R{:d}{},{{{}}}{}",
(data.load ? "LDM" : "STM"), (data.load ? "LDM" : "STM"),
condition, condition,
(data.up ? 'I' : 'D'), (data.up ? 'I' : 'D'),
@@ -132,12 +134,12 @@ Instruction::disassemble() {
}, },
[condition](PsrTransfer& data) { [condition](PsrTransfer& data) {
if (data.type == PsrTransfer::Type::Mrs) { if (data.type == PsrTransfer::Type::Mrs) {
return fmt::format("MRS{} R{:d},{}", return std::format("MRS{} R{:d},{}",
condition, condition,
data.operand, data.operand,
(data.spsr ? "SPSR_all" : "CPSR_all")); (data.spsr ? "SPSR_all" : "CPSR_all"));
} else { } else {
return fmt::format( return std::format(
"MSR{} {}_{},{}{}", "MSR{} {}_{},{}{}",
condition, condition,
(data.spsr ? "SPSR" : "CPSR"), (data.spsr ? "SPSR" : "CPSR"),
@@ -153,9 +155,9 @@ Instruction::disassemble() {
if (const uint32_t* operand = if (const uint32_t* operand =
std::get_if<uint32_t>(&data.operand)) { std::get_if<uint32_t>(&data.operand)) {
op_2 = fmt::format("#{:d}", *operand); op_2 = std::format("#{:d}", *operand);
} else if (const Shift* shift = std::get_if<Shift>(&data.operand)) { } else if (const Shift* shift = std::get_if<Shift>(&data.operand)) {
op_2 = fmt::format("R{:d},{} {}{:d}", op_2 = std::format("R{:d},{} {}{:d}",
shift->rm, shift->rm,
stringify(shift->data.type), stringify(shift->data.type),
(shift->data.immediate ? '#' : 'R'), (shift->data.immediate ? '#' : 'R'),
@@ -165,7 +167,7 @@ Instruction::disassemble() {
switch (data.opcode) { switch (data.opcode) {
case OpCode::MOV: case OpCode::MOV:
case OpCode::MVN: case OpCode::MVN:
return fmt::format("{}{}{} R{:d},{}", return std::format("{}{}{} R{:d},{}",
stringify(data.opcode), stringify(data.opcode),
condition, condition,
(data.set ? "S" : ""), (data.set ? "S" : ""),
@@ -175,13 +177,13 @@ Instruction::disassemble() {
case OpCode::TEQ: case OpCode::TEQ:
case OpCode::CMP: case OpCode::CMP:
case OpCode::CMN: case OpCode::CMN:
return fmt::format("{}{} R{:d},{}", return std::format("{}{} R{:d},{}",
stringify(data.opcode), stringify(data.opcode),
condition, condition,
data.rn, data.rn,
op_2); op_2);
default: default:
return fmt::format("{}{}{} R{:d},R{:d},{}", return std::format("{}{}{} R{:d},R{:d},{}",
stringify(data.opcode), stringify(data.opcode),
condition, condition,
(data.set ? "S" : ""), (data.set ? "S" : ""),
@@ -191,11 +193,11 @@ Instruction::disassemble() {
} }
}, },
[condition](SoftwareInterrupt) { [condition](SoftwareInterrupt) {
return fmt::format("SWI{}", condition); return std::format("SWI{}", condition);
}, },
[condition](CoprocessorDataTransfer& data) { [condition](CoprocessorDataTransfer& data) {
std::string expression = fmt::format(",#{:d}", data.offset); std::string expression = std::format(",#{:d}", data.offset);
return fmt::format( return std::format(
"{}{}{} p{:d},c{:d},[R{:d}{}]{}", "{}{}{} p{:d},c{:d},[R{:d}{}]{}",
(data.load ? "LDC" : "STC"), (data.load ? "LDC" : "STC"),
condition, condition,
@@ -207,7 +209,7 @@ Instruction::disassemble() {
(data.pre ? (data.write ? "!" : "") : expression)); (data.pre ? (data.write ? "!" : "") : expression));
}, },
[condition](CoprocessorDataOperation& data) { [condition](CoprocessorDataOperation& data) {
return fmt::format("CDP{} p{},{},c{},c{},c{},{}", return std::format("CDP{} p{},{},c{},c{},c{},{}",
condition, condition,
data.cpn, data.cpn,
data.cp_opc, data.cp_opc,
@@ -217,7 +219,7 @@ Instruction::disassemble() {
data.cp); data.cp);
}, },
[condition](CoprocessorRegisterTransfer& data) { [condition](CoprocessorRegisterTransfer& data) {
return fmt::format("{}{} p{},{},R{},c{},c{},{}", return std::format("{}{} p{},{},R{},c{},c{},{}",
(data.load ? "MRC" : "MCR"), (data.load ? "MRC" : "MCR"),
condition, condition,
data.cpn, data.cpn,

View File

@@ -1,5 +1,6 @@
#include "cpu/thumb/instruction.hh" #include "cpu/thumb/instruction.hh"
#include "util/bits.hh" #include "util/bits.hh"
#include <format>
namespace matar::thumb { namespace matar::thumb {
std::string std::string
@@ -7,14 +8,14 @@ Instruction::disassemble(uint32_t pc) {
return std::visit( return std::visit(
overloaded{ overloaded{
[](MoveShiftedRegister& data) { [](MoveShiftedRegister& data) {
return fmt::format("{} R{:d},R{:d},#{:d}", return std::format("{} R{:d},R{:d},#{:d}",
stringify(data.opcode), stringify(data.opcode),
data.rd, data.rd,
data.rs, data.rs,
data.offset); data.offset);
}, },
[](AddSubtract& data) { [](AddSubtract& data) {
return fmt::format("{} R{:d},R{:d},{}{:d}", return std::format("{} R{:d},R{:d},{}{:d}",
stringify(data.opcode), stringify(data.opcode),
data.rd, data.rd,
data.rs, data.rs,
@@ -22,27 +23,27 @@ Instruction::disassemble(uint32_t pc) {
data.offset); data.offset);
}, },
[](MovCmpAddSubImmediate& data) { [](MovCmpAddSubImmediate& data) {
return fmt::format( return std::format(
"{} R{:d},#{:d}", stringify(data.opcode), data.rd, data.offset); "{} R{:d},#{:d}", stringify(data.opcode), data.rd, data.offset);
}, },
[](AluOperations& data) { [](AluOperations& data) {
return fmt::format( return std::format(
"{} R{:d},R{:d}", stringify(data.opcode), data.rd, data.rs); "{} R{:d},R{:d}", stringify(data.opcode), data.rd, data.rs);
}, },
[](HiRegisterOperations& data) { [](HiRegisterOperations& data) {
if (data.opcode == HiRegisterOperations::OpCode::BX) { if (data.opcode == HiRegisterOperations::OpCode::BX) {
return fmt::format("{} R{:d}", stringify(data.opcode), data.rs); return std::format("{} R{:d}", stringify(data.opcode), data.rs);
} }
return fmt::format( return std::format(
"{} R{:d},R{:d}", stringify(data.opcode), data.rd, data.rs); "{} R{:d},R{:d}", stringify(data.opcode), data.rd, data.rs);
}, },
[](PcRelativeLoad& data) { [](PcRelativeLoad& data) {
return fmt::format("LDR R{:d},[PC,#{:d}]", data.rd, data.word); return std::format("LDR R{:d},[PC,#{:d}]", data.rd, data.word);
}, },
[](LoadStoreRegisterOffset& data) { [](LoadStoreRegisterOffset& data) {
return fmt::format("{}{} R{:d},[R{:d},R{:d}]", return std::format("{}{} R{:d},[R{:d},R{:d}]",
(data.load ? "LDR" : "STR"), (data.load ? "LDR" : "STR"),
(data.byte ? "B" : ""), (data.byte ? "B" : ""),
data.rd, data.rd,
@@ -51,11 +52,11 @@ Instruction::disassemble(uint32_t pc) {
}, },
[](LoadStoreSignExtendedHalfword& data) { [](LoadStoreSignExtendedHalfword& data) {
if (!data.s && !data.h) { if (!data.s && !data.h) {
return fmt::format( return std::format(
"STRH R{:d},[R{:d},R{:d}]", data.rd, data.rb, data.ro); "STRH R{:d},[R{:d},R{:d}]", data.rd, data.rb, data.ro);
} }
return fmt::format("{}{} R{:d},[R{:d},R{:d}]", return std::format("{}{} R{:d},[R{:d},R{:d}]",
(data.s ? "LDS" : "LDR"), (data.s ? "LDS" : "LDR"),
(data.h ? 'H' : 'B'), (data.h ? 'H' : 'B'),
data.rd, data.rd,
@@ -63,7 +64,7 @@ Instruction::disassemble(uint32_t pc) {
data.ro); data.ro);
}, },
[](LoadStoreImmediateOffset& data) { [](LoadStoreImmediateOffset& data) {
return fmt::format("{}{} R{:d},[R{:d},#{:d}]", return std::format("{}{} R{:d},[R{:d},#{:d}]",
(data.load ? "LDR" : "STR"), (data.load ? "LDR" : "STR"),
(data.byte ? "B" : ""), (data.byte ? "B" : ""),
data.rd, data.rd,
@@ -71,33 +72,33 @@ Instruction::disassemble(uint32_t pc) {
data.offset); data.offset);
}, },
[](LoadStoreHalfword& data) { [](LoadStoreHalfword& data) {
return fmt::format("{} R{:d},[R{:d},#{:d}]", return std::format("{} R{:d},[R{:d},#{:d}]",
(data.load ? "LDRH" : "STRH"), (data.load ? "LDRH" : "STRH"),
data.rd, data.rd,
data.rb, data.rb,
data.offset); data.offset);
}, },
[](SpRelativeLoad& data) { [](SpRelativeLoad& data) {
return fmt::format("{} R{:d},[SP,#{:d}]", return std::format("{} R{:d},[SP,#{:d}]",
(data.load ? "LDR" : "STR"), (data.load ? "LDR" : "STR"),
data.rd, data.rd,
data.word); data.word);
}, },
[](LoadAddress& data) { [](LoadAddress& data) {
return fmt::format("ADD R{:d},{},#{:d}", return std::format("ADD R{:d},{},#{:d}",
data.rd, data.rd,
(data.sp ? "SP" : "PC"), (data.sp ? "SP" : "PC"),
data.word); data.word);
}, },
[](AddOffsetStackPointer& data) { [](AddOffsetStackPointer& data) {
return fmt::format("ADD SP,#{:d}", data.word); return std::format("ADD SP,#{:d}", data.word);
}, },
[](PushPopRegister& data) { [](PushPopRegister& data) {
std::string regs; std::string regs;
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < 16; i++) {
if (get_bit(data.regs, i)) if (get_bit(data.regs, i))
fmt::format_to(std::back_inserter(regs), "R{:d},", i); std::format_to(std::back_inserter(regs), "R{:d},", i);
}; };
if (data.load) { if (data.load) {
@@ -106,14 +107,14 @@ Instruction::disassemble(uint32_t pc) {
else else
regs.pop_back(); regs.pop_back();
return fmt::format("POP {{{}}}", regs); return std::format("POP {{{}}}", regs);
} else { } else {
if (data.pclr) if (data.pclr)
regs += "LR"; regs += "LR";
else else
regs.pop_back(); regs.pop_back();
return fmt::format("PUSH {{{}}}", regs); return std::format("PUSH {{{}}}", regs);
} }
}, },
[](MultipleLoad& data) { [](MultipleLoad& data) {
@@ -121,31 +122,31 @@ Instruction::disassemble(uint32_t pc) {
for (uint8_t i = 0; i < 16; i++) { for (uint8_t i = 0; i < 16; i++) {
if (get_bit(data.regs, i)) if (get_bit(data.regs, i))
fmt::format_to(std::back_inserter(regs), "R{:d},", i); std::format_to(std::back_inserter(regs), "R{:d},", i);
}; };
regs.pop_back(); regs.pop_back();
return fmt::format( return std::format(
"{} R{}!,{{{}}}", (data.load ? "LDMIA" : "STMIA"), data.rb, regs); "{} R{}!,{{{}}}", (data.load ? "LDMIA" : "STMIA"), data.rb, regs);
}, },
[](SoftwareInterrupt& data) { [](SoftwareInterrupt& data) {
return fmt::format("SWI {:d}", data.vector); return std::format("SWI {:d}", data.vector);
}, },
[pc](ConditionalBranch& data) { [pc](ConditionalBranch& data) {
return fmt::format( return std::format(
"B{} #{:d}", "B{} #{:d}",
stringify(data.condition), stringify(data.condition),
static_cast<int32_t>(data.offset + pc + 2 * INSTRUCTION_SIZE)); static_cast<int32_t>(data.offset + pc + 2 * INSTRUCTION_SIZE));
}, },
[pc](UnconditionalBranch& data) { [pc](UnconditionalBranch& data) {
return fmt::format( return std::format(
"B #{:d}", "B #{:d}",
static_cast<int32_t>(data.offset + pc + 2 * INSTRUCTION_SIZE)); static_cast<int32_t>(data.offset + pc + 2 * INSTRUCTION_SIZE));
}, },
[](LongBranchWithLink& data) { [](LongBranchWithLink& data) {
// duh this manual be empty for H = 0 // duh this manual be empty for H = 0
return fmt::format( return std::format(
"BL{} #{:d}", (data.high ? "H" : ""), data.offset); "BL{} #{:d}", (data.high ? "H" : ""), data.offset);
}, },
[](auto) { return std::string("unknown instruction"); } }, [](auto) { return std::string("unknown instruction"); } },

View File

@@ -8,12 +8,6 @@ subdir('cpu')
lib_cpp_args = [] lib_cpp_args = []
fmt = dependency('fmt', version : '>=10.1.0', static: true)
if not fmt.found()
fmt = dependency('fmt', version : '>=10.1.0', static: false)
lib_cpp_args += '-DFMT_HEADER_ONLY'
endif
if get_option('disassembler') if get_option('disassembler')
lib_cpp_args += '-DDISASSEMBLER' lib_cpp_args += '-DDISASSEMBLER'
endif endif
@@ -21,7 +15,6 @@ endif
lib = library( lib = library(
meson.project_name(), meson.project_name(),
lib_sources, lib_sources,
dependencies: [fmt],
include_directories: inc, include_directories: inc,
install: true, install: true,
cpp_args: lib_cpp_args cpp_args: lib_cpp_args

View File

@@ -35,6 +35,6 @@ inline Int
bit_range(Int num, size_t start, size_t end) { bit_range(Int num, size_t start, size_t end) {
// NOTE: we do not require -1 if it is a signed integral // NOTE: we do not require -1 if it is a signed integral
Int left = Int left =
std::numeric_limits<Int>::digits - (std::is_unsigned<Int>::value) - end; std::numeric_limits<Int>::digits - (!std::is_signed<Int>::value) - end;
return static_cast<Int>(num << left) >> (left + start); return static_cast<Int>(num << left) >> (left + start);
} }

View File

@@ -2,7 +2,7 @@
#include <array> #include <array>
#include <bit> #include <bit>
#include <fmt/core.h> #include <format>
#include <string> #include <string>
// Why I wrote this myself? I do not know // Why I wrote this myself? I do not know
@@ -110,7 +110,7 @@ sha256(std::array<uint8_t, N>& data) {
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
fmt::format_to(std::back_inserter(string), std::format_to(std::back_inserter(string),
"{:02x}", "{:02x}",
((h[j] >> (24 - i * 8)) & 0xFF)); ((h[j] >> (24 - i * 8)) & 0xFF));

View File

@@ -1,8 +1,7 @@
#pragma once #pragma once
#include "util/loglevel.hh" #include "util/loglevel.hh"
#include <fmt/ostream.h> #include <print>
#include <iostream>
namespace logging { namespace logging {
namespace ansi { namespace ansi {
@@ -14,7 +13,7 @@ static constexpr auto BOLD = "\033[1m";
static constexpr auto RESET = "\033[0m"; static constexpr auto RESET = "\033[0m";
} }
using fmt::print; using std::print;
class Logger { class Logger {
using LogLevel = matar::LogLevel; using LogLevel = matar::LogLevel;
@@ -27,12 +26,12 @@ class Logger {
} }
template<typename... Args> template<typename... Args>
void log(const fmt::format_string<Args...>& fmt, Args&&... args) { void log(const std::format_string<Args...>& fmt, Args&&... args) {
fmt::println(stream, fmt, std::forward<Args>(args)...); std::println(stream, fmt, std::forward<Args>(args)...);
} }
template<typename... Args> template<typename... Args>
void debug(const fmt::format_string<Args...>& fmt, Args&&... args) { void debug(const std::format_string<Args...>& fmt, Args&&... args) {
if (level & static_cast<uint8_t>(LogLevel::Debug)) { if (level & static_cast<uint8_t>(LogLevel::Debug)) {
print(stream, "{}{}[DEBUG] ", ansi::MAGENTA, ansi::BOLD); print(stream, "{}{}[DEBUG] ", ansi::MAGENTA, ansi::BOLD);
log(fmt, std::forward<Args>(args)...); log(fmt, std::forward<Args>(args)...);
@@ -41,7 +40,7 @@ class Logger {
} }
template<typename... Args> template<typename... Args>
void info(const fmt::format_string<Args...>& fmt, Args&&... args) { void info(const std::format_string<Args...>& fmt, Args&&... args) {
if (level & static_cast<uint8_t>(LogLevel::Info)) { if (level & static_cast<uint8_t>(LogLevel::Info)) {
print(stream, "{}[INFO] ", ansi::WHITE); print(stream, "{}[INFO] ", ansi::WHITE);
log(fmt, std::forward<Args>(args)...); log(fmt, std::forward<Args>(args)...);
@@ -50,7 +49,7 @@ class Logger {
} }
template<typename... Args> template<typename... Args>
void warn(const fmt::format_string<Args...>& fmt, Args&&... args) { void warn(const std::format_string<Args...>& fmt, Args&&... args) {
if (level & static_cast<uint8_t>(LogLevel::Warn)) { if (level & static_cast<uint8_t>(LogLevel::Warn)) {
print(stream, "{}[WARN] ", ansi::YELLOW); print(stream, "{}[WARN] ", ansi::YELLOW);
log(fmt, std::forward<Args>(args)...); log(fmt, std::forward<Args>(args)...);
@@ -59,7 +58,7 @@ class Logger {
} }
template<typename... Args> template<typename... Args>
void error(const fmt::format_string<Args...>& fmt, Args&&... args) { void error(const std::format_string<Args...>& fmt, Args&&... args) {
if (level & static_cast<uint8_t>(LogLevel::Error)) { if (level & static_cast<uint8_t>(LogLevel::Error)) {
print(stream, "{}{}[ERROR] ", ansi::RED, ansi::BOLD); print(stream, "{}{}[ERROR] ", ansi::RED, ansi::BOLD);
log(fmt, std::forward<Args>(args)...); log(fmt, std::forward<Args>(args)...);