Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2012-06

Question about Currency support

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Fuxin Zhang

hi,

The tests/test/cg/taddcurr.pp fails for mips now, after some tracing, I've reduced the error to a simpler one:
program t;

var
  i,j : currency;
begin
  j := -1.001;
  i := j / 10.0;
  writeln(i,' ',j);

end.
The generated code is:
...
.stabn 68,0,6,.Ll2 - main
.Ll2:
addiu $3,$0,-10010 //load -10010 to a int64 store lui $2,%hi(U_$P$T_$$_J)
sw $3,%lo(U_$P$T_$$_J)($2)
addiu $2,$0,-1
lui $3,%hi(U_$P$T_$$_J+4)
addiu $3,$3,%lo(U_$P$T_$$_J+4)
sw $2,($3)
.stabn 68,0,7,.Ll3 - main
.Ll3:
lui $2,%hi(U_$P$T_$$_J)
lw $4,%lo(U_$P$T_$$_J)($2)
lui $2,%hi(U_$P$T_$$_J+4)
addiu $2,$2,%lo(U_$P$T_$$_J+4)
lw $5,($2)
jal fpc_int64_to_double //convert it to double nop
lui $2,%hi(_$T$_Ld1)
addiu $2,$2,%lo(_$T$_Ld1)
lwc1 $f2,($2)
div.s $f0,$f0,$f2 // div 10000.0, but problem is that f0 contains a double value, here div.s is used
lui $2,%hi(_$T$_Ld2)
addiu $2,$2,%lo(_$T$_Ld2)
lwc1 $f2,($2)
div.s $f0,$f0,$f2 // should be div 10.0 lui $2,%hi(_$T$_Ld1)
addiu $2,$2,%lo(_$T$_Ld1)
lwc1 $f2,($2)
mul.s $f0,$f0,$f2 // mul 10000.0
cvt.d.s $f0,$f0
swc1 $f0,84($29)
swc1 $f1,88($29)
lw $4,84($29)
lw $5,88($29)
jal fpc_round_real
nop

I guess it is related to mips/ncpucvn.pas:
tmipseltypeconvnode.first_int_to_real
when compared to ncnv.pas, it seems ignore the floatype of resultdef. But using the inherited first_int_to_real is impossible since int64_to_float64/float32 etc. are not implemented(how can the sparc version work if so, it call the inherited one?)

BTW,

  for the statement i := j / 10.0, is that in the div node, resultdef

refers to i, left refers to j, and right refers to 10.0? But for the typeconvnode, what is the result/left/right node? In general, is there a way for me to learn about the node generating process? E.g. add print somewhere to show it? Add in each node seems too much...

Thanks in advance.

Regards
Fuxin Zhang

Reply by email

Sven Barth
to Fuxin Zhang
"Fuxin Zhang" wrote
BTW, for the statement i := j / 10.0, is that in the div node, resultdef refers to i, left refers to j, and right refers to 10.0? But for the typeconvnode, what is the result/left/right node?

AFAIK the tree of that statement will be the following:

AssigmentNode
Left: Loadnode for i
Right: BinaryNode for /:
Left: Loadnode for j
Right: Constnode for 10.0
Resultdef: floatdef (not necessarily the def of i)

