Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 10:37 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : CMM2: armcfgenv143 generating hex outside of the CSUB

Author Message
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 10:52am 12 Mar 2021
Copy link to clipboard 
Print this post

Hi folks,

Hoping there is some kind soul who knows something about the lower levels of armcfgenv143, .elf, etc.

When I run armcfgenv143 against the attached forth_cmm2.zip using the "merge" strategy it generates:

'File forth_cmm2.bas written 12-03-2021 10:45:26
       E9D06A02 B410130C 1D143304 60116204 4B04F85D 47706303
CSUB forth_cmm2.bas
       000018C8
       'util_memset
       B2C9B342 1E54B510 D9242C02 0C00F04F 0E03F022 F3614603 44860C07 2C0FF361
       4C17F361 6C1FF361 CB04F843 D1FB4573 0303F022 EBA4429A EB000403 D0080C03
       1000F88C 2C01B12C 1001F88C F88CBF18 BD101002 46844770 BF00E7F2
       'util_strcpy
       F8111E42 F8023B01 2B003F01 4770D1F9
       etc ...


Now that isn't going to work because there is "code" outside the CSUB.

Not with much expectation I tried the naive approaches of commenting the offending lines out or moving it down to the start of the CSUB but as expected neither produced working code.

Does anyone have any ideas ? If I have to "deep dive" on this myself then I may never resurface.

Best wishes,

Tom
Edited 2021-03-12 20:53 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 533
Posted: 10:56am 12 Mar 2021
Copy link to clipboard 
Print this post

Hi Tom,
I'm generating CSUB from ELF with ELF2CSUB, so I can check it at evening...
Jiri
Napoleon Commander and SimplEd for CMM2 (GitHub),  CMM2.fun
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 11:17am 12 Mar 2021
Copy link to clipboard 
Print this post

Looking at the BAS code I would suspect something like a symbol name > 31 chars

There is a corruption in the header print - should be

PRINT #2,"'File "+cname$+" "+DATE$+" "+Time$

Also, please post the map file
Edited 2021-03-12 21:24 by matherp
 
epsilon

Senior Member

Joined: 30/07/2020
Location: Belgium
Posts: 255
Posted: 11:36am 12 Mar 2021
Copy link to clipboard 
Print this post

I think this happens when you have symbols such as globals outside of a function context.

E.g. this:

#include "ARMCFunctions.h"

volatile int globalInt=0;  //<-- the offenders
volatile char globalc=' ';

void p_int(int a,int base){
 char b[64];
 IntToStr(b,a,base);
 MMPrintString(b);
}

static void foo(void) {
putConsole('*'); putConsole('\r'); putConsole('\n');  
}

void main(long long int *c, MMFLOAT *b){
++globalInt;
++globalc;

putConsole('a'); putConsole('\r'); putConsole('\n');
foo();
putConsole('b'); putConsole('\r'); putConsole('\n');
void (* volatile fptr)(void);
putConsole('c'); putConsole('\r'); putConsole('\n');
fptr = (void (* volatile)(void)) &foo; // <--- hangs here, how is that even possible?
fptr();
putConsole('d'); putConsole('\r'); putConsole('\n');
}


produces:


'File tomstest.bas 0+DATE$++Time$
4C06B510 6823202A 68234798 4798200D 200A6823 4010E8BD BF004718 080002A4
CSUB tomstest.bas
00000012
'p_int
B094B510 46024C06 A80417C3 68219100 47889003 98034B03 4798681B BD10B014
080002C4 080002C0
'main
20614B23 447B4923 B5304A23 B083585D 68294C1E 60293101 7813589A B2DB3301
68237013 68234798 4798200D 200A6823 68234798 4798202A 200D6823 68234798
4798200A 20626823 68234798 4798200D 200A6823 68234798 47982063 200D6823
68234798 4798200A 447B4B0C 9B019301 68234798 47982064 200D6823 68234798
B003200A 4030E8BD BF004718 080002A4 17FFFFB2 00000000 00000004 FFFFFF4B
End CSUB

Epsilon CMM2 projects
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 11:49am 12 Mar 2021
Copy link to clipboard 
Print this post

  Quote  I think this happens when you have symbols such as globals outside of a function context.


That makes sense as they would go into a psect that isn't catered for and probably can't be. Probably .bss or .data

