ref: 665412c07352379651334fc59cb75a6661242a35
parent: 2b0c34ecb57e0187541b327020d09f41370cfe54
author: ISSOtm <[email protected]>
date: Wed Apr 8 08:28:53 EDT 2020
Implement mid-section alignment directive Fixes #254.
--- a/include/asm/section.h
+++ b/include/asm/section.h
@@ -44,6 +44,7 @@
struct Section *sect_GetSymbolSection(void);
uint32_t sect_GetOutputOffset(void);
+void sect_AlignPC(uint8_t alignment, uint16_t offset);
void out_AbsByte(uint8_t b);
void out_AbsByteGroup(uint8_t const *s, int32_t length);
--- a/src/asm/asmy.y
+++ b/src/asm/asmy.y
@@ -774,6 +774,26 @@
| popo
| pusho
| 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 {
--- a/src/asm/section.c
+++ b/src/asm/section.c
@@ -354,6 +354,28 @@
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)
{
curOffset += growth;
--- /dev/null
+++ b/test/asm/align-pc.asm
@@ -1,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...