From d5328492d7d8637bface29b5c7548b8103d4befc Mon Sep 17 00:00:00 2001 From: David Given Date: Sun, 20 Nov 2016 11:27:40 +0100 Subject: [PATCH] Better handling of float conversions; more tests; converting to unsigned ints works now. --- mach/powerpc/mcg/table | 24 +++++++++++++++---- mach/proto/mcg/treebuilder.c | 6 ++--- plat/qemuppc/tests/from_d_to_si_e.c | 20 ++++++++++++++++ plat/qemuppc/tests/from_d_to_ui_e.c | 16 +++++++++++++ .../tests/{cif8_e.c => from_si_to_d_e.c} | 0 .../tests/{cuf8_e.c => from_ui_to_d_e.c} | 0 util/mcgg/ir.dat | 6 +++-- 7 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 plat/qemuppc/tests/from_d_to_si_e.c create mode 100644 plat/qemuppc/tests/from_d_to_ui_e.c rename plat/qemuppc/tests/{cif8_e.c => from_si_to_d_e.c} (100%) rename plat/qemuppc/tests/{cuf8_e.c => from_ui_to_d_e.c} (100%) diff --git a/mach/powerpc/mcg/table b/mach/powerpc/mcg/table index b6bc0ac48..8511dbb5b 100644 --- a/mach/powerpc/mcg/table +++ b/mach/powerpc/mcg/table @@ -392,17 +392,33 @@ PATTERNS emit "li32 %out.1, 0" cost 8; - out:(iret)reg = FROMF.I(in:(dret)reg) + out:(iret)reg = FROMSF.I(in:(dret)reg) with corrupted(volatile) emit "bl .fromf2i" cost 4; - out:(iret)reg = FROMD.I(in:(dret)reg) + out:(int)reg = FROMSD.I(in:(double)reg) + with preserved(%in) + emit "fctiwz %in, %in" + emit "stfdu %in, -8(sp)" + emit "lwz %out, 4(sp)" + emit "addi sp, sp, 8" + cost 16; + + out:(int)reg = FROMUD.I(in:(double)reg) with corrupted(volatile) - emit "bl .fromd2i" + emit "stfdu %in, -8(sp)" + emit "bl .cfu8" + emit "lwz %out, 0(sp)" + emit "addi sp, sp, 4" + cost 16; + + out:(lret)reg = FROMSF.L(in:(fret)reg) + with corrupted(volatile) + emit "bl .fromf2l" cost 4; - out:(lret)reg = FROMF.L(in:(fret)reg) + out:(lret)reg = FROMUF.I(in:(fret)reg) with corrupted(volatile) emit "bl .fromf2l" cost 4; diff --git a/mach/proto/mcg/treebuilder.c b/mach/proto/mcg/treebuilder.c index 66347447f..5462cbf79 100644 --- a/mach/proto/mcg/treebuilder.c +++ b/mach/proto/mcg/treebuilder.c @@ -404,11 +404,11 @@ static void insn_simple(int opcode) case op_cii: simple_convert(IR_FROMSI); break; case op_ciu: simple_convert(IR_FROMSI); break; case op_cui: simple_convert(IR_FROMUI); break; - case op_cfu: simple_convert(IR_FROMF); break; /* FIXME: technically wrong */ - case op_cfi: simple_convert(IR_FROMF); break; + case op_cfu: simple_convert(IR_FROMUF); break; + case op_cfi: simple_convert(IR_FROMSF); break; case op_cif: simple_convert(IR_FROMSI); break; case op_cuf: simple_convert(IR_FROMUI); break; - case op_cff: simple_convert(IR_FROMF); break; + case op_cff: simple_convert(IR_FROMSF); break; case op_cmp: push( diff --git a/plat/qemuppc/tests/from_d_to_si_e.c b/plat/qemuppc/tests/from_d_to_si_e.c new file mode 100644 index 000000000..8c7e31c3e --- /dev/null +++ b/plat/qemuppc/tests/from_d_to_si_e.c @@ -0,0 +1,20 @@ +#include "test.h" + +/* Constants in globals to defeat constant folding. */ +double one = 1.0; +double zero = 0.0; +double minusone = -1.0; +double big = 2147483647.0; +double minusbig = -2147483648.0; + +/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ +void _m_a_i_n(void) +{ + ASSERT((int)zero == 0); + ASSERT((int)one == 1); + ASSERT((int)minusone == -1); + ASSERT((int)big == 2147483647); + ASSERT((int)minusbig == -2147483648); + + finished(); +} \ No newline at end of file diff --git a/plat/qemuppc/tests/from_d_to_ui_e.c b/plat/qemuppc/tests/from_d_to_ui_e.c new file mode 100644 index 000000000..b16667502 --- /dev/null +++ b/plat/qemuppc/tests/from_d_to_ui_e.c @@ -0,0 +1,16 @@ +#include "test.h" + +/* Constants in globals to defeat constant folding. */ +double one = 1.0; +double zero = 0.0; +double big = 4294967295.0; + +/* Bypasses the CRT, so there's no stdio or BSS initialisation. */ +void _m_a_i_n(void) +{ + ASSERT((unsigned int)zero == 0); + ASSERT((unsigned int)one == 1); + ASSERT((unsigned int)big == 4294967295); + + finished(); +} \ No newline at end of file diff --git a/plat/qemuppc/tests/cif8_e.c b/plat/qemuppc/tests/from_si_to_d_e.c similarity index 100% rename from plat/qemuppc/tests/cif8_e.c rename to plat/qemuppc/tests/from_si_to_d_e.c diff --git a/plat/qemuppc/tests/cuf8_e.c b/plat/qemuppc/tests/from_ui_to_d_e.c similarity index 100% rename from plat/qemuppc/tests/cuf8_e.c rename to plat/qemuppc/tests/from_ui_to_d_e.c diff --git a/util/mcgg/ir.dat b/util/mcgg/ir.dat index b34f37fbb..4b7c4e920 100644 --- a/util/mcgg/ir.dat +++ b/util/mcgg/ir.dat @@ -69,8 +69,10 @@ S ?=I. FROMUI S ?=L. FROMUL S ?=I. FROMSI S ?=L. FROMSL -S ?=F. FROMF -S ?=D. FROMD +S ?=F. FROMUF +S ?=D. FROMUD +S ?=F. FROMSF +S ?=D. FROMSD S L=II FROMIPAIR S I=L. FROML0 S I=L. FROML1