arm.md (movsfcc): Also validate operands[3] when compiling hard float.
* arm.md (movsfcc): Also validate operands[3] when compiling hard float. (movdfcc): Only accept fpu_add_operand for operands[3]. From-SVN: r17974
This commit is contained in:
parent
29a820586a
commit
7a0a1f09c4
@ -1,3 +1,9 @@
|
||||
Sat Feb 14 05:08:21 1998 Richard Earnshaw (rearnsha@arm.com)
|
||||
|
||||
* arm.md (movsfcc): Also validate operands[3] when compiling hard
|
||||
float.
|
||||
(movdfcc): Only accept fpu_add_operand for operands[3].
|
||||
|
||||
Sat Feb 14 02:02:41 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* varasm.c (output_constant_pool): Bring back 'done' label inside
|
||||
|
@ -1,7 +1,7 @@
|
||||
;;- Machine description for Advanced RISC Machines' ARM for GNU compiler
|
||||
;; Copyright (C) 1991, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
||||
;; and Martin Simmons (@harleqn.co.uk).
|
||||
;; and Martin Simmons (@harleqn.co.uk).
|
||||
;; More major hacks by Richard Earnshaw (rwe11@cl.cam.ac.uk)
|
||||
|
||||
;; This file is part of GNU CC.
|
||||
@ -859,6 +859,34 @@
|
||||
"umull%?\\t%Q0, %R0, %1, %2"
|
||||
[(set_attr "type" "mult")])
|
||||
|
||||
(define_insn "smulsi3_highpart"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
|
||||
(truncate:SI
|
||||
(lshiftrt:DI
|
||||
(mult:DI (sign_extend:DI
|
||||
(match_operand:SI 1 "s_register_operand" "%r,0"))
|
||||
(sign_extend:DI
|
||||
(match_operand:SI 2 "s_register_operand" "r,r")))
|
||||
(const_int 32))))
|
||||
(clobber (match_scratch:SI 3 "=&r,&r"))]
|
||||
"arm_fast_multiply"
|
||||
"smull%?\\t%3, %0, %2, %1"
|
||||
[(set_attr "type" "mult")])
|
||||
|
||||
(define_insn "umulsi3_highpart"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=&r,&r")
|
||||
(truncate:SI
|
||||
(lshiftrt:DI
|
||||
(mult:DI (zero_extend:DI
|
||||
(match_operand:SI 1 "s_register_operand" "%r,0"))
|
||||
(zero_extend:DI
|
||||
(match_operand:SI 2 "s_register_operand" "r,r")))
|
||||
(const_int 32))))
|
||||
(clobber (match_scratch:SI 3 "=&r,&r"))]
|
||||
"arm_fast_multiply"
|
||||
"umull%?\\t%3, %0, %2, %1"
|
||||
[(set_attr "type" "mult")])
|
||||
|
||||
(define_insn "mulsf3"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f")
|
||||
(mult:SF (match_operand:SF 1 "s_register_operand" "f")
|
||||
@ -1180,7 +1208,21 @@
|
||||
"
|
||||
{
|
||||
HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << INTVAL (operands[1])) - 1;
|
||||
rtx target, subtarget;
|
||||
|
||||
target = operands[0];
|
||||
/* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
|
||||
subreg as the final target. */
|
||||
if (GET_CODE (target) == SUBREG)
|
||||
{
|
||||
subtarget = gen_reg_rtx (SImode);
|
||||
if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target)))
|
||||
< GET_MODE_SIZE (SImode))
|
||||
target = SUBREG_REG (target);
|
||||
}
|
||||
else
|
||||
subtarget = target;
|
||||
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
{
|
||||
/* Since we are inserting a known constant, we may be able to
|
||||
@ -1191,7 +1233,7 @@
|
||||
<< INTVAL (operands[2]));
|
||||
|
||||
emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2)));
|
||||
emit_insn (gen_iorsi3 (operands[0], op1,
|
||||
emit_insn (gen_iorsi3 (subtarget, op1,
|
||||
GEN_INT (INTVAL (operands[3])
|
||||
<< INTVAL (operands[2]))));
|
||||
}
|
||||
@ -1212,7 +1254,7 @@
|
||||
emit_insn (gen_iorsi3 (op1, gen_rtx (LSHIFTRT, SImode, operands[0],
|
||||
operands[1]),
|
||||
op0));
|
||||
emit_insn (gen_rotlsi3 (operands[0], op1, operands[1]));
|
||||
emit_insn (gen_rotlsi3 (subtarget, op1, operands[1]));
|
||||
}
|
||||
else if ((INTVAL (operands[1]) + INTVAL (operands[2]) == 32)
|
||||
&& ! (const_ok_for_arm (mask)
|
||||
@ -1226,8 +1268,9 @@
|
||||
emit_insn (gen_ashlsi3 (op0, operands[3],
|
||||
GEN_INT (32 - INTVAL (operands[1]))));
|
||||
emit_insn (gen_ashlsi3 (op1, operands[0], operands[1]));
|
||||
emit_insn (gen_iorsi3 (operands[0], gen_rtx (LSHIFTRT, SImode, op1,
|
||||
operands[1]), op0));
|
||||
emit_insn (gen_iorsi3 (subtarget,
|
||||
gen_rtx (LSHIFTRT, SImode, op1,
|
||||
operands[1]), op0));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1270,7 +1313,17 @@
|
||||
if (INTVAL (operands[2]) != 0)
|
||||
op1 = gen_rtx (ASHIFT, SImode, op1, operands[2]);
|
||||
|
||||
emit_insn (gen_iorsi3 (operands[0], op1, op2));
|
||||
emit_insn (gen_iorsi3 (subtarget, op1, op2));
|
||||
}
|
||||
|
||||
if (subtarget != target)
|
||||
{
|
||||
/* If TARGET is still a SUBREG, then it must be wider than a word,
|
||||
so we must be careful only to set the subword we were asked to. */
|
||||
if (GET_CODE (target) == SUBREG)
|
||||
emit_move_insn (target, subtarget);
|
||||
else
|
||||
emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget));
|
||||
}
|
||||
|
||||
DONE;
|
||||
@ -2551,23 +2604,24 @@
|
||||
|
||||
(define_expand "storehi"
|
||||
[;; store the low byte
|
||||
(set (mem:QI (match_operand:SI 1 "" "")) (match_dup 3))
|
||||
(set (match_operand 1 "" "") (match_dup 3))
|
||||
;; extract the high byte
|
||||
(set (match_dup 2)
|
||||
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
|
||||
;; store the high byte
|
||||
(set (mem:QI (match_dup 4))
|
||||
(subreg:QI (match_dup 2) 0))] ;explicit subreg safe
|
||||
(set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe
|
||||
""
|
||||
"
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
rtx addr = XEXP (operands[1], 0);
|
||||
enum rtx_code code = GET_CODE (addr);
|
||||
|
||||
if ((code == PLUS || code == MINUS)
|
||||
&& (GET_CODE (XEXP (operands[1], 1)) == REG
|
||||
|| GET_CODE (XEXP (operands[1], 0)) != REG))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
operands[4] = plus_constant (operands[1], 1);
|
||||
if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
|
||||
|| code == MINUS)
|
||||
addr = force_reg (SImode, addr);
|
||||
|
||||
operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
|
||||
operands[1] = change_address (operands[1], QImode, NULL_RTX);
|
||||
operands[3] = gen_lowpart (QImode, operands[0]);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
operands[2] = gen_reg_rtx (SImode);
|
||||
@ -2575,21 +2629,22 @@
|
||||
")
|
||||
|
||||
(define_expand "storehi_bigend"
|
||||
[(set (mem:QI (match_dup 4)) (match_dup 3))
|
||||
[(set (match_dup 4) (match_dup 3))
|
||||
(set (match_dup 2)
|
||||
(ashiftrt:SI (match_operand 0 "" "") (const_int 8)))
|
||||
(set (mem:QI (match_operand 1 "" ""))
|
||||
(subreg:QI (match_dup 2) 0))]
|
||||
(set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))]
|
||||
""
|
||||
"
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
if ((code == PLUS || code == MINUS)
|
||||
&& (GET_CODE (XEXP (operands[1], 1)) == REG
|
||||
|| GET_CODE (XEXP (operands[1], 0)) != REG))
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
rtx addr = XEXP (operands[1], 0);
|
||||
enum rtx_code code = GET_CODE (addr);
|
||||
|
||||
operands[4] = plus_constant (operands[1], 1);
|
||||
if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
|
||||
|| code == MINUS)
|
||||
addr = force_reg (SImode, addr);
|
||||
|
||||
operands[4] = change_address (operands[1], QImode, plus_constant (addr, 1));
|
||||
operands[1] = change_address (operands[1], QImode, NULL_RTX);
|
||||
operands[3] = gen_lowpart (QImode, operands[0]);
|
||||
operands[0] = gen_lowpart (SImode, operands[0]);
|
||||
operands[2] = gen_reg_rtx (SImode);
|
||||
@ -2598,19 +2653,19 @@
|
||||
|
||||
;; Subroutine to store a half word integer constant into memory.
|
||||
(define_expand "storeinthi"
|
||||
[(set (mem:QI (match_operand:SI 0 "" ""))
|
||||
[(set (match_operand 0 "" "")
|
||||
(subreg:QI (match_operand 1 "" "") 0))
|
||||
(set (mem:QI (match_dup 3)) (subreg:QI (match_dup 2) 0))]
|
||||
(set (match_dup 3) (subreg:QI (match_dup 2) 0))]
|
||||
""
|
||||
"
|
||||
{
|
||||
HOST_WIDE_INT value = INTVAL (operands[1]);
|
||||
enum rtx_code code = GET_CODE (operands[0]);
|
||||
rtx addr = XEXP (operands[0], 0);
|
||||
enum rtx_code code = GET_CODE (addr);
|
||||
|
||||
if ((code == PLUS || code == MINUS)
|
||||
&& (GET_CODE (XEXP (operands[0], 1)) == REG
|
||||
|| GET_CODE (XEXP (operands[0], 0)) != REG))
|
||||
operands[0] = force_reg (SImode, operands[0]);
|
||||
if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT)
|
||||
|| code == MINUS)
|
||||
addr = force_reg (SImode, addr);
|
||||
|
||||
operands[1] = gen_reg_rtx (SImode);
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
@ -2636,7 +2691,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
operands[3] = plus_constant (operands[0], 1);
|
||||
operands[3] = change_address (operands[0], QImode, plus_constant (addr, 1));
|
||||
operands[0] = change_address (operands[0], QImode, NULL_RTX);
|
||||
}
|
||||
")
|
||||
|
||||
@ -2667,16 +2723,15 @@
|
||||
DONE;
|
||||
}
|
||||
if (GET_CODE (operands[1]) == CONST_INT)
|
||||
emit_insn (gen_storeinthi (XEXP (operands[0], 0), operands[1]));
|
||||
emit_insn (gen_storeinthi (operands[0], operands[1]));
|
||||
else
|
||||
{
|
||||
if (GET_CODE (operands[1]) == MEM)
|
||||
operands[1] = force_reg (HImode, operands[1]);
|
||||
if (BYTES_BIG_ENDIAN)
|
||||
emit_insn (gen_storehi_bigend (operands[1],
|
||||
XEXP (operands[0], 0)));
|
||||
emit_insn (gen_storehi_bigend (operands[1], operands[0]));
|
||||
else
|
||||
emit_insn (gen_storehi (operands[1], XEXP (operands[0], 0)));
|
||||
emit_insn (gen_storehi (operands[1], operands[0]));
|
||||
}
|
||||
DONE;
|
||||
}
|
||||
@ -3152,9 +3207,10 @@
|
||||
FAIL;
|
||||
|
||||
operands[3]
|
||||
= arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
|
||||
force_reg (SImode, XEXP (operands[1], 0)),
|
||||
TRUE, FALSE);
|
||||
= arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]),
|
||||
force_reg (SImode, XEXP (operands[1], 0)),
|
||||
TRUE, FALSE, RTX_UNCHANGING_P(operands[1]),
|
||||
MEM_IN_STRUCT_P(operands[1]));
|
||||
")
|
||||
|
||||
;; Load multiple with write-back
|
||||
@ -3221,9 +3277,10 @@
|
||||
FAIL;
|
||||
|
||||
operands[3]
|
||||
= arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
|
||||
force_reg (SImode, XEXP (operands[0], 0)),
|
||||
TRUE, FALSE);
|
||||
= arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]),
|
||||
force_reg (SImode, XEXP (operands[0], 0)),
|
||||
TRUE, FALSE, RTX_UNCHANGING_P (operands[0]),
|
||||
MEM_IN_STRUCT_P(operands[0]));
|
||||
")
|
||||
|
||||
;; Store multiple with write-back
|
||||
@ -3859,8 +3916,16 @@
|
||||
"
|
||||
{
|
||||
enum rtx_code code = GET_CODE (operands[1]);
|
||||
rtx ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
|
||||
arm_compare_fp);
|
||||
rtx ccreg;
|
||||
|
||||
/* When compiling for SOFT_FLOAT, ensure both arms are in registers.
|
||||
Otherwise, ensure it is a valid FP add operand */
|
||||
if ((! TARGET_HARD_FLOAT)
|
||||
|| (! fpu_add_operand (operands[3], SFmode)))
|
||||
operands[3] = force_reg (SFmode, operands[3]);
|
||||
|
||||
ccreg = gen_compare_reg (code, arm_compare_op0, arm_compare_op1,
|
||||
arm_compare_fp);
|
||||
|
||||
operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx);
|
||||
}")
|
||||
@ -3869,7 +3934,7 @@
|
||||
[(set (match_operand:DF 0 "s_register_operand" "")
|
||||
(if_then_else:DF (match_operand 1 "comparison_operator" "")
|
||||
(match_operand:DF 2 "s_register_operand" "")
|
||||
(match_operand:DF 3 "nonmemory_operand" "")))]
|
||||
(match_operand:DF 3 "fpu_add_operand" "")))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"
|
||||
{
|
||||
@ -3881,57 +3946,77 @@
|
||||
}")
|
||||
|
||||
(define_insn "*movsicc_insn"
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r")
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
|
||||
(if_then_else:SI
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SI 1 "arm_not_operand" "0,0,?rI,?rI,K,K")
|
||||
(match_operand:SI 2 "arm_not_operand" "rI,K,rI,K,rI,K")))]
|
||||
(match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
|
||||
(match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
|
||||
""
|
||||
"@
|
||||
mov%D3\\t%0, %2
|
||||
mvn%D3\\t%0, #%B2
|
||||
mov%d3\\t%0, %1
|
||||
mvn%d3\\t%0, #%B1
|
||||
mov%d3\\t%0, %1\;mov%D3\\t%0, %2
|
||||
mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
|
||||
mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
|
||||
mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
|
||||
[(set_attr "length" "4,4,8,8,8,8")
|
||||
[(set_attr "length" "4,4,4,4,8,8,8,8")
|
||||
(set_attr "conds" "use")])
|
||||
|
||||
(define_insn "*movsfcc_hard_insn"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f,f")
|
||||
(if_then_else:SF (match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SF 1 "s_register_operand" "0,0")
|
||||
(match_operand:SF 2 "fpu_add_operand" "fG,H")))]
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
|
||||
(if_then_else:SF
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"@
|
||||
mvf%D3s\\t%0, %2
|
||||
mnf%D3s\\t%0, #%N2"
|
||||
[(set_attr "type" "ffarith")
|
||||
mnf%D3s\\t%0, #%N2
|
||||
mvf%d3s\\t%0, %1
|
||||
mnf%d3s\\t%0, #%N1
|
||||
mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2
|
||||
mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2
|
||||
mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2
|
||||
mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2"
|
||||
[(set_attr "length" "4,4,4,4,8,8,8,8")
|
||||
(set_attr "type" "ffarith")
|
||||
(set_attr "conds" "use")])
|
||||
|
||||
(define_insn "*movsfcc_soft_insn"
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=r")
|
||||
[(set (match_operand:SF 0 "s_register_operand" "=r,r")
|
||||
(if_then_else:SF (match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:SF 1 "s_register_operand" "0")
|
||||
(match_operand:SF 2 "s_register_operand" "r")))]
|
||||
(match_operand:SF 1 "s_register_operand" "0,r")
|
||||
(match_operand:SF 2 "s_register_operand" "r,0")))]
|
||||
"TARGET_SOFT_FLOAT"
|
||||
"mov%D3\\t%0, %2"
|
||||
"@
|
||||
mov%D3\\t%0, %2
|
||||
mov%d3\\t%0, %1"
|
||||
[(set_attr "conds" "use")])
|
||||
|
||||
(define_insn "*movdfcc_insn"
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f")
|
||||
(if_then_else:DF (match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:DF 1 "s_register_operand" "0,0")
|
||||
(match_operand:DF 2 "fpu_add_operand" "fG,H")))]
|
||||
[(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f")
|
||||
(if_then_else:DF
|
||||
(match_operator 3 "comparison_operator"
|
||||
[(match_operand 4 "cc_register" "") (const_int 0)])
|
||||
(match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H")
|
||||
(match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))]
|
||||
"TARGET_HARD_FLOAT"
|
||||
"@
|
||||
mvf%D3d\\t%0, %2
|
||||
mnf%D3d\\t%0, #%N2"
|
||||
[(set_attr "type" "ffarith")
|
||||
mnf%D3d\\t%0, #%N2
|
||||
mvf%d3d\\t%0, %1
|
||||
mnf%d3d\\t%0, #%N1
|
||||
mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2
|
||||
mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2
|
||||
mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2
|
||||
mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2"
|
||||
[(set_attr "length" "4,4,4,4,8,8,8,8")
|
||||
(set_attr "type" "ffarith")
|
||||
(set_attr "conds" "use")])
|
||||
|
||||
;; Jump and linkage insns
|
||||
@ -4158,14 +4243,17 @@
|
||||
DONE;
|
||||
}")
|
||||
|
||||
;; The USE in this pattern is needed to tell flow analysis that this is
|
||||
;; a CASESI insn. It has no other purpose.
|
||||
(define_insn "casesi_internal"
|
||||
[(set (pc)
|
||||
(if_then_else
|
||||
(leu (match_operand:SI 0 "s_register_operand" "r")
|
||||
(match_operand:SI 1 "arm_rhs_operand" "rI"))
|
||||
(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
|
||||
(label_ref (match_operand 2 "" ""))))
|
||||
(label_ref (match_operand 3 "" ""))))]
|
||||
[(parallel [(set (pc)
|
||||
(if_then_else
|
||||
(leu (match_operand:SI 0 "s_register_operand" "r")
|
||||
(match_operand:SI 1 "arm_rhs_operand" "rI"))
|
||||
(mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
|
||||
(label_ref (match_operand 2 "" ""))))
|
||||
(label_ref (match_operand 3 "" ""))))
|
||||
(use (label_ref (match_dup 2)))])]
|
||||
""
|
||||
"*
|
||||
if (flag_pic)
|
||||
@ -5663,8 +5751,7 @@
|
||||
"sub%?s\\t%0, %1, #0"
|
||||
[(set_attr "conds" "set")])
|
||||
|
||||
; Peepholes to spot possible load- and store-multiples, if the ordering is
|
||||
; reversed, check that the memory references aren't volatile.
|
||||
; Peepholes to spot possible load- and store-multiples.
|
||||
|
||||
(define_peephole
|
||||
[(set (match_operand:SI 0 "s_register_operand" "=r")
|
||||
|
Loading…
Reference in New Issue
Block a user