Re: [fpc-devel] FPC and Z80

2020-04-20 Thread nickysn--- via fpc-devel
On Thu, 2020-04-16 at 11:04 +0200, Guillermo wrote:
> Thanks Swen.
> 
> I see last commit was 2 days ago so it is active.  I would like to
> know
> who is responsible to speak to him. May be I can help with the MSX
> target, but I need gidance about the internals of the compiler (I
> tried
> but it is beyond my comprehension right now).

Hi,

The Z80 branch was started by Florian about 2 years ago, but I've
recently picked it up and I'm working on it. I'm targeting the ZX
Spectrum as a first platform, for no particular reason, other than
that's what I could get a working emulator for. Back in the 8-bit era I
never had a Z80 computer, only 6502, but that is harder to support, so
I decided to work on the Z80 target first, because that was already
started by Florian. And besides, I've recently obtained an 8-bit
computer that has it. It's a Pravetz 8M, that's a dual cpu (6502+Z80)
machine, that is like an Apple II+ clone with a built-in Z80 CP/M card,
so later I'm planning to support CP/M as well. The only reason I'm not
starting with the CP/M target is that I don't have an emulator for it,
and development is much faster when you have an emulator. To run code
on the real Z80 computer, I need to write the program to a floppy disk,
which is tedious and slow if you're doing it constantly.

In theory, any Z80 computer can be easily supported. It's the Z80 code
generator that is the hard part. The MSX should be pretty easy to
support I think.

The current state of the Z80 port is that it's partially working, but
it's not complete enough in order to be able to compile a full RTL.
However, simple stuff like this is working on the ZX Spectrum:

program hello;
var
  i: byte;
begin
  PrintChar('F');
  PrintChar('P');
  PrintChar('C');
  for b := 0 to 255 do
PrintHexByte(b);
end.

So, it's just getting started to become interesting :)

I you want to help, feel free to try it and ask any questions that you
might have. Just keep in mind it's still very early and immature, so
don't expect it to work for serious and complex code yet. But we'll
eventually get there as well. :)

Btw, I also did the i8086 (i.e. 16-bit x86) port a few years ago and in
a way, it was much more difficult, because, at the time, the compiler
wasn't really designed to target anything with less than a 32-bit CPU
and 32-bit ALU. The 8-bit AVR target had been started, but wasn't
mature enough yet, and wasn't really working. Nowadays, FPC supports 8-
bit (AVR), 16-bit (i8086), 32-bit and 64-bit architectures, so the work
is easier in many ways. However, the Z80 still has some unique
challenges, so we'll see how it works out. :)

Nikolay

> 
> Guillermo M.
> 
> El Tue, 14 Apr 2020 22:46:47 +0200
> Sven Barth  escribió:
> > Am 13.04.2020 um 13:08 schrieb Guillermo:
> > > Hi Pascaloids,
> > > 
> > > I've read in the web forums[1] that FPC may include Zylog Z80 as
> > > target, specifically Sinclair's micro computers, but looking at
> > > the
> > > SVN[2] I don't see any Z80 reference.  
> > It's currently in development in a branch: 
> > https://svn.freepascal.org/cgi-bin/viewvc.cgi/branches/z80/
> > 
> > Regards,
> > Sven
> 
> ___
> fpc-devel maillist  -  fpc-devel@lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] FPC and Z80

2020-04-20 Thread nickysn--- via fpc-devel
On Thu, 2020-04-16 at 11:04 +0200, Guillermo wrote:
> Thanks Swen.
> 
> I see last commit was 2 days ago so it is active.  I would like to
> know
> who is responsible to speak to him. May be I can help with the MSX
> target, but I need gidance about the internals of the compiler (I
> tried
> but it is beyond my comprehension right now).

I started a wiki page about the Z80 port:

https://wiki.freepascal.org/Z80

It should be a good starting point. I'll try to add more information to
it as I go along.

Nikolay

