mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 03:46:53 -05:00
LoongArch: Machine description files for LA32
gcc/ChangeLog: * config/loongarch/constraints.md: Disable k on LA32. * config/loongarch/loongarch.md (*and<mode>3): Delete. (*and<mode>3_extend): New. (zero_extend<SHORT:mode><GPR:mode>2_la32r): New. (extend<SHORT:mode><GPR:mode>2_la32r): New. (extendqihi2_la32r): New. (*movdi_32bit): Remove not working split, use existing loongarch_split_move instead. (move_doubleword_2_<mode>): New. (load_low<mode>): New. (load_high<mode>): New. (store_word<mode>): New. (movgr2frh<mode>): New. (movfrh2gr<mode>): New. * config/loongarch/predicates.md: Disable low_bitmask_operand and ins_zero_bitmask_operand on LA32. Enable const_call_insn_operand on LA32. * config/loongarch/sync.md (atomic_<amop><mode>): Change to define_expand. (la64_atomic_<amop><mode>): New. (la32_atomic_<amop>si): New. (atomic_fetch_<amop><mode>): Change to define_expand. (la64_atomic_fetch_<amop><mode>): New. (la32_atomic_fetch_<amop>si): New. (atomic_exchange<mode>): Change to define_expand. (la64_atomic_exchange<mode>): New. (la32_atomic_exchangesi): New. Co-authored-by: Jiajie Chen <c@jia.je> Reviewed-by: Xi Ruoyao <xry111@xry111.site> Reviewed-by: Lulu Cheng <chenglulu@loongson.cn>
This commit is contained in:
@@ -133,6 +133,7 @@
|
|||||||
"A memory operand whose address is formed by a base register and (optionally scaled)
|
"A memory operand whose address is formed by a base register and (optionally scaled)
|
||||||
index register."
|
index register."
|
||||||
(and (match_code "mem")
|
(and (match_code "mem")
|
||||||
|
(match_test "TARGET_64BIT")
|
||||||
(match_test "loongarch_base_index_address_p (XEXP (op, 0), mode)")))
|
(match_test "loongarch_base_index_address_p (XEXP (op, 0), mode)")))
|
||||||
|
|
||||||
(define_constraint "l"
|
(define_constraint "l"
|
||||||
|
|||||||
@@ -409,6 +409,12 @@
|
|||||||
(define_mode_iterator ANYFI [(SI "TARGET_HARD_FLOAT")
|
(define_mode_iterator ANYFI [(SI "TARGET_HARD_FLOAT")
|
||||||
(DI "TARGET_DOUBLE_FLOAT")])
|
(DI "TARGET_DOUBLE_FLOAT")])
|
||||||
|
|
||||||
|
;; A mode for which moves involving FPRs may need to be split.
|
||||||
|
(define_mode_iterator SPLITF
|
||||||
|
[(DF "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
|
||||||
|
(DI "!TARGET_64BIT && TARGET_DOUBLE_FLOAT")
|
||||||
|
(TF "TARGET_64BIT && TARGET_DOUBLE_FLOAT")])
|
||||||
|
|
||||||
;; A mode for anything with 32 bits or more, and able to be loaded with
|
;; A mode for anything with 32 bits or more, and able to be loaded with
|
||||||
;; the same addressing mode as ld.w.
|
;; the same addressing mode as ld.w.
|
||||||
(define_mode_iterator LD_AT_LEAST_32_BIT [GPR ANYF])
|
(define_mode_iterator LD_AT_LEAST_32_BIT [GPR ANYF])
|
||||||
@@ -633,7 +639,7 @@
|
|||||||
;; so the redundant sign extension can be removed if the output is used as
|
;; so the redundant sign extension can be removed if the output is used as
|
||||||
;; an input of a bitwise operation. Note plus, rotl, and div are handled
|
;; an input of a bitwise operation. Note plus, rotl, and div are handled
|
||||||
;; separately.
|
;; separately.
|
||||||
(define_code_iterator shift_w [any_shift rotatert])
|
(define_code_iterator shift_w [any_shift (rotatert "!TARGET_32BIT_R")])
|
||||||
(define_code_iterator arith_w [minus mult])
|
(define_code_iterator arith_w [minus mult])
|
||||||
|
|
||||||
(define_expand "<optab><mode>3"
|
(define_expand "<optab><mode>3"
|
||||||
@@ -743,30 +749,33 @@
|
|||||||
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
|
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
|
||||||
(plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r")
|
(plus:SI (match_operand:SI 1 "register_operand" "r,r,r,r,r")
|
||||||
(match_operand:SI 2 "plus_si_operand" "r,I,La,Le,Lb")))]
|
(match_operand:SI 2 "plus_si_operand" "r,I,La,Le,Lb")))]
|
||||||
"TARGET_64BIT"
|
""
|
||||||
{
|
{
|
||||||
if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2])
|
if (TARGET_64BIT)
|
||||||
&& ADDU16I_OPERAND (INTVAL (operands[2])))
|
|
||||||
{
|
{
|
||||||
rtx t1 = gen_reg_rtx (DImode);
|
if (CONST_INT_P (operands[2]) && !IMM12_INT (operands[2])
|
||||||
rtx t2 = gen_reg_rtx (DImode);
|
&& ADDU16I_OPERAND (INTVAL (operands[2])))
|
||||||
rtx t3 = gen_reg_rtx (DImode);
|
{
|
||||||
emit_insn (gen_extend_insn (t1, operands[1], DImode, SImode, 0));
|
rtx t1 = gen_reg_rtx (DImode);
|
||||||
t2 = operands[2];
|
rtx t2 = gen_reg_rtx (DImode);
|
||||||
emit_insn (gen_adddi3 (t3, t1, t2));
|
rtx t3 = gen_reg_rtx (DImode);
|
||||||
t3 = gen_lowpart (SImode, t3);
|
emit_insn (gen_extend_insn (t1, operands[1], DImode, SImode, 0));
|
||||||
emit_move_insn (operands[0], t3);
|
t2 = operands[2];
|
||||||
DONE;
|
emit_insn (gen_adddi3 (t3, t1, t2));
|
||||||
}
|
t3 = gen_lowpart (SImode, t3);
|
||||||
else
|
emit_move_insn (operands[0], t3);
|
||||||
{
|
DONE;
|
||||||
rtx t = gen_reg_rtx (DImode);
|
}
|
||||||
emit_insn (gen_addsi3_extended (t, operands[1], operands[2]));
|
else
|
||||||
t = gen_lowpart (SImode, t);
|
{
|
||||||
SUBREG_PROMOTED_VAR_P (t) = 1;
|
rtx t = gen_reg_rtx (DImode);
|
||||||
SUBREG_PROMOTED_SET (t, SRP_SIGNED);
|
emit_insn (gen_addsi3_extended (t, operands[1], operands[2]));
|
||||||
emit_move_insn (operands[0], t);
|
t = gen_lowpart (SImode, t);
|
||||||
DONE;
|
SUBREG_PROMOTED_VAR_P (t) = 1;
|
||||||
|
SUBREG_PROMOTED_SET (t, SRP_SIGNED);
|
||||||
|
emit_move_insn (operands[0], t);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1376,7 +1385,7 @@
|
|||||||
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
|
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")
|
||||||
(match_operand:<IMODE> 2 "register_operand" "f")]
|
(match_operand:<IMODE> 2 "register_operand" "f")]
|
||||||
UNSPEC_FSCALEB))]
|
UNSPEC_FSCALEB))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_64BIT"
|
||||||
"fscaleb.<fmt>\t%0,%1,%2"
|
"fscaleb.<fmt>\t%0,%1,%2"
|
||||||
[(set_attr "type" "fscaleb")
|
[(set_attr "type" "fscaleb")
|
||||||
(set_attr "mode" "<UNITMODE>")])
|
(set_attr "mode" "<UNITMODE>")])
|
||||||
@@ -1392,7 +1401,7 @@
|
|||||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||||
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
|
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
|
||||||
UNSPEC_FLOGB))]
|
UNSPEC_FLOGB))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_64BIT"
|
||||||
"flogb.<fmt>\t%0,%1"
|
"flogb.<fmt>\t%0,%1"
|
||||||
[(set_attr "type" "flogb")
|
[(set_attr "type" "flogb")
|
||||||
(set_attr "mode" "<UNITMODE>")])
|
(set_attr "mode" "<UNITMODE>")])
|
||||||
@@ -1401,7 +1410,7 @@
|
|||||||
[(set (match_operand:ANYF 0 "register_operand")
|
[(set (match_operand:ANYF 0 "register_operand")
|
||||||
(unspec:ANYF [(abs:ANYF (match_operand:ANYF 1 "register_operand"))]
|
(unspec:ANYF [(abs:ANYF (match_operand:ANYF 1 "register_operand"))]
|
||||||
UNSPEC_FLOGB))]
|
UNSPEC_FLOGB))]
|
||||||
"TARGET_HARD_FLOAT"
|
"TARGET_64BIT"
|
||||||
{
|
{
|
||||||
rtx tmp = gen_reg_rtx (<MODE>mode);
|
rtx tmp = gen_reg_rtx (<MODE>mode);
|
||||||
|
|
||||||
@@ -1421,7 +1430,7 @@
|
|||||||
(define_insn "clz<mode>2"
|
(define_insn "clz<mode>2"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=r")
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
(clz:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
(clz:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"clz.<d>\t%0,%1"
|
"clz.<d>\t%0,%1"
|
||||||
[(set_attr "type" "clz")
|
[(set_attr "type" "clz")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -1437,7 +1446,7 @@
|
|||||||
(define_insn "ctz<mode>2"
|
(define_insn "ctz<mode>2"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=r")
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
(ctz:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
(ctz:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"ctz.<d>\t%0,%1"
|
"ctz.<d>\t%0,%1"
|
||||||
[(set_attr "type" "clz")
|
[(set_attr "type" "clz")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -1553,28 +1562,26 @@
|
|||||||
|
|
||||||
(define_insn "*<optab><mode>3"
|
(define_insn "*<optab><mode>3"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=r,r")
|
[(set (match_operand:GPR 0 "register_operand" "=r,r")
|
||||||
(any_or:GPR (match_operand:GPR 1 "register_operand" "%r,r")
|
(any_bitwise:GPR (match_operand:GPR 1 "register_operand" "%r,r")
|
||||||
(match_operand:GPR 2 "uns_arith_operand" "r,K")))]
|
(match_operand:GPR 2 "uns_arith_operand" "r,K")))]
|
||||||
""
|
""
|
||||||
"<insn>%i2\t%0,%1,%2"
|
"<insn>%i2\t%0,%1,%2"
|
||||||
[(set_attr "type" "logical")
|
[(set_attr "type" "logical")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
|
|
||||||
(define_insn "*and<mode>3"
|
(define_insn "*and<mode>3_extend"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=r,r,r,r")
|
[(set (match_operand:GPR 0 "register_operand" "=r,r")
|
||||||
(and:GPR (match_operand:GPR 1 "register_operand" "%r,r,r,0")
|
(and:GPR (match_operand:GPR 1 "register_operand" "%r,0")
|
||||||
(match_operand:GPR 2 "and_operand" "r,K,Yx,Yy")))]
|
(match_operand:GPR 2 "and_operand" "Yx,Yy")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"@
|
"@
|
||||||
and\t%0,%1,%2
|
|
||||||
andi\t%0,%1,%2
|
|
||||||
* operands[2] = GEN_INT (INTVAL (operands[2]) \
|
* operands[2] = GEN_INT (INTVAL (operands[2]) \
|
||||||
& GET_MODE_MASK (<MODE>mode)); \
|
& GET_MODE_MASK (<MODE>mode)); \
|
||||||
return \"bstrpick.<d>\t%0,%1,%M2\";
|
return \"bstrpick.<d>\t%0,%1,%M2\";
|
||||||
* operands[2] = GEN_INT (~INTVAL (operands[2]) \
|
* operands[2] = GEN_INT (~INTVAL (operands[2]) \
|
||||||
& GET_MODE_MASK (<MODE>mode)); \
|
& GET_MODE_MASK (<MODE>mode)); \
|
||||||
return \"bstrins.<d>\t%0,%.,%M2\";"
|
return \"bstrins.<d>\t%0,%.,%M2\";"
|
||||||
[(set_attr "move_type" "logical,logical,pick_ins,pick_ins")
|
[(set_attr "move_type" "pick_ins,pick_ins")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
|
|
||||||
(define_expand "<optab><mode>3"
|
(define_expand "<optab><mode>3"
|
||||||
@@ -1606,7 +1613,8 @@
|
|||||||
(match_operand:GPR 2 "const_int_operand" "i"))
|
(match_operand:GPR 2 "const_int_operand" "i"))
|
||||||
(and:GPR (match_operand:GPR 3 "register_operand" "r")
|
(and:GPR (match_operand:GPR 3 "register_operand" "r")
|
||||||
(match_operand:GPR 4 "const_int_operand" "i"))))]
|
(match_operand:GPR 4 "const_int_operand" "i"))))]
|
||||||
"loongarch_pre_reload_split ()
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
|
&& loongarch_pre_reload_split ()
|
||||||
&& loongarch_use_bstrins_for_ior_with_mask (<MODE>mode, operands)"
|
&& loongarch_use_bstrins_for_ior_with_mask (<MODE>mode, operands)"
|
||||||
"#"
|
"#"
|
||||||
"&& true"
|
"&& true"
|
||||||
@@ -1734,7 +1742,7 @@
|
|||||||
(match_operand:SI 3 "const_int_operand")
|
(match_operand:SI 3 "const_int_operand")
|
||||||
(const_int 0))
|
(const_int 0))
|
||||||
(match_dup 0))]
|
(match_dup 0))]
|
||||||
"peep2_reg_dead_p (3, operands[0])"
|
"(TARGET_64BIT || TARGET_32BIT_S) && peep2_reg_dead_p (3, operands[0])"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
{
|
{
|
||||||
int len = GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]);
|
int len = GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[3]);
|
||||||
@@ -1795,7 +1803,7 @@
|
|||||||
(neg_bitwise:X
|
(neg_bitwise:X
|
||||||
(not:X (match_operand:X 2 "register_operand" "r"))
|
(not:X (match_operand:X 2 "register_operand" "r"))
|
||||||
(match_operand:X 1 "register_operand" "r")))]
|
(match_operand:X 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"<insn>n\t%0,%1,%2"
|
"<insn>n\t%0,%1,%2"
|
||||||
[(set_attr "type" "logical")
|
[(set_attr "type" "logical")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -1894,7 +1902,7 @@
|
|||||||
[(set (match_operand:GPR 0 "register_operand" "=r,r,r")
|
[(set (match_operand:GPR 0 "register_operand" "=r,r,r")
|
||||||
(zero_extend:GPR
|
(zero_extend:GPR
|
||||||
(match_operand:SHORT 1 "nonimmediate_operand" "r,m,k")))]
|
(match_operand:SHORT 1 "nonimmediate_operand" "r,m,k")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"@
|
"@
|
||||||
bstrpick.w\t%0,%1,<SHORT:7_or_15>,0
|
bstrpick.w\t%0,%1,<SHORT:7_or_15>,0
|
||||||
ld.<SHORT:size>u\t%0,%1
|
ld.<SHORT:size>u\t%0,%1
|
||||||
@@ -1902,6 +1910,15 @@
|
|||||||
[(set_attr "move_type" "pick_ins,load,load")
|
[(set_attr "move_type" "pick_ins,load,load")
|
||||||
(set_attr "mode" "<GPR:MODE>")])
|
(set_attr "mode" "<GPR:MODE>")])
|
||||||
|
|
||||||
|
(define_insn "zero_extend<SHORT:mode><GPR:mode>2_la32r"
|
||||||
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
|
(zero_extend:GPR
|
||||||
|
(match_operand:SHORT 1 "nonimmediate_operand" "m")))]
|
||||||
|
"TARGET_32BIT_R"
|
||||||
|
"ld.<SHORT:size>u\t%0,%1"
|
||||||
|
[(set_attr "move_type" "load")
|
||||||
|
(set_attr "mode" "<GPR:MODE>")])
|
||||||
|
|
||||||
(define_insn "zero_extendqihi2"
|
(define_insn "zero_extendqihi2"
|
||||||
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
||||||
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,k,m")))]
|
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "r,k,m")))]
|
||||||
@@ -1919,7 +1936,7 @@
|
|||||||
[(set (match_operand:GPR 0 "register_operand" "=r")
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
(zero_extend:GPR
|
(zero_extend:GPR
|
||||||
(truncate:SHORT (match_operand:DI 1 "register_operand" "r"))))]
|
(truncate:SHORT (match_operand:DI 1 "register_operand" "r"))))]
|
||||||
"TARGET_64BIT"
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bstrpick.w\t%0,%1,<SHORT:7_or_15>,0"
|
"bstrpick.w\t%0,%1,<SHORT:7_or_15>,0"
|
||||||
[(set_attr "move_type" "pick_ins")
|
[(set_attr "move_type" "pick_ins")
|
||||||
(set_attr "mode" "<GPR:MODE>")])
|
(set_attr "mode" "<GPR:MODE>")])
|
||||||
@@ -1958,7 +1975,7 @@
|
|||||||
[(set (match_operand:GPR 0 "register_operand" "=r,r,r")
|
[(set (match_operand:GPR 0 "register_operand" "=r,r,r")
|
||||||
(sign_extend:GPR
|
(sign_extend:GPR
|
||||||
(match_operand:SHORT 1 "nonimmediate_operand" "r,m,k")))]
|
(match_operand:SHORT 1 "nonimmediate_operand" "r,m,k")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"@
|
"@
|
||||||
ext.w.<SHORT:size>\t%0,%1
|
ext.w.<SHORT:size>\t%0,%1
|
||||||
ld.<SHORT:size>\t%0,%1
|
ld.<SHORT:size>\t%0,%1
|
||||||
@@ -1966,11 +1983,20 @@
|
|||||||
[(set_attr "move_type" "signext,load,load")
|
[(set_attr "move_type" "signext,load,load")
|
||||||
(set_attr "mode" "<GPR:MODE>")])
|
(set_attr "mode" "<GPR:MODE>")])
|
||||||
|
|
||||||
|
(define_insn "extend<SHORT:mode><GPR:mode>2_la32r"
|
||||||
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
|
(sign_extend:GPR
|
||||||
|
(match_operand:SHORT 1 "nonimmediate_operand" "m")))]
|
||||||
|
"TARGET_32BIT_R"
|
||||||
|
"ld.<SHORT:size>\t%0,%1"
|
||||||
|
[(set_attr "move_type" "load")
|
||||||
|
(set_attr "mode" "<GPR:MODE>")])
|
||||||
|
|
||||||
(define_insn "extendqihi2"
|
(define_insn "extendqihi2"
|
||||||
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
|
||||||
(sign_extend:HI
|
(sign_extend:HI
|
||||||
(match_operand:QI 1 "nonimmediate_operand" "r,m,k")))]
|
(match_operand:QI 1 "nonimmediate_operand" "r,m,k")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"@
|
"@
|
||||||
ext.w.b\t%0,%1
|
ext.w.b\t%0,%1
|
||||||
ld.b\t%0,%1
|
ld.b\t%0,%1
|
||||||
@@ -1978,6 +2004,15 @@
|
|||||||
[(set_attr "move_type" "signext,load,load")
|
[(set_attr "move_type" "signext,load,load")
|
||||||
(set_attr "mode" "SI")])
|
(set_attr "mode" "SI")])
|
||||||
|
|
||||||
|
(define_insn "extendqihi2_la32r"
|
||||||
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||||
|
(sign_extend:HI
|
||||||
|
(match_operand:QI 1 "nonimmediate_operand" "m")))]
|
||||||
|
""
|
||||||
|
"ld.b\t%0,%1"
|
||||||
|
[(set_attr "move_type" "load")
|
||||||
|
(set_attr "mode" "SI")])
|
||||||
|
|
||||||
(define_insn "extendsfdf2"
|
(define_insn "extendsfdf2"
|
||||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||||
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
|
(float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
|
||||||
@@ -2090,7 +2125,7 @@
|
|||||||
(define_expand "fixuns_truncdfdi2"
|
(define_expand "fixuns_truncdfdi2"
|
||||||
[(set (match_operand:DI 0 "register_operand")
|
[(set (match_operand:DI 0 "register_operand")
|
||||||
(unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
|
(unsigned_fix:DI (match_operand:DF 1 "register_operand")))]
|
||||||
"TARGET_DOUBLE_FLOAT"
|
"TARGET_64BIT && TARGET_DOUBLE_FLOAT"
|
||||||
{
|
{
|
||||||
rtx reg1 = gen_reg_rtx (DFmode);
|
rtx reg1 = gen_reg_rtx (DFmode);
|
||||||
rtx reg2 = gen_reg_rtx (DFmode);
|
rtx reg2 = gen_reg_rtx (DFmode);
|
||||||
@@ -2172,7 +2207,7 @@
|
|||||||
(define_expand "fixuns_truncsfdi2"
|
(define_expand "fixuns_truncsfdi2"
|
||||||
[(set (match_operand:DI 0 "register_operand")
|
[(set (match_operand:DI 0 "register_operand")
|
||||||
(unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
|
(unsigned_fix:DI (match_operand:SF 1 "register_operand")))]
|
||||||
"TARGET_DOUBLE_FLOAT"
|
"TARGET_64BIT && TARGET_DOUBLE_FLOAT"
|
||||||
{
|
{
|
||||||
rtx reg1 = gen_reg_rtx (SFmode);
|
rtx reg1 = gen_reg_rtx (SFmode);
|
||||||
rtx reg2 = gen_reg_rtx (SFmode);
|
rtx reg2 = gen_reg_rtx (SFmode);
|
||||||
@@ -2222,7 +2257,7 @@
|
|||||||
(zero_extract:X (match_operand:X 1 "register_operand")
|
(zero_extract:X (match_operand:X 1 "register_operand")
|
||||||
(match_operand 2 "const_int_operand")
|
(match_operand 2 "const_int_operand")
|
||||||
(match_operand 3 "const_int_operand")))]
|
(match_operand 3 "const_int_operand")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
{
|
{
|
||||||
if (!loongarch_use_ins_ext_p (operands[1], INTVAL (operands[2]),
|
if (!loongarch_use_ins_ext_p (operands[1], INTVAL (operands[2]),
|
||||||
INTVAL (operands[3])))
|
INTVAL (operands[3])))
|
||||||
@@ -2232,10 +2267,11 @@
|
|||||||
(define_insn "*extzv<mode>"
|
(define_insn "*extzv<mode>"
|
||||||
[(set (match_operand:X 0 "register_operand" "=r")
|
[(set (match_operand:X 0 "register_operand" "=r")
|
||||||
(zero_extract:X (match_operand:X 1 "register_operand" "r")
|
(zero_extract:X (match_operand:X 1 "register_operand" "r")
|
||||||
(match_operand 2 "const_int_operand" "")
|
(match_operand 2 "const_int_operand" "")
|
||||||
(match_operand 3 "const_int_operand" "")))]
|
(match_operand 3 "const_int_operand" "")))]
|
||||||
"loongarch_use_ins_ext_p (operands[1], INTVAL (operands[2]),
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
INTVAL (operands[3]))"
|
&& loongarch_use_ins_ext_p (operands[1], INTVAL (operands[2]),
|
||||||
|
INTVAL (operands[3]))"
|
||||||
{
|
{
|
||||||
operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1);
|
operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1);
|
||||||
return "bstrpick.<d>\t%0,%1,%2,%3";
|
return "bstrpick.<d>\t%0,%1,%2,%3";
|
||||||
@@ -2248,7 +2284,7 @@
|
|||||||
(match_operand 1 "const_int_operand")
|
(match_operand 1 "const_int_operand")
|
||||||
(match_operand 2 "const_int_operand"))
|
(match_operand 2 "const_int_operand"))
|
||||||
(match_operand:GPR 3 "reg_or_0_operand"))]
|
(match_operand:GPR 3 "reg_or_0_operand"))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
{
|
{
|
||||||
if (!loongarch_use_ins_ext_p (operands[0], INTVAL (operands[1]),
|
if (!loongarch_use_ins_ext_p (operands[0], INTVAL (operands[1]),
|
||||||
INTVAL (operands[2])))
|
INTVAL (operands[2])))
|
||||||
@@ -2260,8 +2296,9 @@
|
|||||||
(match_operand:SI 1 "const_int_operand" "")
|
(match_operand:SI 1 "const_int_operand" "")
|
||||||
(match_operand:SI 2 "const_int_operand" ""))
|
(match_operand:SI 2 "const_int_operand" ""))
|
||||||
(match_operand:GPR 3 "reg_or_0_operand" "rJ"))]
|
(match_operand:GPR 3 "reg_or_0_operand" "rJ"))]
|
||||||
"loongarch_use_ins_ext_p (operands[0], INTVAL (operands[1]),
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
INTVAL (operands[2]))"
|
&& loongarch_use_ins_ext_p (operands[0], INTVAL (operands[1]),
|
||||||
|
INTVAL (operands[2]))"
|
||||||
{
|
{
|
||||||
operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
|
operands[1] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[2]) - 1);
|
||||||
return "bstrins.<d>\t%0,%z3,%1,%2";
|
return "bstrins.<d>\t%0,%z3,%1,%2";
|
||||||
@@ -2291,25 +2328,29 @@
|
|||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movdi_32bit"
|
(define_insn "*movdi_32bit"
|
||||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
|
||||||
(match_operand:DI 1 "move_operand" "r,i,w,r,*J*r,*m,*f,*f"))]
|
(match_operand:DI 1 "move_operand" "r,i,w,r,*J*r,*m,*f,*f"))]
|
||||||
"!TARGET_64BIT
|
"!TARGET_64BIT
|
||||||
&& (register_operand (operands[0], DImode)
|
&& (register_operand (operands[0], DImode)
|
||||||
|| reg_or_0_operand (operands[1], DImode))"
|
|| reg_or_0_operand (operands[1], DImode))"
|
||||||
{ return loongarch_output_move (operands); }
|
{ return loongarch_output_move (operands); }
|
||||||
"CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
|
|
||||||
(operands[0]))"
|
|
||||||
[(const_int 0)]
|
|
||||||
"
|
|
||||||
{
|
|
||||||
loongarch_move_integer (operands[0], operands[0], INTVAL (operands[1]));
|
|
||||||
DONE;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
[(set_attr "move_type" "move,const,load,store,mgtf,fpload,mftg,fpstore")
|
[(set_attr "move_type" "move,const,load,store,mgtf,fpload,mftg,fpstore")
|
||||||
(set_attr "mode" "DI")])
|
(set_attr "mode" "DI")])
|
||||||
|
|
||||||
|
;; Split 64-bit move in LoongArch32
|
||||||
|
|
||||||
|
(define_split
|
||||||
|
[(set (match_operand:MOVE64 0 "nonimmediate_operand")
|
||||||
|
(match_operand:MOVE64 1 "move_operand"))]
|
||||||
|
"TARGET_32BIT && reload_completed
|
||||||
|
&& loongarch_split_move_p (operands[0], operands[1])"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
loongarch_split_move (operands[0], operands[1]);
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "*movdi_64bit"
|
(define_insn_and_split "*movdi_64bit"
|
||||||
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
|
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,w,*f,*f,*r,*m")
|
||||||
(match_operand:DI 1 "move_operand" "r,Yd,w,rJ,*r*J,*m,*f,*f"))]
|
(match_operand:DI 1 "move_operand" "r,Yd,w,rJ,*r*J,*m,*f,*f"))]
|
||||||
@@ -2319,8 +2360,8 @@
|
|||||||
{
|
{
|
||||||
return loongarch_output_move (operands);
|
return loongarch_output_move (operands);
|
||||||
}
|
}
|
||||||
"CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
|
"&& CONST_INT_P (operands[1]) && REG_P (operands[0])
|
||||||
(operands[0]))"
|
&& GP_REG_P (REGNO (operands[0]))"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
@@ -2378,7 +2419,7 @@
|
|||||||
(unspec:DI [(match_operand:DI 2 "") (pc)] UNSPEC_LA_PCREL_64_PART1))
|
(unspec:DI [(match_operand:DI 2 "") (pc)] UNSPEC_LA_PCREL_64_PART1))
|
||||||
(set (match_operand:DI 1 "register_operand" "=r")
|
(set (match_operand:DI 1 "register_operand" "=r")
|
||||||
(unspec:DI [(match_dup 2) (pc)] UNSPEC_LA_PCREL_64_PART2))]
|
(unspec:DI [(match_dup 2) (pc)] UNSPEC_LA_PCREL_64_PART2))]
|
||||||
"TARGET_ABI_LP64 && la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE"
|
"TARGET_64BIT && la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE"
|
||||||
{
|
{
|
||||||
return "pcalau12i\t%0,%r2\n\t"
|
return "pcalau12i\t%0,%r2\n\t"
|
||||||
"addi.d\t%1,$r0,%L2\n\t"
|
"addi.d\t%1,$r0,%L2\n\t"
|
||||||
@@ -2396,6 +2437,15 @@
|
|||||||
(match_operand:SI 1 ""))]
|
(match_operand:SI 1 ""))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
|
if (TARGET_32BIT
|
||||||
|
&& ((MEM_P (operands[0])
|
||||||
|
&& loongarch_14bit_shifted_offset_address_p (XEXP (operands[0], 0), SImode)
|
||||||
|
&& !loongarch_12bit_offset_address_p (XEXP (operands[0], 0), SImode))
|
||||||
|
|| (MEM_P (operands[1])
|
||||||
|
&& loongarch_14bit_shifted_offset_address_p (XEXP (operands[1], 0), SImode)
|
||||||
|
&& !loongarch_12bit_offset_address_p (XEXP (operands[1], 0), SImode))))
|
||||||
|
FAIL;
|
||||||
|
|
||||||
if (loongarch_legitimize_move (SImode, operands[0], operands[1]))
|
if (loongarch_legitimize_move (SImode, operands[0], operands[1]))
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
@@ -2404,10 +2454,17 @@
|
|||||||
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,f,f,r,*m")
|
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,w,f,f,r,*m")
|
||||||
(match_operand:SI 1 "move_operand" "r,Yd,w,rJ,rJ,m,f,*f"))]
|
(match_operand:SI 1 "move_operand" "r,Yd,w,rJ,rJ,m,f,*f"))]
|
||||||
"(register_operand (operands[0], SImode)
|
"(register_operand (operands[0], SImode)
|
||||||
|| reg_or_0_operand (operands[1], SImode))"
|
|| reg_or_0_operand (operands[1], SImode))
|
||||||
|
&& !(TARGET_32BIT
|
||||||
|
&& ((MEM_P (operands[0])
|
||||||
|
&& loongarch_14bit_shifted_offset_address_p (XEXP (operands[0], 0), SImode)
|
||||||
|
&& !loongarch_12bit_offset_address_p (XEXP (operands[0], 0), SImode))
|
||||||
|
|| (MEM_P (operands[1])
|
||||||
|
&& loongarch_14bit_shifted_offset_address_p (XEXP (operands[1], 0), SImode)
|
||||||
|
&& !loongarch_12bit_offset_address_p (XEXP (operands[1], 0), SImode))))"
|
||||||
{ return loongarch_output_move (operands); }
|
{ return loongarch_output_move (operands); }
|
||||||
"CONST_INT_P (operands[1]) && REG_P (operands[0]) && GP_REG_P (REGNO
|
"&& CONST_INT_P (operands[1]) && REG_P (operands[0])
|
||||||
(operands[0]))"
|
&& GP_REG_P (REGNO (operands[0]))"
|
||||||
[(const_int 0)]
|
[(const_int 0)]
|
||||||
"
|
"
|
||||||
{
|
{
|
||||||
@@ -2482,7 +2539,7 @@
|
|||||||
(define_expand "movsf"
|
(define_expand "movsf"
|
||||||
[(set (match_operand:SF 0 "")
|
[(set (match_operand:SF 0 "")
|
||||||
(match_operand:SF 1 ""))]
|
(match_operand:SF 1 ""))]
|
||||||
""
|
"TARGET_HARD_FLOAT"
|
||||||
{
|
{
|
||||||
if (loongarch_legitimize_move (SFmode, operands[0], operands[1]))
|
if (loongarch_legitimize_move (SFmode, operands[0], operands[1]))
|
||||||
DONE;
|
DONE;
|
||||||
@@ -2513,7 +2570,7 @@
|
|||||||
(define_expand "movdf"
|
(define_expand "movdf"
|
||||||
[(set (match_operand:DF 0 "")
|
[(set (match_operand:DF 0 "")
|
||||||
(match_operand:DF 1 ""))]
|
(match_operand:DF 1 ""))]
|
||||||
""
|
"TARGET_DOUBLE_FLOAT"
|
||||||
{
|
{
|
||||||
if (loongarch_legitimize_move (DFmode, operands[0], operands[1]))
|
if (loongarch_legitimize_move (DFmode, operands[0], operands[1]))
|
||||||
DONE;
|
DONE;
|
||||||
@@ -2540,6 +2597,41 @@
|
|||||||
[(set_attr "move_type" "move,load,store")
|
[(set_attr "move_type" "move,load,store")
|
||||||
(set_attr "mode" "DF")])
|
(set_attr "mode" "DF")])
|
||||||
|
|
||||||
|
;; Emit a doubleword move in which exactly one of the operands is
|
||||||
|
;; a floating-point register. We can't just emit two normal moves
|
||||||
|
;; because of the constraints imposed by the FPU register model;
|
||||||
|
;; see loongarch_can_change_mode_class for details. Instead, we keep
|
||||||
|
;; the FPR whole and use special patterns to refer to each word of
|
||||||
|
;; the other operand.
|
||||||
|
|
||||||
|
(define_expand "move_doubleword_2_<mode>"
|
||||||
|
[(set (match_operand:SPLITF 0)
|
||||||
|
(match_operand:SPLITF 1))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (FP_REG_RTX_P (operands[0]))
|
||||||
|
{
|
||||||
|
rtx low = loongarch_subword (operands[1], 0);
|
||||||
|
rtx high = loongarch_subword (operands[1], 1);
|
||||||
|
emit_insn (gen_load_low<mode> (operands[0], low));
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
emit_insn (gen_movgr2frh<mode> (operands[0], high, operands[0]));
|
||||||
|
else
|
||||||
|
emit_insn (gen_load_high<mode> (operands[0], high, operands[0]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rtx low = loongarch_subword (operands[0], 0);
|
||||||
|
rtx high = loongarch_subword (operands[0], 1);
|
||||||
|
emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx));
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
emit_insn (gen_movfrh2gr<mode> (high, operands[1]));
|
||||||
|
else
|
||||||
|
emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx));
|
||||||
|
}
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
;; Clear one FCC register
|
;; Clear one FCC register
|
||||||
|
|
||||||
(define_expand "movfcc"
|
(define_expand "movfcc"
|
||||||
@@ -2618,8 +2710,9 @@
|
|||||||
(const_int 0))
|
(const_int 0))
|
||||||
(match_operand:GPR 2 "reg_or_0_operand" "r,J")
|
(match_operand:GPR 2 "reg_or_0_operand" "r,J")
|
||||||
(match_operand:GPR 3 "reg_or_0_operand" "J,r")))]
|
(match_operand:GPR 3 "reg_or_0_operand" "J,r")))]
|
||||||
"register_operand (operands[2], <GPR:MODE>mode)
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
!= register_operand (operands[3], <GPR:MODE>mode)"
|
&& register_operand (operands[2], <GPR:MODE>mode)
|
||||||
|
!= register_operand (operands[3], <GPR:MODE>mode)"
|
||||||
"@
|
"@
|
||||||
<sel>\t%0,%2,%1
|
<sel>\t%0,%2,%1
|
||||||
<selinv>\t%0,%3,%1"
|
<selinv>\t%0,%3,%1"
|
||||||
@@ -2681,7 +2774,7 @@
|
|||||||
(if_then_else:GPR (match_operator 1 "comparison_operator"
|
(if_then_else:GPR (match_operator 1 "comparison_operator"
|
||||||
[(match_operand:GPR 2 "reg_or_0_operand")
|
[(match_operand:GPR 2 "reg_or_0_operand")
|
||||||
(match_operand:GPR 3 "reg_or_0_operand")])))]
|
(match_operand:GPR 3 "reg_or_0_operand")])))]
|
||||||
"TARGET_COND_MOVE_INT"
|
"(TARGET_64BIT || TARGET_32BIT_S) && TARGET_COND_MOVE_INT"
|
||||||
{
|
{
|
||||||
if (!INTEGRAL_MODE_P (GET_MODE (XEXP (operands[1], 0))))
|
if (!INTEGRAL_MODE_P (GET_MODE (XEXP (operands[1], 0))))
|
||||||
FAIL;
|
FAIL;
|
||||||
@@ -2786,7 +2879,7 @@
|
|||||||
[(set (match_operand:P 0 "register_operand" "=j")
|
[(set (match_operand:P 0 "register_operand" "=j")
|
||||||
(unspec:P [(match_operand:P 1 "symbolic_operand" "")]
|
(unspec:P [(match_operand:P 1 "symbolic_operand" "")]
|
||||||
UNSPEC_PCALAU12I))]
|
UNSPEC_PCALAU12I))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"pcalau12i\t%0,%%pc_hi20(%1)"
|
"pcalau12i\t%0,%%pc_hi20(%1)"
|
||||||
[(set_attr "type" "move")])
|
[(set_attr "type" "move")])
|
||||||
|
|
||||||
@@ -2796,7 +2889,7 @@
|
|||||||
[(set (match_operand:P 0 "register_operand" "=r")
|
[(set (match_operand:P 0 "register_operand" "=r")
|
||||||
(unspec:P [(match_operand:P 1 "symbolic_operand" "")]
|
(unspec:P [(match_operand:P 1 "symbolic_operand" "")]
|
||||||
UNSPEC_PCALAU12I_GR))]
|
UNSPEC_PCALAU12I_GR))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"pcalau12i\t%0,%%pc_hi20(%1)"
|
"pcalau12i\t%0,%%pc_hi20(%1)"
|
||||||
[(set_attr "type" "move")])
|
[(set_attr "type" "move")])
|
||||||
|
|
||||||
@@ -2846,7 +2939,7 @@
|
|||||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||||
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
|
(unspec:ANYF [(match_operand:ANYF 1 "register_operand" "f")]
|
||||||
UNSPEC_FRINT))]
|
UNSPEC_FRINT))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"frint.<fmt>\t%0,%1"
|
"frint.<fmt>\t%0,%1"
|
||||||
[(set_attr "type" "fcvt")
|
[(set_attr "type" "fcvt")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -2864,6 +2957,71 @@
|
|||||||
[(set_attr "type" "fcvt")
|
[(set_attr "type" "fcvt")
|
||||||
(set_attr "mode" "<ANYF:MODE>")])
|
(set_attr "mode" "<ANYF:MODE>")])
|
||||||
|
|
||||||
|
;; Load the low word of operand 0 with operand 1.
|
||||||
|
(define_insn "load_low<mode>"
|
||||||
|
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
|
||||||
|
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "rJ,m")]
|
||||||
|
UNSPEC_LOAD_LOW))]
|
||||||
|
"TARGET_HARD_FLOAT"
|
||||||
|
{
|
||||||
|
operands[0] = loongarch_subword (operands[0], 0);
|
||||||
|
return loongarch_output_move (operands);
|
||||||
|
}
|
||||||
|
[(set_attr "move_type" "mgtf,fpload")
|
||||||
|
(set_attr "mode" "<HALFMODE>")])
|
||||||
|
|
||||||
|
;; Load the high word of operand 0 from operand 1, preserving the value
|
||||||
|
;; in the low word.
|
||||||
|
(define_insn "load_high<mode>"
|
||||||
|
[(set (match_operand:SPLITF 0 "register_operand" "=f,f")
|
||||||
|
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "rJ,m")
|
||||||
|
(match_operand:SPLITF 2 "register_operand" "0,0")]
|
||||||
|
UNSPEC_LOAD_HIGH))]
|
||||||
|
"TARGET_HARD_FLOAT"
|
||||||
|
{
|
||||||
|
operands[0] = loongarch_subword (operands[0], 1);
|
||||||
|
return loongarch_output_move (operands);
|
||||||
|
}
|
||||||
|
[(set_attr "move_type" "mgtf,fpload")
|
||||||
|
(set_attr "mode" "<HALFMODE>")])
|
||||||
|
|
||||||
|
;; Store one word of operand 1 in operand 0. Operand 2 is 1 to store the
|
||||||
|
;; high word and 0 to store the low word.
|
||||||
|
(define_insn "store_word<mode>"
|
||||||
|
[(set (match_operand:<HALFMODE> 0 "nonimmediate_operand" "=r,m")
|
||||||
|
(unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f,f")
|
||||||
|
(match_operand 2 "const_int_operand")]
|
||||||
|
UNSPEC_STORE_WORD))]
|
||||||
|
"TARGET_HARD_FLOAT"
|
||||||
|
{
|
||||||
|
operands[1] = loongarch_subword (operands[1], INTVAL (operands[2]));
|
||||||
|
return loongarch_output_move (operands);
|
||||||
|
}
|
||||||
|
[(set_attr "move_type" "mftg,fpstore")
|
||||||
|
(set_attr "mode" "<HALFMODE>")])
|
||||||
|
|
||||||
|
;; Move operand 1 to the high word of operand 0 using movgr2frh.w, preserving the
|
||||||
|
;; value in the low word.
|
||||||
|
(define_insn "movgr2frh<mode>"
|
||||||
|
[(set (match_operand:SPLITF 0 "register_operand" "=f")
|
||||||
|
(unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "rJ")
|
||||||
|
(match_operand:SPLITF 2 "register_operand" "0")]
|
||||||
|
UNSPEC_MOVGR2FRH))]
|
||||||
|
"TARGET_DOUBLE_FLOAT"
|
||||||
|
"movgr2frh.w\t%0,%z1"
|
||||||
|
[(set_attr "move_type" "mgtf")
|
||||||
|
(set_attr "mode" "<HALFMODE>")])
|
||||||
|
|
||||||
|
;; Move high word of operand 1 to operand 0 using movfrh2gr.s.
|
||||||
|
(define_insn "movfrh2gr<mode>"
|
||||||
|
[(set (match_operand:<HALFMODE> 0 "register_operand" "=r")
|
||||||
|
(unspec:<HALFMODE> [(match_operand:SPLITF 1 "register_operand" "f")]
|
||||||
|
UNSPEC_MOVFRH2GR))]
|
||||||
|
"TARGET_DOUBLE_FLOAT"
|
||||||
|
"movfrh2gr.s\t%0,%1"
|
||||||
|
[(set_attr "move_type" "mftg")
|
||||||
|
(set_attr "mode" "<HALFMODE>")])
|
||||||
|
|
||||||
;; Thread-Local Storage
|
;; Thread-Local Storage
|
||||||
|
|
||||||
(define_insn "@got_load_tls_desc<mode>"
|
(define_insn "@got_load_tls_desc<mode>"
|
||||||
@@ -2879,13 +3037,13 @@
|
|||||||
(clobber (reg:SI FCC5_REGNUM))
|
(clobber (reg:SI FCC5_REGNUM))
|
||||||
(clobber (reg:SI FCC6_REGNUM))
|
(clobber (reg:SI FCC6_REGNUM))
|
||||||
(clobber (reg:SI FCC7_REGNUM))
|
(clobber (reg:SI FCC7_REGNUM))
|
||||||
(clobber (reg:SI RETURN_ADDR_REGNUM))]
|
(clobber (reg:P RETURN_ADDR_REGNUM))]
|
||||||
"TARGET_TLS_DESC"
|
"TARGET_TLS_DESC"
|
||||||
{
|
{
|
||||||
return TARGET_EXPLICIT_RELOCS
|
return TARGET_EXPLICIT_RELOCS
|
||||||
? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
|
? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
|
||||||
"addi.d\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
|
"addi.<d>\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
|
||||||
"ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
|
"ld.<d>\t$r1,$r4,%%desc_ld(%0)\n\t"
|
||||||
"jirl\t$r1,$r1,%%desc_call(%0)"
|
"jirl\t$r1,$r1,%%desc_call(%0)"
|
||||||
: "la.tls.desc\t$r4,%0";
|
: "la.tls.desc\t$r4,%0";
|
||||||
}
|
}
|
||||||
@@ -3102,7 +3260,7 @@
|
|||||||
(match_operand 2 "const_uimm5_operand")]
|
(match_operand 2 "const_uimm5_operand")]
|
||||||
UNSPECV_LDDIR)
|
UNSPECV_LDDIR)
|
||||||
(clobber (mem:BLK (scratch)))]
|
(clobber (mem:BLK (scratch)))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"lddir\t%0,%1,%2"
|
"lddir\t%0,%1,%2"
|
||||||
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -3112,7 +3270,7 @@
|
|||||||
(match_operand 1 "const_uimm5_operand")]
|
(match_operand 1 "const_uimm5_operand")]
|
||||||
UNSPECV_LDPTE)
|
UNSPECV_LDPTE)
|
||||||
(clobber (mem:BLK (scratch)))]
|
(clobber (mem:BLK (scratch)))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"ldpte\t%0,%1"
|
"ldpte\t%0,%1"
|
||||||
[(set_attr "type" "load")
|
[(set_attr "type" "load")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -3190,7 +3348,7 @@
|
|||||||
[(set (match_operand:GPR 0 "register_operand" "=r,r")
|
[(set (match_operand:GPR 0 "register_operand" "=r,r")
|
||||||
(rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
|
(rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
|
||||||
(match_operand:SI 2 "arith_operand" "r,I")))]
|
(match_operand:SI 2 "arith_operand" "r,I")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"rotr%i2.<d>\t%0,%1,%2"
|
"rotr%i2.<d>\t%0,%1,%2"
|
||||||
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -3200,7 +3358,7 @@
|
|||||||
(sign_extend:DI
|
(sign_extend:DI
|
||||||
(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
|
(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
|
||||||
(match_operand:SI 2 "arith_operand" "r,I"))))]
|
(match_operand:SI 2 "arith_operand" "r,I"))))]
|
||||||
"TARGET_64BIT"
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"rotr%i2.w\t%0,%1,%2"
|
"rotr%i2.w\t%0,%1,%2"
|
||||||
[(set_attr "type" "shift,shift")
|
[(set_attr "type" "shift,shift")
|
||||||
(set_attr "mode" "SI")])
|
(set_attr "mode" "SI")])
|
||||||
@@ -3212,7 +3370,7 @@
|
|||||||
(set (match_operand:GPR 0 "register_operand")
|
(set (match_operand:GPR 0 "register_operand")
|
||||||
(rotatert:GPR (match_operand:GPR 1 "register_operand")
|
(rotatert:GPR (match_operand:GPR 1 "register_operand")
|
||||||
(match_dup 3)))]
|
(match_dup 3)))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
{
|
{
|
||||||
operands[3] = gen_reg_rtx (SImode);
|
operands[3] = gen_reg_rtx (SImode);
|
||||||
|
|
||||||
@@ -3235,7 +3393,7 @@
|
|||||||
(plus:GPR (ashift:GPR (match_operand:GPR 1 "register_operand" "r")
|
(plus:GPR (ashift:GPR (match_operand:GPR 1 "register_operand" "r")
|
||||||
(match_operand 2 "const_immalsl_operand" ""))
|
(match_operand 2 "const_immalsl_operand" ""))
|
||||||
(match_operand:GPR 3 "register_operand" "r")))]
|
(match_operand:GPR 3 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"alsl.<d>\t%0,%1,%3,%2"
|
"alsl.<d>\t%0,%1,%3,%2"
|
||||||
[(set_attr "type" "arith")
|
[(set_attr "type" "arith")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -3278,8 +3436,9 @@
|
|||||||
(ashift:X (match_operand:X 1 "register_operand" "r")
|
(ashift:X (match_operand:X 1 "register_operand" "r")
|
||||||
(match_operand:SI 2 "const_int_operand" "i"))
|
(match_operand:SI 2 "const_int_operand" "i"))
|
||||||
(match_operand:X 3 "const_int_operand" "i")))]
|
(match_operand:X 3 "const_int_operand" "i")))]
|
||||||
"(const_immalsl_operand (operands[2], SImode)
|
"TARGET_64BIT
|
||||||
|| !<bitwise_operand> (operands[3], <MODE>mode))
|
&& (const_immalsl_operand (operands[2], SImode)
|
||||||
|
|| !<bitwise_operand> (operands[3], <MODE>mode))
|
||||||
&& loongarch_reassoc_shift_bitwise (<is_and>, operands[2], operands[3],
|
&& loongarch_reassoc_shift_bitwise (<is_and>, operands[2], operands[3],
|
||||||
<MODE>mode)"
|
<MODE>mode)"
|
||||||
"#"
|
"#"
|
||||||
@@ -3360,7 +3519,7 @@
|
|||||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
(rotatert:SI (bswap:SI (match_operand:SI 1 "register_operand" "r"))
|
(rotatert:SI (bswap:SI (match_operand:SI 1 "register_operand" "r"))
|
||||||
(const_int 16)))]
|
(const_int 16)))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"revb.2h\t%0,%1"
|
"revb.2h\t%0,%1"
|
||||||
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
||||||
|
|
||||||
@@ -3370,14 +3529,14 @@
|
|||||||
(rotatert:SI
|
(rotatert:SI
|
||||||
(bswap:SI (match_operand:SI 1 "register_operand" "r"))
|
(bswap:SI (match_operand:SI 1 "register_operand" "r"))
|
||||||
(const_int 16))))]
|
(const_int 16))))]
|
||||||
"TARGET_64BIT"
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"revb.2h\t%0,%1"
|
"revb.2h\t%0,%1"
|
||||||
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
||||||
|
|
||||||
(define_insn "bswaphi2"
|
(define_insn "bswaphi2"
|
||||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||||
(bswap:HI (match_operand:HI 1 "register_operand" "r")))]
|
(bswap:HI (match_operand:HI 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"revb.2h\t%0,%1"
|
"revb.2h\t%0,%1"
|
||||||
[(set_attr "type" "shift")])
|
[(set_attr "type" "shift")])
|
||||||
|
|
||||||
@@ -3399,9 +3558,9 @@
|
|||||||
(define_expand "bswapsi2"
|
(define_expand "bswapsi2"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
|
(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
{
|
{
|
||||||
if (!TARGET_64BIT)
|
if (TARGET_32BIT_S)
|
||||||
{
|
{
|
||||||
rtx t = gen_reg_rtx (SImode);
|
rtx t = gen_reg_rtx (SImode);
|
||||||
emit_insn (gen_revb_2h (t, operands[1]));
|
emit_insn (gen_revb_2h (t, operands[1]));
|
||||||
@@ -3565,7 +3724,7 @@
|
|||||||
(match_operator:SI 1 "loongarch_cstore_operator"
|
(match_operator:SI 1 "loongarch_cstore_operator"
|
||||||
[(match_operand:GPR 2 "register_operand")
|
[(match_operand:GPR 2 "register_operand")
|
||||||
(match_operand:GPR 3 "nonmemory_operand")]))]
|
(match_operand:GPR 3 "nonmemory_operand")]))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
{
|
{
|
||||||
loongarch_expand_scc (operands);
|
loongarch_expand_scc (operands);
|
||||||
DONE;
|
DONE;
|
||||||
@@ -3933,12 +4092,18 @@
|
|||||||
return "jr\t%0";
|
return "jr\t%0";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%0)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%0";
|
return "b\t%0";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%0)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%0)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%%plt(%0)";
|
return "b\t%%plt(%0)";
|
||||||
default:
|
default:
|
||||||
@@ -4026,12 +4191,18 @@
|
|||||||
return "jr\t%1";
|
return "jr\t%1";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%1";
|
return "b\t%1";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%%plt(%1)";
|
return "b\t%%plt(%1)";
|
||||||
default:
|
default:
|
||||||
@@ -4064,12 +4235,18 @@
|
|||||||
return "jr\t%1";
|
return "jr\t%1";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%1";
|
return "b\t%1";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r12,%%call36(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r12,%%call30(%1)\n\tjirl\t$r0,$r12,0";
|
||||||
else
|
else
|
||||||
return "b\t%%plt(%1)";
|
return "b\t%%plt(%1)";
|
||||||
default:
|
default:
|
||||||
@@ -4122,12 +4299,18 @@
|
|||||||
return "jirl\t$r1,%0,0";
|
return "jirl\t$r1,%0,0";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%0)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%0";
|
return "bl\t%0";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%0)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%0)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%%plt(%0)";
|
return "bl\t%%plt(%0)";
|
||||||
default:
|
default:
|
||||||
@@ -4199,12 +4382,18 @@
|
|||||||
return "jirl\t$r1,%1,0";
|
return "jirl\t$r1,%1,0";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%1";
|
return "bl\t%1";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%%plt(%1)";
|
return "bl\t%%plt(%1)";
|
||||||
default:
|
default:
|
||||||
@@ -4239,12 +4428,18 @@
|
|||||||
return "jirl\t$r1,%1,0";
|
return "jirl\t$r1,%1,0";
|
||||||
case 1:
|
case 1:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%1";
|
return "bl\t%1";
|
||||||
case 2:
|
case 2:
|
||||||
if (TARGET_CMODEL_MEDIUM)
|
if (TARGET_CMODEL_MEDIUM)
|
||||||
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
if (TARGET_64BIT)
|
||||||
|
return "pcaddu18i\t$r1,%%call36(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
|
else
|
||||||
|
return "pcaddu12i\t$r1,%%call30(%1)\n\tjirl\t$r1,$r1,0";
|
||||||
else
|
else
|
||||||
return "bl\t%%plt(%1)";
|
return "bl\t%%plt(%1)";
|
||||||
default:
|
default:
|
||||||
@@ -4393,7 +4588,7 @@
|
|||||||
(const_int <bytepick_w_lshiftrt_amount>))
|
(const_int <bytepick_w_lshiftrt_amount>))
|
||||||
(ashift:SI (match_operand:SI 2 "register_operand" "r")
|
(ashift:SI (match_operand:SI 2 "register_operand" "r")
|
||||||
(const_int bytepick_w_ashift_amount))))]
|
(const_int bytepick_w_ashift_amount))))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bytepick.w\t%0,%1,%2,<bytepick_imm>"
|
"bytepick.w\t%0,%1,%2,<bytepick_imm>"
|
||||||
[(set_attr "mode" "SI")])
|
[(set_attr "mode" "SI")])
|
||||||
|
|
||||||
@@ -4411,7 +4606,7 @@
|
|||||||
(zero_extract:DI (match_operand:DI 2 "register_operand" "r")
|
(zero_extract:DI (match_operand:DI 2 "register_operand" "r")
|
||||||
(const_int <bytepick_w_ashift_amount>)
|
(const_int <bytepick_w_ashift_amount>)
|
||||||
(const_int <bitsize>))))]
|
(const_int <bitsize>))))]
|
||||||
"TARGET_64BIT"
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bytepick.w\t%0,%2,%1,<bytepick_imm>"
|
"bytepick.w\t%0,%2,%1,<bytepick_imm>"
|
||||||
[(set_attr "mode" "SI")])
|
[(set_attr "mode" "SI")])
|
||||||
|
|
||||||
@@ -4426,7 +4621,7 @@
|
|||||||
(zero_extract:DI (match_operand:DI 2 "register_operand" "r")
|
(zero_extract:DI (match_operand:DI 2 "register_operand" "r")
|
||||||
(const_int 8)
|
(const_int 8)
|
||||||
(const_int 24))))]
|
(const_int 24))))]
|
||||||
"TARGET_64BIT"
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bytepick.w\t%0,%2,%1,1"
|
"bytepick.w\t%0,%2,%1,1"
|
||||||
[(set_attr "mode" "SI")])
|
[(set_attr "mode" "SI")])
|
||||||
|
|
||||||
@@ -4456,7 +4651,7 @@
|
|||||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
|
(unspec:SI [(match_operand:SI 1 "register_operand" "r")]
|
||||||
UNSPEC_BITREV_4B))]
|
UNSPEC_BITREV_4B))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bitrev.4b\t%0,%1"
|
"bitrev.4b\t%0,%1"
|
||||||
[(set_attr "type" "unknown")
|
[(set_attr "type" "unknown")
|
||||||
(set_attr "mode" "SI")])
|
(set_attr "mode" "SI")])
|
||||||
@@ -4465,7 +4660,7 @@
|
|||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(unspec:DI [(match_operand:DI 1 "register_operand" "r")]
|
(unspec:DI [(match_operand:DI 1 "register_operand" "r")]
|
||||||
UNSPEC_BITREV_8B))]
|
UNSPEC_BITREV_8B))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"bitrev.8b\t%0,%1"
|
"bitrev.8b\t%0,%1"
|
||||||
[(set_attr "type" "unknown")
|
[(set_attr "type" "unknown")
|
||||||
(set_attr "mode" "DI")])
|
(set_attr "mode" "DI")])
|
||||||
@@ -4473,7 +4668,7 @@
|
|||||||
(define_insn "@rbit<mode>"
|
(define_insn "@rbit<mode>"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=r")
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
(bitreverse:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
(bitreverse:GPR (match_operand:GPR 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bitrev.<size>\t%0,%1"
|
"bitrev.<size>\t%0,%1"
|
||||||
[(set_attr "type" "unknown")
|
[(set_attr "type" "unknown")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -4492,7 +4687,7 @@
|
|||||||
(define_insn "rbitqi"
|
(define_insn "rbitqi"
|
||||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||||
(bitreverse:QI (match_operand:QI 1 "register_operand" "r")))]
|
(bitreverse:QI (match_operand:QI 1 "register_operand" "r")))]
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
"bitrev.4b\t%0,%1"
|
"bitrev.4b\t%0,%1"
|
||||||
[(set_attr "type" "unknown")
|
[(set_attr "type" "unknown")
|
||||||
(set_attr "mode" "SI")])
|
(set_attr "mode" "SI")])
|
||||||
@@ -4635,7 +4830,7 @@
|
|||||||
(unspec:SI [(match_operand:QHWD 1 "register_operand" "r")
|
(unspec:SI [(match_operand:QHWD 1 "register_operand" "r")
|
||||||
(match_operand:SI 2 "register_operand" "r")]
|
(match_operand:SI 2 "register_operand" "r")]
|
||||||
CRC))]
|
CRC))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"<crc>.w.<size>.w\t%0,%1,%2"
|
"<crc>.w.<size>.w\t%0,%1,%2"
|
||||||
[(set_attr "type" "unknown")
|
[(set_attr "type" "unknown")
|
||||||
(set_attr "mode" "<MODE>")])
|
(set_attr "mode" "<MODE>")])
|
||||||
@@ -4656,7 +4851,7 @@
|
|||||||
(match_operand:SI 1 "register_operand") ; old_chksum
|
(match_operand:SI 1 "register_operand") ; old_chksum
|
||||||
(match_operand:SUBDI 2 "reg_or_0_operand") ; msg
|
(match_operand:SUBDI 2 "reg_or_0_operand") ; msg
|
||||||
(match_operand 3 "const_int_operand")] ; poly
|
(match_operand 3 "const_int_operand")] ; poly
|
||||||
""
|
"TARGET_64BIT"
|
||||||
{
|
{
|
||||||
unsigned HOST_WIDE_INT poly = UINTVAL (operands[3]);
|
unsigned HOST_WIDE_INT poly = UINTVAL (operands[3]);
|
||||||
rtx msg = operands[2];
|
rtx msg = operands[2];
|
||||||
@@ -4753,7 +4948,8 @@
|
|||||||
(define_insn_and_rewrite "simple_load<mode>"
|
(define_insn_and_rewrite "simple_load<mode>"
|
||||||
[(set (match_operand:LD_AT_LEAST_32_BIT 0 "register_operand" "=r,f")
|
[(set (match_operand:LD_AT_LEAST_32_BIT 0 "register_operand" "=r,f")
|
||||||
(match_operand:LD_AT_LEAST_32_BIT 1 "mem_simple_ldst_operand" ""))]
|
(match_operand:LD_AT_LEAST_32_BIT 1 "mem_simple_ldst_operand" ""))]
|
||||||
"loongarch_pre_reload_split ()
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
|
&& loongarch_pre_reload_split ()
|
||||||
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
||||||
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
||||||
"#"
|
"#"
|
||||||
@@ -4766,7 +4962,8 @@
|
|||||||
[(set (match_operand:GPR 0 "register_operand" "=r")
|
[(set (match_operand:GPR 0 "register_operand" "=r")
|
||||||
(any_extend:GPR
|
(any_extend:GPR
|
||||||
(match_operand:SUBDI 1 "mem_simple_ldst_operand" "")))]
|
(match_operand:SUBDI 1 "mem_simple_ldst_operand" "")))]
|
||||||
"loongarch_pre_reload_split ()
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
|
&& loongarch_pre_reload_split ()
|
||||||
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
||||||
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
||||||
"#"
|
"#"
|
||||||
@@ -4778,7 +4975,8 @@
|
|||||||
(define_insn_and_rewrite "simple_store<mode>"
|
(define_insn_and_rewrite "simple_store<mode>"
|
||||||
[(set (match_operand:ST_ANY 0 "mem_simple_ldst_operand" "")
|
[(set (match_operand:ST_ANY 0 "mem_simple_ldst_operand" "")
|
||||||
(match_operand:ST_ANY 1 "reg_or_0_operand" "r,f"))]
|
(match_operand:ST_ANY 1 "reg_or_0_operand" "r,f"))]
|
||||||
"loongarch_pre_reload_split ()
|
"(TARGET_64BIT || TARGET_32BIT_S)
|
||||||
|
&& loongarch_pre_reload_split ()
|
||||||
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
&& la_opt_explicit_relocs == EXPLICIT_RELOCS_AUTO
|
||||||
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
&& (TARGET_CMODEL_NORMAL || TARGET_CMODEL_MEDIUM)"
|
||||||
"#"
|
"#"
|
||||||
|
|||||||
@@ -295,7 +295,8 @@
|
|||||||
|
|
||||||
(define_predicate "low_bitmask_operand"
|
(define_predicate "low_bitmask_operand"
|
||||||
(and (match_code "const_int")
|
(and (match_code "const_int")
|
||||||
(match_test "low_bitmask_len (mode, INTVAL (op)) > 12")))
|
(match_test "low_bitmask_len (mode, INTVAL (op)) > 12")
|
||||||
|
(match_test "!TARGET_32BIT_R")))
|
||||||
|
|
||||||
(define_predicate "d_operand"
|
(define_predicate "d_operand"
|
||||||
(and (match_code "reg")
|
(and (match_code "reg")
|
||||||
@@ -406,6 +407,7 @@
|
|||||||
|
|
||||||
(define_predicate "ins_zero_bitmask_operand"
|
(define_predicate "ins_zero_bitmask_operand"
|
||||||
(and (match_code "const_int")
|
(and (match_code "const_int")
|
||||||
|
(match_test "!TARGET_32BIT_R")
|
||||||
(match_test "low_bitmask_len (mode, \
|
(match_test "low_bitmask_len (mode, \
|
||||||
~UINTVAL (op) | (~UINTVAL(op) - 1)) \
|
~UINTVAL (op) | (~UINTVAL(op) - 1)) \
|
||||||
> 0")
|
> 0")
|
||||||
@@ -438,6 +440,10 @@
|
|||||||
if (offset != const0_rtx)
|
if (offset != const0_rtx)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* TARGET_32BIT always support call30. */
|
||||||
|
if (TARGET_32BIT)
|
||||||
|
return true;
|
||||||
|
|
||||||
/* When compiling with '-mcmodel=medium -mexplicit-relocs'
|
/* When compiling with '-mcmodel=medium -mexplicit-relocs'
|
||||||
symbols are splited in loongarch_legitimize_call_address.
|
symbols are splited in loongarch_legitimize_call_address.
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,10 @@
|
|||||||
;; particular code.
|
;; particular code.
|
||||||
(define_code_attr amop [(ior "or") (xor "xor") (and "and") (plus "add")])
|
(define_code_attr amop [(ior "or") (xor "xor") (and "and") (plus "add")])
|
||||||
|
|
||||||
|
;; For 32 bit.
|
||||||
|
(define_code_attr atomic_optab_insn
|
||||||
|
[(plus "add.w") (ior "or") (xor "xor") (and "and")])
|
||||||
|
|
||||||
;; Memory barriers.
|
;; Memory barriers.
|
||||||
|
|
||||||
(define_expand "mem_thread_fence"
|
(define_expand "mem_thread_fence"
|
||||||
@@ -260,17 +264,48 @@
|
|||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn "atomic_<amop><mode>"
|
(define_expand "atomic_<amop><mode>"
|
||||||
|
[(any_atomic:GPR (match_operand:GPR 0 "memory_operand") ;; mem location
|
||||||
|
(match_operand:GPR 1 "reg_or_0_operand")) ;; value for op
|
||||||
|
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (TARGET_64BIT)
|
||||||
|
emit_insn (gen_la64_atomic_<amop><mode> (operands[0], operands[1], operands[2]));
|
||||||
|
else
|
||||||
|
emit_insn (gen_la32_atomic_<amop>si (operands[0], operands[1], operands[2]));
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn "la64_atomic_<amop><mode>"
|
||||||
[(set (match_operand:GPR 0 "memory_operand" "+ZB")
|
[(set (match_operand:GPR 0 "memory_operand" "+ZB")
|
||||||
(unspec_volatile:GPR
|
(unspec_volatile:GPR
|
||||||
[(any_atomic:GPR (match_dup 0)
|
[(any_atomic:GPR (match_dup 0)
|
||||||
(match_operand:GPR 1 "reg_or_0_operand" "rJ"))
|
(match_operand:GPR 1 "reg_or_0_operand" "rJ"))
|
||||||
(match_operand:SI 2 "const_int_operand")] ;; model
|
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||||
UNSPEC_SYNC_OLD_OP))]
|
UNSPEC_SYNC_OLD_OP))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"am<amop>%A2.<size>\t$zero,%z1,%0"
|
"am<amop>%A2.<size>\t$zero,%z1,%0"
|
||||||
[(set (attr "length") (const_int 4))])
|
[(set (attr "length") (const_int 4))])
|
||||||
|
|
||||||
|
(define_insn "la32_atomic_<amop>si"
|
||||||
|
[(set (match_operand:SI 0 "memory_operand" "+ZB")
|
||||||
|
(unspec_volatile:SI
|
||||||
|
[(any_atomic:SI (match_dup 0)
|
||||||
|
(match_operand:SI 1 "reg_or_0_operand" "rJ"))
|
||||||
|
(match_operand:SI 2 "const_int_operand")] ;; model
|
||||||
|
UNSPEC_SYNC_OLD_OP))
|
||||||
|
(clobber (match_scratch:SI 3 "=&r"))]
|
||||||
|
"!TARGET_64BIT"
|
||||||
|
{
|
||||||
|
return "1:\n\t"
|
||||||
|
"ll.w\t%3,%0\n\t"
|
||||||
|
"<atomic_optab_insn>\t%3,%z1,%3\n\t"
|
||||||
|
"sc.w\t%3,%0\n\t"
|
||||||
|
"beq\t$zero,%3,1b\n\t";
|
||||||
|
}
|
||||||
|
[(set (attr "length") (const_int 16))])
|
||||||
|
|
||||||
(define_insn "atomic_add<mode>"
|
(define_insn "atomic_add<mode>"
|
||||||
[(set (match_operand:SHORT 0 "memory_operand" "+ZB")
|
[(set (match_operand:SHORT 0 "memory_operand" "+ZB")
|
||||||
(unspec_volatile:SHORT
|
(unspec_volatile:SHORT
|
||||||
@@ -282,7 +317,23 @@
|
|||||||
"amadd%A2.<size>\t$zero,%z1,%0"
|
"amadd%A2.<size>\t$zero,%z1,%0"
|
||||||
[(set (attr "length") (const_int 4))])
|
[(set (attr "length") (const_int 4))])
|
||||||
|
|
||||||
(define_insn "atomic_fetch_<amop><mode>"
|
(define_expand "atomic_fetch_<amop><mode>"
|
||||||
|
[(match_operand:GPR 0 "register_operand") ;; old value at mem
|
||||||
|
(any_atomic:GPR (match_operand:GPR 1 "memory_operand") ;; mem location
|
||||||
|
(match_operand:GPR 2 "reg_or_0_operand")) ;; value for op
|
||||||
|
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (TARGET_64BIT)
|
||||||
|
emit_insn (gen_la64_atomic_fetch_<amop><mode> (operands[0], operands[1],
|
||||||
|
operands[2], operands[3]));
|
||||||
|
else
|
||||||
|
emit_insn (gen_la32_atomic_fetch_<amop>si (operands[0], operands[1],
|
||||||
|
operands[2], operands[3]));
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn "la64_atomic_fetch_<amop><mode>"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||||
(match_operand:GPR 1 "memory_operand" "+ZB"))
|
(match_operand:GPR 1 "memory_operand" "+ZB"))
|
||||||
(set (match_dup 1)
|
(set (match_dup 1)
|
||||||
@@ -291,10 +342,30 @@
|
|||||||
(match_operand:GPR 2 "reg_or_0_operand" "rJ"))
|
(match_operand:GPR 2 "reg_or_0_operand" "rJ"))
|
||||||
(match_operand:SI 3 "const_int_operand")] ;; model
|
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||||
UNSPEC_SYNC_OLD_OP))]
|
UNSPEC_SYNC_OLD_OP))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"am<amop>%A3.<size>\t%0,%z2,%1"
|
"am<amop>%A3.<size>\t%0,%z2,%1"
|
||||||
[(set (attr "length") (const_int 4))])
|
[(set (attr "length") (const_int 4))])
|
||||||
|
|
||||||
|
(define_insn "la32_atomic_fetch_<amop>si"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||||
|
(match_operand:SI 1 "memory_operand" "+ZB"))
|
||||||
|
(set (match_dup 1)
|
||||||
|
(unspec_volatile:SI
|
||||||
|
[(any_atomic:SI (match_dup 1)
|
||||||
|
(match_operand:SI 2 "reg_or_0_operand" "rJ"))
|
||||||
|
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||||
|
UNSPEC_SYNC_OLD_OP))
|
||||||
|
(clobber (match_scratch:SI 4 "=&r"))]
|
||||||
|
"!TARGET_64BIT"
|
||||||
|
{
|
||||||
|
return "1:\n\t"
|
||||||
|
"ll.w\t%0,%1\n\t"
|
||||||
|
"<atomic_optab_insn>\t%4,%z2,%0\n\t"
|
||||||
|
"sc.w\t%4,%1\n\t"
|
||||||
|
"beq\t$zero,%4,1b\n\t";
|
||||||
|
}
|
||||||
|
[(set (attr "length") (const_int 16))])
|
||||||
|
|
||||||
(define_insn "atomic_fetch_nand_mask_inverted<mode>"
|
(define_insn "atomic_fetch_nand_mask_inverted<mode>"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||||
(match_operand:GPR 1 "memory_operand" "+ZC"))
|
(match_operand:GPR 1 "memory_operand" "+ZC"))
|
||||||
@@ -305,14 +376,24 @@
|
|||||||
UNSPEC_SYNC_OLD_OP))
|
UNSPEC_SYNC_OLD_OP))
|
||||||
(clobber (match_scratch:GPR 3 "=&r"))]
|
(clobber (match_scratch:GPR 3 "=&r"))]
|
||||||
""
|
""
|
||||||
{
|
{
|
||||||
return "1:\\n\\t"
|
output_asm_insn ("1:", operands);
|
||||||
"ll.<d>\\t%0,%1\\n\\t"
|
output_asm_insn ("ll.<d>\t%0,%1", operands);
|
||||||
"orn\\t%3,%2,%0\\n\\t"
|
if (TARGET_32BIT_R)
|
||||||
"sc.<d>\\t%3,%1\\n\\t"
|
{
|
||||||
"beqz\\t%3,1b";
|
output_asm_insn ("nor\t%3,%0,$zero", operands);
|
||||||
}
|
output_asm_insn ("or\t%3,%2,%3", operands);
|
||||||
[(set (attr "length") (const_int 16))])
|
}
|
||||||
|
else
|
||||||
|
output_asm_insn ("orn\t%3,%2,%0", operands);
|
||||||
|
output_asm_insn ("sc.<d>\t%3,%1", operands);
|
||||||
|
output_asm_insn ("beq\t%3,$zero,1b", operands);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
[(set (attr "length") (if_then_else
|
||||||
|
(match_test "TARGET_32BIT_R")
|
||||||
|
(const_int 20)
|
||||||
|
(const_int 16)))])
|
||||||
|
|
||||||
(define_mode_iterator ALL_SC [GPR (TI "loongarch_16b_atomic_lock_free_p ()")])
|
(define_mode_iterator ALL_SC [GPR (TI "loongarch_16b_atomic_lock_free_p ()")])
|
||||||
(define_mode_attr _scq [(SI "") (DI "") (TI "_scq")])
|
(define_mode_attr _scq [(SI "") (DI "") (TI "_scq")])
|
||||||
@@ -338,7 +419,23 @@
|
|||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
(define_insn "atomic_exchange<mode>"
|
(define_expand "atomic_exchange<mode>"
|
||||||
|
[(match_operand:GPR 0 "register_operand") ;; old value at mem
|
||||||
|
(match_operand:GPR 1 "memory_operand") ;; mem location
|
||||||
|
(match_operand:GPR 2 "register_operand") ;; value for op
|
||||||
|
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (TARGET_64BIT)
|
||||||
|
emit_insn (gen_la64_atomic_exchange<mode> (operands[0], operands[1],
|
||||||
|
operands[2], operands[3]));
|
||||||
|
else
|
||||||
|
emit_insn (gen_la32_atomic_exchangesi (operands[0], operands[1],
|
||||||
|
operands[2], operands[3]));
|
||||||
|
DONE;
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_insn "la64_atomic_exchange<mode>"
|
||||||
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
[(set (match_operand:GPR 0 "register_operand" "=&r")
|
||||||
(unspec_volatile:GPR
|
(unspec_volatile:GPR
|
||||||
[(match_operand:GPR 1 "memory_operand" "+ZB")
|
[(match_operand:GPR 1 "memory_operand" "+ZB")
|
||||||
@@ -346,10 +443,29 @@
|
|||||||
UNSPEC_SYNC_EXCHANGE))
|
UNSPEC_SYNC_EXCHANGE))
|
||||||
(set (match_dup 1)
|
(set (match_dup 1)
|
||||||
(match_operand:GPR 2 "register_operand" "r"))]
|
(match_operand:GPR 2 "register_operand" "r"))]
|
||||||
""
|
"TARGET_64BIT"
|
||||||
"amswap%A3.<size>\t%0,%z2,%1"
|
"amswap%A3.<size>\t%0,%z2,%1"
|
||||||
[(set (attr "length") (const_int 4))])
|
[(set (attr "length") (const_int 4))])
|
||||||
|
|
||||||
|
(define_insn "la32_atomic_exchangesi"
|
||||||
|
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||||
|
(unspec_volatile:SI
|
||||||
|
[(match_operand:SI 1 "memory_operand" "+ZB")
|
||||||
|
(match_operand:SI 3 "const_int_operand")] ;; model
|
||||||
|
UNSPEC_SYNC_EXCHANGE))
|
||||||
|
(set (match_dup 1)
|
||||||
|
(match_operand:SI 2 "register_operand" "r"))
|
||||||
|
(clobber (match_scratch:SI 4 "=&r"))]
|
||||||
|
"!TARGET_64BIT"
|
||||||
|
{
|
||||||
|
return "1:\n\t"
|
||||||
|
"ll.w\t%0,%1\n\t"
|
||||||
|
"or\t%4,$zero,%2\n\t"
|
||||||
|
"sc.w\t%4,%1\n\t"
|
||||||
|
"beq\t$zero,%4,1b\n\t";
|
||||||
|
}
|
||||||
|
[(set (attr "length") (const_int 16))])
|
||||||
|
|
||||||
(define_insn "atomic_exchangeti_scq"
|
(define_insn "atomic_exchangeti_scq"
|
||||||
[(set (match_operand:TI 0 "register_operand" "=&r")
|
[(set (match_operand:TI 0 "register_operand" "=&r")
|
||||||
(unspec_volatile:TI
|
(unspec_volatile:TI
|
||||||
@@ -367,7 +483,7 @@
|
|||||||
output_asm_insn ("ld.d\t%t0,%b1,8", operands);
|
output_asm_insn ("ld.d\t%t0,%b1,8", operands);
|
||||||
output_asm_insn ("move\t%3,%z2", operands);
|
output_asm_insn ("move\t%3,%z2", operands);
|
||||||
output_asm_insn ("sc.q\t%3,%t2,%1", operands);
|
output_asm_insn ("sc.q\t%3,%t2,%1", operands);
|
||||||
output_asm_insn ("beqz\t%3,1b", operands);
|
output_asm_insn ("beq\t%3,$zero,1b", operands);
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -430,7 +546,7 @@
|
|||||||
|
|
||||||
output_asm_insn ("or%i3\t%5,$zero,%3", operands);
|
output_asm_insn ("or%i3\t%5,$zero,%3", operands);
|
||||||
output_asm_insn ("sc.<size>\t%5,%1", operands);
|
output_asm_insn ("sc.<size>\t%5,%1", operands);
|
||||||
output_asm_insn ("beqz\t%5,1b", operands);
|
output_asm_insn ("beq\t%5,$zero,1b", operands);
|
||||||
output_asm_insn ("%T4b\t3f", operands);
|
output_asm_insn ("%T4b\t3f", operands);
|
||||||
output_asm_insn ("2:", operands);
|
output_asm_insn ("2:", operands);
|
||||||
output_asm_insn ("%G4", operands);
|
output_asm_insn ("%G4", operands);
|
||||||
@@ -498,7 +614,7 @@
|
|||||||
emit_insn (gen_rtx_SET (compare, difference));
|
emit_insn (gen_rtx_SET (compare, difference));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word_mode != <MODE>mode)
|
if (word_mode != GET_MODE (compare))
|
||||||
{
|
{
|
||||||
rtx reg = gen_reg_rtx (word_mode);
|
rtx reg = gen_reg_rtx (word_mode);
|
||||||
emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)));
|
emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)));
|
||||||
@@ -515,7 +631,7 @@
|
|||||||
(any_bitwise (match_operand:SHORT 1 "memory_operand" "+ZB") ;; memory
|
(any_bitwise (match_operand:SHORT 1 "memory_operand" "+ZB") ;; memory
|
||||||
(match_operand:SHORT 2 "reg_or_0_operand" "rJ")) ;; val
|
(match_operand:SHORT 2 "reg_or_0_operand" "rJ")) ;; val
|
||||||
(match_operand:SI 3 "const_int_operand" "")] ;; model
|
(match_operand:SI 3 "const_int_operand" "")] ;; model
|
||||||
""
|
"TARGET_64BIT || TARGET_32BIT_S"
|
||||||
{
|
{
|
||||||
/* We have no QI/HImode bitwise atomics, so use the address LSBs to form
|
/* We have no QI/HImode bitwise atomics, so use the address LSBs to form
|
||||||
a mask, then use an aligned SImode atomic. */
|
a mask, then use an aligned SImode atomic. */
|
||||||
@@ -642,26 +758,26 @@
|
|||||||
operands[3], operands[4], mod_f);
|
operands[3], operands[4], mod_f);
|
||||||
}
|
}
|
||||||
|
|
||||||
rtx compare = operands[1];
|
rtx compare = operands[1];
|
||||||
if (operands[3] != const0_rtx)
|
if (operands[3] != const0_rtx)
|
||||||
{
|
{
|
||||||
machine_mode mode = GET_MODE (operands[3]);
|
machine_mode mode = GET_MODE (operands[3]);
|
||||||
rtx op1 = convert_modes (SImode, mode, operands[1], true);
|
rtx op1 = convert_modes (SImode, mode, operands[1], true);
|
||||||
rtx op3 = convert_modes (SImode, mode, operands[3], true);
|
rtx op3 = convert_modes (SImode, mode, operands[3], true);
|
||||||
rtx difference = gen_rtx_MINUS (SImode, op1, op3);
|
rtx difference = gen_rtx_MINUS (SImode, op1, op3);
|
||||||
compare = gen_reg_rtx (SImode);
|
compare = gen_reg_rtx (SImode);
|
||||||
emit_insn (gen_rtx_SET (compare, difference));
|
emit_insn (gen_rtx_SET (compare, difference));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word_mode != <MODE>mode)
|
if (word_mode != GET_MODE (compare))
|
||||||
{
|
{
|
||||||
rtx reg = gen_reg_rtx (word_mode);
|
rtx reg = gen_reg_rtx (word_mode);
|
||||||
emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)));
|
emit_insn (gen_rtx_SET (reg, gen_rtx_SIGN_EXTEND (word_mode, compare)));
|
||||||
compare = reg;
|
compare = reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit_insn (gen_rtx_SET (operands[0],
|
emit_insn (gen_rtx_SET (operands[0],
|
||||||
gen_rtx_EQ (SImode, compare, const0_rtx)));
|
gen_rtx_EQ (SImode, compare, const0_rtx)));
|
||||||
DONE;
|
DONE;
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -716,7 +832,7 @@
|
|||||||
output_asm_insn ("sc.q\t%7,%t3,%1", operands);
|
output_asm_insn ("sc.q\t%7,%t3,%1", operands);
|
||||||
|
|
||||||
/* Check if sc.q has done the store. */
|
/* Check if sc.q has done the store. */
|
||||||
output_asm_insn ("beqz\t%7,1b", operands);
|
output_asm_insn ("beq\t%7,$zero,1b", operands);
|
||||||
|
|
||||||
/* Jump over the mod_f barrier if sc.q has succeeded. */
|
/* Jump over the mod_f barrier if sc.q has succeeded. */
|
||||||
output_asm_insn ("%T4b\t3f", operands);
|
output_asm_insn ("%T4b\t3f", operands);
|
||||||
@@ -870,7 +986,7 @@
|
|||||||
"and\\t%7,%0,%z3\\n\\t"
|
"and\\t%7,%0,%z3\\n\\t"
|
||||||
"or%i5\\t%7,%7,%5\\n\\t"
|
"or%i5\\t%7,%7,%5\\n\\t"
|
||||||
"sc.<size>\\t%7,%1\\n\\t"
|
"sc.<size>\\t%7,%1\\n\\t"
|
||||||
"beqz\\t%7,1b\\n\\t";
|
"beq\\t%7,$zero,1b\\n\\t";
|
||||||
}
|
}
|
||||||
[(set (attr "length") (const_int 20))])
|
[(set (attr "length") (const_int 20))])
|
||||||
|
|
||||||
@@ -967,7 +1083,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
output_asm_insn ("sc.q\t%3,%4,%1", operands);
|
output_asm_insn ("sc.q\t%3,%4,%1", operands);
|
||||||
output_asm_insn ("beqz\t%3,1b", operands);
|
output_asm_insn ("beq\t%3,$zero,1b", operands);
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user