forked from cores/microwatt
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
7.7 KiB
Diff
217 lines
7.7 KiB
Diff
5 years ago
|
[PATCH] Hack out ppc64le gcc fixed point divide instructions
|
||
|
|
||
|
This is a pretty horrible short term hack that removes hardware fixed
|
||
|
point divides from ppc64le gcc. It breaks VMX/VSX, but we aren't using
|
||
|
either on microwatt. We'll implement a hardware divide shortly and this
|
||
|
can go away. Please don't tell my toolchain team.
|
||
|
|
||
|
The firmware.hex file in this directory is a build of micropython using
|
||
|
a recent mainline gcc with this patch.
|
||
|
|
||
|
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
|
||
|
---
|
||
|
|
||
|
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
|
||
|
index 0a2bdb79e15..02e325b73a9 100644
|
||
|
--- a/gcc/config/rs6000/rs6000-builtin.def
|
||
|
+++ b/gcc/config/rs6000/rs6000-builtin.def
|
||
|
@@ -1581,7 +1581,6 @@ BU_VSX_2 (VEC_MERGEH_V2DF, "mergeh_2df", CONST, vsx_mergeh_v2df)
|
||
|
BU_VSX_2 (VEC_MERGEH_V2DI, "mergeh_2di", CONST, vsx_mergeh_v2di)
|
||
|
BU_VSX_2 (XXSPLTD_V2DF, "xxspltd_2df", CONST, vsx_xxspltd_v2df)
|
||
|
BU_VSX_2 (XXSPLTD_V2DI, "xxspltd_2di", CONST, vsx_xxspltd_v2di)
|
||
|
-BU_VSX_2 (DIV_V2DI, "div_2di", CONST, vsx_div_v2di)
|
||
|
BU_VSX_2 (UDIV_V2DI, "udiv_2di", CONST, vsx_udiv_v2di)
|
||
|
BU_VSX_2 (MUL_V2DI, "mul_2di", CONST, vsx_mul_v2di)
|
||
|
|
||
|
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
|
||
|
index 7f0cdc73d9b..ad0a8a74e63 100644
|
||
|
--- a/gcc/config/rs6000/rs6000-c.c
|
||
|
+++ b/gcc/config/rs6000/rs6000-c.c
|
||
|
@@ -1459,8 +1459,6 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
|
||
|
RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
|
||
|
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP,
|
||
|
RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
|
||
|
- { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_DIV_V2DI,
|
||
|
- RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
|
||
|
{ VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI,
|
||
|
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
|
||
|
{ VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP,
|
||
|
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
|
||
|
index 832eda7cbad..1c5245c781b 100644
|
||
|
--- a/gcc/config/rs6000/rs6000-call.c
|
||
|
+++ b/gcc/config/rs6000/rs6000-call.c
|
||
|
@@ -5445,7 +5445,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
|
||
|
gsi_replace (gsi, g, true);
|
||
|
return true;
|
||
|
/* Flavors of vec_div (Integer). */
|
||
|
- case VSX_BUILTIN_DIV_V2DI:
|
||
|
case VSX_BUILTIN_UDIV_V2DI:
|
||
|
arg0 = gimple_call_arg (stmt, 0);
|
||
|
arg1 = gimple_call_arg (stmt, 1);
|
||
|
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
|
||
|
index 9a7a1da987f..c443c2fe579 100644
|
||
|
--- a/gcc/config/rs6000/rs6000.md
|
||
|
+++ b/gcc/config/rs6000/rs6000.md
|
||
|
@@ -3071,45 +3071,6 @@
|
||
|
"maddld %0,%1,%2,%3"
|
||
|
[(set_attr "type" "mul")])
|
||
|
|
||
|
-(define_insn "udiv<mode>3"
|
||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||
|
- (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||
|
- (match_operand:GPR 2 "gpc_reg_operand" "r")))]
|
||
|
- ""
|
||
|
- "div<wd>u %0,%1,%2"
|
||
|
- [(set_attr "type" "div")
|
||
|
- (set_attr "size" "<bits>")])
|
||
|
-
|
||
|
-
|
||
|
-;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
|
||
|
-;; modulus. If it isn't a power of two, force operands into register and do
|
||
|
-;; a normal divide.
|
||
|
-(define_expand "div<mode>3"
|
||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand")
|
||
|
- (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
|
||
|
- (match_operand:GPR 2 "reg_or_cint_operand")))]
|
||
|
- ""
|
||
|
-{
|
||
|
- if (CONST_INT_P (operands[2])
|
||
|
- && INTVAL (operands[2]) > 0
|
||
|
- && exact_log2 (INTVAL (operands[2])) >= 0)
|
||
|
- {
|
||
|
- emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
|
||
|
- DONE;
|
||
|
- }
|
||
|
-
|
||
|
- operands[2] = force_reg (<MODE>mode, operands[2]);
|
||
|
-})
|
||
|
-
|
||
|
-(define_insn "*div<mode>3"
|
||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||
|
- (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||
|
- (match_operand:GPR 2 "gpc_reg_operand" "r")))]
|
||
|
- ""
|
||
|
- "div<wd> %0,%1,%2"
|
||
|
- [(set_attr "type" "div")
|
||
|
- (set_attr "size" "<bits>")])
|
||
|
-
|
||
|
(define_insn "div<mode>3_sra"
|
||
|
[(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
|
||
|
(div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
|
||
|
@@ -3170,37 +3131,6 @@
|
||
|
(set_attr "length" "8,12")
|
||
|
(set_attr "cell_micro" "not")])
|
||
|
|
||
|
-(define_expand "mod<mode>3"
|
||
|
- [(set (match_operand:GPR 0 "gpc_reg_operand")
|
||
|
- (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
|
||
|
- (match_operand:GPR 2 "reg_or_cint_operand")))]
|
||
|
- ""
|
||
|
-{
|
||
|
- int i;
|
||
|
- rtx temp1;
|
||
|
- rtx temp2;
|
||
|
-
|
||
|
- if (!CONST_INT_P (operands[2])
|
||
|
- || INTVAL (operands[2]) <= 0
|
||
|
- || (i = exact_log2 (INTVAL (operands[2]))) < 0)
|
||
|
- {
|
||
|
- if (!TARGET_MODULO)
|
||
|
- FAIL;
|
||
|
-
|
||
|
- operands[2] = force_reg (<MODE>mode, operands[2]);
|
||
|
- }
|
||
|
- else
|
||
|
- {
|
||
|
- temp1 = gen_reg_rtx (<MODE>mode);
|
||
|
- temp2 = gen_reg_rtx (<MODE>mode);
|
||
|
-
|
||
|
- emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
|
||
|
- emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
|
||
|
- emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
|
||
|
- DONE;
|
||
|
- }
|
||
|
-})
|
||
|
-
|
||
|
;; In order to enable using a peephole2 for combining div/mod to eliminate the
|
||
|
;; mod, prefer putting the result of mod into a different register
|
||
|
(define_insn "*mod<mode>3"
|
||
|
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
|
||
|
index 7633171df9c..1a2ac66bd43 100644
|
||
|
--- a/gcc/config/rs6000/vsx.md
|
||
|
+++ b/gcc/config/rs6000/vsx.md
|
||
|
@@ -1602,53 +1602,6 @@
|
||
|
"xvdiv<sd>p %x0,%x1,%x2"
|
||
|
[(set_attr "type" "<VStype_div>")])
|
||
|
|
||
|
-; Emulate vector with scalar for vec_div in V2DImode
|
||
|
-(define_insn_and_split "vsx_div_v2di"
|
||
|
- [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
|
||
|
- (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
|
||
|
- (match_operand:V2DI 2 "vsx_register_operand" "wa")]
|
||
|
- UNSPEC_VSX_DIVSD))]
|
||
|
- "VECTOR_MEM_VSX_P (V2DImode)"
|
||
|
- "#"
|
||
|
- "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed"
|
||
|
- [(const_int 0)]
|
||
|
-{
|
||
|
- rtx op0 = operands[0];
|
||
|
- rtx op1 = operands[1];
|
||
|
- rtx op2 = operands[2];
|
||
|
- rtx op3 = gen_reg_rtx (DImode);
|
||
|
- rtx op4 = gen_reg_rtx (DImode);
|
||
|
- rtx op5 = gen_reg_rtx (DImode);
|
||
|
- emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||
|
- emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||
|
- if (TARGET_POWERPC64)
|
||
|
- emit_insn (gen_divdi3 (op5, op3, op4));
|
||
|
- else
|
||
|
- {
|
||
|
- rtx libfunc = optab_libfunc (sdiv_optab, DImode);
|
||
|
- rtx target = emit_library_call_value (libfunc,
|
||
|
- op5, LCT_NORMAL, DImode,
|
||
|
- op3, DImode,
|
||
|
- op4, DImode);
|
||
|
- emit_move_insn (op5, target);
|
||
|
- }
|
||
|
- emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||
|
- emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||
|
- if (TARGET_POWERPC64)
|
||
|
- emit_insn (gen_divdi3 (op3, op3, op4));
|
||
|
- else
|
||
|
- {
|
||
|
- rtx libfunc = optab_libfunc (sdiv_optab, DImode);
|
||
|
- rtx target = emit_library_call_value (libfunc,
|
||
|
- op3, LCT_NORMAL, DImode,
|
||
|
- op3, DImode,
|
||
|
- op4, DImode);
|
||
|
- emit_move_insn (op3, target);
|
||
|
- }
|
||
|
- emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
|
||
|
- DONE;
|
||
|
-}
|
||
|
- [(set_attr "type" "div")])
|
||
|
|
||
|
(define_insn_and_split "vsx_udiv_v2di"
|
||
|
[(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
|
||
|
@@ -1668,9 +1621,6 @@
|
||
|
rtx op5 = gen_reg_rtx (DImode);
|
||
|
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
|
||
|
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
|
||
|
- if (TARGET_POWERPC64)
|
||
|
- emit_insn (gen_udivdi3 (op5, op3, op4));
|
||
|
- else
|
||
|
{
|
||
|
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||
|
rtx target = emit_library_call_value (libfunc,
|
||
|
@@ -1681,9 +1631,6 @@
|
||
|
}
|
||
|
emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
|
||
|
emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
|
||
|
- if (TARGET_POWERPC64)
|
||
|
- emit_insn (gen_udivdi3 (op3, op3, op4));
|
||
|
- else
|
||
|
{
|
||
|
rtx libfunc = optab_libfunc (udiv_optab, DImode);
|
||
|
rtx target = emit_library_call_value (libfunc,
|