> 
> Guillermo M.
> 
> El Tue, 14 Apr 2020 22:46:47 +0200
> Sven Barth  escribió:
> > Am 13.04.2020 um 13:08 schrieb Guillermo:
> > > Hi Pascaloids,
> > > 
> > > I've read in the web forums[1] that FPC may include Zylog Z80 as
> > > target, specifically Sinclair's micro computers, but looking at
> > > the
> > > SVN[2] I don't see any Z80 reference.  
> > It's currently in development in a branch: 
> > https://svn.freepascal.org/cgi-bin/viewvc.cgi/branches/z80/
> > 
> > Regards,
> > Sven
> 
> ___
> fpc-devel maillist  -  fpc-devel@lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Martin
FPC sometimes generates jump instructions as follows. (Not always bound 
to "IF" but that is the example I found


IF something then begin {long code} end;

The conditional asm jump does not jump all the way to the code after the 
"end".
Instead it points to an unconditional jump, that (according to line 
info) is at the end of some other line.


Such "jump pads" (?) seem common (gdb seems to know about them).

I try to detect them in fpDebug.
Which assumptions are reasonable?

- How long can a series of such "jump forwarders" be.
  Can the unconditional jump, go to another unconditional jump, before 
eventually hitting the line that the pascal code would go to?

  How many to expect max, before getting suspicious?

- If such jumps are within line info, they should not be at the start of 
a line?

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Florian Klämpfl

Am 20.04.20 um 16:44 schrieb Martin:
FPC sometimes generates jump instructions as follows. (Not always bound 
to "IF" but that is the example I found


IF something then begin {long code} end;

The conditional asm jump does not jump all the way to the code after the 
"end".
Instead it points to an unconditional jump, that (according to line 
info) is at the end of some other line.


This might be some artifact introduced by the optimizer. Problem is, the 
jumps are generated at a certain point and then the optimizer starts to 
"mess" with them. During this, it might be that line info is mixed up.




Such "jump pads" (?) seem common (gdb seems to know about them).

I try to detect them in fpDebug.
Which assumptions are reasonable?

- How long can a series of such "jump forwarders" be.
   Can the unconditional jump, go to another unconditional jump, before 
eventually hitting the line that the pascal code would go to?

   How many to expect max, before getting suspicious?


Unlimited in theory.



- If such jumps are within line info, they should not be at the start of 
a line?


Do you have some example code which shows this (together with the needed 
optimizer switches)?

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Problems building xtensa-freertos RTL in trunk

2020-04-20 Thread Florian Klämpfl

Am 20.04.20 um 00:03 schrieb Michael Ring via fpc-devel:

Thanks!

Your commit is close, but not yet there...

to make it work it was necessary for me to re-create the Makefiles, 
arm-freertos was missing in the root makefile and some others, did you 
rebuild fpcmake before using it?


Pierre recreated the makefiles already, so it should be fine, right?



You also did not include the rtl/freertos/arm directory (I guess on 
purpose, it is currently an evil clone of rtl/embedded/arm):


Ok. I added them.



without that directory and it's content the build breaks. I checked if 
you did some magic to re-use the rtl/embedded/arm directory but this 
does not seem to be the case.


No, I applied the patch and forgot to add them.



Currently it is also perhaps a good idea to have a new directory for 
freertos compatible units, from what I know today I will have to change 
the interrupt-names defined in the unitfiles to be CMSIS (and for that 
FreeRTOS) compatible.


This means that we will likely have to rename interrupt names like:

PendSV_Interrupt

to

PendSV_Handler

so that FreeRTOS can properly provide it's own routines for handling 
SysTick, PendSV and SVCall Interrupt Handlers.


Yes.

Another thing: some of the files miss a header, so the correct license. 
If some of them are made by you, can you please provide a header?

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread J. Gareth Moreton

To add my own two pence, although I'm not sure if it's related or not.

Some architectures are very limited in how far a conditional jump can 
branch compared to an unconditional jump (e.g. the offset might only be 
a signed byte).  I ran into this problem on certain ARM platforms when 
developing my recent cross-platform jump optimisations.


Jump pads are one means to avoid assembler errors by ensuring the 
conditional jump stays within range.  The other one, which seems more 
common in FPC, is to (in assembler form), change a conditional jump to 
@1 to "If not condition then goto @2; jump @1; @2:", thereby ensuring 
the conditional jump is within range by having it only jump across one 
instruction (the unconditional jump).


The problem is that it is not always easy to determine if a jump is in 
range during compilation - the problem might be NP-hard, not sure - even 
on architectures like ARM where each machine code instruction is the 
same length.  For example, if you have a procedure where a conditional 
jump to some future label is in range, but only just, and a 2nd 
conditional jump in between is not in range and requires changing to the 
"if not condition" construct described above, the addition of the new 
jump instruction may be enough to cause the 1st jump to become out of 
range.  Jump pads (I like that term, even if it sounds like it belongs 
in a Sonic the Hedgehog game!) suffer from a similar problem depending 
on where they are inserted.


Gareth aka. Kit

On 20/04/2020 21:11, Florian Klämpfl wrote:

Am 20.04.20 um 16:44 schrieb Martin:
FPC sometimes generates jump instructions as follows. (Not always 
bound to "IF" but that is the example I found


IF something then begin {long code} end;

The conditional asm jump does not jump all the way to the code after 
the "end".
Instead it points to an unconditional jump, that (according to line 
info) is at the end of some other line.


This might be some artifact introduced by the optimizer. Problem is, 
the jumps are generated at a certain point and then the optimizer 
starts to "mess" with them. During this, it might be that line info is 
mixed up.




Such "jump pads" (?) seem common (gdb seems to know about them).

I try to detect them in fpDebug.
Which assumptions are reasonable?

- How long can a series of such "jump forwarders" be.
   Can the unconditional jump, go to another unconditional jump, 
before eventually hitting the line that the pascal code would go to?

   How many to expect max, before getting suspicious?


Unlimited in theory.



- If such jumps are within line info, they should not be at the start 
of a line?


Do you have some example code which shows this (together with the 
needed optimizer switches)?

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Martin Frb

On 20/04/2020 22:11, Florian Klämpfl wrote:

Am 20.04.20 um 16:44 schrieb Martin:
FPC sometimes generates jump instructions as follows. (Not always 
bound to "IF" but that is the example I found
- If such jumps are within line info, they should not be at the start 
of a line?


Do you have some example code which shows this (together with the 
needed optimizer switches)?


I have not yet tried in a small example. I got it in the Lazarus IDE 
from svn (with fpc 3.0.4)

components\fpdebug\fpdbgcontroller.pas
line 795 and following
-gh -g -gw -godwarfsets  -gl   -dCR   -Ct -Co -Cr -Ci  -gt  -Sa  -ve -vw 
-vn  -vi   -O-  -CX  -WC


See the lines marked with //

It may be the nested "IF"
If the inner "IF" evals false, it skips over it's "then" block. It jumps 
" jmp +$61 " to after the "then begin end" block.


That might actually be the line, that is the "end" of the outer "then" 
block, so that jump is skipping over the outer "else" block.


However, this jump, has the same line info as the "exit" line. Even so 
the "exit" is in the "then" block, and this "jmp" line is outside of it.

I checked the line info with objdump.

So I guess, having had a 2nd look, I got a better explanation.
Technically this "jmp" would probably belong to the "end" of the outer 
"then" block. But "end" for such blocks usually has no line info.






procedure TDbgControllerStepOutCmd.InternalContinue(AProcess: TDbgProcess;
  AThread: TDbgThread);
var
  Outside: Boolean;
begin
  assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: 
FProcess=AProcess');


  if (AThread = FThread) then begin
  if IsSteppedOut then begin
    CheckForCallAndSetBreak;
  end
  else
  if not assigned(FHiddenBreakpoint) then begin
    if GetOutsideFrame(Outside) then begin
  SetReturnAdressBreakpoint(AProcess, Outside);
    end
    else
    if FStepCount < 12 then
    begin
  Inc(FStepCount);
  if NextInstruction.IsCallInstruction or 
NextInstruction.IsLeaveStackFrame then  // asm "call" // set break 
before "leave" or the frame becomes unavail

  begin
    SetReturnAdressBreakpoint(AProcess, False);
  end
  else
  if NextInstruction.IsReturnInstruction then  / 
LINE 817 

  begin
    FStepCount := MaxInt; // Do one more single-step, and we're 
finished.

    FProcess.Continue(FProcess, FThread, True);
    exit;   /// LINE 821   here goes 
the forwarder

  end;
    end
    else
    begin
  // Enough with the single-stepping
  SetReturnAdressBreakpoint(AProcess, False);
    end;
  end;
  end;

  FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil); 
/ LINE 832 

end;

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:817 if 
NextInstruction.IsReturnInstruction then  // asm "ret"

000100D93578 488B45E8 mov rax,[rbp-$18]
000100D9357C 4883782800   cmp qword ptr [rax+$28],$00
000100D93581 7405 jz +$05
000100D93583 E99E00   jmp +$009E
000100D93588 488B45E8 mov rax,[rbp-$18]

000100D93649 E8420E27FF   call -$00D8F1BE
000100D9364E 4889F1   mov rcx,rsi
000100D93651 FF97E800 call dword ptr [rdi+$00E8]
000100D93657 84C0 test al,al
000100D93659 7502 jnz +$02
000100D9365B EB61 jmp +$61    
<<<


B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:819 
FStepCount := MaxInt; // Do one more single-step, and we're finished.

000100D9365D 488B45E8 mov rax,[rbp-$18]
000100D93661 C7808800FF7F mov [rax+$0088],$7FFF

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:820 
FProcess.Continue(FProcess, FThread, True);

000100D9366B 488B45E8 mov rax,[rbp-$18]
000100D9366F 4C8B6810 mov r13,[rax+$10]
000100D93673 488B45E8 mov rax,[rbp-$18]
..
000100D936B0 4C89E2   mov rdx,r12
000100D936B3 4D89E8   mov rax,r13
000100D936B6 FF939001 call dword ptr [rbx+$0190]

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:821 exit;
000100D936BC EB70 jmp +$70   /// jump to 
end of proc
000100D936BE EB13 jmp +$13    
 This is where the  jump forwards to line 832


B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:827 
SetReturnAdressBreakpoint(AProcess, False);

000100D936C0 488B55F8 mov rdx,[rbp-$08]
000100D936C4 488B4DE8 mov rcx,[rbp-$18]
000100D936C8 41B8 mov eax,$
000100D936CE E8CDF7   call -$0833

B:\lazarus

Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Florian Klämpfl

Am 20.04.20 um 22:45 schrieb Martin Frb:

On 20/04/2020 22:11, Florian Klämpfl wrote:

Am 20.04.20 um 16:44 schrieb Martin:
FPC sometimes generates jump instructions as follows. (Not always 
bound to "IF" but that is the example I found
- If such jumps are within line info, they should not be at the start 
of a line?


Do you have some example code which shows this (together with the 
needed optimizer switches)?


I have not yet tried in a small example. I got it in the Lazarus IDE 
from svn (with fpc 3.0.4)

components\fpdebug\fpdbgcontroller.pas
line 795 and following
-gh -g -gw -godwarfsets  -gl   -dCR   -Ct -Co -Cr -Ci  -gt  -Sa  -ve -vw 
-vn  -vi   -O-  -CX  -WC


Can you post also the relevant output of -al? It makes it easier to see 
where every assembler instruction comes from.




See the lines marked with //

It may be the nested "IF"
If the inner "IF" evals false, it skips over it's "then" block. It jumps 
" jmp +$61 " to after the "then begin end" block.


That might actually be the line, that is the "end" of the outer "then" 
block, so that jump is skipping over the outer "else" block.


However, this jump, has the same line info as the "exit" line. Even so 
the "exit" is in the "then" block, and this "jmp" line is outside of it.

I checked the line info with objdump.

So I guess, having had a 2nd look, I got a better explanation.
Technically this "jmp" would probably belong to the "end" of the outer 
"then" block. But "end" for such blocks usually has no line info.






procedure TDbgControllerStepOutCmd.InternalContinue(AProcess: TDbgProcess;
   AThread: TDbgThread);
var
   Outside: Boolean;
begin
   assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: 
FProcess=AProcess');


   if (AThread = FThread) then begin
   if IsSteppedOut then begin
     CheckForCallAndSetBreak;
   end
   else
   if not assigned(FHiddenBreakpoint) then begin
     if GetOutsideFrame(Outside) then begin
   SetReturnAdressBreakpoint(AProcess, Outside);
     end
     else
     if FStepCount < 12 then
     begin
   Inc(FStepCount);
   if NextInstruction.IsCallInstruction or 
NextInstruction.IsLeaveStackFrame then  // asm "call" // set break 
before "leave" or the frame becomes unavail

   begin
     SetReturnAdressBreakpoint(AProcess, False);
   end
   else
   if NextInstruction.IsReturnInstruction then  / 
LINE 817 

   begin
     FStepCount := MaxInt; // Do one more single-step, and we're 
finished.

     FProcess.Continue(FProcess, FThread, True);
     exit;   /// LINE 821   here goes 
the forwarder

   end;
     end
     else
     begin
   // Enough with the single-stepping
   SetReturnAdressBreakpoint(AProcess, False);
     end;
   end;
   end;

   FProcess.Continue(FProcess, FThread, FHiddenBreakpoint = nil); 
/ LINE 832 

end;

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:817 if 
NextInstruction.IsReturnInstruction then  // asm "ret"

000100D93578 488B45E8 mov rax,[rbp-$18]
000100D9357C 4883782800   cmp qword ptr [rax+$28],$00
000100D93581 7405 jz +$05
000100D93583 E99E00   jmp +$009E
000100D93588 488B45E8 mov rax,[rbp-$18]

000100D93649 E8420E27FF   call -$00D8F1BE
000100D9364E 4889F1   mov rcx,rsi
000100D93651 FF97E800 call dword ptr [rdi+$00E8]
000100D93657 84C0 test al,al
000100D93659 7502 jnz +$02
000100D9365B EB61 jmp +$61    
<<<


B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:819 
FStepCount := MaxInt; // Do one more single-step, and we're finished.

000100D9365D 488B45E8 mov rax,[rbp-$18]
000100D93661 C7808800FF7F mov [rax+$0088],$7FFF

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:820 
FProcess.Continue(FProcess, FThread, True);

000100D9366B 488B45E8 mov rax,[rbp-$18]
000100D9366F 4C8B6810 mov r13,[rax+$10]
000100D93673 488B45E8 mov rax,[rbp-$18]
..
000100D936B0 4C89E2   mov rdx,r12
000100D936B3 4D89E8   mov rax,r13
000100D936B6 FF939001 call dword ptr [rbx+$0190]

B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:821 exit;
000100D936BC EB70 jmp +$70   /// jump to 
end of proc
000100D936BE EB13 jmp +$13    
 This is where the  jump forwards to line 832


B:\lazarus_latest_svn_2\components\fpdebug\fpdbgcontroller.pas:827 
SetReturnAdressBreakpoint(AProcess, False);

000100D936C0 488B55F8 mov rd

Re: [fpc-devel] Problems building xtensa-freertos RTL in trunk

2020-04-20 Thread Michael Ring via fpc-devel


Am 20.04.20 um 22:14 schrieb Florian Klämpfl:

Am 20.04.20 um 00:03 schrieb Michael Ring via fpc-devel:

Thanks!

Your commit is close, but not yet there...

to make it work it was necessary for me to re-create the Makefiles, 
arm-freertos was missing in the root makefile and some others, did 
you rebuild fpcmake before using it?


Pierre recreated the makefiles already, so it should be fine, right?

Yes, I could start the build from trunk




You also did not include the rtl/freertos/arm directory (I guess on 
purpose, it is currently an evil clone of rtl/embedded/arm):


Ok. I added them.



without that directory and it's content the build breaks. I checked 
if you did some magic to re-use the rtl/embedded/arm directory but 
this does not seem to be the case.


No, I applied the patch and forgot to add them.



No worries





Currently it is also perhaps a good idea to have a new directory for 
freertos compatible units, from what I know today I will have to 
change the interrupt-names defined in the unitfiles to be CMSIS (and 
for that FreeRTOS) compatible.


This means that we will likely have to rename interrupt names like:

PendSV_Interrupt

to

PendSV_Handler

so that FreeRTOS can properly provide it's own routines for handling 
SysTick, PendSV and SVCall Interrupt Handlers.


Yes.

Another thing: some of the files miss a header, so the correct 
license. If some of them are made by you, can you please provide a 
header?


Sorry, I will provide new versions with proper headers


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Martin Frb

On 20/04/2020 23:11, Florian Klämpfl wrote:

Am 20.04.20 um 22:45 schrieb Martin Frb:




Can you post also the relevant output of -al? It makes it easier to 
see where every assembler instruction comes from.


This is the entire proc
I put long 


to mark the lines.
1) the begin of the IF
2) the jmp at the very end of that IF
3) the label
4) the next jmp



