aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips/mips.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/mips/mips.md')
-rw-r--r--gcc/config/mips/mips.md1315
1 files changed, 323 insertions, 992 deletions
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 2edbd28d013..4175ab529b4 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -47,7 +47,9 @@
(UNSPEC_CONSTTABLE_DF 17)
(UNSPEC_ALIGN_2 18)
(UNSPEC_ALIGN_4 19)
- (UNSPEC_ALIGN_8 20)])
+ (UNSPEC_ALIGN_8 20)
+ (UNSPEC_CPADD 21)
+ (UNSPEC_RELOC_GPREL16 100)])
;; ....................
@@ -62,11 +64,13 @@
;; call unconditional call
;; load load instruction(s)
;; store store instruction(s)
+;; prefetch memory prefetch
;; move data movement within same register set
;; xfer transfer to/from coprocessor
;; hilo transfer of hi/lo registers
;; arith integer arithmetic instruction
;; darith double precision integer arithmetic instructions
+;; const load constant
;; imul integer multiply
;; imadd integer multiply-add
;; idiv integer divide
@@ -85,7 +89,7 @@
;; nop no operation
(define_attr "type"
- "unknown,branch,jump,call,load,store,move,xfer,hilo,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
+ "unknown,branch,jump,call,load,store,prefetch,move,xfer,hilo,const,arith,darith,imul,imadd,idiv,icmp,fadd,fmul,fmadd,fdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
(const_string "unknown"))
;; Main data type used by the insn
@@ -110,6 +114,12 @@
(const_int 0))
(const_int 24)
] (const_int 12))
+ (eq_attr "type" "const")
+ (symbol_ref "mips_const_insns (operands[1]) * 4")
+ (eq_attr "type" "load")
+ (symbol_ref "mips_fetch_insns (operands[1]) * 4")
+ (eq_attr "type" "store")
+ (symbol_ref "mips_fetch_insns (operands[0]) * 4")
] (const_int 4)))
;; Attribute describing the processor. This attribute must match exactly
@@ -140,15 +150,14 @@
(const_string "yes")
(const_string "no")))
+;; Is it a single instruction?
+(define_attr "single_insn" "no,yes"
+ (symbol_ref "get_attr_length (insn) == (TARGET_MIPS16 ? 2 : 4)"))
+
;; Can the instruction be put into a delay slot?
(define_attr "can_delay" "no,yes"
(if_then_else (and (eq_attr "dslot" "no")
- ; ADJUST_INSN_LENGTH divides length by 2 on mips16,
- ; so cope with it here.
- (ior (and (eq (symbol_ref "mips16") (const_int 0))
- (eq_attr "length" "4"))
- (and (ne (symbol_ref "mips16") (const_int 0))
- (eq_attr "length" "2"))))
+ (eq_attr "single_insn" "yes"))
(const_string "yes")
(const_string "no")))
@@ -165,10 +174,6 @@
(define_asm_attributes
[(set_attr "type" "multi")])
-;; whether or not generating calls to position independent functions
-(define_attr "abicalls" "no,yes"
- (const (symbol_ref "mips_abicalls_attr")))
-
;; .........................
@@ -182,15 +187,14 @@
[(eq_attr "can_delay" "yes")
(nil)
(and (eq_attr "branch_likely" "yes")
- (and (eq_attr "dslot" "no")
- (eq_attr "length" "4")))])
+ (eq_attr "can_delay" "yes"))])
(define_delay (eq_attr "type" "jump")
[(eq_attr "can_delay" "yes")
(nil)
(nil)])
-(define_delay (and (eq_attr "type" "call") (eq_attr "abicalls" "no"))
+(define_delay (eq_attr "type" "call")
[(eq_attr "can_delay" "yes")
(nil)
(nil)])
@@ -1157,7 +1161,7 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=d,d,d")
(sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "0,d,d")
- (match_operand:SI 2 "arith_operand" "I,O,d"))))]
+ (match_operand:SI 2 "arith_operand" "IQ,O,d"))))]
"TARGET_MIPS16 && TARGET_64BIT"
"*
{
@@ -4101,13 +4105,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "zero_extendsidi2_internal"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (zero_extend:DI (match_operand:SI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI (match_operand:SI 1 "memory_operand" "m")))]
"TARGET_64BIT && !TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
[(set_attr "type" "load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "DI")])
(define_expand "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -4126,8 +4129,8 @@ move\\t%0,%z4\\n\\
}")
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
"!TARGET_MIPS16"
"*
{
@@ -4136,18 +4139,17 @@ move\\t%0,%z4\\n\\
else
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "arith,load,load")
+ [(set_attr "type" "arith,load")
(set_attr "mode" "SI")
- (set_attr "length" "4,4,8")])
+ (set_attr "length" "4,*")])
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (zero_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "load,load")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "SI")])
(define_expand "zero_extendhidi2"
[(set (match_operand:DI 0 "register_operand" "")
@@ -4166,8 +4168,8 @@ move\\t%0,%z4\\n\\
}")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=d,d,d")
- (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT && !TARGET_MIPS16"
"*
{
@@ -4176,18 +4178,17 @@ move\\t%0,%z4\\n\\
else
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "arith,load,load")
+ [(set_attr "type" "arith,load")
(set_attr "mode" "DI")
- (set_attr "length" "4,4,8")])
+ (set_attr "length" "4,*")])
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (zero_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT && TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "load,load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "DI")])
(define_expand "zero_extendqihi2"
[(set (match_operand:HI 0 "register_operand" "")
@@ -4207,8 +4208,8 @@ move\\t%0,%z4\\n\\
}")
(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=d,d,d")
- (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
+ [(set (match_operand:HI 0 "register_operand" "=d,d")
+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
"!TARGET_MIPS16"
"*
{
@@ -4217,18 +4218,17 @@ move\\t%0,%z4\\n\\
else
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "arith,load,load")
+ [(set_attr "type" "arith,load")
(set_attr "mode" "HI")
- (set_attr "length" "4,4,8")])
+ (set_attr "length" "4,*")])
(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=d,d")
- (zero_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "load,load")
- (set_attr "mode" "HI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "HI")])
(define_expand "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -4247,8 +4247,8 @@ move\\t%0,%z4\\n\\
}")
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d,d,d")
- (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
"!TARGET_MIPS16"
"*
{
@@ -4257,18 +4257,17 @@ move\\t%0,%z4\\n\\
else
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "arith,load,load")
+ [(set_attr "type" "arith,load")
(set_attr "mode" "SI")
- (set_attr "length" "4,4,8")])
+ (set_attr "length" "4,*")])
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (zero_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "load,load")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "SI")])
(define_expand "zero_extendqidi2"
[(set (match_operand:DI 0 "register_operand" "")
@@ -4287,8 +4286,8 @@ move\\t%0,%z4\\n\\
}")
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=d,d,d")
- (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))]
"TARGET_64BIT && !TARGET_MIPS16"
"*
{
@@ -4297,9 +4296,9 @@ move\\t%0,%z4\\n\\
else
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "arith,load,load")
+ [(set_attr "type" "arith,load")
(set_attr "mode" "DI")
- (set_attr "length" "4,4,8")])
+ (set_attr "length" "4,*")])
;; These can be created when a paradoxical subreg operand with an implicit
;; sign_extend operator is reloaded. Because of the subreg, this is really
@@ -4307,26 +4306,24 @@ move\\t%0,%z4\\n\\
;; ??? It might be possible to eliminate the need for these patterns by adding
;; more support to reload for implicit sign_extend operators.
(define_insn "*paradoxical_extendhidi2"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
+ [(set (match_operand:DI 0 "register_operand" "=d")
(sign_extend:DI
- (subreg:SI (match_operand:HI 1 "memory_operand" "R,m") 0)))]
+ (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0)))]
"TARGET_64BIT"
"*
{
return mips_move_1word (operands, insn, TRUE);
}"
- [(set_attr "type" "load,load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "DI")])
(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (zero_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_64BIT && TARGET_MIPS16"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "load,load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "load")
+ (set_attr "mode" "DI")])
;;
;; ....................
@@ -4376,13 +4373,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "extendhidi2_internal"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (sign_extend:DI (match_operand:HI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))]
"TARGET_64BIT"
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "DI")])
(define_expand "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "")
@@ -4406,13 +4402,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "extendhisi2_internal"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))]
""
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "load")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "SI")])
(define_expand "extendqihi2"
[(set (match_operand:HI 0 "register_operand" "")
@@ -4437,13 +4432,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "extendqihi2_internal"
- [(set (match_operand:HI 0 "register_operand" "=d,d")
- (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:HI 0 "register_operand" "=d")
+ (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))]
""
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "load")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "SI")])
(define_expand "extendqisi2"
@@ -4468,13 +4462,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "extendqisi2_insn"
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))]
""
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "load")
- (set_attr "mode" "SI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "SI")])
(define_expand "extendqidi2"
[(set (match_operand:DI 0 "register_operand" "")
@@ -4498,13 +4491,12 @@ move\\t%0,%z4\\n\\
}")
(define_insn "extendqidi2_insn"
- [(set (match_operand:DI 0 "register_operand" "=d,d")
- (sign_extend:DI (match_operand:QI 1 "memory_operand" "R,m")))]
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))]
"TARGET_64BIT"
"* return mips_move_1word (operands, insn, FALSE);"
[(set_attr "type" "load")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "DI")])
(define_insn "extendsfdf2"
@@ -5004,8 +4996,8 @@ move\\t%0,%z4\\n\\
;; unaligned word moves generated by the bit field patterns
(define_insn "movsi_ulw"
- [(set (match_operand:SI 0 "register_operand" "=&d,&d")
- (unspec:SI [(match_operand:BLK 1 "general_operand" "R,o")]
+ [(set (match_operand:SI 0 "register_operand" "=&d")
+ (unspec:SI [(match_operand:BLK 1 "general_operand" "m")]
UNSPEC_ULW))]
"!TARGET_MIPS16"
"*
@@ -5029,13 +5021,13 @@ move\\t%0,%z4\\n\\
return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
}"
- [(set_attr "type" "load,load")
+ [(set_attr "type" "load")
(set_attr "mode" "SI")
- (set_attr "length" "8,16")])
+ (set_attr "length" "8")])
(define_insn "movsi_usw"
- [(set (match_operand:BLK 0 "memory_operand" "=R,o")
- (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ,dJ")]
+ [(set (match_operand:BLK 0 "memory_operand" "=m")
+ (unspec:BLK [(match_operand:SI 1 "reg_or_0_operand" "dJ")]
UNSPEC_USW))]
"!TARGET_MIPS16"
"*
@@ -5058,15 +5050,15 @@ move\\t%0,%z4\\n\\
}"
[(set_attr "type" "store")
(set_attr "mode" "SI")
- (set_attr "length" "8,16")])
+ (set_attr "length" "8")])
;; Bit field extract patterns which use ldl/ldr.
;; unaligned double word moves generated by the bit field patterns
(define_insn "movdi_uld"
- [(set (match_operand:DI 0 "register_operand" "=&d,&d")
- (unspec:DI [(match_operand:BLK 1 "general_operand" "R,o")]
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (unspec:DI [(match_operand:BLK 1 "general_operand" "m")]
UNSPEC_ULD))]
""
"*
@@ -5090,13 +5082,13 @@ move\\t%0,%z4\\n\\
return mips_fill_delay_slot (ret, DELAY_LOAD, operands, insn);
}"
- [(set_attr "type" "load,load")
+ [(set_attr "type" "load")
(set_attr "mode" "SI")
- (set_attr "length" "8,16")])
+ (set_attr "length" "8")])
(define_insn "movdi_usd"
- [(set (match_operand:BLK 0 "memory_operand" "=R,o")
- (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ,dJ")]
+ [(set (match_operand:BLK 0 "memory_operand" "=m")
+ (unspec:BLK [(match_operand:DI 1 "reg_or_0_operand" "dJ")]
UNSPEC_USD))]
""
"*
@@ -5119,30 +5111,36 @@ move\\t%0,%z4\\n\\
}"
[(set_attr "type" "store")
(set_attr "mode" "SI")
- (set_attr "length" "8,16")])
-
-;; These two patterns support loading addresses with two instructions instead
-;; of using the macro instruction la.
-
-;; ??? mips_move_1word has support for HIGH, so this pattern may be
-;; unnecessary.
-
-(define_insn "high"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (high:SI (match_operand:SI 1 "immediate_operand" "")))]
- "mips_split_addresses && !TARGET_MIPS16"
- "lui\\t%0,%%hi(%1) # high"
- [(set_attr "type" "move")])
+ (set_attr "length" "8")])
-(define_insn "low"
+(define_insn "lowsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(lo_sum:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "immediate_operand" "")))]
"mips_split_addresses && !TARGET_MIPS16"
- "addiu\\t%0,%1,%%lo(%2) # low"
+ "addiu\\t%0,%1,%%lo(%2)"
[(set_attr "type" "arith")
(set_attr "mode" "SI")])
+(define_insn "lowdi"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (lo_sum:DI (match_operand:DI 1 "register_operand" "r")
+ (match_operand:DI 2 "immediate_operand" "")))]
+ "mips_split_addresses && !TARGET_MIPS16 && TARGET_64BIT"
+ "daddiu\\t%0,%1,%%lo(%2)"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "DI")])
+
+(define_insn "lowdi_extend"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (sign_extend:DI
+ (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "immediate_operand" ""))))]
+ "mips_split_addresses && !TARGET_MIPS16 && TARGET_64BIT"
+ "daddiu\\t%0,%1,%%lo(%2)"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "DI")])
+
;; 64-bit integer moves
;; Unlike most other insns, the move insns can't be split with
@@ -5151,21 +5149,12 @@ move\\t%0,%z4\\n\\
(define_expand "movdi"
[(set (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
+ (match_operand:DI 1 "" ""))]
""
"
{
- if (mips_split_addresses && mips_check_split (operands[1], DImode))
- {
- enum machine_mode mode = GET_MODE (operands[0]);
- rtx tem = ((reload_in_progress | reload_completed)
- ? operands[0] : gen_reg_rtx (mode));
-
- emit_insn (gen_rtx_SET (VOIDmode, tem,
- gen_rtx_HIGH (mode, operands[1])));
-
- operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
- }
+ if (mips_legitimize_move (DImode, operands[0], operands[1]))
+ DONE;
/* If we are generating embedded PIC code, and we are referring to a
symbol in the .text section, we must use an offset from the start
@@ -5183,73 +5172,6 @@ move\\t%0,%z4\\n\\
emit_move_insn (operands[0], force_reg (DImode, temp));
DONE;
}
-
- /* If operands[1] is a constant address illegal for pic, then we need to
- handle it just like LEGITIMIZE_ADDRESS does. */
- if (flag_pic && pic_address_needs_scratch (operands[1]))
- {
- rtx temp = force_reg (DImode, XEXP (XEXP (operands[1], 0), 0));
- rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
-
- if (! SMALL_INT (temp2))
- temp2 = force_reg (DImode, temp2);
-
- emit_move_insn (operands[0], gen_rtx_PLUS (DImode, temp, temp2));
- DONE;
- }
-
- /* On the mips16, we can handle a GP relative reference by adding in
- $gp. We need to check the name to see whether this is a string
- constant. */
- if (TARGET_MIPS16
- && register_operand (operands[0], DImode)
- && GET_CODE (operands[1]) == SYMBOL_REF
- && SYMBOL_REF_FLAG (operands[1]))
- {
- const char *name = XSTR (operands[1], 0);
-
- if (name[0] != '*'
- || strncmp (name + 1, LOCAL_LABEL_PREFIX,
- sizeof LOCAL_LABEL_PREFIX - 1) != 0)
- {
- rtx base_reg;
-
- if (reload_in_progress || reload_completed)
- {
- /* In movsi we use the constant table here. However, in
- this case, we're better off copying $28 into a
- register and adding, because the constant table entry
- would be 8 bytes. */
- base_reg = operands[0];
- emit_move_insn (base_reg,
- gen_rtx (CONST, DImode,
- gen_rtx (REG, DImode,
- GP_REG_FIRST + 28)));
- }
- else
- {
- base_reg = gen_reg_rtx (Pmode);
- emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
- }
-
- emit_move_insn (operands[0],
- gen_rtx (PLUS, Pmode, base_reg,
- mips16_gp_offset (operands[1])));
- DONE;
- }
- }
-
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], DImode)
- && !register_operand (operands[1], DImode)
- && (TARGET_MIPS16
- || ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)
- && operands[1] != CONST0_RTX (DImode))))
- {
- rtx temp = force_reg (DImode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
}")
;; For mips16, we need a special case to handle storing $31 into
@@ -5257,7 +5179,7 @@ move\\t%0,%z4\\n\\
;; instruction can be generated by save_restore_insns.
(define_insn ""
- [(set (match_operand:DI 0 "memory_operand" "=R,m")
+ [(set (match_operand:DI 0 "memory_operand" "=m")
(reg:DI 31))]
"TARGET_MIPS16 && TARGET_64BIT"
"*
@@ -5266,32 +5188,31 @@ move\\t%0,%z4\\n\\
return mips_move_2words (operands, insn);
}"
[(set_attr "type" "store")
- (set_attr "mode" "DI")
- (set_attr "length" "4,8")])
+ (set_attr "mode" "DI")])
(define_insn "movdi_internal"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,R,o,*x,*d,*x,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
- (match_operand:DI 1 "general_operand" "d,iF,R,o,d,d,J,*x,*d,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*x,*d,*x,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "general_operand" "d,iF,m,d,J,*x,*d,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
|| operands[1] == CONST0_RTX (DImode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,arith,load,load,store,store,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
+ [(set_attr "type" "move,arith,load,store,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "8,16,8,16,8,16,8,8,8,8,8,8,8,8,8")])
+ (set_attr "length" "8,16,*,*,8,8,8,8,*,8,*")])
(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,To,*d")
- (match_operand:DI 1 "general_operand" "d,d,y,K,N,R,To,d,d,*x"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
+ (match_operand:DI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
"!TARGET_64BIT && TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"* return mips_move_2words (operands, insn);"
- [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
+ [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
(set_attr "mode" "DI")
- (set_attr "length" "8,8,8,8,12,8,16,8,16,8")])
+ (set_attr "length" "8,8,8,8,12,*,*,8")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@@ -5306,17 +5227,17 @@ move\\t%0,%z4\\n\\
"")
(define_insn "movdi_internal2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,*f,*d,*R,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
- (match_operand:DI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*f,*d,*m,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "move_operand" "d,R,m,dJ,*f,*d*J,*m,*f,*f,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D"))]
"TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
|| operands[1] == CONST0_RTX (DImode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
+ [(set_attr "type" "move,const,load,store,move,xfer,load,xfer,store,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,8,8,8,8,8,8,8")])
+ (set_attr "length" "4,*,*,*,4,4,*,4,*,4,4,4,8,8,*,8,*")])
;; Sign-extended operands are reloaded using this instruction, so the
;; constraints must handle every SImode source operand X and destination
@@ -5331,26 +5252,26 @@ move\\t%0,%z4\\n\\
;; The main difference is that dJ -> f and f -> d are the only constraints
;; involving float registers. See mips_secondary_reload_class for details.
(define_insn "*movdi_internal2_extend"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*d,*f,*x,*d,*x,*a,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
- (sign_extend:DI (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*J,*x,*d,*J,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D")))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f,*x,*d,*x,*a,*B*C*D,*B*C*D,*d,*m")
+ (sign_extend:DI (match_operand:SI 1 "move_operand" "d,R,m,dJ,*f,*d*J,*J,*x,*d,*J,*d,*m,*B*C*D,*B*C*D")))]
"TARGET_64BIT
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0)
|| operands[1] == CONST0_RTX (DImode))"
"* return mips_sign_extend (insn, operands[0], operands[1]);"
- [(set_attr "type" "move,arith,arith,load,load,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
+ [(set_attr "type" "move,const,load,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "DI")
- (set_attr "length" "4,4,8,4,8,4,8,4,4,4,4,4,8,8,8,8,8,8,8")])
+ (set_attr "length" "4,*,*,*,4,4,4,4,4,8,8,*,8,*")])
(define_insn "*movdi_internal2_mips16"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d")
- (match_operand:DI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d")
+ (match_operand:DI 1 "move_operand" "d,d,y,K,N,R,m,d,*x"))]
"TARGET_64BIT && TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode))"
"* return mips_move_2words (operands, insn);"
- [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo")
+ [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo")
(set_attr "mode" "DI")
(set_attr_alternative "length"
[(const_int 4)
@@ -5362,13 +5283,9 @@ move\\t%0,%z4\\n\\
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
(const_int 8)
(const_int 12))
- (if_then_else (match_operand:VOID 1 "m16_usym5_4" "")
- (const_int 4)
- (const_int 8))
- (const_int 4)
- (const_int 8)
- (const_int 4)
- (const_int 8)
+ (const_string "*")
+ (const_string "*")
+ (const_string "*")
(const_int 4)])])
@@ -5580,44 +5497,18 @@ move\\t%0,%z4\\n\\
;; 32-bit Integer moves
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "large_int" ""))]
- "!TARGET_DEBUG_D_MODE && !TARGET_MIPS16"
- [(set (match_dup 0)
- (match_dup 2))
- (set (match_dup 0)
- (ior:SI (match_dup 0)
- (match_dup 3)))]
- "
-{
- operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1])
- & BITMASK_UPPER16,
- SImode));
- operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);
-}")
-
;; Unlike most other insns, the move insns can't be split with
;; different predicates, because register spilling and other parts of
;; the compiler, have memoized the insn number already.
(define_expand "movsi"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
+ (match_operand:SI 1 "" ""))]
""
"
{
- if (mips_split_addresses && mips_check_split (operands[1], SImode))
- {
- enum machine_mode mode = GET_MODE (operands[0]);
- rtx tem = ((reload_in_progress | reload_completed)
- ? operands[0] : gen_reg_rtx (mode));
-
- emit_insn (gen_rtx_SET (VOIDmode, tem,
- gen_rtx_HIGH (mode, operands[1])));
-
- operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]);
- }
+ if (mips_legitimize_move (SImode, operands[0], operands[1]))
+ DONE;
/* If we are generating embedded PIC code, and we are referring to a
symbol in the .text section, we must use an offset from the start
@@ -5635,73 +5526,6 @@ move\\t%0,%z4\\n\\
emit_move_insn (operands[0], force_reg (SImode, temp));
DONE;
}
-
- /* If operands[1] is a constant address invalid for pic, then we need to
- handle it just like LEGITIMIZE_ADDRESS does. */
- if (flag_pic && pic_address_needs_scratch (operands[1]))
- {
- rtx temp = force_reg (SImode, XEXP (XEXP (operands[1], 0), 0));
- rtx temp2 = XEXP (XEXP (operands[1], 0), 1);
-
- if (! SMALL_INT (temp2))
- temp2 = force_reg (SImode, temp2);
-
- emit_move_insn (operands[0], gen_rtx_PLUS (SImode, temp, temp2));
- DONE;
- }
-
- /* On the mips16, we can handle a GP relative reference by adding in
- $gp. We need to check the name to see whether this is a string
- constant. */
- if (TARGET_MIPS16
- && register_operand (operands[0], SImode)
- && GET_CODE (operands[1]) == SYMBOL_REF
- && SYMBOL_REF_FLAG (operands[1]))
- {
- const char *name = XSTR (operands[1], 0);
-
- if (name[0] != '*'
- || strncmp (name + 1, LOCAL_LABEL_PREFIX,
- sizeof LOCAL_LABEL_PREFIX - 1) != 0)
- {
- rtx base_reg;
-
- if (reload_in_progress || reload_completed)
- {
- /* We need to reload this address. In this case we
- aren't going to have a chance to combine loading the
- address with the load or store. That means that we
- can either generate a 2 byte move followed by a 4
- byte addition, or a 2 byte load with a 4 byte entry
- in the constant table. Since the entry in the
- constant table might be shared, we're better off, on
- average, loading the address from the constant table. */
- emit_move_insn (operands[0],
- force_const_mem (SImode, operands[1]));
- DONE;
- }
-
- base_reg = gen_reg_rtx (Pmode);
- emit_move_insn (base_reg, mips16_gp_pseudo_reg ());
-
- emit_move_insn (operands[0],
- gen_rtx (PLUS, Pmode, base_reg,
- mips16_gp_offset (operands[1])));
- DONE;
- }
- }
-
- if ((reload_in_progress | reload_completed) == 0
- && !register_operand (operands[0], SImode)
- && !register_operand (operands[1], SImode)
- && (TARGET_MIPS16
- || GET_CODE (operands[1]) != CONST_INT
- || INTVAL (operands[1]) != 0))
- {
- rtx temp = force_reg (SImode, operands[1]);
- emit_move_insn (operands[0], temp);
- DONE;
- }
}")
;; We can only store $ra directly into a small sp offset. Should the
@@ -5728,40 +5552,25 @@ move\\t%0,%z4\\n\\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "movsi_internal"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,R,m,*f,*f,*f,?*f,*d,*R,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*B*C*D,*d,*m,*R")
- (match_operand:SI 1 "move_operand" "d,IKL,Mnis,R,m,dJ,dJ,*f,*d*J,*R,*m,*f,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*R,*B*C*D,*B*C*D,*B*C*D"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,m,*f,*f,*f,*d,*m,*d,*z,*x,*d,*x,*d,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:SI 1 "move_operand" "d,R,m,dJ,*f,*d*J,*m,*f,*f,*z,*d,J,*x,*d,*a,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,arith,arith,load,load,store,store,move,xfer,load,load,xfer,store,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,load,xfer,store,store")
+ [(set_attr "type" "move,const,load,store,move,xfer,load,xfer,store,xfer,xfer,hilo,hilo,hilo,hilo,xfer,load,xfer,store")
(set_attr "mode" "SI")
- (set_attr "length" "4,4,8,4,8,4,8,4,4,4,8,4,4,8,4,4,4,4,4,4,4,4,8,4,4,8")])
-
-;; This is the mips16 movsi instruction. We accept a small integer as
-;; the source if the destination is a GP memory reference. This is
-;; because we want the combine pass to turn adding a GP reference to a
-;; register into a direct GP reference, but the combine pass will pass
-;; in the source as a constant if it finds an equivalent one. If the
-;; instruction is recognized, reload will force the constant back out
-;; into a register.
+ (set_attr "length" "4,*,*,*,4,4,*,4,*,4,4,4,4,4,4,4,*,4,*")])
(define_insn ""
- [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,d,R,m,*d,*d")
- (match_operand:SI 1 "move_operand" "d,d,y,K,N,s,R,m,d,d,*x,*a"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,m,*d,*d")
+ (match_operand:SI 1 "move_operand" "d,d,y,K,N,R,m,d,*x,*a"))]
"TARGET_MIPS16
&& (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode)
- || (GET_CODE (operands[0]) == MEM
- && GET_CODE (XEXP (operands[0], 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST
- && mips16_gp_offset_p (XEXP (XEXP (operands[0], 0), 1))
- && GET_CODE (operands[1]) == CONST_INT
- && (SMALL_INT (operands[1])
- || SMALL_INT_UNSIGNED (operands[1]))))"
+ || register_operand (operands[1], SImode))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,move,move,arith,arith,arith,load,load,store,store,hilo,hilo")
+ [(set_attr "type" "move,move,move,arith,arith,const,load,store,hilo,hilo")
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(const_int 4)
@@ -5773,13 +5582,9 @@ move\\t%0,%z4\\n\\
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
(const_int 8)
(const_int 12))
- (if_then_else (match_operand:VOID 1 "m16_usym8_4" "")
- (const_int 4)
- (const_int 8))
- (const_int 4)
- (const_int 8)
- (const_int 4)
- (const_int 8)
+ (const_string "*")
+ (const_string "*")
+ (const_string "*")
(const_int 4)
(const_int 4)])])
@@ -6025,13 +5830,13 @@ move\\t%0,%z4\\n\\
;; between the general registers and the floating point registers.
(define_insn "movcc"
- [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*d,*R,*m,*d,*f,*f,*f,*f,*R,*m")
- (match_operand:CC 1 "general_operand" "z,*d,*R,*m,*d,*d,*f,*d,*f,*R,*m,*f,*f"))]
+ [(set (match_operand:CC 0 "nonimmediate_operand" "=d,*d,*d,*m,*d,*f,*f,*f,*m")
+ (match_operand:CC 1 "general_operand" "z,*d,*m,*d,*f,*d,*f,*m,*f"))]
"ISA_HAS_8CC && TARGET_HARD_FLOAT"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
+ [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
(set_attr "mode" "SI")
- (set_attr "length" "8,4,4,8,4,8,4,4,4,4,8,4,8")])
+ (set_attr "length" "8,4,*,*,4,4,4,*,*")])
;; Reload condition code registers. reload_incc and reload_outcc
;; both handle moves from arbitrary operands into condition code
@@ -6089,7 +5894,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT"
"lwxc1\\t%0,%1(%2)"
[(set_attr "type" "load")
- (set_attr "mode" "SF")])
+ (set_attr "mode" "SF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (match_operand:SF 0 "register_operand" "=f")
@@ -6098,7 +5904,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT"
"lwxc1\\t%0,%1(%2)"
[(set_attr "type" "load")
- (set_attr "mode" "SF")])
+ (set_attr "mode" "SF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -6107,7 +5914,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"ldxc1\\t%0,%1(%2)"
[(set_attr "type" "load")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (match_operand:DF 0 "register_operand" "=f")
@@ -6116,7 +5924,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"ldxc1\\t%0,%1(%2)"
[(set_attr "type" "load")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "d")
@@ -6125,7 +5934,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT"
"swxc1\\t%0,%1(%2)"
[(set_attr "type" "store")
- (set_attr "mode" "SF")])
+ (set_attr "mode" "SF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (mem:SF (plus:DI (match_operand:DI 1 "register_operand" "d")
@@ -6134,7 +5944,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT"
"swxc1\\t%0,%1(%2)"
[(set_attr "type" "store")
- (set_attr "mode" "SF")])
+ (set_attr "mode" "SF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "d")
@@ -6143,7 +5954,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"sdxc1\\t%0,%1(%2)"
[(set_attr "type" "store")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF")
+ (set_attr "length" "4")])
(define_insn ""
[(set (mem:DF (plus:DI (match_operand:DI 1 "register_operand" "d")
@@ -6152,7 +5964,8 @@ move\\t%0,%z4\\n\\
"ISA_HAS_FP4 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
"sdxc1\\t%0,%1(%2)"
[(set_attr "type" "store")
- (set_attr "mode" "DF")])
+ (set_attr "mode" "DF")
+ (set_attr "length" "4")])
;; 16-bit Integer moves
@@ -6184,25 +5997,25 @@ move\\t%0,%z4\\n\\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "movhi_internal"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
- (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d")
+ (match_operand:HI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
+ [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
(set_attr "mode" "HI")
- (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
+ (set_attr "length" "4,4,*,*,4,4,4,4,4")])
(define_insn ""
- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
- (match_operand:HI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
+ (match_operand:HI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
"TARGET_MIPS16
&& (register_operand (operands[0], HImode)
|| register_operand (operands[1], HImode))"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
+ [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
(set_attr "mode" "HI")
(set_attr_alternative "length"
[(const_int 4)
@@ -6214,10 +6027,8 @@ move\\t%0,%z4\\n\\
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
(const_int 8)
(const_int 12))
- (const_int 4)
- (const_int 8)
- (const_int 4)
- (const_int 8)
+ (const_string "*")
+ (const_string "*")
(const_int 4)])])
@@ -6294,25 +6105,25 @@ move\\t%0,%z4\\n\\
;; in FP registers (off by default, use -mdebugh to enable).
(define_insn "movqi_internal"
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*f*z,*f,*x,*d")
- (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*f*z,*d,*f,*d,*x"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,m,*d,*f*z,*f,*x,*d")
+ (match_operand:QI 1 "general_operand" "d,IK,m,dJ,*f*z,*d,*f,*d,*x"))]
"!TARGET_MIPS16
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode)
|| (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,hilo,hilo")
+ [(set_attr "type" "move,arith,load,store,xfer,xfer,move,hilo,hilo")
(set_attr "mode" "QI")
- (set_attr "length" "4,4,4,8,4,8,4,4,4,4,4")])
+ (set_attr "length" "4,4,*,*,4,4,4,4,4")])
(define_insn ""
- [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,d,R,m,*d")
- (match_operand:QI 1 "general_operand" "d,d,y,K,N,R,m,d,d,*x"))]
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
+ (match_operand:QI 1 "general_operand" "d,d,y,K,N,m,d,*x"))]
"TARGET_MIPS16
&& (register_operand (operands[0], QImode)
|| register_operand (operands[1], QImode))"
"* return mips_move_1word (operands, insn, TRUE);"
- [(set_attr "type" "move,move,move,arith,arith,load,load,store,store,hilo")
+ [(set_attr "type" "move,move,move,arith,arith,load,store,hilo")
(set_attr "mode" "QI")
(set_attr_alternative "length"
[(const_int 4)
@@ -6324,10 +6135,8 @@ move\\t%0,%z4\\n\\
(if_then_else (match_operand:VOID 1 "m16_nuimm8_1" "")
(const_int 8)
(const_int 12))
- (const_int 4)
- (const_int 8)
- (const_int 4)
- (const_int 8)
+ (const_string "*")
+ (const_string "*")
(const_int 4)])])
@@ -6377,37 +6186,37 @@ move\\t%0,%z4\\n\\
}")
(define_insn "movsf_internal1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,m,*f,*d,*d,*d,*d,*R,*m")
- (match_operand:SF 1 "general_operand" "f,G,R,m,fG,fG,*d,*f,*G*d,*R,*m,*d,*d"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
+ (match_operand:SF 1 "general_operand" "f,G,m,fG,*d,*f,*G*d,*m,*d"))]
"TARGET_HARD_FLOAT
&& (register_operand (operands[0], SFmode)
|| nonmemory_operand (operands[1], SFmode))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,xfer,load,load,store,store,xfer,xfer,move,load,load,store,store")
+ [(set_attr "type" "move,xfer,load,store,xfer,xfer,move,load,store")
(set_attr "mode" "SF")
- (set_attr "length" "4,4,4,8,4,8,4,4,4,4,8,4,8")])
+ (set_attr "length" "4,4,*,*,4,4,4,*,*")])
(define_insn "movsf_internal2"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,d,R,m")
- (match_operand:SF 1 "general_operand" " Gd,R,m,d,d"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=d,d,m")
+ (match_operand:SF 1 "general_operand" " Gd,m,d"))]
"TARGET_SOFT_FLOAT && !TARGET_MIPS16
&& (register_operand (operands[0], SFmode)
|| nonmemory_operand (operands[1], SFmode))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,load,load,store,store")
+ [(set_attr "type" "move,load,store")
(set_attr "mode" "SF")
- (set_attr "length" "4,4,8,4,8")])
+ (set_attr "length" "4,*,*")])
(define_insn ""
- [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,d,R,m")
- (match_operand:SF 1 "nonimmediate_operand" "d,d,y,R,m,d,d"))]
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=d,y,d,d,m")
+ (match_operand:SF 1 "nonimmediate_operand" "d,d,y,m,d"))]
"TARGET_MIPS16
&& (register_operand (operands[0], SFmode)
|| register_operand (operands[1], SFmode))"
"* return mips_move_1word (operands, insn, FALSE);"
- [(set_attr "type" "move,move,move,load,load,store,store")
+ [(set_attr "type" "move,move,move,load,store")
(set_attr "mode" "SF")
- (set_attr "length" "4,4,4,4,8,4,8")])
+ (set_attr "length" "4,4,4,*,*")])
;; 64-bit floating point moves
@@ -6424,51 +6233,49 @@ move\\t%0,%z4\\n\\
operands[1] = force_reg (DFmode, operands[1]);
}")
-(define_insn "movdf_internal1"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,To,*f,*d,*d,*d,*d,*R,*T")
- (match_operand:DF 1 "general_operand" "f,G,R,To,fG,fG,*d,*f,*d*G,*R,*T,*d,*d"))]
- "TARGET_HARD_FLOAT && !(TARGET_FLOAT64 && !TARGET_64BIT)
- && TARGET_DOUBLE_FLOAT
+(define_insn "movdf_internal1a"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
+ (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_64BIT
&& (register_operand (operands[0], DFmode)
|| nonmemory_operand (operands[1], DFmode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,move,load,load,store,store,xfer,xfer,move,load,load,store,store")
+ [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
(set_attr "mode" "DF")
- (set_attr "length" "4,8,8,16,8,16,8,8,8,8,16,8,16")])
+ (set_attr "length" "4,8,*,*,4,4,4,*,*")])
-(define_insn "movdf_internal1a"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,R,R,To,To,*d,*d,*To,*R,*d")
- (match_operand:DF 1 "general_operand" " f,To,f,G,f,G,*To,*R,*d,*d,*d"))]
- "TARGET_HARD_FLOAT && (TARGET_FLOAT64 && !TARGET_64BIT)
- && TARGET_DOUBLE_FLOAT
+(define_insn "movdf_internal1b"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,m,*f,*d,*d,*d,*m")
+ (match_operand:DF 1 "general_operand" "f,G,m,fG,*d,*f,*d*G,*m,*d"))]
+ "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_64BIT
&& (register_operand (operands[0], DFmode)
|| nonmemory_operand (operands[1], DFmode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,load,store,store,store,store,load,load,store,store,move")
+ [(set_attr "type" "move,move,load,store,xfer,xfer,move,load,store")
(set_attr "mode" "DF")
- (set_attr "length" "4,8,4,4,8,8,8,4,8,4,4")])
+ (set_attr "length" "4,8,*,*,8,8,8,*,*")])
(define_insn "movdf_internal2"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,d,R,To,d,f,f")
- (match_operand:DF 1 "general_operand" "dG,R,To,d,d,f,d,f"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,d,m,d,f,f")
+ (match_operand:DF 1 "general_operand" "dG,m,d,f,d,f"))]
"(TARGET_SOFT_FLOAT || TARGET_SINGLE_FLOAT) && !TARGET_MIPS16
&& (register_operand (operands[0], DFmode)
|| nonmemory_operand (operands[1], DFmode))"
"* return mips_move_2words (operands, insn); "
- [(set_attr "type" "move,load,load,store,store,xfer,load,move")
+ [(set_attr "type" "move,load,store,xfer,xfer,move")
(set_attr "mode" "DF")
- (set_attr "length" "8,8,16,8,16,8,8,4")])
+ (set_attr "length" "8,*,*,8,8,4")])
(define_insn ""
- [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,d,R,To")
- (match_operand:DF 1 "nonimmediate_operand" "d,d,y,R,To,d,d"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=d,y,d,d,m")
+ (match_operand:DF 1 "nonimmediate_operand" "d,d,y,m,d"))]
"TARGET_MIPS16
&& (register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
"* return mips_move_2words (operands, insn);"
- [(set_attr "type" "move,move,move,load,load,store,store")
+ [(set_attr "type" "move,move,move,load,store")
(set_attr "mode" "DF")
- (set_attr "length" "8,8,8,8,16,8,16")])
+ (set_attr "length" "8,8,8,*,*")])
(define_split
[(set (match_operand:DF 0 "register_operand" "")
@@ -6487,7 +6294,7 @@ move\\t%0,%z4\\n\\
(define_insn "loadgp"
[(set (reg:DI 28)
- (unspec_volatile:DI [(match_operand:DI 0 "address_operand" "")
+ (unspec_volatile:DI [(match_operand:DI 0 "immediate_operand" "")
(match_operand:DI 1 "register_operand" "")]
UNSPEC_LOADGP))
(clobber (reg:DI 1))]
@@ -6632,8 +6439,8 @@ move\\t%0,%z4\\n\\
(set_attr "length" "80")])
(define_insn "movstrsi_internal3"
- [(set (match_operand:BLK 0 "memory_operand" "=Ro") ;; destination
- (match_operand:BLK 1 "memory_operand" "Ro")) ;; source
+ [(set (match_operand:BLK 0 "memory_operand" "=m") ;; destination
+ (match_operand:BLK 1 "memory_operand" "m")) ;; source
(clobber (match_scratch:SI 4 "=&d")) ;; temp 1
(clobber (match_scratch:SI 5 "=&d")) ;; temp 2
(clobber (match_scratch:SI 6 "=&d")) ;; temp 3
@@ -7460,19 +7267,17 @@ move\\t%0,%z4\\n\\
;; not have and immediate). We recognize a shift of a load in order
;; to make it simple enough for combine to understand.
+;; ??? FIXME: turn into a define_insn_and_split
(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=d,d")
- (lshiftrt:SI (match_operand:SI 1 "memory_operand" "R,m")
- (match_operand:SI 2 "immediate_operand" "I,I")))]
- "TARGET_MIPS16"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
+ (match_operand:SI 2 "immediate_operand" "I")))]
+ "0 && TARGET_MIPS16"
"lw\\t%0,%1\;srl\\t%0,%2"
[(set_attr "type" "load")
(set_attr "mode" "SI")
(set_attr_alternative "length"
[(if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
- (const_int 8)
- (const_int 12))
- (if_then_else (match_operand:VOID 2 "m16_uimm3_b" "")
(const_int 12)
(const_int 16))])])
@@ -9704,21 +9509,22 @@ move\\t%0,%z4\\n\\
if (GET_MODE (operands[0]) != Pmode)
abort ();
- if (! flag_pic)
+ if (TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64))
{
- if (!(Pmode == DImode))
- emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
- else
- emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
- }
- else
- {
- if (!(Pmode == DImode))
- emit_jump_insn (gen_tablejump_internal3 (operands[0], operands[1]));
+ rtx temp;
+
+ temp = gen_reg_rtx (Pmode);
+ if (Pmode == SImode)
+ emit_insn (gen_cpaddsi (temp, operands[0]));
else
- emit_jump_insn (gen_tablejump_internal4 (operands[0], operands[1]));
+ emit_insn (gen_cpadddi (temp, operands[0]));
+ operands[0] = temp;
}
+ if (Pmode == SImode)
+ emit_jump_insn (gen_tablejump_internal1 (operands[0], operands[1]));
+ else
+ emit_jump_insn (gen_tablejump_internal2 (operands[0], operands[1]));
DONE;
}
}")
@@ -9727,7 +9533,7 @@ move\\t%0,%z4\\n\\
[(set (pc)
(match_operand:SI 0 "register_operand" "d"))
(use (label_ref (match_operand 1 "" "")))]
- "!(Pmode == DImode)"
+ "Pmode == SImode"
"%*j\\t%0"
[(set_attr "type" "jump")
(set_attr "mode" "none")])
@@ -9741,13 +9547,23 @@ move\\t%0,%z4\\n\\
[(set_attr "type" "jump")
(set_attr "mode" "none")])
-(define_expand "tablejump_internal3"
- [(parallel [(set (pc)
- (plus:SI (match_operand:SI 0 "register_operand" "d")
- (label_ref:SI (match_operand 1 "" ""))))
- (use (label_ref:SI (match_dup 1)))])]
- ""
- "")
+(define_insn "cpaddsi"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (plus:SI (match_operand:SI 1 "register_operand" "d")
+ (unspec [(const_int 0)] UNSPEC_CPADD)))]
+ "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
+ "addu\t%0,%1,%+"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")])
+
+(define_insn "cpadddi"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (plus:DI (match_operand:DI 1 "register_operand" "d")
+ (unspec [(const_int 0)] UNSPEC_CPADD)))]
+ "TARGET_ABICALLS && (mips_abi == ABI_32 || mips_abi == ABI_O64)"
+ "daddu\t%0,%1,%+"
+ [(set_attr "type" "arith")
+ (set_attr "mode" "DI")])
(define_expand "tablejump_mips161"
[(set (pc) (plus:SI (sign_extend:SI
@@ -9793,64 +9609,6 @@ move\\t%0,%z4\\n\\
}
}")
-;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
-;;; it is not valid. ??? With the USE, the condition tests may not be required
-;;; any longer.
-
-;;; ??? The length depends on the ABI. It is two for o32, and one for n32.
-;;; We just use the conservative number here.
-
-(define_insn ""
- [(set (pc)
- (plus:SI (match_operand:SI 0 "register_operand" "d")
- (label_ref:SI (match_operand 1 "" ""))))
- (use (label_ref:SI (match_dup 1)))]
- "!(Pmode == DImode) && next_active_insn (insn) != 0
- && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
- && PREV_INSN (next_active_insn (insn)) == operands[1]"
- "*
-{
- /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
- if (mips_abi == ABI_32 || mips_abi == ABI_O64
- || (mips_abi == ABI_N32 && TARGET_GAS))
- output_asm_insn (\".cpadd\\t%0\", operands);
- return \"%*j\\t%0\";
-}"
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_expand "tablejump_internal4"
- [(parallel [(set (pc)
- (plus:DI (match_operand:DI 0 "register_operand" "d")
- (label_ref:DI (match_operand 1 "" ""))))
- (use (label_ref:DI (match_dup 1)))])]
- ""
- "")
-
-;;; Make sure that this only matches the insn before ADDR_DIFF_VEC. Otherwise
-;;; it is not valid. ??? With the USE, the condition tests may not be required
-;;; any longer.
-
-(define_insn ""
- [(set (pc)
- (plus:DI (match_operand:DI 0 "register_operand" "d")
- (label_ref:DI (match_operand 1 "" ""))))
- (use (label_ref:DI (match_dup 1)))]
- "Pmode == DImode && next_active_insn (insn) != 0
- && GET_CODE (PATTERN (next_active_insn (insn))) == ADDR_DIFF_VEC
- && PREV_INSN (next_active_insn (insn)) == operands[1]"
- "*
-{
- /* .cpadd expands to add REG,REG,$gp when pic, and nothing when not pic. */
- if (TARGET_GAS && mips_abi == ABI_64)
- output_asm_insn (\".cpadd\\t%0\", operands);
- return \"%*j\\t%0\";
-}"
- [(set_attr "type" "jump")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
;; Implement a switch statement when generating embedded PIC code.
;; Switches are implemented by `tablejump' when not using -membedded-pic.
@@ -10141,471 +9899,67 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
;;
;; ....................
-;; calls.c now passes a third argument, make saber happy
-
(define_expand "call"
- [(parallel [(call (match_operand 0 "memory_operand" "m")
- (match_operand 1 "" "i"))
- (clobber (reg:SI 31))
+ [(parallel [(call (match_operand 0 "" "")
+ (match_operand 1 "" ""))
(use (match_operand 2 "" "")) ;; next_arg_reg
(use (match_operand 3 "" ""))])] ;; struct_value_size_rtx
""
- "
{
- rtx addr;
-
- if (operands[0]) /* eliminate unused code warnings */
- {
- addr = XEXP (operands[0], 0);
- if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
- || ! call_insn_operand (addr, VOIDmode))
- XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, addr);
-
- /* In order to pass small structures by value in registers
- compatibly with the MIPS compiler, we need to shift the value
- into the high part of the register. Function_arg has encoded
- a PARALLEL rtx, holding a vector of adjustments to be made
- as the next_arg_reg variable, so we split up the insns,
- and emit them separately. */
-
- if (operands[2] != (rtx)0 && GET_CODE (operands[2]) == PARALLEL)
- {
- rtvec adjust = XVEC (operands[2], 0);
- int num = GET_NUM_ELEM (adjust);
- int i;
-
- for (i = 0; i < num; i++)
- emit_insn (RTVEC_ELT (adjust, i));
- }
-
- if (TARGET_MIPS16
- && mips16_hard_float
- && operands[2] != 0
- && (int) GET_MODE (operands[2]) != 0)
- {
- if (build_mips16_call_stub (NULL_RTX, operands[0], operands[1],
- (int) GET_MODE (operands[2])))
- DONE;
- }
-
- emit_call_insn (gen_call_internal0 (operands[0], operands[1],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + 31)));
- DONE;
- }
-}")
+ mips_expand_call (0, XEXP (operands[0], 0), operands[1], operands[2]);
+ DONE;
+})
-(define_expand "call_internal0"
- [(parallel [(call (match_operand 0 "" "")
- (match_operand 1 "" ""))
- (clobber (match_operand:SI 2 "" ""))])]
+(define_insn "call_internal"
+ [(call (mem:SI (match_operand 0 "call_insn_operand" "c,S"))
+ (match_operand 1 "" "i,i"))
+ (clobber (reg:SI 31))]
""
- "")
-
-;; We need to recognize reg:SI 31 specially for the mips16, because we
-;; don't have a constraint letter for it.
-
-(define_insn ""
- [(call (mem (match_operand 0 "call_insn_operand" "ei"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=y"))]
- "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
- && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
- "%*jal\\t%0"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_internal1"
- [(call (mem (match_operand 0 "call_insn_operand" "ri"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
-{
- register rtx target = operands[0];
-
- if (GET_CODE (target) == CONST_INT)
- return \"%[li\\t%@,%0\\n\\t%*jal\\t%2,%@%]\";
- else if (CONSTANT_ADDRESS_P (target))
- return \"%*jal\\t%0\";
- else
- return \"%*jal\\t%2,%0\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")])
-
-(define_insn "call_internal2"
- [(call (mem (match_operand 0 "call_insn_operand" "ri"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
-{
- register rtx target = operands[0];
-
- if (GET_CODE (target) == CONST_INT)
- return \"li\\t%^,%0\\n\\tjal\\t%2,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%0\\n\\tjal\\t%2,%^\";
- else
- return \"dla\\t%^,%0\\n\\tjal\\t%2,%^\";
- }
- else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
- else
- return \"jal\\t%2,%0\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_internal3a"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "!TARGET_MIPS16
- && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
- "%*jal\\t%2,%0"
- [(set_attr "type" "call")
- (set_attr "mode" "none")])
-
-(define_insn "call_internal3b"
- [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "!TARGET_MIPS16
- && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
- "%*jal\\t%2,%0"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "1")])
-
-(define_insn "call_internal3c"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "e"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=y"))]
- "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
- && GET_CODE (operands[2]) == REG && REGNO (operands[2]) == 31"
- "%*jal\\t%2,%0"
+ "@
+ %*jalr\\t%0
+ %*jal\\t%0"
[(set_attr "type" "call")
(set_attr "mode" "none")])
-(define_insn "call_internal4a"
- [(call (mem:SI (match_operand:SI 0 "register_operand" "r"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
- "*
-{
- if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
- else
- return \"jal\\t%2,%0\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_internal4b"
- [(call (mem:DI (match_operand:DI 0 "register_operand" "r"))
- (match_operand 1 "" "i"))
- (clobber (match_operand:SI 2 "register_operand" "=d"))]
- "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
- "*
-{
- if (REGNO (operands[0]) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%0\\n\\tjal\\t%2,%^\";
- else
- return \"jal\\t%2,%0\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-;; calls.c now passes a fourth argument, make saber happy
-
(define_expand "call_value"
- [(parallel [(set (match_operand 0 "register_operand" "=df")
- (call (match_operand 1 "memory_operand" "m")
- (match_operand 2 "" "i")))
- (clobber (reg:SI 31))
- (use (match_operand 3 "" ""))])] ;; next_arg_reg
- ""
- "
-{
- rtx addr;
-
- if (operands[0]) /* eliminate unused code warning */
- {
- addr = XEXP (operands[1], 0);
- if ((GET_CODE (addr) != REG && (!CONSTANT_ADDRESS_P (addr) || TARGET_LONG_CALLS))
- || ! call_insn_operand (addr, VOIDmode))
- XEXP (operands[1], 0) = copy_to_mode_reg (Pmode, addr);
-
- /* In order to pass small structures by value in registers
- compatibly with the MIPS compiler, we need to shift the value
- into the high part of the register. Function_arg has encoded
- a PARALLEL rtx, holding a vector of adjustments to be made
- as the next_arg_reg variable, so we split up the insns,
- and emit them separately. */
-
- if (operands[3] != (rtx)0 && GET_CODE (operands[3]) == PARALLEL)
- {
- rtvec adjust = XVEC (operands[3], 0);
- int num = GET_NUM_ELEM (adjust);
- int i;
-
- for (i = 0; i < num; i++)
- emit_insn (RTVEC_ELT (adjust, i));
- }
-
- if (TARGET_MIPS16
- && mips16_hard_float
- && ((operands[3] != 0
- && (int) GET_MODE (operands[3]) != 0)
- || GET_MODE_CLASS (GET_MODE (operands[0])) == MODE_FLOAT))
- {
- if (build_mips16_call_stub (operands[0], operands[1], operands[2],
- (operands[3] == 0 ? 0
- : (int) GET_MODE (operands[3]))))
- DONE;
- }
-
- /* Handle Irix6 function calls that have multiple non-contiguous
- results. */
- if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) > 1)
- {
- emit_call_insn (gen_call_value_multiple_internal0
- (XEXP (XVECEXP (operands[0], 0, 0), 0),
- operands[1], operands[2],
- XEXP (XVECEXP (operands[0], 0, 1), 0),
- gen_rtx_REG (SImode, GP_REG_FIRST + 31)));
- DONE;
- }
-
- /* We have a call returning a DImode structure in an FP reg.
- Strip off the now unnecessary PARALLEL. */
- if (GET_CODE (operands[0]) == PARALLEL)
- operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0);
-
- emit_call_insn (gen_call_value_internal0 (operands[0], operands[1], operands[2],
- gen_rtx_REG (SImode,
- GP_REG_FIRST + 31)));
-
- DONE;
- }
-}")
-
-(define_expand "call_value_internal0"
[(parallel [(set (match_operand 0 "" "")
(call (match_operand 1 "" "")
(match_operand 2 "" "")))
- (clobber (match_operand:SI 3 "" ""))])]
+ (use (match_operand 3 "" ""))])] ;; next_arg_reg
""
- "")
-
-;; Recognize $31 specially on the mips16, because we don't have a
-;; constraint letter for it.
-
-(define_insn ""
- [(set (match_operand 0 "register_operand" "=d")
- (call (mem (match_operand 1 "call_insn_operand" "ei"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=y"))]
- "TARGET_MIPS16 && !TARGET_ABICALLS && !TARGET_LONG_CALLS
- && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
- "%*jal\\t%1"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_value_internal1"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem (match_operand 1 "call_insn_operand" "ri"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
-{
- register rtx target = operands[1];
-
- if (GET_CODE (target) == CONST_INT)
- return \"%[li\\t%@,%1\\n\\t%*jal\\t%3,%@%]\";
- else if (CONSTANT_ADDRESS_P (target))
- return \"%*jal\\t%1\";
- else
- return \"%*jal\\t%3,%1\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")])
-
-(define_insn "call_value_internal2"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem (match_operand 1 "call_insn_operand" "ri"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
{
- register rtx target = operands[1];
-
- if (GET_CODE (target) == CONST_INT)
- return \"li\\t%^,%1\\n\\tjal\\t%3,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%1\\n\\tjal\\t%3,%^\";
- else
- return \"dla\\t%^,%1\\n\\tjal\\t%3,%^\";
- }
- else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
- else
- return \"jal\\t%3,%1\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_value_internal3a"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "!TARGET_MIPS16
- && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS"
- "%*jal\\t%3,%1"
- [(set_attr "type" "call")
- (set_attr "mode" "none")])
-
-(define_insn "call_value_internal3b"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "!TARGET_MIPS16
- && Pmode == DImode && !TARGET_ABICALLS && TARGET_LONG_CALLS"
- "%*jal\\t%3,%1"
- [(set_attr "type" "call")
- (set_attr "mode" "none")])
+ mips_expand_call (operands[0], XEXP (operands[1], 0),
+ operands[2], operands[3]);
+ DONE;
+})
-(define_insn "call_value_internal3c"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:SI (match_operand:SI 1 "register_operand" "e"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=y"))]
- "TARGET_MIPS16 && !(Pmode == DImode) && !TARGET_ABICALLS && TARGET_LONG_CALLS
- && GET_CODE (operands[3]) == REG && REGNO (operands[3]) == 31"
- "%*jal\\t%3,%1"
+(define_insn "call_value_internal"
+ [(set (match_operand 0 "register_operand" "=df,df")
+ (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
+ (match_operand 2 "" "i,i")))
+ (clobber (reg:SI 31))]
+ ""
+ "@
+ %*jalr\\t%1
+ %*jal\\t%1"
[(set_attr "type" "call")
(set_attr "mode" "none")])
-(define_insn "call_value_internal4a"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:SI (match_operand:SI 1 "register_operand" "r"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "!(Pmode == DImode) && TARGET_ABICALLS && TARGET_LONG_CALLS"
- "*
-{
- if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
- else
- return \"jal\\t%3,%1\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_insn "call_value_internal4b"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem:DI (match_operand:DI 1 "register_operand" "r"))
- (match_operand 2 "" "i")))
- (clobber (match_operand:SI 3 "register_operand" "=d"))]
- "Pmode == DImode && TARGET_ABICALLS && TARGET_LONG_CALLS"
- "*
-{
- if (REGNO (operands[1]) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%1\\n\\tjal\\t%3,%^\";
- else
- return \"jal\\t%3,%1\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-(define_expand "call_value_multiple_internal0"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand 1 "" "")
- (match_operand 2 "" "")))
- (set (match_operand 3 "" "")
- (call (match_dup 1)
- (match_dup 2)))
- (clobber (match_operand:SI 4 "" ""))])]
+(define_insn "call_value_multiple_internal"
+ [(set (match_operand 0 "register_operand" "=df,df")
+ (call (mem:SI (match_operand 1 "call_insn_operand" "c,S"))
+ (match_operand 2 "" "i,i")))
+ (set (match_operand 3 "register_operand" "=df,df")
+ (call (mem:SI (match_dup 1))
+ (match_dup 2)))
+ (clobber (reg:SI 31))]
""
- "")
-
-;; ??? May eventually need all 6 versions of the call patterns with multiple
-;; return values.
-
-(define_insn "call_value_multiple_internal1"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem (match_operand 1 "call_insn_operand" "ri"))
- (match_operand 2 "" "i")))
- (set (match_operand 3 "register_operand" "=df")
- (call (mem (match_dup 1))
- (match_dup 2)))
- (clobber (match_operand:SI 4 "register_operand" "=d"))]
- "!TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
-{
- register rtx target = operands[1];
-
- if (GET_CODE (target) == CONST_INT)
- return \"%[li\\t%@,%1\\n\\t%*jal\\t%4,%@%]\";
- else if (CONSTANT_ADDRESS_P (target))
- return \"%*jal\\t%1\";
- else
- return \"%*jal\\t%4,%1\";
-}"
+ "@
+ %*jalr\\t%1
+ %*jal\\t%1"
[(set_attr "type" "call")
(set_attr "mode" "none")])
-(define_insn "call_value_multiple_internal2"
- [(set (match_operand 0 "register_operand" "=df")
- (call (mem (match_operand 1 "call_insn_operand" "ri"))
- (match_operand 2 "" "i")))
- (set (match_operand 3 "register_operand" "=df")
- (call (mem (match_dup 1))
- (match_dup 2)))
- (clobber (match_operand:SI 4 "register_operand" "=d"))]
- "TARGET_ABICALLS && !TARGET_LONG_CALLS"
- "*
-{
- register rtx target = operands[1];
-
- if (GET_CODE (target) == CONST_INT)
- return \"li\\t%^,%1\\n\\tjal\\t%4,%^\";
- else if (CONSTANT_ADDRESS_P (target))
- {
- if (GET_MODE (target) == SImode)
- return \"la\\t%^,%1\\n\\tjal\\t%4,%^\";
- else
- return \"dla\\t%^,%1\\n\\tjal\\t%4,%^\";
- }
- else if (REGNO (target) != PIC_FUNCTION_ADDR_REGNUM)
- return \"move\\t%^,%1\\n\\tjal\\t%4,%^\";
- else
- return \"jal\\t%4,%1\";
-}"
- [(set_attr "type" "call")
- (set_attr "mode" "none")
- (set_attr "length" "8")])
-
-
;; Call subroutine returning any type.
(define_expand "untyped_call"
@@ -10616,21 +9970,18 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
""
"
{
- if (operands[0]) /* silence statement not reached warnings */
- {
- int i;
+ int i;
- emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
+ emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
- for (i = 0; i < XVECLEN (operands[2], 0); i++)
- {
- rtx set = XVECEXP (operands[2], 0, i);
- emit_move_insn (SET_DEST (set), SET_SRC (set));
- }
-
- emit_insn (gen_blockage ());
- DONE;
+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
+ {
+ rtx set = XVECEXP (operands[2], 0, i);
+ emit_move_insn (SET_DEST (set), SET_SRC (set));
}
+
+ emit_insn (gen_blockage ());
+ DONE;
}")
;;
@@ -10647,10 +9998,10 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(match_operand 1 "const_int_operand" "")
(match_operand 2 "const_int_operand" ""))]
"ISA_HAS_PREFETCH"
-"{
- if (symbolic_operand (operands[0], GET_MODE (operands[0])))
- operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
-}")
+{
+ if (symbolic_operand (operands[0], GET_MODE (operands[0])))
+ operands[0] = force_reg (GET_MODE (operands[0]), operands[0]);
+})
(define_insn "prefetch_si_address"
[(prefetch (plus:SI (match_operand:SI 0 "register_operand" "r")
@@ -10659,7 +10010,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(match_operand:SI 2 "const_int_operand" "n"))]
"ISA_HAS_PREFETCH && Pmode == SImode"
"* return mips_emit_prefetch (operands);"
- [(set_attr "type" "load")])
+ [(set_attr "type" "prefetch")])
(define_insn "prefetch_si"
[(prefetch (match_operand:SI 0 "register_operand" "r")
@@ -10667,7 +10018,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(match_operand:SI 2 "const_int_operand" "n"))]
"ISA_HAS_PREFETCH && Pmode == SImode"
"* return mips_emit_prefetch (operands);"
- [(set_attr "type" "load")])
+ [(set_attr "type" "prefetch")])
(define_insn "prefetch_di_address"
[(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
@@ -10676,7 +10027,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(match_operand:DI 2 "const_int_operand" "n"))]
"ISA_HAS_PREFETCH && Pmode == DImode"
"* return mips_emit_prefetch (operands);"
- [(set_attr "type" "load")])
+ [(set_attr "type" "prefetch")])
(define_insn "prefetch_di"
[(prefetch (match_operand:DI 0 "register_operand" "r")
@@ -10684,7 +10035,7 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(match_operand:DI 2 "const_int_operand" "n"))]
"ISA_HAS_PREFETCH && Pmode == DImode"
"* return mips_emit_prefetch (operands);"
- [(set_attr "type" "load")])
+ [(set_attr "type" "prefetch")])
(define_insn "nop"
[(const_int 0)]
@@ -11189,26 +10540,6 @@ ld\\t%2,%1-%S1(%2)\;daddu\\t%2,%2,$31\\n\\t%*j\\t%2"
(set_attr "mode" "none")
(set_attr "length" "8")])
-;; For the rare case where we need to load an address into a register
-;; that can not be recognized by the normal movsi/addsi instructions.
-;; I have no idea how many insns this can actually generate. It should
-;; be rare, so over-estimating as 10 instructions should not have any
-;; real performance impact.
-(define_insn "leasi"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (match_operand:SI 1 "address_operand" "p"))]
- "Pmode == SImode"
- "la %0,%a1"
- [(set_attr "type" "arith")
- (set_attr "mode" "SI")
- (set_attr "length" "40")])
-
-;; Similarly for targets where we have 64bit pointers.
-(define_insn "leadi"
- [(set (match_operand:DI 0 "register_operand" "=d")
- (match_operand:DI 1 "address_operand" "p"))]
- "Pmode == DImode"
- "la %0,%a1"
- [(set_attr "type" "arith")
- (set_attr "mode" "DI")
- (set_attr "length" "40")])
+(define_expand "reloc_gprel16"
+ [(const (unspec [(match_operand:SI 0 "" "")] UNSPEC_RELOC_GPREL16))]
+ "" "")