mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 09:55:42 -05:00
preproc: generate .size in script_data sections (#9233)
This commit is contained in:
parent
ccb9c4d294
commit
4af2bd3207
2
Makefile
2
Makefile
|
|
@ -529,7 +529,7 @@ ifneq ($(NODEP),1)
|
|||
endif
|
||||
|
||||
$(DATA_ASM_BUILDDIR)/%.o: $(DATA_ASM_SUBDIR)/%.s
|
||||
$(PREPROC) $< charmap.txt | $(CPP) $(CPPFLAGS) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@
|
||||
$(PREPROC) -s $< charmap.txt | $(CPP) $(CPPFLAGS) $(INCLUDE_SCANINC_ARGS) - | $(PREPROC) -ie $< charmap.txt | $(AS) $(ASFLAGS) -o $@
|
||||
|
||||
$(DATA_ASM_BUILDDIR)/%.d: $(DATA_ASM_SUBDIR)/%.s
|
||||
$(SCANINC) -M $@ $(INCLUDE_SCANINC_ARGS) -I "" $<
|
||||
|
|
|
|||
|
|
@ -160,9 +160,9 @@ Directive AsmFile::GetDirective()
|
|||
return Directive::Unknown;
|
||||
}
|
||||
|
||||
// Checks if we're at label that ends with '::'.
|
||||
// Returns the name if so and an empty string if not.
|
||||
std::string AsmFile::GetGlobalLabel()
|
||||
// Checks if we're at label and if so, returns its symbol and scope.
|
||||
// Returns 'label::none' if not.
|
||||
Label AsmFile::GetLabel()
|
||||
{
|
||||
long start = m_pos;
|
||||
long pos = m_pos;
|
||||
|
|
@ -175,14 +175,57 @@ std::string AsmFile::GetGlobalLabel()
|
|||
pos++;
|
||||
}
|
||||
|
||||
if (m_buffer[pos] == ':' && m_buffer[pos + 1] == ':')
|
||||
if (m_buffer[pos] == ':')
|
||||
{
|
||||
m_pos = pos + 2;
|
||||
ExpectEmptyRestOfLine();
|
||||
return std::string(&m_buffer[start], pos - start);
|
||||
std::string symbol(&m_buffer[start], pos - start);
|
||||
if (m_buffer[pos + 1] == ':')
|
||||
{
|
||||
m_pos = pos + 2;
|
||||
ExpectEmptyRestOfLine();
|
||||
return Label(symbol, Label::global);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pos = pos + 1;
|
||||
return Label(symbol, Label::local);
|
||||
}
|
||||
}
|
||||
|
||||
return std::string();
|
||||
return Label("", Label::none);
|
||||
}
|
||||
|
||||
std::string AsmFile::PeekSection()
|
||||
{
|
||||
long oldPos = m_pos;
|
||||
std::string section;
|
||||
|
||||
SkipWhitespace();
|
||||
|
||||
// TODO: Support 'pushsection', 'popsection', '.previous'.
|
||||
if (CheckForDirective(".bss"))
|
||||
{
|
||||
section = ".bss";
|
||||
}
|
||||
else if (CheckForDirective(".data"))
|
||||
{
|
||||
section = ".data";
|
||||
}
|
||||
else if (CheckForDirective(".rodata"))
|
||||
{
|
||||
section = ".rodata";
|
||||
}
|
||||
else if (CheckForDirective(".text"))
|
||||
{
|
||||
section = ".text";
|
||||
}
|
||||
else if (CheckForDirective(".section"))
|
||||
{
|
||||
SkipWhitespace();
|
||||
section = ReadIdentifier();
|
||||
}
|
||||
|
||||
m_pos = oldPos;
|
||||
return section;
|
||||
}
|
||||
|
||||
// Skips tabs and spaces.
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@ enum class Directive
|
|||
Unknown
|
||||
};
|
||||
|
||||
struct Label
|
||||
{
|
||||
std::string symbol;
|
||||
enum Type { none, global, local } type;
|
||||
|
||||
Label() : symbol(""), type(none) {}
|
||||
Label(const Label&) = default;
|
||||
Label(std::string symbol_, Type type_) : symbol(symbol_), type(type_) {}
|
||||
explicit operator bool() { return !symbol.empty() && type != none; }
|
||||
};
|
||||
|
||||
class AsmFile
|
||||
{
|
||||
public:
|
||||
|
|
@ -43,7 +54,8 @@ public:
|
|||
AsmFile(const AsmFile&) = delete;
|
||||
~AsmFile();
|
||||
Directive GetDirective();
|
||||
std::string GetGlobalLabel();
|
||||
Label GetLabel();
|
||||
std::string PeekSection();
|
||||
std::string ReadPath();
|
||||
int ReadString(unsigned char* s);
|
||||
int ReadBraille(unsigned char* s);
|
||||
|
|
@ -60,6 +72,7 @@ private:
|
|||
long m_lineNum;
|
||||
long m_lineStart;
|
||||
std::string m_filename;
|
||||
bool m_scriptData;
|
||||
|
||||
bool ConsumeComma();
|
||||
int ReadPadLength();
|
||||
|
|
|
|||
|
|
@ -51,9 +51,11 @@ void PrintAsmBytes(unsigned char *s, int length)
|
|||
}
|
||||
}
|
||||
|
||||
void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
|
||||
void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum, bool doSize)
|
||||
{
|
||||
std::stack<AsmFile> stack;
|
||||
Label prevLabel;
|
||||
bool inScriptData = false;
|
||||
|
||||
stack.push(AsmFile(filename, isStdin, doEnum));
|
||||
std::printf("# 1 \"%s\"\n", filename.c_str());
|
||||
|
|
@ -62,6 +64,11 @@ void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
|
|||
{
|
||||
while (stack.top().IsAtEnd())
|
||||
{
|
||||
const char *ps = prevLabel.symbol.c_str();
|
||||
if (doSize && inScriptData && prevLabel)
|
||||
std::printf(".ifdef %s ; .size %s, . - %s ; .endif\n", ps, ps, ps);
|
||||
prevLabel = Label();
|
||||
|
||||
stack.pop();
|
||||
|
||||
if (stack.empty())
|
||||
|
|
@ -100,15 +107,28 @@ void PreprocAsmFile(std::string filename, bool isStdin, bool doEnum)
|
|||
}
|
||||
case Directive::Unknown:
|
||||
{
|
||||
std::string globalLabel = stack.top().GetGlobalLabel();
|
||||
Label label = stack.top().GetLabel();
|
||||
|
||||
if (globalLabel.length() != 0)
|
||||
if (label)
|
||||
{
|
||||
const char *s = globalLabel.c_str();
|
||||
std::printf("%s: ; .global %s\n", s, s);
|
||||
const char *s = label.symbol.c_str();
|
||||
const char *ps = prevLabel.symbol.c_str();
|
||||
|
||||
if (doSize && inScriptData && prevLabel)
|
||||
std::printf(".ifdef %s ; .size %s, . - %s ; .endif ; ", ps, ps, ps);
|
||||
|
||||
if (label.type == Label::global)
|
||||
std::printf(".global %s\n%s:\n", s, s);
|
||||
|
||||
prevLabel = label;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string section = stack.top().PeekSection();
|
||||
if (section == "script_data")
|
||||
inScriptData = true;
|
||||
else if (section != "")
|
||||
inScriptData = false;
|
||||
stack.top().OutputLine();
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +167,7 @@ const char* GetFileExtension(const char* filename)
|
|||
|
||||
static void UsageAndExit(const char *program)
|
||||
{
|
||||
std::fprintf(stderr, "Usage: %s [-i] [-e] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n", program);
|
||||
std::fprintf(stderr, "Usage: %s [-i] [-e] [-s] SRC_FILE CHARMAP_FILE\nwhere -i denotes if input is from stdin\n -e enables enum handling\n -s enables '.size' handling\n", program);
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
|
@ -158,9 +178,10 @@ int main(int argc, char **argv)
|
|||
const char *charmap = NULL;
|
||||
bool isStdin = false;
|
||||
bool doEnum = false;
|
||||
bool doSize = false;
|
||||
|
||||
/* preproc [-i] [-e] SRC_FILE CHARMAP_FILE */
|
||||
while ((opt = getopt(argc, argv, "ie")) != -1)
|
||||
/* preproc [-i] [-e] [-s] SRC_FILE CHARMAP_FILE */
|
||||
while ((opt = getopt(argc, argv, "ies")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
|
|
@ -170,6 +191,9 @@ int main(int argc, char **argv)
|
|||
case 'e':
|
||||
doEnum = true;
|
||||
break;
|
||||
case 's':
|
||||
doSize = true;
|
||||
break;
|
||||
default:
|
||||
UsageAndExit(argv[0]);
|
||||
break;
|
||||
|
|
@ -196,7 +220,7 @@ int main(int argc, char **argv)
|
|||
|
||||
if ((extension[0] == 's') && extension[1] == 0)
|
||||
{
|
||||
PreprocAsmFile(source, isStdin, doEnum);
|
||||
PreprocAsmFile(source, isStdin, doEnum, doSize);
|
||||
}
|
||||
else if ((extension[0] == 'c' || extension[0] == 'i') && extension[1] == 0)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user