diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2010-03-07 18:45:46 +0100 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2010-03-07 18:45:46 +0100 |
commit | 3534f08c85eea82516f24dc415f45abd27ee0f94 (patch) | |
tree | 72149d306fb0cb019afd654196720253217d47db /toolchain | |
parent | d75cbd79e9feecccfb1ce8b6e696c5987badde6b (diff) |
add binutils patch
Diffstat (limited to 'toolchain')
-rw-r--r-- | toolchain/binutils/patches/lemote-fix.patch | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/toolchain/binutils/patches/lemote-fix.patch b/toolchain/binutils/patches/lemote-fix.patch new file mode 100644 index 000000000..74d240e21 --- /dev/null +++ b/toolchain/binutils/patches/lemote-fix.patch @@ -0,0 +1,362 @@ +diff -Nur binutils-2.20.orig/gas/config/tc-mips.c binutils-2.20/gas/config/tc-mips.c +--- binutils-2.20.orig/gas/config/tc-mips.c 2009-09-22 17:41:00.000000000 +0200 ++++ binutils-2.20/gas/config/tc-mips.c 2010-03-06 18:44:16.000000000 +0100 +@@ -761,6 +761,15 @@ + NUM_FIX_VR4120_CLASSES + }; + ++/* ...likewise -mfix-loongson2f-jump. */ ++static int mips_fix_loongson2f_jump; ++ ++/* ...likewise -mfix-loongson2f-nop. */ ++static int mips_fix_loongson2f_nop; ++ ++/* True if -mfix-loongson2f-nop or -mfix-loongson2f-jump passed */ ++static int mips_fix_loongson2f; ++ + /* Given two FIX_VR4120_* values X and Y, bit Y of element X is set if + there must be at least one other instruction between an instruction + of type X and an instruction of type Y. */ +@@ -1918,6 +1927,8 @@ + if (nop_insn.insn_mo == NULL && strcmp (name, "nop") == 0) + { + create_insn (&nop_insn, mips_opcodes + i); ++ if (mips_fix_loongson2f_nop) ++ nop_insn.insn_opcode = LOONGSON2F_NOP_INSN; + nop_insn.fixed_p = 1; + } + } +@@ -2731,6 +2742,53 @@ + return nops; + } + ++static void ++macro_build (expressionS *ep, const char *name, const char *fmt, ...); ++ ++static void fix_loongson2f_nop(struct mips_cl_insn *ip) ++{ ++ /* Fix NOP issue: Replace nops by "or at,at,zero" */ ++ if (strcmp(ip->insn_mo->name, "nop") == 0) ++ ip->insn_opcode = LOONGSON2F_NOP_INSN; ++} ++ ++static void fix_loongson2f_jump(struct mips_cl_insn *ip) ++{ ++ ++ /* Fix Jump Issue: Eliminate instruction fetch from outside 256M region ++ * jr target pc &= 'hffff_ffff_cfff_ffff ++ */ ++ if (strcmp(ip->insn_mo->name, "j") == 0 ++ || strcmp(ip->insn_mo->name, "jr") == 0 ++ || strcmp(ip->insn_mo->name, "jalr") == 0) ++ { ++ int sreg; ++ expressionS ep; ++ ++ if (! mips_opts.at) ++ return; ++ ++ sreg = EXTRACT_OPERAND (RS, *ip); ++ if (sreg == ZERO || sreg == KT0 || sreg == KT1 || sreg == ATREG) ++ return; ++ ++ ep.X_op = O_constant; ++ ep.X_add_number = 0xcfff0000; ++ macro_build (&ep, "lui", "t,u", ATREG, BFD_RELOC_HI16); ++ ep.X_add_number = 0xffff; ++ macro_build (&ep, "ori", "t,r,i", ATREG, ATREG, BFD_RELOC_LO16); ++ macro_build (NULL, "and", "d,v,t", sreg, sreg, ATREG); ++ } ++} ++ ++static void fix_loongson2f(struct mips_cl_insn *ip) ++{ ++ if (mips_fix_loongson2f_nop) ++ fix_loongson2f_nop(ip); ++ if (mips_fix_loongson2f_jump) ++ fix_loongson2f_jump(ip); ++} ++ + /* Output an instruction. IP is the instruction information. + ADDRESS_EXPR is an operand of the instruction to be used with + RELOC_TYPE. */ +@@ -2744,6 +2802,9 @@ + bfd_boolean relaxed_branch = FALSE; + segment_info_type *si = seg_info (now_seg); + ++ if (mips_fix_loongson2f) ++ fix_loongson2f(ip); ++ + /* Mark instruction labels in mips16 mode. */ + mips16_mark_labels (); + +@@ -11220,6 +11281,10 @@ + OPTION_MNO_7000_HILO_FIX, + OPTION_FIX_24K, + OPTION_NO_FIX_24K, ++ OPTION_FIX_LOONGSON2F_JUMP, ++ OPTION_NO_FIX_LOONGSON2F_JUMP, ++ OPTION_FIX_LOONGSON2F_NOP, ++ OPTION_NO_FIX_LOONGSON2F_NOP, + OPTION_FIX_VR4120, + OPTION_NO_FIX_VR4120, + OPTION_FIX_VR4130, +@@ -11308,6 +11373,10 @@ + {"mfix7000", no_argument, NULL, OPTION_M7000_HILO_FIX}, + {"no-fix-7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX}, + {"mno-fix7000", no_argument, NULL, OPTION_MNO_7000_HILO_FIX}, ++ {"mfix-loongson2f-jump", no_argument, NULL, OPTION_FIX_LOONGSON2F_JUMP}, ++ {"mno-fix-loongson2f-jump", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_JUMP}, ++ {"mfix-loongson2f-nop", no_argument, NULL, OPTION_FIX_LOONGSON2F_NOP}, ++ {"mno-fix-loongson2f-nop", no_argument, NULL, OPTION_NO_FIX_LOONGSON2F_NOP}, + {"mfix-vr4120", no_argument, NULL, OPTION_FIX_VR4120}, + {"mno-fix-vr4120", no_argument, NULL, OPTION_NO_FIX_VR4120}, + {"mfix-vr4130", no_argument, NULL, OPTION_FIX_VR4130}, +@@ -11575,6 +11644,22 @@ + mips_fix_24k = 0; + break; + ++ case OPTION_FIX_LOONGSON2F_JUMP: ++ mips_fix_loongson2f_jump = 1; ++ break; ++ ++ case OPTION_NO_FIX_LOONGSON2F_JUMP: ++ mips_fix_loongson2f_jump = 0; ++ break; ++ ++ case OPTION_FIX_LOONGSON2F_NOP: ++ mips_fix_loongson2f_nop = 1; ++ break; ++ ++ case OPTION_NO_FIX_LOONGSON2F_NOP: ++ mips_fix_loongson2f_nop = 0; ++ break; ++ + case OPTION_FIX_VR4120: + mips_fix_vr4120 = 1; + break; +@@ -11789,6 +11874,8 @@ + return 0; + } + ++ mips_fix_loongson2f = mips_fix_loongson2f_nop || mips_fix_loongson2f_jump; ++ + return 1; + } + +@@ -14794,6 +14881,8 @@ + mips_handle_align (fragS *fragp) + { + char *p; ++ int bytes, size, excess; ++ valueT opcode; + + if (fragp->fr_type != rs_align_code) + return; +@@ -14801,17 +14890,27 @@ + p = fragp->fr_literal + fragp->fr_fix; + if (*p) + { +- int bytes; ++ opcode = mips16_nop_insn.insn_opcode; ++ size = 2; ++ } ++ else ++ { ++ opcode = nop_insn.insn_opcode; ++ size = 4; ++ } + +- bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; +- if (bytes & 1) +- { +- *p++ = 0; +- fragp->fr_fix++; +- } +- md_number_to_chars (p, mips16_nop_insn.insn_opcode, 2); +- fragp->fr_var = 2; ++ bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; ++ excess = bytes % size; ++ if (excess != 0) ++ { ++ /* If we're not inserting a whole number of instructions, pad the ++ end of the fixed part of the frag with zeros */ ++ memset (p, 0, excess); ++ p += excess; ++ fragp->fr_fix += excess; + } ++ md_number_to_chars (p, opcode, size); ++ fragp->fr_var = size; + } + + static void +@@ -15523,6 +15622,8 @@ + -mmt generate MT instructions\n\ + -mno-mt do not generate MT instructions\n")); + fprintf (stream, _("\ ++-mfix-loongson2f-jump work around Loongson2F JUMP instructions\ ++-mfix-loongson2f-nop work around Loongson2F NOP errata\n\ + -mfix-vr4120 work around certain VR4120 errata\n\ + -mfix-vr4130 work around VR4130 mflo/mfhi errata\n\ + -mfix-24k insert a nop after ERET and DERET instructions\n\ +diff -Nur binutils-2.20.orig/gas/config/tc-mips.h binutils-2.20/gas/config/tc-mips.h +--- binutils-2.20.orig/gas/config/tc-mips.h 2009-09-02 09:24:20.000000000 +0200 ++++ binutils-2.20/gas/config/tc-mips.h 2010-03-06 18:44:16.000000000 +0100 +@@ -59,7 +59,7 @@ + extern void mips_handle_align (struct frag *); + #define HANDLE_ALIGN(fragp) mips_handle_align (fragp) + +-#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2) ++#define MAX_MEM_FOR_RS_ALIGN_CODE (3 + 4) + + struct insn_label_list; + struct mips_segment_info { +diff -Nur binutils-2.20.orig/gas/doc/c-mips.texi binutils-2.20/gas/doc/c-mips.texi +--- binutils-2.20.orig/gas/doc/c-mips.texi 2009-09-28 12:23:57.000000000 +0200 ++++ binutils-2.20/gas/doc/c-mips.texi 2010-03-06 18:44:16.000000000 +0100 +@@ -172,6 +172,19 @@ + Cause nops to be inserted if the read of the destination register + of an mfhi or mflo instruction occurs in the following two instructions. + ++@item -mfix-loongson2f-jump ++@itemx -mno-fix-loongson2f-jump ++Eliminate instruction fetch from outside 256M region to work around the ++Loongson2F @samp{jump} instructions. Without it, under extreme cases, kernel ++may crash. The issue has been solved in latest processor batches, but this fix ++has no side effect to them. ++ ++@item -mfix-loongson2f-nop ++@itemx -mno-fix-loongson2f-nop ++Replace nops by @code{or at,at,zero} to work around the Loongson2F @samp{nop} ++errata. Without it, under extreme cases, cpu might deadlock. The issue has been ++solved in latest loongson2f batches, but this fix has no side effect to them. ++ + @item -mfix-vr4120 + @itemx -no-mfix-vr4120 + Insert nops to work around certain VR4120 errata. This option is +diff -Nur binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-2.d binutils-2.20/gas/testsuite/gas/mips/loongson-2f-2.d +--- binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-2.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.20/gas/testsuite/gas/mips/loongson-2f-2.d 2010-03-06 18:44:16.000000000 +0100 +@@ -0,0 +1,18 @@ ++#as: -mfix-loongson2f-nop ++#objdump: -M reg-names=numeric -dr ++#name: ST Microelectronics Loongson-2F workarounds of nop issue ++ ++.*: file format .* ++ ++ ++Disassembly of section .text: ++ ++00000000 <loongson2f_nop_insn>: ++ 0: 00200825 move \$1,\$1 ++ 4: 00200825 move \$1,\$1 ++ 8: 00200825 move \$1,\$1 ++ c: 00200825 move \$1,\$1 ++ 10: 00200825 move \$1,\$1 ++ 14: 00200825 move \$1,\$1 ++ 18: 00200825 move \$1,\$1 ++ 1c: 00200825 move \$1,\$1 +diff -Nur binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-2.s binutils-2.20/gas/testsuite/gas/mips/loongson-2f-2.s +--- binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-2.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.20/gas/testsuite/gas/mips/loongson-2f-2.s 2010-03-06 18:44:16.000000000 +0100 +@@ -0,0 +1,10 @@ ++# Test the work around of the NOP issue of loongson2F ++ .text ++ .set noreorder ++ ++ .align 5 # Test _implicit_ nops ++loongson2f_nop_insn: ++ nop # Test _explicit_ nops ++ ++# align section end to 16-byte boundary for easier testing on multiple targets ++ .p2align 4 +diff -Nur binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-3.d binutils-2.20/gas/testsuite/gas/mips/loongson-2f-3.d +--- binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-3.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.20/gas/testsuite/gas/mips/loongson-2f-3.d 2010-03-06 18:44:16.000000000 +0100 +@@ -0,0 +1,35 @@ ++#as: -mfix-loongson2f-jump ++#objdump: -M reg-names=numeric -dr ++#name: ST Microelectronics Loongson-2F workarounds of Jump Instruction issue ++ ++.*: file format .* ++ ++ ++Disassembly of section .text: ++ ++00000000 <.text>: ++ 0: 3c01cfff lui \$1,0xcfff ++ 4: 3421ffff ori \$1,\$1,0xffff ++ 8: 03c1f024 and \$30,\$30,\$1 ++ c: 03c00008 jr \$30 ++ 10: 00000000 nop ++ ++ 14: 3c01cfff lui \$1,0xcfff ++ 18: 3421ffff ori \$1,\$1,0xffff ++ 1c: 03e1f824 and \$31,\$31,\$1 ++ 20: 03e00008 jr \$31 ++ 24: 00000000 nop ++ ++ 28: 3c01cfff lui \$1,0xcfff ++ 2c: 3421ffff ori \$1,\$1,0xffff ++ 30: 03c1f024 and \$30,\$30,\$1 ++ 34: 03c0f809 jalr \$30 ++ 38: 00000000 nop ++ ++ 3c: 00200008 jr \$1 ++ 40: 00000000 nop ++ ++ 44: 08000000 j 0x0 ++ 44: R_MIPS_26 external_label ++ 48: 00000000 nop ++ 4c: 00000000 nop +diff -Nur binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-3.s binutils-2.20/gas/testsuite/gas/mips/loongson-2f-3.s +--- binutils-2.20.orig/gas/testsuite/gas/mips/loongson-2f-3.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.20/gas/testsuite/gas/mips/loongson-2f-3.s 2010-03-06 18:44:16.000000000 +0100 +@@ -0,0 +1,23 @@ ++# Test the work around of the Jump instruction Issue of Loongson2F ++ .text ++ .set noreorder ++ ++ j $30 # j with register ++ nop ++ ++ jr $31 # jr ++ nop ++ ++ jalr $30 # jalr ++ nop ++ ++ .set noat ++ jr $1 # jr with at register and .set annotation ++ nop ++ .set at ++ ++ j external_label # j with label ++ nop ++ ++# align section end to 16-byte boundary for easier testing on multiple targets ++ .p2align 4 +diff -Nur binutils-2.20.orig/gas/testsuite/gas/mips/mips.exp binutils-2.20/gas/testsuite/gas/mips/mips.exp +--- binutils-2.20.orig/gas/testsuite/gas/mips/mips.exp 2009-09-22 17:41:03.000000000 +0200 ++++ binutils-2.20/gas/testsuite/gas/mips/mips.exp 2010-03-06 18:44:16.000000000 +0100 +@@ -789,6 +789,8 @@ + + run_dump_test "loongson-2e" + run_dump_test "loongson-2f" ++ run_dump_test "loongson-2f-2" ++ run_dump_test "loongson-2f-3" + + run_dump_test_arches "octeon" [mips_arch_list_matching octeon] + run_list_test_arches "octeon-ill" "" \ +diff -Nur binutils-2.20.orig/include/opcode/mips.h binutils-2.20/include/opcode/mips.h +--- binutils-2.20.orig/include/opcode/mips.h 2009-09-02 09:21:40.000000000 +0200 ++++ binutils-2.20/include/opcode/mips.h 2010-03-06 18:44:16.000000000 +0100 +@@ -1106,4 +1106,8 @@ + extern const struct mips_opcode mips16_opcodes[]; + extern const int bfd_mips16_num_opcodes; + ++/* Replace the original nops by "or at,at,zero", ++ Used to implement -mfix-loongson2f */ ++#define LOONGSON2F_NOP_INSN 0x00200825 ++ + #endif /* _MIPS_H_ */ |