Re: [fpc-devel] FPC and Z80
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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