Re: Double Trouble with Phix (bug)

new topic     » goto parent     » topic index » view thread      » older message » newer message

OK, it works on windows, but does not work on linux.

I've got some idea what the problem is but not a proper solution yet.

First, I changed the newspin line and tested that without the set_range:

atom spin = c_func(new_spin,{1,100,10}) -- range is 1..100, try it!  

Then, in builtins\VM\pcfunc.e I changed the first set of these

                        if i=1 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm0,qword[rsp] 
                                    [] 
                                  } 
                        elsif i=2 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm0,qword[rsp] 
--                                      movsd xmm1,qword[rsp] 
                                    [] 
                                  } 
                        elsif i=3 then 
                            #ilASM{ 
                                    [64] 
                                        movsd xmm1,qword[rsp] 
                                        movsd xmm2,qword[rsp] 
                                    [] 
                                  } 

and (after p -c p, obviously) the set_range 25,75 now works. Since the first arg is a pointer, the i=1 part is not executed and we left xmm0/1/2 as 25,75,75.

But of course if you comment out the set_range, the original new_spin is now faulty, with a range of 1..10 step 10, which makes sense as we left xmm0/1/2 as 1,10,10.

So my theory is that windows puts the third arg, if floating point, in xmm2, no matter what types the first and second args are.
However I think (I've never seen this written down) that linux puts the third arg in xmm0 if 1st & 2nd args don't blag any xmm registers, up to xmm2 if they both do.

I'm thinking the fix will be entirely in pcfunc.e, and in fact we've got all the right assembly instructions we need, just the wrong controlling hll code. Maybe it will be something like this:

sequence xmmi = tagset(la) -- (used as-is under windows) 
... 
if platform()=LINUX then 
  for i=1 to la do //set xmmi[i] correctly// end for 
end if 
 
-- and in the main for i=la to 1 by -1 loop: 
  integer xi = xmmi[i] 
 
--    if i=1 then     \  times 
      if xi=1 then    /  40ish 

Of course you have to have a separate forward pass to allocate registers, then a backward one to shove them on the stack.

If you're up for it, you might want to have a go at that yourself....?

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu