[fpc-pascal] PAS2JS: operations with array of record

2018-01-10 Thread warleyalex via fpc-pascal
Since it's missing the Pas2JS specific forum, I don't know if here is correct
place to post things about "Pas2JS".

I'm using it a lot and it's very promising. I came across with issue when
dealing with array of records. 

I would like to convert this little piece of DWScript code to Pas2JS,
unfortunately, I couldn't find a way how to push an array of record. For
instance:
type   JC = record  id : integer; external 'id';  name : string;
external 'name';  age : integer; external 'age';   end; type   JB =
record field1 : string; external 'field1'; params : Array of JC;
external 'params';   end; type   JA= record fields : array of JB;
external 'JA';   end; var recA : JA; var recB : JB; var recC : JC; for var
k:=0 to 2 do begin   recC.id := k;   recC.name := 'abc'+IntToStr(k);  
recC.age := 10+k;   recB.field1 := 'rec'+ IntToStr(k);  
recB.params.Add(recC);   recA.fields.Add(recB); end; 
Just to referente, the above DWScript code will emit the following JS:
function Copy$JC(s,d) {d.id=s.id;d.name=s.name;d.age=s.age;   
return d; } function Clone$JC($) {return {   id:$.id,  
name:$.name,   age:$.age} } /// JB = record /// [line: 23, column:
3] function Copy$JB(s,d) {d.field1=s.field1;d.params=s.params;   
return d; } function Clone$JB($) {return {   field1:$.field1,  
params:$.params} } /// JA = record /// [line: 29, column: 3] function
Copy$JA(s,d) {d.JA=s.JA;return d; } function Clone$JA($) {return
{   JA:$.JA} } var recA = {JA:[]}; var recB = {field1:"",params:[]};
var recC = {id:0,name:"",age:0}; var k = 0; for(k=0;k=2;k++) {   recC.id
= k;   recC.name = "abc"+k.toString();   recC.age = 10+k;   recB.field1 =
"rec"+k.toString();   recB.params.push(Clone$JC(recC));  
recA.JA.push(Clone$JB(recB)); } /*  RecA object*/{"JA" : [{ "field1"
: "rec0", "params" : [{ "id" : 0,
"name" : "abc0", "age" : 10 }, {
"id" : 1, "name" : "abc1", "age" : 11   
 
}, { "id" : 2, "name" : "abc2",
"age" : 12 } ] }, { "field1" : "rec1",
"params" : [{ "id" : 0, "name" : "abc0",

"age" : 10 }, { "id" : 1, "name"
: "abc1", "age" : 11 }, { "id" :
2, "name" : "abc2", "age" : 12 }

] }, { "field1" : "rec2", "params" : [{
"id" : 0, "name" : "abc0", "age" : 10   
 
}, { "id" : 1, "name" : "abc1",
"age" : 11 }, { "id" : 2, "name"
: "abc2", "age" : 12 } ] } ]} 
I believe it will be nice if PAS2JS could generate similar code, each
record type, the DWScript compiler emits corresponding intermediate Clone
and Copy functions.
The PAS2JS transpiler uses another approach (the record variable creates a
JavaScript object) whereas DWScript with identical functionality using
ordinary arrays.
I don't know,I believe it will achieves better performance using
ordinary arrays, at least.
Anyway, what I couldn't find is the built-in kind ofpseudo-methods for
the record data type,set of operations, for inserting, removing,
sorting and otherwise manipulate the content, for instance:
In addition to Low, High, Lengthand Count,  

 Add(item [,...]) / Push(item [,...]) : increases Length by one and
adds one or more item at the end of the array, can also add arrays
(concatenation).  

 Clear() : empties the array (equivalent to SetLength(0))  

 Copy(startIndex[, count]) : creates a new dynamic array containing
count items from startIndex, if count isn't specified, copies to the end of
the array.  

 Delete(index[, count]) : deletes the item at the specified index
and reduces Length by count (default one).  

 IndexOf([startIndex, ]item) : returns the index of an item, returns
a negative value if not found.  

 Insert(index, item) : insert an item at the specified index.  

 Join(delimiter : String) : joins the elements of an array into a
string, and returns the string. 

 Map([map function]) : creates a new array by mapping elements of
the array according to a map function. The map function takes a single
parameter of the type of the array items and returns the mapped value.
 

 Peek() : returns the last item.  

 Pop() : returns the last item and removes it from the array.  

 Remove([startIndex, ]item) : removes the item if it can be found
and returns its previous index, returns a negative value if not found.
 

 Reverse() : reverses the order of the items.  

 SetLength(newLength) : defines the length of a dynamic array  

 Sort([compare function]) : sort an 

Re: [fpc-pascal] Generics vs templates

2018-01-10 Thread Michael Schnell

On 09.01.2018 08:04, Sven Barth via fpc-pascal wrote:
But you need to program in a way that allows the usage of multiple, 
different types. That can more often than not lead to worse performance.

Seemingly it is done that way.

I rather often did a kind of "Generics" in ANSI C by using Macros. It's 
catastrophic for code writing and for debugging but does not impose any 
performance issues.


I suppose there is a reason why in Pascal Generics are not translated in 
multiple dedicatedly typed code snippets at compile time.


