Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
__pycache__
tools/mwcc_compiler/*.*
tools/elf2dol
*.exe
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ OBJCOPY := $(DEVKITPPC)/bin/powerpc-eabi-objcopy
CC := $(WINE) tools/mwcc_compiler/2.0/mwcceppc.exe
LD := $(WINE) tools/mwcc_compiler/2.7/mwldeppc.exe
PPROC := python tools/postprocess.py
GLBLASM := python tools/inlineasm/globalasm.py
ELF2DOL := tools/elf2dol
SHA1SUM := sha1sum
ASMDIFF := ./asmdiff.sh
Expand Down Expand Up @@ -121,4 +122,5 @@ $(OBJ_DIR)/%.o: %.c

$(OBJ_DIR)/%.o: %.cpp
$(CC) $(PREPROCESS) -o $*.cp $<
$(GLBLASM) $*.cp
$(CC) $(CFLAGS) -c -o $@ $*.cp
2 changes: 1 addition & 1 deletion obj_files.mk
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TEXT_O_FILES := \
$(OBJ_DIR)/asm/Core/x/xPar.o \
$(OBJ_DIR)/asm/Core/x/xParCmd.o \
$(OBJ_DIR)/asm/Core/x/xParGroup.o \
$(OBJ_DIR)/asm/Core/x/xParMgr.o \
$(OBJ_DIR)/src/Core/x/xParMgr.o \
$(OBJ_DIR)/asm/Core/x/xPartition.o \
$(OBJ_DIR)/asm/Core/x/xpkrsvc.o \
$(OBJ_DIR)/asm/Core/x/xQuickCull.o \
Expand Down
10 changes: 9 additions & 1 deletion src/Core/x/xParMgr.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
#include "xParMgr.h"
#include "xParMgr.h"

#pragma GLOBAL_ASM("asm/Core/x/xParMgr.s", "xParMgrInit__Fv")

#pragma GLOBAL_ASM("asm/Core/x/xParMgr.s", "xParMgrKillAllParticles__Fv")

#pragma GLOBAL_ASM("asm/Core/x/xParMgr.s", "xParMgrUpdate__Ff")

#pragma GLOBAL_ASM("asm/Core/x/xParMgr.s", "xParMgrRender__Fv")
46 changes: 46 additions & 0 deletions tools/inlineasm/globalasm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import argparse
from pathlib import Path
from helpers import *
import os

info = """globalasm.py:

Inserts assembly directly into CPP source.
Specified by #pragma GLOBAL_ASM(assemblyFilePath, functionName)
"""

parser = argparse.ArgumentParser(description=info)
parser.add_argument("cpFile", help="The .cp file to process")

def run():

args = parser.parse_args()
cpPath = Path(args.cpFile)
cpText = open(cpPath).read()
matches = getPragmaMatches(cpText)

if len(matches) == 0:
return

for match in matches:

replace = match[0]
args = getPragmaArgs(match[1])
asmPath = Path(args[0])
asmFileText = open(asmPath).read()

funcToImport = args[1]
funcs = getAsmFunctions(asmFileText)
# check to see if function argument given is in the file
if funcToImport + ":" not in funcs:
error(funcToImport + " is undefined in " + str(asmPath))

asmBlock = getAsmFunctionBlock(asmFileText, funcToImport + ":")
codeBytes = blockToBytes(asmBlock)
newSource = ""
newSource = writeCode(newSource, funcToImport, codeBytes)
cpText = cpText.replace(replace, newSource)

open(cpPath, "w").write(cpText)

run()
73 changes: 73 additions & 0 deletions tools/inlineasm/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import re

pragmaRegex = r"(#pragma\sGLOBAL_ASM\((.*)\))"

def getPragmaMatches(fileText):
matches = re.findall(pragmaRegex, fileText)
return matches

# Arguments are processed outside of the regex to keep it simple
# and support any changes we may make in the future
def getPragmaArgs(argString):
args = argString.split(",")
args = map(str.strip, args)
args = map(lambda x: x.replace("\"", ""), args)
return list(args)

labelRegex = r".+:"

def getLabels(fileText):
matches = re.findall(labelRegex, fileText)
return matches

def getAsmFunctions(fileText):
matches = getLabels(fileText)
return list(filter(lambda x: "lbl_" not in x, matches))

def getAsmFunctionBlock(fileText, label):
data = []
found = False
for line in fileText.splitlines():
if label in line:
found = True
continue
if found:
data.append(line.strip())
if len(line) == 0:
break
return data

def filterBlockCode(block):
return list(filter(lambda x: "/*" in x, block))

def codeLineToBytes(line):
d = line.split()
b = "0x" + "".join(d[3:7])
return b

def blockToBytes(block):
code = filterBlockCode(block)
return list(map(codeLineToBytes, code))

def bytesToString(byteLine):
return "opword" + " " + byteLine

funcTemplate = """extern "C" {
asm void {name}() {
nofralloc
{data}
}}"""

def writeCode(source, funcName, codeBytes):
source += "\n"
t = funcTemplate.replace("{name}", funcName)
bs = list(map(bytesToString, codeBytes))
t = t.replace("{data}", "\n".join(bs))
source += t + "\n"

return source

def error(text):
print("Error during #pragma processing:")
print(text)
exit(69)