From 2f0c79aa61e82cbc5da4b9ab399362b2cdd8ea2e Mon Sep 17 00:00:00 2001 From: Han Shen Date: Wed, 10 Jun 2015 14:50:26 -0700 Subject: [PATCH] [gold][aarch64] Fix erratum 835769. gold/ChangeLog: * aarch64.cc (AArch64_insn_utilities::BYTES_PER_INSN): Move defintion outside class definition. (AArch64_insn_utilities::AARCH64_ZR): New static constant. (AArch64_insn_utilities::aarch64_op31): New member. (AArch64_insn_utilities::aarch64_ra): New member. (AArch64_insn_utilities::aarch64_mac): New member. (AArch64_insn_utilities::aarch64_mlxl): New member. (ST_E_835769): New global enum member. (Stub_table::relocate_stubs): Add 835769 handler. (Stub_template_repertoire::Stub_template_repertoire): Install new stub type. (AArch64_relobj::scan_errata): This func is renamed from scan_erratum_843419. (AArch64_relobj::do_count_local_symbols): Add 835769 handler. (AArch64_relobj::do_relocate_sections): Add 835769 handler. (AArch64_relobj::scan_sections_for_stubs): Add 835769 handler. (Target_aarch64::scan_erratum_835769_span): New method. (Target_aarch64::create_erratum_stub): New method. (Target_aarch64::is_erratum_835769_sequence): New method. (Target_aarch64::scan_erratum_843419_sequence): Move part of the code into create_erratum_stub. * options.h (fix_cortex_a53_835769): New option. --- gold/ChangeLog | 27 ++++++ gold/aarch64.cc | 293 ++++++++++++++++++++++++++++++++++++++++++++++++-------- gold/options.h | 9 +- 3 files changed, 285 insertions(+), 44 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 7039dd2..7e9997d 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,30 @@ +2015-06-12 Han Shen + + Fix erratum 835769. + + * aarch64.cc (AArch64_insn_utilities::BYTES_PER_INSN): Move + defintion outside class definition. + (AArch64_insn_utilities::AARCH64_ZR): New static constant. + (AArch64_insn_utilities::aarch64_op31): New member. + (AArch64_insn_utilities::aarch64_ra): New member. + (AArch64_insn_utilities::aarch64_mac): New member. + (AArch64_insn_utilities::aarch64_mlxl): New member. + (ST_E_835769): New global enum member. + (Stub_table::relocate_stubs): Add 835769 handler. + (Stub_template_repertoire::Stub_template_repertoire): Install new + stub type. + (AArch64_relobj::scan_errata): This func is renamed from + scan_erratum_843419. + (AArch64_relobj::do_count_local_symbols): Add 835769 handler. + (AArch64_relobj::do_relocate_sections): Add 835769 handler. + (AArch64_relobj::scan_sections_for_stubs): Add 835769 handler. + (Target_aarch64::scan_erratum_835769_span): New method. + (Target_aarch64::create_erratum_stub): New method. + (Target_aarch64::is_erratum_835769_sequence): New method. + (Target_aarch64::scan_erratum_843419_sequence): Move part of the + code into create_erratum_stub. + * options.h (fix_cortex_a53_835769): New option. + 2015-06-11 Cary Coutant * aarch64.cc (Erratum_stub::STUB_ADDR_ALIGN): Move initialization diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 8dfd933..72a65db 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -77,7 +77,10 @@ class AArch64_insn_utilities public: typedef typename elfcpp::Swap<32, big_endian>::Valtype Insntype; - static const int BYTES_PER_INSN = 4; + static const int BYTES_PER_INSN; + + // Zero register encoding - 31. + static const unsigned int AARCH64_ZR; static unsigned int aarch64_bit(Insntype insn, int pos) @@ -87,6 +90,18 @@ public: aarch64_bits(Insntype insn, int pos, int l) { return (insn >> pos) & ((1 << l) - 1); } + // Get the encoding field "op31" of 3-source data processing insns. "op31" is + // the name defined in armv8 insn manual C3.5.9. + static unsigned int + aarch64_op31(Insntype insn) + { return aarch64_bits(insn, 21, 3); } + + // Get the encoding field "ra" of 3-source data processing insns. "ra" is the + // third source register. See armv8 insn manual C3.5.9. + static unsigned int + aarch64_ra(Insntype insn) + { return aarch64_bits(insn, 10, 5); } + static bool is_adrp(const Insntype insn) { return (insn & 0x9F000000) == 0x90000000; } @@ -330,8 +345,42 @@ public: return true; } return false; + } // End of "aarch64_mem_op_p". + + // Return true if INSN is mac insn. + static bool + aarch64_mac(Insntype insn) + { return (insn & 0xff000000) == 0x9b000000; } + + // Return true if INSN is multiply-accumulate. + // (This is similar to implementaton in elfnn-aarch64.c.) + static bool + aarch64_mlxl(Insntype insn) + { + uint32_t op31 = aarch64_op31(insn); + if (aarch64_mac(insn) + && (op31 == 0 || op31 == 1 || op31 == 5) + /* Exclude MUL instructions which are encoded as a multiple-accumulate + with RA = XZR. */ + && aarch64_ra(insn) != AARCH64_ZR) + { + return true; + } + return false; } -}; +}; // End of "AArch64_insn_utilities". + + +// Insn length in byte. + +template +const int AArch64_insn_utilities::BYTES_PER_INSN = 4; + + +// Zero register encoding - 31. + +template +const unsigned int AArch64_insn_utilities::AARCH64_ZR = 0x1f; // Output_data_got_aarch64 class. @@ -603,8 +652,11 @@ enum // Stub for erratum 843419 handling. ST_E_843419 = 4, + // Stub for erratum 835769 handling. + ST_E_835769 = 5, + // Number of total stub types. - ST_NUMBER = 5 + ST_NUMBER = 6 }; @@ -695,6 +747,9 @@ Stub_template_repertoire::Stub_template_repertoire() 0x14000000, /* b