-Michael
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Register Allocation on x86_64

2018-01-10 Thread Jonas Maebe

On 10/01/18 17:06, Martok wrote:



Afaik there are only two limitations:
* routines containing assembly blocks (including pure assembly routines)
cannot be inlined> * regular procedures that contain assembly blocks will never 
use regvars

Somehow I have a feeling that the fix for one would also fix the other...


They are orthogonal issues.


I'd add the manual RIP addressing that was mentioned on the bugtracker recently


That's not a limitation. Not supporting absolute addressing on x86-64 
would be a limitation.



(OT: is -Cg supposed to work on platforms where it is not set by default?).


I think it does, although I don't think it does anything on Win64 (as 
its code is already position-independent by default).



For the original issue, since manually using assembler blocks makes things
complicated, is there a way to "strongly suggest" to the compiler that a
variable should become a regvar if the entire routine is pure Pascal? Something
like the (purely decorative) {register} comments in
/packages/pasjpeg/src/jdcolor.pas?


No, and I don't think it would be a good idea to spend time on 
complicating the compiler with such functionality. Over time, such hints 
become more of a burden than a gain (I believe all modern C compilers 
completely ignore such hints).



Jonas

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
2018-01-10 18:09 GMT+01:00 Karoly Balogh (Charlie/SGR) <
char...@scenergy.dfmk.hu>:

> Hi,
>
> On Wed, 10 Jan 2018, Matias Vara wrote:
>
> > BTW, this only applies to inline assembler functions rigth? In the case
> > of normal procedures that contains a block asm end; there is no problem,
> > Am I right?
>
> No, it applies to *ALL* assembler code. Also inline blocks. The only
> difference is, for blocks you can hint the compiler which registers you
> use, so the compiler can also tailor code which improves the interaction
> with your assembler code:
>
> https://www.freepascal.org/docs-html/ref/refse87.html
>
> This is not true for pure assembler functions tho', for performance
> reasons among others.
>
> Charlie
>

This is very interesting.

Thanks a lot.



> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
Hello,

2018-01-10 18:03 GMT+01:00 Karoly Balogh (Charlie/SGR) <
char...@scenergy.dfmk.hu>:

> Hi,
>
> On Wed, 10 Jan 2018, Matias Vara wrote:
>
> > Thank you very much Karol, I completly missed this point during the
> > development of my kernel (Or maybe I had in mind sometime ago but I
> > forgot it)It was only when I decided to play with -02 that all these
> > issues arrised.
>
> BTW, your code (as shown by the parameter passing in your assembler dumps)
> seems to use the Microsoft x64 calling convention, which declares RSI
> value as callee-saved, and then your code overwrites that without saving.
>
> So the fact that your code overwrites it, could be the culprit. (And then
> the OUTSD instruction also increases RSI by 4, so even if that MOV
> wouldn't be there, you'd still need to save it.)
>
> Also note that the 64bit x86-64 ABI is very different between Linux and
> Windows, for example.
>
>
Thanks, I am going to review all the assembler code.


> BTW, developing a kernel in Pascal is cool... ;)
>

It is indeed :)

Matias


>
> Charlie
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Karoly Balogh (Charlie/SGR)
Hi,

On Wed, 10 Jan 2018, Matias Vara wrote:

> BTW, this only applies to inline assembler functions rigth? In the case
> of normal procedures that contains a block asm end; there is no problem,
> Am I right?

No, it applies to *ALL* assembler code. Also inline blocks. The only
difference is, for blocks you can hint the compiler which registers you
use, so the compiler can also tailor code which improves the interaction
with your assembler code:

https://www.freepascal.org/docs-html/ref/refse87.html

This is not true for pure assembler functions tho', for performance
reasons among others.

Charlie
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Karoly Balogh (Charlie/SGR)
Hi,

On Wed, 10 Jan 2018, Matias Vara wrote:

> Thank you very much Karol, I completly missed this point during the
> development of my kernel (Or maybe I had in mind sometime ago but I
> forgot it)It was only when I decided to play with -02 that all these
> issues arrised. 

BTW, your code (as shown by the parameter passing in your assembler dumps)
seems to use the Microsoft x64 calling convention, which declares RSI
value as callee-saved, and then your code overwrites that without saving.

So the fact that your code overwrites it, could be the culprit. (And then
the OUTSD instruction also increases RSI by 4, so even if that MOV
wouldn't be there, you'd still need to save it.)

Also note that the 64bit x86-64 ABI is very different between Linux and
Windows, for example.

BTW, developing a kernel in Pascal is cool... ;)

Charlie___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
BTW, this only applies to inline assembler functions rigth? In the case of
normal procedures that contains a block asm end; there is no problem, Am I
right?

Matias

2018-01-10 17:51 GMT+01:00 Matias Vara :

