Add Nexys Video support
[microwatt.git] / fpga / nodivide.patch
1 [PATCH] Hack out ppc64le gcc fixed point divide instructions
2
3 This is a pretty horrible short term hack that removes hardware fixed
4 point divides from ppc64le gcc. It breaks VMX/VSX, but we aren't using
5 either on microwatt. We'll implement a hardware divide shortly and this
6 can go away. Please don't tell my toolchain team.
7
8 The firmware.hex file in this directory is a build of micropython using
9 a recent mainline gcc with this patch.
10
11 Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
12 ---
13
14 diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
15 index 0a2bdb79e15..02e325b73a9 100644
16 --- a/gcc/config/rs6000/rs6000-builtin.def
17 +++ b/gcc/config/rs6000/rs6000-builtin.def
18 @@ -1581,7 +1581,6 @@ BU_VSX_2 (VEC_MERGEH_V2DF, "mergeh_2df", CONST, vsx_mergeh_v2df)
19 BU_VSX_2 (VEC_MERGEH_V2DI, "mergeh_2di", CONST, vsx_mergeh_v2di)
20 BU_VSX_2 (XXSPLTD_V2DF, "xxspltd_2df", CONST, vsx_xxspltd_v2df)
21 BU_VSX_2 (XXSPLTD_V2DI, "xxspltd_2di", CONST, vsx_xxspltd_v2di)
22 -BU_VSX_2 (DIV_V2DI, "div_2di", CONST, vsx_div_v2di)
23 BU_VSX_2 (UDIV_V2DI, "udiv_2di", CONST, vsx_udiv_v2di)
24 BU_VSX_2 (MUL_V2DI, "mul_2di", CONST, vsx_mul_v2di)
25
26 diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
27 index 7f0cdc73d9b..ad0a8a74e63 100644
28 --- a/gcc/config/rs6000/rs6000-c.c
29 +++ b/gcc/config/rs6000/rs6000-c.c
30 @@ -1459,8 +1459,6 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
31 RS6000_BTI_V4SF, RS6000_BTI_V4SF, RS6000_BTI_V4SF, 0 },
32 { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_XVDIVDP,
33 RS6000_BTI_V2DF, RS6000_BTI_V2DF, RS6000_BTI_V2DF, 0 },
34 - { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_DIV_V2DI,
35 - RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
36 { VSX_BUILTIN_VEC_DIV, VSX_BUILTIN_UDIV_V2DI,
37 RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, 0 },
38 { VSX_BUILTIN_VEC_DOUBLE, VSX_BUILTIN_XVCVSXDDP,
39 diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
40 index 832eda7cbad..1c5245c781b 100644
41 --- a/gcc/config/rs6000/rs6000-call.c
42 +++ b/gcc/config/rs6000/rs6000-call.c
43 @@ -5445,7 +5445,6 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
44 gsi_replace (gsi, g, true);
45 return true;
46 /* Flavors of vec_div (Integer). */
47 - case VSX_BUILTIN_DIV_V2DI:
48 case VSX_BUILTIN_UDIV_V2DI:
49 arg0 = gimple_call_arg (stmt, 0);
50 arg1 = gimple_call_arg (stmt, 1);
51 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
52 index 9a7a1da987f..c443c2fe579 100644
53 --- a/gcc/config/rs6000/rs6000.md
54 +++ b/gcc/config/rs6000/rs6000.md
55 @@ -3071,45 +3071,6 @@
56 "maddld %0,%1,%2,%3"
57 [(set_attr "type" "mul")])
58
59 -(define_insn "udiv<mode>3"
60 - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
61 - (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
62 - (match_operand:GPR 2 "gpc_reg_operand" "r")))]
63 - ""
64 - "div<wd>u %0,%1,%2"
65 - [(set_attr "type" "div")
66 - (set_attr "size" "<bits>")])
67 -
68 -
69 -;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
70 -;; modulus. If it isn't a power of two, force operands into register and do
71 -;; a normal divide.
72 -(define_expand "div<mode>3"
73 - [(set (match_operand:GPR 0 "gpc_reg_operand")
74 - (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
75 - (match_operand:GPR 2 "reg_or_cint_operand")))]
76 - ""
77 -{
78 - if (CONST_INT_P (operands[2])
79 - && INTVAL (operands[2]) > 0
80 - && exact_log2 (INTVAL (operands[2])) >= 0)
81 - {
82 - emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
83 - DONE;
84 - }
85 -
86 - operands[2] = force_reg (<MODE>mode, operands[2]);
87 -})
88 -
89 -(define_insn "*div<mode>3"
90 - [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
91 - (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
92 - (match_operand:GPR 2 "gpc_reg_operand" "r")))]
93 - ""
94 - "div<wd> %0,%1,%2"
95 - [(set_attr "type" "div")
96 - (set_attr "size" "<bits>")])
97 -
98 (define_insn "div<mode>3_sra"
99 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
100 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
101 @@ -3170,37 +3131,6 @@
102 (set_attr "length" "8,12")
103 (set_attr "cell_micro" "not")])
104
105 -(define_expand "mod<mode>3"
106 - [(set (match_operand:GPR 0 "gpc_reg_operand")
107 - (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
108 - (match_operand:GPR 2 "reg_or_cint_operand")))]
109 - ""
110 -{
111 - int i;
112 - rtx temp1;
113 - rtx temp2;
114 -
115 - if (!CONST_INT_P (operands[2])
116 - || INTVAL (operands[2]) <= 0
117 - || (i = exact_log2 (INTVAL (operands[2]))) < 0)
118 - {
119 - if (!TARGET_MODULO)
120 - FAIL;
121 -
122 - operands[2] = force_reg (<MODE>mode, operands[2]);
123 - }
124 - else
125 - {
126 - temp1 = gen_reg_rtx (<MODE>mode);
127 - temp2 = gen_reg_rtx (<MODE>mode);
128 -
129 - emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
130 - emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
131 - emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
132 - DONE;
133 - }
134 -})
135 -
136 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
137 ;; mod, prefer putting the result of mod into a different register
138 (define_insn "*mod<mode>3"
139 diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
140 index 7633171df9c..1a2ac66bd43 100644
141 --- a/gcc/config/rs6000/vsx.md
142 +++ b/gcc/config/rs6000/vsx.md
143 @@ -1602,53 +1602,6 @@
144 "xvdiv<sd>p %x0,%x1,%x2"
145 [(set_attr "type" "<VStype_div>")])
146
147 -; Emulate vector with scalar for vec_div in V2DImode
148 -(define_insn_and_split "vsx_div_v2di"
149 - [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
150 - (unspec:V2DI [(match_operand:V2DI 1 "vsx_register_operand" "wa")
151 - (match_operand:V2DI 2 "vsx_register_operand" "wa")]
152 - UNSPEC_VSX_DIVSD))]
153 - "VECTOR_MEM_VSX_P (V2DImode)"
154 - "#"
155 - "VECTOR_MEM_VSX_P (V2DImode) && !reload_completed"
156 - [(const_int 0)]
157 -{
158 - rtx op0 = operands[0];
159 - rtx op1 = operands[1];
160 - rtx op2 = operands[2];
161 - rtx op3 = gen_reg_rtx (DImode);
162 - rtx op4 = gen_reg_rtx (DImode);
163 - rtx op5 = gen_reg_rtx (DImode);
164 - emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
165 - emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
166 - if (TARGET_POWERPC64)
167 - emit_insn (gen_divdi3 (op5, op3, op4));
168 - else
169 - {
170 - rtx libfunc = optab_libfunc (sdiv_optab, DImode);
171 - rtx target = emit_library_call_value (libfunc,
172 - op5, LCT_NORMAL, DImode,
173 - op3, DImode,
174 - op4, DImode);
175 - emit_move_insn (op5, target);
176 - }
177 - emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
178 - emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
179 - if (TARGET_POWERPC64)
180 - emit_insn (gen_divdi3 (op3, op3, op4));
181 - else
182 - {
183 - rtx libfunc = optab_libfunc (sdiv_optab, DImode);
184 - rtx target = emit_library_call_value (libfunc,
185 - op3, LCT_NORMAL, DImode,
186 - op3, DImode,
187 - op4, DImode);
188 - emit_move_insn (op3, target);
189 - }
190 - emit_insn (gen_vsx_concat_v2di (op0, op5, op3));
191 - DONE;
192 -}
193 - [(set_attr "type" "div")])
194
195 (define_insn_and_split "vsx_udiv_v2di"
196 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
197 @@ -1668,9 +1621,6 @@
198 rtx op5 = gen_reg_rtx (DImode);
199 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0)));
200 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0)));
201 - if (TARGET_POWERPC64)
202 - emit_insn (gen_udivdi3 (op5, op3, op4));
203 - else
204 {
205 rtx libfunc = optab_libfunc (udiv_optab, DImode);
206 rtx target = emit_library_call_value (libfunc,
207 @@ -1681,9 +1631,6 @@
208 }
209 emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1)));
210 emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1)));
211 - if (TARGET_POWERPC64)
212 - emit_insn (gen_udivdi3 (op3, op3, op4));
213 - else
214 {
215 rtx libfunc = optab_libfunc (udiv_optab, DImode);
216 rtx target = emit_library_call_value (libfunc,