Introducing .align directive, thanks to Bastian Schick for most of the implementation. Also, updated documentation and Windows script

This commit is contained in:
ggn 2022-08-16 09:20:04 +03:00 committed by Shamus Hammons
parent db581e2d9e
commit 253a4352d6
5 changed files with 107 additions and 110 deletions

View File

@ -90,6 +90,7 @@ int d_prgflags(void);
int d_opt(void); int d_opt(void);
int d_dsp(void); int d_dsp(void);
int d_objproc(void); int d_objproc(void);
int d_align(void);
void SetLargestAlignment(int); void SetLargestAlignment(int);
// Directive handler table // Directive handler table
@ -163,6 +164,7 @@ int (*dirtab[])() = {
d_opt, // 66 .opt d_opt, // 66 .opt
d_objproc, // 67 .objproc d_objproc, // 67 .objproc
(void *)d_dsm, // 68 .dsm (void *)d_dsm, // 68 .dsm
d_align // 69 .align
}; };
@ -842,6 +844,48 @@ int d_qphrase(void)
} }
//
// Adjust location to <alignment> bytes
//
int d_align(void)
{
unsigned bytesToSkip;
uint64_t eval;
if (abs_expr(&eval) != OK)
return 0;
if (eval < 2)
{
return error("Invalid .align value specified");
}
if (dsp56001)
{
bytesToSkip = eval - sloc % eval;
D_ZEROFILL(bytesToSkip*3);
return 0;
}
bytesToSkip = eval - (rgpu || rdsp ? orgaddr : sloc) % eval;
if ( bytesToSkip != eval )
{
if ((scattr & SBSS) == 0)
{
D_ZEROFILL(bytesToSkip);
}
else
{
sloc += bytesToSkip;
if (orgactive)
orgaddr += bytesToSkip;
}
}
return 0;
}
// //
// Do auto-even. This must be called ONLY if 'sloc' is odd. // Do auto-even. This must be called ONLY if 'sloc' is odd.
// //

View File

@ -113,6 +113,7 @@ opt 66
.objproc 67 .objproc 67
.dsm 68 .dsm 68
dsm 68 dsm 68
.align 69
.if 500 .if 500
if 500 if 500
.else 501 .else 501

View File

@ -17,12 +17,10 @@ the accuracy of printed or duplicated material after the date of publication and
disclaims liability for changes, errors or omissions.* disclaims liability for changes, errors or omissions.*
*Copyright © 2011-2020, Reboot* *Copyright © 2011-2022, the rmac authors*
*All rights reserved.* *All rights reserved.*
*Reboot Document number F00000K-001 Rev. A.*
Contents Contents
======== ========
@ -158,11 +156,11 @@ Switch Description
+o\ *0-30*/*p* Enable specific optimisation +o\ *0-30*/*p* Enable specific optimisation
~o\ *0-30*/*p* Disable specific optimisation ~o\ *0-30*/*p* Disable specific optimisation
`0: Absolute long adddresses to word (on by default)` `0: Absolute long adddresses to word`
`1: move.l #x,Dn/An to moveq (on by default)` `1: move.l #x,Dn/An to moveq`
`2: Word branches to short (on by default)` `2: Word branches to short`
`3: Outer displacement 0(An) to (An)` `3: Outer displacement 0(An) to (An)`
@ -182,7 +180,7 @@ Switch Description
`11: 56001 Auto convert short addressing mode to long (default: on)` `11: 56001 Auto convert short addressing mode to long (default: on)`
`o30: Enforce PC relative (alternative name: op)` `30: Enforce PC relative (alternative name: op)`
-p Produce an executable (**.prg**) output file. -p Produce an executable (**.prg**) output file.
-ps Produce an executable (**.prg**) output file with symbols. -ps Produce an executable (**.prg**) output file with symbols.
@ -652,7 +650,7 @@ and may not be used as symbols (e.g. labels, equates, or the names of macros):
a0 a1 a2 a3 a4 a5 a6 a7 a0 a1 a2 a3 a4 a5 a6 a7
Tom/Jerry: Tom/Jerry:
r0 r1 r2 r3 r4 r5 r6 r7 r0 r1 r2 r3 r4 r5 r6 r7
r8 r9 r10 r11 r12 rl3 r14 r15 r8 r9 r10 r11 r12 r13 r14 r15
6502: 6502:
x y a x y a
DSP56001: DSP56001:
@ -1037,7 +1035,14 @@ Directives relating to the 6502 are described in the chapter on `6502 Support`_.
Therefore, to align GPU/DSP code, align the current section before and Therefore, to align GPU/DSP code, align the current section before and
after the GPU/DSP code. after the GPU/DSP code.
**.assert** *expression* [,\ *expression*...] **.align** *expression*
A generalised version of the above directives, this will align the program
counter to the boundary of the specified value. Note that there is not much
error checking happening (only values 0 and 1 are rejected). Also note that
in DSP56001 mode the align value is assumed to be in DSP words, i.e. 24 bits.
**.assert** *expression* [,\ *expression*...]
Assert that the conditions are true (non-zero). If any of the comma-seperated Assert that the conditions are true (non-zero). If any of the comma-seperated
expressions evaluates to zero an assembler warning is issued. For example: expressions evaluates to zero an assembler warning is issued. For example:

View File