> Thank you very much Karol, I completly missed this point during the
> development of my kernel (Or maybe I had in mind sometime ago but I forgot
> it)
> It was only when I decided to play with -02 that all these issues arrised.
>
> Matias
>
> 2018-01-10 17:34 GMT+01:00 Karoly Balogh (Charlie/SGR) <
> char...@scenergy.dfmk.hu>:
>
>> Hi,
>>
>> On Wed, 10 Jan 2018, Matias Vara wrote:
>>
>> > Hi Karol and thanks you very much! I got confused with the function
>> > names, I feel very sorry.As I said in my previous email, I fixed by
>> > rewriting the assembler function. However, I don't why it worked.
>>
>> By accident. Simply the register/stack/memory layout being different upon
>> entry, and it worked by pure luck.
>>
>> > So I understand you correctly, if I use assembler in my procedures there
>> > could be a risk that I trash a variable that the compiler is using.
>>
>> Yes. All operating systems and CPU architectures define a so called ABI or
>> calling convention, which functions must respect. This details which
>> registers are the parameters to be passed on, and which registers are free
>> to destroy in a function and which ones *MUST* be saved/preserved (usually
>> on the stack). There's no way around this. The compiler will expect that
>> your assembly subfunctions play by the rules.
>>
>> See here, for example, for x86:
>> https://en.wikipedia.org/wiki/X86_calling_conventions
>>
>> > Is  the compiler warning me about this?
>>
>> No. Assembly is quite a minefield in this regard. If you use assembler,
>> the compiler assumes you know what you're doing, and doesn't analyze the
>> assembler function. You have to respect the ABI of your CPU *AND* target
>> platform by hand, and save the nonvolatile registers.
>>
>> (This is BTW, not Free Pascal specific. Delphi does the same, or more or
>> less any other language which supports inline assembly.)
>>
>> Charlie
>>
>> ___
>> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
>> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>>
>
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
Thank you very much Karol, I completly missed this point during the
development of my kernel (Or maybe I had in mind sometime ago but I forgot
it)
It was only when I decided to play with -02 that all these issues arrised.

Matias

2018-01-10 17:34 GMT+01:00 Karoly Balogh (Charlie/SGR) <
char...@scenergy.dfmk.hu>:

> Hi,
>
> On Wed, 10 Jan 2018, Matias Vara wrote:
>
> > Hi Karol and thanks you very much! I got confused with the function
> > names, I feel very sorry.As I said in my previous email, I fixed by
> > rewriting the assembler function. However, I don't why it worked.
>
> By accident. Simply the register/stack/memory layout being different upon
> entry, and it worked by pure luck.
>
> > So I understand you correctly, if I use assembler in my procedures there
> > could be a risk that I trash a variable that the compiler is using.
>
> Yes. All operating systems and CPU architectures define a so called ABI or
> calling convention, which functions must respect. This details which
> registers are the parameters to be passed on, and which registers are free
> to destroy in a function and which ones *MUST* be saved/preserved (usually
> on the stack). There's no way around this. The compiler will expect that
> your assembly subfunctions play by the rules.
>
> See here, for example, for x86:
> https://en.wikipedia.org/wiki/X86_calling_conventions
>
> > Is  the compiler warning me about this?
>
> No. Assembly is quite a minefield in this regard. If you use assembler,
> the compiler assumes you know what you're doing, and doesn't analyze the
> assembler function. You have to respect the ABI of your CPU *AND* target
> platform by hand, and save the nonvolatile registers.
>
> (This is BTW, not Free Pascal specific. Delphi does the same, or more or
> less any other language which supports inline assembly.)
>
> Charlie
>
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Karoly Balogh (Charlie/SGR)
Hi,

On Wed, 10 Jan 2018, Matias Vara wrote:

> Hi Karol and thanks you very much! I got confused with the function
> names, I feel very sorry.As I said in my previous email, I fixed by
> rewriting the assembler function. However, I don't why it worked. 

By accident. Simply the register/stack/memory layout being different upon
entry, and it worked by pure luck.

> So I understand you correctly, if I use assembler in my procedures there
> could be a risk that I trash a variable that the compiler is using.

Yes. All operating systems and CPU architectures define a so called ABI or
calling convention, which functions must respect. This details which
registers are the parameters to be passed on, and which registers are free
to destroy in a function and which ones *MUST* be saved/preserved (usually
on the stack). There's no way around this. The compiler will expect that
your assembly subfunctions play by the rules.

See here, for example, for x86:
https://en.wikipedia.org/wiki/X86_calling_conventions

> Is  the compiler warning me about this? 

No. Assembly is quite a minefield in this regard. If you use assembler,
the compiler assumes you know what you're doing, and doesn't analyze the
assembler function. You have to respect the ABI of your CPU *AND* target
platform by hand, and save the nonvolatile registers.

(This is BTW, not Free Pascal specific. Delphi does the same, or more or
less any other language which supports inline assembly.)

Charlie
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
Hi Karol and thanks you very much! I got confused with the function names,
I feel very sorry.
As I said in my previous email, I fixed by rewriting the assembler
function. However, I don't why it worked.
So I understand you correctly, if I use assembler in my procedures there
could be a risk that I trash a variable that the compiler is using. Is the
compiler warning me about this?

Matias

2018-01-10 17:14 GMT+01:00 Karoly Balogh (Charlie/SGR) <
char...@scenergy.dfmk.hu>:

