(if_then_else (ior ;; In general, constant-pool loads are extended
;; instructions. We don't yet optimize for 16-bit
;; PC-relative references.
- (eq_attr "move_type" "sll0,loadpool")
+ (eq_attr "move_type" "sll0,loadpool,ext_ins")
(eq_attr "jal" "direct")
(eq_attr "got" "load"))
(const_string "yes")
;; register =op1 x
(define_insn "*and<mode>3"
- [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d")
- (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d")
- (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,!u,d,d,d,!u,d,d")
+ (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "o,o,W,!u,d,d,d,0,d,0")
+ (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Uean,K,Yx,Yw,!u,d,Yz")))]
"!TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
{
int len;
+ int pos;
switch (which_alternative)
{
case 7:
case 8:
return "and\t%0,%1,%2";
+ case 9:
+ mips_bit_clear_info (<MODE>mode, INTVAL (operands[2]), &pos, &len);
+ operands[1] = GEN_INT (pos);
+ operands[2] = GEN_INT (len);
+ return "<d>ins\t%0,$0,%1,%2";
default:
gcc_unreachable ();
}
}
- [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical")
- (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*")
+ [(set_attr "move_type" "load,load,load,andi,andi,ext_ins,shift_shift,logical,logical,ext_ins")
+ (set_attr "compression" "*,*,*,micromips,*,*,*,micromips,*,*")
(set_attr "mode" "<MODE>")])
(define_insn "*and<mode>3_mips16"
- [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d")
- (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0")
- (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d,d,d")
+ (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "%W,W,W,d,0,d,0,0?")
+ (match_operand:GPR 2 "and_operand" "Yb,Yh,Yw,Yw,d,Yx,Yz,K")))]
"TARGET_MIPS16 && and_operands_ok (<MODE>mode, operands[1], operands[2])"
{
+ int len;
+ int pos;
+
switch (which_alternative)
{
case 0:
return "#";
case 4:
return "and\t%0,%2";
+ case 5:
+ len = low_bitmask_len (<MODE>mode, INTVAL (operands[2]));
+ operands[2] = GEN_INT (len);
+ return "ext\t%0,%1,0,%2";
+ case 6:
+ mips_bit_clear_info (<MODE>mode, INTVAL (operands[2]), &pos, &len);
+ operands[1] = GEN_INT (pos);
+ operands[2] = GEN_INT (len);
+ return "ins\t%0,$0,%1,%2";
+ case 7:
+ return "andi\t%0,%x2";
default:
gcc_unreachable ();
}
}
- [(set_attr "move_type" "load,load,load,shift_shift,logical")
- (set_attr "mode" "<MODE>")])
+ [(set_attr "move_type" "load,load,load,shift_shift,logical,ext_ins,ext_ins,andi")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "no,no,no,no,no,yes,yes,yes")
+ (set (attr "enabled")
+ (cond [(and (eq_attr "alternative" "7")
+ (not (match_test "ISA_HAS_MIPS16E2")))
+ (const_string "no")
+ (and (eq_attr "alternative" "0,1")
+ (match_test "!GENERATE_MIPS16E"))
+ (const_string "no")]
+ (const_string "yes")))])
(define_expand "ior<mode>3"
[(set (match_operand:GPR 0 "register_operand")
(match_operand:GPR 2 "uns_arith_operand")))]
""
{
- if (TARGET_MIPS16)
+ if (TARGET_MIPS16 && !ISA_HAS_MIPS16E2)
operands[2] = force_reg (<MODE>mode, operands[2]);
})
(set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
+(define_insn "*ior<mode>3_mips16_asmacro"
+ [(set (match_operand:GPR 0 "register_operand" "=d,d")
+ (ior:GPR (match_operand:GPR 1 "register_operand" "%0,0")
+ (match_operand:GPR 2 "uns_arith_operand" "d,K")))]
+ "ISA_HAS_MIPS16E2"
+ "@
+ or\t%0,%2
+ ori\t%0,%x2"
+ [(set_attr "alu_type" "or")
+ (set_attr "mode" "<MODE>")
+ (set_attr "extended_mips16" "*,yes")])
+
(define_insn "*ior<mode>3_mips16"
[(set (match_operand:GPR 0 "register_operand" "=d")
(ior:GPR (match_operand:GPR 1 "register_operand" "%0")
(match_operand:GPR 2 "register_operand" "d")))]
- "TARGET_MIPS16"
+ "TARGET_MIPS16 && !ISA_HAS_MIPS16E2"
"or\t%0,%2"
[(set_attr "alu_type" "or")
(set_attr "mode" "<MODE>")])
(set_attr "compression" "micromips,*,*")
(set_attr "mode" "<MODE>")])
+;; We increase statically the cost of the output register for XORI
+;; to counterweight LRA cost calculation as XORI tends to be chosen
+;; frequently hurting the code size. The reason of not choosing CMPI is
+;; that LRA tends to add up the cost of the T register as it is in a small
+;; class and a possible reload. In reality, the use of T register comes for
+;; free in a number of cases as we don't need any MIPS16 registers.
(define_insn "*xor<mode>3_mips16"
- [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t")
- (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d")
- (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d")))]
+ [(set (match_operand:GPR 0 "register_operand" "=d,t,t,t,d?")
+ (xor:GPR (match_operand:GPR 1 "register_operand" "%0,d,d,d,0")
+ (match_operand:GPR 2 "uns_arith_operand" "d,Uub8,K,d,K")))]
"TARGET_MIPS16"
"@
xor\t%0,%2
cmpi\t%1,%2
cmpi\t%1,%2
- cmp\t%1,%2"
+ cmp\t%1,%2
+ xori\t%0,%x2"
[(set_attr "alu_type" "xor")
(set_attr "mode" "<MODE>")
- (set_attr "extended_mips16" "no,no,yes,no")])
+ (set_attr "extended_mips16" "no,no,yes,no,yes")
+ (set (attr "enabled")
+ (cond [(and (eq_attr "alternative" "4")
+ (not (match_test "ISA_HAS_MIPS16E2")))
+ (const_string "no")]
+ (const_string "yes")))])
(define_insn "*nor<mode>3"
[(set (match_operand:GPR 0 "register_operand" "=d")
INTVAL (operands[3]))"
"<d>ext\t%0,%1,%3,%2"
[(set_attr "type" "arith")
+ (set_attr "extended_mips16" "yes")
(set_attr "mode" "<MODE>")])
(define_insn "*extzv_truncsi_exts"
INTVAL (operands[2]))"
"<d>ins\t%0,%z3,%2,%1"
[(set_attr "type" "arith")
+ (set_attr "extended_mips16" "yes")
(set_attr "mode" "<MODE>")])
;; Combiner pattern for cins (clear and insert bit field). We can