.section 
.text.n_fpdbgcontroller$_$tdbgcontrollerstepoutcmd_$__$$_internalcontinue$tdbgprocess$tdbgthread,"x"

    .balign 16,0x90
.globl 
FPDBGCONTROLLER$_$TDBGCONTROLLERSTEPOUTCMD_$__$$_INTERNALCONTINUE$TDBGPROCESS$TDBGTHREAD

FPDBGCONTROLLER$_$TDBGCONTROLLERSTEPOUTCMD_$__$$_INTERNALCONTINUE$TDBGPROCESS$TDBGTHREAD:
.Lc206:
# Temps allocated between rbp-72 and rbp-32
.seh_proc 
FPDBGCONTROLLER$_$TDBGCONTROLLERSTEPOUTCMD_$__$$_INTERNALCONTINUE$TDBGPROCESS$TDBGTHREAD

.Ll380:
# [793] begin
    pushq    %rbp
.seh_pushreg %rbp
.Lc208:
.Lc209:
    movq    %rsp,%rbp
.Lc210:
    leaq    -112(%rsp),%rsp
.seh_stackalloc 112
    movq    %rbx,-72(%rbp)
    movq    %rdi,-64(%rbp)
    movq    %rsi,-56(%rbp)
    movq    %r12,-48(%rbp)
    movq    %r13,-40(%rbp)
