Skip to content

Commit 673d9ee

Browse files
committed
implement .definedatalabel, .definearmlabel, and .definethumblabel directives
1 parent 7cd5391 commit 673d9ee

6 files changed

Lines changed: 57 additions & 10 deletions

File tree

Archs/ARM/ArmParser.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ std::unique_ptr<CAssemblerCommand> parseDirectivePool(Parser& parser, int flags)
5656
return seq;
5757
}
5858

59+
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineArmLabel(Parser& parser, int flags)
60+
{
61+
return parseDirectiveDefineLabel(parser, flags, false);
62+
}
63+
64+
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineThumbLabel(Parser& parser, int flags)
65+
{
66+
return parseDirectiveDefineLabel(parser, flags, true);
67+
}
68+
5969
const char* msgTemplate = R"(
6070
mov r12,r12
6171
b %after%
@@ -89,6 +99,8 @@ const DirectiveMap armDirectives = {
8999
{ ".arm", { &parseDirectiveArm, 0 } },
90100
{ ".pool", { &parseDirectivePool, 0 } },
91101
{ ".msg", { &parseDirectiveMsg, 0 } },
102+
{ ".definearmlabel", { &parseDirectiveDefineArmLabel, 0 } },
103+
{ ".definethumblabel", { &parseDirectiveDefineThumbLabel, 0 } },
92104
};
93105

94106
std::unique_ptr<CAssemblerCommand> ArmParser::parseDirective(Parser& parser)

Commands/CAssemblerLabel.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include "Core/SymbolData.h"
88
#include "Util/Util.h"
99

10-
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName)
10+
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, std::optional<bool> thumbMode)
1111
{
1212
this->defined = false;
1313
this->label = nullptr;
@@ -27,15 +27,15 @@ CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& origi
2727
// does this need to be in validate?
2828
if (label->getUpdateInfo())
2929
{
30-
if (&Architecture::current() == &Arm && Arm.GetThumbMode())
31-
label->setInfo(1);
32-
else
30+
if (&Architecture::current() != &Arm)
3331
label->setInfo(0);
32+
else
33+
label->setInfo(thumbMode.value_or(Arm.GetThumbMode()));
3434
}
3535
}
3636

37-
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value)
38-
: CAssemblerLabel(name,originalName)
37+
CAssemblerLabel::CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value, std::optional<bool> thumbMode)
38+
: CAssemblerLabel(name,originalName,thumbMode)
3939
{
4040
labelValue = value;
4141
}

Commands/CAssemblerLabel.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
#include "Core/Expression.h"
55
#include "Core/Types.h"
66

7+
#include <optional>
8+
79
class Label;
810

911
class CAssemblerLabel: public CAssemblerCommand
1012
{
1113
public:
12-
CAssemblerLabel(const Identifier& name, const Identifier& originalName);
13-
CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value);
14+
CAssemblerLabel(const Identifier& name, const Identifier& originalName, std::optional<bool> thumbMode = std::nullopt);
15+
CAssemblerLabel(const Identifier& name, const Identifier& originalName, Expression& value, std::optional<bool> thumbMode = std::nullopt);
1416
bool Validate(const ValidateState &state) override;
1517
void Encode() const override;
1618
void writeTempData(TempData& tempData) const override;

Parser/DirectivesParser.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <algorithm>
2323
#include <initializer_list>
24+
#include <optional>
2425

2526
std::unique_ptr<CAssemblerCommand> parseDirectiveOpen(Parser& parser, int flags)
2627
{
@@ -618,7 +619,7 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveSym(Parser& parser, int flags)
618619
return nullptr;
619620
}
620621

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

641-
return std::make_unique<CAssemblerLabel>(identifier,Identifier(tok.getOriginalText()),value);
642+
return std::make_unique<CAssemblerLabel>(identifier,Identifier(tok.getOriginalText()),value,thumbMode);
643+
}
644+
645+
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags)
646+
{
647+
return parseDirectiveDefineLabel(parser, flags, std::nullopt);
648+
}
649+
650+
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineDataLabel(Parser& parser, int flags)
651+
{
652+
return parseDirectiveDefineLabel(parser, flags, false);
642653
}
643654

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

834845
{ ".definelabel", { &parseDirectiveDefineLabel, 0 } },
846+
{ ".definedatalabel", { &parseDirectiveDefineDataLabel, 0 } },
835847
{ ".function", { &parseDirectiveFunction, DIRECTIVE_MANUALSEPARATOR } },
836848
{ ".func", { &parseDirectiveFunction, DIRECTIVE_MANUALSEPARATOR } },
837849

Parser/DirectivesParser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <memory>
44
#include <string>
55
#include <unordered_map>
6+
#include <optional>
67

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

8081
extern const DirectiveMap directives;
82+
83+
std::unique_ptr<CAssemblerCommand> parseDirectiveDefineLabel(Parser& parser, int flags, std::optional<bool> thumbMode);

Readme.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,13 @@ Defines `Label` with a given value, creating a symbol for it. This can be used s
765765

766766
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.
767767

768+
769+
```
770+
.definedatalabel Label,value
771+
```
772+
773+
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).
774+
768775
### Function labels
769776

770777
```
@@ -895,6 +902,17 @@ ldr r0,=0xFFEEDDCC
895902

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

905+
### Define labels
906+
907+
```
908+
.definearmlabel Label,value
909+
.definethumblabel Label,value
910+
```
911+
912+
Identical to `.definelabel`, but explicitly createy an ARM or THUMB label regardless of the current mode.
913+
914+
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.
915+
898916
# 6. Macros
899917

900918
## 6.1 Assembler-defined MIPS macros

0 commit comments

Comments
 (0)