> Hi,
>
> On Wed, 10 Jan 2018, Matias Vara wrote:
>
> > I am getting an exception when I enable the -O2 optimization. More
> > precisaily, the line that stars with write_portd is corrupting the
> > data section. This is the pascal code:
> >
> > function PciReadDword(const bus, device, func, regnum: UInt32): UInt32;
> > var
> >   Send: DWORD;
> > begin
> >   Send := $8000 or (bus shl 16) or (device shl 11) or (func shl 8)
> or (regnum shl 2);
> >   write_portd(@Send, PCI_CONF_PORT_INDEX);
> >   read_portd(@Send, PCI_CONF_PORT_DATA);
> >   Result := Send;
> > end;
> >
> > which generates (without -02):
> >
> > .section .text.n_arch_$$_pcireaddword$longword$longword$longword$
> longword$$longword,"x"
> > .balign 16,0x90
> > .globl ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$
> LONGWORD
> > ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD:
> >
> > (***shipp***)
> >
> > and with -O2:
> >
> > .section .text.n_arch_$$_pciwriteword$word$word$word$word$word,"x"
> > .balign 16,0x90
> > .globl ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
> > ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD:
> >
> > The first thing that I realize was the the optimized version is not
> > generating the correct source when is exiting since it should return
> > "Send", but am I right? The assembler code of write_portd remains the
> > same, Am I missing something?
>
> The -O2 version of the function you sent is from a different one, it's
> from a Write function, not a Read... So no wonder it doesn't return
> anything... :)
>
> BTW, -O2 uses register variables, while -O- doesn't. If your assembler
> trashes one of them without preserving one, it can lead to crashes...
> But there could be many other reasons.
>
> Without seeing the actual assembler functions it's hard to tell.
>
> Charlie
> ___
> fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Karoly Balogh (Charlie/SGR)
Hi,

On Wed, 10 Jan 2018, Matias Vara wrote:

> I am getting an exception when I enable the -O2 optimization. More
> precisaily, the line that stars with write_portd is corrupting the
> data section. This is the pascal code: 
>
> function PciReadDword(const bus, device, func, regnum: UInt32): UInt32;
> var
>   Send: DWORD;
> begin
>   Send := $8000 or (bus shl 16) or (device shl 11) or (func shl 8) or 
> (regnum shl 2);
>   write_portd(@Send, PCI_CONF_PORT_INDEX);
>   read_portd(@Send, PCI_CONF_PORT_DATA);
>   Result := Send;
> end;  
>
> which generates (without -02):
>
> .section 
> .text.n_arch_$$_pcireaddword$longword$longword$longword$longword$$longword,"x"
> .balign 16,0x90
> .globl ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD
> ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD:
>
> (***shipp***)
>
> and with -O2:
>
> .section .text.n_arch_$$_pciwriteword$word$word$word$word$word,"x"
> .balign 16,0x90
> .globl ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
> ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD:
>
> The first thing that I realize was the the optimized version is not
> generating the correct source when is exiting since it should return
> "Send", but am I right? The assembler code of write_portd remains the
> same, Am I missing something? 

The -O2 version of the function you sent is from a different one, it's
from a Write function, not a Read... So no wonder it doesn't return
anything... :)

BTW, -O2 uses register variables, while -O- doesn't. If your assembler
trashes one of them without preserving one, it can lead to crashes...
But there could be many other reasons.

Without seeing the actual assembler functions it's hard to tell.

Charlie___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Register Allocation on x86_64

2018-01-10 Thread Martok
Hi,

> variables in the same routine. Unlike in e.g. gcc, there are no 
> annotations for assembly routines that they expect certain variables to 
> be in memory and/or registers, that the block may touch arbitrary memory 
> locations, etc. Hence, the compiler is as conservative as possible.
This took me a while to understand, but what you're saying is that the issue is
not so much about what registers might be modified (we could just say that if
the annotation exists, it is assumed to be complete), but that the assembler
code might try to take the address of a variable (possibly with indirections),
which must therefore not be a regvar?
That makes sense. Unfortunately...

> Afaik there are only two limitations:
> * routines containing assembly blocks (including pure assembly routines) 
> cannot be inlined> * regular procedures that contain assembly blocks will 
> never use regvars
Somehow I have a feeling that the fix for one would also fix the other...

I'd add the manual RIP addressing that was mentioned on the bugtracker recently
(OT: is -Cg supposed to work on platforms where it is not set by default?).


For the original issue, since manually using assembler blocks makes things
complicated, is there a way to "strongly suggest" to the compiler that a
variable should become a regvar if the entire routine is pure Pascal? Something
like the (purely decorative) {register} comments in
/packages/pasjpeg/src/jdcolor.pas?


-- 
Regards,
Martok

Ceterum censeo b32079 esse sanandam.

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
I think the problem was the way write_portd() is implemented:

procedure write_portd(const Data: Pointer; const Port: Word); {$IFDEF
ASMINLINE} inline; {$ENDIF}
asm // RCX: data, RDX: port
  {$IFDEF LINUX} mov dx, port {$ENDIF}
mov rsi, data // DX=port
outsd
end;

If I replace with something that does not use the outsd instruction, it
works fine.

Matias

2018-01-10 15:55 GMT+01:00 Matias Vara :