.seh_savereg %rbx, 40
.seh_savereg %rdi, 48
.seh_savereg %rsi, 56
.seh_savereg %r12, 64
.seh_savereg %r13, 72
.seh_endprologue
# Var AProcess located at rbp-8, size=OS_64
# Var AThread located at rbp-16, size=OS_64
# Var $self located at rbp-24, size=OS_64
# Var Outside located at rbp-32, size=OS_8
    movq    %rcx,-24(%rbp)
    movq    %rdx,-8(%rbp)
    movq    %r8,-16(%rbp)
.Ll381:
    movb    $85,-32(%rbp)
.Ll382:
# [794] assert(FProcess=AProcess, 'TDbgControllerStepOutCmd.DoContinue: 
FProcess=AProcess');

    movq    -24(%rbp),%rax
    movq    24(%rax),%rax
    cmpq    -8(%rbp),%rax
    jne    .Lj1617
    jmp    .Lj1618
.Lj1617:
    movq    %rbp,%r9
    leaq    _$FPDBGCONTROLLER$_Ld1(%rip),%rdx
    leaq    _$FPDBGCONTROLLER$_Ld24(%rip),%rcx
    movl    $794,%r8d
    call    fpc_assert
.Lj1618:
.Ll383:
# [796] if (AThread = FThread) then begin
    movq    -24(%rbp),%rax
    movq    16(%rax),%rax
    cmpq    -16(%rbp),%rax
    je    .Lj1627
    jmp    .Lj1628
