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
12 changes: 12 additions & 0 deletions Archs/ARM/ArmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ std::unique_ptr<CAssemblerCommand> parseDirectivePool(Parser& parser, int flags)
return seq;
}

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineArmLabel(Parser& parser, int flags)
{
return parseDirectiveDefineLabel(parser, flags, false);
}

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineThumbLabel(Parser& parser, int flags)
{
return parseDirectiveDefineLabel(parser, flags, true);
}

const char* msgTemplate = R"(
mov r12,r12
b %after%
Expand Down Expand Up @@ -89,6 +99,8 @@ const DirectiveMap armDirectives = {
{ ".arm", { &parseDirectiveArm, 0 } },
{ ".pool", { &parseDirectivePool, 0 } },
{ ".msg", { &parseDirectiveMsg, 0 } },
{ ".definearmlabel", { &parseDirectiveDefineArmLabel, 0 } },
{ ".definethumblabel", { &parseDirectiveDefineThumbLabel, 0 } },
};

std::unique_ptr<CAssemblerCommand> ArmParser::parseDirective(Parser& parser)
Expand Down
12 changes: 6 additions & 6 deletions Commands/CAssemblerLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include "Core/SymbolData.h"
#include "Util/Util.h"

CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName)
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, std::optional<bool> thumbMode)
{
this->defined = false;
this->label = nullptr;
Expand All @@ -27,15 +27,15 @@ CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& origi
// does this need to be in validate?
if (label->getUpdateInfo())
{
if (&Architecture::current() == &Arm && Arm.GetThumbMode())
label->setInfo(1);
else
if (&Architecture::current() != &Arm)
label->setInfo(0);
else
label->setInfo(thumbMode.value_or(Arm.GetThumbMode()));
}
}

CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value)
: CAssemblerLabel(name,originalName)
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value, std::optional<bool> thumbMode)
: CAssemblerLabel(name,originalName,thumbMode)
{
labelValue = value;
}
Expand Down
6 changes: 4 additions & 2 deletions Commands/CAssemblerLabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
#include "Core/Expression.h"
#include "Core/Types.h"

#include <optional>

class Label;

class CAssemblerLabel: public CAssemblerCommand
{
public:
CAssemblerLabel(const Identifier& name, const Identifier& originalName);
CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value);
CAssemblerLabel(const Identifier& name, const Identifier& originalName, std::optional<bool> thumbMode = std::nullopt);
CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value, std::optional<bool> thumbMode = std::nullopt);
bool Validate(const ValidateState &state) override;
void Encode() const override;
void writeTempData(TempData& tempData) const override;
Expand Down
16 changes: 14 additions & 2 deletions Parser/DirectivesParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <algorithm>
#include <initializer_list>
#include <optional>

std::unique_ptr<CAssemblerCommand> parseDirectiveOpen(Parser& parser, int flags)
{
Expand Down Expand Up @@ -618,7 +619,7 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveSym(Parser& parser, int flags)
return nullptr;
}

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags)
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags, std::optional<bool> thumbMode)
{
const Token& tok = parser.nextToken();
if (tok.type != TokenType::Identifier)
Expand All @@ -638,7 +639,17 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int
return nullptr;
}

return std::make_unique<CAssemblerLabel>(identifier,Identifier(tok.getOriginalText()),value);
return std::make_unique<CAssemblerLabel>(identifier,Identifier(tok.getOriginalText()),value,thumbMode);
}

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags)
{
return parseDirectiveDefineLabel(parser, flags, std::nullopt);
}

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineDataLabel(Parser& parser, int flags)
{
return parseDirectiveDefineLabel(parser, flags, false);
}

std::unique_ptr<CAssemblerCommand> parseDirectiveFunction(Parser& parser, int flags)
Expand Down Expand Up @@ -832,6 +843,7 @@ const DirectiveMap directives = {
{ ".sym", { &parseDirectiveSym, 0 } },

{ ".definelabel", { &parseDirectiveDefineLabel, 0 } },
{ ".definedatalabel", { &parseDirectiveDefineDataLabel, 0 } },
{ ".function", { &parseDirectiveFunction, DIRECTIVE_MANUALSEPARATOR } },
{ ".func", { &parseDirectiveFunction, DIRECTIVE_MANUALSEPARATOR } },

Expand Down
3 changes: 3 additions & 0 deletions Parser/DirectivesParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <memory>
#include <string>
#include <unordered_map>
#include <optional>

class CAssemblerCommand;
class Parser;
Expand Down Expand Up @@ -78,3 +79,5 @@ using DirectiveMap = std::unordered_multimap<std::string, const DirectiveEntry>;
#define DIRECTIVE_AREA_SHARED 0x00000001

extern const DirectiveMap directives;

std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags, std::optional<bool> thumbMode);
18 changes: 18 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,13 @@ Defines `Label` with a given value, creating a symbol for it. This can be used s

Unlike `Label:`, note that `.definelabel Label,value` is evaluated only once, thus using any expressions that refer to the current state of the assembler (e.g. `org()`, `.`) in combination with `.definelabel` leads to undefined behavior.


```
.definedatalabel Label,value
```

For architectures other than ARM, this works identically to `.definelabel`, however it can be used to essentially document your intent that the symbol doesn't refer to code. Under ARM architecture, it works identically to `.definearmlabel` (see below).

### Function labels

```
Expand Down Expand Up @@ -895,6 +902,17 @@ ldr r0,=0xFFEEDDCC

Inserts a no$gba debug message as described by GBATEK.

### Define labels

```
.definearmlabel Label,value
.definethumblabel Label,value
```

Identical to `.definelabel`, but explicitly creates an ARM or THUMB label regardless of the current mode.

Only relevant when linking external code through `.importobj`. ARM uses the least significant bit in addresses to signify whether the code at the target address is using ARM or THUMB mode when setting the program counter through instructions such as `bl` or `blx`. armips automatically remembers the current mode when labels are defined, but this mode may be incorrect when using `.definelabel`. Note that using `.definethumblabel` for data may result in incorrect addresses.

# 6. Macros

## 6.1 Assembler-defined MIPS macros
Expand Down