diff options
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.patch | 224 |
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 @@ | |||
1 | From: David Holsgrove <david.holsgrove@xilinx.com> | ||
2 | Subject: [PATCH 8/8] [Patch, microblaze]: Add branch_compare instruction | ||
3 | |||
4 | To facilitate optimization pass understanding of the conditional | ||
5 | branch for microblaze, remove the UNSPEC'd signed_compare / | ||
6 | unsigned_compare instructions, and replace with a complete | ||
7 | branch_compare which will output_asm_insn the correct cmp/cmpu | ||
8 | depending on comparison code and signed / unsigned. | ||
9 | |||
10 | We then return the correct branch instruction. | ||
11 | |||
12 | cbranchsi now calls an expanded microblaze_expand_conditional_branch | ||
13 | function which will carry out compare against zero, compare EQ/NE, | ||
14 | and all other compares appropriately. | ||
15 | |||
16 | -funroll-loops optimization pass can now proceed | ||
17 | |||
18 | Changelog | ||
19 | |||
20 | 2013-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 | |||
32 | Signed-off-by: David Holsgrove <david.holsgrove@xilinx.com> | ||
33 | Upstream-Status: Pending | ||
34 | |||
35 | diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c | ||
36 | index 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[]) | ||
129 | diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md | ||
130 | index 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 | ;;---------------------------------------------------------------- | ||
210 | diff --git a/gcc/config/microblaze/predicates.md b/gcc/config/microblaze/predicates.md | ||
211 | index 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 | -- | ||
223 | 1.7.5.4 | ||
224 | |||