operands[3] = tmp;
})
+(define_insn "and_load_zero_extend<mode>"
+ [(set (match_operand:X 0 "register_operand" "=r,r,r,r,r,r")
+ (and:X (match_operand:X 1 "memory_operand" "%m,m,m,k,k,k")
+ (match_operand:X 2 "mask_operand" "Yb,Yh,Yw,Yb,Yh,Yw")))]
+ ""
+ "@
+ ld.bu\t%0,%1
+ ld.hu\t%0,%1
+ ld.wu\t%0,%1
+ ldx.bu\t%0,%1
+ ldx.hu\t%0,%1
+ ldx.wu\t%0,%1"
+ [(set_attr "move_type" "load,load,load,load,load,load")
+ (set_attr "mode" "<MODE>")])
+
;; We always avoid the shift operation in bstrins_<mode>_for_ior_mask
;; if possible, but the result may be sub-optimal when one of the masks
;; is (1 << N) - 1 and one of the src register is the dest register.
(match_operand 0 "low_bitmask_operand")
(match_operand 0 "ins_zero_bitmask_operand")))
+(define_predicate "mask_operand"
+ (ior (match_operand 0 "qi_mask_operand")
+ (match_operand 0 "hi_mask_operand")
+ (match_operand 0 "si_mask_operand")))
+
(define_predicate "const_call_insn_operand"
(match_code "const,symbol_ref,label_ref")
{
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-final { scan-assembler-not "bstrpick" } } */
+/* { dg-final { scan-assembler "ld\\.wu" } } */
+
+struct st
+{
+ char const *name;
+};
+struct fst
+{
+ struct st *groups;
+};
+
+struct fst *pfunc (int);
+
+const char *
+test (int pc, unsigned group)
+{
+ struct fst *pci = pfunc (pc);
+
+ return pci->groups[group].name;
+}