Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 338405 | Differences between
and this patch

Collapse All | Expand All

(-)a/gas/config/tc-mips.c (-9 / +110 lines)
Lines 761-766 enum fix_vr4120_class { Link Here
761
  NUM_FIX_VR4120_CLASSES
761
  NUM_FIX_VR4120_CLASSES
762
};
762
};
763
763
764
/* ...likewise -mfix-loongson2f-jump.  */
765
static int mips_fix_loongson2f_jump;
766
767
/* ...likewise -mfix-loongson2f-nop.  */
768
static int mips_fix_loongson2f_nop;
769
770
/* True if -mfix-loongson2f-nop or -mfix-loongson2f-jump passed */
771
static int mips_fix_loongson2f;
772
764
/* Given two FIX_VR4120_* values X and Y, bit Y of element X is set if
773
/* Given two FIX_VR4120_* values X and Y, bit Y of element X is set if
765
   there must be at least one other instruction between an instruction
774
   there must be at least one other instruction between an instruction
766
   of type X and an instruction of type Y.  */
775
   of type X and an instruction of type Y.  */
Lines 1918-1923 md_begin (void) Link Here
1918
	      if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
1927
	      if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0)
1919
		{
1928
		{
1920
		  create_insn (&nop_insn, mips_opcodes + i);
1929
		  create_insn (&nop_insn, mips_opcodes + i);
1930
		  if (mips_fix_loongson2f_nop)
1931
		    nop_insn.insn_opcode = LOONGSON2F_NOP_INSN;
1921
		  nop_insn.fixed_p = 1;
1932
		  nop_insn.fixed_p = 1;
1922
		}
1933
		}
1923
	    }
1934
	    }
Lines 2731-2736 nops_for_insn_or_target (const struct mips_cl_insn *history, Link Here
2731
  return nops;
2742
  return nops;
2732
}
2743
}
2733
2744
2745
static void
2746
macro_build (expressionS *ep, const char *name, const char *fmt, ...);
2747
2748
static void fix_loongson2f_nop(struct mips_cl_insn *ip)
2749
{
2750
  /* Fix NOP issue: Replace nops by "or at,at,zero" */
2751
  if (strcmp(ip->insn_mo->name, "nop") == 0)
2752
    ip->insn_opcode = LOONGSON2F_NOP_INSN;
2753
}
2754
2755
static void fix_loongson2f_jump(struct mips_cl_insn *ip)
2756
{
2757
2758
  /* Fix Jump Issue: Eliminate instruction fetch from outside 256M region
2759
   *                 jr target pc &= 'hffff_ffff_cfff_ffff
2760
   */
2761
  if (strcmp(ip->insn_mo->name, "j") == 0
2762
      || strcmp(ip->insn_mo->name, "jr") == 0
2763
      || strcmp(ip->insn_mo->name, "jalr") == 0)
2764
    {
2765
      int sreg;
2766
      expressionS ep;
2767
2768
      if (! mips_opts.at)
2769
        return;
2770
2771
      sreg = EXTRACT_OPERAND (RS, *ip);
2772
      if (sreg == ZERO || sreg == KT0 || sreg == KT1 || sreg == ATREG)
2773
        return;
2774
2775
      ep.X_op = O_constant;
2776
      ep.X_add_number = 0xcfff0000;
2777
      macro_build (&ep, "lui", "t,u", ATREG, BFD_RELOC_HI16);
2778
      ep.X_add_number = 0xffff;
2779
      macro_build (&ep, "ori", "t,r,i", ATREG, ATREG, BFD_RELOC_LO16);
2780
      macro_build (NULL, "and", "d,v,t", sreg, sreg, ATREG);
2781
    }
2782
}
2783
2784
static void fix_loongson2f(struct mips_cl_insn *ip)
2785
{
2786
  if (mips_fix_loongson2f_nop)
2787
    fix_loongson2f_nop(ip);
2788
  if (mips_fix_loongson2f_jump)
2789
    fix_loongson2f_jump(ip);
2790
}
2791
2734
/* Output an instruction.  IP is the instruction information.
2792
/* Output an instruction.  IP is the instruction information.
2735
   ADDRESS_EXPR is an operand of the instruction to be used with
2793
   ADDRESS_EXPR is an operand of the instruction to be used with
2736
   RELOC_TYPE.  */
2794
   RELOC_TYPE.  */