.Lj1627:
.Ll384:
# [797] if IsSteppedOut then begin
    movq    -24(%rbp),%rcx
    call 
FPDBGCONTROLLER$_$TDBGCONTROLLERHIDDENBREAKSTEPBASECMD_$__$$_GETISSTEPPEDOUT$$BOOLEAN

    testb    %al,%al
    jne    .Lj1629
    jmp    .Lj1630
.Lj1629:
.Ll385:
# [798] CheckForCallAndSetBreak;
    movq    -24(%rbp),%rcx
    call 
FPDBGCONTROLLER$_$TDBGCONTROLLERHIDDENBREAKSTEPBASECMD_$__$$_CHECKFORCALLANDSETBREAK$$BOOLEAN

    jmp    .Lj1635
.Lj1630:
.Ll386:
# [801] if not assigned(FHiddenBreakpoint) then begin
    movq    -24(%rbp),%rax
    cmpq    $0,72(%rax)
    je    .Lj1636
    jmp    .Lj1637
.Lj1636:
.Ll387:
# [802] if GetOutsideFrame(Outside) then begin
    leaq    -32(%rbp),%rdx
    movq    -24(%rbp),%rcx
    call 
FPDBGCONTROLLER$_$TDBGCONTROLLERSTEPOUTCMD_$__$$_GETOUTSIDEFRAME$BOOLEAN$$BOOLEAN

    testb    %al,%al
    jne    .Lj1638
    jmp    .Lj1639
