diff options
Diffstat (limited to 'gcc/config/mips/mips.md')
-rw-r--r-- | gcc/config/mips/mips.md | 109 |
1 files changed, 91 insertions, 18 deletions
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 7aa461d..bbcc5c9 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -342,13 +342,14 @@ ;; syncloop memory atomic operation implemented as a sync loop ;; nop no operation ;; ghost an instruction that produces no real code +;; multimem microMIPS multiword load and store (define_attr "type" "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore, prefetch,prefetchx,condmove,mtc,mfc,mthi,mtlo,mfhi,mflo,const,arith,logical, shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move, fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt, frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat, - multi,atomic,syncloop,nop,ghost" + multi,atomic,syncloop,nop,ghost,multimem" (cond [(eq_attr "jal" "!unset") (const_string "call") (eq_attr "got" "load") (const_string "load") @@ -413,9 +414,15 @@ ;; Length of instruction in bytes. (define_attr "length" "" - (cond [;; Direct branch instructions have a range of [-0x20000,0x1fffc], - ;; relative to the address of the delay slot. If a branch is - ;; outside this range, we have a choice of two sequences. + (cond [(and (eq_attr "extended_mips16" "yes") + (match_test "TARGET_MIPS16")) + (const_int 8) + + ;; Direct microMIPS branch instructions have a range of + ;; [-0x10000,0xfffe], otherwise the range is [-0x20000,0x1fffc]. + ;; If a branch is outside this range, we have a choice of two + ;; sequences. + ;; ;; For PIC, an out-of-range branch like: ;; ;; bne r1,r2,target @@ -451,8 +458,15 @@ ;; from the shorten_branches reference address. (and (eq_attr "type" "branch") (not (match_test "TARGET_MIPS16"))) - (cond [(and (le (minus (match_dup 0) (pc)) (const_int 131064)) - (le (minus (pc) (match_dup 0)) (const_int 131068))) + (cond [;; Any variant can handle the 17-bit range. + (and (le (minus (match_dup 0) (pc)) (const_int 65532)) + (le (minus (pc) (match_dup 0)) (const_int 65534))) + (const_int 4) + + ;; The 18-bit range is OK other than for microMIPS. + (and (not (match_test "TARGET_MICROMIPS")) + (and (le (minus (match_dup 0) (pc)) (const_int 131064)) + (le (minus (pc) (match_dup 0)) (const_int 131068)))) (const_int 4) ;; The non-PIC case: branch, first delay slot, and J. @@ -712,6 +726,9 @@ ;; modes. (define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")]) +(define_mode_iterator MOVEP1 [SI SF]) +(define_mode_iterator MOVEP2 [SI SF]) + ;; This mode iterator allows :HILO to be used as the mode of the ;; concatenated HI and LO registers. (define_mode_iterator HILO [(DI "!TARGET_64BIT") (TI "TARGET_64BIT")]) @@ -3937,7 +3954,7 @@ (define_insn "mov_<load>l" [(set (match_operand:GPR 0 "register_operand" "=d") (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") - (match_operand:QI 2 "memory_operand" "m")] + (match_operand:QI 2 "memory_operand" "ZC")] UNSPEC_LOAD_LEFT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" "<load>l\t%0,%2" @@ -3947,7 +3964,7 @@ (define_insn "mov_<load>r" [(set (match_operand:GPR 0 "register_operand" "=d") (unspec:GPR [(match_operand:BLK 1 "memory_operand" "m") - (match_operand:QI 2 "memory_operand" "m") + (match_operand:QI 2 "memory_operand" "ZC") (match_operand:GPR 3 "register_operand" "0")] UNSPEC_LOAD_RIGHT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[1])" @@ -3958,7 +3975,7 @@ (define_insn "mov_<store>l" [(set (match_operand:BLK 0 "memory_operand" "=m") (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") - (match_operand:QI 2 "memory_operand" "m")] + (match_operand:QI 2 "memory_operand" "ZC")] UNSPEC_STORE_LEFT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" "<store>l\t%z1,%2" @@ -3968,7 +3985,7 @@ (define_insn "mov_<store>r" [(set (match_operand:BLK 0 "memory_operand" "+m") (unspec:BLK [(match_operand:GPR 1 "reg_or_0_operand" "dJ") - (match_operand:QI 2 "memory_operand" "m") + (match_operand:QI 2 "memory_operand" "ZC") (match_dup 0)] UNSPEC_STORE_RIGHT))] "!TARGET_MIPS16 && mips_mem_fits_mode_p (<MODE>mode, operands[0])" @@ -5447,6 +5464,14 @@ (pc)))] "!TARGET_MIPS16" { + /* For a simple BNEZ or BEQZ microMIPS branch. */ + if (TARGET_MICROMIPS + && operands[3] == const0_rtx + && get_attr_length (insn) <= 8) + return mips_output_conditional_branch (insn, operands, + "%*b%C1z%:\t%2,%0", + "%*b%N1z%:\t%2,%0"); + return mips_output_conditional_branch (insn, operands, MIPS_BRANCH ("b%C1", "%2,%z3,%0"), MIPS_BRANCH ("b%N1", "%2,%z3,%0")); @@ -5463,6 +5488,14 @@ (label_ref (match_operand 0 "" ""))))] "!TARGET_MIPS16" { + /* For a simple BNEZ or BEQZ microMIPS branch. */ + if (TARGET_MICROMIPS + && operands[3] == const0_rtx + && get_attr_length (insn) <= 8) + return mips_output_conditional_branch (insn, operands, + "%*b%N0z%:\t%2,%1", + "%*b%C0z%:\t%2,%1"); + return mips_output_conditional_branch (insn, operands, MIPS_BRANCH ("b%N1", "%2,%z3,%0"), MIPS_BRANCH ("b%C1", "%2,%z3,%0")); @@ -5766,7 +5799,14 @@ [(set (pc) (label_ref (match_operand 0)))] "!TARGET_MIPS16 && TARGET_ABSOLUTE_JUMPS" - { return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); } +{ + /* Use a branch for microMIPS. The assembler will choose + a 16-bit branch, a 32-bit branch, or a 32-bit jump. */ + if (TARGET_MICROMIPS && !TARGET_ABICALLS_PIC2) + return "%*b\t%l0%/"; + else + return MIPS_ABSOLUTE_JUMP ("%*j\t%l0%/"); +} [(set_attr "type" "jump")]) (define_insn "*jump_pic" @@ -5829,7 +5869,12 @@ (define_insn "indirect_jump_<mode>" [(set (pc) (match_operand:P 0 "register_operand" "d"))] "" - "%*j\t%0%/" +{ + if (TARGET_MICROMIPS) + return "%*jr%:\t%0"; + else + return "%*j\t%0%/"; +} [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -5873,7 +5918,12 @@ (match_operand:P 0 "register_operand" "d")) (use (label_ref (match_operand 1 "" "")))] "" - "%*j\t%0%/" +{ + if (TARGET_MICROMIPS) + return "%*jr%:\t%0"; + else + return "%*j\t%0%/"; +} [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6094,7 +6144,12 @@ [(any_return) (use (match_operand 0 "pmode_register_operand" ""))] "" - "%*j\t%0%/" +{ + if (TARGET_MICROMIPS) + return "%*jr%:\t%0"; + else + return "%*j\t%0%/"; +} [(set_attr "type" "jump") (set_attr "mode" "none")]) @@ -6350,7 +6405,12 @@ [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S")) (match_operand 1 "" ""))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" - { return MIPS_CALL ("j", operands, 0, 1); } +{ + if (TARGET_MICROMIPS) + return MICROMIPS_J ("j", operands, 0); + else + return MIPS_CALL ("j", operands, 0, 1); +} [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6371,7 +6431,12 @@ (call (mem:SI (match_operand 1 "call_insn_operand" "j,S")) (match_operand 2 "" "")))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" - { return MIPS_CALL ("j", operands, 1, 2); } +{ + if (TARGET_MICROMIPS) + return MICROMIPS_J ("j", operands, 1); + else + return MIPS_CALL ("j", operands, 1, 2); +} [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6383,7 +6448,12 @@ (call (mem:SI (match_dup 1)) (match_dup 2)))] "TARGET_SIBCALLS && SIBLING_CALL_P (insn)" - { return MIPS_CALL ("j", operands, 1, 2); } +{ + if (TARGET_MICROMIPS) + return MICROMIPS_J ("j", operands, 1); + else + return MIPS_CALL ("j", operands, 1, 2); +} [(set_attr "jal" "indirect,direct") (set_attr "jal_macro" "no")]) @@ -6629,7 +6699,7 @@ (define_insn "prefetch" - [(prefetch (match_operand:QI 0 "address_operand" "p") + [(prefetch (match_operand:QI 0 "address_operand" "ZD") (match_operand 1 "const_int_operand" "n") (match_operand 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS" @@ -6922,6 +6992,9 @@ ; MIPS fixed-point instructions. (include "mips-fixed.md") +; microMIPS patterns. +(include "micromips.md") + ; ST-Microelectronics Loongson-2E/2F-specific patterns. (include "loongson.md") |