+2020-02-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/87763
+ * config/aarch64/aarch64-protos.h (aarch64_movk_shift): Declare.
+ * config/aarch64/aarch64.c (aarch64_movk_shift): New function.
+ * config/aarch64/aarch64.md (aarch64_movk<mode>): New pattern.
+
2020-02-06 Richard Sandiford <richard.sandiford@arm.com>
PR rtl-optimization/87763
bool aarch64_split_dimode_const_store (rtx, rtx);
bool aarch64_symbolic_address_p (rtx);
bool aarch64_uimm12_shift (HOST_WIDE_INT);
+int aarch64_movk_shift (const wide_int_ref &, const wide_int_ref &);
bool aarch64_use_return_insn_p (void);
const char *aarch64_output_casesi (rtx *);
|| (val & (((HOST_WIDE_INT) 0xffff) << 16)) == val);
}
+/* Test whether:
+
+ X = (X & AND_VAL) | IOR_VAL;
+
+ can be implemented using:
+
+ MOVK X, #(IOR_VAL >> shift), LSL #shift
+
+ Return the shift if so, otherwise return -1. */
+int
+aarch64_movk_shift (const wide_int_ref &and_val,
+ const wide_int_ref &ior_val)
+{
+ unsigned int precision = and_val.get_precision ();
+ unsigned HOST_WIDE_INT mask = 0xffff;
+ for (unsigned int shift = 0; shift < precision; shift += 16)
+ {
+ if (and_val == ~mask && (ior_val & mask) == ior_val)
+ return shift;
+ mask <<= 16;
+ }
+ return -1;
+}
+
/* VAL is a value with the inner mode of MODE. Replicate it to fill a
64-bit (DImode) integer. */
[(set_attr "type" "mov_imm")]
)
+;; Match MOVK as a normal AND and IOR operation.
+(define_insn "aarch64_movk<mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (ior:GPI (and:GPI (match_operand:GPI 1 "register_operand" "0")
+ (match_operand:GPI 2 "const_int_operand"))
+ (match_operand:GPI 3 "const_int_operand")))]
+ "aarch64_movk_shift (rtx_mode_t (operands[2], <MODE>mode),
+ rtx_mode_t (operands[3], <MODE>mode)) >= 0"
+ {
+ int shift = aarch64_movk_shift (rtx_mode_t (operands[2], <MODE>mode),
+ rtx_mode_t (operands[3], <MODE>mode));
+ operands[2] = gen_int_mode (UINTVAL (operands[3]) >> shift, SImode);
+ operands[3] = gen_int_mode (shift, SImode);
+ return "movk\\t%<w>0, #%X2, lsl %3";
+ }
+)
+
(define_expand "movti"
[(set (match_operand:TI 0 "nonimmediate_operand")
(match_operand:TI 1 "general_operand"))]
+2020-02-06 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR target/87763
+ * gcc.target/aarch64/movk_2.c: New test.
+
2020-02-06 Marek Polacek <polacek@redhat.com>
PR c++/93597 - ICE with lambda in operator function.
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+#include <stdint.h>
+
+#define H3 ((uint64_t) 0xffff << 48)
+#define H2 ((uint64_t) 0xffff << 32)
+#define H1 ((uint64_t) 0xffff << 16)
+#define H0 ((uint64_t) 0xffff)
+
+/*
+** f1:
+** mov w0, w1
+** movk w0, #0x9876(?:, lsl #?0)?
+** ret
+*/
+uint32_t
+f1 (uint32_t dummy, uint32_t x)
+{
+ return (x & 0xffff0000) | 0x9876;
+}
+
+/*
+** f2:
+** movk w0, #0x1234, lsl #?16
+** ret
+*/
+uint32_t
+f2 (uint32_t x)
+{
+ return (x & 0xffff) | 0x12340000;
+}
+
+/*
+** g1:
+** movk x0, #0x1234, lsl #?0
+** ret
+*/
+uint64_t
+g1 (uint64_t x)
+{
+ return (x & (H3 | H2 | H1)) | 0x1234;
+}
+
+/*
+** g2:
+** movk x0, #0x900e, lsl #?16
+** ret
+*/
+uint64_t
+g2 (uint64_t x)
+{
+ return (x & (H3 | H2 | H0)) | ((uint64_t) 0x900e << 16);
+}
+
+/*
+** g3:
+** movk x0, #0xee33, lsl #?32
+** ret
+*/
+uint64_t
+g3 (uint64_t x)
+{
+ return (x & (H3 | H1 | H0)) | ((uint64_t) 0xee33 << 32);
+}
+
+/*
+** g4:
+** mov x0, x1
+** movk x0, #0x7654, lsl #?48
+** ret
+*/
+uint64_t
+g4 (uint64_t dummy, uint64_t x)
+{
+ return (x & (H2 | H1 | H0)) | ((uint64_t) 0x7654 << 48);
+}