.Lj1638:
.Ll388:
# [803] SetReturnAdressBreakpoint(AProcess, Outside);
    movzbl    -32(%rbp),%r8d
    movq    -8(%rbp),%rdx
    movq    -24(%rbp),%rcx
    call 
FPDBGCONTROLLER$_$TDBGCONTROLLERSTEPOUTCMD_$__$$_SETRETURNADRESSBREAKPOINT$TDBGPROCESS$BOOLEAN

    jmp    .Lj1650
.Lj1639:
.Ll389:
# [806] if FStepCount < 12 then
    movq    -24(%rbp),%rax
    cmpl    $12,136(%rax)
    jl    .Lj1651
    jmp    .Lj1652
.Lj1651:
.Ll390:
# [811] Inc(FStepCount);
    movq    -24(%rbp),%rax
    movslq    136(%rax),%rbx
    addq    $1,%rbx
    jno    .Lj1655
    call    FPC_OVERFLOW
.Lj1655:
    movq    %rbx,%rax
    subq    $-2147483648,%rax
# Fix for Win64-GAS bug
    movl    $4294967295,%edx
    cmpq    %rdx,%rax
    jbe    .Lj1656
    call    fpc_rangeerror
.Lj1656:
    movq    -24(%rbp),%rax
    movl    %ebx,136(%rax)
.Ll391:
# [812] if NextInstruction.IsCallInstruction or 
NextInstruction.IsLeaveStackFrame then  // asm "call" // set break 
before "leave" or the frame becomes unavail

    movq    -24(%rbp),%rax
    cmpq    $0,40(%rax)
    je    .Lj1663
    jmp    .Lj1664
