Index: gold/ChangeLog =================================================================== RCS file: /cvs/src/src/gold/ChangeLog,v retrieving revision 1.1017 diff -r1.1017 ChangeLog 0a1,6 > 2012-12-19 Ben Cheng > > * arm.cc (Target_arm::attributes_accept_div): New function. > (Target_arm::attributes_forbid_div): New function. > (Target_arm::merge_object_attributes): Merge the Tag_DIV_use attribute using the same new functions as what bfd/elf32_arm.c does. > Index: gold/arm.cc =================================================================== RCS file: /cvs/src/src/gold/arm.cc,v retrieving revision 1.160 diff -r1.160 arm.cc 2800a2801,2812 > // Query attributes object to see if integer divide instructions may be > // present in an object. > static bool > attributes_accept_div(int arch, int profile, > const Object_attribute* div_attr); > > // Query attributes object to see if integer divide instructions are > // forbidden to be in the object. This is not the inverse of > // attributes_accept_div. > static bool > attributes_forbid_div(const Object_attribute* div_attr); > 10384a10397,10438 > // Query attributes object to see if integer divide instructions may be > // present in an object. > > template > bool > Target_arm::attributes_accept_div(int arch, int profile, > const Object_attribute* div_attr) > { > switch (div_attr->int_value()) > { > case 0: > /* Integer divide allowed if instruction contained in archetecture. */ > if (arch == elfcpp::TAG_CPU_ARCH_V7 && (profile == 'R' || profile == 'M')) > return true; > else if (arch >= elfcpp::TAG_CPU_ARCH_V7E_M) > return true; > else > return false; > > case 1: > /* Integer divide explicitly prohibited. */ > return false; > > default: > /* Unrecognised case - treat as allowing divide everywhere. */ > case 2: > /* Integer divide allowed in ARM state. */ > return true; > } > } > > // Query attributes object to see if integer divide instructions are > // forbidden to be in the object. This is not the inverse of > // attributes_accept_div. > > template > bool > Target_arm::attributes_forbid_div(const Object_attribute* div_attr) > { > return div_attr->int_value() == 1; > } > 10753,10772c10807,10828 < case elfcpp::Tag_DIV_use: < // This tag is set to zero if we can use UDIV and SDIV in Thumb < // mode on a v7-M or v7-R CPU; to one if we can not use UDIV or < // SDIV at all; and to two if we can use UDIV or SDIV on a v7-A < // CPU. We will merge as follows: If the input attribute's value < // is one then the output attribute's value remains unchanged. If < // the input attribute's value is zero or two then if the output < // attribute's value is one the output value is set to the input < // value, otherwise the output value must be the same as the < // inputs. */ < if (in_attr[i].int_value() != 1 && out_attr[i].int_value() != 1) < { < if (in_attr[i].int_value() != out_attr[i].int_value()) < { < gold_error(_("DIV usage mismatch between %s and output"), < name); < } < } < < if (in_attr[i].int_value() != 1) --- > case elfcpp::Tag_DIV_use: { > // A value of zero on input means that the divide instruction may > // be used if available in the base architecture as specified via > // Tag_CPU_arch and Tag_CPU_arch_profile. A value of 1 means that > // the user did not want divide instructions. A value of 2 > // explicitly means that divide instructions were allowed in ARM > // and Thumb state. > int arch = this-> > get_aeabi_object_attribute(elfcpp::Tag_CPU_arch)-> > int_value(); > int profile = this-> > get_aeabi_object_attribute(elfcpp::Tag_CPU_arch_profile)-> > int_value(); > if (in_attr[i].int_value() == out_attr[i].int_value()) > /* Do nothing. */ ; > else if (attributes_forbid_div(&in_attr[i]) > && !attributes_accept_div(arch, profile, &out_attr[i])) > out_attr[i].set_int_value(1); > else if (attributes_forbid_div(&out_attr[i]) > && attributes_accept_div(arch, profile, &in_attr[i])) > out_attr[i].set_int_value(in_attr[i].int_value()); > else if (in_attr[i].int_value() == 2) 10774d10829 < 10775a10831 > }