Recent

Author Topic: light pascal  (Read 18155 times)

PascalDragon

  • Hero Member
  • *****
  • Posts: 5446
  • Compiler Developer
Re: light pascal
« Reply #30 on: December 24, 2019, 02:09:07 pm »
Also for the embedded target one can explicitely decide which features should be enabled when compiling the RTL (take a look at $fpcdir/rtl/embedded/system.cfg), thus avoiding that it's used by accident.

In FPC 3.0.4 I did not find a system.cfg in this folder, but a rtl.cfg. Do you mean this?
In 3.0.4 it's indeed the rtl.cfg. For trunk that was changed to system.cfg which is used to compile the System unit and rtl.cfg which is used for the remainder of the RTL (currently only used for i8086 to ensure that smartlinking is enabled) as the enabled features are now stored in the System unit.

FPK

  • Full Member
  • ***
  • Posts: 118
Re: light pascal
« Reply #31 on: December 24, 2019, 11:33:59 pm »
*sigh* again the myth of the large binaries. An empty program for avr25 results in

<fpc trunk for avr> -Wpattiny28 tavr.pp -O4
Free Pascal Compiler version 3.3.1 [2019/12/24] for avr
Copyright (c) 1993-2019 by Florian Klaempfl and others
Target OS: Embedded
Compiling tavr.pp
Assembling program
Linking tavr
2 lines compiled, 0.0 sec, 38 bytes code, 0 bytes data

The 38 bytes come from the interrupt handlers.

The point you mentioned is empty program.

Of course, I did so, because this is the example people typically use trying to make their point.

julkas

  • Guest
Re: light pascal
« Reply #32 on: December 25, 2019, 10:37:46 am »
OKEY
From now on, I check 2x how the code I write affects the size of the output.
My first working FPC AVR target port (without strings, advanced records, heap, ...) http://elm-chan.org/fsw/ff/00index_p.html  - hex image size is ~ 9k vs C ~ 2 - 4k.

FPK

  • Full Member
  • ***
  • Posts: 118
Re: light pascal
« Reply #33 on: December 25, 2019, 04:32:06 pm »
OKEY
From now on, I check 2x how the code I write affects the size of the output.
My first working FPC AVR target port (without strings, advanced records, heap, ...) http://elm-chan.org/fsw/ff/00index_p.html  - hex image size is ~ 9k vs C ~ 2 - 4k.

Not unlikely for a first try. Pascal is not C and some innocent looking code might pull in unwanted parts of the RTL. I hope you checked the map file for such problems?

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: light pascal
« Reply #34 on: December 25, 2019, 05:31:51 pm »
Did you use trunk? The newest doesn't pull in exception handling for divisions/modulus by constants for example

devport

  • New Member
  • *
  • Posts: 26
Re: light pascal
« Reply #35 on: December 25, 2019, 05:48:11 pm »
I'm using build from December 22, 2019

julkas

  • Guest
Re: light pascal
« Reply #36 on: December 25, 2019, 07:25:02 pm »
Did you use trunk? The newest doesn't pull in exception handling for divisions/modulus by constants for example
Code: Text  [Select][+][-]
  1. $  ppcrossavr.exe -i
  2. Free Pascal Compiler version 3.3.1
  3.  
  4. Compiler date      : 2019/09/22
  5. Compiler CPU target: avr
  6.  
Any reason for update?

Thaddy

  • Hero Member
  • *****
  • Posts: 14197
  • Probably until I exterminate Putin.
Re: light pascal
« Reply #37 on: December 26, 2019, 08:54:55 am »
2019/09/22 is not exactly new is it? Trunk is a moving target and if you want to use it, plz compile on a daily basis, not three monthly.
Specialize a type, not a var.

julkas

  • Guest
Re: light pascal
« Reply #38 on: January 01, 2020, 02:32:37 pm »
2019/09/22 is not exactly new is it? Trunk is a moving target and if you want to use it, plz compile on a daily basis, not three monthly.
After update -
Code: Text  [Select][+][-]
  1. $  ppcrossavr.exe -i
  2. Free Pascal Compiler version 3.3.1
  3.  
  4. Compiler date      : 2020/01/01
  5. Compiler CPU target: avr
  6.  
Code: Text  [Select][+][-]
  1. 2120 lines compiled, 0.4 sec, 9694 bytes code, 539 bytes data
  2.  