.Lj1663:
    movq    -24(%rbp),%rax
    movq    24(%rax),%rcx
    call FPDBGCLASSES$_$TDBGPROCESS_$__$$_GETDISASSEMBLER$$TDBGASMDECODER
    movq    %rax,%rbx
    movq    -24(%rbp),%rax
    movq    16(%rax),%rdi
    movq    -24(%rbp),%rax
    movq    16(%rax),%rsi
    testq    %rsi,%rsi
    jne    .Lj1675
    movl    $210,%ecx
    call    fpc_handleerror
.Lj1675:
    movq    (%rsi),%rsi
    movq    %rsi,%rcx
    call    fpc_check_object
    movq    %rdi,%rcx
    call    *248(%rsi)
    movq    %rax,%rsi
    movq    %rbx,%rdi
    movq    %rbx,%r12
    testq    %r12,%r12
    jne    .Lj1678
    movl    $210,%ecx
    call    fpc_handleerror
.Lj1678:
    movq    (%r12),%r12
    movq    %r12,%rcx
    call    fpc_check_object
    movq    %rdi,%rcx
    movq    %rsi,%rdx
    call    *256(%r12)
    movq    -24(%rbp),%rdx
    movq    

Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread J. Gareth Moreton

Hi Martin,

Can you remind me which version of FPC you're compiling with, and the 
compiler options specified? My jump optimisation code in the trunk 
should eliminate most of those jump pads and 'conditional jump inversions'.


Gareth aka. Kit


--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Internal jump instructions for longer conditional jumps

2020-04-20 Thread Martin Frb

On 21/04/2020 00:05, J. Gareth Moreton wrote:

Hi Martin,

Can you remind me which version of FPC you're compiling with, and the 
compiler options specified? My jump optimisation code in the trunk 
should eliminate most of those jump pads and 'conditional jump 
inversions'.


Fpc 3.0.4
-gh -g -gw -godwarfsets  -gl   -dCR   -Ct -Co -Cr -Ci  -gt  -Sa  -ve -vw 
-vn  -vi   -O-  -CX  -WC


My concern right here was not about the performance.

This is about the line info applied to those.
In this case a "jmp" that I guess belongs after the "then begin end" is 
attributed to the last line in the "then begin end".
Simply because no line exists between the last line of "then" and the 
first line of "else". So the "then" line extends until the next line 
starts, and eats anything that is inbetwen.


In the example below, a single step from the marked line, should go to 
DoGood().

But it does go to "bar" (which is not executed, but contains the jmp)

That is obviously irritating.
GDB somehow detects that.
Now, I added this to fpdebug too. Though currently with a limit, as to 
how many such jumps are stepped over. That limit may have to go.


The debugger has to deal with this.
   IF true then begin
  IF false then begin  // Single step from here
  foo;
  bar;
  end;
   end
   else begin
 ...
  end;
  DoGood();

--
While the debugger runs best with -O-, if you do optimizations mind that 
line info may need adjustments.
You may well be aware of it, but it also is an easy to make oversight. 
So if you are interested below a real case:


Long ago there was an issue (fixed by now)
line 1:  mov  const => mem
line 2:  mov mem => reg
line 2: 

2nd line was correctly removed.
But somehow it ended up
line 1: move const => reg
line 2:  mov reg => mem
line 2: 

Which meant that when you stepped over line 1, the memory (which the 
debugger shows for the variable) was not yet updated. The debugger 
showed the outdated value.

https://bugs.freepascal.org/view.php?id=25584


___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] State of SSE/AVX intrinsics

2020-04-20 Thread J. Gareth Moreton

Hi everyone,

So to start the story, I'm planning to make use of the nodes that were 
introduced for the SSE and AVX intrinstics as part of some vectorisation 
code, since they can help manage the code generation and contain some 
sanity checks.  I noticed though that some intrinsics are missing; for 
example, the VMASKMOV instructions, which were introduced with AVX and 
don't have a direct SSE equivalent (MASKMOVDQU and MASKMOVQ can only 
write to memory and work on integers rather than floating-point values, 
and mixing MM integer and floating-point instructions incur a CPU state 
switch penalty).


Instructions like VMASKMOV are very useful because it would allow 
vectorisation of 3-component arrays (e.g. Cartesean coordinates), so I 
plan to look at introducing nodes for these instructions. Would this be 
okay to do?


