CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

inline function
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Felo



Joined: 23 May 2020
Posts: 7

View user's profile Send private message

inline function
PostPosted: Mon Jan 25, 2021 2:20 pm     Reply with quote

Question:
What is the code that the compiler generates for inline functions used for?
Question details: I don't understand what the code generated by the compiler at addresses 00040 to 00044 of the following .lst file is used for

Compiler version: 5.015
lst file
00014 .................... #device PIC18F46K22
00015 ....................
01019 .................... #list
01020 ....................
01021 .................... #device ADC=16
01022 ....................
01023 .................... #FUSES NOWDT //No Watch Dog Timer
01024 .................... #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
01025 .................... #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
01026 ....................
01027 .................... #use delay(crystal=20000000)
01028 ....................
01029 ....................
01030 .................... #pragma inline
01031 ....................
01032 .................... int suma(int a, int b) {
01033 .................... return (a +b);
00040 5009 01034 MOVF 09,W
00042 2408 01035 ADDWF 08,W
00044 6E01 01036 MOVWF 01
01037 .................... }
01038 ....................
01039 .................... void main(void){
00004 6AF8 01040 CLRF FF8
00006 9ED0 01041 BCF FD0.7
00008 50C1 01042 MOVF FC1,W
0000A 0BF0 01043 ANDLW F0
0000C 6EC1 01044 MOVWF FC1
0000E 0E00 01045 MOVLW 00
00010 010F 01046 MOVLB F
00012 6F38 01047 MOVWF x38
00014 6F3C 01048 MOVWF x3C
00016 6F39 01049 MOVWF x39
00018 6F3A 01050 MOVWF x3A
0001A 6F3B 01051 MOVWF x3B
0001C 0101 01052 MOVLB 1
0001E 6B88 01053 CLRF x88
00020 6A77 01054 CLRF F77
00022 6A78 01055 CLRF F78
00024 6A79 01056 CLRF F79
00026 6A05 01057 CLRF 05
01058 .................... int c =0;
01059 .................... for (int i=0;i<4;i++)
00028 6A06 01060 CLRF 06
0002A 5006 01061 MOVF 06,W
0002C 0803 01062 SUBLW 03
0002E E311 01063 BNC 0052
01064 .................... for (int k=0;k < 3;k++)
00030 6A07 01065 CLRF 07
00032 5007 01066 MOVF 07,W
00034 0802 01067 SUBLW 02
00036 E30B 01068 BNC 004E
01069 .................... c = suma(i,k);
00038 C006 F008 01070 MOVFF 06,08
0003C C007 F009 01071 MOVFF 07,09
00046 C001 F005 01072 MOVFF 01,05
0004A 2A07 01073 INCF 07,F
0004C D7F2 01074 BRA 0032
0004E 2A06 01075 INCF 06,F
00050 D7EC 01076 BRA 002A
01077 ....................
01078 ....................
01079 .................... }
00052 0003 1080 SLEEP

