diff options
Diffstat (limited to 'meta-microblaze/recipes-devtools/gcc/gcc-13/0027-Intial-commit-of-64-bit-Microblaze.patch')
| -rw-r--r-- | meta-microblaze/recipes-devtools/gcc/gcc-13/0027-Intial-commit-of-64-bit-Microblaze.patch | 784 |
1 files changed, 784 insertions, 0 deletions
diff --git a/meta-microblaze/recipes-devtools/gcc/gcc-13/0027-Intial-commit-of-64-bit-Microblaze.patch b/meta-microblaze/recipes-devtools/gcc/gcc-13/0027-Intial-commit-of-64-bit-Microblaze.patch new file mode 100644 index 00000000..c998d5eb --- /dev/null +++ b/meta-microblaze/recipes-devtools/gcc/gcc-13/0027-Intial-commit-of-64-bit-Microblaze.patch | |||
| @@ -0,0 +1,784 @@ | |||
| 1 | From dd3eee641d2bf28216bf02f324cf8b81d4a61e43 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Mahesh Bodapati <mbodapat@xilinx.com> | ||
| 3 | Date: Tue, 13 Sep 2022 13:56:52 +0530 | ||
| 4 | Subject: [PATCH 27/54] Intial commit of 64-bit Microblaze | ||
| 5 | |||
| 6 | Conflicts: | ||
| 7 | gcc/config/microblaze/microblaze.md | ||
| 8 | --- | ||
| 9 | gcc/config/microblaze/constraints.md | 6 + | ||
| 10 | gcc/config/microblaze/microblaze-protos.h | 1 + | ||
| 11 | gcc/config/microblaze/microblaze.cc | 109 +++++-- | ||
| 12 | gcc/config/microblaze/microblaze.h | 4 +- | ||
| 13 | gcc/config/microblaze/microblaze.md | 352 +++++++++++++++++++++- | ||
| 14 | gcc/config/microblaze/microblaze.opt | 7 +- | ||
| 15 | gcc/config/microblaze/t-microblaze | 7 +- | ||
| 16 | 7 files changed, 456 insertions(+), 30 deletions(-) | ||
| 17 | |||
| 18 | diff --git a/gcc/config/microblaze/constraints.md b/gcc/config/microblaze/constraints.md | ||
| 19 | index aae4be73ae3..26742d34980 100644 | ||
| 20 | --- a/gcc/config/microblaze/constraints.md | ||
| 21 | +++ b/gcc/config/microblaze/constraints.md | ||
| 22 | @@ -52,6 +52,12 @@ | ||
| 23 | (and (match_code "const_int") | ||
| 24 | (match_test "ival > 0 && ival < 0x10000"))) | ||
| 25 | |||
| 26 | +(define_constraint "K" | ||
| 27 | + "A constant in the range 0xffffff8000000000L to 0x0000007fffffffffL (inclusive)." | ||
| 28 | + (and (match_code "const_int") | ||
| 29 | + (match_test "ival > (long)0xffffff8000000000L && ival < (long)0x0000007fffffffffL"))) | ||
| 30 | + | ||
| 31 | + | ||
| 32 | ;; Define floating point constraints | ||
| 33 | |||
| 34 | (define_constraint "G" | ||
| 35 | diff --git a/gcc/config/microblaze/microblaze-protos.h b/gcc/config/microblaze/microblaze-protos.h | ||
| 36 | index 41557af0f3c..0e9f783c4a4 100644 | ||
| 37 | --- a/gcc/config/microblaze/microblaze-protos.h | ||
| 38 | +++ b/gcc/config/microblaze/microblaze-protos.h | ||
| 39 | @@ -36,6 +36,7 @@ extern void microblaze_expand_divide (rtx *); | ||
| 40 | extern void microblaze_expand_conditional_branch (enum machine_mode, rtx *); | ||
| 41 | extern void microblaze_expand_conditional_branch_reg (machine_mode, rtx *); | ||
| 42 | extern void microblaze_expand_conditional_branch_sf (rtx *); | ||
| 43 | +extern void microblaze_expand_conditional_branch_df (rtx *); | ||
| 44 | extern int microblaze_can_use_return_insn (void); | ||
| 45 | extern void print_operand (FILE *, rtx, int); | ||
| 46 | extern void print_operand_address (FILE *, rtx); | ||
| 47 | diff --git a/gcc/config/microblaze/microblaze.cc b/gcc/config/microblaze/microblaze.cc | ||
| 48 | index e28ab593c3e..7975bc182f2 100644 | ||
| 49 | --- a/gcc/config/microblaze/microblaze.cc | ||
| 50 | +++ b/gcc/config/microblaze/microblaze.cc | ||
| 51 | @@ -3438,11 +3438,11 @@ microblaze_expand_move (machine_mode mode, rtx operands[]) | ||
| 52 | op0 = operands[0]; | ||
| 53 | op1 = operands[1]; | ||
| 54 | |||
| 55 | - if (!register_operand (op0, SImode) | ||
| 56 | - && !register_operand (op1, SImode) | ||
| 57 | + if (!register_operand (op0, mode) | ||
| 58 | + && !register_operand (op1, mode) | ||
| 59 | && (GET_CODE (op1) != CONST_INT || INTVAL (op1) != 0)) | ||
| 60 | { | ||
| 61 | - rtx temp = force_reg (SImode, op1); | ||
| 62 | + rtx temp = force_reg (mode, op1); | ||
| 63 | emit_move_insn (op0, temp); | ||
| 64 | return true; | ||
| 65 | } | ||
| 66 | @@ -3511,12 +3511,12 @@ microblaze_expand_move (machine_mode mode, rtx operands[]) | ||
| 67 | && (flag_pic == 2 || microblaze_tls_symbol_p (p0) | ||
| 68 | || !SMALL_INT (p1))))) | ||
| 69 | { | ||
| 70 | - rtx temp = force_reg (SImode, p0); | ||
| 71 | + rtx temp = force_reg (mode, p0); | ||
| 72 | rtx temp2 = p1; | ||
| 73 | |||
| 74 | if (flag_pic && reload_in_progress) | ||
| 75 | df_set_regs_ever_live (PIC_OFFSET_TABLE_REGNUM, true); | ||
| 76 | - emit_move_insn (op0, gen_rtx_PLUS (SImode, temp, temp2)); | ||
| 77 | + emit_move_insn (op0, gen_rtx_PLUS (mode, temp, temp2)); | ||
| 78 | return true; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | @@ -3647,7 +3647,7 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[]) | ||
| 82 | rtx cmp_op0 = operands[1]; | ||
| 83 | rtx cmp_op1 = operands[2]; | ||
| 84 | rtx label1 = operands[3]; | ||
| 85 | - rtx comp_reg = gen_reg_rtx (SImode); | ||
| 86 | + rtx comp_reg = gen_reg_rtx (mode); | ||
| 87 | rtx condition; | ||
| 88 | |||
| 89 | gcc_assert ((GET_CODE (cmp_op0) == REG) || (GET_CODE (cmp_op0) == SUBREG)); | ||
| 90 | @@ -3656,23 +3656,36 @@ microblaze_expand_conditional_branch (machine_mode mode, rtx operands[]) | ||
| 91 | if (cmp_op1 == const0_rtx) | ||
| 92 | { | ||
| 93 | comp_reg = cmp_op0; | ||
| 94 | - condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); | ||
| 95 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
| 96 | + condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx); | ||
| 97 | + if (mode == SImode) | ||
| 98 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
| 99 | + else | ||
| 100 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
| 101 | + | ||
| 102 | } | ||
| 103 | |||
| 104 | else if (code == EQ || code == NE) | ||
| 105 | { | ||
| 106 | /* Use xor for equal/not-equal comparison. */ | ||
| 107 | - emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1)); | ||
| 108 | - condition = gen_rtx_fmt_ee (signed_condition (code), SImode, comp_reg, const0_rtx); | ||
| 109 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
| 110 | + if (mode == SImode) | ||
| 111 | + emit_insn (gen_xorsi3 (comp_reg, cmp_op0, cmp_op1)); | ||
| 112 | + else | ||
| 113 | + emit_insn (gen_xordi3 (comp_reg, cmp_op0, cmp_op1)); | ||
| 114 | + condition = gen_rtx_fmt_ee (signed_condition (code), mode, comp_reg, const0_rtx); | ||
| 115 | + if (mode == SImode) | ||
| 116 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
| 117 | + else | ||
| 118 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
| 119 | } | ||
| 120 | else | ||
| 121 | { | ||
| 122 | /* Generate compare and branch in single instruction. */ | ||
| 123 | cmp_op1 = force_reg (mode, cmp_op1); | ||
| 124 | condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); | ||
| 125 | - emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
| 126 | + if (mode == SImode) | ||
| 127 | + emit_jump_insn (gen_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
| 128 | + else | ||
| 129 | + emit_jump_insn (gen_long_branch_compare(condition, cmp_op0, cmp_op1, label1)); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | @@ -3683,7 +3696,7 @@ microblaze_expand_conditional_branch_reg (machine_mode mode, rtx operands[]) | ||
| 134 | rtx cmp_op0 = operands[1]; | ||
| 135 | rtx cmp_op1 = operands[2]; | ||
| 136 | rtx label1 = operands[3]; | ||
| 137 | - rtx comp_reg = gen_reg_rtx (SImode); | ||
| 138 | + rtx comp_reg = gen_reg_rtx (mode); | ||
| 139 | rtx condition; | ||
| 140 | |||
| 141 | gcc_assert ((GET_CODE (cmp_op0) == REG) | ||
| 142 | @@ -3694,30 +3707,63 @@ microblaze_expand_conditional_branch_reg (machine_mode mode, rtx operands[]) | ||
| 143 | { | ||
| 144 | comp_reg = cmp_op0; | ||
| 145 | condition = gen_rtx_fmt_ee (signed_condition (code), | ||
| 146 | - SImode, comp_reg, const0_rtx); | ||
| 147 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
| 148 | + mode, comp_reg, const0_rtx); | ||
| 149 | + if (mode == SImode) | ||
| 150 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
| 151 | + else | ||
| 152 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
| 153 | } | ||
| 154 | else if (code == EQ) | ||
| 155 | { | ||
| 156 | - emit_insn (gen_seq_internal_pat (comp_reg, | ||
| 157 | - cmp_op0, cmp_op1)); | ||
| 158 | - condition = gen_rtx_EQ (SImode, comp_reg, const0_rtx); | ||
| 159 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
| 160 | + if (mode == SImode) | ||
| 161 | + { | ||
| 162 | + emit_insn (gen_seq_internal_pat (comp_reg, cmp_op0, | ||
| 163 | + cmp_op1)); | ||
| 164 | + } | ||
| 165 | + else | ||
| 166 | + { | ||
| 167 | + emit_insn (gen_seq_internal_pat (comp_reg, cmp_op0, | ||
| 168 | + cmp_op1)); | ||
| 169 | + } | ||
| 170 | + condition = gen_rtx_EQ (mode, comp_reg, const0_rtx); | ||
| 171 | + if (mode == SImode) | ||
| 172 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
| 173 | + else | ||
| 174 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
| 175 | + | ||
| 176 | } | ||
| 177 | else if (code == NE) | ||
| 178 | { | ||
| 179 | - emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
| 180 | - cmp_op1)); | ||
| 181 | - condition = gen_rtx_NE (SImode, comp_reg, const0_rtx); | ||
| 182 | - emit_jump_insn (gen_condjump (condition, label1)); | ||
| 183 | + if (mode == SImode) | ||
| 184 | + { | ||
| 185 | + emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
| 186 | + cmp_op1)); | ||
| 187 | + } | ||
| 188 | + else | ||
| 189 | + { | ||
| 190 | + emit_insn (gen_sne_internal_pat (comp_reg, cmp_op0, | ||
| 191 | + cmp_op1)); | ||
| 192 | + } | ||
| 193 | + condition = gen_rtx_NE (mode, comp_reg, const0_rtx); | ||
| 194 | + if (mode == SImode) | ||
| 195 | + emit_jump_insn (gen_condjump (condition, label1)); | ||
| 196 | + else | ||
| 197 | + emit_jump_insn (gen_long_condjump (condition, label1)); | ||
| 198 | } | ||
| 199 | else | ||
| 200 | { | ||
| 201 | /* Generate compare and branch in single instruction. */ | ||
| 202 | cmp_op1 = force_reg (mode, cmp_op1); | ||
| 203 | condition = gen_rtx_fmt_ee (code, mode, cmp_op0, cmp_op1); | ||
| 204 | - emit_jump_insn (gen_branch_compare (condition, cmp_op0, | ||
| 205 | - cmp_op1, label1)); | ||
| 206 | + if (mode == SImode) | ||
| 207 | + emit_jump_insn (gen_branch_compare (condition, cmp_op0, | ||
| 208 | + cmp_op1, label1)); | ||
| 209 | + else | ||
| 210 | + { | ||
| 211 | + emit_jump_insn (gen_long_branch_compare (condition, cmp_op0, | ||
| 212 | + cmp_op1, label1)); | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | } | ||
| 216 | } | ||
| 217 | |||
| 218 | @@ -3734,6 +3780,19 @@ microblaze_expand_conditional_branch_sf (rtx operands[]) | ||
| 219 | emit_jump_insn (gen_condjump (condition, operands[3])); | ||
| 220 | } | ||
| 221 | |||
| 222 | +void | ||
| 223 | +microblaze_expand_conditional_branch_df (rtx operands[]) | ||
| 224 | +{ | ||
| 225 | + rtx condition; | ||
| 226 | + rtx cmp_op0 = XEXP (operands[0], 0); | ||
| 227 | + rtx cmp_op1 = XEXP (operands[0], 1); | ||
| 228 | + rtx comp_reg = gen_reg_rtx (DImode); | ||
| 229 | + | ||
| 230 | + emit_insn (gen_cstoredf4 (comp_reg, operands[0], cmp_op0, cmp_op1)); | ||
| 231 | + condition = gen_rtx_NE (DImode, comp_reg, const0_rtx); | ||
| 232 | + emit_jump_insn (gen_long_condjump (condition, operands[3])); | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | /* Implement TARGET_FRAME_POINTER_REQUIRED. */ | ||
| 236 | |||
| 237 | static bool | ||
| 238 | diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h | ||
| 239 | index 94d96bf6b5d..f35f7075ce3 100644 | ||
| 240 | --- a/gcc/config/microblaze/microblaze.h | ||
| 241 | +++ b/gcc/config/microblaze/microblaze.h | ||
| 242 | @@ -102,6 +102,7 @@ extern enum pipeline_type microblaze_pipe; | ||
| 243 | #define ASM_SPEC "\ | ||
| 244 | %(target_asm_spec) \ | ||
| 245 | %{mbig-endian:-EB} \ | ||
| 246 | +%{m64:-m64} \ | ||
| 247 | %{mlittle-endian:-EL}" | ||
| 248 | |||
| 249 | /* Extra switches sometimes passed to the linker. */ | ||
| 250 | @@ -110,6 +111,7 @@ extern enum pipeline_type microblaze_pipe; | ||
| 251 | #define LINK_SPEC "%{shared:-shared} -N -relax \ | ||
| 252 | %{mbig-endian:-EB --oformat=elf32-microblaze} \ | ||
| 253 | %{mlittle-endian:-EL --oformat=elf32-microblazeel} \ | ||
| 254 | + %{m64:-EL --oformat=elf64-microblazeel} \ | ||
| 255 | %{Zxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \ | ||
| 256 | %{mxl-mode-xmdstub:-defsym _TEXT_START_ADDR=0x800} \ | ||
| 257 | %{mxl-gp-opt:%{G*}} %{!mxl-gp-opt: -G 0} \ | ||
| 258 | @@ -217,7 +219,7 @@ extern enum pipeline_type microblaze_pipe; | ||
| 259 | #define MIN_UNITS_PER_WORD 4 | ||
| 260 | #define INT_TYPE_SIZE 32 | ||
| 261 | #define SHORT_TYPE_SIZE 16 | ||
| 262 | -#define LONG_TYPE_SIZE 32 | ||
| 263 | +#define LONG_TYPE_SIZE 64 | ||
| 264 | #define LONG_LONG_TYPE_SIZE 64 | ||
| 265 | #define FLOAT_TYPE_SIZE 32 | ||
| 266 | #define DOUBLE_TYPE_SIZE 64 | ||
| 267 | diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md | ||
| 268 | index b05f7da30b4..3f572fe2351 100644 | ||
| 269 | --- a/gcc/config/microblaze/microblaze.md | ||
| 270 | +++ b/gcc/config/microblaze/microblaze.md | ||
| 271 | @@ -497,7 +497,6 @@ | ||
| 272 | (set_attr "mode" "SF") | ||
| 273 | (set_attr "length" "4")]) | ||
| 274 | |||
| 275 | - | ||
| 276 | (define_insn "divsf3" | ||
| 277 | [(set (match_operand:SF 0 "register_operand" "=d") | ||
| 278 | (div:SF (match_operand:SF 1 "register_operand" "d") | ||
| 279 | @@ -508,6 +507,7 @@ | ||
| 280 | (set_attr "mode" "SF") | ||
| 281 | (set_attr "length" "4")]) | ||
| 282 | |||
| 283 | + | ||
| 284 | (define_insn "sqrtsf2" | ||
| 285 | [(set (match_operand:SF 0 "register_operand" "=d") | ||
| 286 | (sqrt:SF (match_operand:SF 1 "register_operand" "d")))] | ||
| 287 | @@ -562,6 +562,18 @@ | ||
| 288 | |||
| 289 | ;; Adding 2 DI operands in register or reg/imm | ||
| 290 | |||
| 291 | +(define_insn "adddi3_long" | ||
| 292 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 293 | + (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%dJ,dJ") | ||
| 294 | + (match_operand:DI 2 "arith_plus_operand" "d,K")))] | ||
| 295 | + "TARGET_MB_64" | ||
| 296 | + "@ | ||
| 297 | + addlk\t%0,%z1,%2 | ||
| 298 | + addlik\t%0,%z1,%2" | ||
| 299 | + [(set_attr "type" "arith,arith") | ||
| 300 | + (set_attr "mode" "DI,DI") | ||
| 301 | + (set_attr "length" "4,4")]) | ||
| 302 | + | ||
| 303 | (define_insn "adddi3" | ||
| 304 | [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 305 | (plus:DI (match_operand:DI 1 "register_operand" "%d,d") | ||
| 306 | @@ -606,6 +618,18 @@ | ||
| 307 | ;; Double Precision Subtraction | ||
| 308 | ;;---------------------------------------------------------------- | ||
| 309 | |||
| 310 | +(define_insn "subdi3_long" | ||
| 311 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 312 | + (minus:DI (match_operand:DI 1 "register_operand" "d,d") | ||
| 313 | + (match_operand:DI 2 "register_operand" "d,n")))] | ||
| 314 | + "TARGET_MB_64" | ||
| 315 | + "@ | ||
| 316 | + rsubl\t%0,%2,%1 | ||
| 317 | + addlik\t%0,%z1,-%2" | ||
| 318 | + [(set_attr "type" "darith") | ||
| 319 | + (set_attr "mode" "DI,DI") | ||
| 320 | + (set_attr "length" "4,4")]) | ||
| 321 | + | ||
| 322 | (define_insn "subdi3" | ||
| 323 | [(set (match_operand:DI 0 "register_operand" "=&d") | ||
| 324 | (minus:DI (match_operand:DI 1 "register_operand" "d") | ||
| 325 | @@ -795,6 +819,15 @@ | ||
| 326 | (set_attr "mode" "SI") | ||
| 327 | (set_attr "length" "4")]) | ||
| 328 | |||
| 329 | +(define_insn "negdi2_long" | ||
| 330 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 331 | + (neg:DI (match_operand:DI 1 "register_operand" "d")))] | ||
| 332 | + "TARGET_MB_64" | ||
| 333 | + "rsubl\t%0,%1,r0" | ||
| 334 | + [(set_attr "type" "darith") | ||
| 335 | + (set_attr "mode" "DI") | ||
| 336 | + (set_attr "length" "4")]) | ||
| 337 | + | ||
| 338 | (define_insn "negdi2" | ||
| 339 | [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 340 | (neg:DI (match_operand:DI 1 "register_operand" "d")))] | ||
| 341 | @@ -814,6 +847,15 @@ | ||
| 342 | (set_attr "mode" "SI") | ||
| 343 | (set_attr "length" "4")]) | ||
| 344 | |||
| 345 | +(define_insn "one_cmpldi2_long" | ||
| 346 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 347 | + (not:DI (match_operand:DI 1 "register_operand" "d")))] | ||
| 348 | + "TARGET_MB_64" | ||
| 349 | + "xorli\t%0,%1,-1" | ||
| 350 | + [(set_attr "type" "arith") | ||
| 351 | + (set_attr "mode" "DI") | ||
| 352 | + (set_attr "length" "4")]) | ||
| 353 | + | ||
| 354 | (define_insn "*one_cmpldi2" | ||
| 355 | [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 356 | (not:DI (match_operand:DI 1 "register_operand" "d")))] | ||
| 357 | @@ -840,6 +882,20 @@ | ||
| 358 | ;; Logical | ||
| 359 | ;;---------------------------------------------------------------- | ||
| 360 | |||
| 361 | +(define_insn "anddi3" | ||
| 362 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 363 | + (and:DI (match_operand:DI 1 "arith_operand" "d,d") | ||
| 364 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
| 365 | + "TARGET_MB_64" | ||
| 366 | + "@ | ||
| 367 | + andl\t%0,%1,%2 | ||
| 368 | + andli\t%0,%1,%2 #andl1" | ||
| 369 | + ;; andli\t%0,%1,%2 #andl3 | ||
| 370 | + ;; andli\t%0,%1,%2 #andl2 | ||
| 371 | + [(set_attr "type" "arith,arith") | ||
| 372 | + (set_attr "mode" "DI,DI") | ||
| 373 | + (set_attr "length" "4,4")]) | ||
| 374 | + | ||
| 375 | (define_insn "andsi3" | ||
| 376 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") | ||
| 377 | (and:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d") | ||
| 378 | @@ -855,6 +911,18 @@ | ||
| 379 | (set_attr "length" "4,8,8,8")]) | ||
| 380 | |||
| 381 | |||
| 382 | +(define_insn "iordi3" | ||
| 383 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 384 | + (ior:DI (match_operand:DI 1 "arith_operand" "d,d") | ||
| 385 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
| 386 | + "TARGET_MB_64" | ||
| 387 | + "@ | ||
| 388 | + orl\t%0,%1,%2 | ||
| 389 | + orli\t%0,%1,%2 #andl1" | ||
| 390 | + [(set_attr "type" "arith,arith") | ||
| 391 | + (set_attr "mode" "DI,DI") | ||
| 392 | + (set_attr "length" "4,4")]) | ||
| 393 | + | ||
| 394 | (define_insn "iorsi3" | ||
| 395 | [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") | ||
| 396 | (ior:SI (match_operand:SI 1 "arith_operand" "%d,d,d,d") | ||
| 397 | @@ -869,6 +937,19 @@ | ||
| 398 | (set_attr "mode" "SI,SI,SI,SI") | ||
| 399 | (set_attr "length" "4,8,8,8")]) | ||
| 400 | |||
| 401 | +(define_insn "xordi3" | ||
| 402 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 403 | + (xor:DI (match_operand:DI 1 "arith_operand" "%d,d") | ||
| 404 | + (match_operand:DI 2 "arith_operand" "d,K")))] | ||
| 405 | + "TARGET_MB_64" | ||
| 406 | + "@ | ||
| 407 | + xorl\t%0,%1,%2 | ||
| 408 | + xorli\t%0,%1,%2 #andl1" | ||
| 409 | + [(set_attr "type" "arith,arith") | ||
| 410 | + (set_attr "mode" "DI,DI") | ||
| 411 | + (set_attr "length" "4,4")]) | ||
| 412 | + | ||
| 413 | + | ||
| 414 | (define_insn "xorsi3" | ||
| 415 | [(set (match_operand:SI 0 "register_operand" "=d,d,d") | ||
| 416 | (xor:SI (match_operand:SI 1 "arith_operand" "%d,d,d") | ||
| 417 | @@ -937,6 +1018,26 @@ | ||
| 418 | (set_attr "mode" "SI") | ||
| 419 | (set_attr "length" "4")]) | ||
| 420 | |||
| 421 | +;;(define_expand "extendqidi2" | ||
| 422 | +;; [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 423 | +;; (sign_extend:DI (match_operand:QI 1 "general_operand" "d")))] | ||
| 424 | +;; "TARGET_MB_64" | ||
| 425 | +;; { | ||
| 426 | +;; if (GET_CODE (operands[1]) != REG) | ||
| 427 | +;; FAIL; | ||
| 428 | +;; } | ||
| 429 | +;;) | ||
| 430 | + | ||
| 431 | + | ||
| 432 | +;;(define_insn "extendqidi2" | ||
| 433 | +;; [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 434 | +;; (sign_extend:DI (match_operand:QI 1 "register_operand" "d")))] | ||
| 435 | +;; "TARGET_MB_64" | ||
| 436 | +;; "sextl8\t%0,%1" | ||
| 437 | +;; [(set_attr "type" "arith") | ||
| 438 | +;; (set_attr "mode" "DI") | ||
| 439 | +;; (set_attr "length" "4")]) | ||
| 440 | + | ||
| 441 | (define_insn "extendhisi2" | ||
| 442 | [(set (match_operand:SI 0 "register_operand" "=d") | ||
| 443 | (sign_extend:SI (match_operand:HI 1 "register_operand" "d")))] | ||
| 444 | @@ -946,6 +1047,16 @@ | ||
| 445 | (set_attr "mode" "SI") | ||
| 446 | (set_attr "length" "4")]) | ||
| 447 | |||
| 448 | +(define_insn "extendhidi2" | ||
| 449 | + [(set (match_operand:DI 0 "register_operand" "=d") | ||
| 450 | + (sign_extend:DI (match_operand:HI 1 "register_operand" "d")))] | ||
| 451 | + "TARGET_MB_64" | ||
| 452 | + "sextl16\t%0,%1" | ||
| 453 | + [(set_attr "type" "arith") | ||
| 454 | + (set_attr "mode" "DI") | ||
| 455 | + (set_attr "length" "4")]) | ||
| 456 | + | ||
| 457 | + | ||
| 458 | ;; Those for integer source operand are ordered | ||
| 459 | ;; widest source type first. | ||
| 460 | |||
| 461 | @@ -1009,6 +1120,32 @@ | ||
| 462 | ) | ||
| 463 | |||
| 464 | |||
| 465 | +(define_insn "*movdi_internal_64" | ||
| 466 | + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o") | ||
| 467 | + (match_operand:DI 1 "general_operand" " d,K,J,R,o,d,d"))] | ||
| 468 | + "TARGET_MB_64 && (INTVAL(operands[1]) < 0x7fffffffff) && (INTVAL(operands[1]) > 0xffffff8000000000)" | ||
| 469 | + { | ||
| 470 | + switch (which_alternative) | ||
| 471 | + { | ||
| 472 | + case 0: | ||
| 473 | + return "addlk\t%0,%1"; | ||
| 474 | + case 1: | ||
| 475 | + return "addlik\t%0,r0,%1"; | ||
| 476 | + case 2: | ||
| 477 | + return "addlk\t%0,r0,r0"; | ||
| 478 | + case 3: | ||
| 479 | + case 4: | ||
| 480 | + return "lli\t%0,%1"; | ||
| 481 | + case 5: | ||
| 482 | + case 6: | ||
| 483 | + return "sli\t%1,%0"; | ||
| 484 | + } | ||
| 485 | + return "unreachable"; | ||
| 486 | + } | ||
| 487 | + [(set_attr "type" "no_delay_move,no_delay_arith,no_delay_arith,no_delay_load,no_delay_load,no_delay_store,no_delay_store") | ||
| 488 | + (set_attr "mode" "DI") | ||
| 489 | + (set_attr "length" "8,8,8,8,12,8,12")]) | ||
| 490 | + | ||
| 491 | |||
| 492 | (define_insn "*movdi_internal" | ||
| 493 | [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,o") | ||
| 494 | @@ -1421,6 +1558,36 @@ | ||
| 495 | (set_attr "length" "4,4")] | ||
| 496 | ) | ||
| 497 | |||
| 498 | +;; Barrel shift left | ||
| 499 | +(define_expand "ashldi3" | ||
| 500 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
| 501 | + (ashift:DI (match_operand:DI 1 "register_operand" "d") | ||
| 502 | + (match_operand:DI 2 "arith_operand" "")))] | ||
| 503 | +"TARGET_MB_64" | ||
| 504 | +{ | ||
| 505 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 506 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 507 | + { | ||
| 508 | + emit_insn(gen_ashldi3_long (operands[0], operands[1],operands[2])); | ||
| 509 | + DONE; | ||
| 510 | + } | ||
| 511 | +else | ||
| 512 | + FAIL; | ||
| 513 | +} | ||
| 514 | +) | ||
| 515 | + | ||
| 516 | +(define_insn "ashldi3_long" | ||
| 517 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 518 | + (ashift:DI (match_operand:DI 1 "register_operand" "d,d") | ||
| 519 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
| 520 | + "TARGET_MB_64" | ||
| 521 | + "@ | ||
| 522 | + bsllli\t%0,%1,%2 | ||
| 523 | + bslll\t%0,%1,%2" | ||
| 524 | + [(set_attr "type" "bshift,bshift") | ||
| 525 | + (set_attr "mode" "DI,DI") | ||
| 526 | + (set_attr "length" "4,4")] | ||
| 527 | +) | ||
| 528 | ;; The following patterns apply when there is no barrel shifter present | ||
| 529 | |||
| 530 | (define_insn "*ashlsi3_with_mul_delay" | ||
| 531 | @@ -1546,6 +1713,36 @@ | ||
| 532 | ;;---------------------------------------------------------------- | ||
| 533 | ;; 32-bit right shifts | ||
| 534 | ;;---------------------------------------------------------------- | ||
| 535 | +;; Barrel shift left | ||
| 536 | +(define_expand "ashrdi3" | ||
| 537 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
| 538 | + (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") | ||
| 539 | + (match_operand:DI 2 "arith_operand" "")))] | ||
| 540 | +"TARGET_MB_64" | ||
| 541 | +{ | ||
| 542 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 543 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 544 | + { | ||
| 545 | + emit_insn(gen_ashrdi3_long (operands[0], operands[1],operands[2])); | ||
| 546 | + DONE; | ||
| 547 | + } | ||
| 548 | +else | ||
| 549 | + FAIL; | ||
| 550 | +} | ||
| 551 | +) | ||
| 552 | + | ||
| 553 | +(define_insn "ashrdi3_long" | ||
| 554 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 555 | + (ashiftrt:DI (match_operand:DI 1 "register_operand" "d,d") | ||
| 556 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
| 557 | + "TARGET_MB_64" | ||
| 558 | + "@ | ||
| 559 | + bslrai\t%0,%1,%2 | ||
| 560 | + bslra\t%0,%1,%2" | ||
| 561 | + [(set_attr "type" "bshift,bshift") | ||
| 562 | + (set_attr "mode" "DI,DI") | ||
| 563 | + (set_attr "length" "4,4")] | ||
| 564 | + ) | ||
| 565 | (define_expand "ashrsi3" | ||
| 566 | [(set (match_operand:SI 0 "register_operand" "=&d") | ||
| 567 | (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") | ||
| 568 | @@ -1655,6 +1852,36 @@ | ||
| 569 | ;;---------------------------------------------------------------- | ||
| 570 | ;; 32-bit right shifts (logical) | ||
| 571 | ;;---------------------------------------------------------------- | ||
| 572 | +;; Barrel shift left | ||
| 573 | +(define_expand "lshrdi3" | ||
| 574 | + [(set (match_operand:DI 0 "register_operand" "=&d") | ||
| 575 | + (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") | ||
| 576 | + (match_operand:DI 2 "arith_operand" "")))] | ||
| 577 | +"TARGET_MB_64" | ||
| 578 | +{ | ||
| 579 | +;;if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 580 | +if (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 65) | ||
| 581 | + { | ||
| 582 | + emit_insn(gen_lshrdi3_long (operands[0], operands[1],operands[2])); | ||
| 583 | + DONE; | ||
| 584 | + } | ||
| 585 | +else | ||
| 586 | + FAIL; | ||
| 587 | +} | ||
| 588 | +) | ||
| 589 | + | ||
| 590 | +(define_insn "lshrdi3_long" | ||
| 591 | + [(set (match_operand:DI 0 "register_operand" "=d,d") | ||
| 592 | + (lshiftrt:DI (match_operand:DI 1 "register_operand" "d,d") | ||
| 593 | + (match_operand:DI 2 "arith_operand" "I,d")))] | ||
| 594 | + "TARGET_MB_64" | ||
| 595 | + "@ | ||
| 596 | + bslrli\t%0,%1,%2 | ||
| 597 | + bslrl\t%0,%1,%2" | ||
| 598 | + [(set_attr "type" "bshift,bshift") | ||
| 599 | + (set_attr "mode" "DI,DI") | ||
| 600 | + (set_attr "length" "4,4")] | ||
| 601 | + ) | ||
| 602 | |||
| 603 | (define_expand "lshrsi3" | ||
| 604 | [(set (match_operand:SI 0 "register_operand" "=&d") | ||
| 605 | @@ -1800,6 +2027,8 @@ | ||
| 606 | (set_attr "length" "4")] | ||
| 607 | ) | ||
| 608 | |||
| 609 | + | ||
| 610 | + | ||
| 611 | ;;---------------------------------------------------------------- | ||
| 612 | ;; Setting a register from an floating point comparison. | ||
| 613 | ;;---------------------------------------------------------------- | ||
| 614 | @@ -1815,6 +2044,18 @@ | ||
| 615 | (set_attr "length" "4")] | ||
| 616 | ) | ||
| 617 | |||
| 618 | +(define_insn "cstoredf4" | ||
| 619 | + [(set (match_operand:DI 0 "register_operand" "=r") | ||
| 620 | + (match_operator:DI 1 "ordered_comparison_operator" | ||
| 621 | + [(match_operand:DF 2 "register_operand" "r") | ||
| 622 | + (match_operand:DF 3 "register_operand" "r")]))] | ||
| 623 | + "TARGET_MB_64" | ||
| 624 | + "dcmp.%C1\t%0,%3,%2" | ||
| 625 | + [(set_attr "type" "fcmp") | ||
| 626 | + (set_attr "mode" "DF") | ||
| 627 | + (set_attr "length" "4")] | ||
| 628 | +) | ||
| 629 | + | ||
| 630 | ;;---------------------------------------------------------------- | ||
| 631 | ;; Conditional branches | ||
| 632 | ;;---------------------------------------------------------------- | ||
| 633 | @@ -1927,6 +2168,115 @@ | ||
| 634 | (set_attr "length" "12")] | ||
| 635 | ) | ||
| 636 | |||
| 637 | + | ||
| 638 | +(define_expand "cbranchdi4" | ||
| 639 | + [(set (pc) | ||
| 640 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
| 641 | + [(match_operand:DI 1 "register_operand") | ||
| 642 | + (match_operand:DI 2 "arith_operand" "I,i")]) | ||
| 643 | + (label_ref (match_operand 3 "")) | ||
| 644 | + (pc)))] | ||
| 645 | + "TARGET_MB_64" | ||
| 646 | +{ | ||
| 647 | + microblaze_expand_conditional_branch (DImode, operands); | ||
| 648 | + DONE; | ||
| 649 | +}) | ||
| 650 | + | ||
| 651 | +(define_expand "cbranchdi4_reg" | ||
| 652 | + [(set (pc) | ||
| 653 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
| 654 | + [(match_operand:DI 1 "register_operand") | ||
| 655 | + (match_operand:DI 2 "register_operand")]) | ||
| 656 | + (label_ref (match_operand 3 "")) | ||
| 657 | + (pc)))] | ||
| 658 | + "TARGET_MB_64" | ||
| 659 | +{ | ||
| 660 | + microblaze_expand_conditional_branch_reg (DImode, operands); | ||
| 661 | + DONE; | ||
| 662 | +}) | ||
| 663 | + | ||
| 664 | +(define_expand "cbranchdf4" | ||
| 665 | + [(set (pc) | ||
| 666 | + (if_then_else (match_operator 0 "ordered_comparison_operator" | ||
| 667 | + [(match_operand:DF 1 "register_operand") | ||
| 668 | + (match_operand:DF 2 "register_operand")]) | ||
| 669 | + (label_ref (match_operand 3 "")) | ||
| 670 | + (pc)))] | ||
| 671 | + "TARGET_MB_64" | ||
| 672 | +{ | ||
| 673 | + microblaze_expand_conditional_branch_df (operands); | ||
| 674 | + DONE; | ||
| 675 | + | ||
| 676 | +}) | ||
| 677 | + | ||
| 678 | +;; Used to implement comparison instructions | ||
| 679 | +(define_expand "long_condjump" | ||
| 680 | + [(set (pc) | ||
| 681 | + (if_then_else (match_operand 0) | ||
| 682 | + (label_ref (match_operand 1)) | ||
| 683 | + (pc)))]) | ||
| 684 | + | ||
| 685 | +(define_insn "long_branch_zero" | ||
| 686 | + [(set (pc) | ||
| 687 | + (if_then_else (match_operator:DI 0 "ordered_comparison_operator" | ||
| 688 | + [(match_operand:DI 1 "register_operand" "d") | ||
| 689 | + (const_int 0)]) | ||
| 690 | + (match_operand:DI 2 "pc_or_label_operand" "") | ||
| 691 | + (match_operand:DI 3 "pc_or_label_operand" ""))) | ||
| 692 | + ] | ||
| 693 | + "TARGET_MB_64" | ||
| 694 | + { | ||
| 695 | + if (operands[3] == pc_rtx) | ||
| 696 | + return "beal%C0i%?\t%z1,%2"; | ||
| 697 | + else | ||
| 698 | + return "beal%N0i%?\t%z1,%3"; | ||
| 699 | + } | ||
| 700 | + [(set_attr "type" "branch") | ||
| 701 | + (set_attr "mode" "none") | ||
| 702 | + (set_attr "length" "4")] | ||
| 703 | +) | ||
| 704 | + | ||
| 705 | +(define_insn "long_branch_compare" | ||
| 706 | + [(set (pc) | ||
| 707 | + (if_then_else (match_operator:DI 0 "cmp_op" | ||
| 708 | + [(match_operand:DI 1 "register_operand" "d") | ||
| 709 | + (match_operand:DI 2 "register_operand" "d") | ||
| 710 | + ]) | ||
| 711 | + (label_ref (match_operand 3)) | ||
| 712 | + (pc))) | ||
| 713 | + (clobber(reg:DI R_TMP))] | ||
| 714 | + "TARGET_MB_64" | ||
| 715 | + { | ||
| 716 | + operands[4] = gen_rtx_REG (DImode, MB_ABI_ASM_TEMP_REGNUM); | ||
| 717 | + enum rtx_code code = GET_CODE (operands[0]); | ||
| 718 | + | ||
| 719 | + if (code == GT || code == LE) | ||
| 720 | + { | ||
| 721 | + output_asm_insn ("cmpl\tr18,%z1,%z2", operands); | ||
| 722 | + code = swap_condition (code); | ||
| 723 | + } | ||
| 724 | + else if (code == GTU || code == LEU) | ||
| 725 | + { | ||
| 726 | + output_asm_insn ("cmplu\tr18,%z1,%z2", operands); | ||
| 727 | + code = swap_condition (code); | ||
| 728 | + } | ||
| 729 | + else if (code == GE || code == LT) | ||
| 730 | + { | ||
| 731 | + output_asm_insn ("cmpl\tr18,%z2,%z1", operands); | ||
| 732 | + } | ||
| 733 | + else if (code == GEU || code == LTU) | ||
| 734 | + { | ||
| 735 | + output_asm_insn ("cmplu\tr18,%z2,%z1", operands); | ||
| 736 | + } | ||
| 737 | + | ||
| 738 | + operands[0] = gen_rtx_fmt_ee (signed_condition (code), DImode, operands[4], const0_rtx); | ||
| 739 | + return "beal%C0i%?\tr18,%3"; | ||
| 740 | + } | ||
| 741 | + [(set_attr "type" "branch") | ||
| 742 | + (set_attr "mode" "none") | ||
| 743 | + (set_attr "length" "12")] | ||
| 744 | +) | ||
| 745 | + | ||
| 746 | ;;---------------------------------------------------------------- | ||
| 747 | ;; Unconditional branches | ||
| 748 | ;;---------------------------------------------------------------- | ||
| 749 | diff --git a/gcc/config/microblaze/microblaze.opt b/gcc/config/microblaze/microblaze.opt | ||
| 750 | index 37aaaf9ffda..96615a6d2c4 100644 | ||
| 751 | --- a/gcc/config/microblaze/microblaze.opt | ||
| 752 | +++ b/gcc/config/microblaze/microblaze.opt | ||
| 753 | @@ -136,4 +136,9 @@ Target | ||
| 754 | |||
| 755 | mxl-frequency | ||
| 756 | Target Mask(AREA_OPTIMIZED_2) | ||
| 757 | -Use 8 stage pipeline (frequency optimization) | ||
| 758 | +Use 8 stage pipeline (frequency optimization). | ||
| 759 | + | ||
| 760 | +m64 | ||
| 761 | +Target Mask(MB_64) | ||
| 762 | +MicroBlaze 64-bit mode. | ||
| 763 | + | ||
| 764 | diff --git a/gcc/config/microblaze/t-microblaze b/gcc/config/microblaze/t-microblaze | ||
| 765 | index 7e2fc5dcef8..4c25cfe15e7 100644 | ||
| 766 | --- a/gcc/config/microblaze/t-microblaze | ||
| 767 | +++ b/gcc/config/microblaze/t-microblaze | ||
| 768 | @@ -1,8 +1,11 @@ | ||
| 769 | -MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-endian | ||
| 770 | -MULTILIB_DIRNAMES = bs m mh le | ||
| 771 | +MULTILIB_OPTIONS = mxl-barrel-shift mno-xl-soft-mul mxl-multiply-high mlittle-endian m64 | ||
| 772 | +MULTILIB_DIRNAMES = bs m mh le m64 | ||
| 773 | MULTILIB_EXCEPTIONS = *mxl-barrel-shift/mxl-multiply-high mxl-multiply-high | ||
| 774 | MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/mlittle-endian | ||
| 775 | +MULTILIB_EXCEPTIONS += *mxl-barrel-shift/mxl-multiply-high/m64 | ||
| 776 | MULTILIB_EXCEPTIONS += mxl-multiply-high/mlittle-endian | ||
| 777 | +MULTILIB_EXCEPTIONS += mxl-multiply-high/m64 | ||
| 778 | +MULTILIB_EXCEPTIONS += *mxl-multiply-high/mlittle-endian/m64 | ||
| 779 | |||
| 780 | # Extra files | ||
| 781 | microblaze-c.o: $(srcdir)/config/microblaze/microblaze-c.cc \ | ||
| 782 | -- | ||
| 783 | 2.34.1 | ||
| 784 | |||
