summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch')
-rw-r--r--recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch224
1 files changed, 0 insertions, 224 deletions
diff --git a/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch b/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch
deleted file mode 100644
index 4da74f3f..00000000
--- a/recipes-devtools/gcc/files/0008-Patch-microblaze-Add-branch_compare-instruction.patch
+++ /dev/null
@@ -1,224 +0,0 @@
1From: David Holsgrove <david.holsgrove@xilinx.com>
2Subject: [PATCH 8/8] [Patch, microblaze]: Add branch_compare instruction
3
4To facilitate optimization pass understanding of the conditional
5branch for microblaze, remove the UNSPEC'd signed_compare /
6unsigned_compare instructions, and replace with a complete
7branch_compare which will output_asm_insn the correct cmp/cmpu
8depending on comparison code and signed / unsigned.
9
10We then return the correct branch instruction.
11
12cbranchsi now calls an expanded microblaze_expand_conditional_branch
13function which will carry out compare against zero, compare EQ/NE,
14and all other compares appropriately.
15
16-funroll-loops optimization pass can now proceed
17
18Changelog
19
202013-03-19 David Holsgrove <david.holsgrove@xilinx.com>
21
22 * gcc/config/microblaze/predicates.md: Add cmp_op predicate.
23 * gcc/config/microblaze/microblaze.md: Add branch_compare
24 instruction which uses cmp_op predicate and emits cmp insn
25 before branch.
26 * gcc/config/microblaze/microblaze.c
27 (microblaze_emit_compare): Rename to
28 microblaze_expand_conditional_branch and consolidate logic.
29 (microblaze_expand_conditional_branch): emit branch_compare
30 insn instead of handling cmp op separate from branch insn.
31
32Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com>
33Upstream-Status: Pending
34
35diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c
36index 4417289..84b58bf 100644
37--- a/gcc/config/microblaze/microblaze.c
38+++ b/gcc/config/microblaze/microblaze.c
39@@ -3336,65 +3336,45 @@ microblaze_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
40 emit_move_insn (mem, fnaddr);
41 }
42
43-/* Emit instruction to perform compare.
44- cmp is (compare_op op0 op1). */
45-static rtx
46-microblaze_emit_compare (enum machine_mode mode, rtx cmp, enum rtx_code *cmp_code)
47+/* Generate conditional branch -- first, generate test condition,
48+ second, generate correct branch instruction. */
49+
50+void
51+microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[])
52 {
53- rtx cmp_op0 = XEXP (cmp, 0);
54- rtx cmp_op1 = XEXP (cmp, 1);
55+ enum rtx_code code = GET_CODE (operands[0]);
56+ rtx cmp_op0 = operands[1];
57+ rtx cmp_op1 = operands[2];
58+ rtx label1 = operands[3];
59 rtx comp_reg = gen_reg_rtx (SImode);
60- enum rtx_code code = *cmp_code;
61-
62+ rtx condition;
63+
64 gcc_assert ((GET_CODE (cmp_op0) == REG) || (GET_CODE (cmp_op0) == SUBREG));
65
66 /* If comparing against zero, just test source reg. */
67- if (cmp_op1 == const0_rtx)
68- return cmp_op0;
69+ if (cmp_op1 == const0_rtx)
70+ {
71+ comp_reg = cmp_op0;
72+ condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx);
73+ emit_jump_insn (gen_condjump (condition, label1));
74+ }
75
76- if (code == EQ || code == NE)
77+ else if (code == EQ || code == NE)
78 {
79 /* Use xor for equal/not-equal comparison. */
80 emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1));
81+ condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx);
82+ emit_jump_insn (gen_condjump (condition, label1));
83 }
84- else if (code == GT || code == GTU || code == LE || code == LEU)
85- {
86- /* MicroBlaze compare is not symmetrical. */
87- /* Swap argument order. */
88- cmp_op1 = force_reg (mode, cmp_op1);
89- if (code == GT || code == LE)
90- emit_insn (gen_signed_compare (comp_reg, cmp_op0, cmp_op1));
91- else
92- emit_insn (gen_unsigned_compare (comp_reg, cmp_op0, cmp_op1));
93- /* Translate test condition. */
94- *cmp_code = swap_condition (code);
95- }
96- else /* if (code == GE || code == GEU || code == LT || code == LTU) */
97+ else
98 {
99+ /* Generate compare and branch in single instruction. */
100 cmp_op1 = force_reg (mode, cmp_op1);
101- if (code == GE || code == LT)
102- emit_insn (gen_signed_compare (comp_reg, cmp_op1, cmp_op0));
103- else
104- emit_insn (gen_unsigned_compare (comp_reg, cmp_op1, cmp_op0));
105+ condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1);
106+ emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1));
107 }
108-
109- return comp_reg;
110 }
111
112-/* Generate conditional branch -- first, generate test condition,
113- second, generate correct branch instruction. */
114-
115-void
116-microblaze_expand_conditional_branch (enum machine_mode mode, rtx operands[])
117-{
118- enum rtx_code code = GET_CODE (operands[0]);
119- rtx comp;
120- rtx condition;
121-
122- comp = microblaze_emit_compare (mode, operands[0], &code);
123- condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp, const0_rtx);
124- emit_jump_insn (gen_condjump (condition, operands[3]));
125-}
126
127 void
128 microblaze_expand_conditional_branch_sf (rtx operands[])
129diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md
130index 49d8f01..9c1e1a3 100644
131--- a/gcc/config/microblaze/microblaze.md
132+++ b/gcc/config/microblaze/microblaze.md
133@@ -1624,28 +1624,6 @@
134 (set_attr "length" "4")]
135 )
136
137-(define_insn "signed_compare"
138- [(set (match_operand:SI 0 "register_operand" "=d")
139- (unspec
140- [(match_operand:SI 1 "register_operand" "d")
141- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMP))]
142- ""
143- "cmp\t%0,%1,%2"
144- [(set_attr "type" "arith")
145- (set_attr "mode" "SI")
146- (set_attr "length" "4")])
147-
148-(define_insn "unsigned_compare"
149- [(set (match_operand:SI 0 "register_operand" "=d")
150- (unspec
151- [(match_operand:SI 1 "register_operand" "d")
152- (match_operand:SI 2 "register_operand" "d")] UNSPEC_CMPU))]
153- ""
154- "cmpu\t%0,%1,%2"
155- [(set_attr "type" "arith")
156- (set_attr "mode" "SI")
157- (set_attr "length" "4")])
158-
159 ;;----------------------------------------------------------------
160 ;; Setting a register from an floating point comparison.
161 ;;----------------------------------------------------------------
162@@ -1719,6 +1697,47 @@
163 (set_attr "length" "4")]
164 )
165
166+(define_insn "branch_compare"
167+ [(set (pc)
168+ (if_then_else (match_operator:SI 0 "cmp_op"
169+ [(match_operand:SI 1 "register_operand" "d")
170+ (match_operand:SI 2 "register_operand" "d")
171+ ])
172+ (label_ref (match_operand 3))
173+ (pc)))
174+ (clobber(reg:SI R_TMP))]
175+ ""
176+ {
177+ operands[4] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM);
178+ enum rtx_code code = GET_CODE (operands[0]);
179+
180+ if (code == GT || code == LE)
181+ {
182+ output_asm_insn ("cmp\tr18,%z1,%z2", operands);
183+ code = swap_condition (code);
184+ }
185+ else if (code == GTU || code == LEU)
186+ {
187+ output_asm_insn ("cmpu\tr18,%z1,%z2", operands);
188+ code = swap_condition (code);
189+ }
190+ else if (code == GE || code == LT)
191+ {
192+ output_asm_insn ("cmp\tr18,%z2,%z1", operands);
193+ }
194+ else if (code == GEU || code == LTU)
195+ {
196+ output_asm_insn ("cmpu\tr18,%z2,%z1", operands);
197+ }
198+
199+ operands[0] = gen_rtx_fmt_ee (signed_condition (code), SImode, operands[4], const0_rtx);
200+ return "b%C0i%?\tr18,%3";
201+ }
202+ [(set_attr "type" "branch")
203+ (set_attr "mode" "none")
204+ (set_attr "length" "12")]
205+)
206+
207 ;;----------------------------------------------------------------
208 ;; Unconditional branches
209 ;;----------------------------------------------------------------
210diff --git a/gcc/config/microblaze/predicates.md b/gcc/config/microblaze/predicates.md
211index 5fd1bd4..2c23291 100644
212--- a/gcc/config/microblaze/predicates.md
213+++ b/gcc/config/microblaze/predicates.md
214@@ -119,3 +119,7 @@
215 ;; Test for valid PIC call operand
216 (define_predicate "call_insn_plt_operand"
217 (match_test "PLT_ADDR_P (op)"))
218+
219+;; Return if the code of this rtx pattern is a comparison.
220+(define_predicate "cmp_op"
221+ (match_code "gt,ge,gtu,geu,lt,le,ltu,leu"))
222--
2231.7.5.4
224