> Hello everyone,
>
> I am getting an exception when I enable the -O2 optimization. More
> precisaily, the line that stars with write_portd is corrupting the data
> section. This is the pascal code:
>
> function PciReadDword(const bus, device, func, regnum: UInt32): UInt32;
> var
>   Send: DWORD;
> begin
>   Send := $8000 or (bus shl 16) or (device shl 11) or (func shl 8) or
> (regnum shl 2);
>   write_portd(@Send, PCI_CONF_PORT_INDEX);
>   read_portd(@Send, PCI_CONF_PORT_DATA);
>   Result := Send;
> end;
>
> *which generates (without -02):*
>
> .section .text.n_arch_$$_pcireaddword$longword$longword$longword$
> longword$$longword,"x"
> .balign 16,0x90
> .globl ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD
> ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD:
> .Lc207:
> .seh_proc ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$
> LONGWORD
> .Ll464:
> # [992] begin
> pushq %rbp
> .seh_pushreg %rbp
> .Lc209:
> .Lc210:
> movq %rsp,%rbp
> .Lc211:
> leaq -80(%rsp),%rsp
> .seh_stackalloc 80
> .seh_endprologue
> # Var bus located at rbp-8, size=OS_32
> # Var device located at rbp-16, size=OS_32
> # Var func located at rbp-24, size=OS_32
> # Var regnum located at rbp-32, size=OS_32
> # Var $result located at rbp-40, size=OS_32
> # Var Send located at rbp-48, size=OS_32
> movl %ecx,-8(%rbp)
> movl %edx,-16(%rbp)
> movl %r8d,-24(%rbp)
> movl %r9d,-32(%rbp)
> .Ll465:
> # [993] Send := $8000 or (bus shl 16) or (device shl 11) or (func shl
> 8) or (regnum shl 2);
> movl -8(%rbp),%eax
> shll $16,%eax
> orl $2147483648,%eax
> movl -16(%rbp),%edx
> shll $11,%edx
> orl %eax,%edx
> movl -24(%rbp),%eax
> shll $8,%eax
> orl %edx,%eax
> movl -32(%rbp),%edx
> shll $2,%edx
> orl %eax,%edx
> movl %edx,-48(%rbp)
> .Ll466:
> # [995] write_portd(@Send, PCI_CONF_PORT_INDEX);
> leaq -48(%rbp),%rcx
> movl $3320,%edx
> call ARCH_$$_WRITE_PORTD$POINTER$WORD
> .Ll467:
> # [996] read_portd(@Send, PCI_CONF_PORT_DATA);
> leaq -48(%rbp),%rcx
> movl $3324,%edx
> call ARCH_$$_READ_PORTD$POINTER$WORD
> .Ll468:
> # [997] Result := Send;
> movl -48(%rbp),%eax
> movl %eax,-40(%rbp)
> .Ll469:
> # [998] end;
> movl -40(%rbp),%eax
> nop
> leaq (%rbp),%rsp
> popq %rbp
> ret
> .seh_endproc
> .Lc208:
> .Lt28:
> .Ll470:
>
> *and with -O2:*
>
> .section .text.n_arch_$$_pciwriteword$word$word$word$word$word,"x"
> .balign 16,0x90
> .globl ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
> ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD:
> .Lc148:
> # Temps allocated between rbp-16 and rbp-8
> .seh_proc ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
> .Ll471:
> # [1014] begin
> pushq %rbp
> .seh_pushreg %rbp
> .Lc150:
> .Lc151:
> movq %rsp,%rbp
> .Lc152:
> leaq -48(%rsp),%rsp
> .seh_stackalloc 48
> # Var bus located in register ax
> # Var device located in register dx
> # Var func located in register r8w
> # Var regnum located in register r9w
> # Var value located in register cx
> movq %rbx,-16(%rbp)
> .seh_savereg %rbx, 32
> .seh_endprologue
> # Var Send located at rbp-8, size=OS_32
> movw %cx,%ax
> movw 48(%rbp),%bx
> # PeepHole Optimization,var11
> .Ll472:
> # [1015] Send := $8000 or (bus shl 16) or (device shl 11) or (func shl
> 8) or (regnum and $fc);
> andl $65535,%eax
> shll $16,%eax
> orl $2147483648,%eax
> # PeepHole Optimization,var11
> andl $65535,%edx
> shll $11,%edx
> orl %eax,%edx
> # PeepHole Optimization,var11
> andl $65535,%r8d
> shll $8,%r8d
> orl %edx,%r8d
> # PeepHole Optimization,var1
> # PeepHole Optimization,var11
> andl $252,%r9d
> orl %r8d,%r9d
> movl %r9d,-8(%rbp)
> .Ll473:
> # [1016] write_portd(@Send, PCI_CONF_PORT_INDEX);
> leaq -8(%rbp),%rcx
> movl $3320,%edx
> call ARCH_$$_WRITE_PORTD$POINTER$WORD
> .Ll474:
> # [1017] write_portw(value, PCI_CONF_PORT_DATA);
> movw %bx,%cx
> # Var value located in register cx
> # PeepHole Optimization,var11
> andl $65535,%ecx
> movl $3324,%edx
> call ARCH_$$_WRITE_PORTW$WORD$WORD
> .Ll475:
> # [1018] end;
> movq -16(%rbp),%rbx
> leaq (%rbp),%rsp
> popq %rbp
> ret
> .seh_endproc
>
> The first thing that I realize was the the optimized version is not
> generating the correct source when is exiting since it should return
> "Send", but am I right? The assembler code of write_portd remains the same,
> Am I missing something?
>
> Regards, Matias.
>
>
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Comp type

