gas/ChangeLog 2003-12-02 Kazuhiro Inaoka * config/tc-m32r.c : Add new machine m32r2. Add new instructions. (line_separator_chars) : Use '!'. * config/tc-m32r.h : Add new machine m32r2. Index: gas/config/tc-m32r.c =================================================================== RCS file: /cvs/src/src/gas/config/tc-m32r.c,v retrieving revision 1.31 diff -c -r1.31 tc-m32r.c *** gas/config/tc-m32r.c 22 Nov 2003 02:35:30 -0000 1.31 --- gas/config/tc-m32r.c 2 Dec 2003 08:56:11 -0000 *************** *** 27,32 **** --- 27,33 ---- #include "opcodes/m32r-desc.h" #include "opcodes/m32r-opc.h" #include "cgen.h" + #include "elf/m32r.h" /* Linked list of symbols that are debugging symbols to be defined as the beginning of the current instruction. */ *************** *** 93,113 **** shouldn't assume or require it to). */ static int warn_unmatched_high = 0; ! /* Non-zero if -m32rx has been specified, in which case support for the ! extended M32RX instruction set should be enabled. */ ! static int enable_m32rx = 0; /* Non-zero if -m32rx -hidden has been specified, in which case support for the special M32RX instruction set should be enabled. */ static int enable_special = 0; /* Non-zero if the programmer should be warned when an explicit parallel instruction might have constraint violations. */ static int warn_explicit_parallel_conflicts = 1; /* Non-zero if insns can be made parallel. */ static int optimize; /* Stuff for .scomm symbols. */ static segT sbss_section; static asection scom_section; --- 94,136 ---- shouldn't assume or require it to). */ static int warn_unmatched_high = 0; ! /* 1 if -m32rx has been specified, in which case support for the ! extended M32RX instruction set should be enabled. ! 2 if -m32r2 has been specified, in which case support for the ! extended M32R2 instruction set should be enabled. ! */ ! static int enable_m32rx = 0; /* default M32R */ /* Non-zero if -m32rx -hidden has been specified, in which case support for the special M32RX instruction set should be enabled. */ static int enable_special = 0; + /* Non-zero if -bitinst has been specified, in which case support for + extended M32R bit-field instruction set should be enabled. */ + static int enable_special_m32r = 0; + + /* Non-zero if -float has been specified, in which case support for + extended M32R floating point instruction set should be enabled. */ + static int enable_special_float = 0; + /* Non-zero if the programmer should be warned when an explicit parallel instruction might have constraint violations. */ static int warn_explicit_parallel_conflicts = 1; + /* Non-zero if the programmer should be errored when an explicit parallel + instruction might have constraint violations. */ + static int error_explicit_parallel_conflicts = 1; + + /* Non-zero if insns can be made parallel. */ + static int use_parallel = -1; + /* Non-zero if insns can be made parallel. */ static int optimize; + /* m32r er_flags */ + static int m32r_flags = 0; + + /* Stuff for .scomm symbols. */ static segT sbss_section; static asection scom_section; *************** *** 115,121 **** const char comment_chars[] = ";"; const char line_comment_chars[] = "#"; ! const char line_separator_chars[] = ""; const char EXP_CHARS[] = "eE"; const char FLT_CHARS[] = "dD"; --- 138,144 ---- const char comment_chars[] = ";"; const char line_comment_chars[] = "#"; ! const char line_separator_chars[] = "!"; const char EXP_CHARS[] = "eE"; const char FLT_CHARS[] = "dD"; *************** *** 146,163 **** static struct m32r_hi_fixup *m32r_hi_fixup_list; ! static void allow_m32rx PARAMS ((int)); static void ! allow_m32rx (on) ! int on; { enable_m32rx = on; if (stdoutput != NULL) ! bfd_set_arch_mach (stdoutput, TARGET_ARCH, ! enable_m32rx ? bfd_mach_m32rx : bfd_mach_m32r); } #define M32R_SHORTOPTS "O" --- 169,197 ---- static struct m32r_hi_fixup *m32r_hi_fixup_list; ! struct { ! enum bfd_architecture bfd_mach; ! int mach_flags; ! } mach_table[] = ! { ! { bfd_mach_m32r, (1<machs = mach_table[on].mach_flags; } + #define M32R_SHORTOPTS "O" *************** *** 167,184 **** { #define OPTION_M32R (OPTION_MD_BASE) #define OPTION_M32RX (OPTION_M32R + 1) ! #define OPTION_WARN_PARALLEL (OPTION_M32RX + 1) #define OPTION_NO_WARN_PARALLEL (OPTION_WARN_PARALLEL + 1) ! #define OPTION_SPECIAL (OPTION_NO_WARN_PARALLEL + 1) ! #define OPTION_WARN_UNMATCHED (OPTION_SPECIAL + 1) #define OPTION_NO_WARN_UNMATCHED (OPTION_WARN_UNMATCHED + 1) {"m32r", no_argument, NULL, OPTION_M32R}, {"m32rx", no_argument, NULL, OPTION_M32RX}, {"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN_PARALLEL}, {"Wp", no_argument, NULL, OPTION_WARN_PARALLEL}, {"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN_PARALLEL}, {"Wnp", no_argument, NULL, OPTION_NO_WARN_PARALLEL}, {"hidden", no_argument, NULL, OPTION_SPECIAL}, /* Sigh. I guess all warnings must now have both variants. */ {"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED}, {"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED}, --- 201,240 ---- { #define OPTION_M32R (OPTION_MD_BASE) #define OPTION_M32RX (OPTION_M32R + 1) ! #define OPTION_M32R2 (OPTION_M32RX + 1) ! #define OPTION_BIG (OPTION_M32R2 + 1) ! #define OPTION_LITTLE (OPTION_BIG + 1) ! #define OPTION_PARALLEL (OPTION_LITTLE + 1) ! #define OPTION_NO_PARALLEL (OPTION_PARALLEL + 1) ! #define OPTION_WARN_PARALLEL (OPTION_NO_PARALLEL + 1) #define OPTION_NO_WARN_PARALLEL (OPTION_WARN_PARALLEL + 1) ! #define OPTION_ERROR_PARALLEL (OPTION_NO_WARN_PARALLEL + 1) ! #define OPTION_NO_ERROR_PARALLEL (OPTION_ERROR_PARALLEL + 1) ! #define OPTION_SPECIAL (OPTION_NO_ERROR_PARALLEL + 1) ! #define OPTION_SPECIAL_M32R (OPTION_SPECIAL + 1) ! #define OPTION_SPECIAL_FLOAT (OPTION_SPECIAL_M32R + 1) ! #define OPTION_WARN_UNMATCHED (OPTION_SPECIAL_FLOAT + 1) #define OPTION_NO_WARN_UNMATCHED (OPTION_WARN_UNMATCHED + 1) {"m32r", no_argument, NULL, OPTION_M32R}, {"m32rx", no_argument, NULL, OPTION_M32RX}, + {"m32r2", no_argument, NULL, OPTION_M32R2}, + {"big", no_argument, NULL, OPTION_BIG}, + {"little", no_argument, NULL, OPTION_LITTLE}, + {"EB", no_argument, NULL, OPTION_BIG}, + {"EL", no_argument, NULL, OPTION_LITTLE}, + {"parallel", no_argument, NULL, OPTION_PARALLEL}, + {"no-parallel", no_argument, NULL, OPTION_NO_PARALLEL}, {"warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_WARN_PARALLEL}, {"Wp", no_argument, NULL, OPTION_WARN_PARALLEL}, {"no-warn-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_WARN_PARALLEL}, {"Wnp", no_argument, NULL, OPTION_NO_WARN_PARALLEL}, + {"error-explicit-parallel-conflicts", no_argument, NULL, OPTION_ERROR_PARALLEL}, + {"Ep", no_argument, NULL, OPTION_ERROR_PARALLEL}, + {"no-error-explicit-parallel-conflicts", no_argument, NULL, OPTION_NO_ERROR_PARALLEL}, + {"Enp", no_argument, NULL, OPTION_NO_ERROR_PARALLEL}, {"hidden", no_argument, NULL, OPTION_SPECIAL}, + {"bitinst", no_argument, NULL, OPTION_SPECIAL_M32R}, + {"float", no_argument, NULL, OPTION_SPECIAL_FLOAT}, /* Sigh. I guess all warnings must now have both variants. */ {"warn-unmatched-high", no_argument, NULL, OPTION_WARN_UNMATCHED}, {"Wuh", no_argument, NULL, OPTION_WARN_UNMATCHED}, *************** *** 197,202 **** --- 253,279 ---- size_t md_longopts_size = sizeof (md_longopts); + static void little (int); + static void + little (int on) + { + target_big_endian = !on; + } + + /* Use parallel execution */ + static int parallel (void); + static int + parallel (void) + { + if (!enable_m32rx) + return 0; + + if (use_parallel == 1) + return 1; + + return 0; + } + int md_parse_option (c, arg) int c; *************** *** 216,221 **** --- 293,320 ---- allow_m32rx (1); break; + case OPTION_M32R2: + allow_m32rx (2); + enable_special = 1; + enable_special_m32r = 1; + break; + + case OPTION_BIG: + target_big_endian = 1; + break; + + case OPTION_LITTLE: + target_big_endian = 0; + break; + + case OPTION_PARALLEL: + use_parallel = 1; + break; + + case OPTION_NO_PARALLEL: + use_parallel = 0; + break; + case OPTION_WARN_PARALLEL: warn_explicit_parallel_conflicts = 1; break; *************** *** 224,229 **** --- 323,336 ---- warn_explicit_parallel_conflicts = 0; break; + case OPTION_ERROR_PARALLEL: + error_explicit_parallel_conflicts = 1; + break; + + case OPTION_NO_ERROR_PARALLEL: + error_explicit_parallel_conflicts = 0; + break; + case OPTION_SPECIAL: if (enable_m32rx) enable_special = 1; *************** *** 235,240 **** --- 342,355 ---- } break; + case OPTION_SPECIAL_M32R: + enable_special_m32r = 1; + break; + + case OPTION_SPECIAL_FLOAT: + enable_special_float = 1; + break; + case OPTION_WARN_UNMATCHED: warn_unmatched_high = 1; break; *************** *** 271,276 **** --- 386,395 ---- fprintf (stream, _("\ -m32rx support the extended m32rx instruction set\n")); fprintf (stream, _("\ + -m32r2 support the extended m32r2 instruction set\n")); + fprintf (stream, _("\ + -EL,-little use little endian\n")); + fprintf (stream, _("\ -O try to combine instructions in parallel\n")); fprintf (stream, _("\ *************** *** 285,290 **** --- 404,421 ---- -Wp synonym for -warn-explicit-parallel-conflicts\n")); fprintf (stream, _("\ -Wnp synonym for -no-warn-explicit-parallel-conflicts\n")); + fprintf (stream, _("\ + -error-explicit-parallel-conflicts error when parallel instructions\n")); + fprintf (stream, _("\ + violate contraints\n")); + fprintf (stream, _("\ + -no-error-explicit-parallel-conflicts do not error when parallel\n")); + fprintf (stream, _("\ + instructions violate contraints\n")); + fprintf (stream, _("\ + -Ep synonym for -error-explicit-parallel-conflicts\n")); + fprintf (stream, _("\ + -Enp synonym for -no-error-explicit-parallel-conflicts\n")); fprintf (stream, _("\ -warn-unmatched-high warn when an (s)high reloc has no matching low reloc\n")); *************** *** 295,300 **** --- 426,432 ---- fprintf (stream, _("\ -Wnuh synonym for -no-warn-unmatched-high\n")); + #if 0 fprintf (stream, _("\ -relax create linker relaxable code\n")); *************** *** 322,327 **** --- 454,461 ---- /* Not documented as so far there is no need for them.... */ { "m32r", allow_m32rx, 0 }, { "m32rx", allow_m32rx, 1 }, + { "m32r2", allow_m32rx, 2 }, + { "little", little, 1 }, { NULL, NULL, 0 } }; *************** *** 459,464 **** --- 593,608 ---- input_line_pointer = save_input_line; } + void + m32r_flush_pending_output() + { + if (debug_sym_link) + { + expand_debug_syms (debug_sym_link, 1); + debug_sym_link = (sym_linkS *) 0; + } + } + /* Cover function to fill_insn called after a label and at end of assembly. The result is always 1: we're called in a conditional to see if the current line is a label. */ *************** *** 488,493 **** --- 632,656 ---- return 1; } + + /* The default target format to use. */ + + const char * + m32r_target_format () + { + #ifdef TE_LINUX + if (target_big_endian) + return "elf32-m32r-linux"; + else + return "elf32-m32rle-linux"; + #else + if (target_big_endian) + return "elf32-m32r"; + else + return "elf32-m32rle"; + #endif + } + void md_begin () { *************** *** 500,506 **** /* Set the machine number and endian. */ gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, CGEN_CPU_OPEN_ENDIAN, ! CGEN_ENDIAN_BIG, CGEN_CPU_OPEN_END); m32r_cgen_init_asm (gas_cgen_cpu_desc); --- 663,670 ---- /* Set the machine number and endian. */ gas_cgen_cpu_desc = m32r_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, 0, CGEN_CPU_OPEN_ENDIAN, ! (target_big_endian ? ! CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE), CGEN_CPU_OPEN_END); m32r_cgen_init_asm (gas_cgen_cpu_desc); *************** *** 711,717 **** go away if the instructions are swapped, and we want to make sure that any other errors are detected before this happens. */ if (a_pipe == PIPE_S ! || b_pipe == PIPE_O) return _("Instructions share the same execution pipeline"); return NULL; --- 875,882 ---- go away if the instructions are swapped, and we want to make sure that any other errors are detected before this happens. */ if (a_pipe == PIPE_S ! || b_pipe == PIPE_O ! || (b_pipe == PIPE_O_OS && (enable_m32rx != 2))) return _("Instructions share the same execution pipeline"); return NULL; *************** *** 791,798 **** --- 956,981 ---- as_bad (_("not a 16 bit instruction '%s'"), str); return; } + #ifdef E_M32R2_ARCH + else if ((enable_m32rx == 1) + /* FIXME: Need standard macro to perform this test. */ + && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH) + & (1 << MACH_M32R2)) + && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH) + & (1 << MACH_M32RX))))) + { + /* xgettext:c-format */ + as_bad (_("instruction '%s' is for the M32R2 only"), str); + return; + } + else if ((! enable_special + && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL)) + || (! enable_special_m32r + && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R))) + #else else if (! enable_special && CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL)) + #endif { /* xgettext:c-format */ as_bad (_("unknown instruction '%s'"), str); *************** *** 887,894 **** --- 1070,1095 ---- as_bad (_("not a 16 bit instruction '%s'"), str); return; } + #ifdef E_M32R2_ARCH + else if ((enable_m32rx == 1) + /* FIXME: Need standard macro to perform this test. */ + && ((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH) + & (1 << MACH_M32R2)) + && !((CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_MACH) + & (1 << MACH_M32RX))))) + { + /* xgettext:c-format */ + as_bad (_("instruction '%s' is for the M32R2 only"), str); + return; + } + else if ((! enable_special + && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL)) + || (! enable_special_m32r + && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R))) + #else else if (! enable_special && CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL)) + #endif { /* xgettext:c-format */ as_bad (_("unknown instruction '%s'"), str); *************** *** 1001,1006 **** --- 1202,1217 ---- return; } + if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL) + || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL)) + m32r_flags |= E_M32R_HAS_HIDDEN_INST; + if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_M32R) + || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_M32R)) + m32r_flags |= E_M32R_HAS_BIT_INST; + if (CGEN_INSN_ATTR_VALUE (first.insn, CGEN_INSN_SPECIAL_FLOAT) + || CGEN_INSN_ATTR_VALUE (second.insn, CGEN_INSN_SPECIAL_FLOAT)) + m32r_flags |= E_M32R_HAS_FLOAT_INST; + /* Set these so m32r_fill_insn can use them. */ prev_seg = now_seg; prev_subseg = now_subseg; *************** *** 1021,1026 **** --- 1232,1238 ---- if ((str2 = strstr (str, "||")) != NULL) { assemble_two_insns (str, str2, 1); + m32r_flags |= E_M32R_HAS_PARALLEL; return; } *************** *** 1043,1050 **** --- 1255,1280 ---- return; } + #ifdef E_M32R2_ARCH + if ((enable_m32rx == 1) + /* FIXME: Need standard macro to perform this test. */ + && ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH) + & (1 << MACH_M32R2)) + && !((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_MACH) + & (1 << MACH_M32RX))))) + { + /* xgettext:c-format */ + as_bad (_("instruction '%s' is for the M32R2 only"), str); + return; + } + else if ((! enable_special + && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL)) + || (! enable_special_m32r + && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R))) + #else if (! enable_special && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL)) + #endif { /* xgettext:c-format */ as_bad (_("unknown instruction '%s'"), str); *************** *** 1058,1063 **** --- 1288,1300 ---- return; } + if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL)) + m32r_flags |= E_M32R_HAS_HIDDEN_INST; + if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_M32R)) + m32r_flags |= E_M32R_HAS_BIT_INST; + if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_SPECIAL_FLOAT)) + m32r_flags |= E_M32R_HAS_FLOAT_INST; + if (CGEN_INSN_BITSIZE (insn.insn) == 32) { /* 32 bit insns must live on 32 bit boundaries. */ *************** *** 1948,1951 **** --- 2185,2196 ---- return 0; return 1; + } + + void + m32r_elf_final_processing () + { + if (use_parallel) + m32r_flags |= E_M32R_HAS_PARALLEL; + elf_elfheader (stdoutput)->e_flags |= m32r_flags; } Index: gas/config/tc-m32r.h =================================================================== RCS file: /cvs/src/src/gas/config/tc-m32r.h,v retrieving revision 1.9 diff -c -r1.9 tc-m32r.h *** gas/config/tc-m32r.h 25 Jul 2003 14:35:54 -0000 1.9 --- gas/config/tc-m32r.h 2 Dec 2003 08:56:11 -0000 *************** *** 26,39 **** #error M32R support requires BFD_ASSEMBLER #endif ! #define LISTING_HEADER "M32R GAS " /* The target BFD architecture. */ #define TARGET_ARCH bfd_arch_m32r ! #define TARGET_FORMAT "elf32-m32r" #define TARGET_BYTES_BIG_ENDIAN 1 /* call md_pcrel_from_section, not md_pcrel_from */ long md_pcrel_from_section PARAMS ((struct fix *, segT)); --- 26,47 ---- #error M32R support requires BFD_ASSEMBLER #endif ! #define LISTING_HEADER \ ! (target_big_endian \ ! ? "M32R GAS" : "M32R GAS Little Endian") /* The target BFD architecture. */ #define TARGET_ARCH bfd_arch_m32r ! /* The endianness of the target format may change based on command ! line arguments. */ ! #define TARGET_FORMAT m32r_target_format() ! extern const char *m32r_target_format PARAMS ((void)); + /* Default to big endian. */ + #ifndef TARGET_BYTES_BIG_ENDIAN #define TARGET_BYTES_BIG_ENDIAN 1 + #endif /* call md_pcrel_from_section, not md_pcrel_from */ long md_pcrel_from_section PARAMS ((struct fix *, segT)); *************** *** 101,103 **** --- 109,118 ---- #define md_cleanup m32r_elf_section_change_hook #define md_elf_section_change_hook m32r_elf_section_change_hook extern void m32r_elf_section_change_hook PARAMS ((void)); + + #define md_flush_pending_output() m32r_flush_pending_output () + extern void m32r_flush_pending_output PARAMS ((void)); + + #define elf_tc_final_processing m32r_elf_final_processing + extern void m32r_elf_final_processing PARAMS ((void)); +