Tom: if you need global variables then use CFuncRam - you have 128 bytes available that won't be changed by anything in MMbasic
Edited 2021-03-12 22:03 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:05pm 12 Mar 2021
Copy link to clipboard 
Print this post

I agree it makes sense, but I'm not explicitly using any globals, it's all pure functions.

It's happening when I blindly flag all the functions as static so that the compiler will inline them.

Will follow up later - sorry for sending fire & forget questions, just trying to use a day off to investigate the optimisation possibilities for spforth.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 12:13pm 12 Mar 2021
Copy link to clipboard 
Print this post

  Quote  It's happening when I blindly flag all the functions as static so that the compiler will inline them.


Static doesn't necessarily imply inline, merely that the scope of the function is local to the file.

In general inline is a disaster, not sure why, but if I force inline the code often runs slower. The H series chips have very clever caching and trying to outguess both the chip and the compiler nearly always ends in failure. Likewise it is VERY difficult to beat the compiler by writing you own assembler

Back to the problem: the map is the key - you need to see what has been put into a psect other than .text or .rodata. Those are the only two that are supported
Edited 2021-03-12 22:15 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 12:29pm 12 Mar 2021
Copy link to clipboard 
Print this post

Thanks Peter,

I'm aware of the broader meaning of "static", but I believe if you don't mark a function as static then gcc won't inline it (or will also compile a non-inlined copy) because it believes it might need to be called from elsewhere.

> Likewise it is VERY difficult to beat the compiler by writing you own assembler

I understand that is the conventional wisdom, I don't have the experience to gainsay it, but that doesn't mean I may not experiment in the future.

At the moment after the early gains I reported I'm finding spforth very stubborn to optimise- the Forth words I believed I could inline all turn out to be compile time words so don't impact execution speed. I'm sure a Forth should be able to do better than x1.5 a BASIC, but perhaps that belief is based on old non-tokenised BASICs that weren't doing things like hash-table variable lookups.

> Back to the problem: the map is the key ...

How do I generate "the map"?

Best wishes,

Tom
Edited 2021-03-12 22:30 by thwill
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 12:33pm 12 Mar 2021
Copy link to clipboard 
Print this post

Are you using any STATIC variables? - they will go into .bss

for a map file add "-Map output.map " or similar to the link command
Edited 2021-03-12 22:37 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 01:22pm 12 Mar 2021
Copy link to clipboard 
Print this post

  matherp said  Are you using any STATIC variables? - they will go into .bss


Not explicitly, though I can't speak for what the compiler is doing

  Quote  for a map file add "-Map output.map " or similar to the link command


Thanks, is it helpful ?

Memory Configuration

Name             Origin             Length             Attributes
rom              0x08000000         0x00100000         xr
ram              0x20000000         0x00020000         xrw
ram1             0x10000000         0x00010000         xrw
*default*        0x00000000         0xffffffff

Linker script and memory map

               0x20020000                _eram = 0x20020000

.text           0x08000000     0x72eb
*(.isr_vector)
*(.text*)
.text          0x08000000        0x0 forth_cmm2.o
.text.forth_docol
               0x08000000       0x18 forth_cmm2.o
.text.util_memset
               0x08000018       0x5c forth_cmm2.o
               0x08000018                util_memset
.text.util_strcpy
               0x08000074       0x10 forth_cmm2.o
               0x08000074                util_strcpy
.text.util_strncpy
               0x08000084       0x70 forth_cmm2.o
               0x08000084                util_strncpy
.text.util_strlen
               0x080000f4       0x18 forth_cmm2.o
               0x080000f4                util_strlen
.text.forth_word_internal
               0x0800010c      0x1a0 forth_cmm2.o
               0x0800010c                forth_word_internal
.text.forth_number_internal
               0x080002ac       0x8c forth_cmm2.o
               0x080002ac                forth_number_internal
.text.forth_find_internal
               0x08000338       0x74 forth_cmm2.o
               0x08000338                forth_find_internal
.text.forth_tcfa_internal
               0x080003ac        0x8 forth_cmm2.o
               0x080003ac                forth_tcfa_internal
.text.forth_create_internal
               0x080003b4      0x15c forth_cmm2.o
               0x080003b4                forth_create_internal
.text.forth_comma_internal
               0x08000510        0xc forth_cmm2.o
               0x08000510                forth_comma_internal
.text.forth_tell_internal
               0x0800051c       0x2c forth_cmm2.o
               0x0800051c                forth_tell_internal