Lines 2744-2749 append_insn (struct mips_cl_insn *ip, expressionS *address_expr, Link Here
2744
  bfd_boolean relaxed_branch = FALSE;
2802
  bfd_boolean relaxed_branch = FALSE;
2745
  segment_info_type *si = seg_info (now_seg);
2803
  segment_info_type *si = seg_info (now_seg);
2746
2804
2805
  if (mips_fix_loongson2f)
2806
    fix_loongson2f(ip);
2807
2747
  /* Mark instruction labels in mips16 mode.  */
2808
  /* Mark instruction labels in mips16 mode.  */
2748
  mips16_mark_labels ();
2809
  mips16_mark_labels ();
2749
2810
Lines 11220-11225 enum options Link Here
11220
    OPTION_MNO_7000_HILO_FIX, 
11281
    OPTION_MNO_7000_HILO_FIX, 
11221
    OPTION_FIX_24K,
11282
    OPTION_FIX_24K,
11222
    OPTION_NO_FIX_24K,
11283
    OPTION_NO_FIX_24K,
11284
    OPTION_FIX_LOONGSON2F_JUMP,
11285
    OPTION_NO_FIX_LOONGSON2F_JUMP,
11286
    OPTION_FIX_LOONGSON2F_NOP,
11287
    OPTION_NO_FIX_LOONGSON2F_NOP,
11223
    OPTION_FIX_VR4120,
11288
    OPTION_FIX_VR4120,
11224
    OPTION_NO_FIX_VR4120,
11289
    OPTION_NO_FIX_VR4120,
11225
    OPTION_FIX_VR4130,
11290
    OPTION_FIX_VR4130,
Lines 11308-11313 struct option md_longopts[] = Link Here
11308
  {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
11373
  {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX},
11309
  {"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
11374
  {"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
11310
  {"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
11375
  {"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX},
11376
  {"mfix-loongson2f-jump", no_argument, NULL, OPTION_FIX_LOONGSON2F_JUMP},
11377
  {"mno-fix-loongson2f-jump", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_JUMP},
11378
  {"mfix-loongson2f-nop", no_argument, NULL, OPTION_FIX_LOONGSON2F_NOP},
11379
  {"mno-fix-loongson2f-nop", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_NOP},
11311
  {"mfix-vr4120",    no_argument, NULL, OPTION_FIX_VR4120},
11380
  {"mfix-vr4120",    no_argument, NULL, OPTION_FIX_VR4120},
11312
  {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120},
11381
  {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120},
11313
  {"mfix-vr4130",    no_argument, NULL, OPTION_FIX_VR4130},
11382
  {"mfix-vr4130",    no_argument, NULL, OPTION_FIX_VR4130},
Lines 11575-11580 md_parse_option (int c, char *arg) Link Here
11575
      mips_fix_24k = 0;
11644
      mips_fix_24k = 0;
11576
      break;
11645
      break;
11577
11646
11647
    case OPTION_FIX_LOONGSON2F_JUMP:
11648
      mips_fix_loongson2f_jump = 1;
11649
      break;
11650
11651
    case OPTION_NO_FIX_LOONGSON2F_JUMP:
11652
      mips_fix_loongson2f_jump = 0;
11653
      break;
11654
11655
    case OPTION_FIX_LOONGSON2F_NOP:
11656
      mips_fix_loongson2f_nop = 1;
11657
      break;
11658
11659
    case OPTION_NO_FIX_LOONGSON2F_NOP:
11660
      mips_fix_loongson2f_nop = 0;
11661
      break;
11662
11578
    case OPTION_FIX_VR4120:
11663
    case OPTION_FIX_VR4120:
11579
      mips_fix_vr4120 = 1;
11664
      mips_fix_vr4120 = 1;
11580
      break;
11665
      break;
Lines 11789-11794 md_parse_option (int c, char *arg) Link Here
11789
      return 0;
11874
      return 0;
11790
    }
11875
    }
11791
11876
11877
    mips_fix_loongson2f = mips_fix_loongson2f_nop || mips_fix_loongson2f_jump;
11878
11792
  return 1;
11879
  return 1;
11793
}
11880
}
11794
11881
Lines 14794-14799 void Link Here
14794
mips_handle_align (fragS *fragp)
14881
mips_handle_align (fragS *fragp)
14795
{
14882
{
14796
  char *p;
14883
  char *p;
14884
  int bytes, size, excess;
14885
  valueT opcode;
14797
14886
14798
  if (fragp->fr_type != rs_align_code)
14887
  if (fragp->fr_type != rs_align_code)
14799
    return;
14888
    return;
Lines 14801-14817 mips_handle_align (fragS *fragp) Link Here
14801
  p = fragp->fr_literal + fragp->fr_fix;
14890
  p = fragp->fr_literal + fragp->fr_fix;
14802
  if (*p)
14891
  if (*p)
14803
    {
14892
    {
14804
      int bytes;
14893
      opcode = mips16_nop_insn.insn_opcode;
14894
      size = 2;
14895
    }
14896
  else
14897
    {
14898
      opcode = nop_insn.insn_opcode;
14899
      size = 4;
14900
    }
14805
14901
14806
      bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
14902
  bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
14807
      if (bytes & 1)
14903
  excess = bytes % size;
14808
	{
14904
  if (excess != 0)
14809
	  *p++ = 0;
14905
    {
14810
	  fragp->fr_fix++;
14906
      /* If we're not inserting a whole number of instructions, pad the
14811
	}
14907
         end of the fixed part of the frag with zeros */
14812
      md_number_to_chars (p, mips16_nop_insn.insn_opcode, 2);
14908
      memset (p, 0, excess);
14813
      fragp->fr_var = 2;
14909
      p += excess;
14910
      fragp->fr_fix += excess;
14814
    }
14911
    }
14912
  md_number_to_chars (p, opcode, size);
14913
  fragp->fr_var = size;
14815
}
14914
}
14816
14915
14817
static void
14916
static void
Lines 15523-15528 MIPS options:\n\ Link Here
15523
-mmt			generate MT instructions\n\
15622
-mmt			generate MT instructions\n\
15524
-mno-mt			do not generate MT instructions\n"));
15623
-mno-mt			do not generate MT instructions\n"));
15525
  fprintf (stream, _("\
15624
  fprintf (stream, _("\
15625
-mfix-loongson2f-jump	work around Loongson2F JUMP instructions\
15626
-mfix-loongson2f-nop	work around Loongson2F NOP errata\n\
15526
-mfix-vr4120		work around certain VR4120 errata\n\
15627
-mfix-vr4120		work around certain VR4120 errata\n\
15527
-mfix-vr4130		work around VR4130 mflo/mfhi errata\n\
15628
-mfix-vr4130		work around VR4130 mflo/mfhi errata\n\
15528
-mfix-24k		insert a nop after ERET and DERET instructions\n\
15629
-mfix-24k		insert a nop after ERET and DERET instructions\n\
(-)a/gas/config/tc-mips.h (-1 / +1 lines)
Lines 59-65 extern char mips_nop_opcode (void); Link Here
59
extern void mips_handle_align (struct frag *);
59
extern void mips_handle_align (struct frag *);
60
#define HANDLE_ALIGN(fragp)  mips_handle_align (fragp)
60
#define HANDLE_ALIGN(fragp)  mips_handle_align (fragp)
61
61
62
#define MAX_MEM_FOR_RS_ALIGN_CODE  (1 + 2)
62
#define MAX_MEM_FOR_RS_ALIGN_CODE  (3 + 4)
63
63
64
struct insn_label_list;
64
struct insn_label_list;
65
struct mips_segment_info {
65
struct mips_segment_info {
(-)a/gas/doc/c-mips.texi (+13 lines)
Lines 172-177 This tells the assembler to accept MT instructions. Link Here
172
Cause nops to be inserted if the read of the destination register
172
Cause nops to be inserted if the read of the destination register
173
of an mfhi or mflo instruction occurs in the following two instructions.
173
of an mfhi or mflo instruction occurs in the following two instructions.
174
174
175
@item -mfix-loongson2f-jump
176
@itemx -mno-fix-loongson2f-jump
177
Eliminate instruction fetch from outside 256M region to work around the
178
Loongson2F @samp{jump} instructions. Without it, under extreme cases, kernel
179
may crash. The issue has been solved in latest processor batches, but this fix
180
has no side effect to them.
181
182
@item -mfix-loongson2f-nop
183
@itemx -mno-fix-loongson2f-nop
184
Replace nops by @code{or at,at,zero} to work around the Loongson2F @samp{nop}
185
errata. Without it, under extreme cases, cpu might deadlock. The issue has been
186
solved in latest loongson2f batches, but this fix has no side effect to them.
187
175
@item -mfix-vr4120
188
@item -mfix-vr4120
176
@itemx -no-mfix-vr4120
189
@itemx -no-mfix-vr4120
177
Insert nops to work around certain VR4120 errata.  This option is
190
Insert nops to work around certain VR4120 errata.  This option is
(-)a/gas/testsuite/gas/mips/loongson-2f-2.d (+18 lines)
Line 0 Link Here
1
#as: -mfix-loongson2f-nop
2
#objdump: -M reg-names=numeric -dr
3
#name: ST Microelectronics Loongson-2F workarounds of nop issue 
4
5
.*:     file format .*
6
7
8
Disassembly of section .text:
9
10
00000000 <loongson2f_nop_insn>:
11
   0:	00200825 	move	\$1,\$1
12
   4:	00200825 	move	\$1,\$1
13
   8:	00200825 	move	\$1,\$1
14
   c:	00200825 	move	\$1,\$1
15
  10:	00200825 	move	\$1,\$1
16
  14:	00200825 	move	\$1,\$1
17
  18:	00200825 	move	\$1,\$1
18
  1c:	00200825 	move	\$1,\$1
(-)a/gas/testsuite/gas/mips/loongson-2f-2.s (+10 lines)
Line 0 Link Here
1
# Test the work around of the NOP issue of loongson2F
2
	.text
3
	.set noreorder
4
5
	.align 5	# Test _implicit_ nops
6
loongson2f_nop_insn:
7
	nop		# Test _explicit_ nops
8
9
# align section end to 16-byte boundary for easier testing on multiple targets
10
	.p2align 4
(-)a/gas/testsuite/gas/mips/loongson-2f-3.d (+35 lines)
Line 0 Link Here
1
#as: -mfix-loongson2f-jump
2
#objdump: -M reg-names=numeric -dr
3
#name: ST Microelectronics Loongson-2F workarounds of Jump Instruction issue 
4
5
.*:     file format .*
6
7
8
Disassembly of section .text:
9
10
00000000 <.text>:
11
   0:	3c01cfff 	lui	\$1,0xcfff
12
   4:	3421ffff 	ori	\$1,\$1,0xffff
13
   8:	03c1f024 	and	\$30,\$30,\$1
14
   c:	03c00008 	jr	\$30
15
  10:	00000000 	nop
16
17
  14:	3c01cfff 	lui	\$1,0xcfff
18
  18:	3421ffff 	ori	\$1,\$1,0xffff
19
  1c:	03e1f824 	and	\$31,\$31,\$1
20
  20:	03e00008 	jr	\$31
21
  24:	00000000 	nop
22
23
  28:	3c01cfff 	lui	\$1,0xcfff
24
  2c:	3421ffff 	ori	\$1,\$1,0xffff
25
  30:	03c1f024 	and	\$30,\$30,\$1
26
  34:	03c0f809 	jalr	\$30
27
  38:	00000000 	nop
28
29
  3c:	00200008 	jr	\$1
30
  40:	00000000 	nop
31
32
  44:	08000000 	j	0x0
33
			44: R_MIPS_26	external_label
34
  48:	00000000 	nop
35
  4c:	00000000 	nop
(-)a/gas/testsuite/gas/mips/loongson-2f-3.s (+23 lines)
Line 0 Link Here
1
# Test the work around of the Jump instruction Issue of Loongson2F
2
	.text
3
	.set noreorder
4
5
	j	$30	# j with register
6
	 nop
7
8
	jr	$31	# jr
9
	 nop
10
11
	jalr	$30	# jalr
12
	 nop
13
14
	.set	noat
15
	jr	$1	# jr with at register and .set annotation
16
 	 nop
17
	.set	at
18
19
	j	external_label	# j with label
20
	 nop
21
22
# align section end to 16-byte boundary for easier testing on multiple targets
23
	.p2align 4
(-)a/gas/testsuite/gas/mips/mips.exp (+2 lines)
Lines 789-794 if { [istarget mips*-*-vxworks*] } { Link Here
789
789
790
    run_dump_test "loongson-2e"
790
    run_dump_test "loongson-2e"
791
    run_dump_test "loongson-2f"
791
    run_dump_test "loongson-2f"
792
    run_dump_test "loongson-2f-2"
793
    run_dump_test "loongson-2f-3"
792
794
793
    run_dump_test_arches "octeon"	[mips_arch_list_matching octeon]
795
    run_dump_test_arches "octeon"	[mips_arch_list_matching octeon]
794
    run_list_test_arches "octeon-ill" "" \
796
    run_list_test_arches "octeon-ill" "" \
(-)a/include/opcode/mips.h (+4 lines)
Lines 1106-1109 extern int bfd_mips_num_opcodes; Link Here
1106
extern const struct mips_opcode mips16_opcodes[];
1106
extern const struct mips_opcode mips16_opcodes[];
1107
extern const int bfd_mips16_num_opcodes;
1107
extern const int bfd_mips16_num_opcodes;
1108
1108
1109
/* Replace the original nops by "or at,at,zero",
1110
   Used to implement -mfix-loongson2f */
1111
#define LOONGSON2F_NOP_INSN	0x00200825
1112
1109
#endif /* _MIPS_H_ */
1113
#endif /* _MIPS_H_ */

Return to bug 338405