2018-01-10 Thread Tony Whyman
Thanks for the history. Comp has always puzzled me before, especially 
with these two functions from the RTL


function MSecsToTimeStamp(MSecs: Comp): TTimeStamp;
function TimeStampToMSecs(const TimeStamp: TTimeStamp): comp;

I assume that these have come down from Turbo Pascal - but it still 
seems odd that milliseconds is represented by a "real" type.


Tony Whyman


On 10/01/18 08:04, Jonas Maebe wrote:

Mattias Gaertner wrote:

Comp is Int64 div 1.

No, that is currency. Comp is a plain 64 bit integer. It originally
comes from Turbo Pascal, which did not have a regular 64 bit integer
type. The x87 fpu can be used to perform 64 bit integer math though, so
it was originally a 64 bit integer type whose calculations were
performed using the fpu.

In FPC, it's the same on platforms that still use the x87 fpu. On other
platforms, comp is an alias for the int64 type.


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal



___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

[fpc-pascal] issue when enabling -O2

2018-01-10 Thread Matias Vara
Hello everyone,

I am getting an exception when I enable the -O2 optimization. More
precisaily, the line that stars with write_portd is corrupting the data
section. This is the pascal code:

function PciReadDword(const bus, device, func, regnum: UInt32): UInt32;
var
  Send: DWORD;
begin
  Send := $8000 or (bus shl 16) or (device shl 11) or (func shl 8) or
(regnum shl 2);
  write_portd(@Send, PCI_CONF_PORT_INDEX);
  read_portd(@Send, PCI_CONF_PORT_DATA);
  Result := Send;
end;

*which generates (without -02):*

.section
.text.n_arch_$$_pcireaddword$longword$longword$longword$longword$$longword,"x"
.balign 16,0x90
.globl ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD
ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD:
.Lc207:
.seh_proc ARCH_$$_PCIREADDWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$$LONGWORD
.Ll464:
# [992] begin
pushq %rbp
.seh_pushreg %rbp
.Lc209:
.Lc210:
movq %rsp,%rbp
.Lc211:
leaq -80(%rsp),%rsp
.seh_stackalloc 80
.seh_endprologue
# Var bus located at rbp-8, size=OS_32
# Var device located at rbp-16, size=OS_32
# Var func located at rbp-24, size=OS_32
# Var regnum located at rbp-32, size=OS_32
# Var $result located at rbp-40, size=OS_32
# Var Send located at rbp-48, size=OS_32
movl %ecx,-8(%rbp)
movl %edx,-16(%rbp)
movl %r8d,-24(%rbp)
movl %r9d,-32(%rbp)
.Ll465:
# [993] Send := $8000 or (bus shl 16) or (device shl 11) or (func shl
8) or (regnum shl 2);
movl -8(%rbp),%eax
shll $16,%eax
orl $2147483648,%eax
movl -16(%rbp),%edx
shll $11,%edx
orl %eax,%edx
movl -24(%rbp),%eax
shll $8,%eax
orl %edx,%eax
movl -32(%rbp),%edx
shll $2,%edx
orl %eax,%edx
movl %edx,-48(%rbp)
.Ll466:
# [995] write_portd(@Send, PCI_CONF_PORT_INDEX);
leaq -48(%rbp),%rcx
movl $3320,%edx
call ARCH_$$_WRITE_PORTD$POINTER$WORD
.Ll467:
# [996] read_portd(@Send, PCI_CONF_PORT_DATA);
leaq -48(%rbp),%rcx
movl $3324,%edx
call ARCH_$$_READ_PORTD$POINTER$WORD
.Ll468:
# [997] Result := Send;
movl -48(%rbp),%eax
movl %eax,-40(%rbp)
.Ll469:
# [998] end;
movl -40(%rbp),%eax
nop
leaq (%rbp),%rsp
popq %rbp
ret
.seh_endproc
.Lc208:
.Lt28:
.Ll470:

*and with -O2:*