.text.forth_parse_error
               0x08000548       0x8c forth_cmm2.o
               0x08000548                forth_parse_error
.text.forth_udot_internal
               0x080005d4       0x78 forth_cmm2.o
               0x080005d4                forth_udot_internal
.text.forth_execute_internal
               0x0800064c      0x90c forth_cmm2.o
               0x0800064c                forth_execute_internal
.text.forth_add_builtin
               0x08000f58       0x48 forth_cmm2.o
               0x08000f58                forth_add_builtin
.text.forth_add_codeword
               0x08000fa0       0x1c forth_cmm2.o
               0x08000fa0                forth_add_codeword
.text.forth_add_builtins
               0x08000fbc      0xca8 forth_cmm2.o
.text.forth_init
               0x08001c64       0x48 forth_cmm2.o
               0x08001c64                forth_init
.text.forth_init_run
               0x08001cac       0x38 forth_cmm2.o
               0x08001cac                forth_init_run
.text.forth_run_internal
               0x08001ce4       0xe8 forth_cmm2.o
               0x08001ce4                forth_run_internal
.text.forth_run
               0x08001dcc        0x8 forth_cmm2.o
               0x08001dcc                forth_run
.text.forth_run_string
               0x08001dd4       0x3c forth_cmm2.o
               0x08001dd4                forth_run_string
.text.forth_add_extended_words
               0x08001e10     0x4510 forth_cmm2.o
               0x08001e10                forth_add_extended_words
.text.startup.main
               0x08006320       0x30 forth_cmm2.o
               0x08006320                main
*(.init)
*(.fini)
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend.o *crtend?.o) .ctors)
*(SORT_BY_NAME(.ctors.*))
*(.ctors)
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend.o *crtend?.o) .dtors)
*(SORT_BY_NAME(.dtors.*))
*(.dtors)
*(.rodata*)
.rodata.str1.4
               0x08006350      0xf9b forth_cmm2.o
                               0xff3 (size before relaxing)
*(.eh_fram e*)

.glue_7         0x080072ec        0x0
.glue_7        0x080072ec        0x0 linker stubs

.glue_7t        0x080072ec        0x0
.glue_7t       0x080072ec        0x0 linker stubs

.vfp11_veneer   0x080072ec        0x0
.vfp11_veneer  0x080072ec        0x0 linker stubs

.v4_bx          0x080072ec        0x0
.v4_bx         0x080072ec        0x0 linker stubs

.iplt           0x080072ec        0x0
.iplt          0x080072ec        0x0 forth_cmm2.o

.rel.dyn        0x080072ec        0x0
.rel.iplt      0x080072ec        0x0 forth_cmm2.o

.ARM.extab
*(.ARM.extab* .gnu.linkonce.armextab.*)
               0x080072eb                __exidx_start = .

.ARM.exidx
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
               0x080072eb                __exidx_end = .
               0x080072eb                __etext = .
               0x080072eb                _sidata = __etext

.data           0x20000000        0x0 load address 0x080072eb
               0x20000000                __data_start__ = .
               0x20000000                _sdata = __data_start__
*(vtable)
*(.data*)
.data          0x20000000        0x0 forth_cmm2.o
               0x20000000                . = ALIGN (0x4)
               [!provide]                PROVIDE (__preinit_array_start = .)
*(.preinit_array)
               [!provide]                PROVIDE (__preinit_array_end = .)
               0x20000000                . = ALIGN (0x4)
               [!provide]                PROVIDE (__init_array_start = .)
*(SORT_BY_NAME(.init_array.*))
*(.init_array)
               [!provide]                PROVIDE (__init_array_end = .)
               0x20000000                . = ALIGN (0x4)
               [!provide]                PROVIDE (__fini_array_start = .)
*(SORT_BY_NAME(.fini_array.*))
*(.fini_array)
               [!provide]                PROVIDE (__fini_array_end = .)
*(.jcr*)
               0x20000000                . = ALIGN (0x4)
               0x20000000                __data_end__ = .
               0x20000000                _edata = __data_end__

.igot.plt       0x20000000        0x0 load address 0x080072ec
.igot.plt      0x20000000        0x0 forth_cmm2.o

.bss            0x20000000       0x40 load address 0x080072f0
               0x20000000                . = ALIGN (0x4)
               0x20000000                __bss_start__ = .
               0x20000000                _sbss = __bss_start__
*(.bss*)
.bss           0x20000000       0x40 forth_cmm2.o
               0x20000000                val
