From 10a9829174397471ff95856c94aac352190ca7b9 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 1 May 2003 01:00:30 +0000 Subject: [PATCH] gas/ 2003-04-30 H.J. Lu * config/tc-ia64.c (ia64_number_to_chars): New function pointer. (ia64_float_to_chars): Likewise. (dot_byteorder): Set target_big_endian, ia64_number_to_chars and ia64_float_to_chars by tc_segment_info_data.endian from the current segment if byteorder == -1. (md_begin): Call dot_byteorder to set target_big_endian. (md_atof): Call ia64_float_to_chars to convert floating point. (ia64_float_to_chars_bigendian): New function. (ia64_float_to_chars_littleendian): Likewise. (ia64_elf_section_change_hook): Likewise. * config/tc-ia64.h (ia64_number_to_chars): New. (md_number_to_chars): Changed to (*ia64_number_to_chars) (ia64_elf_section_change_hook): New. (md_elf_section_change_hook): Defined. (ia64_segment_info_type): New struct. (TC_SEGMENT_INFO_TYPE): Defined. gas/testsuite/ 2003-04-30 H.J. Lu * gas/ia64/ia64.exp: Add order. * gas/ia64/order.s: New file. * gas/ia64/order.d: Likewise. --- gas/ChangeLog | 20 ++++++++ gas/config/tc-ia64.c | 85 +++++++++++++++++++++++++++++---- gas/config/tc-ia64.h | 17 ++++++- gas/testsuite/ChangeLog | 7 +++ gas/testsuite/gas/ia64/ia64.exp | 1 + gas/testsuite/gas/ia64/order.d | 36 ++++++++++++++ gas/testsuite/gas/ia64/order.s | 37 ++++++++++++++ 7 files changed, 191 insertions(+), 12 deletions(-) create mode 100644 gas/testsuite/gas/ia64/order.d create mode 100644 gas/testsuite/gas/ia64/order.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 87de95555bd..51a17244fb5 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,23 @@ +2003-04-30 H.J. Lu + + * config/tc-ia64.c (ia64_number_to_chars): New function pointer. + (ia64_float_to_chars): Likewise. + (dot_byteorder): Set target_big_endian, ia64_number_to_chars + and ia64_float_to_chars by tc_segment_info_data.endian from + the current segment if byteorder == -1. + (md_begin): Call dot_byteorder to set target_big_endian. + (md_atof): Call ia64_float_to_chars to convert floating point. + (ia64_float_to_chars_bigendian): New function. + (ia64_float_to_chars_littleendian): Likewise. + (ia64_elf_section_change_hook): Likewise. + + * config/tc-ia64.h (ia64_number_to_chars): New. + (md_number_to_chars): Changed to (*ia64_number_to_chars) + (ia64_elf_section_change_hook): New. + (md_elf_section_change_hook): Defined. + (ia64_segment_info_type): New struct. + (TC_SEGMENT_INFO_TYPE): Defined. + 2003-04-30 H.J. Lu * config/tc-ia64.c (md_section_align): Deleted. diff --git a/gas/config/tc-ia64.c b/gas/config/tc-ia64.c index 10a17a9c4fa..7b582aaaab9 100644 --- a/gas/config/tc-ia64.c +++ b/gas/config/tc-ia64.c @@ -156,6 +156,15 @@ struct label_fix extern int target_big_endian; +void (*ia64_number_to_chars) PARAMS ((char *, valueT, int)); + +static void ia64_float_to_chars_bigendian + PARAMS ((char *, LITTLENUM_TYPE *, int)); +static void ia64_float_to_chars_littleendian + PARAMS ((char *, LITTLENUM_TYPE *, int)); +static void (*ia64_float_to_chars) + PARAMS ((char *, LITTLENUM_TYPE *, int)); + /* Characters which always start a comment. */ const char comment_chars[] = ""; @@ -4308,7 +4317,32 @@ static void dot_byteorder (byteorder) int byteorder; { - target_big_endian = byteorder; + segment_info_type *seginfo = seg_info (now_seg); + + if (byteorder == -1) + { + if (seginfo->tc_segment_info_data.endian == 0) + seginfo->tc_segment_info_data.endian + = TARGET_BYTES_BIG_ENDIAN ? 1 : 2; + byteorder = seginfo->tc_segment_info_data.endian == 1; + } + else + seginfo->tc_segment_info_data.endian = byteorder ? 1 : 2; + + if (target_big_endian != byteorder) + { + target_big_endian = byteorder; + if (target_big_endian) + { + ia64_number_to_chars = number_to_chars_bigendian; + ia64_float_to_chars = ia64_float_to_chars_bigendian; + } + else + { + ia64_number_to_chars = number_to_chars_littleendian; + ia64_float_to_chars = ia64_float_to_chars_littleendian; + } + } } static void @@ -6535,7 +6569,10 @@ md_begin () bfd_set_section_alignment (stdoutput, text_section, 4); - target_big_endian = TARGET_BYTES_BIG_ENDIAN; + /* Make sure fucntion pointers get initialized. */ + target_big_endian = -1; + dot_byteorder (TARGET_BYTES_BIG_ENDIAN); + pseudo_func[FUNC_DTP_MODULE].u.sym = symbol_new (".", undefined_section, FUNC_DTP_MODULE, &zero_address_frag); @@ -10554,7 +10591,6 @@ md_atof (type, lit, size) int *size; { LITTLENUM_TYPE words[MAX_LITTLENUMS]; - LITTLENUM_TYPE *word; char *t; int prec; @@ -10589,19 +10625,18 @@ md_atof (type, lit, size) t = atof_ieee (input_line_pointer, type, words); if (t) input_line_pointer = t; - *size = prec * sizeof (LITTLENUM_TYPE); - for (word = words + prec - 1; prec--;) - { - md_number_to_chars (lit, (long) (*word--), sizeof (LITTLENUM_TYPE)); - lit += sizeof (LITTLENUM_TYPE); - } + (*ia64_float_to_chars) (lit, words, prec); + if (type == 'X') { /* It is 10 byte floating point with 6 byte padding. */ - memset (lit, 0, 6); + memset (&lit [10], 0, 6); *size = 8 * sizeof (LITTLENUM_TYPE); } + else + *size = prec * sizeof (LITTLENUM_TYPE); + return 0; } @@ -10656,3 +10691,33 @@ ia64_handle_align (fragp) memcpy (p, (target_big_endian ? be_nop : le_nop), 16); fragp->fr_var = 16; } + +static void +ia64_float_to_chars_bigendian (char *lit, LITTLENUM_TYPE *words, + int prec) +{ + while (prec--) + { + number_to_chars_bigendian (lit, (long) (*words++), + sizeof (LITTLENUM_TYPE)); + lit += sizeof (LITTLENUM_TYPE); + } +} + +static void +ia64_float_to_chars_littleendian (char *lit, LITTLENUM_TYPE *words, + int prec) +{ + while (prec--) + { + number_to_chars_littleendian (lit, (long) (words[prec]), + sizeof (LITTLENUM_TYPE)); + lit += sizeof (LITTLENUM_TYPE); + } +} + +void +ia64_elf_section_change_hook (void) +{ + dot_byteorder (-1); +} diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h index 37124ce5db1..e0c8171f35a 100644 --- a/gas/config/tc-ia64.h +++ b/gas/config/tc-ia64.h @@ -26,15 +26,28 @@ /* Linux is little endian by default. HPUX is big endian by default. */ #ifdef TE_HPUX -#define md_number_to_chars number_to_chars_bigendian #define TARGET_BYTES_BIG_ENDIAN 1 #define MD_FLAGS_DEFAULT EF_IA_64_BE #else -#define md_number_to_chars number_to_chars_littleendian #define TARGET_BYTES_BIG_ENDIAN 0 #define MD_FLAGS_DEFAULT EF_IA_64_ABI64 #endif /* TE_HPUX */ +extern void (*ia64_number_to_chars) PARAMS ((char *, valueT, int)); +#define md_number_to_chars (*ia64_number_to_chars) + +extern void ia64_elf_section_change_hook PARAMS ((void)); +#define md_elf_section_change_hook ia64_elf_section_change_hook + +/* We record the endian for this section. 0 means default, 1 means + big endian and 2 means little endian. */ +struct ia64_segment_info_type +{ + unsigned int endian : 2; +}; + +#define TC_SEGMENT_INFO_TYPE struct ia64_segment_info_type + /* We need to set the default object file format in ia64_init and not in md_begin. This is because parse_args is called before md_begin, and we do not want md_begin to wipe out the flag settings set by options parsed in diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index f8adc49db0a..54f489d9ea3 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2003-04-30 H.J. Lu + + * gas/ia64/ia64.exp: Add order. + + * gas/ia64/order.s: New file. + * gas/ia64/order.d: Likewise. + 2003-04-29 H.J. Lu * gas/ia64/ia64.exp: Add align. diff --git a/gas/testsuite/gas/ia64/ia64.exp b/gas/testsuite/gas/ia64/ia64.exp index deae264a19c..2e66eb7b40a 100644 --- a/gas/testsuite/gas/ia64/ia64.exp +++ b/gas/testsuite/gas/ia64/ia64.exp @@ -44,4 +44,5 @@ if [istarget "ia64-*"] then { run_dump_test "real" run_dump_test "align" + run_dump_test "order" } diff --git a/gas/testsuite/gas/ia64/order.d b/gas/testsuite/gas/ia64/order.d new file mode 100644 index 00000000000..4522ddf4b99 --- /dev/null +++ b/gas/testsuite/gas/ia64/order.d @@ -0,0 +1,36 @@ +#objdump: -j .foo -j .bar -rs +#name: ia64 byte order + +.*: +file format .* + +RELOCATION RECORDS FOR \[.foo\]: +OFFSET TYPE VALUE +0000000000000008 DIR64MSB foo +0000000000000018 DIR64MSB foo +0000000000000028 DIR64LSB foo +0000000000000038 DIR64LSB foo + + +RELOCATION RECORDS FOR \[.bar\]: +OFFSET TYPE VALUE +0000000000000010 DIR64LSB foo +0000000000000040 DIR64LSB foo +0000000000000058 DIR64MSB foo +0000000000000080 DIR64MSB foo + + +Contents of section .foo: + 0000 12340000 12345678 00000000 00000000 ................ + 0010 01234567 89abcdef 00000000 00000000 ................ + 0020 34120000 78563412 00000000 00000000 ................ + 0030 efcdab89 67452301 00000000 00000000 ................ +Contents of section .bar: + 0000 cdcccc3d 00000000 9a999999 9999c93f ................ + 0010 00000000 00000000 00000000 00000000 ................ + 0020 cdcccccc cccccccc fd3f0000 00000000 ................ + 0030 cdcccccc cccccccc fe3f0000 00000000 ................ + 0040 00000000 00000000 3dcccccd 00000000 ................ + 0050 3fc99999 9999999a 00000000 00000000 ................ + 0060 3ffdcccc cccccccc cccd0000 00000000 ................ + 0070 3ffecccc cccccccc cccd0000 00000000 ................ + 0080 00000000 00000000 ........ diff --git a/gas/testsuite/gas/ia64/order.s b/gas/testsuite/gas/ia64/order.s new file mode 100644 index 00000000000..2867ce081ba --- /dev/null +++ b/gas/testsuite/gas/ia64/order.s @@ -0,0 +1,37 @@ + .global foo# + .section .foo,"aw","progbits" + .msb + data2 0x1234 + data4 0x12345678 + data8 foo# + .section .bar,"aw","progbits" + .lsb + real4 0.1 + real8 0.2 + data8 foo# + .section .foo,"aw","progbits" + data8 0x123456789abcdef +// data16 0x123456789abcdef + data8 foo# + .section .bar,"aw","progbits" + real10 0.4 + real16 0.8 + data8 foo# + .section .foo,"aw","progbits" + .lsb + data2 0x1234 + data4 0x12345678 + data8 foo# + .section .bar,"aw","progbits" + .msb + real4 0.1 + real8 0.2 + data8 foo# + .section .foo,"aw","progbits" + data8 0x123456789abcdef +// data16 0x123456789abcdef + data8 foo# + .section .bar,"aw","progbits" + real10 0.4 + real16 0.8 + data8 foo# -- 2.30.2