Any hint, advice?

Happy New Year to great Pascal community !

BTW - Careful with whitespaces on Windows !
« Last Edit: January 01, 2020, 02:59:37 pm by julkas »

FPK

  • Full Member
  • ***
  • Posts: 118
Re: light pascal
« Reply #39 on: January 01, 2020, 03:35:15 pm »
Pascal is not C and some innocent looking code might pull in unwanted parts of the RTL. I hope you checked the map file for such problems?

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: light pascal
« Reply #40 on: January 01, 2020, 04:04:44 pm »
Show the code that generates that much

julkas

  • Guest
Re: light pascal
« Reply #41 on: January 01, 2020, 04:10:48 pm »

d.ioannidis

  • Full Member
  • ***
  • Posts: 221
    • Nephelae
Re: light pascal
« Reply #42 on: January 09, 2020, 10:41:14 pm »
Did you use trunk? The newest doesn't pull in exception handling for divisions/modulus by constants for example
< snip >
Any reason for update?

Well for this example, a TX-only software ( bit-bang'ed ) UART for attiny85 I had ( if I remember correctly, don't have a 3.0.4 ppcrossavr handy ) approx. ~20% size reduction :

Code: Pascal  [Select][+][-]
  1. // bit bang'ing Software-UART TX example
  2. //
  3. // Adapted / Ported from
  4. //
  5. // a tiny software UART TX for the AVR ATtiny
  6. // https://marcelmg.github.io/software_uart/
  7.  
  8. program fp_attiny85_test;
  9.  
  10. {$MODE OBJFPC}
  11. {$MACRO ON}
  12. {$INLINE ON}
  13. {$LONGSTRINGS OFF}
  14. {$WRITEABLECONST OFF}
  15.  
  16. // Timer interrupt service routine name.
  17. {$DEFINE TIMER_INT := 'TIMER0_COMPA_ISR'}
  18.  
  19. // Change these to use another pin.
  20. {$DEFINE TX_PORT    := PORTB }
  21. {$DEFINE TX_PIN     := 0     }
  22. {$DEFINE TX_DDR     := DDRB  }
  23. {$DEFINE TX_DDR_PIN := 0     }
  24.  
  25. uses
  26.   intrinsics;
  27.  
  28. // Read directly from flash and not from SRAM.
  29. // HAS_LPMX also means that movw is available.
  30. {$if defined(CPUAVR_HAS_LPMX)}
  31. const
  32.   HelloWorldStr: string[14] = 'Hello World ! '; section '.progmem';
  33.   FPCStr: string[22] = 'Free Pascal Rocks !!! '; section '.progmem';
  34.  
  35.   function read_progmem_byte(constref v: byte): byte; assembler; nostackframe;
  36.   asm
  37.     MOVW    ZL, r24
  38.     LPM     r24, Z
  39.   end;
  40.  
  41.   function read_progmem_str(constref s: shortstring): ShortString;
  42.   var
  43.     len, i: byte;
  44.   begin
  45.     len := read_progmem_byte(byte(s[0]));
  46.     setlength(Result, len);
  47.     for i := 1 to len do
  48.       Result[i] := char(read_progmem_byte(byte(s[i])));
  49.   end;
  50. {$ENDIF}
  51.  
  52.   procedure AtomicWrite(var Value: word; new_value: word);
  53.   var
  54.     b: byte;
  55.   begin
  56.     b := avr_save;
  57.     Value := new_value;
  58.     avr_restore(b);
  59.   end;
  60.  
  61.   function AtomicRead(var Value: word): word;
  62.   var
  63.     b: byte;
  64.   begin
  65.     b := avr_save;
  66.     Result := Value;
  67.     avr_restore(b);
  68.   end;
  69.  
  70. var
  71.   // Used as a TX shift register.
  72.   tx_shift_reg: word;
  73.  
  74.   function UART_tx(constref ACharacter: char): boolean;
  75.   var
  76.     local_tx_shift_reg: word;
  77.   begin
  78.     Result := True;
  79.     local_tx_shift_reg := AtomicRead(tx_shift_reg);
  80.  
  81.     // Check if sending the previous character is not yet finished.
  82.     // Transmission is finished when tx_shift_reg = 0.
  83.     if local_tx_shift_reg <> 0 then
  84.       Result := False
  85.     else
  86.     begin
  87.  
  88.       // Fill the TX shift register with the character to be sent and
  89.       // the start & stop bits (start bit (1<<0) is already 0).
  90.       local_tx_shift_reg := (word(ACharacter) shl 1) or (1 shl 9);
  91.       AtomicWrite(tx_shift_reg, local_tx_shift_reg);
  92.  
  93.       // Start Timer0 with a prescaler of 8.
  94.       TCCR0B := (1 shl CS0 + 1);
  95.     end;
  96.   end;
  97.  
  98.   procedure UART_tx_str(constref AString: ShortString);
  99.   var
  100.     iLen, x: byte;
  101.   begin
  102.     iLen := Length(AString);
  103.     x := 1;
  104.     while (iLen >= x) do
  105.       // Send the next character after the
  106.       // the previous character transmission is finished.
  107.       if UART_tx(AString[x]) then
  108.         Inc(x);
  109.   end;
  110.  
  111.   procedure UART_init;
  112.   begin
  113.     // Set TX pin as output.
  114.     TX_DDR := TX_DDR or (1 shl TX_DDR_PIN);
  115.     TX_PORT := TX_PORT or (1 shl TX_PIN);
  116.  
  117.     // Set Timer0 to CTC mode.
  118.     TCCR0A := (1 shl WGM0 + 1);
  119.  
  120.     // Enable output compare 0 A interrupt.
  121.     TIMSK := TIMSK or (1 shl OCF0A);
  122.  
  123.     // Set compare value to 103 to achieve a 9600 baud rate (i.e. 104µs),
  124.     // together with the 8MHz/8=1MHz Timer0 clock.
  125.     {NOTE: since the internal 8MHz oscillator is not very accurate, this value can be tuned
  126.       to achieve the desired baud rate, so if it doesn't work with the nominal value (103), try
  127.       increasing or decreasing the value by 1 or 2 }
  128.     OCR0A := 103;
  129.   end;
  130.  
  131.   procedure TIMER0_COMPA_ISR; public Name TIMER_INT; Interrupt;
  132.   begin
  133.     // Output LSB of the TX shift register at the TX pin.
  134.     if (tx_shift_reg and 1) = 1 then
  135.       TX_PORT := TX_PORT or (1 shl TX_PIN)
  136.     else
  137.       TX_PORT := TX_PORT and not (1 shl TX_PIN);
  138.  
  139.     // Shift the TX shift register one bit to the right.
  140.     tx_shift_reg := (tx_shift_reg shr 1);
  141.  
  142.     // If the stop bit has been sent, the shift register will be 0
  143.     // and the transmission is completed, so we can stop & reset Timer0.
  144.     if tx_shift_reg = 0 then
  145.     begin
  146.       TCCR0B := 0;
  147.       TCNT0 := 0;
  148.     end;
  149.   end;
  150.  
  151.   // Generated by delay loop calculator
  152.   // at http://www.bretmulvey.com/avrdelay.html
  153.  
  154.   // Delay 4 000 000 cycles
  155.   // 500ms at 8.0 MHz
  156.   procedure _delay_loop; assembler; nostackframe;
  157.   label
  158.     L1;
  159.   asm
  160.     LDI     r18, 21
  161.     LDI     r19, 75
  162.     LDI     r20, 191
  163.   L1:
  164.     DEC     r20
  165.     BRNE    L1
  166.     DEC     r19
  167.     BRNE    L1
  168.     DEC     r18
  169.     BRNE    L1
  170.     NOP
  171.   end;
  172.  
  173. begin
  174.   UART_init;
  175.  
  176.   // Enable Global Interrupts.
  177.   avr_sei;
  178.  
  179.   repeat
  180. // Read directly from flash and not from SRAM.
  181. // HAS_LPMX also means that movw is available.
  182. {$if defined(CPUAVR_HAS_LPMX)}
  183.     UART_tx_str(read_progmem_str(HelloWorldStr));
  184.     UART_tx_str(read_progmem_str(FPCStr));
  185. {$elseif}
  186.     UART_tx_str('Hello World ! ');
  187.     UART_tx_str('Free Pascal Rocks !!! ');
  188. {$endif}
  189.     _delay_loop;
  190.   until False;
  191. end.    

