"bext\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
+;; We do not define SHIFT_COUNT_TRUNCATED, so we have to have variants
+;; that mask/extend the count if we want to eliminate those ops
+;;
+;; We could (in theory) use GPR for the various modes, but I haven't
+;; seen those cases appear in practice. Without a testcase I've
+;; elected to keep the modes X which is easy to reason about.
+(define_insn "*bext<mode>_mask_pos"
+ [(set (match_operand:X 0 "register_operand" "=r")
+ (zero_extract:X (match_operand:X 1 "register_operand" "r")
+ (const_int 1)
+ (and:X
+ (match_operand:X 2 "register_operand" "r")
+ (match_operand 3 "const_int_operand"))))]
+ "(TARGET_ZBS
+ && INTVAL (operands[3]) + 1 == GET_MODE_BITSIZE (<MODE>mode))"
+ "bext\t%0,%1,%2"
+ [(set_attr "type" "bitmanip")])
+
;; This is a bext followed by a seqz. Normally this would be a 3->2 split
;; But the and-not pattern with a constant operand is a define_insn_and_split,
;; so this looks like a 2->2 split, which combine rejects. So implement it
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+struct obstack;
+struct bitmap_head_def;
+typedef struct bitmap_head_def *bitmap;
+struct obstack
+{
+ long chunk_size;
+ struct _obstack_chunk *chunk;
+ char *object_base;
+ char *next_free;
+ char *chunk_limit;
+ long int temp;
+ int alignment_mask;
+
+
+
+ struct _obstack_chunk *(*chunkfun) (void *, long);
+ void (*freefun) (void *, struct _obstack_chunk *);
+ void *extra_arg;
+ unsigned use_extra_arg:1;
+ unsigned maybe_empty_object:1;
+
+
+
+ unsigned alloc_failed:1;
+
+
+};
+
+typedef unsigned long BITMAP_WORD;
+typedef struct bitmap_obstack {
+ struct bitmap_element_def *elements;
+ struct bitmap_head_def *heads;
+ struct obstack obstack;
+} bitmap_obstack;
+typedef struct bitmap_element_def {
+ struct bitmap_element_def *next;
+ struct bitmap_element_def *prev;
+ unsigned int indx;
+ BITMAP_WORD bits[((128 + (8
+ * 8 * 1u) - 1) / (8
+ * 8 * 1u))];
+} bitmap_element;
+bitmap_element *bitmap_find_bit (bitmap, unsigned int);
+
+
+int
+bitmap_bit_p (bitmap head, int bit)
+{
+ bitmap_element *ptr;
+ unsigned bit_num;
+ unsigned word_num;
+
+ ptr = bitmap_find_bit (head, bit);
+ if (ptr == 0)
+ return 0;
+
+ bit_num = bit % (8
+ * 8 * 1u);
+ word_num = bit / (8
+ * 8 * 1u) % ((128 + (8
+ * 8 * 1u) - 1) / (8
+ * 8 * 1u));
+
+ return (ptr->bits[word_num] >> bit_num) & 1;
+}
+
+/* { dg-final { scan-assembler-times "bext\t" 1 } } */
+/* { dg-final { scan-assembler-not "slr\t"} } */
+/* { dg-final { scan-assembler-not "andi\t"} } */
+