If i and the resultdef of the binary node are not the same a typeconvnode will also be added, where:
Left: the binary node
Right: Nil (AFAIK a typeconvnode doesn't have a right node at all...) Resultdef: the degree if the target type (here the def if i)

In general, is there a way for me to learn about the node generating process? E.g. add print somewhere to show it? Add in each node seems too much...

AFAIK FPC has an option for this. Call the compiler using -h and check the -v options. One of them should dump the tree to a txt file.

Regards,
Sven

Reply by email

Sven Barth
to Sven Barth
"Sven Barth" wrote 5 lines
> In general, is there a way for me to learn about the node generating > process? E.g. add print somewhere to show it? Add in each node seems too > much... AFAIK FPC has an option for this. Call the compiler using -h and check

the -v options. One of them should dump the tree to a txt file.

Ok, I rechecked: the option is "-vp" and will trigger the compiler to write a "tree.log" file.

Regards,
Sven

Reply by email

Fuxin Zhang
Show quoted text 12 lines
Am 04.06.2012 10:22 schrieb "Sven Barth" : > > In general, is there a way for me to learn about the node generating > > process? E.g. add print somewhere to show it? Add in each node seems > too > > much... > > AFAIK FPC has an option for this. Call the compiler using -h and check the -v options. One of them should dump the tree to a txt file. Ok, I rechecked: the option is "-vp" and will trigger the compiler to write a "tree.log" file.

Exactly what I need, thank you!

Regards, Sven

Reply by email

Jonas Maebe
to Fuxin Zhang: The tests/test/cg/taddcurr.pp fails for mips now, after some tracing, I've reduced the…

Fuxin Zhang wrote on Mon, 04 Jun 2012:

Show quoted text 6 lines
I guess it is related to mips/ncpucvn.pas: tmipseltypeconvnode.first_int_to_real when compared to ncnv.pas, it seems ignore the floatype of resultdef. But using the inherited first_int_to_real is impossible since int64_to_float64/float32 etc. are not implemented(how can the sparc version work if so, it call the inherited one?)

Because of the two blocks rtl/linux/system.pp that are bracked with {$if defined(CPUARM) or defined(CPUM68K) or defined(CPUSPARC)}. You should probably add CPUMIPS to them, so it also imports the necessary helpers.

BTW, for the statement i := j / 10.0, is that in the div node,

It's a slash node, not a div node (a div node represents the "div" operator).

resultdef refers to i, left refers to j, and right refers to 10.0?

resultdef refers to whatever the default result type of that division is, which in turn depends on the result types of the arguments (j and 10.0). It will be set by the pass_typecheck method, which is called during parsing.

The assignment node will insert a type conversion from this resultdef (which is the resultdef of its right node, the division) to the resultdef of the target of the assignment node (its left node, "i" in this case). If the types are the same, the typeconversion will be optimized away.

In general, the type using which Pascal expressions are evaluated is completely independently from how the result is used afterwards.

Currency is a special case because of all the scaling going on though. In addition to the resultdef, there's also the nf_is_currency node flag to determine whether or not the value still has to be scaled.

But for the typeconvnode, what is the result/left/right node?

There is no right node in a typeconvnode, only a left node (ttypeconvnode inherits from tunarynode, not from binary node). Left is whatever you are converting from, and resultdef (once it has been set from ttypeconvnode.totypedef) is what you are converting to.

Jonas

Reply by email

Fuxin Zhang
Show quoted text 14 lines
In general, the type using which Pascal expressions are evaluated is completely independently from how the result is used afterwards. Currency is a special case because of all the scaling going on though. In addition to the resultdef, there's also the nf_is_currency node flag to determine whether or not the value still has to be scaled. > But for the typeconvnode, what is the result/left/right node? There is no right node in a typeconvnode, only a left node (ttypeconvnode inherits from tunarynode, not from binary node). Left is whatever you are converting from, and resultdef (once it has been set from ttypeconvnode.totypedef) is what you are converting to.

I see now.

another question, after switch to int64_to_floatxx, the code should be correct, but there is another issue that can be reduced to:

  i : currency;
  i := 9.99;
  frac(i)  frac(9.99)

frac(i) will be 9.89999999999998E-001

tests/test/cg/taddcurr.pp still fail with this.

in gdb,
(gdb) p 9.99 * 10000.0 / 10000.0
$1 = 9.9899999999999967

Is it the test program taddcurr.pp cannot work for non-x86 systems?

Jonas

Reply by email

Fuxin Zhang
Show quoted text 11 lines
Fuxin Zhang wrote on Tue, 05 Jun 2012: > Is it the test program taddcurr.pp cannot work for non-x86 systems? It works on SPARC at least: http://www.freepascal.org/testsuite/cgi-bin/testsuite.cgi?action=3&run1id=113194&testfileid=99 It doesn't work on ppc32 currently, but that's due to a bug in the ppc32 code generator somewhere (the ppc compiler halts with an internalerror; I haven't had the time yet to properly debug it).

I have found the cause of failure:

double div 99900/10000.0 = 9.99 in round to nearest mode, =9.899.. in round to zero mode.

After correcting the related fpc_setfsr, taddcurr.pp now pass.

Jonas

Reply by email