mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-22 03:02:06 +00:00
@@ -44,6 +44,7 @@ void out_EndLoadSection(void);
|
|||||||
|
|
||||||
struct Section *sect_GetSymbolSection(void);
|
struct Section *sect_GetSymbolSection(void);
|
||||||
uint32_t sect_GetOutputOffset(void);
|
uint32_t sect_GetOutputOffset(void);
|
||||||
|
void sect_AlignPC(uint8_t alignment, uint16_t offset);
|
||||||
|
|
||||||
void out_AbsByte(uint8_t b);
|
void out_AbsByte(uint8_t b);
|
||||||
void out_AbsByteGroup(uint8_t const *s, int32_t length);
|
void out_AbsByteGroup(uint8_t const *s, int32_t length);
|
||||||
|
|||||||
@@ -774,6 +774,26 @@ simple_pseudoop : include
|
|||||||
| popo
|
| popo
|
||||||
| pusho
|
| pusho
|
||||||
| opt
|
| opt
|
||||||
|
| align
|
||||||
|
;
|
||||||
|
|
||||||
|
align : T_OP_ALIGN uconst {
|
||||||
|
if ($2 > 16)
|
||||||
|
yyerror("Alignment must be between 0 and 16, not %u",
|
||||||
|
$2);
|
||||||
|
else
|
||||||
|
sect_AlignPC($2, 0);
|
||||||
|
}
|
||||||
|
| T_OP_ALIGN uconst ',' uconst {
|
||||||
|
if ($2 > 16)
|
||||||
|
yyerror("Alignment must be between 0 and 16, not %u",
|
||||||
|
$2);
|
||||||
|
else if ($4 >= 1 << $2)
|
||||||
|
yyerror("Offset must be between 0 and %u, not %u",
|
||||||
|
(1 << $2) - 1, $4);
|
||||||
|
else
|
||||||
|
sect_AlignPC($2, $4);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt : T_POP_OPT {
|
opt : T_POP_OPT {
|
||||||
|
|||||||
@@ -354,6 +354,28 @@ uint32_t sect_GetOutputOffset(void)
|
|||||||
return curOffset + loadOffset;
|
return curOffset + loadOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sect_AlignPC(uint8_t alignment, uint16_t offset)
|
||||||
|
{
|
||||||
|
struct Section *sect = sect_GetSymbolSection();
|
||||||
|
|
||||||
|
if (sect->nOrg != -1) {
|
||||||
|
if ((sym_GetValue(pPCSymbol) - offset) % (1 << alignment))
|
||||||
|
yyerror("Section's fixed address fails required alignment (PC = $%04x)",
|
||||||
|
sym_GetValue(pPCSymbol));
|
||||||
|
} else if (sect->nAlign != 0) {
|
||||||
|
if ((((sect->alignOfs + curOffset) % (1 << sect->nAlign)) - offset) % (1 << alignment)) {
|
||||||
|
yyerror("Section's alignment fails required alignment (offset from section start = $%04x)",
|
||||||
|
curOffset);
|
||||||
|
} else if (alignment > sect->nAlign) {
|
||||||
|
sect->nAlign = alignment;
|
||||||
|
sect->alignOfs = (offset - curOffset) % (1 << alignment);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sect->nAlign = alignment;
|
||||||
|
sect->alignOfs = offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void growSection(uint32_t growth)
|
static inline void growSection(uint32_t growth)
|
||||||
{
|
{
|
||||||
curOffset += growth;
|
curOffset += growth;
|
||||||
|
|||||||
22
test/asm/align-pc.asm
Normal file
22
test/asm/align-pc.asm
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
SECTION "fixed org", SRAM[$BEAD]
|
||||||
|
ds 42
|
||||||
|
static_assert @ == $BED7
|
||||||
|
align 5,$17
|
||||||
|
|
||||||
|
|
||||||
|
; Should land at $0001
|
||||||
|
SECTION "align", ROM0,ALIGN[1,1]
|
||||||
|
db 69
|
||||||
|
align 1 ; This wants to go at $0000, $0002, $0004...
|
||||||
|
|
||||||
|
|
||||||
|
; Should land at $0003
|
||||||
|
SECTION "under-aligned", ROM0,ALIGN[1,1]
|
||||||
|
dw $BEEF
|
||||||
|
align 2,1 ; This wants to go at $0001, $0005, $0009...
|
||||||
|
|
||||||
|
|
||||||
|
; Should land at $0005
|
||||||
|
SECTION "forced align", ROM0
|
||||||
|
dw $DEAD
|
||||||
|
align 2,3 ; This wants to go at $0003, $0007, $000B...
|
||||||
0
test/asm/align-pc.err
Normal file
0
test/asm/align-pc.err
Normal file
0
test/asm/align-pc.out
Normal file
0
test/asm/align-pc.out
Normal file
0
test/asm/align-pc.out.bin
Normal file
0
test/asm/align-pc.out.bin
Normal file
Reference in New Issue
Block a user