*(COMMON)
               0x20000040                . = ALIGN (0x4)
               0x20000040                __bss_end__ = .
               0x20000040                _ebss = __bss_end__

.heap           0x20000040        0x0
               0x20000040                __end__ = .
               0x20000040                _end = __end__
               0x20000040                end = __end__
*(.heap*)
               0x20000040                __HeapLimit = .

.co_stack       0x20000040        0x0
               0x20000040                . = ALIGN (0x8)
*(.co_stack .co_stack.*)
               0x20020000                __StackTop = (ORIGIN (ram) + LENGTH (ram))
               0x20020000                __StackLimit = (__StackTop - SIZEOF (.co_stack))
               [!provide]                PROVIDE (__stack = __StackTop)
               0x00000001                ASSERT ((__StackLimit >= __HeapLimit), region ram  overflowed with stack)
LOAD forth_cmm2.o
OUTPUT(forth_cmm2.elf elf32-littlearm)
LOAD linker stubs

.comment        0x00000000       0x4d
.comment       0x00000000       0x4d forth_cmm2.o
                                0x4e (size before relaxing)

.ARM.attributes
               0x00000000       0x32
.ARM.attributes
               0x00000000       0x32 forth_cmm2.o


Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 01:27pm 12 Mar 2021
Copy link to clipboard 
Print this post

There appears to be a variable val in .bss that is 64 bytes long.

Are you doing something like:

char val[64]={something};
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 01:43pm 12 Mar 2021
Copy link to clipboard 
Print this post

The only 'val' in the codebase is the name of a function parameter and that's a 4 byte value.

Could the compiler/optimiser be adding it for some reason? the garbage isn't present at -O0 but starts to appear at -O1 -O2 and -O3.

Aside: I think I have a suspicion about my performance problems, the main instruction dispatch loop is a huge case statement:

switch (x) {
       case 1 : drop(); break;
       case 2 : dup();  break;
       case 3 : save(); break;
       case 4 : over(); break;
       ...
}


though the numbers are #defined.

I don't think the optimiser is doing anything special with this. Switching to an enum should cause the optimiser to use a branch table or binary search. I think the former, because I suspect it is storing function pointers in such a table, which of course aren't working - all supposition of course.

Anyway that's me done until this evening, thanks for your help,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10310
Posted: 02:09pm 12 Mar 2021
Copy link to clipboard 
Print this post

Is val related to a switch statement? Could be a jump table that is being created in .bss?

Can I assume there is nothing in .bss when you use O0? i.e.bss is zero length

.bss            0x20000000       0x40 load address 0x080072f0
              0x20000000                . = ALIGN (0x4)
              0x20000000                __bss_start__ = .
              0x20000000                _sbss = __bss_start__
*(.bss*)
.bss           0x20000000       0x40 forth_cmm2.o
              0x20000000                val
*(COMMON)
              0x20000040                . = ALIGN (0x4)
              0x20000040                __bss_end__ = .
              0x20000040                _ebss = __bss_end__


In any event you need to play with the code until .bss is zero length
Edited 2021-03-13 03:55 by matherp
 
GerryL
Newbie

Joined: 24/01/2019
Location: Australia
Posts: 39
Posted: 01:50am 13 Mar 2021
Copy link to clipboard 
Print this post

Hi Tom, just as an aside is your function "forth_add_codeword" pretty small (about 26 bytes long) or really large (approx 3200 bytes)?


Gerry
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 07:04am 13 Mar 2021
Copy link to clipboard 
Print this post

  GerryL said  Hi Tom, just as an aside is your function "forth_add_codeword" pretty small (about 26 bytes long) or really large (approx 3200 bytes)?


Pretty small:

void forth_add_codeword(forth_t *self, char *name) {
   dictionary_entry_t *pentry = forth_find_internal(self, name, -1);
   forth_comma_internal(self, (cell_t) &pentry->codeword);
}


Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
GerryL
Newbie

Joined: 24/01/2019
Location: Australia
Posts: 39
Posted: 01:28am 14 Mar 2021
Copy link to clipboard 
Print this post

I note that even with the following code the .bss size in the ELF file is 0x40 so just wonder if it defaults to that, in fact with a number of my C functions its 0x40.
#include "ARMCFunctions.h"


void main(long long int *c, MMFLOAT *b){
*c = 20;
*b = 20.0;

}


Gerry
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025