HI Richard, The base patch is now committed. The final patch, including your final edits is attached. I will be posting the optimization pieces later this week. Thanks for working with me on this. Catherine > -----Original Message----- > From: Richard Sandiford [mailto:rdsandiford@googlemail.com] > Sent: Thursday, February 21, 2013 4:20 PM > To: Moore, Catherine > Cc: gcc-patches@gcc.gnu.org; Rozycki, Maciej > Subject: Re: FW: [PATCH] [MIPS] microMIPS gcc support > > "Moore, Catherine" writes: > >> Looks good otherwise, but please post an updated patch. It's > >> probably stating the obvious, but the patch is too invasive for this > >> late stage of 4.8, so it'll need to wait until 4.9. > >> > > > > The updated patch is attached. How's it looking this time? > > Almost there. :-) > > As I mentioned in an earlier reply, please always check for warnings. > If you're not bootstrapping on a MIPS host then instead configure the cross > compiler with --enable-werror-always, using a recent GCC as the host > compiler. If the patch goes in with warnings, it'll break the build for other > people. > > The warnings I could see are: > > > + for (n = 0; n < XVECLEN (pattern, 0); n++) > > + { > > + rtx set, reg, mem, this_base; > > + HOST_WIDE_INT this_offset; > > + unsigned int this_regno; > > this_regno is an unused variable (thanks for making it unused though). > > > static bool > > mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) > > { > > + > > + unsigned int compression_mode = mips_get_compress_mode (decl); > > compression_mode is unused. > > > +static bool > > +umips_build_save_restore (mips_save_restore_fn fn, > > + unsigned *mask, HOST_WIDE_INT *offset) { > > + int i, nregs; > > + unsigned int j; > > + rtx pattern, set, reg, mem; > > + HOST_WIDE_INT this_offset; > > + rtx this_base; > > + > > + /* Try matching $16 to $31 (s0 to ra). */ for (i = 0; i < > > + ARRAY_SIZE (umips_swm_mask); i++) > > + if ((*mask & 0xffff0000) == umips_swm_mask[i]) > > + break; > > + > > + if (i == ARRAY_SIZE (umips_swm_mask)) > > + return false; > > "i" needs to be unsigned to avoid a "comparison between signed and > unsigned" > warning. > > > +/* Return the assembly instruction for microMIPS lwm or swm. > > + SAVE_P and PATTERN are as for umips_save_restore_pattern_p. */ > > + > > +const char * > > +umips_output_save_restore (bool save_p, rtx pattern) { > > + static char buffer[300]; > > + char *s; > > + int n; > > + HOST_WIDE_INT offset; > > + rtx base, mem, set, reg, last_set, last_reg; > > + > > + /* Parse the pattern. */ > > + gcc_assert (umips_save_restore_pattern_p (save_p, pattern)); > > + > > + s = strcpy (buffer, save_p ? "swm\t" : "lwm\t"); s += strlen (s); > > + n = XVECLEN (pattern, 0); > > + > > + set = XVECEXP (pattern, 0, 0); > > + reg = save_p ? SET_SRC (set) : SET_DEST (set); > > "reg" is unused and should be deleted. > > In case it sounds otherwise, I didn't build the patch to try to catch you out. > I built it so that I could try to answer: > > > > Is this a test of the swap_p case? Thanks if so, but could you add > > > a comment saying where the SWP gets generated, and why the test > > > needs to be skipped at -O1 and -Os? > > > > > Yes, this was the swap_p case. But it turns out that > > umips-lpw-swp-1.c was also testing the swap_p case. I've now dropped > > this test in favor of a different test that exercises the swap_p = false case. > > You had mentioned testing for explicit registers. This is turning out > > to be problematic. The Linux and ELF tool chains don't always use the > > same register set. In addition, -O3 seems to expose more > > opportunities for generating these instructions so the code generated > > isn't consistent among optimization options. I've changed it back to > > just testing for swp, but I'm open to other suggestions. > > I've attached some tests below, both for LWP (which didn't seem to be > covered) and SWP. They use things like multiplication to force a particular > load or store order in scheduled code, so that both swap_p and !swap_p are > covered (verified using both printfs and -fno-peephole2). > umips-lwp-7.c tests for: > > /* Avoid invalid load pair instructions. */ > if (load_p && REGNO (first_reg) == REGNO (base1)) > return false; > > /* We must avoid this case for anti-dependence. > Ex: lw $3, 4($3) > lw $2, 0($3) > first_reg is $2, but the base is $3. */ > if (load_p > && swap_p > && REGNO (first_reg) + 1 == REGNO (base1)) > return false; > > while umips-lwp-8.c is an example of something that would be pessimised by > not having the swap_p test above. > > I also noticed a couple of other things while testing: > > - ISA_HAS_LOAD_DELAY should be false for microMIPS, otherwise we'll try > to insert nops after LWP on targets that default to -mips1, and ICE > when we see that we have a double SET. > > - In the testsuite, a -mmicromips test option should override an ambient > -mips16, and vice versa. > > - umips-movep-2.c fails on n64 because there the moves are DImode rather > than SImode. Since the initial patch is just for 32-bit, I forced > -mgp32 for now. Also, the function needs a MICROMIPS attribute. > > There were various other minor formatting and comment nits that were > probably easier for me to fix than describe. There was also some trailing > whitespace. > > The patch is OK for 4.9 with this one applied on top of it, provided that it > works with your setup of course. Thanks for your patience! > > Richard > > > Index: gcc/config/mips/constraints.md > ========================================================== > ========= > --- gcc/config/mips/constraints.md 2013-02-21 19:57:26.000000000 +0000 > +++ gcc/config/mips/constraints.md 2013-02-21 20:24:30.909497318 +0000 > @@ -239,9 +239,10 @@ (define_memory_constraint "ZC" > @code{sc}. When not compiling for microMIPS code, @code{ZC} is > equivalent to @code{R}." > (and (match_code "mem") > - (if_then_else (match_test "TARGET_MICROMIPS") > - (match_test "umips_12bit_offset_address_p (XEXP (op, > 0), mode)") > - (match_test "mips_address_insns (XEXP (op, 0), mode, > false)")))) > + (if_then_else > + (match_test "TARGET_MICROMIPS") > + (match_test "umips_12bit_offset_address_p (XEXP (op, 0), mode)") > + (match_test "mips_address_insns (XEXP (op, 0), mode, false)")))) > > (define_address_constraint "ZD" > "When compiling microMIPS code, this constraint matches an address > operand > Index: gcc/config/mips/micromips.md > ========================================================== > ========= > --- gcc/config/mips/micromips.md 2013-02-21 19:57:26.000000000 +0000 > +++ gcc/config/mips/micromips.md 2013-02-21 20:29:35.840530555 +0000 > @@ -48,8 +48,7 @@ (define_peephole2 > "TARGET_MICROMIPS > && umips_load_store_pair_p (true, operands)" > [(parallel [(set (match_dup 0) (match_dup 1)) > - (set (match_dup 2) (match_dup 3))])] > -) > + (set (match_dup 2) (match_dup 3))])]) > > ;; The behavior of the LWP insn is undefined if placed in a delay slot. > (define_insn "*lwp" > @@ -77,8 +76,7 @@ (define_peephole2 > "TARGET_MICROMIPS > && umips_load_store_pair_p (false, operands)" > [(parallel [(set (match_dup 0) (match_dup 1)) > - (set (match_dup 2) (match_dup 3))])] > -) > + (set (match_dup 2) (match_dup 3))])]) > > ;; The behavior of the SWP insn is undefined if placed in a delay slot. > (define_insn "*swp" > @@ -106,8 +104,7 @@ (define_peephole2 > "TARGET_MICROMIPS > && umips_movep_target_p (operands[0], operands[2])" > [(parallel [(set (match_dup 0) (match_dup 1)) > - (set (match_dup 2) (match_dup 3))])] > -) > + (set (match_dup 2) (match_dup 3))])]) > > ;; The behavior of the MOVEP insn is undefined if placed in a delay slot. > (define_insn "*movep" > Index: gcc/config/mips/mips.c > ========================================================== > ========= > --- gcc/config/mips/mips.c 2013-02-21 20:03:53.631341344 +0000 > +++ gcc/config/mips/mips.c 2013-02-21 21:08:27.247096879 +0000 > @@ -1252,7 +1252,7 @@ mips_use_debug_exception_return_p (tree } > > /* Return the set of compression modes that are explicitly required > - by DECL. */ > + by the attributes in ATTRIBUTES. */ > > static unsigned int > mips_get_compress_on_flags (tree attributes) @@ -1269,7 +1269,7 @@ > mips_get_compress_on_flags (tree attribu } > > /* Return the set of compression modes that are explicitly forbidden > - by DECL. */ > + by the attributes in ATTRIBUTES. */ > > static unsigned int > mips_get_compress_off_flags (tree attributes) @@ -1290,6 +1290,7 @@ > mips_get_compress_off_flags (tree attrib > > /* Return the compression mode that should be used for function DECL. > Return the ambient setting if DECL is null. */ > + > static unsigned int > mips_get_compress_mode (tree decl) > { > @@ -1411,20 +1412,16 @@ mips_merge_decl_attributes (tree olddecl > > diff = (mips_get_compress_on_flags (DECL_ATTRIBUTES (olddecl)) > ^ mips_get_compress_on_flags (DECL_ATTRIBUTES (newdecl))); > - > if (diff) > error ("%qE redeclared with conflicting %qs attributes", > DECL_NAME (newdecl), mips_get_compress_on_name (diff)); > > - > diff = (mips_get_compress_off_flags (DECL_ATTRIBUTES (olddecl)) > ^ mips_get_compress_off_flags (DECL_ATTRIBUTES (newdecl))); > - > if (diff) > error ("%qE redeclared with conflicting %qs attributes", > DECL_NAME (newdecl), mips_get_compress_off_name (diff)); > > - > return merge_attributes (DECL_ATTRIBUTES (olddecl), > DECL_ATTRIBUTES (newdecl)); > } > @@ -6194,7 +6191,7 @@ mips_start_function_definition (const ch > if (TARGET_MICROMIPS) > fprintf (asm_out_file, "\t.set\tmicromips\n"); #ifdef > HAVE_GAS_MICROMIPS > - else > + else > fprintf (asm_out_file, "\t.set\tnomicromips\n"); #endif > > @@ -7040,8 +7037,6 @@ mips_call_may_need_jalx_p (tree decl) static bool > mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) { > - > - unsigned int compression_mode = mips_get_compress_mode (decl); > if (!TARGET_SIBCALLS) > return false; > > @@ -7050,8 +7045,8 @@ mips_function_ok_for_sibcall (tree decl, > if (mips_interrupt_type_p (TREE_TYPE (current_function_decl))) > return false; > > - /* Direct Js are only possible to functions that use the same ISA > - encoding. There is no JX counterpoart of JALX. */ > + /* Direct Js are only possible to functions that use the same ISA encoding. > + There is no JX counterpoart of JALX. */ > if (decl > && const_call_insn_operand (XEXP (DECL_RTL (decl), 0), VOIDmode) > && mips_call_may_need_jalx_p (decl)) @@ -10400,10 +10395,10 @@ > mips_save_reg (rtx reg, rtx mem) > instruction. The entries are ordered by number of registers set in > the mask. We also ignore the single register encodings because a > normal SW/LW is preferred. */ > - > + > static const unsigned int umips_swm_mask[17] = { > 0xc0ff0000, 0x80ff0000, 0x40ff0000, 0x807f0000, > - 0x00ff0000, 0x803f0000, 0x007f0000, 0x801f0000, > + 0x00ff0000, 0x803f0000, 0x007f0000, 0x801f0000, > 0x003f0000, 0x800f0000, 0x001f0000, 0x80070000, > 0x000f0000, 0x80030000, 0x00070000, 0x80010000, > 0x00030000 > @@ -10424,8 +10419,8 @@ static const unsigned int umips_swm_enco > umips_build_save_restore (mips_save_restore_fn fn, > unsigned *mask, HOST_WIDE_INT *offset) { > - int i, nregs; > - unsigned int j; > + int nregs; > + unsigned int i, j; > rtx pattern, set, reg, mem; > HOST_WIDE_INT this_offset; > rtx this_base; > @@ -10438,7 +10433,7 @@ umips_build_save_restore (mips_save_rest > if (i == ARRAY_SIZE (umips_swm_mask)) > return false; > > - /* Adjust offset for output. */ > + /* Get the offset of the lowest save slot. */ > nregs = (umips_swm_encoding[i] & 0xf) + (umips_swm_encoding[i] >> 4); > this_offset = *offset - UNITS_PER_WORD * (nregs - 1); > > @@ -10453,10 +10448,9 @@ umips_build_save_restore (mips_save_rest > /* For registers $16-$23 and $30. */ > for (j = 0; j < (umips_swm_encoding[i] & 0xf); j++) > { > - unsigned int regno; > HOST_WIDE_INT offset = this_offset + j * UNITS_PER_WORD; > mem = gen_frame_mem (SImode, plus_constant (Pmode, this_base, > offset)); > - regno = (j != 8) ? 16 + j : 30; > + unsigned int regno = (j != 8) ? 16 + j : 30; > *mask &= ~(1 << regno); > reg = gen_rtx_REG (SImode, regno); > if (fn == mips_save_reg) > @@ -10488,7 +10482,7 @@ umips_build_save_restore (mips_save_rest > > pattern = emit_insn (pattern); > if (fn == mips_save_reg) > - RTX_FRAME_RELATED_P (pattern) = 1; > + RTX_FRAME_RELATED_P (pattern) = 1; > > /* Adjust the last offset. */ > *offset -= UNITS_PER_WORD * nregs; > @@ -10514,7 +10508,7 @@ mips_for_each_saved_gpr_and_fpr (HOST_WI > the return register be stored at func+4, and also it allows us not to > need a nop in the epilogue if at least one register is reloaded in > addition to return address. */ > - offset = cfun->machine->frame.gp_sp_offset - sp_offset; > + offset = frame->gp_sp_offset - sp_offset; > mask = frame->mask; > > if (TARGET_MICROMIPS) > @@ -17087,8 +17081,8 @@ mips_option_override (void) > > /* Now select the ISA mode. > > - Do all CPP-sensitive stuff in uncompressed mode; > - We'll switch modes later if required. */ > + Do all CPP-sensitive stuff in uncompressed mode; we'll switch modes > + later if required. */ > mips_set_compression_mode (0); > } > > @@ -17366,7 +17360,6 @@ umips_save_restore_pattern_p (bool save_ > { > rtx set, reg, mem, this_base; > HOST_WIDE_INT this_offset; > - unsigned int this_regno; > > /* Check that we have a SET. */ > set = XVECEXP (pattern, 0, n); > @@ -17414,7 +17407,8 @@ umips_save_restore_pattern_p (bool save_ > > return false; > } > -/* Return the assembly instruction for microMIPS lwm or swm. > + > +/* Return the assembly instruction for microMIPS LWM or SWM. > SAVE_P and PATTERN are as for umips_save_restore_pattern_p. */ > > const char * > @@ -17424,7 +17418,7 @@ umips_output_save_restore (bool save_p, > char *s; > int n; > HOST_WIDE_INT offset; > - rtx base, mem, set, reg, last_set, last_reg; > + rtx base, mem, set, last_set, last_reg; > > /* Parse the pattern. */ > gcc_assert (umips_save_restore_pattern_p (save_p, pattern)); @@ - > 17434,7 +17428,6 @@ umips_output_save_restore (bool save_p, > n = XVECLEN (pattern, 0); > > set = XVECEXP (pattern, 0, 0); > - reg = save_p ? SET_SRC (set) : SET_DEST (set); > mem = save_p ? SET_DEST (set) : SET_SRC (set); > mips_split_plus (XEXP (mem, 0), &base, &offset); > > @@ -17506,7 +17499,9 @@ umips_load_store_pair_p_1 (bool load_p, > return true; > } > > -/* Return true if operands can be used in an LWP or SWP instruction. */ > +/* OPERANDS describes the operands to a pair of SETs, in the order > + dest1, src1, dest2, src2. Return true if the operands can be used > + in an LWP or SWP instruction; LOAD_P says which. */ > > bool > umips_load_store_pair_p (bool load_p, rtx *operands) @@ -17537,8 > +17532,9 @@ umips_load_store_pair_p (bool load_p, rt > return false; > } > > -/* Return the assembly instruction for microMIPS lwp or swp. > - LOAD_P is true for load. */ > +/* Return the assembly instruction for a microMIPS LWP or SWP in which > + the first register is REG and the first memory slot is MEM. > + LOAD_P is true for LWP. */ > > static void > umips_output_load_store_pair_1 (bool load_p, rtx reg, rtx mem) @@ - > 17551,6 +17547,9 @@ umips_output_load_store_pair_1 (bool loa > output_asm_insn ("swp\t%0,%1", ops); } > > +/* Output the assembly instruction for a microMIPS LWP or SWP instruction. > + LOAD_P and OPERANDS are as for umips_load_store_pair_p. */ > + > void > umips_output_load_store_pair (bool load_p, rtx *operands) { @@ -17569,7 > +17568,7 @@ umips_output_load_store_pair (bool load_ > mem1 = operands[0]; > mem2 = operands[2]; > } > - > + > if (REGNO (reg2) == REGNO (reg1) + 1) > { > umips_output_load_store_pair_1 (load_p, reg1, mem1); @@ -17588,12 > +17587,12 @@ umips_movep_target_p (rtx reg1, rtx reg2 > int regno1, regno2, pair; > unsigned int i; > static const int match[8] = { > - 0x00000060, /* 5, 6 */ > - 0x000000a0, /* 5, 7 */ > - 0x000000c0, /* 6, 7 */ > - 0x00200010, /* 4, 21 */ > - 0x00400010, /* 4, 22 */ > - 0x00000030, /* 4, 5 */ > + 0x00000060, /* 5, 6 */ > + 0x000000a0, /* 5, 7 */ > + 0x000000c0, /* 6, 7 */ > + 0x00200010, /* 4, 21 */ > + 0x00400010, /* 4, 22 */ > + 0x00000030, /* 4, 5 */ > 0x00000050, /* 4, 6 */ > 0x00000090 /* 4, 7 */ > }; > @@ -17604,7 +17603,7 @@ umips_movep_target_p (rtx reg1, rtx reg2 > regno1 = REGNO (reg1); > regno2 = REGNO (reg2); > > - if (!GP_REG_P (regno1) || !GP_REG_P (regno2)) > + if (!GP_REG_P (regno1) || !GP_REG_P (regno2)) > return false; > > pair = (1 << regno1) | (1 << regno2); > Index: gcc/config/mips/mips.h > ========================================================== > ========= > --- gcc/config/mips/mips.h 2013-02-21 20:03:53.632341352 +0000 > +++ gcc/config/mips/mips.h 2013-02-21 20:04:23.070542151 +0000 > @@ -1019,7 +1019,8 @@ #define ISA_HAS_DSPR2 > (TARGET_DSPR2 && > and "addiu $4,$4,1". */ > #define ISA_HAS_LOAD_DELAY (ISA_MIPS1 > \ > && !TARGET_MIPS3900 > \ > - && !TARGET_MIPS16) > + && !TARGET_MIPS16 \ > + && !TARGET_MICROMIPS) > > /* Likewise mtc1 and mfc1. */ > #define ISA_HAS_XFER_DELAY (mips_isa <= 3 \ > Index: gcc/config/mips/mips.md > ========================================================== > ========= > --- gcc/config/mips/mips.md 2013-02-21 19:57:26.000000000 +0000 > +++ gcc/config/mips/mips.md 2013-02-21 20:06:12.347267724 +0000 > @@ -5471,7 +5471,7 @@ (define_insn "*branch_equality" > 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")); > Index: gcc/testsuite/gcc.target/mips/mips.exp > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/mips.exp 2013-02-21 > 20:03:53.632341352 +0000 > +++ gcc/testsuite/gcc.target/mips/mips.exp 2013-02-21 > 20:04:23.071542158 +0000 > @@ -817,6 +817,8 @@ proc mips-dg-finish {} { > # | | > # -mips16/-mflip-mips16 -mno-mips16 > # | | > +# -micromips -mno-micromips > +# | | > # -mips3d -mno-mips3d > # | | > # -mpaired-single -mno-paired-single > @@ -905,6 +907,8 @@ proc mips-dg-options { args } { > > # Handle dependencies between options on the left of the > # dependency diagram. > + mips_option_dependency options "-mips16" "-mno-micromips" > + mips_option_dependency options "-mmicromips" "-mno-mips16" > mips_option_dependency options "-mips3d" "-mpaired-single" > mips_option_dependency options "-mpaired-single" "-mfp64" > mips_option_dependency options "-mfp64" "-mhard-float" > Index: gcc/testsuite/gcc.target/mips/umips-lwp-1.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-1.c 2013-02-21 > 20:33:17.980173008 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[0]; > + int r6 = r4[1]; > + r4[2] = r5 * r5; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tlwp\t\\\$5,0\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-2.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-2.c 2013-02-21 > 20:36:21.709519202 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[0]; > + int r6 = r4[1]; > + r4[2] = r6 * r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tlwp\t\\\$5,0\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-3.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-3.c 2013-02-21 > 20:36:29.710578763 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[511]; > + int r6 = r4[512]; > + r4[2] = r5 * r5; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tlwp\t\\\$5,2044\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-4.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-4.c 2013-02-21 > 20:36:37.533637002 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[511]; > + int r6 = r4[512]; > + r4[2] = r6 * r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tlwp\t\\\$5,2044\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-5.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-5.c 2013-02-21 > 20:36:46.255701936 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[512]; > + int r6 = r4[513]; > + r4[2] = r5 * r5; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler-not "\tlwp" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-6.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-6.c 2013-02-21 > 20:36:53.911758937 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4) > +{ > + int r5 = r4[512]; > + int r6 = r4[513]; > + r4[2] = r6 * r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[3]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler-not "\tlwp" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-7.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-7.c 2013-02-21 > 20:04:23.074542181 +0000 > @@ -0,0 +1,41 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +f1 (int *r4, int dummy, int *other) > +{ > + int r5 = r4[1]; > + int newr4 = r4[0]; > + other[0] = r5 * r5; > + { > + register int r5asm asm ("$5") = r5; > + register int r4asm asm ("$4") = newr4; > + asm ("#foo" : "=m" (other[1]) : "d" (r4asm), "d" (r5asm)); > + } > +} > + > +void MICROMIPS > +f2 (int *r4, int dummy, int *other) > +{ > + int newr4 = r4[0]; > + int r5 = *(int *)(newr4 + 4); > + { > + register int r5asm asm ("$5") = r5; > + register int r4asm asm ("$4") = newr4; > + asm ("#foo" : "=m" (other[0]) : "d" (r4asm), "d" (r5asm)); > + } > +} > + > +void MICROMIPS > +f3 (int dummy, int *r5, int *other) > +{ > + int newr5 = r5[1]; > + int r4 = *(int *)newr5; > + { > + register int r5asm asm ("$4") = r4; > + register int r4asm asm ("$5") = newr5; > + asm ("#foo" : "=m" (other[0]) : "d" (r4asm), "d" (r5asm)); > + } > +} > + > +/* { dg-final { scan-assembler-not "\tlwp" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-8.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-8.c 2013-02-21 > 20:04:23.074542181 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-mgp32 -fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +f1 (int dummy, int *r5, int *other) > +{ > + int r4 = r5[0]; > + int newr5 = r5[1]; > + other[0] = r4 * r4; > + { > + register int r5asm asm ("$4") = r4; > + register int r4asm asm ("$5") = newr5; > + asm ("#foo" : "=m" (other[1]) : "d" (r4asm), "d" (r5asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tlwp\t\\\$4,0\\(\\\$5\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-swp-1.c > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/umips-lwp-swp-1.c 2013-02-21 > 20:03:53.633341359 +0000 > +++ /dev/null 2013-02-18 18:12:58.656083693 +0000 > @@ -1,17 +0,0 @@ > -/* Test that an SWP can be generated when the instruction order is > reversed: > - > - ie. ST $3, mem+4 > - ST $2, mem > -*/ > - > -/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ > -/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > -/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ > -/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > - > -void MICROMIPS > -foo (long long l1, long long *l2) > -{ > - *l2 = l1; > -} > -/* { dg-final { scan-assembler "\tswp\t\\\$4,0\\(\\\$6\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-swp-2.c > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/umips-lwp-swp-2.c 2013-02-21 > 20:03:53.633341359 +0000 > +++ /dev/null 2013-02-18 18:12:58.656083693 +0000 > @@ -1,176 +0,0 @@ > -/* Test that an SWP can be generated when the instruction order is not > reversed: > - > - ie. ST $2, mem > - ST $2, mem+4 > -*/ > - > -/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ > -/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > - > -#include > - > -void MICROMIPS s(int, ...); > -void MICROMIPS z(int, ...); > -void MICROMIPS c(int, ...); > - > -typedef int l[500]; > - > -void > -MICROMIPS f (int n) > -{ > - int i; > - l a0, a1, a2, a3, a4, a5, a6, a7, a8, a9; > - l a10, a11, a12, a13, a14, a15, a16, a17, a18, a19; > - l a20, a21, a22, a23, a24, a25, a26, a27, a28, a29; > - l a30, a31, a32, a33, a34, a35, a36, a37, a38, a39; > - int i0, i1, i2, i3, i4, i5, i6, i7, i8, i9; > - int i10, i11, i12, i13, i14, i15, i16, i17, i18, i19; > - int i20, i21, i22, i23, i24, i25, i26, i27, i28, i29; > - int i30, i31, i32, i33, i34, i35, i36, i37, i38, i39; > - > - for (i = 0; i < n; i++) > - { > - s (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, > - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, > - a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, > - a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); > - i0 = a0[0]; > - i1 = a1[0]; > - i2 = a2[0]; > - i3 = a3[0]; > - i4 = a4[0]; > - i5 = a5[0]; > - i6 = a6[0]; > - i7 = a7[0]; > - i8 = a8[0]; > - i9 = a9[0]; > - i10 = a10[0]; > - i11 = a11[0]; > - i12 = a12[0]; > - i13 = a13[0]; > - i14 = a14[0]; > - i15 = a15[0]; > - i16 = a16[0]; > - i17 = a17[0]; > - i18 = a18[0]; > - i19 = a19[0]; > - i20 = a20[0]; > - i21 = a21[0]; > - i22 = a22[0]; > - i23 = a23[0]; > - i24 = a24[0]; > - i25 = a25[0]; > - i26 = a26[0]; > - i27 = a27[0]; > - i28 = a28[0]; > - i29 = a29[0]; > - i30 = a30[0]; > - i31 = a31[0]; > - i32 = a32[0]; > - i33 = a33[0]; > - i34 = a34[0]; > - i35 = a35[0]; > - i36 = a36[0]; > - i37 = a37[0]; > - i38 = a38[0]; > - i39 = a39[0]; > - z (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, > - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, > - a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, > - a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); > - a0[i0] = i0; > - a1[i1] = i1; > - a2[i2] = i2; > - a3[i3] = i3; > - a4[i4] = i4; > - a5[i5] = i5; > - a6[i6] = i6; > - a7[i7] = i7; > - a8[i8] = i8; > - a9[i9] = i9; > - a10[i10] = i10; > - a11[i11] = i11; > - a12[i12] = i12; > - a13[i13] = i13; > - a14[i14] = i14; > - a15[i15] = i15; > - a16[i16] = i16; > - a17[i17] = i17; > - a18[i18] = i18; > - a19[i19] = i19; > - a20[i20] = i20; > - a21[i21] = i21; > - a22[i22] = i22; > - a23[i23] = i23; > - a24[i24] = i24; > - a25[i25] = i25; > - a26[i26] = i26; > - a27[i27] = i27; > - a28[i28] = i28; > - a29[i29] = i29; > - a30[i30] = i30; > - a31[i31] = i31; > - a32[i32] = i32; > - a33[i33] = i33; > - a34[i34] = i34; > - a35[i35] = i35; > - a36[i36] = i36; > - a37[i37] = i37; > - a38[i38] = i38; > - a39[i39] = i39; > - c (40, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, > - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, > - a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, > - a30, a31, a32, a33, a34, a35, a36, a37, a38, a39); > - } > -} > - > -int > -MICROMIPS main () > -{ > - f (1); > -} > - > -void > -MICROMIPS s (int n, ...) > -{ > - va_list list; > - > - va_start (list, n); > - while (n--) > - { > - int *a = va_arg (list, int *); > - a[0] = n; > - } > - va_end (list); > -} > - > -void > -MICROMIPS z (int n, ...) > -{ > - va_list list; > - > - va_start (list, n); > - while (n--) > - { > - int *a = va_arg (list, int *); > - __builtin_memset (a, 0, sizeof (l)); > - } > - va_end (list); > -} > - > -void > -MICROMIPS c (int n, ...) > -{ > - va_list list; > - > - va_start (list, n); > - while (n--) > - { > - int *a = va_arg (list, int *); > - if (a[n] != n) > - ; > - } > - va_end (list); > -} > -/* { dg-final { scan-assembler "\tswp" } } */ > Index: gcc/testsuite/gcc.target/mips/umips-lwp-swp-volatile.c > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/umips-lwp-swp-volatile.c 2013-02-21 > 19:57:47.000000000 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-lwp-swp-volatile.c 2013-02-21 > 20:04:49.560724491 +0000 > @@ -2,8 +2,8 @@ > /* { dg-options "-mmicromips" } */ > > /* This test ensures that we do not generate microMIPS SWP or LWP > - instructions when any component of the accessed memory is volatile; > - they are unsafe for such since they might cause replay of partial > + instructions when any component of the accessed memory is volatile; > + they are unsafe for such since they might cause replay of partial > accesses if interrupted by an exception. */ > > static void set_csr (volatile void *p, int v) > Index: gcc/testsuite/gcc.target/mips/umips-movep-2.c > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/umips-movep-2.c 2013-02-21 > 20:03:53.632341352 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-movep-2.c 2013-02-21 > 20:42:40.247604192 +0000 > @@ -1,12 +1,13 @@ > /* Check that we can generate the MOVEP instruction. */ > -/* { dg-options "-fpeephole2 (-mmicromips)" } */ > +/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ > /* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > > int bar (int, int); > > -int > +int MICROMIPS > foo (int n, int a) > { > return bar (0, 0); > } > -/* { dg-final { scan-assembler "\tmovep\t" } } */ > + > +/* { dg-final { scan-assembler "\tmovep\t\\\$4,\\\$5,\\\$0,\\\$0" } } > +*/ > Index: gcc/testsuite/gcc.target/mips/umips-save-restore-1.c > ========================================================== > ========= > --- gcc/testsuite/gcc.target/mips/umips-save-restore-1.c 2013-02-21 > 19:57:47.000000000 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-save-restore-1.c 2013-02-21 > 20:06:37.807422840 +0000 > @@ -5,7 +5,7 @@ > int bar (int, int, int, int, int); > > MICROMIPS int > -foo (int n, int a, int b, int c, int d) > +foo (int n, int a, int b, int c, int d) > { > int i, j; > > Index: gcc/testsuite/gcc.target/mips/umips-swp-1.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-1.c 2013-02-21 > 20:04:23.075542188 +0000 > @@ -0,0 +1,10 @@ > +/* { dg-options "-fpeephole2 -mgp32 (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (long long l1, long long *l2) > +{ > + *l2 = l1; > +} > + > +/* { dg-final { scan-assembler "\tswp\t\\\$4,0\\(\\\$6\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-2.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-2.c 2013-02-21 > 20:40:04.431076334 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r6 *= r6; > + r4[0] = r5; > + r4[1] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tswp\t\\\$5,0\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-3.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-3.c 2013-02-21 > 20:40:16.614164109 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r5 *= r5; > + r4[0] = r5; > + r4[1] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tswp\t\\\$5,0\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-4.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-4.c 2013-02-21 > 20:40:21.540184989 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r6 *= r6; > + r4[511] = r5; > + r4[512] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tswp\t\\\$5,2044\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-5.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-5.c 2013-02-21 > 20:40:28.131170677 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r5 *= r5; > + r4[511] = r5; > + r4[512] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler "\tswp\t\\\$5,2044\\(\\\$4\\)" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-6.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-6.c 2013-02-21 > 20:40:33.757163423 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r6 *= r6; > + r4[512] = r5; > + r4[513] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler-not "\tswp" } }*/ > Index: gcc/testsuite/gcc.target/mips/umips-swp-7.c > ========================================================== > ========= > --- /dev/null 2013-02-18 18:12:58.656083693 +0000 > +++ gcc/testsuite/gcc.target/mips/umips-swp-7.c 2013-02-21 > 20:40:38.486160549 +0000 > @@ -0,0 +1,17 @@ > +/* { dg-options "-fpeephole2 -mtune=m14k (-mmicromips)" } */ > +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */ > + > +void MICROMIPS > +foo (int *r4, int r5, int r6) > +{ > + r5 *= r5; > + r4[512] = r5; > + r4[513] = r6; > + { > + register int r5asm asm ("$5") = r5; > + register int r6asm asm ("$6") = r6; > + asm ("#foo" : "=m" (r4[2]) : "d" (r5asm), "d" (r6asm)); > + } > +} > + > +/* { dg-final { scan-assembler-not "\tswp" } }*/