Inline procedures | Documentation

boolean byte code data dptr file function high idata lcall memory module procedure record register segment type value xdata 8051
Procedures Inline procedures

# Inline procedures

Procedures (and functions) that are declared with the Inline directive are copied to the places where they are called. This has the effect that there is no actual procedure (or function) call, the code of the procedure is just copied to where the procedure is needed, this results in faster execution speed if the procedure or function is used a lot but but usually means also larger code size. You can override this behaviour with the $InlineCode directive. When set to Off (default is On) the compiler will generate normal calls to inline procedures.
Example:

    {
        This file is part of the Turbo51 code examples.
        Copyright (C) 2008 by Igor Funa

        http://turbo51.com/

        This file is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    }

    Program Example4;

    { Usless program just to demonstrate sets and inline procedures/functions }

    Type
      TFlag = (fl0, fl1, fl2, fl3, fl4, fl5, fl6);
      TFlagsSet = Set of TFlag;

      TVariantRecord = Record
                         Case Byte of
                           0: (L: LongInt);
                           1: (W0, W1: Word);
                           2: (B0, B1, B2, B3: Byte);
                           3: (DataWord: Word; LocalFlags: Set of 0..7; Flags: TFlagsSet);
                           4: (IndividualBits: Set of 0..31);
                           5: (Ch0, Ch1, Ch2, Ch3: Char);
                       end;

    Const
       InitialFlags = [fl0, fl4, fl5];
       TempFlags    = [fl0, fl1, fl3];

    Var
      WatchdogClock: Boolean absolute P0.4;

      GlobalFlags: TFlagsSet;
      DataRecord1,
      DataRecord2: TVariantRecord;
      Character: Char;
      B1, B2: Byte;

    Function UpcaseChar (Ch: Char): Char;
    {$I InlineChar.inc }

    Function InlineUpcaseChar (Ch: Char): Char; Inline;
    {$I InlineChar.inc }

    Procedure RestartWatchdog; Inline; Assembler;
    Asm
      CPL  WatchdogClock;
    end;

    Procedure Multiply (Var Factor: Byte);
    begin
      Factor := Factor * 10;
      If Factor >= 100 then Factor := 0;
    end;

    Procedure InlineMultiply (Var Factor: Byte); Inline;
    begin
      Factor := Factor * 10;
      If Factor >= 100 then Factor := 0;
    end;

    begin
      GlobalFlags := InitialFlags;

      Include (GlobalFlags, fl4);
      Exclude (GlobalFlags, fl5);
      Change  (GlobalFlags, fl6);

      RestartWatchdog;

      DataRecord1.L := $12345678;
      With DataRecord2 do
        begin
          DataWord   := DataRecord1.W0 + DataRecord1.W1;
          LocalFlags := [3, 5, 6];
          Flags      := GlobalFlags;
        end;

      RestartWatchdog;

      Case fl6 in DataRecord2.Flags of
        True: DataRecord2.Flags := DataRecord2.Flags * TempFlags + [fl2, fl3];
        else  DataRecord2.Flags := TempFlags;
      end;

      RestartWatchdog;

      If 0 in DataRecord2.IndividualBits then With DataRecord2 do
        begin
          Include (IndividualBits, 4);
          Exclude (IndividualBits, 15);
          Change  (IndividualBits, 31);
        end;

    { Call to function UpcaseChar }

      Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
      DataRecord1.Ch0 := UpcaseChar (Character);

    { Inline function InlineUpcaseChar }

      Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
      DataRecord1.Ch1 := InlineUpcaseChar (Character);

    { Call to procedure Multiply }

      Multiply (DataRecord1.B1);

    { Inline procedure InlineMultiply }

      InlineMultiply (DataRecord1.B1);

    {$InlineCode Off }

    { Normal call to Inline function InlineUpcaseChar }

      Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
      DataRecord1.Ch1 := InlineUpcaseChar (Character);

    { Normal call to Inline procedure InlineMultiply }

      InlineMultiply (DataRecord1.B1);
    end.

