Skip to content
Permalink
Browse files

Merge pull request #152 from Prof9/align-file

Add .aligna directive for aligning file address (as opposed to memory address)
  • Loading branch information...
Kingcom committed Jun 21, 2019
2 parents ceba062 + 8260786 commit bc6b4620d3a04178854c536fef6fea4c2720a722
@@ -46,7 +46,7 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveArm(Parser& parser, int flags)
std::unique_ptr<CAssemblerCommand> parseDirectivePool(Parser& parser, int flags)
{
auto seq = make_unique<CommandSequence>();
seq->addCommand(make_unique<CDirectiveAlignFill>(4,CDirectiveAlignFill::Align));
seq->addCommand(make_unique<CDirectiveAlignFill>(4,CDirectiveAlignFill::AlignVirtual));
seq->addCommand(make_unique<ArmPoolCommand>());

return std::move(seq);
@@ -320,20 +320,24 @@ bool CDirectiveAlignFill::Validate()
}
}

if (mode != Fill && isPowerOfTwo(value) == false)
{
Logger::queueError(Logger::Error, L"Invalid alignment %d", value);
return false;
}

int64_t oldSize = finalSize;
int64_t mod;
switch (mode)
{
case Align:
if (isPowerOfTwo(value) == false)
{
Logger::queueError(Logger::Error,L"Invalid alignment %d",value);
return false;
}

case AlignVirtual:
mod = g_fileManager->getVirtualAddress() % value;
finalSize = mod ? value-mod : 0;
break;
case AlignPhysical:
mod = g_fileManager->getPhysicalAddress() % value;
finalSize = mod ? value-mod : 0;
break;
case Fill:
finalSize = value;
break;
@@ -375,9 +379,12 @@ void CDirectiveAlignFill::writeTempData(TempData& tempData) const
{
switch (mode)
{
case Align:
case AlignVirtual:
tempData.writeLine(virtualAddress,formatString(L".align 0x%08X",value));
break;
case AlignPhysical:
tempData.writeLine(virtualAddress, formatString(L".aligna 0x%08X", value));
break;
case Fill:
tempData.writeLine(virtualAddress,formatString(L".fill 0x%08X,0x%02X",value,fillByte));
break;
@@ -388,7 +395,8 @@ void CDirectiveAlignFill::writeSymData(SymbolData& symData) const
{
switch (mode)
{
case Align: // ?
case AlignVirtual: // ?
case AlignPhysical: // ?
break;
case Fill:
symData.addData(virtualAddress,value,SymbolData::Data8);
@@ -69,7 +69,7 @@ class CDirectiveIncbin: public CAssemblerCommand
class CDirectiveAlignFill: public CAssemblerCommand
{
public:
enum Mode { Align, Fill };
enum Mode { AlignPhysical, AlignVirtual, Fill };

CDirectiveAlignFill(int64_t value, Mode mode);
CDirectiveAlignFill(Expression& value, Mode mode);
@@ -122,17 +122,20 @@ std::unique_ptr<CAssemblerCommand> parseDirectiveAlignFill(Parser& parser, int f
CDirectiveAlignFill::Mode mode;
switch (flags & DIRECTIVE_USERMASK)
{
case DIRECTIVE_FILE_ALIGN:
mode = CDirectiveAlignFill::Align;
case DIRECTIVE_ALIGN_VIRTUAL:
mode = CDirectiveAlignFill::AlignVirtual;
break;
case DIRECTIVE_FILE_FILL:
case DIRECTIVE_ALIGN_PHYSICAL:
mode = CDirectiveAlignFill::AlignPhysical;
break;
case DIRECTIVE_ALIGN_FILL:
mode = CDirectiveAlignFill::Fill;
break;
default:
return nullptr;
}

if (mode == CDirectiveAlignFill::Align && parser.peekToken().type == TokenType::Separator)
if (mode != CDirectiveAlignFill::Fill && parser.peekToken().type == TokenType::Separator)
return make_unique<CDirectiveAlignFill>(UINT64_C(4),mode);

std::vector<Expression> list;
@@ -674,9 +677,10 @@ const DirectiveMap directives = {
{ L".orga", { &parseDirectivePosition, DIRECTIVE_POS_PHYSICAL } },
{ L"orga", { &parseDirectivePosition, DIRECTIVE_POS_PHYSICAL } },
{ L".headersize", { &parseDirectiveHeaderSize, 0 } },
{ L".align", { &parseDirectiveAlignFill, DIRECTIVE_FILE_ALIGN } },
{ L".fill", { &parseDirectiveAlignFill, DIRECTIVE_FILE_FILL } },
{ L"defs", { &parseDirectiveAlignFill, DIRECTIVE_FILE_FILL } },
{ L".align", { &parseDirectiveAlignFill, DIRECTIVE_ALIGN_VIRTUAL } },
{ L".aligna", { &parseDirectiveAlignFill, DIRECTIVE_ALIGN_PHYSICAL } },
{ L".fill", { &parseDirectiveAlignFill, DIRECTIVE_ALIGN_FILL } },
{ L"defs", { &parseDirectiveAlignFill, DIRECTIVE_ALIGN_FILL } },
{ L".skip", { &parseDirectiveSkip, 0 } },

{ L".if", { &parseDirectiveConditional, DIRECTIVE_COND_IF } },
@@ -27,8 +27,9 @@ using DirectiveMap = std::unordered_multimap<std::wstring, const DirectiveEntry>
// file directive flags
#define DIRECTIVE_POS_PHYSICAL 0x00000001
#define DIRECTIVE_POS_VIRTUAL 0x00000002
#define DIRECTIVE_FILE_ALIGN 0x00000001
#define DIRECTIVE_FILE_FILL 0x00000002
#define DIRECTIVE_ALIGN_PHYSICAL 0x00000001
#define DIRECTIVE_ALIGN_VIRTUAL 0x00000002
#define DIRECTIVE_ALIGN_FILL 0x00000004

// conditional directive flags
#define DIRECTIVE_COND_IF 0x00000001
@@ -470,10 +470,11 @@ The following values are supported:
### Align the output position

```
.align [num[,value]]
.align [num[,value]]
.aligna [num[,value]]
```

Writes bytes of `value` into the output file until the memory position is a multiple of `num`. `num` has to be a power of two. If `num` isn't specified, then the alignment will be 4. If `value` isn't specified, zeros are inserted. Only the lowest 8 bits of `value` are inserted.
Writes bytes of `value` into the output file until the memory position is a multiple of `num`. `num` has to be a power of two. If `num` isn't specified, then the alignment will be 4. If `value` isn't specified, zeros are inserted. Only the lowest 8 bits of `value` are inserted. `.align` aligns the memory address (i.e. `org()`), whereas `.aligna` aligns the file address (i.e. `orga()`).

### Fill space with a value

@@ -0,0 +1,11 @@
.gba
.create "output.bin",0

; Invalid align
.align 3
.aligna 3
; But fill works fine
.fill 3, 0x11
.fill 3

.close
@@ -0,0 +1,2 @@
Errors.asm(5) error: Invalid alignment 3
Errors.asm(6) error: Invalid alignment 3
@@ -0,0 +1,34 @@
.gba
.create "output.bin",0

; Align+fill
.db 0x01
.align 2, 0x22 ; 1 byte
.db 0x03
.align 4, 0x44 ; 1 byte
.db 0x05
.align 8, 0x66 ; 3 bytes

; Align where it isn't needed
.align 1, 0x77 ; 0 bytes
.align 2, 0x88 ; 0 bytes
.align 4, 0x99 ; 0 bytes
.align 8, 0xAA ; 0 bytes

; Default align
.db 0xB
.align ; 3 bytes

; Fill
.fill 0x40, 0xCC ; 64 bytes
.fill 0x40 ; 64 bytes

; Align virtual address
.headersize 2
.org 0x80 ; org=0x80, orga=0x7E
.db 0xDD
.align 4, 0xEE ; Produces 3 bytes
; Align physical address
.aligna 4, 0xFF ; org=0x84, orga=0x82, so produces 2 bytes

.close
Binary file not shown.

0 comments on commit bc6b462

Please sign in to comment.
You can’t perform that action at this time.