if (aarch64_can_use_per_function_literal_pools_p ())
return function_section (current_function_decl);
+ /* When using anchors for constants use the readonly section. */
+ if (known_le (GET_MODE_SIZE (mode), 8))
+ return readonly_data_section;
+
return default_elf_select_rtx_section (mode, x, align);
}
*cost += extra_cost->fp[mode == DFmode || mode == DDmode].fpconst;
else if (!aarch64_float_const_zero_rtx_p (x))
{
- /* This will be a load from memory. */
+ /* Load from constdata - the cost of CONST_DOUBLE should be
+ higher than the cost of a MEM so that later optimizations
+ won't deoptimize an anchor load into a non-anchor load. */
if (mode == DFmode || mode == DDmode)
- *cost += extra_cost->ldst.loadd;
+ *cost += extra_cost->ldst.loadd + 1;
else
- *cost += extra_cost->ldst.loadf;
+ *cost += extra_cost->ldst.loadf + 1;
}
else
/* Otherwise this is +0.0. We get this using MOVI d0, #0
emit_move_insn (operands[0], gen_lowpart (<MODE>mode, tmp));
DONE;
}
+
+ /* Expand into a literal load using anchors. */
+ if (GET_CODE (operands[1]) == CONST_DOUBLE
+ && !aarch64_can_const_movi_rtx_p (operands[1], <MODE>mode)
+ && !aarch64_float_const_representable_p (operands[1])
+ && !aarch64_float_const_zero_rtx_p (operands[1])
+ && !aarch64_float_const_rtx_p (operands[1]))
+ {
+ operands[1] = force_const_mem (<MODE>mode, operands[1]);
+ emit_move_insn (operands[0], operands[1]);
+ DONE;
+ }
}
)
/* { dg-final { scan-assembler-times "movi\td\[0-9\]+, #?0" 1 } } */
-/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, \.LC\[0-9\]" 2 } } */
-/* { dg-final { scan-assembler-times "ldr\td\[0-9\]+, \\\[x\[0-9\], #:lo12:\.LC\[0-9\]\\\]" 2 } } */
+/* { dg-final { scan-assembler-times "adrp\tx\[0-9\]+, " 2 } } */
+/* { dg-final { scan-assembler-times "ldr\td\[0-9\]+, \\\[x\[0-9\], #:lo12:" 2 } } */
/* { dg-final { scan-assembler-times "fmov\td\[0-9\]+, 1\\\.5e\\\+0" 1 } } */
return 1;
}
-/* { dg-final { scan-assembler-times "adrp" 6 } } */
+/* { dg-final { scan-assembler-times "adrp" 4 } } */