diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1992-06-12 14:33:54 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1992-06-12 14:33:54 +0000 |
commit | 65437fe868f007fdc51f5477dabdee2947a89b46 (patch) | |
tree | b2f41f171ced38e8623ed4983e95f57dc64a7f86 | |
parent | 45b33951a8562a13054992d3a2cfb9c42fb121af (diff) | |
download | gcc-65437fe868f007fdc51f5477dabdee2947a89b46.zip gcc-65437fe868f007fdc51f5477dabdee2947a89b46.tar.gz gcc-65437fe868f007fdc51f5477dabdee2947a89b46.tar.bz2 |
Make logical ops use a clobbered register instead of $1
From-SVN: r1195
-rw-r--r-- | gcc/config/mips/mips.c | 84 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 47 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 272 | ||||
-rw-r--r-- | gcc/config/mips/x-mips | 8 | ||||
-rw-r--r-- | gcc/config/mips/x-sysv | 8 | ||||
-rw-r--r-- | gcc/config/mips/x-ultrix | 8 |
6 files changed, 346 insertions, 81 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index c69abaa..08a6129 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -438,6 +438,23 @@ large_int (op, mode) return TRUE; } +/* Return truth value of whether OP is an integer which can be loaded + with an lui instruction. */ + +int +lui_int (op, mode) + rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) != CONST_INT) + return FALSE; + + if ((INTVAL (op) & 0x0000ffff) == 0) /* lui reg,value>>16 */ + return TRUE; + + return FALSE; +} + /* Return truth value of whether OP is a register or the constant 0. */ int @@ -1049,12 +1066,7 @@ mips_move_1word (operands, insn, unsignedp) } else if (GP_REG_P (regno0)) - { - if ((INTVAL (operands[1]) & 0x0000ffff) == 0) - ret = "lui\t%0,(%X1)>>16"; - else - ret = "li\t%0,%1"; - } + ret = "li\t%0,%X1\t\t# %1"; } else if (code1 == CONST_DOUBLE && mode == SFmode) @@ -3551,6 +3563,65 @@ mips_output_lineno (stream, line) } +/* If defined, a C statement to be executed just prior to the + output of assembler code for INSN, to modify the extracted + operands so they will be output differently. + + Here the argument OPVEC is the vector containing the operands + extracted from INSN, and NOPERANDS is the number of elements of + the vector which contain meaningful data for this insn. The + contents of this vector are what will be used to convert the + insn template into assembler code, so you can change the + assembler output by changing the contents of the vector. + + We use it to check if the current insn needs a nop in front of it + because of load delays, and also to update the delay slot + statistics. */ + +void +final_prescan_insn (insn, opvec, noperands) + rtx insn; + rtx opvec[]; + int noperands; +{ + if (dslots_number_nops > 0) + { + enum machine_mode mode = GET_MODE (mips_load_reg); + rtx pattern = PATTERN (insn); + int length = get_attr_length (insn); + + /* Do we need to emit a NOP? */ + if (length == 0 + || (mips_load_reg != (rtx)0 && reg_mentioned_p (mips_load_reg, pattern)) + || (mips_load_reg2 != (rtx)0 && reg_mentioned_p (mips_load_reg2, pattern)) + || (mips_load_reg3 != (rtx)0 && reg_mentioned_p (mips_load_reg3, pattern)) + || (mips_load_reg4 != (rtx)0 && reg_mentioned_p (mips_load_reg4, pattern))) + fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); + + else + dslots_load_filled++; + + while (--dslots_number_nops > 0) + fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); + + mips_load_reg = (rtx)0; + mips_load_reg2 = (rtx)0; + mips_load_reg3 = (rtx)0; + mips_load_reg4 = (rtx)0; + + if (set_noreorder && --set_noreorder == 0) + fputs ("\t.set\treorder\n", asm_out_file); + } + + if (TARGET_STATS) + { + enum rtx_code code = GET_CODE (insn); + if (code == JUMP_INSN || code == CALL_INSN) + dslots_jump_total++; + } +} + + /* Output at beginning of assembler file. If we are optimizing to use the global pointer, create a temporary file to hold all of the text stuff, and write it out to the end. @@ -4373,4 +4444,3 @@ null_epilogue () return (compute_frame_size (get_frame_size ())) == 0; } - diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 87e2879..c0b0bef 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -125,6 +125,7 @@ extern unsigned long compute_frame_size (); extern void expand_block_move (); extern int equality_op (); extern int fcmp_op (); +extern void final_prescan_insn (); extern int fpsw_register_operand (); extern struct rtx_def * function_arg (); extern void function_arg_advance (); @@ -135,6 +136,7 @@ extern void gen_conditional_branch (); extern struct rtx_def * gen_int_relational (); extern void init_cumulative_args (); extern int large_int (); +extern int lui_int (); extern int md_register_operand (); extern int mips_address_cost (); extern void mips_asm_file_end (); @@ -428,7 +430,7 @@ while (0) /* Print subsidiary information on the compiler version in use. */ -#define MIPS_VERSION "[AL 1.1, MM 19]" +#define MIPS_VERSION "[AL 1.1, MM 20]" #ifndef MACHINE_TYPE #define MACHINE_TYPE "BSD Mips" @@ -2504,47 +2506,7 @@ while (0) statistics. */ #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ -do \ - { \ - if (dslots_number_nops > 0 && mips_load_reg != (rtx)0) \ - { \ - enum machine_mode mode = GET_MODE (mips_load_reg); \ - rtx pattern = PATTERN (INSN); \ - \ - if (reg_mentioned_p (mips_load_reg, pattern) \ - || (mips_load_reg2 != (rtx)0 \ - && reg_mentioned_p (mips_load_reg2, pattern)) \ - || (mips_load_reg3 != (rtx)0 \ - && reg_mentioned_p (mips_load_reg3, pattern)) \ - || (mips_load_reg4 != (rtx)0 \ - && reg_mentioned_p (mips_load_reg4, pattern)) \ - || get_attr_length (INSN) == 0) \ - { \ - fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); \ - } \ - else \ - dslots_load_filled++; \ - \ - while (--dslots_number_nops > 0) \ - fputs ((set_noreorder) ? "\tnop\n" : "\t#nop\n", asm_out_file); \ - \ - mips_load_reg = (rtx)0; \ - mips_load_reg2 = (rtx)0; \ - mips_load_reg3 = (rtx)0; \ - mips_load_reg4 = (rtx)0; \ - \ - if (set_noreorder && --set_noreorder == 0) \ - fputs ("\t.set\treorder\n", asm_out_file); \ - } \ - \ - if (TARGET_STATS) \ - { \ - enum rtx_code code = GET_CODE (INSN); \ - if (code == JUMP_INSN || code == CALL_INSN) \ - dslots_jump_total++; \ - } \ - } \ -while (0) + final_prescan_insn (INSN, OPVEC, NOPERANDS) /* Tell final.c how to eliminate redundant test instructions. @@ -3310,4 +3272,3 @@ while (0) #define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) #define MIPS_MARK_STAB(code) ((code)+CODE_MASK) #define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) - diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 00cae6d..730d624 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1153,20 +1153,98 @@ move\\t%0,%z4\\n\\ ;; the optimizer can fold things together, at the expense of not moving the ;; constant out of loops. -(define_insn "andsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d") - (and:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d") - (match_operand:SI 2 "arith32_operand" "d,K,I,M")))] +(define_expand "andsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (and:SI (match_operand:SI 1 "arith32_operand" "dKIM") + (match_operand:SI 2 "arith32_operand" "dKIM")))] + "" + " +{ + extern rtx gen_andsi3_internal2 (); + + /* Canonlicalize */ + if (GET_CODE (operands[1]) == CONST_INT) + { + rtx temp; + + if (GET_CODE (operands[2]) == CONST_INT) + { + emit_move_insn (operands[0], + gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) & INTVAL (operands[2]))); + DONE; + } + + temp = operands[1]; + operands[1] = operands[2]; + operands[2] = temp; + } + + if (GET_CODE (operands[2]) == CONST_INT && !SMALL_INT_UNSIGNED (operands[2])) + { + emit_insn (gen_andsi3_internal2 (operands[0], + operands[1], + operands[2], + gen_reg_rtx (SImode))); + DONE; + } +}") + +(define_insn "andsi3_internal1" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (and:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "uns_arith_operand" "d,K")))] + "" + "@ + and\\t%0,%1,%2 + andi\\t%0,%1,%x2" + [(set_attr "type" "arith") + (set_attr "mode" "SI") + (set_attr "length" "1")]) + +(define_insn "andsi3_internal2" + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (and:SI (match_operand:SI 1 "register_operand" "d,d,d,d") + (match_operand:SI 2 "arith32_operand" "d,K,I,M"))) + (clobber (match_operand:SI 3 "register_operand" "=d,d,d,d"))] "" "@ and\\t%0,%1,%2 andi\\t%0,%1,%x2 - %[li\\t%@,%X2\;and\\t%0,%1,%@%] - %[li\\t%@,%X2\;and\\t%0,%1,%@%]" + li\\t%3,%X2\\t\\t# %2\;and\\t%0,%1,%3 + li\\t%3,%X2\\t\\t# %2\;and\\t%0,%1,%3" [(set_attr "type" "arith,arith,multi,multi") (set_attr "mode" "SI") (set_attr "length" "1,1,2,3")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (and:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "lui_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))] + "") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (and:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "large_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 5))) + (set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))] + " +{ + int val = INTVAL (operands[2]); + operands[4] = gen_rtx (CONST_INT, VOIDmode, val & 0xffff0000); + operands[5] = gen_rtx (CONST_INT, VOIDmode, val & 0x0000ffff); +}") + (define_insn "anddi3" [(set (match_operand:DI 0 "register_operand" "=d") (and:DI (match_operand:DI 1 "register_operand" "d") @@ -1190,20 +1268,98 @@ move\\t%0,%z4\\n\\ (set (subreg:SI (match_dup 0) 1) (and:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] "") -(define_insn "iorsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d") - (ior:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d") - (match_operand:SI 2 "arith32_operand" "d,K,I,M")))] +(define_expand "iorsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (ior:SI (match_operand:SI 1 "arith32_operand" "dKIM") + (match_operand:SI 2 "arith32_operand" "dKIM")))] + "" + " +{ + extern rtx gen_iorsi3_internal2 (); + + /* Canonlicalize */ + if (GET_CODE (operands[1]) == CONST_INT) + { + rtx temp; + + if (GET_CODE (operands[2]) == CONST_INT) + { + emit_move_insn (operands[0], + gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) | INTVAL (operands[2]))); + DONE; + } + + temp = operands[1]; + operands[1] = operands[2]; + operands[2] = temp; + } + + if (GET_CODE (operands[2]) == CONST_INT && !SMALL_INT_UNSIGNED (operands[2])) + { + emit_insn (gen_iorsi3_internal2 (operands[0], + operands[1], + operands[2], + gen_reg_rtx (SImode))); + DONE; + } +}") + +(define_insn "iorsi3_internal1" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (ior:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "uns_arith_operand" "d,K")))] + "" + "@ + or\\t%0,%1,%2 + ori\\t%0,%1,%x2" + [(set_attr "type" "arith") + (set_attr "mode" "SI") + (set_attr "length" "1")]) + +(define_insn "iorsi3_internal2" + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (ior:SI (match_operand:SI 1 "register_operand" "d,d,d,d") + (match_operand:SI 2 "arith32_operand" "d,K,I,M"))) + (clobber (match_operand:SI 3 "register_operand" "=d,d,d,d"))] "" "@ or\\t%0,%1,%2 ori\\t%0,%1,%x2 - %[li\\t%@,%X2\;or\\t%0,%1,%@%] - %[li\\t%@,%X2\;or\\t%0,%1,%@%]" + li\\t%3,%X2\\t\\t# %2\;or\\t%0,%1,%3 + li\\t%3,%X2\\t\\t# %2\;or\\t%0,%1,%3" [(set_attr "type" "arith,arith,multi,multi") (set_attr "mode" "SI") (set_attr "length" "1,1,2,3")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (ior:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "lui_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))] + "") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (ior:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "large_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 5))) + (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))] + " +{ + int val = INTVAL (operands[2]); + operands[4] = gen_rtx (CONST_INT, VOIDmode, val & 0xffff0000); + operands[5] = gen_rtx (CONST_INT, VOIDmode, val & 0x0000ffff); +}") + (define_insn "iordi3" [(set (match_operand:DI 0 "register_operand" "=d") (ior:DI (match_operand:DI 1 "register_operand" "d") @@ -1227,20 +1383,99 @@ move\\t%0,%z4\\n\\ (set (subreg:SI (match_dup 0) 1) (ior:SI (subreg:SI (match_dup 1) 1) (subreg:SI (match_dup 2) 1)))] "") -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,?d,?d") - (xor:SI (match_operand:SI 1 "arith32_operand" "%d,d,d,d") - (match_operand:SI 2 "arith32_operand" "d,K,I,M")))] +(define_expand "xorsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (xor:SI (match_operand:SI 1 "arith32_operand" "dKIM") + (match_operand:SI 2 "arith32_operand" "dKIM")))] + "" + " +{ + extern rtx gen_xorsi3_internal2 (); + + /* Canonlicalize */ + if (GET_CODE (operands[1]) == CONST_INT) + { + rtx temp; + + if (GET_CODE (operands[2]) == CONST_INT) + { + emit_move_insn (operands[0], + gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[1]) ^ INTVAL (operands[2]))); + DONE; + } + + temp = operands[1]; + operands[1] = operands[2]; + operands[2] = temp; + } + + if (GET_CODE (operands[2]) == CONST_INT && !SMALL_INT_UNSIGNED (operands[2])) + { + emit_insn (gen_xorsi3_internal2 (operands[0], + operands[1], + operands[2], + gen_reg_rtx (SImode))); + DONE; + } +}") + +(define_insn "xorsi3_internal1" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (xor:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "uns_arith_operand" "d,K")))] + "" + "@ + xor\\t%0,%1,%2 + xori\\t%0,%1,%x2" + [(set_attr "type" "arith") + (set_attr "mode" "SI") + (set_attr "length" "1")]) + +(define_insn "xorsi3_internal2" + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (xor:SI (match_operand:SI 1 "register_operand" "d,d,d,d") + (match_operand:SI 2 "arith32_operand" "d,K,I,M"))) + (clobber (match_operand:SI 3 "register_operand" "=d,d,d,d"))] "" "@ xor\\t%0,%1,%2 xori\\t%0,%1,%x2 - %[li\\t%@,%X2\;xor\\t%0,%1,%@%] - %[li\\t%@,%X2\;xor\\t%0,%1,%@%]" + li\\t%3,%X2\\t\\t# %2\;xor\\t%0,%1,%3 + li\\t%3,%X2\\t\\t# %2\;xor\\t%0,%1,%3" [(set_attr "type" "arith,arith,multi,multi") (set_attr "mode" "SI") (set_attr "length" "1,1,2,3")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (xor:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "lui_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))] + "") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (xor:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "large_int" ""))) + (clobber (match_operand:SI 3 "register_operand" ""))] + "reload_completed && !TARGET_DEBUG_D_MODE" + + [(set (match_dup 3) (match_dup 4)) + (set (match_dup 3) (ior:SI (match_dup 3) (match_dup 5))) + (set (match_dup 0) (xor:SI (match_dup 1) (match_dup 3)))] + " +{ + int val = INTVAL (operands[2]); + operands[4] = gen_rtx (CONST_INT, VOIDmode, val & 0xffff0000); + operands[5] = gen_rtx (CONST_INT, VOIDmode, val & 0x0000ffff); +}") + + (define_insn "xordi3" [(set (match_operand:DI 0 "register_operand" "=d") (xor:DI (match_operand:DI 1 "register_operand" "d") @@ -3993,4 +4228,3 @@ move\\t%0,%z4\\n\\ ;; eval: (modify-syntax-entry ?{ "(}") ;; eval: (modify-syntax-entry ?} "){") ;; End: - diff --git a/gcc/config/mips/x-mips b/gcc/config/mips/x-mips index 5f9ad70..cede48d 100644 --- a/gcc/config/mips/x-mips +++ b/gcc/config/mips/x-mips @@ -5,12 +5,12 @@ # being used in secondary stage builds). We need to pass # the -Wf,-XNg1500 option so the compiler can compile the # G++ file cp-parse.c. Otherwise it complains about -# too many case statements. Down with fixed size tables! +# too many case statements. The -Olimit is so the user +# can use -O2. Down with fixed size tables! CC = $(OLDCC) -OLDCC = cc -Wf,-XNg1500 - -X_CFLAGS = -O1 +OPT = -O1 +OLDCC = cc -Wf,-XNg1500 -Olimit 3000 $(OPT) # The bison output files are machine-indep, # so different flags for a particular machine are not useful. diff --git a/gcc/config/mips/x-sysv b/gcc/config/mips/x-sysv index b3f864d..049ee82 100644 --- a/gcc/config/mips/x-sysv +++ b/gcc/config/mips/x-sysv @@ -5,12 +5,12 @@ # being used in secondary stage builds). We need to pass # the -Wf,-XNg1500 option so the compiler can compile the # G++ file cp-parse.c. Otherwise it complains about -# too many case statements. Down with fixed size tables! +# too many case statements. -Olimit is so the user +# can use -O2. Down with fixed size tables! CC = $(OLDCC) -OLDCC = cc -Wf,-XNg1500 - -X_CFLAGS = -O1 +OPT = -O1 +OLDCC = cc -Wf,-XNg1500 -Olimit 3000 $(OPT) # The bison output files are machine-indep, # so different flags for a particular machine are not useful. diff --git a/gcc/config/mips/x-ultrix b/gcc/config/mips/x-ultrix index 0498bb1..6e46f0e 100644 --- a/gcc/config/mips/x-ultrix +++ b/gcc/config/mips/x-ultrix @@ -5,12 +5,12 @@ # being used in secondary stage builds). We need to pass # the -Wf,-XNg1500 option so the compiler can compile the # G++ file cp-parse.c. Otherwise it complains about -# too many case statements. Down with fixed size tables! +# too many case statements. -Olimit is so the user +# can use -O2. Down with fixed size tables! CC = $(OLDCC) -OLDCC = cc -Wf,-XNg1500 - -X_CFLAGS = -O1 +OPT = -O1 +OLDCC = cc -Wf,-XNg1500 -Olimit 3000 $(OPT) # The bison output files are machine-indep, # so different flags for a particular machine are not useful. |