Project build options

Code: Pascal  [Select][+][-]
  1. -Tembedded
  2. -Pavr
  3. -MObjFPC
  4. -Scghi
  5. -CX
  6. -Os4
  7. -gt
  8. -Xs
  9. -XX
  10. -l
  11. -vewnhibq
  12. -Fi..\lib\avr-embedded
  13. -Fu..\source
  14. -Fu.
  15. -FU..\lib\avr-embedded
  16. -FE..\bin
  17. -o..\bin\fp_attiny85_test
  18. -a
  19. -al
  20. -Xe
  21. -Xm
  22. -Sm
  23. -CpAVR25
  24. -WpATTINY85
  25. -XPavr-
  26. -FDG:\Programming\dimitris\tools\avr8-gnu-toolchain\bin
  27. -dF_CPU:=8000000
  28.  


and avrsize reports :

Code: Pascal  [Select][+][-]
  1. Compile Project, Mode: Release, OS: embedded, CPU: avr, Target: G:\Programming\dimitris\Projects\fp_attiny85_test\bin\fp_attiny85_test: Success, Hints: 1
  2. fp_attiny85_test.lpr(131,13) Hint: Local proc "TIMER0_COMPA_ISR" is not used
  3. Project: Executing command after: Success
  4. AVR Memory Usage
  5. ----------------
  6. Device: attiny85
  7.  
  8. Program:     626 bytes (7.6% Full)
  9. (.text + .data + .bootloader)
  10.  
  11. Data:          2 bytes (0.4% Full)
  12. (.data + .bss + .noinit)

