[rsp] Introduce microcode build process, disassemble and build both rspboot versions (#2764)

* [rsp] Introduce microcode build process, disassemble and build both rspboot versions

* Suggested changes

* Check-in tool for generating armips.cpp from upstream sources, regen armips.cpp against a newer commit

* License armips_gen.py, add notice that armips.cpp is automatically generated

* Qualify comment with X105

* Clarify the assumed purpose of rspboot releasing SP_SEMAPHORE
This commit is contained in:
Tharo
2026-08-02 15:27:33 +01:00
committed by GitHub
parent 32b88f90a8
commit da4a1f661c
14 changed files with 21657 additions and 22 deletions
+1
View File
@@ -1,5 +1,6 @@
# Output files
*.exe
armips
bin2c
mkdmadata
mkldscript
+15 -7
View File
@@ -1,4 +1,3 @@
CFLAGS := -Wall -Wextra -pedantic -std=gnu99 -g -O2
PROGRAMS := bin2c mkdmadata mkldscript mkspecrules preprocess_pragmas vtxdis
UNAME_S := $(shell uname -s)
@@ -18,10 +17,16 @@ EGCS_BINUTILS_VERSION := 0.6
EGCS_GCC_VERSION := 0.7
EGCS_DIR := egcs/$(DETECTED_OS)
WARNFLAGS := -Wall -Wextra -pedantic
OPTFLAGS := -O2 -g
LDFLAGS :=
ifeq ($(shell command -v clang >/dev/null 2>&1; echo $$?),0)
CC := clang
CXX := clang++
else
CC := gcc
CXX := g++
endif
LLD ?= 0
@@ -31,10 +36,12 @@ ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
endif
ifneq ($(LLD),0)
CFLAGS += -fuse-ld=lld
LDFLAGS += -fuse-ld=lld
endif
all: $(PROGRAMS) $(IDO_RECOMP_5_3_DIR) $(IDO_RECOMP_7_1_DIR) $(EGCS_DIR)
.PHONY: all clean distclean
all: $(PROGRAMS) armips $(IDO_RECOMP_5_3_DIR) $(IDO_RECOMP_7_1_DIR) $(EGCS_DIR)
$(MAKE) -C fado
$(MAKE) -C audio
$(MAKE) -C com-plugin
@@ -52,8 +59,10 @@ clean:
distclean: clean
$(MAKE) -C audio distclean
$(MAKE) -C assets distclean
$(RM) armips
.PHONY: all clean distclean
armips: armips.cpp
$(CXX) $(WARNFLAGS) -std=c++17 $(OPTFLAGS) -s -fno-rtti -pipe -Wno-unused-parameter -Wno-sign-compare $< -o $@
bin2c_SOURCES := bin2c.c
mkdmadata_SOURCES := mkdmadata.c spec.c util.c
@@ -62,10 +71,9 @@ mkspecrules_SOURCES := mkspecrules.c spec.c util.c
preprocess_pragmas_SOURCES := preprocess_pragmas.c
vtxdis_SOURCES := vtxdis.c
define COMPILE =
define COMPILE
$(1): $($1_SOURCES)
$(CC) $(CFLAGS) $$^ -o $$@
$(CC) $(WARNFLAGS) -std=gnu99 $(OPTFLAGS) $$^ $(LDFLAGS) -o $$@
endef
$(foreach p,$(PROGRAMS),$(eval $(call COMPILE,$(p))))
+20859
View File
File diff suppressed because it is too large Load Diff
+168
View File
@@ -0,0 +1,168 @@
diff --git a/Commands/CAssemblerLabel.cpp b/Commands/CAssemblerLabel.cpp
index 3ca67dd..50ea7ae 100644
--- a/Commands/CAssemblerLabel.cpp
+++ b/Commands/CAssemblerLabel.cpp
@@ -1,6 +1,5 @@
#include "Commands/CAssemblerLabel.h"
-#include "Archs/ARM/Arm.h"
#include "Core/Common.h"
#include "Core/FileManager.h"
#include "Core/Misc.h"
@@ -26,12 +25,7 @@ CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& origi
// does this need to be in validate?
if (label->getUpdateInfo())
- {
- if (&Architecture::current() != &Arm)
- label->setInfo(0);
- else
- label->setInfo(thumbMode.value_or(Arm.GetThumbMode()));
- }
+ label->setInfo(0);
}
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value, std::optional<bool> thumbMode)
diff --git a/Commands/CDirectiveConditional.cpp b/Commands/CDirectiveConditional.cpp
index e2177bd..1170247 100644
--- a/Commands/CDirectiveConditional.cpp
+++ b/Commands/CDirectiveConditional.cpp
@@ -1,12 +1,9 @@
#include "Commands/CDirectiveConditional.h"
-#include "Archs/ARM/Arm.h"
#include "Core/Common.h"
#include "Core/Misc.h"
#include "Util/Util.h"
-extern CArmArchitecture Arm;
-
CDirectiveConditional::CDirectiveConditional(ConditionType type)
{
this->type = type;
diff --git a/Core/Assembler.cpp b/Core/Assembler.cpp
index b1d006c..51d9c49 100644
--- a/Core/Assembler.cpp
+++ b/Core/Assembler.cpp
@@ -1,11 +1,7 @@
#include "Core/Assembler.h"
-#include "Archs/ARM/Arm.h"
-#include "Archs/ARM/ArmExpressionFunctions.h"
#include "Archs/MIPS/Mips.h"
#include "Archs/MIPS/MipsExpressionFunctions.h"
-#include "Archs/SuperH/SuperH.h"
-#include "Archs/SuperH/ShExpressionFunctions.h"
#include "Commands/CAssemblerCommand.h"
#include "Core/Allocations.h"
#include "Core/Common.h"
@@ -21,9 +17,7 @@ bool encodeAssembly(std::unique_ptr<CAssemblerCommand> content, SymbolData& symD
{
bool Revalidate;
- Arm.Pass2();
Mips.Pass2();
- SuperH.Pass2();
ValidateState validation;
do // loop until everything is constant
@@ -50,9 +44,7 @@ bool encodeAssembly(std::unique_ptr<CAssemblerCommand> content, SymbolData& symD
Revalidate = content->Validate(validation);
- Arm.Revalidate();
Mips.Revalidate();
- SuperH.Revalidate();
if (Global.memoryMode)
g_fileManager->closeFile();
@@ -162,8 +154,6 @@ bool runArmips(ArmipsArguments& settings)
Global.FileInfo.LineNumber = 0;
Global.FileInfo.FileNum = 0;
- Arm.clear();
-
ExpressionFunctionHandler::instance().reset();
registerExpressionFunctions(ExpressionFunctionHandler::instance());
diff --git a/Parser/DirectivesParser.cpp b/Parser/DirectivesParser.cpp
index d20d401..483d18e 100644
--- a/Parser/DirectivesParser.cpp
+++ b/Parser/DirectivesParser.cpp
@@ -1,8 +1,6 @@
#include "Parser/DirectivesParser.h"
-#include "Archs/ARM/Arm.h"
#include "Archs/MIPS/Mips.h"
-#include "Archs/SuperH/SuperH.h"
#include "Commands/CAssemblerLabel.h"
#include "Commands/CDirectiveArea.h"
#include "Commands/CDirectiveConditional.h"
@@ -432,51 +430,6 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveMipsArch(Parser& parser, int fl
return nullptr;
}
-std::unique_ptr<CAssemblerCommand> parseDirectiveArmArch(Parser& parser, int flags)
-{
- Architecture::setCurrent(Arm);
-
- switch (flags)
- {
- case DIRECTIVE_ARM_GBA:
- Arm.SetThumbMode(true);
- Arm.setVersion(AARCH_GBA);
- return std::make_unique<ArchitectureCommand>(".gba\n.thumb", ".thumb");
- case DIRECTIVE_ARM_NDS:
- Arm.SetThumbMode(false);
- Arm.setVersion(AARCH_NDS);
- return std::make_unique<ArchitectureCommand>(".nds\n.arm", ".arm");
- case DIRECTIVE_ARM_3DS:
- Arm.SetThumbMode(false);
- Arm.setVersion(AARCH_3DS);
- return std::make_unique<ArchitectureCommand>(".3ds\n.arm", ".arm");
- case DIRECTIVE_ARM_BIG:
- Arm.SetThumbMode(false);
- Arm.setVersion(AARCH_BIG);
- return std::make_unique<ArchitectureCommand>(".arm.big\n.arm", ".arm");
- case DIRECTIVE_ARM_LITTLE:
- Arm.SetThumbMode(false);
- Arm.setVersion(AARCH_LITTLE);
- return std::make_unique<ArchitectureCommand>(".arm.little\n.arm", ".arm");
- }
-
- return nullptr;
-}
-
-std::unique_ptr<CAssemblerCommand> parseDirectiveShArch(Parser& parser, int flags)
-{
- Architecture::setCurrent(SuperH);
-
- switch (flags)
- {
- case DIRECTIVE_SH_SATURN:
- SuperH.setVersion(SHARCH_SATURN);
- return std::make_unique<ArchitectureCommand>(".saturn", "");
- }
-
- return nullptr;
-}
-
std::unique_ptr<CAssemblerCommand> parseDirectiveArea(Parser& parser, int flags)
{
std::vector<Expression> parameters;
@@ -820,15 +773,6 @@ const DirectiveMap directives = {
{ ".n64", { &parseDirectiveMipsArch, DIRECTIVE_MIPS_N64 } },
{ ".rsp", { &parseDirectiveMipsArch, DIRECTIVE_MIPS_RSP } },
- { ".gba", { &parseDirectiveArmArch, DIRECTIVE_ARM_GBA } },
- { ".nds", { &parseDirectiveArmArch, DIRECTIVE_ARM_NDS } },
- { ".3ds", { &parseDirectiveArmArch, DIRECTIVE_ARM_3DS } },
- { ".arm.big", { &parseDirectiveArmArch, DIRECTIVE_ARM_BIG } },
- { ".arm.little", { &parseDirectiveArmArch, DIRECTIVE_ARM_LITTLE } },
-
- { ".saturn", { &parseDirectiveShArch, DIRECTIVE_SH_SATURN } },
- { ".32x", { &parseDirectiveShArch, DIRECTIVE_SH_SATURN } },
-
{ ".area", { &parseDirectiveArea, 0 } },
{ ".autoregion", { &parseDirectiveAutoRegion, 0 } },
{ ".region", { &parseDirectiveArea, DIRECTIVE_AREA_SHARED } },
+177
View File
@@ -0,0 +1,177 @@
#!/usr/bin/env python
# SPDX-FileCopyrightText: © 2026 ZeldaRET
# SPDX-License-Identifier: CC0-1.0
#
# Create a single-file armips assembler from an upstream commit, for MIPS only.
# Changing the target commit may require updating
# - armips.diff
# - the included file list
# - the line filters in filter_lines
#
import contextlib, io, os
ARMIPS_URL = "https://github.com/kingcom/armips"
ARMIPS_COMMIT = "9029577f6448c78dadcffbc876d2b8cbcfc6da9b"
ARMIPS_MAJOR_VER = "v0.11"
ARMIPS_PATCH = "armips.diff"
ARMIPS_OUTPUT = "armips.cpp"
file_list = (
"Util/FileSystem.h",
"ext/tinyformat/tinyformat.h",
"Core/Types.h",
"Core/Types.cpp",
"Commands/CAssemblerCommand.h",
"Core/Expression.h",
"Parser/Tokenizer.h",
"Core/ExpressionFunctionHandler.h",
"Core/ExpressionFunctions.h",
"Core/SymbolData.h",
"Util/Util.h",
"Util/FileClasses.h",
"Util/ByteArray.h",
"Core/FileManager.h",
"Core/ELF/ElfTypes.h",
"Core/ELF/ElfFile.h",
"Core/ELF/ElfRelocator.h",
"Archs/Architecture.h",
"Archs/MIPS/Mips.h",
"Archs/MIPS/MipsOpcodes.h",
"Archs/MIPS/CMipsInstruction.h",
"Util/EncodingTable.h",
"Core/Misc.h",
"Core/Assembler.h",
"Core/SymbolTable.h",
"Core/Common.h",
"Core/Allocations.h",
"Core/Allocations.cpp",
"Parser/DirectivesParser.h",
"Archs/MIPS/MipsMacros.h",
"Archs/MIPS/MipsParser.h",
"Archs/MIPS/CMipsInstruction.cpp",
"Archs/MIPS/MipsExpressionFunctions.h",
"Archs/MIPS/MipsElfRelocator.h",
"Archs/MIPS/Mips.cpp",
"Archs/MIPS/MipsElfFile.h",
"Util/CRC.h",
"Archs/MIPS/MipsElfFile.cpp",
"Commands/CommandSequence.h",
"Parser/Parser.h",
"Archs/MIPS/MipsElfRelocator.cpp",
"Archs/MIPS/MipsExpressionFunctions.cpp",
"Archs/MIPS/MipsMacros.cpp",
"Archs/MIPS/MipsOpcodes.cpp",
"Parser/ExpressionParser.h",
"Core/ExpressionFunctionHandler.cpp",
"Archs/MIPS/PsxRelocator.h",
"Commands/CDirectiveFile.h",
"Archs/MIPS/MipsParser.cpp",
"Archs/MIPS/PsxRelocator.cpp",
"Archs/Architecture.cpp",
"Commands/CAssemblerCommand.cpp",
"Commands/CAssemblerLabel.h",
"Commands/CAssemblerLabel.cpp",
"Commands/CDirectiveArea.h",
"Commands/CDirectiveArea.cpp",
"Commands/CDirectiveConditional.h",
"Commands/CDirectiveConditional.cpp",
"Commands/CDirectiveData.h",
"Commands/CDirectiveData.cpp",
"Commands/CDirectiveFile.cpp",
"Commands/CDirectiveMessage.h",
"Commands/CDirectiveMessage.cpp",
"Commands/CommandSequence.cpp",
"Parser/DirectivesParser.cpp",
"Parser/ExpressionParser.cpp",
"Parser/Parser.cpp",
"Parser/Tokenizer.cpp",
"Util/ByteArray.cpp",
"Util/CRC.cpp",
"Util/EncodingTable.cpp",
"Util/FileClasses.cpp",
"Util/Util.cpp",
"Main/CommandLineInterface.h",
"Main/CommandLineInterface.cpp",
"Core/ELF/ElfFile.cpp",
"Core/ELF/ElfRelocator.cpp",
"Core/Assembler.cpp",
"Core/Common.cpp",
"Core/Expression.cpp",
"Core/ExpressionFunctions.cpp",
"Core/FileManager.cpp",
"Core/Misc.cpp",
"Core/SymbolData.cpp",
"Core/SymbolTable.cpp",
"Main/main.cpp",
)
file_header = \
f"""// == AUTOMATICALLY GENERATED by armips_gen.py, do not edit directly ==
// armips assembler {ARMIPS_MAJOR_VER} (commit {ARMIPS_COMMIT})
// {ARMIPS_URL}
// To simplify compilation, all files have been concatenated into one.
// MIPS only, other architectures not included.\n\n"""
@contextlib.contextmanager
def working_dir(x: str):
old = os.getcwd()
os.chdir(x)
try:
yield
finally:
os.chdir(old)
def filter_lines(line: str):
blacklist = (
"#pragma once",
"#include \"",
"#include <tinyformat.h>"
)
return not any(s in line for s in blacklist)
def cat_file(fout: io.TextIOBase, fin_name: str):
with open(fin_name) as fin:
lines = fin.readlines()
lines = map(str.rstrip, filter(filter_lines, lines))
fout.write("\n".join(lines) + "\n")
def combine_armips(fout_name: str, armips_path: str):
with open(fout_name, "w") as fout:
fout.write(file_header)
fout.write("/*\n")
cat_file(fout, os.path.join(armips_path, "LICENSE.txt"))
fout.write("*/\n\n")
fout.write("#define ARMIPS_USE_STD_FILESYSTEM\n")
for f in file_list:
fout.write(f"\n#pragma region \"File: {f}\"\n")
cat_file(fout, os.path.join(armips_path, f))
def main():
with working_dir(os.path.dirname(os.path.realpath(__file__))):
temp_dir = "armips_clone"
# Acquire the base armips commit
os.system(f"rm -rf {temp_dir}")
os.system(f"git init {temp_dir} 2>/dev/null")
with working_dir(temp_dir):
os.system(f"git remote add origin {ARMIPS_URL}.git")
os.system(f"git fetch origin --depth 1 {ARMIPS_COMMIT}")
os.system(f"git checkout FETCH_HEAD 2>/dev/null")
# Apply patch
os.system(f"git apply ../{ARMIPS_PATCH}")
# Concat all included files
print(f"Creating {ARMIPS_OUTPUT}")
combine_armips(ARMIPS_OUTPUT, os.path.expanduser(temp_dir))
os.system(f"rm -rf {temp_dir}")
if __name__ == "__main__":
main()