Add a rule for sdl ldl $1==$2 to work around a bug.

In our powerpc table, sdl fails to kill the old value of the local.
This is a bug, because a later ldl can load the old value instead of
the newly stored value.  By rewriting "sdl 0" "ldl 0" as "dup 8" "sdl
0", the newly added rule works around the bug, but only when the ldl
is immediately after the sdl.

This rule improves code that uses double-precision floating point.
The output of printf("%f", 6.0) in C changes from all zero digits to
"6000000" but still doesn't print the decimal point.  The result of
atof("-123.456") becomes correct.  In startrek, I can now move the
Enterprise, but I still can't fire phasers without crashing the game.

We already have a rule for stl lol $1==$2.  We had two copies of the
rule, so I am deleting the second copy.
This commit is contained in:
George Koehler 2016-09-30 11:50:50 -04:00
parent 6ae415d48b
commit e22c8881e7

View file

@ -923,10 +923,14 @@ PATTERNS
pat dup $1==INT32 /* Duplicate word on top of stack */ pat dup $1==INT32 /* Duplicate word on top of stack */
with GPR with GPR
yields %1 %1 yields %1 %1
with FSREG
yields %1 %1
pat dup $1==INT64 /* Duplicate double-word on top of stack */ pat dup $1==INT64 /* Duplicate double-word on top of stack */
with GPR GPR with GPR GPR
yields %2 %1 %2 %1 yields %2 %1 %2 %1
with FREG
yields %1 %1
pat exg $1==INT32 /* Exchange top two words on stack */ pat exg $1==INT32 /* Exchange top two words on stack */
with GPR GPR with GPR GPR
@ -936,7 +940,12 @@ PATTERNS
leaving leaving
dup 4 dup 4
stl $1 stl $1
pat sdl ldl $1==$2 /* Store then load double local */
leaving
dup 8
sdl $1
pat lal sti lal loi $1==$3 && $2==$4 /* Store then load local, of a different size */ pat lal sti lal loi $1==$3 && $2==$4 /* Store then load local, of a different size */
leaving leaving
dup INT32 dup INT32
@ -1045,12 +1054,7 @@ PATTERNS
leaving leaving
lol $1 lol $1
sti INT32 sti INT32
pat stl lol $1==$2 /* Save then load (generated by C compiler) */
leaving
dup 4
stl $1
pat zrl /* Zero local */ pat zrl /* Zero local */
leaving leaving
loc 0 loc 0