FPC Compiler builded with OPT="-O1 -CX -XX" :
Code: Pascal  [Select][+][-]
  1. FPC executable:
  2. Compiler=G:\Programming\dimitris\tools\fpc-trunk\bin\x86_64-win64\fpc.exe
  3. Options=
  4. CompilerDate=5/1/2020 20:00:02
  5. RealCompiler=G:\Programming\dimitris\tools\fpc-trunk\bin\x86_64-win64\ppcrossavr.exe
  6. RealCompilerDate=8/1/2020 20:18:24
  7. RealTargetOS=embedded
  8. RealTargetCPU=avr
  9. RealCompilerInPath=G:\Programming\dimitris\tools\fpc-trunk\bin\x86_64-win64\ppcrossavr.exe
  10. Version=3.3.1
  11. CfgFilename=G:\Programming\dimitris\tools\fpc-trunk\bin\x86_64-win64\fpc.cfg

julkas

  • Guest
Re: light pascal
« Reply #43 on: January 13, 2020, 03:10:30 pm »
*sigh* again the myth of the large binaries. An empty program for avr25 results in

<fpc trunk for avr> -Wpattiny28 tavr.pp -O4
Free Pascal Compiler version 3.3.1 [2019/12/24] for avr
Copyright (c) 1993-2019 by Florian Klaempfl and others
Target OS: Embedded
Compiling tavr.pp
Assembling program
Linking tavr
2 lines compiled, 0.0 sec, 38 bytes code, 0 bytes data

The 38 bytes come from the interrupt handlers.

Try following -
Code: Pascal  [Select][+][-]
  1. program tt;
  2.  
  3. var
  4.   x: DWORD;
  5.  
  6. begin
  7.   x := x div 17;
  8. end.  

Result - I think it's not acceptable
Code: Text  [Select][+][-]
  1. $ ppcrossavr.exe -Tembedded -Cpavr5 -vi -aln -Wpatmega328p -XPavr- -O3 -Xm tt.pas
  2. Target OS: Embedded
  3. Compiling tt.pas
  4. Assembling tt
  5. Linking tt
  6. 7 lines compiled, 0.1 sec, 1814 bytes code, 50 bytes data
« Last Edit: January 13, 2020, 06:21:30 pm by julkas »

FPK

  • Full Member
  • ***
  • Posts: 118
Re: light pascal
« Reply #44 on: January 13, 2020, 09:08:13 pm »
Whether it is acceptable or not does not matter. div handling with all it's infrastructure needed in object pascal is that big. FPC generates an ldi, three moves and a call for the div.

Of course, one could cheat and implement some special tailored div. procedure for such useless benchmarks so the exception handling infrastructure is left out but this makes no difference in real world programs.

 

TinyPortal © 2005-2018