@ -132,7 +132,7 @@ void date_string(char * buf, uint32_t date)
// //
// Transform letters a-f in the address and data columns of the listing to // Transform letters a-f in the address and data columns of the listing to
// uppercase. (People seem to like uppercase hex better in assembly-language // uppercase. (People seem to like uppercase hex better in assembly-language
// listings....) // listings....)
// //
void uc_ln(char * ln) void uc_ln(char * ln)

View File

@ -1,79 +1,20 @@
@echo off rem @echo off
REM Check for file dates and build .h files if needed rem Check for file dates and build .h files if needed
SET FILE1=68k.mch call :CHECK_OUT_OF_DATE 68k.mch 68ktab.h
SET FILE2=68ktab.h call :CHECK_OUT_OF_DATE direct.tab mntab.h
if not exist %FILE2% GOTO BUILD call :CHECK_OUT_OF_DATE kw.tab kwtab.h
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i call :CHECK_OUT_OF_DATE risc.tab risckw.h
if %NEWEST%==%FILE1% GOTO BUILD call :CHECK_OUT_OF_DATE dsp56k.mch dsp56ktab.h
call :CHECK_OUT_OF_DATE 6502.tab 6502kw.h
call :CHECK_OUT_OF_DATE op.tab opkw.h
call :CHECK_OUT_OF_DATE 68kregs.tab 68kregs.h
call :CHECK_OUT_OF_DATE 56kregs.tab 56kregs.h
call :CHECK_OUT_OF_DATE 6502regs.tab 6502regs.h
call :CHECK_OUT_OF_DATE riscregs.tab riscregs.h
call :CHECK_OUT_OF_DATE unary.tab unarytab.h
SET FILE1=direct.tab GOTO NOGEN
SET FILE2=mntab.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=kw.tab
SET FILE2=kwtab.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=risc.tab
SET FILE2=risckw.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=dsp56k.mch
SET FILE2=dsp56ktab.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=6502.tab
SET FILE2=6502kw.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=op.tab
SET FILE2=opkw.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=68kregs.tab
SET FILE2=68kregs.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=56kregs.tab
SET FILE2=56kregs.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=6502regs.tab
SET FILE2=6502regs.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=riscregs.tab
SET FILE2=riscregs.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
SET FILE1=unary.tab
SET FILE2=unarytab.h
if not exist %FILE2% GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
GOTO END
:BUILD :BUILD
@ -94,7 +35,7 @@ kwgen reg65 <6502regs.tab >6502regs.h
kwgen regrisc <riscregs.tab >riscregs.h kwgen regrisc <riscregs.tab >riscregs.h
kwgen unary <unary.tab >unarytab.h kwgen unary <unary.tab >unarytab.h
rem touch files that include these header files so they'll recompile rem Touch timestamps of files that include these header files so they'll recompile
echo Generating tables... echo Generating tables...
copy /b amode.c +,, >NUL copy /b amode.c +,, >NUL
copy /b direct.c +,, >NUL copy /b direct.c +,, >NUL
@ -104,34 +45,40 @@ copy /b procln.c +,, >NUL
copy /b riscasm.c +,, >NUL copy /b riscasm.c +,, >NUL
copy /b token.c +,, >NUL copy /b token.c +,, >NUL
copy /b dsp56k_mach.c +,, >NUL copy /b dsp56k_mach.c +,, >NUL
:END
REM If eagen0.c is newer than eagen.c then "touch" eagen.c so that visual studio will recompile both.
REM Same for amode.c / parmode.h and mach.c / 68ktab.h
SET FILE1=eagen0.c
SET FILE2=eagen.c
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE2% GOTO CHECK2
Echo touching eagen0.c...
copy /b eagen.c +,, >NUL copy /b eagen.c +,, >NUL
goto :END
:CHECK2 :NOGEN
SET FILE1=parmode.h
SET FILE2=amode.c
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE2% GOTO CHECK3
Echo touching amode.c...
copy /b amode.c +,, >NUL
:CHECK3 REM If eagen0.c is newer than eagen.c then "touch" eagen.c so that visual studio will recompile oth.
SET FILE1=68ktab.h REM Same for amode.c / parmode.h and mach.c / 68ktab.h
SET FILE2=mach.c call :CHECK_AND_TOUCH eagen0.c eagen.c
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i call :CHECK_AND_TOUCH parmode.h amode.c
if %NEWEST%==%FILE2% GOTO END call :CHECK_AND_TOUCH 68ktab.h mach.c
Echo touching mach.c...
copy /b mach.c +,, >NUL
:END :END
exit /b
rem Check if second passed file is older compared to the first, or doesn't exist, or is zero size. In which case go generate everything just to be sure
:CHECK_OUT_OF_DATE
SET FILE1=%1
SET FILE2=%2
if not exist %FILE2% GOTO BUILD
FOR /F "usebackq" %%A IN ('%FILE2%') DO set size=%%~zA
if "%size%"=="0" GOTO BUILD
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE1% GOTO BUILD
exit /b
rem Check if second passed file is older compared to the first, and "touch" the file stamp of hat file if yes
:CHECK_AND_TOUCH
SET FILE1=%1
SET FILE2=%2
for /F %%i IN ('dir /b /OD %FILE1% %FILE2% ^| more +1') DO SET NEWEST=%%i
if %NEWEST%==%FILE2% GOTO :CHECK_AND_TOUCH_END
Echo touching %2...
copy /b %2 +,, >NUL
:CHECK_AND_TOUCH_END
exit /b