On another note, I'm wondering if the RTL could benefit from some 
initializers for the MM types for ease of use.  For example, one of the 
registers used in VMASKMOV is a mask, and for a programmer using 
intrinstics, being able to do something like "mmval := 
x86_vmaskmovps(Coord, [True, True, True, False]);" - granted I have to 
think about performance since all those Boolean consrants should ideally 
be merged into single 128-bit memory block (as 
) that is loaded into an XMM register 
with VMOVPS.


What would you suggest? I'm just speaking a bit from experience in that 
using C++ intrinsics can get a little cumbersome sometimes and easy to 
get wrong (at least as far as performance and alignment are concerned, 
for example), and having the FPC ones be friendlier would make a world 
of difference.


I'm still working out quite a few things and experimenting a lot.  I'll 
be sure to be doing a lot of documentation.  However, any help or 
insight into the current design practices for intrinstics and their 
respective nodes will be greatly appreciated.


Gareth aka. Kit

P.S. Regarding vectorisation challenges, I'm looking at sequences like 
"V.X*V.X + V.Y*V.Y + V.Z*V.Z" (scalar length of a 3-dimensional vector), 
which I would love to be able to naturally compile into:


VMOVPS XMM1, Mask_1110
VMASKMOVPS XMM0, XMM1, V
VMULPS XMM0, XMM0, XMM0
VHADDPS XMM0, XMM0, XMM0
VHADDPS XMM0, XMM0, XMM0

And then maybe take it further to produce:

VMOVPS XMM1, Mask_1110
VMASKMOVPS XMM0, XMM1, V
VDPPS XMM0, XMM0, $71 { 01110001b }

(This could be an optimisation at the node level rather than a peephole 
optimisation, although if it doesn't know exactly what VMASKMOVPS is 
doing, then the immediate in (V)DPPS will be forced to be $FF)



--
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] New Target Announcement: Windows on ARM64

2020-04-20 Thread Sven Barth via fpc-devel

Hello together!

I'm happy to announce initial support for the Windows on ARM64 target, 
aka aarch64-win64.


Simple programs work already and the compiler is at least able to 
display its help message (when trying to compiler something it silently 
crashes, I've not yet found out why that is the case). Optimizations 
don't work yet, so please use -O- when building (especially when 
building the compiler/RTL).


Just in case anyone thinks that: no, this does not mean that 
Metro/WinRT/UWP apps are supported.


Currently a clang installation is required as we use clang for the 
external assembler, because GNU AS does not yet support COFF for 
Aarch64. And we don't support Microsoft's arm64asm.exe yet...
Thus you should either have clang in your PATH or you need to use -FD… 
or CROSSBINDIR=… to point the compiler to the directory containing the 
clang binary while setting -XP… / BINUTILSPREFIX=… to empty.
Due to GNU LD also not being available we currently *only* support the 
internal linker (FPC does not support Microsoft's link.exe either).


Unlike i386-win32 and x86_64-win64 this target uses SEH from the beginning.

Also the NX_COMPAT and DYNAMIC_BASE flags are enabled by default and a 
relocation section is generated, because this is required by Windows on 
ARM64.


To build the compiler you can do the following:

make all FPMAKEOPT="-T " CPU_TARGET=aarch64 OS_TARGET=win64 
BINUTILSPREFIX= OPT=-O-


You might also need to specify OS_SOURCE and CPU_SOURCE (which is your 
host's target, e.g. if you have a Win64 ppcx64: OS_SOURCE=win64 
CPU_SOURCE=aarch64).


Please give this target a go (if you have access to a Windows on ARM64 
machine (1)) and report any problems you find so that the target will be 
nice and well soon. :)


Things left to do (in no specific order):
- implement an internal Aarch64 assembler (this way we could get rid of 
the clang dependency, though I won't work on that)

- implement support for Microsoft's armasm64.exe
- figure out why the compiler can't compile code on Windows on ARM64
- try to compile and run Lazarus
- fix optimizations
- fix other bugs (obviously ;) )
- implement Windows on ARM32, just for the sake of completeness ;)

(1) Apparantly one can also run a Windows on ARM64 in QEMU: 
https://winaero.com/blog/install-windows-10-arm-qemu/


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] State of SSE/AVX intrinsics

2020-04-20 Thread denisgolovan via fpc-devel
Hi

I think another related idea is adding some "attribute" to dynamic arrays types 
to force them to be aligned to 32/64 bytes.
Precisely for this purpose, I am forced to maintain my own FPC fork.

-- Regards,
Denis Golovan
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel