--- ../cambridge-src/binutils-2.8.1/gas/config/tc-mips.c Thu Sep 9 00:09:29 1999 +++ binutils-2.8.1/gas/config/tc-mips.c Fri Nov 10 20:28:11 2000 @@ -3079,12 +3079,14 @@ else if (mips_pic == SVR4_PIC && ! mips_big_got) { expressionS ex; + /* If we're at mips2 or higher, we don't need nops after loads */ + int use_load_delay = mips_opts.isa < 2; /* If this is a reference to an external symbol, we want lw $reg,($gp) (BFD_RELOC_MIPS_GOT16) Otherwise we want lw $reg,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) addiu $reg,$reg, (BFD_RELOC_LO16) If there is a constant, it must be added in after. */ ex.X_add_number = ep->X_add_number; @@ -3093,9 +3095,11 @@ macro_build ((char *) NULL, counter, ep, mips_opts.isa < 3 ? "lw" : "ld", "t,o(b)", reg, (int) BFD_RELOC_MIPS_GOT16, GP); - macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", ""); + if (use_load_delay) + macro_build ((char *) NULL, counter, (expressionS *) NULL, "nop", ""); p = frag_var (rs_machine_dependent, 4, 0, - RELAX_ENCODE (0, 4, -8, 0, 0, mips_opts.warn_about_macros), + RELAX_ENCODE (0, 4, use_load_delay ? -8 : -4, 0, 0, + mips_opts.warn_about_macros), ep->X_add_symbol, (offsetT) 0, (char *) NULL); macro_build (p, counter, ep, mips_opts.isa < 3 ? "addiu" : "daddiu", @@ -3955,13 +3959,13 @@ lw $tempreg,($gp) (BFD_RELOC_MIPS_GOT16) For a local symbol, we want lw $tempreg,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) addiu $tempreg,$tempreg, (BFD_RELOC_LO16) If we have a small constant, and this is a reference to an external symbol, we want lw $tempreg,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) addiu $tempreg,$tempreg, For a local symbol, we want the same instruction sequence, but we output a BFD_RELOC_LO16 reloc on the @@ -3976,6 +3980,10 @@ For a local symbol, we want the same instruction sequence, but we output a BFD_RELOC_LO16 reloc on the addiu instruction. */ + + /* If we're at mips2 or higher, we don't need nops after loads */ + int use_load_delay = mips_opts.isa < 2; + expr1.X_add_number = offset_expr.X_add_number; offset_expr.X_add_number = 0; frag_grow (32); @@ -3986,7 +3994,7 @@ { int off; - if (breg == 0) + if (breg == 0 || !use_load_delay) off = 0; else { @@ -3997,14 +4005,19 @@ "nop", ""); off = 4; } - p = frag_var (rs_machine_dependent, 8 - off, 0, - RELAX_ENCODE (0, 8 - off, -4 - off, 4 - off, 0, + p = frag_var (rs_machine_dependent, + (use_load_delay ? 8 : 4) - off, 0, + RELAX_ENCODE (0, + (use_load_delay ? 8 : 4) - off, + -4 - off, + (use_load_delay ? 4 : 0) - off, + 0, (breg == 0 ? mips_opts.warn_about_macros : 0)), offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL); - if (breg == 0) + if (breg == 0 && use_load_delay) { macro_build (p, &icnt, (expressionS *) NULL, "nop", ""); p += 4; @@ -4019,13 +4032,14 @@ else if (expr1.X_add_number >= -0x8000 && expr1.X_add_number < 0x8000) { - macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + if (use_load_delay) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", ""); macro_build ((char *) NULL, &icnt, &expr1, mips_opts.isa < 3 ? "addiu" : "daddiu", "t,r,j", tempreg, tempreg, (int) BFD_RELOC_LO16); (void) frag_var (rs_machine_dependent, 0, 0, - RELAX_ENCODE (0, 0, -12, -4, 0, 0), + RELAX_ENCODE (0, 0, (use_load_delay ? -12 : -8), -4, 0, 0), offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL); } @@ -4044,14 +4058,19 @@ off1 = 0; else { - macro_build ((char *) NULL, &icnt, (expressionS *) NULL, - "nop", ""); + off1 = 0; + if (mips_opts.isa < 2) + { + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + "nop", ""); + off1 -= 4; + } macro_build ((char *) NULL, &icnt, (expressionS *) NULL, mips_opts.isa < 3 ? "addu" : "daddu", "d,v,t", treg, AT, breg); + off1 -= 4; breg = 0; tempreg = treg; - off1 = -8; } /* Set mips_optimize around the lui instruction to avoid @@ -4355,7 +4374,7 @@ /* If this is a reference to an external symbol, and we are using a small GOT, we want lw $25,($gp) (BFD_RELOC_MIPS_CALL16) - nop + nop (if mips1) jalr $25 nop lw $gp,cprestore($sp) @@ -4370,7 +4389,7 @@ lw $gp,cprestore($sp) If the symbol is not external, we want lw $25,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) addiu $25,$25, (BFD_RELOC_LO16) jalr $25 nop @@ -4378,14 +4397,18 @@ frag_grow (40); if (! mips_big_got) { + int use_load_delay = mips_opts.isa < 2; + macro_build ((char *) NULL, &icnt, &offset_expr, mips_opts.isa < 3 ? "lw" : "ld", "t,o(b)", PIC_CALL_REG, (int) BFD_RELOC_MIPS_CALL16, GP); - macro_build ((char *) NULL, &icnt, (expressionS *) NULL, - "nop", ""); + if (use_load_delay) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, + "nop", ""); p = frag_var (rs_machine_dependent, 4, 0, - RELAX_ENCODE (0, 4, -8, 0, 0, 0), + RELAX_ENCODE (0, 4, use_load_delay ? -8 : -4, + 0, 0, 0), offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL); } @@ -4711,11 +4734,11 @@ { /* If this is a reference to an external symbol, we want lw $tempreg,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) $treg,0($tempreg) Otherwise we want lw $tempreg,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) addiu $tempreg,$tempreg, (BFD_RELOC_LO16) $treg,0($tempreg) If there is a base register, we add it to $tempreg before @@ -4724,6 +4747,10 @@ 16 bits, because we have no way to load the upper 16 bits (actually, we could handle them for the subset of cases in which we are not using $at). */ + + /* If we're at mips2 or higher, we don't need nops after loads */ + int use_load_delay = mips_opts.isa < 2; + assert (offset_expr.X_op == O_symbol); expr1.X_add_number = offset_expr.X_add_number; offset_expr.X_add_number = 0; @@ -4734,9 +4761,10 @@ macro_build ((char *) NULL, &icnt, &offset_expr, mips_opts.isa < 3 ? "lw" : "ld", "t,o(b)", tempreg, (int) BFD_RELOC_MIPS_GOT16, GP); - macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", ""); + if (use_load_delay) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", ""); p = frag_var (rs_machine_dependent, 4, 0, - RELAX_ENCODE (0, 4, -8, 0, 0, 0), + RELAX_ENCODE (0, 4, use_load_delay ? -8 : -4, 0, 0, 0), offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL); macro_build (p, &icnt, &offset_expr, @@ -5184,15 +5212,17 @@ else if (mips_pic == SVR4_PIC && ! mips_big_got) { int off; + /* If we're at mips2 or higher, we don't need nops after loads */ + int use_load_delay = mips_opts.isa < 2; /* If this is a reference to an external symbol, we want lw $at,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) $treg,0($at) $treg+1,4($at) Otherwise we want lw $at,($gp) (BFD_RELOC_MIPS_GOT16) - nop + nop (if mips1) $treg,($at) (BFD_RELOC_LO16) $treg+1,+4($at) (BFD_RELOC_LO16) If there is a base register we add it to $at before the @@ -5204,7 +5234,7 @@ if (expr1.X_add_number < -0x8000 || expr1.X_add_number >= 0x8000 - 4) as_bad ("PIC code offset overflow (max 16 signed bits)"); - if (breg == 0) + if (breg == 0 || !use_load_delay) off = 0; else off = 4; @@ -5212,7 +5242,8 @@ macro_build ((char *) NULL, &icnt, &offset_expr, mips_opts.isa < 3 ? "lw" : "ld", "t,o(b)", AT, (int) BFD_RELOC_MIPS_GOT16, GP); - macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", ""); + if (use_load_delay) + macro_build ((char *) NULL, &icnt, (expressionS *) NULL, "nop", ""); if (breg != 0) macro_build ((char *) NULL, &icnt, (expressionS *) NULL, mips_opts.isa < 3 ? "addu" : "daddu", @@ -5234,7 +5265,7 @@ mips_optimize = hold_mips_optimize; (void) frag_var (rs_machine_dependent, 0, 0, - RELAX_ENCODE (0, 0, -16 - off, -8, 1, 0), + RELAX_ENCODE (0, 0, -16 - off, use_load_delay ? -8 : -4, 1, 0), offset_expr.X_add_symbol, (offsetT) 0, (char *) NULL); }