Compiled program above looks like this:

    ; Turbo51 version 0.1.3.0, Copyright 2000 - 2008 Igor Funa

    $REGISTERBANK (0)

    _CODE         SEGMENT  CODE
    _DATA         SEGMENT  DATA

                  EXTRN    IDATA (StackStart)

                  EXTRN    CODE  (sysRandomWord)

    ; {
    ;     This file is part of the Turbo51 code examples.
    ;     Copyright (C) 2008 by Igor Funa
    ;
    ;     http://turbo51.com/
    ;
    ;     This file is distributed in the hope that it will be useful,
    ;     but WITHOUT ANY WARRANTY; without even the implied warranty of
    ;     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ; }
    ;
    ; Program Example4;
    ;
    ; { Usless program just to demonstrate sets and inline procedures/functions }
    ;
    ; Type
    ;   TFlag = (fl0, fl1, fl2, fl3, fl4, fl5, fl6);
    ;   TFlagsSet = Set of TFlag;
    ;
    ;   TVariantRecord = Record
    ;                      Case Byte of
    ;                        0: (L: LongInt);
    ;                        1: (W0, W1: Word);
    ;                        2: (B0, B1, B2, B3: Byte);
    ;                        3: (DataWord: Word; LocalFlags: Set of 0..7; Flags: TFlagsSet);
    ;                        4: (IndividualBits: Set of 0..31);
    ;                        5: (Ch0, Ch1, Ch2, Ch3: Char);
    ;                    end;
    ;
    ; Const

    RSEG _CONST

    ;    InitialFlags = [fl0, fl4, fl5];
    ;    TempFlags    = [fl0, fl1, fl3];
    ;
    ; Var
    ;   WatchdogClock: Boolean absolute P0.4;
    WatchdogClock                   BIT      P0.4

    ;
    ;   GlobalFlags: TFlagsSet;

    RSEG _DATA

    GlobalFlags:                    DS       1

    ;   DataRecord1,
    ;   DataRecord2: TVariantRecord;
    DataRecord1:                    DS       4
    DataRecord2:                    DS       4

    ;   Character: Char;
    Character:                      DS       1

    ;   B1, B2: Byte;
    ;
    ; Function UpcaseChar (Ch: Char): Char;
    Ch:                             DS       1

    RSEG _CODE

    USING 0

    UpcaseChar:
    ; {$I InlineChar.inc }
    ; {
    ;     This file is part of the Turbo51 code examples.
    ;     Copyright (C) 2008 by Igor Funa
    ;
    ;     >http://turbo51.com/
    ;
    ;     This file is distributed in the hope that it will be useful,
    ;     but WITHOUT ANY WARRANTY; without even the implied warranty of
    ;     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ; }
    ;
    ; begin
    ;   Result := Char (Byte (Ch) and $DF);
                  MOV       A, Ch
                  ANL       A, #$DF

    ; end;
                  RET

    ;
    ; Function InlineUpcaseChar (Ch: Char): Char; Inline;

    RSEG _DATA

    Ch:                             DS       1

    RSEG _CODE

    InlineUpcaseChar:
    ; {$I InlineChar.inc }
    ; {
    ;     This file is part of the Turbo51 code examples.
    ;     Copyright (C) 2008 by Igor Funa
    ;
    ;     >http://turbo51.com/
    ;
    ;     This file is distributed in the hope that it will be useful,
    ;     but WITHOUT ANY WARRANTY; without even the implied warranty of
    ;     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    ; }
    ;
    ; begin
    ;   Result := Char (Byte (Ch) and $DF);
                  MOV       A, Ch
                  ANL       A, #$DF

    ; end;
                  RET

    ;
    ; Procedure RestartWatchdog; Inline; Assembler;
    ; Asm
    ;   CPL  WatchdogClock;
    ; end;
    ;
    ; Procedure Multiply (Var Factor: Byte);

    RSEG _DATA

    Factor:                         DS       1

    RSEG _CODE

    Multiply:
    ; begin
    ;   Factor := Factor * 10;
                  MOV       R0, Factor
                  MOV       A, @R0
                  MOV       B, #$0A
                  MUL       AB
                  MOV       @R0, A

    ;   If Factor >= 100 then Factor := 0;
                  ADD       A, #-100
                  JNC       L_00C7
                  MOV       @R0, #0
    L_00C7:

    ; end;
                  RET

    ;
    ; Procedure InlineMultiply (Var Factor: Byte); Inline;

    RSEG _DATA

    Factor:                         DS       1

    RSEG _CODE

    InlineMultiply:
    ; begin
    ;   Factor := Factor * 10;
                  MOV       R0, Factor
                  MOV       A, @R0
                  MOV       B, #$0A
                  MUL       AB
                  MOV       @R0, A

    ;   If Factor >= 100 then Factor := 0;
                  ADD       A, #-100
                  JNC       L_00D6
                  MOV       @R0, #0
    L_00D6:

    ; end;
                  RET

    CSEG AT 0

    Example4:
    ;
    ; begin
                  MOV       SP, #StackStart-1

    ;   GlobalFlags := InitialFlags;
                  MOV       GlobalFlags, #$31

    ;
    ;   Include (GlobalFlags, fl4);
                  ORL       GlobalFlags, #$10

    ;   Exclude (GlobalFlags, fl5);
                  ANL       GlobalFlags, #$DF

    ;   Change  (GlobalFlags, fl6);
                  XRL       GlobalFlags, #$40

    ;
    ;   RestartWatchdog;
    ;   CPL  WatchdogClock;
                  CPL       P0.4

    ;
    ;   DataRecord1.L := $12345678;
                  MOV       DataRecord1, #$78
                  MOV       DataRecord1+1, #$56
                  MOV       DataRecord1+2, #$34
                  MOV       DataRecord1+3, #$12

    ;   With DataRecord2 do
    ;     begin
    ;       DataWord   := DataRecord1.W0 + DataRecord1.W1;
                  MOV       A, DataRecord1
                  ADD       A, DataRecord1+2
                  MOV       DataRecord2, A
                  MOV       A, DataRecord1+1
                  ADDC      A, DataRecord1+3
                  MOV       DataRecord2+1, A

    ;       LocalFlags := [3, 5, 6];
                  MOV       DataRecord2+2, #$68

    ;       Flags      := GlobalFlags;
                  MOV       DataRecord2+3, GlobalFlags

    ;     end;
    ;
    ;   RestartWatchdog;
    ;   CPL  WatchdogClock;
                  CPL       P0.4

    ;
    ;   Case fl6 in DataRecord2.Flags of
                  MOV       A, DataRecord2+3

    ;     True: DataRecord2.Flags := DataRecord2.Flags * TempFlags + [fl2, fl3];
                  JNB       ACC.6, L_0040
                  MOV       A, DataRecord2+3
                  ANL       A, #$0B
                  ORL       A, #$0C
                  MOV       DataRecord2+3, A
                  SJMP      L_0043
    L_0040:

    ;     else  DataRecord2.Flags := TempFlags;
                  MOV       DataRecord2+3, #$0B
    L_0043:

    ;   end;
    ;
    ;   RestartWatchdog;
    ;   CPL  WatchdogClock;
                  CPL       P0.4

    ;
    ;   If 0 in DataRecord2.IndividualBits then With DataRecord2 do
                  MOV       A, DataRecord2
                  JNB       ACC.0, L_0053

    ;     begin
    ;       Include (IndividualBits, 4);
                  ORL       DataRecord2, #$10

    ;       Exclude (IndividualBits, 15);
                  ANL       DataRecord2+1, #$7F

    ;       Change  (IndividualBits, 31);
                  XRL       DataRecord2+3, #$80

    ;     end;
    L_0053:
    ;
    ; { Call to function UpcaseChar }
    ;
    ;   Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
                  MOV       R2, #LOW  ($001A)
                  MOV       R3, #HIGH ($001A)
                  LCALL     sysRandomWord
                  MOV       A, R2
                  ADD       A, #LOW  ($0061)
                  MOV       Character, A

    ;   DataRecord1.Ch0 := UpcaseChar (Character);
                  MOV       Ch, Character
                  LCALL     UpcaseChar
                  MOV       DataRecord1, A

    ;
    ; { Inline function InlineUpcaseChar }
    ;
    ;   Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
                  MOV       R2, #LOW  ($001A)
                  MOV       R3, #HIGH ($001A)
                  LCALL     sysRandomWord
                  MOV       A, R2
                  ADD       A, #LOW  ($0061)
                  MOV       Character, A

    ;   DataRecord1.Ch1 := InlineUpcaseChar (Character);
                  MOV       Ch, Character

    ;   Result := Char (Byte (Ch) and $DF);
                  MOV       A, Ch
                  ANL       A, #$DF

                  MOV       DataRecord1+1, A
    ;
    ; { Call to procedure Multiply }
    ;
    ;   Multiply (DataRecord1.B1);
                  MOV       Factor, #DataRecord1+1
                  LCALL     Multiply

    ;
    ; { Inline procedure InlineMultiply }
    ;
    ;   InlineMultiply (DataRecord1.B1);
                  MOV       Factor, #DataRecord1+1

    ;   Factor := Factor * 10;
                  MOV       R0, Factor
                  MOV       A, @R0
                  MOV       B, #$0A
                  MUL       AB
                  MOV       @R0, A

    ;   If Factor >= 100 then Factor := 0;
                  ADD       A, #-100
                  JNC       L_0093
                  MOV       @R0, #0
    L_0093:

    ;
    ; {$InlineCode Off }
    ;
    ; { Normal call to Inline function InlineUpcaseChar }
    ;
    ;   Character := Chr (Ord ('a') + Random (Ord ('z') - Ord ('a') + 1));
                  MOV       R2, #LOW  ($001A)
                  MOV       R3, #HIGH ($001A)
                  LCALL     sysRandomWord
                  MOV       A, R2
                  ADD       A, #LOW  ($0061)
                  MOV       Character, A

    ;   DataRecord1.Ch1 := InlineUpcaseChar (Character);
                  MOV       Ch, Character
                  LCALL     InlineUpcaseChar
                  MOV       DataRecord1+1, A

    ;
    ; { Normal call to Inline procedure InlineMultiply }
    ;
    ;   InlineMultiply (DataRecord1.B1);
                  MOV       Factor, #DataRecord1+1
                  LCALL     InlineMultiply

    ; end.
    L_00AD:
                  SJMP      L_00AD

    RSEG _CONST

                  END