Thanks
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Mon Jan 25, 2021 2:46 pm     Reply with quote

    The suma() function adds two numbers and returns the result.
    Code:
     int suma(int a, int b) {
    return (a +b);
    }

    It's put "inline" to eliminate the need for CALL and RETURN instructions.
    This reason for this could be to increase the speed of execution or to
    reduce the amount of flash memory used for the program.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    inline function
    PostPosted: Mon Jan 25, 2021 3:00 pm     Reply with quote

    PCM programmer wrote:
    The suma() function adds two numbers and returns the result.
    Code:
     int suma(int a, int b) {
    return (a +b);
    }

    It's put "inline" to eliminate the need for CALL and RETURN instructions.
    This reason for this could be to increase the speed of execution or to
    reduce the amount of flash memory used for the program.

    In my case I use inline because I want the function code to be generated in different memory areas.
    I do not understand why the compiler generates the code that I indicate in the post.
    Thanks for answering
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Mon Jan 25, 2021 3:09 pm     Reply with quote

    Does that mean you still need an answer ? Your question was:
    Quote:

    I don't understand what the code generated by the compiler at addresses
    00040 to 00044 of the following .lst file is used for.


    00040 to 00044 is the following code:
    Quote:
    01032 .................... int suma(int a, int b) {
    01033 .................... return (a +b);
    00040 5009 01034 MOVF 09,W
    00042 2408 01035 ADDWF 08,W
    00044 6E01 01036 MOVWF 01
    01037 .................... }

    It's used to add two numbers and give back the result.

    If your question is really "What does the entire program do ?", then post a
    link to the entire program so we can look at it.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    inline function
    PostPosted: Mon Jan 25, 2021 3:16 pm     Reply with quote

    PCM programmer wrote:
    Does that mean you still need an answer ? Your question was:
    Quote:

    I don't understand what the code generated by the compiler at addresses
    00040 to 00044 of the following .lst file is used for.


    00040 to 00044 is the following code:
    Quote:
    01032 .................... int suma(int a, int b) {
    01033 .................... return (a +b);
    00040 5009 01034 MOVF 09,W
    00042 2408 01035 ADDWF 08,W
    00044 6E01 01036 MOVWF 01
    01037 .................... }

    It's used to add two numbers and give back the result.

    If your question is really "What does the entire program do ?", then post a
    link to the entire program so we can look at it.

    The program is trivial. It works perfectly. The question is about the compiler.
    However I annex the program.
    Thank you.
    Program:
    #include <inlineTest.h>
    #pragma inline

    int suma(int a, int b) {
    return (a +b);
    }

    void main(void){
    int c =0;
    for (int i=0;i<4;i++)
    for (int k=0;k < 3;k++)
    c = suma(i,k);
    }
    Ttelmah



    Joined: 11 Mar 2010
    Posts: 19195

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 12:53 am     Reply with quote

    If you look at your original listing, and then 'reorder' based on the actual
    memory address, you have (comments inline):
    Code:


    01069 .................... c = suma(i,k);
    00038 C006 F008 01070 MOVFF 06,08 //Move the two values
    0003C C007 F009 01071 MOVFF 07,09 //to the working registers

    //The suma function code is at address 0040
    00040 5009 01034 MOVF 09,W
    00042 2408 01035 ADDWF 08,W //add the values
    00044 6E01 01036 MOVWF 01

    00046 C001 F005 01072 MOVFF 01,05 //move the result to final location

    Though the code is 'shown', where is is declared, the physical assembly
    code has been placed 'inside' the main function where it is called. Hence
    'inline'.

    Now with the 'inline' function, if you called it multiple times, the listing
    below the actual declaration, would show a new copy for every place
    it was called, with the addresses being those for the location where it
    was 'called'.
    The assembler just happens to always display the code where it is declared,
    not repositioning it to where it is used. You have to solve this yourself.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    IMHO it is very poor code generation.
    PostPosted: Tue Jan 26, 2021 2:21 am     Reply with quote

    Hi Ttelmah:
    IMHO it is very poor code generation.
    Even when the function is called more than once, the code in the function declaration is generated as many times as it is called in the program as can be seen in this other example. This useless code consumes memory since it not only appears in the list, it is also in the .hex file.
    Thank you for your prompt and effective response.
    Kind Regards

    MPASM

    CCS PCH C Compiler, Version 5.015, xxxx 26-Jan-21 02:48

    Filename: D:\SoftIOM\inlineTest.lst

    ROM used: 144 bytes (0%)
    Largest free fragment is 65392
    RAM used: 5 (0%) at main() level
    9 (0%) worst case
    Stack used: 0 locations
    Stack size: 31

    00000 EF02 F000 00001 GOTO 0004
    00002 .................... #include <inlineTest.h>
    00003 .................... #include <18F46k22.h>
    00004 .................... //////////// Standard Header file for the PIC18F46K22 device ////////////////
    00005 .................... ///////////////////////////////////////////////////////////////////////////
    00006 .................... //// (C) Copyright 1996, 2013 Custom Computer Services ////
    00007 .................... //// This source code may only be used by licensed users of the CCS C ////
    00008 .................... //// compiler. This source code may only be distributed to other ////
    00009 .................... //// licensed users of the CCS C compiler. No other use, reproduction ////
    00010 .................... //// or distribution is permitted without written permission. ////
    00011 .................... //// Derivative programs created using this software in object code ////
    00012 .................... //// form are not restricted in any way. ////
    00013 .................... ///////////////////////////////////////////////////////////////////////////
    00014 .................... #device PIC18F46K22
    00015 ....................
    01019 .................... #list
    01020 ....................
    01021 .................... #device ADC=16
    01022 ....................
    01023 .................... #FUSES NOWDT //No Watch Dog Timer
    01024 .................... #FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
    01025 .................... #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
    01026 ....................
    01027 .................... #use delay(crystal=20000000)
    01028 ....................
    01029 ....................
    01030 .................... #pragma inline
    01031 ....................
    01032 .................... int suma(int a, int b) {
    01033 .................... return (a +b);
    00040 5009 01034 MOVF 09,W // (Observe how the code in the declaration is repeated each time the function is called
    00042 2408 01035 ADDWF 08,W//
    00044 6E01 01036 MOVWF 01
    // again
    00062 5009 01037 MOVF 09,W
    00064 2408 01038 ADDWF 08,W
    00066 6E01 01039 MOVWF 01
    //and agin
    00080 5009 01040 MOVF 09,W
    00082 2408 01041 ADDWF 08,W
    00084 6E01 01042 MOVWF 01
    01043 .................... }
    01044 ....................
    01045 .................... void main(void){
    00004 6AF8 01046 CLRF FF8
    00006 9ED0 01047 BCF FD0.7
    00008 50C1 01048 MOVF FC1,W
    0000A 0BF0 01049 ANDLW F0
    0000C 6EC1 01050 MOVWF FC1
    0000E 0E00 01051 MOVLW 00
    00010 010F 01052 MOVLB F
    00012 6F38 01053 MOVWF x38
    00014 6F3C 01054 MOVWF x3C
    00016 6F39 01055 MOVWF x39
    00018 6F3A 01056 MOVWF x3A
    0001A 6F3B 01057 MOVWF x3B
    0001C 0101 01058 MOVLB 1
    0001E 6B88 01059 CLRF x88
    00020 6A77 01060 CLRF F77
    00022 6A78 01061 CLRF F78
    00024 6A79 01062 CLRF F79
    00026 6A05 01063 CLRF 05
    01064 .................... int c =0;
    01065 .................... for (int i=0;i<4;i++)
    00028 6A06 01066 CLRF 06
    0002A 5006 01067 MOVF 06,W
    0002C 0803 01068 SUBLW 03
    0002E E311 01069 BNC 0052
    01070 .................... for (int k=0;k < 3;k++)
    00030 6A07 01071 CLRF 07
    00032 5007 01072 MOVF 07,W
    00034 0802 01073 SUBLW 02
    00036 E30B 01074 BNC 004E
    01075 .................... c = suma(i,k);
    00038 C006 F008 01076 MOVFF 06,08
    0003C C007 F009 01077 MOVFF 07,09
    00046 C001 F005 01078 MOVFF 01,05
    0004A 2A07 01079 INCF 07,F
    0004C D7F2 01080 BRA 0032
    0004E 2A06 01081 INCF 06,F
    00050 D7EC 01082 BRA 002A
    01083 .................... for (i=0;i<10;i++)
    00052 6A06 01084 CLRF 06
    00054 5006 01085 MOVF 06,W
    00056 0809 01086 SUBLW 09
    00058 E30B 01087 BNC 0070
    01088 .................... c = suma(i,i);
    0005A C006 F008 01089 MOVFF 06,08
    0005E C006 F009 01090 MOVFF 06,09
    00068 C001 F005 01091 MOVFF 01,05
    0006C 2A06 01092 INCF 06,F
    0006E D7F2 01093 BRA 0054
    01094 .................... for (i=0;i<10;i++)
    00070 6A06 01095 CLRF 06
    00072 5006 01096 MOVF 06,W
    00074 0809 01097 SUBLW 09
    00076 E30B 01098 BNC 008E
    01099 .................... c = suma(i,i);
    00078 C006 F008 01100 MOVFF 06,08
    0007C C006 F009 01101 MOVFF 06,09
    00086 C001 F005 01102 MOVFF 01,05
    0008A 2A06 01103 INCF 06,F
    0008C D7F2 01104 BRA 0072
    01105 ....................
    01106 ....................
    01107 ....................
    01108 ....................
    01109 .................... }
    0008E 0003 1110 SLEEP

    Configuration Fuses:
    Word 1: E200 HSH NOPLLEN PRIMARY_ON FCMEN IESO
    Word 2: 1C1E PUT BROWNOUT BORV19 NOWDT WDT128
    Word 3: BF00 CCP2C1 PBADEN CCP3B5 HFOFST TIMER3C0 CCP2D2 MCLR
    Word 4: 0081 STVREN NOLVP NOXINST NODEBUG
    Word 5: C00F NOPROTECT NOCPB NOCPD
    Word 6: E00F NOWRT NOWRTC NOWRTB NOWRTD
    Word 7: 400F NOEBTR NOEBTRB

    SYMBOL TABLE
    LABEL VALUE

    _RETURN_ 00000001
    MAIN.c 00000005
    MAIN.i 00000006
    MAIN.k 00000007
    suma.a 00000008
    suma.b 00000009
    CCP_5_LOW 00000F55
    CCP_5 00000F55
    CCP_5_HIGH 00000F56
    CCP_4 00000F58
    CCP_4_LOW 00000F58
    CCP_4_HIGH 00000F59
    CCP_3 00000F5E
    CCP_3_LOW 00000F5E
    CCP_3_HIGH 00000F5F
    CCP_2_LOW 00000F67
    CCP_2 00000F67
    CCP_2_HIGH 00000F68
    C2OUT 00000F78
    C1OUT 00000F79
    CCP_1 00000FBE
    CCP_1_LOW 00000FBE
    CCP_1_HIGH 00000FBF
    Allocation: 0000EEEF
    MAIN 00000000
    suma 00000000

    MEMORY USAGE
    Ttelmah



    Joined: 11 Mar 2010
    Posts: 19195

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 2:57 am     Reply with quote

    You are missing the point.
    Declaring a function as 'inline', _specifically_ MAKES the compiler
    generate the code for every place it is used.
    It is _you_ who are making the compiler generate the code for every
    place it is used.
    Simply declare the function without #inline, and the code will be
    generated just once, and called each time it is used.
    BUT, this is inherently slower than having the code regenerated for
    each location. Done like this, there is no call/return, so a couple of
    double cycle instructions quicker.
    It is not the compiler doing this. You are specifically telling the compiler
    to make the code 'inline'. As PCM says this is normally done for speed.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    Forgive the insistence.
    PostPosted: Tue Jan 26, 2021 4:07 am     Reply with quote

    Hello:

    I understand that generating the code of the function in the place it is called increases the execution speed as you well explained. The inline function is used for this purpose.
    I can't understand how generating the code in the declaration that never executes (the one that appears in the declaration of the inline function) can help.
    Thanks for your time.
    Ttelmah



    Joined: 11 Mar 2010
    Posts: 19195

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 4:33 am     Reply with quote

    Er. It doesn't.

    The assembler .lst file is not (and never is), 'in code order'. It is blocks of code
    placed in the order they are typed.
    So it has the #inline function shown where it is declared. However the order
    'in use', is determined by the address the function is actually placed at.
    So the routines for the #use RS232 are shown just below this in the listing.
    Same for delay code, etc. etc..
    temtronic



    Joined: 01 Jul 2010
    Posts: 9081
    Location: Greensville,Ontario

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 6:19 am     Reply with quote

    In the early days ( V2.534...) I was confused about the listing, then saw that the addresses 'all over the place'. So I used 'sort.exe' ( A DOS program) , to 'reorder' the listing based upon the address where code is stored. That allowed me to easily SEE and understand what was going on.
    At the time I was doing a 'time sensitive' program(bit banged serial) and needed to KNOW exactly how the PIC was being coded.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    Please observe the generated .hex file that I attach
    PostPosted: Tue Jan 26, 2021 7:06 am     Reply with quote

    You are correct that the order that appears in the list corresponds to the order in which the instructions were written and not to the order in which the code is generated.
    I attach the .hex file that was generated for the .lst file that we are analyzing.
    File Summary:
    Filename: inlineTest.hex
    File Status: Good
    Target Chip: PIC18F46K22
    File Type: INHX32 (Intel Hex)
    Program Size: 72 Instructions (1%)
    Program Range: 0000-008F
    Data EE Size: 0 bytes
    Checksum: A5C1
    Config Size: 14 bytes
    Created: 26-Jan-21 02:48
    Addresses are: Byte addresses

    Program Memory
    000000: EF02 F000 6AF8 9ED0 50C1 0BF0 6EC1 0E00
    000010: 010F 6F38 6F3C 6F39 6F3A 6F3B 0101 6B88
    000020: 6A77 6A78 6A79 6A05 6A06 5006 0803 E311
    000030: 6A07 5007 0802 E30B C006 F008 C007 F009
    000040: 5009 2408 6E01 C001 F005 2A07 D7F2 2A06
    000050: D7EC 6A06 5006 0809 E30B C006 F008 C006
    000060: F009 5009 2408 6E01 C001 F005 2A06 D7F2
    000070: 6A06 5006 0809 E30B C006 F008 C006 F009
    000080: 5009 2408 6E01 C001 F005 2A06 D7F2 0003

    Configuration Words
    300000: E200 1C1E BF00 0081 C00F E00F 400F

    ;PIC18F46K22
    ;CRC=9164 CREATED="26-Jan-21 02:48"


    Please note that in the directions
    Addresses Content
    00040 to 44 has 5009 2408 6E01
    00062 to 66 has 5009 2408 6E01
    Like 0080 to 0084
    Content that corresponds to what appears in the .lst file
    01032 .................... int suma(int a, int b) {
    01033 .................... return (a +b);
    00040 5009 01034 MOVF 09,W
    00042 2408 01035 ADDWF 08,W
    00044 6E01 01036 MOVWF 01
    00062 5009 01037 MOVF 09,W
    00064 2408 01038 ADDWF 08,W
    00066 6E01 01039 MOVWF 01
    00080 5009 01040 MOVF 09,W
    00082 2408 01041 ADDWF 08,W
    00084 6E01 01042 MOVWF 01


    Those instructions are in the program memory but never executed. That's what I mean.


    I consider the PICC a magnificent tool, so I try to understand it, and perfect it.
    Thank you
    Ttelmah



    Joined: 11 Mar 2010
    Posts: 19195

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 7:15 am     Reply with quote

    Of course they are executed. Where do you think the processor goes after
    the instruction at 0x3C?.
    Look at the order I posted the code.
    Felo



    Joined: 23 May 2020
    Posts: 7

    View user's profile Send private message

    Thank you for your patience.
    PostPosted: Tue Jan 26, 2021 7:48 am     Reply with quote

    Now I realize.
    Ttelmah wrote:
    Of course they are executed. Where do you think the processor goes after
    the instruction at 0x3C?.
    Look at the order I posted the code.
    PCM programmer



    Joined: 06 Sep 2003
    Posts: 21708

    View user's profile Send private message

    PostPosted: Tue Jan 26, 2021 10:29 am     Reply with quote

    There is also a CCS FAQ that will help you answer questions like this
    in the future:
    http://www.ccsinfo.com/faq.php

    Click on the question below in the Compiler Behavior section of the FAQ:
    Why does the .LST file look out of order ?
    http://www.ccsinfo.com/faq.php?page=lst_out_of_order
    Display posts from previous:   
    Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
    Goto page 1, 2  Next
    Page 1 of 2

     
    Jump to:  
    You cannot post new topics in this forum
    You cannot reply to topics in this forum
    You cannot edit your posts in this forum
    You cannot delete your posts in this forum
    You cannot vote in polls in this forum


    Powered by phpBB © 2001, 2005 phpBB Group