From 718de16a582012ae8e98027b86cdba8ebd72d32e Mon Sep 17 00:00:00 2001 From: michael Date: Wed, 9 Sep 1998 00:59:17 +0000 Subject: [PATCH] All switches and directives OK, and Peters changes to unit format --- docs/prog.tex | 706 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 549 insertions(+), 157 deletions(-) diff --git a/docs/prog.tex b/docs/prog.tex index c3470372b4..e9a046d77f 100644 --- a/docs/prog.tex +++ b/docs/prog.tex @@ -23,6 +23,9 @@ \usepackage{html} \latex{\usepackage{multicol}} \latex{\usepackage{fpcman}} +\usepackage{fancyheadings} +\pagestyle{fancy} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} \html{\input{fpc-html.tex}} % define the version number here, and not in the fpc.sty !!! \newcommand{\remark}[1]{\par$\rightarrow$\textbf{#1}\par} @@ -67,12 +70,25 @@ updated. If you find something which isn't correct, or you think something %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \chapter{Compiler directives} \label{ch:CompSwitch} + \fpc supports compiler directives in your source file. They are not the same as Turbo Pascal directives, although some are supported for compatibility. There is a distinction between local and global directives; local directives take effect from the moment they are encountered, global directives have an effect on all of the compiled code. +Many switches have a long form also. If they do, then the name of the +long form is given also. For long switches, the + or - character to switch +the option on or off, may be replaced by \var{ON} or \var{OFF} keywords. + +Thus \verb|{$I+}| is equivalent to \verb|{$IOCHECKS ON}| or +\verb|{$IOCHECKS +}| and +\verb|{$C-}| is equivalent to \verb|{$ASSERTIONS OFF}| or +\verb|{$ASSERTIONS -}| + +The long forms of the switches are the same as their Delphi +counterparts. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Local switches \section{Local directives} @@ -82,6 +98,58 @@ compiler's behaviour from the moment they're encountered until the moment another switch annihilates their behaviour, or the end of the unit or program is reached. +\subsection{\var{\$DEFINE} : Define a symbol} + +The directive +\begin{verbatim} +{$DEFINE name} +\end{verbatim} +defines the symbol \var{name}. This symbol remains defined until the end of +the current module, or until a \var{\$UNDEF name} directive is encountered. + +If \var{name} is already defined, this has no effect. \var{Name} is case +insensitive. + + +\subsection{\var{\$ELSE} : Switch conditional compilation} + +The \var{\{\$ELSE \}} switches between compiling and ignoting the source +text delimited by the preceding \var{\{\$IFxxx\}} and following +\var{\{\$ENDIF\}}. Any text after the \var{ELSE} keyword but before the +brace is ignored: +\begin{verbatim} +{$ELSE some ignored text} +\end{verbatim} +is the same as +\begin{verbatim} +{$ELSE} +\end{verbatim} +This is useful for indication what switch is meant. + +\subsection{\var{\$ENDIF} : End conditional compilation} + +The \var{\{\$ENDIF\}} directive ends the conditional compilation initiated by the +last \var{\{\$IFxxx\}} directive. Any text after the \var{ENDIF} keyword but +before the closing brace is ignored: +\begin{verbatim} +{$ENDIF some ignored text} +\end{verbatim} +is the same as +\begin{verbatim} +{$ENDIF} +\end{verbatim} +This is useful for indication what switch is meant to be ended. + +\subsection{\var{\$ERROR} : Generate error message} + +The following code +\begin{verbatim} +{$ERROR This code is erroneous !} +\end{verbatim} +will display an error message when the compiler encounters it, +and increase the error count of the compiler. +The compiler will continue to compile, but no code will be emitted. + \subsection{\var{\$F} : Far or near functions} This directive is recognized for compatibility with Turbo Pascal. Under the 32-bit programming model, the concept of near and far calls have no meaning, @@ -132,10 +200,103 @@ displayed in that case is: testf.pp(3) Warning: NEAR ignored \end{verbatim} -\subsection{\var{\$I} : Input/Output checking} -The \var{\{\$I-\}} directive tells the compiler not to generate input/output -checking code in your program. If you compile using the \var{-Ci} compiler -switch, the \fpc compiler inserts input/output +\subsection{\var{\$FATAL} : Generate fatal error message} + +The following code +\begin{verbatim} +{$FATAL This code is erroneous !} +\end{verbatim} +will display an error message when the compiler encounters it, and trigger +and increase the error count of the compiler. +The compiler will immediatly stop the compilation process. + + +\subsection{\var{\$H} or \var{\$LONGSTRINGS} : Use AnsiStrings} + +If \var{\{\$LONGSTRINGS ON\}} is specified, the keyword \var{String} (no +length specifier) will be treated as \var{AnsiString}, and the compiler +will treat the corresponding varible as an ansistring, and will +generate corresponding code. + +By default, the use of ansistrings is off, corresponding to \var{\{\$H-\}}. + +This feature is still experimental, and should be used with caution for the +time being. + +\subsection{\var{\$HINT} : Generate hint message} + +If the generation of hints is turned on, through the \var{-vh} command-line +option or the \var{\{\$HINTS ON\}} directive, then +\begin{verbatim} +{$Hint This code should be optimized } +\end{verbatim} +will display a hint message when the compiler encounters it. + +\subsection{\var{\$HINTS} : Emit hints} + +\var{\{\$HINTS ON\}} switches the generation of hints on. +\var{\{\$HINTS OFF\}} switches the generation of hints off. +Contrary to the command-line option \var{-vh} this is a local switch, +this is useful for checking parts of your code. + +\subsection{\var{\$IF} : Start conditional compilation} + +The directive \var{\{\$IF expr\}} will continue the compilation +if the boolean expression \var{expr} evaluates to \var{true}. If the +compilation evaluates to false, then the source are skipped to the first +\var{\{\$ELSE\}} or \var{\{\$ENDIF\}} directive. + +The compiler must be able to evaluate the expression at compile time. +This means that you cannot use variables or constants that are defined in +the source. Macros and symbols may be used, however. + +More information on this can be found in the section about +conditionals. + +\subsection{\var{\$IFDEF} : Start conditional compilation} + +The \var{\{\$IFDEF name\}} will skip the compilation of the text that +follows it if the symbol \var{name} is not defined. If it is defined, then +compilation continues as if the directive wasn't there. + +\subsection{\var{\$IFNDEF} : Start conditional compilation} + +The \var{\{\$IFNDEF name\}} will skip the compilation of the text that +follows it if the symbol \var{name} is defined. If it is not defined, then +compilation continues as if the directive wasn't there. + +\subsection{\var{\$IFOPT} : Start conditional compilation} + +The \var{\{\$IFOPT switch\}} will skip the compilation of the text that +follows it if the switch \var{switch} is currently not in the specified +state. If it is in the specified state, then compilation continues as if the directive +wasn't there. + +As an example: +\begin{verbatim} +{$IFOPT M+} + Writeln ('Compiled with type information'); +{$ENDIF} +\end{verbatim} +Will compile the writeln statement if generation of type information is on. + +\subsection{\var{\$INFO} : Generate info message} + +If the generation of info is turned on, through the \var{-vi} command-line +option, then +\begin{verbatim} +{$INFO This was coded on a rainy day by Bugs Bunny } +\end{verbatim} +will display an info message when the compiler encounters it. + + +\subsection{\var{\$I} or \var{\$IOCHECK} : Input/Output checking} +The \var{\{\$I-\}} or \var{\{\$IOCHECK OFF\}} directive tells the compiler +not to generate input/output checking code in your program. By default, the +compiler does not generate this code, you must switch it on using the +\var{-Ci} command-lne switch. + +If you compile using the \var{-Ci} compiler switch, the \fpc compiler inserts input/output checking code after every input/output call in your program. If an error occurred during input or output, then a run-time error will be generated. Use this switch if you wish to avoid this behavior. @@ -161,10 +322,11 @@ if IOResult<>0 then ... \end{verbatim} -\subsection{\var{\$I} : Include file } -The \var{\{\$I filename\}} directive tells the compiler to read further -statements from the file \var{filename}. The statements read there will be -inserted as if they occurred in the current file. +\subsection{\var{\$I} or \var{\$INCLUDE} : Include file } +The \var{\{\$I filename\}} or \var{\{\$INCLUDE filename\}} directive +tells the compiler to read further statements from the file \var{filename}. +The statements read there will be inserted as if they occurred in the +current file. The compiler will append the \file{.pp} extension to the file if you don't specify an extension yourself. Do not put the filename between quotes, as @@ -178,32 +340,32 @@ a block in one file (with a \var{Begin} keyword) and end it in another (with a \var{End} keyword). The smallest entity in an include file must be a token, i.e. an identifier, keyword or operator. -\subsection{\var{\$L} : Link object file} -The \var{\{\$L filename\}} directive tells the compiler that the file \file{filename} -should be linked to your program. You can only use this directive in a -program. If you do use it in a unit, the compiler will not complain, but -simply ignores the directive. +The compiler will look for the file to include in the following places: -The compiler will {\em not} look for the file in the unit path. -The name will be passed to the linker {\em exactly} as you've typed it. +\begin{enumerate} +\item It will look in the path specified in the incude file name. +\item It will look in the directory where the current source file is. +\item it will look in all directories specified in the include file search +path. +\end{enumerate} +You can add files to the include file search path with the \var{-I} +command-line option. -Since the files name is passed directly to the linker, this means that on -\linux systems, the name is case sensitive, and must be typed exactly as it -appears on your system. +\subsection{\var{\$I} or \var{\$INCLUDE} : Include compiler info} -{\em Remark :} Take care that the object file you're linking is in a -format the linker understands. Which format this is, depends on the platform -you're on. Typing \var{ld} on the command line gives a list of formats -\var{ld} knows about. - -You can pass other files and options to the linker using the \var{-k} -command-line option. You can specify more than one of these options, and -they will be passed to the linker, in the order that you specified them on -the command line, just before the names of the object files that must be -linked. +In this form: +\begin{verbatim} +{$INCLUDE %xxx%} +\end{verbatim} +where \var{xxx} is one of \var{TIME}, \var{DATE}, \var{FPCVERSION} or +\var{FPCTARGET}, will generate a macro with the value of these things. +If \var{xxx} is none of the above, then it is assumed to be the value of +an environment variable. It's value will be fetched. % Assembler type -\subsection{\var{\$I386\_XXX} : Specify assembler format (Intel x86 only)} +\subsection{\var{\$I386\_XXX} : Specify assembler format} +This switch can only be used in the i386 assembler. + This switch informs the compiler what kind of assembler it can expect in an \var{asm} block. The \var{XXX} should be replaced by one of the following: \begin{description} @@ -217,8 +379,74 @@ These switches are local, and retain their value to the end of the unit that is compiled, unless they are replaced by another directive of the same type. The command-line switch that corresponds to this switch is \var{-R}. +\subsection{\var{\$L} or \var{\$LINK} : Link object file} +The \var{\{\$L filename\}} or \var{\{\$LINK filename\}} directive +tells the compiler that the file \file{filename} should be linked to +your program. -\subsection{\var{\$MMX} : MMX support (Intel x86 only)} +the compiler will look for this file in the following way: + +\begin{enumerate} +\item It will look in the path specified in the object file name. +\item It will look in the directory where the current source file is. +\item it will look in all directories specified in the object file search path. +\end{enumerate} +You can add files to the object file search path with the \var{-Fo} +option. + +On \linux systems, the name is case sensitive, and must be typed +exactly as it appears on your system. + +{\em Remark :} Take care that the object file you're linking is in a +format the linker understands. Which format this is, depends on the platform +you're on. Typing \var{ld} on the command line gives a list of formats +\var{ld} knows about. + +You can pass other files and options to the linker using the \var{-k} +command-line option. You can specify more than one of these options, and +they will be passed to the linker, in the order that you specified them on +the command line, just before the names of the object files that must be +linked. + +\subsection{\var{\$LINKLIB} : Link to a library} +The \var{\{\$LINKLIB name\}} will link to a library \file{name}. +This has the effect of passing \var{-lname} to the linker. + +As an example, consider the following unit: +\begin{verbatim} +unit getlen; + +interface +{$LINKLIB c} + +function strlen (P : pchar) : longint;cdecl; + +implementation + +function strlen (P : pchar) : longint;cdecl;external; + +end. +\end{verbatim} +If one would issue the command the command +\begin{verbatim} +ppc386 foo.pp +\end{verbatim} +where foo.pp has the above unit in its \var{uses} clause, +then the compiler would link your program to the c library, by passing the +linker the \var{-lc} option. + +The same effect could be obtained by removing the linklib directive in the +above unit, and specify \var{-k-lc} on the command-line: +\begin{verbatim} +ppc386 -k-lc foo.pp +\end{verbatim} + +\subsection{\var{\$M} or \var{\$TYPEINFO} : Generate type info} + +This switch is recognized for Delphi compatibility only since the generation +of type information isn't fully implemented yet. + +\subsection{\var{\$MMX} : Intel MMX support} As of version 0.9.8, \fpc supports optimization for the \textbf{MMX} Intel processor (see also \ref{ch:MMXSupport}). This optimizes certain code parts for the \textbf{MMX} Intel processor, thus greatly improving speed. The speed is noticed mostly when @@ -260,6 +488,23 @@ end. See, however, the chapter on MMX (\ref{ch:MMXSupport}) for more information on this topic. +\subsection{\var{\$NOTE} : Generate note message} + +If the generation of notes is turned on, through the \var{-vn} command-line +option or the \var{\{\$NOTES ON\}} directive, then +\begin{verbatim} +{$NOTE Ask Santa Claus to look at this code } +\end{verbatim} +will display a note message when the compiler encounters it. + + +\subsection{\var{\$NOTES} : Emit notes} + +\var{\{\$NOTES ON\}} switches the generation of notes on. +\var{\{\$NOTES OFF\}} switches the generation of notes off. + Contrary to the command-line option \var{-vn} this +is a local switch, this is useful for checking parts of your code. + \subsection{\var{\$OUTPUT\_FORMAT} : Specify the output format} \var{\{\$OUTPUT\_FORMAT format\}} has the same functionality as the \var{-A} command-line option : It tells the compiler what kind of object file must be @@ -275,12 +520,123 @@ obj & OMF file.\\ wasm & assembler for the Watcom assembler. \\ \hline \end{FPCltable} -\subsection{\var{\$V} : Var-string checking} +\subsection{\var{\$P} or \var{\$OPENSTRINGS} : Use open strings} -When in the \var{+} state, the compiler checks that strings passed as -parameters are of the same, identical, string type as the declared +This switch is provided for compatibility only, as open strings aren't +implemented yet. + +\subsection{\var{\$PACKENUM} : Minimum enumeration type size} + +This directive tells the compiler the minimum number of bytes it should +use when storing enumerated types. It is of the following form: +\begin{verbatim} +{$PACKENUM xxx} +{$MINENUMSIZE xxx} +\end{verbatim} +Where the form with \var{\$MINENUMSIZE} is for Delphi compatibility. +var{xxx} can be one of \var{1,2} or \var{4}, or \var{NORMAL} or +\var{DEFAULT}, corresponding to the default value of 4. + + +As an alternative form one can use \var{\{\$Z1\}}, \var{\{\$Z2\}} +\var{\{\$Z4\}}. Contrary to Delphi, the default size is 4 bytes +(\var{\{\$Z4\}}). + +So the follwoing code +\begin{verbatim} +{$PACKENUM 1} +Type + Days = (monday, tuesday, wednesday, thursday, friday, + saturday, sunday); +\end{verbatim} +will use 1 byte to store a variable of type \var{Days}, wheras it nomally +would use 4 bytes. The above code is equivalent to +\begin{verbatim} +{$Z1} +Type + Days = (monday, tuesday, wednesday, thursday, friday, + saturday, sunday); +\end{verbatim} + +\subsection{\var{\$PACKRECORDS} : Alignment of record elements} + +This directive controls the byte alignment of the elements in a record, +object or class type definition. + +It is of the following form: +\begin{verbatim} +{$PACKRECORDS xx} +\end{verbatim} + +Where \var{xxx} is one of 1,2,4,16 or \var{NORMAL} or \var{DEFAULT}. +This means that the elements of a record will be aligned on 1,2, 4 or +16 byte boundaries. Thus, the size of a record will always be a multiple of +the alignment size. +The default alignment (which can be selected with \var{DEFAULT}) is 2, +contrary to Turbo Pascal, where it is 1. + +More information of this can be found in the reference guide, in the section +about record types. + +\subsection{\var{\$STOP} : Generate fatal error message} + +The following code +\begin{verbatim} +{$STOP This code is erroneous !} +\end{verbatim} +will display an error message when the compiler encounters it. +The compiler will immediatly stop the compilation process. + +It has the same effect as the \var{\{\$FATAL\}} directive. + + +\subsection{\var{\$UNDEF} : Undefine a symbol} + +The directive +\begin{verbatim} +{$UNDEF name} +\end{verbatim} +un-defines the symbol \var{name} if it was previously defined. +\var{Name} is case insensitive. + + +\subsection{\var{\$V} or \var{\$VARSTRINGCHECKS} : Var-string checking} + +When in the \var{+} or \var{ON} state, the compiler checks that strings +passed as parameters are of the same, identical, string type as the declared parameters of the procedure. +\subsection{\var{\$WAIT} : Wait for enter key press} + +If the compiler encaounters a +\begin{verbatim} +{$WAIT } +\end{verbatim} +directive, it will resume compiling only after the user has pressed the +enter key. If the generation of info messages is turned on, then the compiler +will display the follwing message: +\begin{verbatim} +Press to continue +\end{verbatim} +before waiting for a keypress. Careful ! this may interfere with automatic +compilation processes. It should be used for debuggig purposes only. + +\subsection{\var{\$WARNING} : Generate warning message} + +If the generation of warnings is turned on, through the \var{-vw} +command-line option or the \var{\{\$WARNINGS ON\}} directive, then +\begin{verbatim} +{$WARNING This is dubious code } +\end{verbatim} +will display a warning message when the compiler encounters it. + +\subsection{\var{\$WARNINGS} : Emit warnings} + +\var{\{\$WARNINGS ON\}} switches the generation of warnings on. +\var{\{\$WARNINGS OFF\}} switches the generation of warnings off. +Contrary to the command-line option \var{-vw} this +is a local switch, this is useful for checking parts of your code. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Global switches \section{Global directives} @@ -289,13 +645,13 @@ Global directives affect the whole of the compilation process. That is why they also have a command - line counterpart. The command-line counterpart is given for each of the directives. -\subsection{\var{\$A} : Align Data} +\subsection{\var{\$A} or \var{\$ALIGN}: Align Data} This switch is recognized for Turbo Pascal Compatibility, but is not yet implemented. The alignment of data will be different in any case, since \fpc is a 32-bit compiler. -\subsection{\var{\$B} : Complete boolean evaluation} +\subsection{\var{\$B} or \var{\$BOOLEVAL}: Complete boolean evaluation} This switch is understood by the \fpc compiler, but is ignored. The compiler always uses shortcut evaluation, i.e. the evaluation of a boolean expression @@ -308,9 +664,10 @@ If False and Bofu then ... \end{verbatim} -\subsection{\var{\$D} : Debugging symbols} +\subsection{\var{\$D} or \var{\$DEBUGINFO}: Debugging symbols} -When this switch is on, the compiler inserts GNU debugging information in +When this switch is on (\var{\{\$DEBUGINFO ON\}}), +the compiler inserts GNU debugging information in the executable. The effect of this switch is the same as the command-line switch \var{-g}. By default, insertion of debugging information is off. @@ -352,12 +709,25 @@ long as the only type used is single or real. This option is recognised for Turbo Pascal compatibility, but is ignored, -\subsection{\var{\$L} : Local symbol information} +\subsection{\var{\$L} or \var{\$LOCALSYMBOLS}: Local symbol information} This switch (not to be confused with the \var{\{\$L file\}} file linking directive) is recognised for Turbo Pascal compatibility, but is ignored. generation of symbol information is controlled by the \var{\$D} switch. +\subsection{\var{\$M} or \var{\$MEMORY}: Memory sizes} + +This switch can be used to set the heap and stacksize. It's format is as +follows: +\begin{verbatim} +{$M StackSize,HeapSize} +\end{verbatim} +Wher \var{StackSize} and \var{HeapSize} should be two integer values, +greater than 1024. The first number sets the size of the stack, and the +second the size of the heap. (Stack setting is ignored under \linux). +The two numbers can be set on the command line using the \var{-Ch} +(and \var{-Cs} switches. + \subsection{\var{\$N} : Numeric processing } This switch is recognised for Turbo Pascal compatibility, but is otherwise @@ -369,10 +739,10 @@ mathematics. This switch is recognised for Turbo Pascal compatibility, but is otherwise ignored. -\subsection{\var{\$Q} : Overflow checking} -The \var{\{\$Q+\}} directive turns on integer overflow checking. -This means that the compiler inserts code to check for overflow when doing -computations with an integer. +\subsection{\var{\$Q} \var{\$OVERFLOWCHECKS}: Overflow checking} +The \var{\{\$Q+\}} or \var{\{\$OVERFLOWCHECKS ON\}} directive turns on +integer overflow checking. This means that the compiler inserts code +to check for overflow when doing computations with integers. When an overflow occurs, the run-time library will print a message \var{Overflow at xxx}, and exit the program with exit code 215. @@ -388,7 +758,7 @@ generation. The generation of overflow checking code can also be controlled using the \var{-Co} command line compiler option (see \userref). -\subsection{\var{\$R} : Range checking} +\subsection{\var{\$R} or \var{\$RANGECHECKS} : Range checking} By default, the computer doesn't generate code to check the ranges of array indices, enumeration types, subrange types, etc. Specifying the \var{\{\$R+\}} switch tells the computer to generate code to check these @@ -396,7 +766,7 @@ indices. If, at run-time, an index or enumeration type is specified that is out of the declared range of the compiler, then a run-time error is generated, and the program exits with exit code 201. -The \var{\{\$R-\}} switch tells the compiler not to generate range checking +The \var{\{\$RANGECHECKS OFF\}} switch tells the compiler not to generate range checking code. This may result in faulty program behaviour, but no run-time errors will be generated. @@ -415,11 +785,19 @@ Specifying \var{\{\$S-\}} will turn generation of stack-checking code off. The command-line compiler switch \var{-Ct} has the same effect as the \var{\{\$S+\}} directive. +\subsection{\var{\$T} or \var{\$TYPEDADDRESS} : Typed address operator (@)} -\subsection{\var{\$X} : Extended syntax} +In the \var{\{\$T+\}} or \var{\{\$TYPEDADDRESS ON\}} state the @ operator, +when applied to a variable, returns a result of type \var{\^{}T}, if the +type of the variable is \var{T}. In the \var{\{\$T-\}} state, the result is +always an untyped pointer, which is assignment compatible with all other +pointer types. + +\subsection{\var{\$X} or \var{\$EXTENDEDSYNTAX} : Extended syntax} Extended syntax allows you to drop the result of a function. This means that you can use a function call as if it were a procedure. Standard this feature -is on. You can switch it off using the \var{\{\$X-\}} directive. +is on. You can switch it off using the \var{\{\$X-\}} or +\var{\{\$EXTENDEDSYNTAX OFF\}}directive. The following, for instance, will not compile : \begin{verbatim} @@ -441,6 +819,12 @@ you an extra variable. The command-line compiler switch \var{-Sa1} has the same effect as the \var{\{\$X+\}} directive. +\subsection{\var{\$Y} or \var{\$REFERENCEINFO} : Insert Browser information} + +This switch controls the generation of browser inforation. It is recognized +for compatibility with Turbo Pascal and Delphi only, as Browser information +generation is not yet fully supported. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Using conditionals and macros @@ -840,10 +1224,12 @@ some substantial differences, as will be explained in the following. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Intel syntax -\section{Intel syntax (Intel x86 only) } +\section{Intel syntax} \label{se:Intel} -As of version 0.9.7, \fpc supports Intel syntax in it's \var{asm} blocks. +As of version 0.9.7, \fpc supports Intel syntax for the Intel family of Ix86 +processors in it's \var{asm} blocks. + The Intel syntax in your \var{asm} block is converted to AT\&T syntax by the compiler, after which it is inserted in the compiled source. The supported assembler constructs are a subset of the normal assembly @@ -979,9 +1365,10 @@ The Intel inline assembler supports the following macros : %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % AT&T syntax -\section{AT\&T Syntax (Intel x86 only) } +\section{AT\&T Syntax} \label{se:AttSyntax} -\fpc uses the \gnu \var{as} assembler to generate its object files. Since +\fpc uses the \gnu \var{as} assembler to generate its object files for +the Intel Ix86 processors . Since the \gnu assembler uses AT\&T assembly syntax, the code you write should use the same syntax. The differences between AT\&T and Intel syntax as used in Turbo Pascal are summarized in the following: @@ -1136,9 +1523,7 @@ popstack & Right-to-left & Caller & No \\ \hline More about this can be found in \seec{Linking} on linking. - - -\subsection{ Intel x86 calling conventions } +\subsection{ Ix86 calling conventions } Standard entry code for procedures and functions is as follows on the x86 architecture: @@ -1159,7 +1544,7 @@ To have more information on function return values take a look at the \seec{RegConvs} section. -\subsection{ Motorola 680x0 calling conventions } +\subsection{ M680x0 calling conventions } Standard entry code for procedures and functions is as follows on the 680x0 architecture: @@ -1185,7 +1570,7 @@ To have more information on function return values take a look at the %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Telling the compiler what registers have changed -\section{Telling the compiler what registers have changed} +\section{Signalling changed registers} \label{se:RegChanges} When the compiler uses variables, it sometimes stores them, or the result of some calculations, in the processor registers. If you insert assembler code @@ -1343,7 +1728,7 @@ However, the \var{[ C ]} directive is no longer supoerted as of version %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Linking an object file in your program -\section{Explicitly linking an object file in your program} +\section{Linking to an object file} \label{se:LinkIn} Having declared the external function that resides in an object file, @@ -1412,8 +1797,9 @@ and your Pascal program in \file{fibo.pp}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Linking your program to a library -\section{Linking your program to a library} +\section{Linking to a library} \label{se:LinkOut} + To link your program to a library, the procedure depends on how you declared the external procedure. If you used thediffers a little from the procedure when you link in an object file. although the declaration step @@ -1757,7 +2143,7 @@ set up the stack. Then it calls the main program. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % MMX Support %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\chapter{MMX support (Intel x86 only) } +\chapter{Intel MMX support} \label{ch:MMXSupport} \section{What is it about ?} @@ -2183,7 +2569,7 @@ ReleaseTempHeap; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Accessing DOS memory under the GO32 extender -\section{Accessing \dos memory under the Go32 extender (Intel x86 only) } +\section{using \dos memory under the Go32 extender} \label{se:AccessingDosMemory} Because \fpc is a 32 bit compiler, and uses a \dos extender, accessing DOS @@ -2587,6 +2973,8 @@ set in the unit flags implementation part. \end{enumerate} +\section{reading ppufiles} + We will first create an object ppufile which will be used below. We are opening unit \file{test.ppu} as an example. @@ -2609,7 +2997,7 @@ begin end; \end{verbatim} -\emph{ Remark: } When a function fails (for example not enough bytes left in an +Note: When a function fails (for example not enough bytes left in an entry) it sets the \var{ppufile.error} variable. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -2631,48 +3019,55 @@ tppuheader=packed record end; \end{verbatim} -The header is already read by the ppufile.open command. You can access all -fields using ppufile.header which holds the current header record +The header is already read by the \var{ppufile.open} command. +You can access all fields using \var{ppufile.header} which holds +the current header record. + +\begin{tabular}{lp{10cm}} +\raggedright +field & description \\ \hline +\var{id} & +this is allways 'PPU', can be checked with +\mbox{\var{function ppufile.CheckPPUId:boolean;}} \\ +\var{ver} & ppu version, currently '015', can be checked with +\mbox{\var{function ppufile.GetPPUVersion:longint;}} (returns 15) \\ +\var{compiler} + & compiler version used to create the unit. Doesn't contain the + patchlevel. Currently 0.99 where 0 is the high byte and 99 the + low byte \\ +\var{cpu} & cpu for which this unit is created. + 0 = i386 + 1 = m68k \\ +\var{target} & target for which this unit is created, this depends also on the + cpu! + + For i386: +\begin{tabular}[t]{ll} +0 & Go32v1 \\ +1 & Go32V2 \\ +2 & Linux-i386 \\ +3 & OS/2 \\ +4 & Win32 +\end{tabular} -\begin{description} -\item[\var{id}] this is always 'PPU' \\ - \var{function ppufile.CheckPPUId:boolean;} -\item[\var{ver}] ppu version, currently '015' \\ - \var{function ppufile.GetPPUVersion:longint;} (returns 15) -\item[\var{compiler}] compiler version used to create the unit. Doesn't contain the -patchlevel. Currently 0.99 where 0 is the high byte and 99 the low byte -\item[\var{cpu}] cpu for which this unit is created - \begin{description} - \item[0] i386 - \item[1] m68k - \end{description} -\item[\var{target}] target for which this unit is created, this -depends also on the cpu! -For i386: - \begin{description} - \item[\var{0}] Go32v1 - \item[\var{1}] Go32V2 - \item[\var{2}] Linux-i386 - \item[\var{3}] OS/2 - \item[\var{4}] Win32 (Windows 95/98/NT) - \end{description} For m68k: - \begin{description} - \item[\var{0}] Amiga - \item[\var{1}] Mac68k - \item[\var{2}] Atari - \item[\var{3}] Linux-m68k - \end{description} +\begin{tabular}[t]{ll} +0 & Amiga \\ +1 & Mac68k \\ +2 & Atari \\ +3 & Linux-m68k +\end{tabular} \\ +\var{flag} & +the unit flags, contains a combination of the uf\_ constants which +are definied in \file{ppu.pas} \\ +\var{size} & size of this unit without this header \\ +\var{checksum} & + checksum of the interface parts of this unit, which determine if + a unit is changed or not, so other units can see if they need to + be recompiled +\\ \hline +\end{tabular} -\item[\var{flags}] the unit flags, contains a combination of -the uf\_ constants which are definied in \file{ppu.pas} -\item[\var{size}] size of this unit without this header -\item[\var{checksum}] checksum of the interface parts of this -unit, which determine if a unit is changed or not, -so other units can see if they need to be recompiled -\end{description} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % The sections \section{The sections} @@ -2689,20 +3084,22 @@ Each entry starts with an entryheader. end; \end{verbatim} -\begin{description} -\item[\var{id}] this is 1 or 2 and can be check if it the entry is correctly +\begin{tabular}{lp{10cm}} +field & Description \\ \hline +id & this is 1 or 2 and can be check if it the entry is correctly found. 1 means its a main entry, which says that it is part of the basic layout as explained before. 2 toggles that it it a sub entry -of a record or object -\item[\var{nr}] contains the ib constant number which determines what kind of -entry it is -\item[\var{size}] size of this entry without the header, can be used to skip entries -very easily. -\end{description} +of a record or object \\ +nr & contains the ib constant number which determines what kind of +entry it is \\ +size & size of this entry without the header, can be used to skip entries +very easily. \\ \hline +\end{tabular} -To read an entry you can simply call \var{ppufile.readentry:byte} it returns the -\var{tppuentry.nr} field, which holds the type of the entry. A common way how -this works is (example is for the symbols): +To read an entry you can simply call \var{ppufile.readentry:byte}, +it returns the +\var{tppuentry.nr} field, which holds the type of the entry. +A common way how this works is (example is for the symbols): \begin{verbatim} repeat @@ -2716,47 +3113,45 @@ this works is (example is for the symbols): \end{verbatim} Then you can parse each entry type yourself. \var{ppufile.readentry} will take -care of skipping unread byte in the entry an read the next entry +care of skipping unread bytes in the entry an read the next entry correctly! A special function is \var{skipuntilentry(untilb:byte):boolean;} -which will read the ppufile until it finds entry untilb in the main -entrys. +which will read the ppufile until it finds entry \var{untilb} in the main +entries. -Parsing an entry can be done with \var{ppufile.get} functions. The +Parsing an entry can be done with \var{ppufile.getxxx} functions. The available functions are: - \begin{verbatim} - procedure ppufile.getdata(var b;len:longint); - function getbyte:byte; - function getword:word; - function getlongint:longint; - function getreal:ppureal; - function getstring:string; +procedure ppufile.getdata(var b;len:longint); +function getbyte:byte; +function getword:word; +function getlongint:longint; +function getreal:ppureal; +function getstring:string; \end{verbatim} To check if you're at the end of an entry you can use the following function: \begin{verbatim} - function EndOfEntry:boolean; +function EndOfEntry:boolean; \end{verbatim} +{\em notes:} +\begin{enumerate} +\item \var{ppureal} is the best real that exists for the cpu where the +unit is created for. Currently it is \var{extended} for i386 and +\var{single} for m68k. +\item the \var{ibobjectdef} and \var{ibrecorddef} have stored a definition +and symbol section for themselves. So you'll need a recursive call. See +\file{ppudump.pp} for a correct implementation. +\end{enumerate} -\emph{ Remark: } ppureal is the bestreal that is possible for the cpu where the -unit is created for. Currently its extended for i386 and single for m68k. +A complete list of entries and what their fields contain can be found +in \file{ppudump.pp}. -\emph{ Remark: } the ibobjectdef and ibrecorddef have stored a definition and -symbol section for themselves. So you'll need a recursive call. See -\file{ppudump.pas} for a good implementation. - -For a complete list of entries and what their fields contain can be found -in \file{ppudump.pp} - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% Creating ppufiles \section{Creating ppufiles} -To create a new ppufile works almost the same as writing. First you need +Creating a new ppufile works almost the same as writing. First you need to init the object and call create: - \begin{verbatim} ppufile:=new(pppufile,'output.ppu'); ppufile.create; @@ -2764,7 +3159,6 @@ to init the object and call create: After that you can simply write all needed entries. You'll have to take care that you write at least the basic entries for the sections: - \begin{verbatim} ibendinterface ibenddefs @@ -2775,38 +3169,36 @@ care that you write at least the basic entries for the sections: \end{verbatim} Writing an entry is a little different than reading it. You need to first -put everything in the entry with \var{ppufile.put}: - +put everything in the entry with ppufile.putxxx: \begin{verbatim} - procedure putdata(var b;len:longint); - procedure putbyte(b:byte); - procedure putword(w:word); - procedure putlongint(l:longint); - procedure putreal(d:ppureal); - procedure putstring(s:string); +procedure putdata(var b;len:longint); +procedure putbyte(b:byte); +procedure putword(w:word); +procedure putlongint(l:longint); +procedure putreal(d:ppureal); +procedure putstring(s:string); \end{verbatim} After putting all the things in the entry you need to call -\var{ppufile.writeentry(ibnr:byte)} where \var{ibnr} -is the entry number you're writing. +\var{ppufile.writeentry(ibnr:byte)} where \var{ibnr} is the entry number +you're writing. -At the end of the file you need to call ppufile.writeheader to write the -new header to the file. This takes automaticly care of the new size of the -ppufile. When that's also done you can call \var{ppufile.close} and dispose the +At the end of the file you need to call \var{ppufile.writeheader} to write the +new header to the file. This takes automatically care of the new size of the +ppufile. When that is also done you can call \var{ppufile.close} and dispose the object. Extra functions/variables available for writing are: - \begin{verbatim} - ppufile.NewHeader; - ppufile.NewEntry; +ppufile.NewHeader; +ppufile.NewEntry; +\end{verbatim} +This will give you a clean header or entry. Normally called automatically +in \var{ppufile.writeentry}, so you can't forget it. +\begin{verbatim} +ppufile.flush; \end{verbatim} -this will give you a clean header or entry. Normally called automaticly -in \var{ppufile.writeentry()}, so you can't forget it. -\begin{verbatim} -ppufile.flush; -\end{verbatim} to flush the current buffers to the disk \begin{verbatim} ppufile.do_crc:boolean;