.section .text.n_arch_$$_pciwriteword$word$word$word$word$word,"x"
.balign 16,0x90
.globl ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD:
.Lc148:
# Temps allocated between rbp-16 and rbp-8
.seh_proc ARCH_$$_PCIWRITEWORD$WORD$WORD$WORD$WORD$WORD
.Ll471:
# [1014] begin
pushq %rbp
.seh_pushreg %rbp
.Lc150:
.Lc151:
movq %rsp,%rbp
.Lc152:
leaq -48(%rsp),%rsp
.seh_stackalloc 48
# Var bus located in register ax
# Var device located in register dx
# Var func located in register r8w
# Var regnum located in register r9w
# Var value located in register cx
movq %rbx,-16(%rbp)
.seh_savereg %rbx, 32
.seh_endprologue
# Var Send located at rbp-8, size=OS_32
movw %cx,%ax
movw 48(%rbp),%bx
# PeepHole Optimization,var11
.Ll472:
# [1015] Send := $8000 or (bus shl 16) or (device shl 11) or (func shl
8) or (regnum and $fc);
andl $65535,%eax
shll $16,%eax
orl $2147483648,%eax
# PeepHole Optimization,var11
andl $65535,%edx
shll $11,%edx
orl %eax,%edx
# PeepHole Optimization,var11
andl $65535,%r8d
shll $8,%r8d
orl %edx,%r8d
# PeepHole Optimization,var1
# PeepHole Optimization,var11
andl $252,%r9d
orl %r8d,%r9d
movl %r9d,-8(%rbp)
.Ll473:
# [1016] write_portd(@Send, PCI_CONF_PORT_INDEX);
leaq -8(%rbp),%rcx
movl $3320,%edx
call ARCH_$$_WRITE_PORTD$POINTER$WORD
.Ll474:
# [1017] write_portw(value, PCI_CONF_PORT_DATA);
movw %bx,%cx
# Var value located in register cx
# PeepHole Optimization,var11
andl $65535,%ecx
movl $3324,%edx
call ARCH_$$_WRITE_PORTW$WORD$WORD
.Ll475:
# [1018] end;
movq -16(%rbp),%rbx
leaq (%rbp),%rsp
popq %rbp
ret
.seh_endproc

The first thing that I realize was the the optimized version is not
generating the correct source when is exiting since it should return
"Send", but am I right? The assembler code of write_portd remains the same,
Am I missing something?

Regards, Matias.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Comp type

2018-01-10 Thread greim

AFAIK there is a small difference between comp and int64

COMP is 63bit + sign bit

int64 is 2s complement.

I hope I am right here.

Markus


___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Problems with writing to console

2018-01-10 Thread James Richters
> note that constants related to the windows 10 virtual terminal are not 
> defined in FPC yet.
Correction:  They were not added as of 3.0.4.rc1, they have been added now, not 
sure exactly which version they are/were included.

James

