From 390f49ba23a8dea54e05b5610d4bae0a0611da0e Mon Sep 17 00:00:00 2001 From: Rangi42 Date: Wed, 25 Oct 2023 20:39:48 -0400 Subject: [PATCH] [in progress] Implement `ds align[]` --- include/asm/lexer.h | 6 ++++++ src/asm/parser.y | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/asm/lexer.h b/include/asm/lexer.h index 91bb0a8ec6..239b3e4f0a 100644 --- a/include/asm/lexer.h +++ b/include/asm/lexer.h @@ -90,6 +90,12 @@ int yylex(void); bool lexer_CaptureRept(struct CaptureBody *capture); bool lexer_CaptureMacroBody(struct CaptureBody *capture); +struct DsAlignment { + uint32_t nbBytes; + uint8_t alignment; + uint16_t alignOfs; +}; + #define INITIAL_DS_ARG_SIZE 2 struct DsArgList { size_t nbArgs; diff --git a/src/asm/parser.y b/src/asm/parser.y index 89d6164a1c..737f8ff35d 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -509,6 +509,7 @@ enum { struct SectionSpec sectSpec; struct MacroArgs *macroArg; enum AssertionType assertType; + struct DsAlignment dsAlign; struct DsArgList dsArgs; struct PurgeArgList purgeArgs; struct { @@ -664,6 +665,7 @@ enum { %type sectmod %type macroargs +%type ds_align %type ds_args %type purge_args @@ -1169,6 +1171,40 @@ ds : T_POP_DS uconst { sect_Skip($2, true); } sect_RelBytes($2, $4.args, $4.nbArgs); freeDsArgList(&$4); } + | T_POP_DS ds_align trailing_comma { + sect_Skip($2.nbBytes, true); + sect_AlignPC($2.alignment, $2.alignOfs); + } + | T_POP_DS ds_align T_COMMA ds_args trailing_comma { + sect_RelBytes($2.nbBytes, $4.args, $4.nbArgs); + sect_AlignPC($2.alignment, $2.alignOfs); + freeDsArgList(&$4); + } +; + +ds_align : T_OP_ALIGN T_LBRACK uconst T_RBRACK { + if ($3 > 16) { + error("Alignment must be between 0 and 16, not %u\n", $3); + } else { + uint32_t mask = (1 << $3) - 1; + + // TODO: correct formula; sym_GetPCValue() won't work in floating sections + $$.alignment = $3; + $$.nbBytes = (mask + 1 - (sym_GetPCValue() & mask)) & mask; + } + } + | T_OP_ALIGN T_LBRACK uconst T_COMMA uconst T_RBRACK { + if ($3 > 16) { + error("Alignment must be between 0 and 16, not %u\n", $3); + } else if ($5 >= 1 << $3) { + error("Offset must be between 0 and %u, not %u\n", + (1 << $3) - 1, $5); + } else { + $$.alignment = $3; + $$.alignOfs = $5; + $$.nbBytes = 0; // TODO: correct formula + } + } ; ds_args : reloc_8bit {