summaryrefslogtreecommitdiff
path: root/gcc48-rh1469697-14.patch
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
committerCoprDistGit <infra@openeuler.org>2024-08-01 14:23:42 +0000
commit82711f6567ef069eebb942e382e2c3fa61fbf538 (patch)
tree22200b7326b32ca672ffb6e4ce6d19a09dc476e5 /gcc48-rh1469697-14.patch
parent5d624aa0d36abe76a344f0593eae5cf36d083b15 (diff)
automatic import of compat-libgfortran-48openeuler24.03_LTSopeneuler23.09
Diffstat (limited to 'gcc48-rh1469697-14.patch')
-rw-r--r--gcc48-rh1469697-14.patch301
1 files changed, 301 insertions, 0 deletions
diff --git a/gcc48-rh1469697-14.patch b/gcc48-rh1469697-14.patch
new file mode 100644
index 0000000..bb060fd
--- /dev/null
+++ b/gcc48-rh1469697-14.patch
@@ -0,0 +1,301 @@
+commit 21397732bbcef3347c0d5ff8a0ee5163e803e2fb
+Author: Jeff Law <law@redhat.com>
+Date: Mon Oct 2 12:30:26 2017 -0600
+
+ Dependencies for aarch64 work
+
+diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
+index 07ff7031b35..91dd5b7fc02 100644
+--- a/gcc/config/aarch64/aarch64-protos.h
++++ b/gcc/config/aarch64/aarch64-protos.h
+@@ -181,6 +181,7 @@ unsigned aarch64_dbx_register_number (unsigned);
+ unsigned aarch64_trampoline_size (void);
+ void aarch64_asm_output_labelref (FILE *, const char *);
+ void aarch64_elf_asm_named_section (const char *, unsigned, tree);
++const char * aarch64_output_probe_stack_range (rtx, rtx);
+ void aarch64_expand_epilogue (bool);
+ void aarch64_expand_mov_immediate (rtx, rtx);
+ void aarch64_expand_prologue (void);
+diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
+index 5afc167d569..cadf193cfcf 100644
+--- a/gcc/config/aarch64/aarch64.c
++++ b/gcc/config/aarch64/aarch64.c
+@@ -969,6 +969,199 @@ aarch64_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+ return true;
+ }
+
++static int
++aarch64_internal_mov_immediate (rtx dest, rtx imm, bool generate,
++ enum machine_mode mode)
++{
++ int i;
++ unsigned HOST_WIDE_INT val, val2, mask;
++ int one_match, zero_match;
++ int num_insns;
++
++ val = INTVAL (imm);
++
++ if (aarch64_move_imm (val, mode))
++ {
++ if (generate)
++ emit_insn (gen_rtx_SET (VOIDmode, dest, imm));
++ return 1;
++ }
++
++ /* Check to see if the low 32 bits are either 0xffffXXXX or 0xXXXXffff
++ (with XXXX non-zero). In that case check to see if the move can be done in
++ a smaller mode. */
++ val2 = val & 0xffffffff;
++ if (mode == DImode
++ && aarch64_move_imm (val2, SImode)
++ && (((val >> 32) & 0xffff) == 0 || (val >> 48) == 0))
++ {
++ if (generate)
++ emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (val2)));
++
++ /* Check if we have to emit a second instruction by checking to see
++ if any of the upper 32 bits of the original DI mode value is set. */
++ if (val == val2)
++ return 1;
++
++ i = (val >> 48) ? 48 : 32;
++
++ if (generate)
++ emit_insn (gen_insv_immdi (dest, GEN_INT (i),
++ GEN_INT ((val >> i) & 0xffff)));
++
++ return 2;
++ }
++
++ if ((val >> 32) == 0 || mode == SImode)
++ {
++ if (generate)
++ {
++ emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (val & 0xffff)));
++ if (mode == SImode)
++ emit_insn (gen_insv_immsi (dest, GEN_INT (16),
++ GEN_INT ((val >> 16) & 0xffff)));
++ else
++ emit_insn (gen_insv_immdi (dest, GEN_INT (16),
++ GEN_INT ((val >> 16) & 0xffff)));
++ }
++ return 2;
++ }
++
++ /* Remaining cases are all for DImode. */
++
++ mask = 0xffff;
++ zero_match = ((val & mask) == 0) + ((val & (mask << 16)) == 0) +
++ ((val & (mask << 32)) == 0) + ((val & (mask << 48)) == 0);
++ one_match = ((~val & mask) == 0) + ((~val & (mask << 16)) == 0) +
++ ((~val & (mask << 32)) == 0) + ((~val & (mask << 48)) == 0);
++
++ if (zero_match != 2 && one_match != 2)
++ {
++ /* Try emitting a bitmask immediate with a movk replacing 16 bits.
++ For a 64-bit bitmask try whether changing 16 bits to all ones or
++ zeroes creates a valid bitmask. To check any repeated bitmask,
++ try using 16 bits from the other 32-bit half of val. */
++
++ for (i = 0; i < 64; i += 16, mask <<= 16)
++ {
++ val2 = val & ~mask;
++ if (val2 != val && aarch64_bitmask_imm (val2, mode))
++ break;
++ val2 = val | mask;
++ if (val2 != val && aarch64_bitmask_imm (val2, mode))
++ break;
++ val2 = val2 & ~mask;
++ val2 = val2 | (((val2 >> 32) | (val2 << 32)) & mask);
++ if (val2 != val && aarch64_bitmask_imm (val2, mode))
++ break;
++ }
++ if (i != 64)
++ {
++ if (generate)
++ {
++ emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (val2)));
++ emit_insn (gen_insv_immdi (dest, GEN_INT (i),
++ GEN_INT ((val >> i) & 0xffff)));
++ }
++ return 2;
++ }
++ }
++
++ /* Generate 2-4 instructions, skipping 16 bits of all zeroes or ones which
++ are emitted by the initial mov. If one_match > zero_match, skip set bits,
++ otherwise skip zero bits. */
++
++ num_insns = 1;
++ mask = 0xffff;
++ val2 = one_match > zero_match ? ~val : val;
++ i = (val2 & mask) != 0 ? 0 : (val2 & (mask << 16)) != 0 ? 16 : 32;
++
++ if (generate)
++ emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_INT (one_match > zero_match
++ ? (val | ~(mask << i))
++ : (val & (mask << i)))));
++ for (i += 16; i < 64; i += 16)
++ {
++ if ((val2 & (mask << i)) == 0)
++ continue;
++ if (generate)
++ emit_insn (gen_insv_immdi (dest, GEN_INT (i),
++ GEN_INT ((val >> i) & 0xffff)));
++ num_insns ++;
++ }
++
++ return num_insns;
++}
++
++/* Add DELTA to REGNUM in mode MODE. SCRATCHREG can be used to hold a
++ temporary value if necessary. FRAME_RELATED_P should be true if
++ the RTX_FRAME_RELATED flag should be set and CFA adjustments added
++ to the generated instructions. If SCRATCHREG is known to hold
++ abs (delta), EMIT_MOVE_IMM can be set to false to avoid emitting the
++ immediate again.
++
++ Since this function may be used to adjust the stack pointer, we must
++ ensure that it cannot cause transient stack deallocation (for example
++ by first incrementing SP and then decrementing when adjusting by a
++ large immediate). */
++
++static void
++aarch64_add_constant_internal (enum machine_mode mode, int regnum,
++ int scratchreg, HOST_WIDE_INT delta,
++ bool frame_related_p, bool emit_move_imm)
++{
++ HOST_WIDE_INT mdelta = abs_hwi (delta);
++ rtx this_rtx = gen_rtx_REG (mode, regnum);
++ rtx insn;
++
++ if (!mdelta)
++ return;
++
++ /* Single instruction adjustment. */
++ if (aarch64_uimm12_shift (mdelta))
++ {
++ insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta)));
++ RTX_FRAME_RELATED_P (insn) = frame_related_p;
++ return;
++ }
++
++ /* Emit 2 additions/subtractions if the adjustment is less than 24 bits.
++ Only do this if mdelta is not a 16-bit move as adjusting using a move
++ is better. */
++ if (mdelta < 0x1000000 && !aarch64_move_imm (mdelta, mode))
++ {
++ HOST_WIDE_INT low_off = mdelta & 0xfff;
++
++ low_off = delta < 0 ? -low_off : low_off;
++ insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (low_off)));
++ RTX_FRAME_RELATED_P (insn) = frame_related_p;
++ insn = emit_insn (gen_add2_insn (this_rtx, GEN_INT (delta - low_off)));
++ RTX_FRAME_RELATED_P (insn) = frame_related_p;
++ return;
++ }
++
++ /* Emit a move immediate if required and an addition/subtraction. */
++ rtx scratch_rtx = gen_rtx_REG (mode, scratchreg);
++ if (emit_move_imm)
++ aarch64_internal_mov_immediate (scratch_rtx, GEN_INT (mdelta), true, mode);
++ insn = emit_insn (delta < 0 ? gen_sub2_insn (this_rtx, scratch_rtx)
++ : gen_add2_insn (this_rtx, scratch_rtx));
++ if (frame_related_p)
++ {
++ RTX_FRAME_RELATED_P (insn) = frame_related_p;
++ rtx adj = plus_constant (mode, this_rtx, delta);
++ add_reg_note (insn , REG_CFA_ADJUST_CFA,
++ gen_rtx_SET (VOIDmode, this_rtx, adj));
++ }
++}
++
++static inline void
++aarch64_sub_sp (int scratchreg, HOST_WIDE_INT delta, bool frame_related_p)
++{
++ aarch64_add_constant_internal (Pmode, SP_REGNUM, scratchreg, -delta,
++ frame_related_p, true);
++}
++
+ /* Implement TARGET_PASS_BY_REFERENCE. */
+
+ static bool
+@@ -1476,6 +1669,47 @@ aarch64_libgcc_cmp_return_mode (void)
+ return SImode;
+ }
+
++#define PROBE_INTERVAL (1 << STACK_CHECK_PROBE_INTERVAL_EXP)
++
++/* We use the 12-bit shifted immediate arithmetic instructions so values
++ must be multiple of (1 << 12), i.e. 4096. */
++#define ARITH_FACTOR 4096
++
++/* Probe a range of stack addresses from REG1 to REG2 inclusive. These are
++ absolute addresses. */
++
++const char *
++aarch64_output_probe_stack_range (rtx reg1, rtx reg2)
++{
++ static int labelno = 0;
++ char loop_lab[32];
++ rtx xops[2];
++
++ ASM_GENERATE_INTERNAL_LABEL (loop_lab, "LPSRL", labelno++);
++
++ /* Loop. */
++ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, loop_lab);
++
++ /* TEST_ADDR = TEST_ADDR + PROBE_INTERVAL. */
++ xops[0] = reg1;
++ xops[1] = GEN_INT (PROBE_INTERVAL);
++ output_asm_insn ("sub\t%0, %0, %1", xops);
++
++ /* Probe at TEST_ADDR. */
++ output_asm_insn ("str\txzr, [%0]", xops);
++
++ /* Test if TEST_ADDR == LAST_ADDR. */
++ xops[1] = reg2;
++ output_asm_insn ("cmp\t%0, %1", xops);
++
++ /* Branch. */
++ fputs ("\tb.ne\t", asm_out_file);
++ assemble_name_raw (asm_out_file, loop_lab);
++ fputc ('\n', asm_out_file);
++
++ return "";
++}
++
+ static bool
+ aarch64_frame_pointer_required (void)
+ {
+diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
+index 91299901bbf..17082486ac8 100644
+--- a/gcc/config/aarch64/aarch64.md
++++ b/gcc/config/aarch64/aarch64.md
+@@ -88,6 +88,7 @@
+ UNSPEC_ST4
+ UNSPEC_TLS
+ UNSPEC_TLSDESC
++ UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing.
+ UNSPEC_VSTRUCTDUMMY
+ ])
+
+@@ -3399,6 +3400,18 @@
+ [(set_attr "length" "0")]
+ )
+
++(define_insn "probe_stack_range"
++ [(set (match_operand:DI 0 "register_operand" "=r")
++ (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")
++ (match_operand:DI 2 "register_operand" "r")]
++ UNSPECV_PROBE_STACK_RANGE))]
++ ""
++{
++ return aarch64_output_probe_stack_range (operands[0], operands[2]);
++}
++ [(set_attr "length" "32")]
++)
++
+ ;; Named pattern for expanding thread pointer reference.
+ (define_expand "get_thread_pointerdi"
+ [(match_operand:DI 0 "register_operand" "=r")]