-Original Message-
From: fpc-pascal [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of 
James Richters
Sent: Wednesday, January 10, 2018 6:14 AM
To: 'FPC-Pascal users discussions' 
Subject: Re: [fpc-pascal] Problems with writing to console

If all you want is colors and simple positioning,  you could use Ansi escape 
codes instead of the CRT unit, then you would not have the issue with 
redirection and CRT not being supported.  Windows 10 builds after 10586 have 
re-enabled Ansi escape codes, however after build 14393 it is no longer enabled 
for executables by default.  It can be enabled with SetConsoleMode();   note 
that constants related to the windows 10 virtual terminal are not defined in 
FPC yet.  Here's a FPC example:

Const
   ENABLE_VIRTUAL_TERMINAL_PROCESSING =$0004;
Var dwOriginalOutMode, dwRequestedOutModes, dwRequestedInModes, dwOutMode:Dword;
Begin
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOriginalOutMode);
dwRequestedOutModes := ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode := dwOriginalOutMode OR dwRequestedOutModes;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOutMode);
Writeln('^[30m ',#27,'[30mBlack',#27,'[0m (black)');
Writeln('^[31m ',#27,'[31mRed',#27,'[0m');
Writeln('^[32m ',#27,'[32mGreen',#27,'[0m');
Writeln('^[33m ',#27,'[33mYellow',#27,'[0m');
Writeln('^[34m ',#27,'[34mBlue',#27,'[0m');
Writeln('^[35m ',#27,'[35mMagenta',#27,'[0m');
Writeln('^[36m ',#27,'[36mCyan',#27,'[0m');
Writeln('^[37m ',#27,'[37mWhite',#27,'[0m');
Readln;
End.

See full example attached.Of course the program is intended to run on 
versions of random versions of windows, many of which had Ansi capability 
disabled, then this would not be a potential solution.  Windows 3.11, Windows 
95 and Windows 98 had Ansi capability, but Windows 2000, Windows XP, Widnows 7, 
and Windows 10 before build 10586 did not, then Windows 10 build 10586 had Ansi 
capability again by default until Build 14393 where it still had Ansi 
Capability but not turned on by default anymore.

James

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Problems with writing to console

2018-01-10 Thread James Richters
If all you want is colors and simple positioning,  you could use Ansi escape 
codes instead of the CRT unit, then you would not have the issue with 
redirection and CRT not being supported.  Windows 10 builds after 10586 have 
re-enabled Ansi escape codes, however after build 14393 it is no longer enabled 
for executables by default.  It can be enabled with SetConsoleMode();   note 
that constants related to the windows 10 virtual terminal are not defined in 
FPC yet.  Here's a FPC example:

Const
ENABLE_VIRTUAL_TERMINAL_PROCESSING =$0004;
Var
dwOriginalOutMode,
dwRequestedOutModes,
dwRequestedInModes,
dwOutMode:Dword;
Begin
GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOriginalOutMode);
dwRequestedOutModes := ENABLE_VIRTUAL_TERMINAL_PROCESSING;
dwOutMode := dwOriginalOutMode OR dwRequestedOutModes;
SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), dwOutMode);
Writeln('^[30m ',#27,'[30mBlack',#27,'[0m (black)');
Writeln('^[31m ',#27,'[31mRed',#27,'[0m');
Writeln('^[32m ',#27,'[32mGreen',#27,'[0m');
Writeln('^[33m ',#27,'[33mYellow',#27,'[0m');
Writeln('^[34m ',#27,'[34mBlue',#27,'[0m');
Writeln('^[35m ',#27,'[35mMagenta',#27,'[0m');
Writeln('^[36m ',#27,'[36mCyan',#27,'[0m');
Writeln('^[37m ',#27,'[37mWhite',#27,'[0m');
Readln;
End.

See full example attached.Of course the program is intended to run on 
versions of random versions of windows, many of which had Ansi capability 
disabled, then this would not be a potential solution.  Windows 3.11, Windows 
95 and Windows 98 had Ansi capability, but Windows 2000, Windows XP, Widnows 7, 
and Windows 10 before build 10586 did not, then Windows 10 build 10586 had Ansi 
capability again by default until Build 14393 where it still had Ansi 
Capability but not turned on by default anymore.

James

-Original Message-
From: fpc-pascal [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of 
James Richters
Sent: Tuesday, January 09, 2018 10:28 PM
To: 'FPC-Pascal users discussions' 
Subject: Re: [fpc-pascal] Problems with writing to console

I suspect the output when writing to StdOut is moving the cursor to a location 
that is not known or kept track of by regular writeln in the CRT unit.  If this 
is what's causing seemingly random positioning,   You could possibly keep track 
of where the cursor is supposed to be yourself with the CRT functions WhereX32 
& WhereY32 then move the cursor to  a fixed position with the CRT function 
GotoXY32 , perform the Writeln to StdOut, then move the cursor back to the 
position saved by WhereX32/WhereY32 with another GotoXY32.  You mentioned you 
have several applications that work together, so maybe you can somehow use 
these functions to keep things straight in the console window, by possibly 
parking the cursor in a known position and relaying the position to the other 
program.

One problem with using WhereX32, WhereY32, and GotoXY32 with windows consoles, 
is that the console window is not a predetermined shape, it depends on how the 
user has the system configured. You can get around this two ways:

1. by detecting the existing shape of the console window with 
GetConsoleScreenBufferInfo()   Now you will know the shape of the console 
window and stay within it.
2. force the windows console window to be  particular shape with 
SetConsoleWindowInfo();  and you can also force a particular console screen 
buffer with SetConsoleScreenBufferSize();   I believe there is also a way to 
force the font, and font size for windows consoles as well.

I've attached a CRT Demo program that uses the above functions as an example.

It's not clear If you are using StdOut for redirection purposes, however if the 
output is redirected, none of this will work, because as Michael mentioned, CRT 
with redirection is not supported.. if you try it, StdOut is all that is 
redirected and Output is just lost. so then you don't have anything on the 
screen and none of the positioning will mean anything.   I did notice you can 
also write stuff to StdErr and it will redirect separately from output with 2> 
but if you use 2>&1 then you get no screen output.  So if you did want some 
stuff on the screen and to redirect other stuff, then the stuff you want 
redirected could be done with stderr and you could also still use positioning 
functions for normal output.  I attached another sample program that 
demonstrates this, try to run it with various redirects and it will be clear 
what is redirected and what isn't  It also shows writing things to stderr then 
using gotoxy32 to write over it so it won't even show up on the screen. If the 
program is run without redirection. (set wait4key to false to see this)

James

-Original Message-
From: fpc-pascal [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of 
Michael Van Canneyt
Sent: Tuesday, January 09, 2018 7:16 PM
To: FPC-Pascal users discussions 
Subject: Re: 

Re: [fpc-pascal] Comp type

2018-01-10 Thread Mattias Gaertner
On Wed, 10 Jan 2018 09:04:12 +0100
Jonas Maebe  wrote:

> Mattias Gaertner wrote:
> > Comp is Int64 div 1.  
> 
> No, that is currency. Comp is a plain 64 bit integer. It originally
> comes from Turbo Pascal, which did not have a regular 64 bit integer
> type. The x87 fpu can be used to perform 64 bit integer math though, so
> it was originally a 64 bit integer type whose calculations were
> performed using the fpu.
> 
> In FPC, it's the same on platforms that still use the x87 fpu. On other
> platforms, comp is an alias for the int64 type.

Thanks. Good to know.

I guess I got confused by the 'real' in Darius qeustion.

Mattias
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Re: [fpc-pascal] Comp type

2018-01-10 Thread Jonas Maebe
Mattias Gaertner wrote:
> Comp is Int64 div 1.

No, that is currency. Comp is a plain 64 bit integer. It originally
comes from Turbo Pascal, which did not have a regular 64 bit integer
type. The x87 fpu can be used to perform 64 bit integer math though, so
it was originally a 64 bit integer type whose calculations were
performed using the fpu.

In FPC, it's the same on platforms that still use the x87 fpu. On other
platforms, comp is an alias for the int64 type.


Jonas
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal