diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 273 | ||||
-rw-r--r-- | bfd/Makefile.am | 5 | ||||
-rw-r--r-- | bfd/Makefile.in | 5 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 53 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 5621 | ||||
-rw-r--r-- | bfd/libbfd.h | 33 | ||||
-rw-r--r-- | bfd/reloc.c | 86 | ||||
-rw-r--r-- | bfd/xtensa-isa.c | 1820 | ||||
-rw-r--r-- | bfd/xtensa-modules.c | 11785 |
9 files changed, 14263 insertions, 5418 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index eefb123..df81821 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,276 @@ +2004-10-07 Bob Wilson <bob.wilson@acm.org> + + * elf32-xtensa.c (elf32xtensa_size_opt): New global variable. + (xtensa_default_isa): Global variable moved here from xtensa-isa.c. + (elf32xtensa_no_literal_movement): New global variable. + (elf_howto_table): Add entries for new relocations. + (elf_xtensa_reloc_type_lookup): Handle new relocations. + (property_table_compare): When addresses are equal, compare sizes and + various property flags. + (property_table_matches): New. + (xtensa_read_table_entries): Extend to read new property tables. Add + output_addr parameter to indicate that output addresses should be used. + Use bfd_get_section_limit. + (elf_xtensa_find_property_entry): New. + (elf_xtensa_in_literal_pool): Use elf_xtensa_find_property_entry. + (elf_xtensa_check_relocs): Handle new relocations. + (elf_xtensa_do_reloc): Use bfd_get_section_limit. Handle new + relocations. Use new xtensa-isa.h functions. + (build_encoding_error_message): Remove encode_result parameter. Add + new target_address parameter used to detect alignment errors. + (elf_xtensa_relocate_section): Use bfd_get_section_limit. Clean up + error handling. Use new is_operand_relocation function. + (elf_xtensa_combine_prop_entries, elf_xtensa_merge_private_bfd_data): + Use underbar macro for error messages. Formatting. + (get_const16_opcode): New. + (get_l32r_opcode): Add a separate flag for initialization. + (get_relocation_opnd): Operand number is no longer explicit in the + relocation. Change to decode the opcode and analyze its operands. + (get_relocation_slot): New. + (get_relocation_opcode): Add bfd parameter. Use bfd_get_section_limit. + Use new xtensa-isa.h functions to handle multislot instructions. + (is_l32r_relocation): Add bfd parameter. Use is_operand_relocation. + (get_asm_simplify_size, is_alt_relocation, is_operand_relocation, + insn_decode_len, insn_decode_opcode, check_branch_target_aligned, + check_loop_aligned, check_branch_target_aligned_address, narrowable, + widenable, narrow_instruction, widen_instruction, op_single_fmt_table, + get_single_format, init_op_single_format_table): New. + (elf_xtensa_do_asm_simplify): Add error_message parameter and use it + instead of calling _bfd_error_handler. Use new xtensa-isa.h functions. + (contract_asm_expansion): Add error_message parameter and pass it to + elf_xtensa_do_asm_simplify. Replace use of R_XTENSA_OP0 relocation + with R_XTENSA_SLOT0_OP. + (get_expanded_call_opcode): Extend to handle either L32R or CONST16 + instructions. Use new xtensa-isa.h functions. + (r_reloc struct): Add new virtual_offset field. + (r_reloc_init): Add contents and content_length parameters. Set + virtual_offset field to zero. Add contents to target_offset field for + partial_inplace relocations. + (r_reloc_is_defined): Check for null. + (print_r_reloc): New debug function. + (source_reloc struct): Replace xtensa_operand field with pair of the + opcode and the operand position. Add is_abs_literal field. + (init_source_reloc): Specify operand by opcode/position pair. Set + is_abs_literal field. + (source_reloc_compare): When target_offsets are equal, compare other + fields to make sorting predictable. + (literal_value struct): Add is_abs_literal field. + (value_map_hash_table struct): Add has_last_loc and last_loc fields. + (init_literal_value): New. + (is_same_value): Replace with ... + (literal_value_equal): ... this function. Add comparisons of + virtual_offset and is_abs_literal fields. + (value_map_hash_table_init): Use bfd_zmalloc. Check for allocation + failure. Initialize has_last_loc field. + (value_map_hash_table_delete): New. + (hash_literal_value): Rename to ... + (literal_value_hash): ... this. Include is_abs_literal flag and + virtual_offset field in the hash value. + (get_cached_value): Rename to ... + (value_map_get_cached_value): ... this. Update calls to + literal_value_hash and literal_value_equal. + (add_value_map): Check for allocation failure. Update calls to + value_map_get_cached_value and literal_value_hash. + (text_action, text_action_list, text_action_t): New types. + (find_fill_action, compute_removed_action_diff, adjust_fill_action, + text_action_add, text_action_add_literal, offset_with_removed_text, + offset_with_removed_text_before_fill, find_insn_action, + print_action_list, print_removed_literals): New. + (offset_with_removed_literals): Delete. + (xtensa_relax_info struct): Add is_relaxable_asm_section, action_list, + fix_array, fix_array_count, allocated_relocs, relocs_count, and + allocated_relocs_count fields. + (init_xtensa_relax_info): Initialize new fields. + (reloc_bfd_fix struct): Add new translated field. + (reloc_bfd_fix_init): Add translated parameter and use it to set the + translated field. + (fix_compare, cache_fix_array): New. + (get_bfd_fix): Remove fix_list parameter and get all relax_info for the + section via get_xtensa_relax_info. Use cache_fix_array to set up + sorted fix_array and use bsearch instead of linear search. + (section_cache_t): New struct. + (init_section_cache, section_cache_section, clear_section_cache): New. + (ebb_t, ebb_target_enum, proposed_action, ebb_constraint): New types. + (init_ebb_constraint, free_ebb_constraint, init_ebb, extend_ebb_bounds, + extend_ebb_bounds_forward, extend_ebb_bounds_backward, + insn_block_decodable_len, ebb_propose_action, ebb_add_proposed_action): + New. + (retrieve_contents): Use bfd_get_section_limit. + (elf_xtensa_relax_section): Add relocations_analyzed flag. Update call + to compute_removed_literals. Free value_map_hash_table when no longer + needed. + (analyze_relocations): Check is_relaxable_asm_section flag. Call + compute_text_actions for all sections. + (find_relaxable_sections): Mark sections as relaxable if they contain + ASM_EXPAND relocations that can be optimized. Adjust r_reloc_init + call. Increment relax_info src_count field only for appropriate + relocation types. Remove is_literal_section check. + (collect_source_relocs): Use bfd_get_section_limit. Adjust calls to + r_reloc_init and find_associated_l32r_irel. Check + is_relaxable_asm_section flag. Handle L32R instructions with absolute + literals. Pass is_abs_literal flag to init_source_reloc. + (is_resolvable_asm_expansion): Use bfd_get_section_limit. Check for + CONST16 instructions. Adjust calls to r_reloc_init and + pcrel_reloc_fits. Handle weak symbols conservatively. + (find_associated_l32r_irel): Add bfd parameter and pass it to + is_l32r_relocation. + (compute_text_actions, compute_ebb_proposed_actions, + compute_ebb_actions, check_section_ebb_pcrels_fit, + check_section_ebb_reduces, text_action_add_proposed, + compute_fill_extra_space): New. + (remove_literals): Replace with ... + (compute_removed_literals): ... this function. Call + init_section_cache. Use bfd_get_section_limit. Sort internal_relocs. + Call xtensa_read_table_entries to get the property table. Skip + relocations other than R_XTENSA_32 and R_XTENSA_PLT. Use new + is_removable_literal, remove_dead_literal, and + identify_literal_placement functions. + (get_irel_at_offset): Rewrite to use bsearch on sorted relocations + instead of linear search. + (is_removable_literal, remove_dead_literal, + identify_literal_placement): New. + (relocations_reach): Update check for literal not referenced by any + PC-relative relocations. Adjust call to pcrel_reloc_fits. + (coalesce_shared_literal, move_shared_literal): New. + (relax_section): Use bfd_get_section_limit. Call + translate_section_fixes. Update calls to r_reloc_init and + offset_with_removed_text. Check new is_relaxable_asm_section flag. + Add call to pin_internal_relocs. Add special handling for + R_XTENSA_ASM_SIMPLIFY and R_XTENSA_DIFF* relocs. Use virtual_offset + info to calculate new addend_displacement variable. Replace code for + deleting literals with more general code to perform the actions + determined by the action_list for the section. + (translate_section_fixes, translate_reloc_bfd_fix): New. + (translate_reloc): Check new is_relaxable_asm_section flag. Call + find_removed_literal only if is_operand_relocation. Update call to + offset_with_removed_text. Use new target_offset and removed_bytes + variables. + (move_literal): New. + (relax_property_section): Use bfd_get_section_limit. Set new + is_full_prop_section flag and handle new property tables. Update calls + to r_reloc_init and offset_with_removed_text. Check + is_relaxable_asm_section flag. Handle expansion of zero-sized + unreachable entries, with use of offset_with_removed_text_before_fill. + For relocatable links, combine entries only for literal tables. + (relax_section_symbols): Check is_relaxable_asm_section flag. Update + calls to offset_with_removed_text. Translate st_size field for + function symbols. + (do_fix_for_relocatable_link): Change to return bfd_boolean to indicate + failure. Add contents parameter. Update call to get_bfd_fix. Update + call to r_reloc_init. Call _bfd_error_handler and return FALSE for + R_XTENSA_ASM_EXPAND relocs. + (do_fix_for_final_link): Add input_bfd and contents parameters. Update + call to get_bfd_fix. Include offset from contents for partial_inplace + relocations. + (is_reloc_sym_weak): New. + (pcrel_reloc_fits): Use new xtensa-isa.h functions. + (prop_sec_len): New. + (xtensa_is_property_section): Handle new property sections. + (is_literal_section): Delete. + (internal_reloc_compare): When r_offset matches, compare r_info and + r_addend to make sorting predictable. + (internal_reloc_matches): New. + (xtensa_get_property_section_name): Handle new property sections. + (xtensa_get_property_predef_flags): New. + (xtensa_callback_required_dependence): Use bfd_get_section_limit. + Update calls to xtensa_isa_init, is_l32r_relocation, and r_reloc_init. + * xtensa-isa.c (xtensa_default_isa): Moved to elf32-xtensa.c. + (xtisa_errno, xtisa_error_msg): New variables. + (xtensa_isa_errno, xtensa_isa_error_msg): New. + (xtensa_insnbuf_alloc): Add error handling. + (xtensa_insnbuf_to_chars): Add num_chars parameter. Update to + use xtensa_format_decode. Add error handling. + (xtensa_insnbuf_from_chars): Add num_chars parameter. Decode the + instruction length to find the number of bytes to copy. + (xtensa_isa_init): Add error handling. Replace calls to + xtensa_load_isa and xtensa_extend_isa with code to initialize lookup + tables in the xtensa_modules structure. + (xtensa_check_isa_config, xtensa_add_isa, xtensa_load_isa, + xtensa_extend_isa): Delete. + (xtensa_isa_free): Change to only free lookup tables. + (opname_lookup_compare): Replace with ... + (xtensa_isa_name_compare): ... this function. Use strcasecmp. + (xtensa_insn_maxlength): Rename to ... + (xtensa_isa_maxlength): ... this. + (xtensa_insn_length): Delete. + (xtensa_insn_length_from_first_byte): Replace with ... + (xtensa_isa_length_from_chars): ... this function. + (xtensa_num_opcodes): Rename to ... + (xtensa_isa_num_opcodes): ... this. + (xtensa_isa_num_pipe_stages, xtensa_isa_num_formats, + xtensa_isa_num_regfiles, xtensa_isa_num_stages, + xtensa_isa_num_sysregs, xtensa_isa_num_interfaces, + xtensa_isa_num_funcUnits, xtensa_format_name, xtensa_format_lookup, + xtensa_format_decode, xtensa_format_encode, xtensa_format_length, + xtensa_format_num_slots, xtensa_format_slot_nop_opcode, + xtensa_format_get_slot, xtensa_format_set_slot): New functions. + (xtensa_opcode_lookup): Add error handling. + (xtensa_decode_insn): Replace with ... + (xtensa_opcode_decode): ... this function, with new format and + slot parameters. Add error handling. + (xtensa_encode_insn): Replace with ... + (xtensa_opcode_encode): ... this function, which does the encoding via + one of the entries in the "encode_fns" array. Add error handling. + (xtensa_opcode_name): Add error handling. + (xtensa_opcode_is_branch, xtensa_opcode_is_jump, xtensa_opcode_is_loop, + xtensa_opcode_is_call): New. + (xtensa_num_operands): Replace with ... + (xtensa_opcode_num_operands): ... this function. Add error handling. + (xtensa_opcode_num_stateOperands, + xtensa_opcode_num_interfaceOperands, xtensa_opcode_num_funcUnit_uses, + xtensa_opcode_funcUnit_use, xtensa_operand_name, + xtensa_operand_is_visible): New. + (xtensa_get_operand, xtensa_operand_kind): Delete. + (xtensa_operand_inout): Add error handling and special-case for + "sout" operands. + (xtensa_operand_get_field, xtensa_operand_set_field): Rewritten to + operate on one slot of an instruction. Added error handling. + (xtensa_operand_encode): Handle default operands with no encoding + functions. Check for success by comparing against decoded value. + Add error handling. + (xtensa_operand_decode): Handle default operands. Return decoded value + through argument pointer. Add error handling. + (xtensa_operand_is_register, xtensa_operand_regfile, + xtensa_operand_num_regs, xtensa_operand_is_known_reg): New. + (xtensa_operand_isPCRelative): Rename to ... + (xtensa_operand_is_PCrelative): ... this. Add error handling. + (xtensa_operand_do_reloc, xtensa_operand_undo_reloc): Return value + through argument pointer. Add error handling. + (xtensa_stateOperand_state, xtensa_stateOperand_inout, + xtensa_interfaceOperand_interface, xtensa_regfile_lookup, + xtensa_regfile_lookup_shortname, xtensa_regfile_name, + xtensa_regfile_shortname, xtensa_regfile_view_parent, + xtensa_regfile_num_bits, xtensa_regfile_num_entries, + xtensa_state_lookup, xtensa_state_name, xtensa_state_num_bits, + xtensa_state_is_exported, xtensa_sysreg_lookup, + xtensa_sysreg_lookup_name, xtensa_sysreg_name, xtensa_sysreg_number, + xtensa_sysreg_is_user, xtensa_interface_lookup, xtensa_interface_name, + xtensa_interface_num_bits, xtensa_interface_inout, + xtensa_interface_has_side_effect, xtensa_funcUnit_lookup, + xtensa_funcUnit_name, xtensa_funcUnit_num_copies): New. + * xtensa-modules.c: Rewrite to use new data structures. + * reloc.c (BFD_RELOC_XTENSA_DIFF8, BFD_RELOC_XTENSA_DIFF16, + BFD_RELOC_XTENSA_DIFF32, BFD_RELOC_XTENSA_SLOT0_OP, + BFD_RELOC_XTENSA_SLOT1_OP, BFD_RELOC_XTENSA_SLOT2_OP, + BFD_RELOC_XTENSA_SLOT3_OP, BFD_RELOC_XTENSA_SLOT4_OP, + BFD_RELOC_XTENSA_SLOT5_OP, BFD_RELOC_XTENSA_SLOT6_OP, + BFD_RELOC_XTENSA_SLOT7_OP, BFD_RELOC_XTENSA_SLOT8_OP, + BFD_RELOC_XTENSA_SLOT9_OP, BFD_RELOC_XTENSA_SLOT10_OP, + BFD_RELOC_XTENSA_SLOT11_OP, BFD_RELOC_XTENSA_SLOT12_OP, + BFD_RELOC_XTENSA_SLOT13_OP, BFD_RELOC_XTENSA_SLOT14_OP, + BFD_RELOC_XTENSA_SLOT0_ALT, BFD_RELOC_XTENSA_SLOT1_ALT, + BFD_RELOC_XTENSA_SLOT2_ALT, BFD_RELOC_XTENSA_SLOT3_ALT, + BFD_RELOC_XTENSA_SLOT4_ALT, BFD_RELOC_XTENSA_SLOT5_ALT, + BFD_RELOC_XTENSA_SLOT6_ALT, BFD_RELOC_XTENSA_SLOT7_ALT, + BFD_RELOC_XTENSA_SLOT8_ALT, BFD_RELOC_XTENSA_SLOT9_ALT, + BFD_RELOC_XTENSA_SLOT10_ALT, BFD_RELOC_XTENSA_SLOT11_ALT, + BFD_RELOC_XTENSA_SLOT12_ALT, BFD_RELOC_XTENSA_SLOT13_ALT, + BFD_RELOC_XTENSA_SLOT14_ALT): Add new relocations. + * Makefile.am (xtensa-isa.lo, xtensa-modules.lo): Update dependencies. + * Makefile.in: Regenerate. + * bfd-in2.h: Likewise. + * libbfd.h: Likewise. + 2004-10-07 Richard Sandiford <rsandifo@redhat.com> * elf64-mips.c (mips_elf64_write_rel): Use STN_UNDEF for relocs diff --git a/bfd/Makefile.am b/bfd/Makefile.am index a7eabfc..966aff3 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -1557,10 +1557,9 @@ xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \ $(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \ libxcoff.h xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h -xtensa-isa.lo: xtensa-isa.c $(INCDIR)/xtensa-isa.h \ - $(INCDIR)/xtensa-isa-internal.h -xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa.h \ +xtensa-isa.lo: xtensa-isa.c $(INCDIR)/filenames.h $(INCDIR)/xtensa-isa.h \ $(INCDIR)/xtensa-isa-internal.h +xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa-internal.h aix5ppc-core.lo: aix5ppc-core.c aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \ $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index ac92e49..5a551cd 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -2112,10 +2112,9 @@ xcofflink.lo: xcofflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \ $(INCDIR)/coff/internal.h $(INCDIR)/coff/xcoff.h libcoff.h \ libxcoff.h xsym.lo: xsym.c xsym.h $(INCDIR)/filenames.h -xtensa-isa.lo: xtensa-isa.c $(INCDIR)/xtensa-isa.h \ - $(INCDIR)/xtensa-isa-internal.h -xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa.h \ +xtensa-isa.lo: xtensa-isa.c $(INCDIR)/filenames.h $(INCDIR)/xtensa-isa.h \ $(INCDIR)/xtensa-isa-internal.h +xtensa-modules.lo: xtensa-modules.c $(INCDIR)/xtensa-isa-internal.h aix5ppc-core.lo: aix5ppc-core.c aout64.lo: aout64.c aoutx.h $(INCDIR)/filenames.h $(INCDIR)/safe-ctype.h \ $(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \ diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 6feb83e..2e851a9 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -3621,9 +3621,56 @@ to one of its own internal functions or data structures. */ PLT entries. Otherwise, this is just a generic 32-bit relocation. */ BFD_RELOC_XTENSA_PLT, -/* Generic Xtensa relocations. Only the operand number is encoded -in the relocation. The details are determined by extracting the -instruction opcode. */ +/* Xtensa relocations to mark the difference of two local symbols. +These are only needed to support linker relaxation and can be ignored +when not relaxing. The field is set to the value of the difference +assuming no relaxation. The relocation encodes the position of the +first symbol so the linker can determine whether to adjust the field +value. */ + BFD_RELOC_XTENSA_DIFF8, + BFD_RELOC_XTENSA_DIFF16, + BFD_RELOC_XTENSA_DIFF32, + +/* Generic Xtensa relocations for instruction operands. Only the slot +number is encoded in the relocation. The relocation applies to the +last PC-relative immediate operand, or if there are no PC-relative +immediates, to the last immediate operand. */ + BFD_RELOC_XTENSA_SLOT0_OP, + BFD_RELOC_XTENSA_SLOT1_OP, + BFD_RELOC_XTENSA_SLOT2_OP, + BFD_RELOC_XTENSA_SLOT3_OP, + BFD_RELOC_XTENSA_SLOT4_OP, + BFD_RELOC_XTENSA_SLOT5_OP, + BFD_RELOC_XTENSA_SLOT6_OP, + BFD_RELOC_XTENSA_SLOT7_OP, + BFD_RELOC_XTENSA_SLOT8_OP, + BFD_RELOC_XTENSA_SLOT9_OP, + BFD_RELOC_XTENSA_SLOT10_OP, + BFD_RELOC_XTENSA_SLOT11_OP, + BFD_RELOC_XTENSA_SLOT12_OP, + BFD_RELOC_XTENSA_SLOT13_OP, + BFD_RELOC_XTENSA_SLOT14_OP, + +/* Alternate Xtensa relocations. Only the slot is encoded in the +relocation. The meaning of these relocations is opcode-specific. */ + BFD_RELOC_XTENSA_SLOT0_ALT, + BFD_RELOC_XTENSA_SLOT1_ALT, + BFD_RELOC_XTENSA_SLOT2_ALT, + BFD_RELOC_XTENSA_SLOT3_ALT, + BFD_RELOC_XTENSA_SLOT4_ALT, + BFD_RELOC_XTENSA_SLOT5_ALT, + BFD_RELOC_XTENSA_SLOT6_ALT, + BFD_RELOC_XTENSA_SLOT7_ALT, + BFD_RELOC_XTENSA_SLOT8_ALT, + BFD_RELOC_XTENSA_SLOT9_ALT, + BFD_RELOC_XTENSA_SLOT10_ALT, + BFD_RELOC_XTENSA_SLOT11_ALT, + BFD_RELOC_XTENSA_SLOT12_ALT, + BFD_RELOC_XTENSA_SLOT13_ALT, + BFD_RELOC_XTENSA_SLOT14_ALT, + +/* Xtensa relocations for backward compatibility. These have all been +replaced by BFD_RELOC_XTENSA_SLOT0_OP. */ BFD_RELOC_XTENSA_OP0, BFD_RELOC_XTENSA_OP1, BFD_RELOC_XTENSA_OP2, diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 0755e09..09ef0e1 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -35,13 +35,16 @@ #include "xtensa-isa.h" #include "xtensa-config.h" +#define XTENSA_NO_NOP_REMOVAL 0 + /* Main interface functions. */ static void elf_xtensa_info_to_howto_rela PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); static reloc_howto_type *elf_xtensa_reloc_type_lookup PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); extern int xtensa_read_table_entries - PARAMS ((bfd *, asection *, property_table_entry **, const char *)); + PARAMS ((bfd *, asection *, property_table_entry **, const char *, + bfd_boolean)); static bfd_boolean elf_xtensa_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); @@ -103,6 +106,10 @@ static bfd_boolean xtensa_elf_dynamic_symbol_p PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *)); static int property_table_compare PARAMS ((const PTR, const PTR)); +static int property_table_matches + PARAMS ((const PTR, const PTR)); +static property_table_entry *elf_xtensa_find_property_entry + PARAMS ((property_table_entry *, int, bfd_vma)); static bfd_boolean elf_xtensa_in_literal_pool PARAMS ((property_table_entry *, int, bfd_vma)); static void elf_xtensa_make_sym_local @@ -123,13 +130,13 @@ static bfd_reloc_status_type elf_xtensa_do_reloc static char * vsprint_msg VPARAMS ((const char *, const char *, int, ...)); static char *build_encoding_error_message - PARAMS ((xtensa_opcode, xtensa_encode_result)); + PARAMS ((xtensa_opcode, bfd_vma)); static bfd_reloc_status_type bfd_elf_xtensa_reloc PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); -static void do_fix_for_relocatable_link - PARAMS ((Elf_Internal_Rela *, bfd *, asection *)); +static bfd_boolean do_fix_for_relocatable_link + PARAMS ((Elf_Internal_Rela *, bfd *, asection *, bfd_byte *)); static void do_fix_for_final_link - PARAMS ((Elf_Internal_Rela *, asection *, bfd_vma *)); + PARAMS ((Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *)); static bfd_vma elf_xtensa_create_plt_entry PARAMS ((bfd *, bfd *, unsigned)); static int elf_xtensa_combine_prop_entries @@ -148,27 +155,47 @@ static bfd_boolean is_direct_call_opcode PARAMS ((xtensa_opcode)); static bfd_boolean is_windowed_call_opcode PARAMS ((xtensa_opcode)); +static xtensa_opcode get_const16_opcode + PARAMS ((void)); static xtensa_opcode get_l32r_opcode PARAMS ((void)); static bfd_vma l32r_offset PARAMS ((bfd_vma, bfd_vma)); static int get_relocation_opnd - PARAMS ((Elf_Internal_Rela *)); + PARAMS ((xtensa_opcode, int)); +static int get_relocation_slot + PARAMS ((int)); static xtensa_opcode get_relocation_opcode - PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *)); + PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *)); static bfd_boolean is_l32r_relocation - PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *)); + PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *)); +static bfd_boolean is_alt_relocation + PARAMS ((int)); +static bfd_boolean is_operand_relocation + PARAMS ((int)); +static bfd_size_type insn_decode_len + PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type)); +static xtensa_opcode insn_decode_opcode + PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, int)); +static bfd_boolean check_branch_target_aligned + PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_vma)); +static bfd_boolean check_loop_aligned + PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_vma)); +static bfd_boolean check_branch_target_aligned_address + PARAMS ((bfd_vma, int)); +static bfd_size_type get_asm_simplify_size + PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type)); /* Functions for link-time code simplifications. */ -static bfd_reloc_status_type elf_xtensa_do_asm_simplify - PARAMS ((bfd_byte *, bfd_vma, bfd_vma)); +static bfd_reloc_status_type elf_xtensa_do_asm_simplify + PARAMS ((bfd_byte *, bfd_vma, bfd_vma, char **)); static bfd_reloc_status_type contract_asm_expansion - PARAMS ((bfd_byte *, bfd_vma, Elf_Internal_Rela *)); + PARAMS ((bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **)); static xtensa_opcode swap_callx_for_call_opcode PARAMS ((xtensa_opcode)); static xtensa_opcode get_expanded_call_opcode - PARAMS ((bfd_byte *, int)); + PARAMS ((bfd_byte *, int, bfd_boolean *)); /* Access to internal relocations, section contents and symbols. */ @@ -199,18 +226,22 @@ static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry PARAMS ((bfd *, unsigned long)); static bfd_vma get_elf_r_symndx_offset PARAMS ((bfd *, unsigned long)); +static bfd_boolean is_reloc_sym_weak + PARAMS ((bfd *, Elf_Internal_Rela *)); static bfd_boolean pcrel_reloc_fits - PARAMS ((xtensa_operand, bfd_vma, bfd_vma)); + PARAMS ((xtensa_opcode, int, bfd_vma, bfd_vma)); static bfd_boolean xtensa_is_property_section PARAMS ((asection *)); static bfd_boolean xtensa_is_littable_section PARAMS ((asection *)); -static bfd_boolean is_literal_section - PARAMS ((asection *)); static int internal_reloc_compare PARAMS ((const PTR, const PTR)); +static int internal_reloc_matches + PARAMS ((const PTR, const PTR)); extern char *xtensa_get_property_section_name PARAMS ((asection *, const char *)); +static flagword xtensa_get_property_predef_flags + PARAMS ((asection *)); /* Other functions called directly by the linker. */ @@ -221,9 +252,20 @@ extern bfd_boolean xtensa_callback_required_dependence deps_callback_t, PTR)); +/* Globally visible flag for choosing size optimization of NOP removal + instead of branch-target-aware minimization for NOP removal. + When nonzero, narrow all instructions and remove all NOPs possible + around longcall expansions. */ +int elf32xtensa_size_opt; + + +/* The "new_section_hook" is used to set up a per-section + "xtensa_relax_info" data structure with additional information used + during relaxation. */ typedef struct xtensa_relax_info_struct xtensa_relax_info; + /* Total count of PLT relocations seen during check_relocs. The actual PLT code must be split into multiple sections and all the sections have to be created before size_dynamic_sections, @@ -234,12 +276,25 @@ typedef struct xtensa_relax_info_struct xtensa_relax_info; static int plt_reloc_count = 0; +/* The GNU tools do not easily allow extending interfaces to pass around + the pointer to the Xtensa ISA information, so instead we add a global + variable here (in BFD) that can be used by any of the tools that need + this information. */ + +xtensa_isa xtensa_default_isa; + + /* When this is true, relocations may have been modified to refer to symbols from other input files. The per-section list of "fix" records needs to be checked when resolving relocations. */ static bfd_boolean relaxing_section = FALSE; +/* When this is true, during final links, literals that cannot be + coalesced and their relocations may be moved to other sections. */ + +int elf32xtensa_no_literal_movement = 1; + static reloc_howto_type elf_howto_table[] = { @@ -296,10 +351,115 @@ static reloc_howto_type elf_howto_table[] = /* GNU extension to record C++ vtable member usage. */ HOWTO (R_XTENSA_GNU_VTENTRY, 0, 2, 0, FALSE, 0, complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY", - FALSE, 0x00000000, 0x00000000, FALSE) + FALSE, 0x00000000, 0x00000000, FALSE), + + /* Relocations for supporting difference of symbols. */ + HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", + FALSE, 0xffffffff, 0xffffffff, FALSE), + HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", + FALSE, 0xffffffff, 0xffffffff, FALSE), + HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, + bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", + FALSE, 0xffffffff, 0xffffffff, FALSE), + + /* General immediate operand relocations. */ + HOWTO (R_XTENSA_SLOT0_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT1_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT2_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT3_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT4_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT5_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT6_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT7_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT8_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT9_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT10_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT11_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT12_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT13_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT14_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP", + FALSE, 0x00000000, 0x00000000, TRUE), + + /* "Alternate" relocations. The meaning of these is opcode-specific. */ + HOWTO (R_XTENSA_SLOT0_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT1_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT2_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT3_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT4_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT5_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT6_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT7_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT8_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT9_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT10_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT11_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT12_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT13_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT", + FALSE, 0x00000000, 0x00000000, TRUE), + HOWTO (R_XTENSA_SLOT14_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont, + bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT", + FALSE, 0x00000000, 0x00000000, TRUE) }; -#ifdef DEBUG_GEN_RELOC +#if DEBUG_GEN_RELOC #define TRACE(str) \ fprintf (stderr, "Xtensa bfd reloc lookup %d (%s)\n", code, str) #else @@ -321,6 +481,18 @@ elf_xtensa_reloc_type_lookup (abfd, code) TRACE ("BFD_RELOC_32"); return &elf_howto_table[(unsigned) R_XTENSA_32 ]; + case BFD_RELOC_XTENSA_DIFF8: + TRACE ("BFD_RELOC_XTENSA_DIFF8"); + return &elf_howto_table[(unsigned) R_XTENSA_DIFF8 ]; + + case BFD_RELOC_XTENSA_DIFF16: + TRACE ("BFD_RELOC_XTENSA_DIFF16"); + return &elf_howto_table[(unsigned) R_XTENSA_DIFF16 ]; + + case BFD_RELOC_XTENSA_DIFF32: + TRACE ("BFD_RELOC_XTENSA_DIFF32"); + return &elf_howto_table[(unsigned) R_XTENSA_DIFF32 ]; + case BFD_RELOC_XTENSA_RTLD: TRACE ("BFD_RELOC_XTENSA_RTLD"); return &elf_howto_table[(unsigned) R_XTENSA_RTLD ]; @@ -370,6 +542,22 @@ elf_xtensa_reloc_type_lookup (abfd, code) return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTENTRY ]; default: + if (code >= BFD_RELOC_XTENSA_SLOT0_OP + && code <= BFD_RELOC_XTENSA_SLOT14_OP) + { + unsigned n = (R_XTENSA_SLOT0_OP + + (code - BFD_RELOC_XTENSA_SLOT0_OP)); + return &elf_howto_table[n]; + } + + if (code >= BFD_RELOC_XTENSA_SLOT0_ALT + && code <= BFD_RELOC_XTENSA_SLOT14_ALT) + { + unsigned n = (R_XTENSA_SLOT0_ALT + + (code - BFD_RELOC_XTENSA_SLOT0_ALT)); + return &elf_howto_table[n]; + } + break; } @@ -468,8 +656,48 @@ property_table_compare (ap, bp) const property_table_entry *a = (const property_table_entry *) ap; const property_table_entry *b = (const property_table_entry *) bp; - /* Check if one entry overlaps with the other; this shouldn't happen - except when searching for a match. */ + if (a->address == b->address) + { + /* The only circumstance where two entries may legitimately have the + same address is when one of them is a zero-size placeholder to + mark a place where fill can be inserted. The zero-size entry should + come first. */ + BFD_ASSERT ((a->size == 0 || b->size == 0)); + + if (a->size != b->size) + return (a->size - b->size); + + if ((a->flags & XTENSA_PROP_ALIGN) != (b->flags & XTENSA_PROP_ALIGN)) + return ((b->flags & XTENSA_PROP_ALIGN) + - (a->flags & XTENSA_PROP_ALIGN)); + + if ((a->flags & XTENSA_PROP_ALIGN) + && (GET_XTENSA_PROP_ALIGNMENT (a->flags) + != GET_XTENSA_PROP_ALIGNMENT (b->flags))) + return (GET_XTENSA_PROP_ALIGNMENT (a->flags) + - GET_XTENSA_PROP_ALIGNMENT (b->flags)); + + if ((a->flags & XTENSA_PROP_UNREACHABLE) + != (b->flags & XTENSA_PROP_UNREACHABLE)) + return ((b->flags & XTENSA_PROP_UNREACHABLE) + - (a->flags & XTENSA_PROP_UNREACHABLE)); + + return (a->flags - b->flags); + } + + return (a->address - b->address); +} + + +static int +property_table_matches (ap, bp) + const PTR ap; + const PTR bp; +{ + const property_table_entry *a = (const property_table_entry *) ap; + const property_table_entry *b = (const property_table_entry *) bp; + + /* Check if one entry overlaps with the other. */ if ((b->address >= a->address && b->address < (a->address + a->size)) || (a->address >= b->address && a->address < (b->address + b->size))) return 0; @@ -478,16 +706,17 @@ property_table_compare (ap, bp) } -/* Get the literal table or instruction table entries for the given - section. Sets TABLE_P and returns the number of entries. On error, - returns a negative value. */ +/* Get the literal table or property table entries for the given + section. Sets TABLE_P and returns the number of entries. On + error, returns a negative value. */ int -xtensa_read_table_entries (abfd, section, table_p, sec_name) +xtensa_read_table_entries (abfd, section, table_p, sec_name, output_addr) bfd *abfd; asection *section; property_table_entry **table_p; const char *sec_name; + bfd_boolean output_addr; { asection *table_section; char *table_section_name; @@ -498,27 +727,44 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name) bfd_size_type num_records; Elf_Internal_Rela *internal_relocs; bfd_vma section_addr; + flagword predef_flags; + bfd_size_type table_entry_size; + + if (!section + || !(section->flags & SEC_ALLOC) + || (section->flags & SEC_DEBUGGING)) + { + *table_p = NULL; + return 0; + } - table_section_name = - xtensa_get_property_section_name (section, sec_name); + table_section_name = xtensa_get_property_section_name (section, sec_name); table_section = bfd_get_section_by_name (abfd, table_section_name); free (table_section_name); - if (table_section != NULL) + if (table_section) table_size = table_section->size; - + if (table_size == 0) { *table_p = NULL; return 0; } - num_records = table_size / 8; + predef_flags = xtensa_get_property_predef_flags (table_section); + table_entry_size = 12; + if (predef_flags) + table_entry_size -= 4; + + num_records = table_size / table_entry_size; table_data = retrieve_contents (abfd, table_section, TRUE); blocks = (property_table_entry *) bfd_malloc (num_records * sizeof (property_table_entry)); block_count = 0; - - section_addr = section->output_section->vma + section->output_offset; + + if (output_addr) + section_addr = section->output_section->vma + section->output_offset; + else + section_addr = section->vma; /* If the file has not yet been relocated, process the relocations and sort out the table entries that apply to the specified section. */ @@ -541,11 +787,18 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name) if (get_elf_r_symndx_section (abfd, r_symndx) == section) { bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx); + BFD_ASSERT (sym_off == 0); + BFD_ASSERT (rel->r_addend == 0); blocks[block_count].address = (section_addr + sym_off + rel->r_addend + bfd_get_32 (abfd, table_data + rel->r_offset)); blocks[block_count].size = bfd_get_32 (abfd, table_data + rel->r_offset + 4); + if (predef_flags) + blocks[block_count].flags = predef_flags; + else + blocks[block_count].flags = + bfd_get_32 (abfd, table_data + rel->r_offset + 8); block_count++; } } @@ -555,17 +808,23 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name) /* The file has already been relocated and the addresses are already in the table. */ bfd_vma off; + bfd_size_type section_limit = bfd_get_section_limit (abfd, section); - for (off = 0; off < table_size; off += 8) + for (off = 0; off < table_size; off += table_entry_size) { bfd_vma address = bfd_get_32 (abfd, table_data + off); if (address >= section_addr - && address < section_addr + section->size) + && address < section_addr + section_limit) { blocks[block_count].address = address; blocks[block_count].size = bfd_get_32 (abfd, table_data + off + 4); + if (predef_flags) + blocks[block_count].flags = predef_flags; + else + blocks[block_count].flags = + bfd_get_32 (abfd, table_data + off + 8); block_count++; } } @@ -574,34 +833,47 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name) release_contents (table_section, table_data); release_internal_relocs (table_section, internal_relocs); - if (block_count > 0) + if (block_count > 0) { /* Now sort them into address order for easy reference. */ qsort (blocks, block_count, sizeof (property_table_entry), property_table_compare); } - + *table_p = blocks; return block_count; } -static bfd_boolean -elf_xtensa_in_literal_pool (lit_table, lit_table_size, addr) - property_table_entry *lit_table; - int lit_table_size; +property_table_entry * +elf_xtensa_find_property_entry (property_table, property_table_size, addr) + property_table_entry *property_table; + int property_table_size; bfd_vma addr; { property_table_entry entry; + property_table_entry *rv; - if (lit_table_size == 0) - return FALSE; + if (property_table_size == 0) + return NULL; entry.address = addr; entry.size = 1; + entry.flags = 0; - if (bsearch (&entry, lit_table, lit_table_size, - sizeof (property_table_entry), property_table_compare)) + rv = bsearch (&entry, property_table, property_table_size, + sizeof (property_table_entry), property_table_matches); + return rv; +} + + +static bfd_boolean +elf_xtensa_in_literal_pool (lit_table, lit_table_size, addr) + property_table_entry *lit_table; + int lit_table_size; + bfd_vma addr; +{ + if (elf_xtensa_find_property_entry (lit_table, lit_table_size, addr)) return TRUE; return FALSE; @@ -714,8 +986,8 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs) size = symtab_hdr->sh_info; size *= sizeof (bfd_signed_vma); - local_got_refcounts = ((bfd_signed_vma *) - bfd_zalloc (abfd, size)); + local_got_refcounts = + (bfd_signed_vma *) bfd_zalloc (abfd, size); if (local_got_refcounts == NULL) return FALSE; elf_local_got_refcounts (abfd) = local_got_refcounts; @@ -727,8 +999,41 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs) case R_XTENSA_OP0: case R_XTENSA_OP1: case R_XTENSA_OP2: + case R_XTENSA_SLOT0_OP: + case R_XTENSA_SLOT1_OP: + case R_XTENSA_SLOT2_OP: + case R_XTENSA_SLOT3_OP: + case R_XTENSA_SLOT4_OP: + case R_XTENSA_SLOT5_OP: + case R_XTENSA_SLOT6_OP: + case R_XTENSA_SLOT7_OP: + case R_XTENSA_SLOT8_OP: + case R_XTENSA_SLOT9_OP: + case R_XTENSA_SLOT10_OP: + case R_XTENSA_SLOT11_OP: + case R_XTENSA_SLOT12_OP: + case R_XTENSA_SLOT13_OP: + case R_XTENSA_SLOT14_OP: + case R_XTENSA_SLOT0_ALT: + case R_XTENSA_SLOT1_ALT: + case R_XTENSA_SLOT2_ALT: + case R_XTENSA_SLOT3_ALT: + case R_XTENSA_SLOT4_ALT: + case R_XTENSA_SLOT5_ALT: + case R_XTENSA_SLOT6_ALT: + case R_XTENSA_SLOT7_ALT: + case R_XTENSA_SLOT8_ALT: + case R_XTENSA_SLOT9_ALT: + case R_XTENSA_SLOT10_ALT: + case R_XTENSA_SLOT11_ALT: + case R_XTENSA_SLOT12_ALT: + case R_XTENSA_SLOT13_ALT: + case R_XTENSA_SLOT14_ALT: case R_XTENSA_ASM_EXPAND: case R_XTENSA_ASM_SIMPLIFY: + case R_XTENSA_DIFF8: + case R_XTENSA_DIFF16: + case R_XTENSA_DIFF32: /* Nothing to do for these. */ break; @@ -1417,18 +1722,30 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation, bfd_boolean is_weak_undef; char **error_message; { + xtensa_format fmt; xtensa_opcode opcode; - xtensa_operand operand; - xtensa_encode_result encode_result; xtensa_isa isa = xtensa_default_isa; - xtensa_insnbuf ibuff; - bfd_vma self_address; - int opnd; + static xtensa_insnbuf ibuff = NULL; + static xtensa_insnbuf sbuff = NULL; + bfd_vma self_address = 0; + bfd_size_type input_size; + int opnd, slot; uint32 newval; + if (!ibuff) + { + ibuff = xtensa_insnbuf_alloc (isa); + sbuff = xtensa_insnbuf_alloc (isa); + } + + input_size = bfd_get_section_limit (abfd, input_section); + switch (howto->type) { case R_XTENSA_NONE: + case R_XTENSA_DIFF8: + case R_XTENSA_DIFF16: + case R_XTENSA_DIFF32: return bfd_reloc_ok; case R_XTENSA_ASM_EXPAND: @@ -1437,14 +1754,14 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation, /* Check for windowed CALL across a 1GB boundary. */ xtensa_opcode opcode = get_expanded_call_opcode (contents + address, - input_section->size - address); + input_size - address, 0); if (is_windowed_call_opcode (opcode)) { self_address = (input_section->output_section->vma + input_section->output_offset + address); - if ((self_address >> CALL_SEGMENT_BITS) != - (relocation >> CALL_SEGMENT_BITS)) + if ((self_address >> CALL_SEGMENT_BITS) + != (relocation >> CALL_SEGMENT_BITS)) { *error_message = "windowed longcall crosses 1GB boundary; " "return may fail"; @@ -1455,16 +1772,17 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation, return bfd_reloc_ok; case R_XTENSA_ASM_SIMPLIFY: - { + { /* Convert the L32R/CALLX to CALL. */ - bfd_reloc_status_type retval = - elf_xtensa_do_asm_simplify (contents, address, input_section->size); + bfd_reloc_status_type retval = + elf_xtensa_do_asm_simplify (contents, address, input_size, + error_message); if (retval != bfd_reloc_ok) - return retval; + return bfd_reloc_dangerous; /* The CALL needs to be relocated. Continue below for that part. */ address += 3; - howto = &elf_howto_table[(unsigned) R_XTENSA_OP0 ]; + howto = &elf_howto_table[(unsigned) R_XTENSA_SLOT0_OP ]; } break; @@ -1479,67 +1797,125 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation, return bfd_reloc_ok; } - /* Read the instruction into a buffer and decode the opcode. */ - ibuff = xtensa_insnbuf_alloc (isa); - xtensa_insnbuf_from_chars (isa, ibuff, contents + address); - opcode = xtensa_decode_insn (isa, ibuff); - - /* Determine which operand is being relocated. */ - if (opcode == XTENSA_UNDEFINED) + /* Only instruction slot-specific relocations handled below.... */ + slot = get_relocation_slot (howto->type); + if (slot == XTENSA_UNDEFINED) { - *error_message = "cannot decode instruction"; + *error_message = "unexpected relocation"; return bfd_reloc_dangerous; } - if (howto->type < R_XTENSA_OP0 || howto->type > R_XTENSA_OP2) + /* Read the instruction into a buffer and decode the opcode. */ + xtensa_insnbuf_from_chars (isa, ibuff, contents + address, + input_size - address); + fmt = xtensa_format_decode (isa, ibuff); + if (fmt == XTENSA_UNDEFINED) { - *error_message = "unexpected relocation"; + *error_message = "cannot decode instruction format"; return bfd_reloc_dangerous; } - opnd = howto->type - R_XTENSA_OP0; + xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff); - /* Calculate the PC address for this instruction. */ - if (!howto->pc_relative) + opcode = xtensa_opcode_decode (isa, fmt, slot, sbuff); + if (opcode == XTENSA_UNDEFINED) { - *error_message = "expected PC-relative relocation"; + *error_message = "cannot decode instruction opcode"; return bfd_reloc_dangerous; } - self_address = (input_section->output_section->vma - + input_section->output_offset - + address); + /* Check for opcode-specific "alternate" relocations. */ + if (is_alt_relocation (howto->type)) + { + if (opcode == get_l32r_opcode ()) + { + /* Handle the special-case of non-PC-relative L32R instructions. */ + bfd *output_bfd = input_section->output_section->owner; + asection *lit4_sec = bfd_get_section_by_name (output_bfd, ".lit4"); + if (!lit4_sec) + { + *error_message = "relocation references missing .lit4 section"; + return bfd_reloc_dangerous; + } + self_address = ((lit4_sec->vma & ~0xfff) + + 0x40000 - 3); /* -3 to compensate for do_reloc */ + newval = relocation; + opnd = 1; + } + else if (opcode == get_const16_opcode ()) + { + /* ALT used for high 16 bits. */ + newval = relocation >> 16; + opnd = 1; + } + else + { + /* No other "alternate" relocations currently defined. */ + *error_message = "unexpected relocation"; + return bfd_reloc_dangerous; + } + } + else /* Not an "alternate" relocation.... */ + { + if (opcode == get_const16_opcode ()) + { + newval = relocation & 0xffff; + opnd = 1; + } + else + { + /* ...normal PC-relative relocation.... */ - /* Apply the relocation. */ - operand = xtensa_get_operand (isa, opcode, opnd); - newval = xtensa_operand_do_reloc (operand, relocation, self_address); - encode_result = xtensa_operand_encode (operand, &newval); - xtensa_operand_set_field (operand, ibuff, newval); + /* Determine which operand is being relocated. */ + opnd = get_relocation_opnd (opcode, howto->type); + if (opnd == XTENSA_UNDEFINED) + { + *error_message = "unexpected relocation"; + return bfd_reloc_dangerous; + } - /* Write the modified instruction back out of the buffer. */ - xtensa_insnbuf_to_chars (isa, ibuff, contents + address); - free (ibuff); + if (!howto->pc_relative) + { + *error_message = "expected PC-relative relocation"; + return bfd_reloc_dangerous; + } - if (encode_result != xtensa_encode_result_ok) + /* Calculate the PC address for this instruction. */ + self_address = (input_section->output_section->vma + + input_section->output_offset + + address); + + newval = relocation; + } + } + + /* Apply the relocation. */ + if (xtensa_operand_do_reloc (isa, opcode, opnd, &newval, self_address) + || xtensa_operand_encode (isa, opcode, opnd, &newval) + || xtensa_operand_set_field (isa, opcode, opnd, fmt, slot, + sbuff, newval)) { - char *message = build_encoding_error_message (opcode, encode_result); - *error_message = message; + *error_message = build_encoding_error_message (opcode, relocation); return bfd_reloc_dangerous; } - /* Final check for call. */ + /* Check for calls across 1GB boundaries. */ if (is_direct_call_opcode (opcode) && is_windowed_call_opcode (opcode)) { - if ((self_address >> CALL_SEGMENT_BITS) != - (relocation >> CALL_SEGMENT_BITS)) + if ((self_address >> CALL_SEGMENT_BITS) + != (relocation >> CALL_SEGMENT_BITS)) { - *error_message = "windowed call crosses 1GB boundary; " - "return may fail"; + *error_message = + "windowed call crosses 1GB boundary; return may fail"; return bfd_reloc_dangerous; } } + /* Write the modified instruction back out of the buffer. */ + xtensa_format_set_slot (isa, fmt, slot, ibuff, sbuff); + xtensa_insnbuf_to_chars (isa, ibuff, contents + address, + input_size - address); return bfd_reloc_ok; } @@ -1575,55 +1951,29 @@ vsprint_msg VPARAMS ((const char *origmsg, const char *fmt, int arglen, ...)) static char * -build_encoding_error_message (opcode, encode_result) +build_encoding_error_message (opcode, target_address) xtensa_opcode opcode; - xtensa_encode_result encode_result; + bfd_vma target_address; { const char *opname = xtensa_opcode_name (xtensa_default_isa, opcode); - const char *msg = NULL; + const char *msg; - switch (encode_result) + msg = "cannot encode"; + if (is_direct_call_opcode (opcode)) { - case xtensa_encode_result_ok: - msg = "unexpected valid encoding"; - break; - case xtensa_encode_result_align: - msg = "misaligned encoding"; - break; - case xtensa_encode_result_not_in_table: - msg = "encoding not in lookup table"; - break; - case xtensa_encode_result_too_low: - msg = "encoding out of range: too low"; - break; - case xtensa_encode_result_too_high: - msg = "encoding out of range: too high"; - break; - case xtensa_encode_result_not_ok: - default: - msg = "could not encode"; - break; + if ((target_address & 0x3) != 0) + msg = "misaligned call target"; + else + msg = "call target out of range"; } - - if (is_direct_call_opcode (opcode) - && (encode_result == xtensa_encode_result_too_low - || encode_result == xtensa_encode_result_too_high)) - - msg = "direct call out of range"; - - else if (opcode == get_l32r_opcode ()) + else if (opcode == get_l32r_opcode ()) { - /* L32Rs have the strange interaction with encoding in that they - have an unsigned immediate field, so libisa returns "too high" - when the absolute value is out of range and never returns "too - low", but I leave the "too low" message in case anything - changes. */ - if (encode_result == xtensa_encode_result_too_low) - msg = "literal out of range"; - else if (encode_result == xtensa_encode_result_too_high) - msg = "literal placed after use"; + if ((target_address & 0x3) != 0) + msg = "misaligned literal target"; + else + msg = "literal target out of range"; } - + return vsprint_msg (opname, ": %s", strlen (msg) + 2, msg); } @@ -1709,7 +2059,7 @@ bfd_elf_xtensa_reloc (abfd, reloc_entry, symbol, data, input_section, to the reloc entry rather than the raw data. Everything except relocations against section symbols has already been handled above. */ - + BFD_ASSERT (symbol->flags & BSF_SECTION_SYM); reloc_entry->addend = relocation; reloc_entry->address += input_section->output_offset; @@ -1816,9 +2166,10 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, property_table_entry *lit_table = 0; int ltblsize = 0; char *error_message = NULL; + bfd_size_type input_size; - if (xtensa_default_isa == NULL) - xtensa_isa_init (); + if (!xtensa_default_isa) + xtensa_default_isa = xtensa_isa_init (0, 0); dynobj = elf_hash_table (info)->dynobj; symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; @@ -1835,11 +2186,14 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, if (elf_hash_table (info)->dynamic_sections_created) { ltblsize = xtensa_read_table_entries (input_bfd, input_section, - &lit_table, XTENSA_LIT_SEC_NAME); + &lit_table, XTENSA_LIT_SEC_NAME, + TRUE); if (ltblsize < 0) return FALSE; } + input_size = bfd_get_section_limit (input_bfd, input_section); + rel = relocs; relend = relocs + input_section->reloc_count; for (; rel < relend; rel++) @@ -1872,7 +2226,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, if (info->relocatable) { - /* This is a relocatable link. + /* This is a relocatable link. 1) If the reloc is against a section symbol, adjust according to the output section. 2) If there is a new target for this relocation, @@ -1883,15 +2237,26 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, if (relaxing_section) { /* Check if this references a section in another input file. */ - do_fix_for_relocatable_link (rel, input_bfd, input_section); + if (!do_fix_for_relocatable_link (rel, input_bfd, input_section, + contents)) + return FALSE; r_type = ELF32_R_TYPE (rel->r_info); } - if (r_type == R_XTENSA_ASM_SIMPLIFY) + if (r_type == R_XTENSA_ASM_SIMPLIFY) { + char *error_message = NULL; /* Convert ASM_SIMPLIFY into the simpler relocation so that they never escape a relaxing link. */ - contract_asm_expansion (contents, input_section->size, rel); + r = contract_asm_expansion (contents, input_size, rel, + &error_message); + if (r != bfd_reloc_ok) + { + if (!((*info->callbacks->reloc_dangerous) + (info, error_message, input_bfd, input_section, + rel->r_offset))) + return FALSE; + } r_type = ELF32_R_TYPE (rel->r_info); } @@ -1979,7 +2344,8 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, if (relaxing_section) { /* Check if this references a section in another input file. */ - do_fix_for_final_link (rel, input_section, &relocation); + do_fix_for_final_link (rel, input_bfd, input_section, contents, + &relocation); /* Update some already cached values. */ r_type = ELF32_R_TYPE (rel->r_info); @@ -1987,9 +2353,12 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, } /* Sanity check the address. */ - if (rel->r_offset >= bfd_get_section_limit (input_bfd, input_section) + if (rel->r_offset >= input_size && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE) { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): relocation offset out of range (size=0x%x)"), + input_bfd, input_section, rel->r_offset, input_size); bfd_set_error (bfd_error_bad_value); return FALSE; } @@ -1999,9 +2368,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, { bfd_boolean dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info); - if (dynamic_symbol && (r_type == R_XTENSA_OP0 - || r_type == R_XTENSA_OP1 - || r_type == R_XTENSA_OP2)) + if (dynamic_symbol && is_operand_relocation (r_type)) { /* This is an error. The symbol's real value won't be known until runtime and it's likely to be out of range anyway. */ @@ -2073,7 +2440,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, /* Create the PLT entry and set the initial contents of the literal entry to the address of the PLT entry. */ - relocation = + relocation = elf_xtensa_create_plt_entry (dynobj, output_bfd, srel->reloc_count); } @@ -2114,12 +2481,12 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, relocation + rel->r_addend, contents, rel->r_offset, is_weak_undef, &error_message); - + if (r != bfd_reloc_ok && !warned) { const char *name; - BFD_ASSERT (r == bfd_reloc_dangerous); + BFD_ASSERT (r == bfd_reloc_dangerous || r == bfd_reloc_other); BFD_ASSERT (error_message != (char *) NULL); if (h != NULL) @@ -2132,8 +2499,16 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, name = bfd_section_name (input_bfd, sec); } if (name) - error_message = vsprint_msg (error_message, ": %s", - strlen (name), name); + { + if (rel->r_addend == 0) + error_message = vsprint_msg (error_message, ": %s", + strlen (name) + 2, name); + else + error_message = vsprint_msg (error_message, ": (%s+0x%x)", + strlen (name) + 22, + name, rel->r_addend); + } + if (!((*info->callbacks->reloc_dangerous) (info, error_message, input_bfd, input_section, rel->r_offset))) @@ -2205,7 +2580,7 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc) if (sgotloc_size != section_size) { (*_bfd_error_handler) - ("internal inconsistency in size of .got.loc section"); + (_("internal inconsistency in size of .got.loc section")); return -1; } @@ -2519,10 +2894,10 @@ elf_xtensa_merge_private_bfd_data (ibfd, obfd) out_mach = out_flag & EF_XTENSA_MACH; in_mach = in_flag & EF_XTENSA_MACH; - if (out_mach != in_mach) + if (out_mach != in_mach) { (*_bfd_error_handler) - ("%B: incompatible machine type. Output is 0x%x. Input is 0x%x", + (_("%B: incompatible machine type. Output is 0x%x. Input is 0x%x"), ibfd, out_mach, in_mach); bfd_set_error (bfd_error_wrong_format); return FALSE; @@ -2532,22 +2907,20 @@ elf_xtensa_merge_private_bfd_data (ibfd, obfd) { elf_flags_init (obfd) = TRUE; elf_elfheader (obfd)->e_flags = in_flag; - + if (bfd_get_arch (obfd) == bfd_get_arch (ibfd) && bfd_get_arch_info (obfd)->the_default) return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd), bfd_get_mach (ibfd)); - + return TRUE; } - if ((out_flag & EF_XTENSA_XT_INSN) != - (in_flag & EF_XTENSA_XT_INSN)) - elf_elfheader(obfd)->e_flags &= (~ EF_XTENSA_XT_INSN); + if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN)) + elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_INSN); - if ((out_flag & EF_XTENSA_XT_LIT) != - (in_flag & EF_XTENSA_XT_LIT)) - elf_elfheader(obfd)->e_flags &= (~ EF_XTENSA_XT_LIT); + if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT)) + elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_LIT); return TRUE; } @@ -2585,7 +2958,7 @@ elf_xtensa_print_private_bfd_data (abfd, farg) flagword e_flags = elf_elfheader (abfd)->e_flags; fprintf (f, "\nXtensa header:\n"); - if ((e_flags & EF_XTENSA_MACH) == E_XTENSA_MACH) + if ((e_flags & EF_XTENSA_MACH) == E_XTENSA_MACH) fprintf (f, "\nMachine = Base\n"); else fprintf (f, "\nMachine Id = 0x%x\n", e_flags & EF_XTENSA_MACH); @@ -2949,13 +3322,29 @@ is_windowed_call_opcode (opcode) static xtensa_opcode +get_const16_opcode (void) +{ + static bfd_boolean done_lookup = FALSE; + static xtensa_opcode const16_opcode = XTENSA_UNDEFINED; + if (!done_lookup) + { + const16_opcode = xtensa_opcode_lookup (xtensa_default_isa, "const16"); + done_lookup = TRUE; + } + return const16_opcode; +} + + +static xtensa_opcode get_l32r_opcode (void) { static xtensa_opcode l32r_opcode = XTENSA_UNDEFINED; - if (l32r_opcode == XTENSA_UNDEFINED) + static bfd_boolean done_lookup = FALSE; + + if (!done_lookup) { l32r_opcode = xtensa_opcode_lookup (xtensa_default_isa, "l32r"); - BFD_ASSERT (l32r_opcode != XTENSA_UNDEFINED); + done_lookup = TRUE; } return l32r_opcode; } @@ -2976,136 +3365,800 @@ l32r_offset (addr, pc) } -/* Get the operand number for a PC-relative relocation. - If the relocation is not a PC-relative one, return (-1). */ - static int -get_relocation_opnd (irel) - Elf_Internal_Rela *irel; +get_relocation_opnd (opcode, r_type) + xtensa_opcode opcode; + int r_type; { - if (ELF32_R_TYPE (irel->r_info) < R_XTENSA_OP0 - || ELF32_R_TYPE (irel->r_info) >= R_XTENSA_max) - return -1; - return ELF32_R_TYPE (irel->r_info) - R_XTENSA_OP0; + xtensa_isa isa = xtensa_default_isa; + int last_immed, last_opnd, opi; + + if (opcode == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + + /* Find the last visible PC-relative immediate operand for the opcode. + If there are no PC-relative immediates, then choose the last visible + immediate; otherwise, fail and return XTENSA_UNDEFINED. */ + last_immed = XTENSA_UNDEFINED; + last_opnd = xtensa_opcode_num_operands (isa, opcode); + for (opi = last_opnd - 1; opi >= 0; opi--) + { + if (xtensa_operand_is_visible (isa, opcode, opi) == 0) + continue; + if (xtensa_operand_is_PCrelative (isa, opcode, opi) == 1) + { + last_immed = opi; + break; + } + if (last_immed == XTENSA_UNDEFINED + && xtensa_operand_is_register (isa, opcode, opi) == 0) + last_immed = opi; + } + if (last_immed < 0) + return XTENSA_UNDEFINED; + + /* If the operand number was specified in an old-style relocation, + check for consistency with the operand computed above. */ + if (r_type >= R_XTENSA_OP0 && r_type <= R_XTENSA_OP2) + { + int reloc_opnd = r_type - R_XTENSA_OP0; + if (reloc_opnd != last_immed) + return XTENSA_UNDEFINED; + } + + return last_immed; +} + + +int +get_relocation_slot (r_type) + int r_type; +{ + switch (r_type) + { + case R_XTENSA_OP0: + case R_XTENSA_OP1: + case R_XTENSA_OP2: + return 0; + + default: + if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP) + return r_type - R_XTENSA_SLOT0_OP; + if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT) + return r_type - R_XTENSA_SLOT0_ALT; + break; + } + + return XTENSA_UNDEFINED; } /* Get the opcode for a relocation. */ static xtensa_opcode -get_relocation_opcode (sec, contents, irel) +get_relocation_opcode (abfd, sec, contents, irel) + bfd *abfd; asection *sec; bfd_byte *contents; Elf_Internal_Rela *irel; { static xtensa_insnbuf ibuff = NULL; + static xtensa_insnbuf sbuff = NULL; xtensa_isa isa = xtensa_default_isa; - - if (get_relocation_opnd (irel) == -1) - return XTENSA_UNDEFINED; + xtensa_format fmt; + int slot; if (contents == NULL) return XTENSA_UNDEFINED; - if (sec->size <= irel->r_offset) + if (bfd_get_section_limit (abfd, sec) <= irel->r_offset) return XTENSA_UNDEFINED; if (ibuff == NULL) - ibuff = xtensa_insnbuf_alloc (isa); - + { + ibuff = xtensa_insnbuf_alloc (isa); + sbuff = xtensa_insnbuf_alloc (isa); + } + /* Decode the instruction. */ - xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset]); - return xtensa_decode_insn (isa, ibuff); + xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset], + sec->size - irel->r_offset); + fmt = xtensa_format_decode (isa, ibuff); + slot = get_relocation_slot (ELF32_R_TYPE (irel->r_info)); + if (slot == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff); + return xtensa_opcode_decode (isa, fmt, slot, sbuff); } bfd_boolean -is_l32r_relocation (sec, contents, irel) +is_l32r_relocation (abfd, sec, contents, irel) + bfd *abfd; asection *sec; bfd_byte *contents; Elf_Internal_Rela *irel; { xtensa_opcode opcode; - - if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_OP1) + if (!is_operand_relocation (ELF32_R_TYPE (irel->r_info))) return FALSE; - - opcode = get_relocation_opcode (sec, contents, irel); + opcode = get_relocation_opcode (abfd, sec, contents, irel); return (opcode == get_l32r_opcode ()); } + +static bfd_size_type +get_asm_simplify_size (contents, content_len, offset) + bfd_byte *contents; + bfd_size_type content_len; + bfd_size_type offset; +{ + bfd_size_type insnlen, size = 0; + + /* Decode the size of the next two instructions. */ + insnlen = insn_decode_len (contents, content_len, offset); + if (insnlen == 0) + return 0; + + size += insnlen; + + insnlen = insn_decode_len (contents, content_len, offset + size); + if (insnlen == 0) + return 0; + + size += insnlen; + return size; +} + + +bfd_boolean +is_alt_relocation (r_type) + int r_type; +{ + return (r_type >= R_XTENSA_SLOT0_ALT + && r_type <= R_XTENSA_SLOT14_ALT); +} + + +bfd_boolean +is_operand_relocation (r_type) + int r_type; +{ + switch (r_type) + { + case R_XTENSA_OP0: + case R_XTENSA_OP1: + case R_XTENSA_OP2: + return TRUE; + + default: + if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP) + return TRUE; + if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT) + return TRUE; + break; + } + + return FALSE; +} + + +#define MIN_INSN_LENGTH 2 + +/* Return 0 if it fails to decode. */ + +bfd_size_type +insn_decode_len (contents, content_len, offset) + bfd_byte *contents; + bfd_size_type content_len; + bfd_size_type offset; +{ + int insn_len; + xtensa_isa isa = xtensa_default_isa; + xtensa_format fmt; + static xtensa_insnbuf ibuff = NULL; + + if (offset + MIN_INSN_LENGTH > content_len) + return 0; + + if (ibuff == NULL) + ibuff = xtensa_insnbuf_alloc (isa); + xtensa_insnbuf_from_chars (isa, ibuff, &contents[offset], + content_len - offset); + fmt = xtensa_format_decode (isa, ibuff); + if (fmt == XTENSA_UNDEFINED) + return 0; + insn_len = xtensa_format_length (isa, fmt); + if (insn_len == XTENSA_UNDEFINED) + return 0; + return insn_len; +} + + +/* Decode the opcode for a single slot instruction. + Return 0 if it fails to decode or the instruction is multi-slot. */ + +xtensa_opcode +insn_decode_opcode (contents, content_len, offset, slot) + bfd_byte *contents; + bfd_size_type content_len; + bfd_size_type offset; + int slot; +{ + xtensa_isa isa = xtensa_default_isa; + xtensa_format fmt; + static xtensa_insnbuf insnbuf = NULL; + static xtensa_insnbuf slotbuf = NULL; + + if (offset + MIN_INSN_LENGTH > content_len) + return XTENSA_UNDEFINED; + + if (insnbuf == NULL) + { + insnbuf = xtensa_insnbuf_alloc (isa); + slotbuf = xtensa_insnbuf_alloc (isa); + } + + xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset], + content_len - offset); + fmt = xtensa_format_decode (isa, insnbuf); + if (fmt == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + + if (slot >= xtensa_format_num_slots (isa, fmt)) + return XTENSA_UNDEFINED; + + xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf); + return xtensa_opcode_decode (isa, fmt, slot, slotbuf); +} + + +/* The offset is the offset in the contents. + The address is the address of that offset. */ + +static bfd_boolean +check_branch_target_aligned (contents, content_length, offset, address) + bfd_byte *contents; + bfd_size_type content_length; + bfd_vma offset; + bfd_vma address; +{ + bfd_size_type insn_len = insn_decode_len (contents, content_length, offset); + if (insn_len == 0) + return FALSE; + return check_branch_target_aligned_address (address, insn_len); +} + + +static bfd_boolean +check_loop_aligned (contents, content_length, offset, address) + bfd_byte *contents; + bfd_size_type content_length; + bfd_vma offset; + bfd_vma address; +{ + bfd_size_type loop_len, insn_len; + xtensa_opcode opcode = + insn_decode_opcode (contents, content_length, offset, 0); + BFD_ASSERT (opcode != XTENSA_UNDEFINED); + if (opcode != XTENSA_UNDEFINED) + return FALSE; + BFD_ASSERT (xtensa_opcode_is_loop (xtensa_default_isa, opcode)); + if (!xtensa_opcode_is_loop (xtensa_default_isa, opcode)) + return FALSE; + + loop_len = insn_decode_len (contents, content_length, offset); + BFD_ASSERT (loop_len != 0); + if (loop_len == 0) + return FALSE; + + insn_len = insn_decode_len (contents, content_length, offset + loop_len); + BFD_ASSERT (insn_len != 0); + if (insn_len == 0) + return FALSE; + + return check_branch_target_aligned_address (address + loop_len, insn_len); +} + + +static bfd_boolean +check_branch_target_aligned_address (addr, len) + bfd_vma addr; + int len; +{ + if (len == 8) + return (addr % 8 == 0); + return ((addr >> 2) == ((addr + len - 1) >> 2)); +} + + +/* Instruction widening and narrowing. */ + +static bfd_boolean narrow_instruction + PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, bfd_boolean)); +static bfd_boolean widen_instruction + PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, bfd_boolean)); +static xtensa_format get_single_format + PARAMS ((xtensa_opcode)); +static void init_op_single_format_table + PARAMS ((void)); + + +struct string_pair +{ + const char *wide; + const char *narrow; +}; + + +/* For the set of narrowable instructions we do NOT include the + narrowings beqz -> beqz.n or bnez -> bnez.n because of complexities + involved during linker relaxation that may require these to + re-expand in some conditions. Also, the narrowing "or" -> mov.n + requires special case code to ensure it only works when op1 == op2. */ + +struct string_pair narrowable[] = +{ + { "add", "add.n" }, + { "addi", "addi.n" }, + { "addmi", "addi.n" }, + { "l32i", "l32i.n" }, + { "movi", "movi.n" }, + { "ret", "ret.n" }, + { "retw", "retw.n" }, + { "s32i", "s32i.n" }, + { "or", "mov.n" } /* special case only when op1 == op2 */ +}; + +struct string_pair widenable[] = +{ + { "add", "add.n" }, + { "addi", "addi.n" }, + { "addmi", "addi.n" }, + { "beqz", "beqz.n" }, + { "bnez", "bnez.n" }, + { "l32i", "l32i.n" }, + { "movi", "movi.n" }, + { "ret", "ret.n" }, + { "retw", "retw.n" }, + { "s32i", "s32i.n" }, + { "or", "mov.n" } /* special case only when op1 == op2 */ +}; + + +/* Attempt to narrow an instruction. Return true if the narrowing is + valid. If the do_it parameter is non-zero, then perform the action + in-place directly into the contents. Otherwise, do not modify the + contents. The set of valid narrowing are specified by a string table + but require some special case operand checks in some cases. */ + +static bfd_boolean +narrow_instruction (contents, content_length, offset, do_it) + bfd_byte *contents; + bfd_size_type content_length; + bfd_size_type offset; + bfd_boolean do_it; +{ + xtensa_opcode opcode; + bfd_size_type insn_len, opi; + xtensa_isa isa = xtensa_default_isa; + xtensa_format fmt, o_fmt; + + static xtensa_insnbuf insnbuf = NULL; + static xtensa_insnbuf slotbuf = NULL; + static xtensa_insnbuf o_insnbuf = NULL; + static xtensa_insnbuf o_slotbuf = NULL; + + if (insnbuf == NULL) + { + insnbuf = xtensa_insnbuf_alloc (isa); + slotbuf = xtensa_insnbuf_alloc (isa); + o_insnbuf = xtensa_insnbuf_alloc (isa); + o_slotbuf = xtensa_insnbuf_alloc (isa); + } + + BFD_ASSERT (offset < content_length); + + if (content_length < 2) + return FALSE; + + /* We will hand-code a few of these for a little while. + These have all been specified in the assembler aleady. */ + xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset], + content_length - offset); + fmt = xtensa_format_decode (isa, insnbuf); + if (xtensa_format_num_slots (isa, fmt) != 1) + return FALSE; + + if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0) + return FALSE; + + opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf); + if (opcode == XTENSA_UNDEFINED) + return FALSE; + insn_len = xtensa_format_length (isa, fmt); + if (insn_len > content_length) + return FALSE; + + for (opi = 0; opi < (sizeof (narrowable)/sizeof (struct string_pair)); ++opi) + { + bfd_boolean is_or = (strcmp ("or", narrowable[opi].wide) == 0); + + if (opcode == xtensa_opcode_lookup (isa, narrowable[opi].wide)) + { + uint32 value, newval; + int i, operand_count, o_operand_count; + xtensa_opcode o_opcode; + + /* Address does not matter in this case. We might need to + fix it to handle branches/jumps. */ + bfd_vma self_address = 0; + + o_opcode = xtensa_opcode_lookup (isa, narrowable[opi].narrow); + if (o_opcode == XTENSA_UNDEFINED) + return FALSE; + o_fmt = get_single_format (o_opcode); + if (o_fmt == XTENSA_UNDEFINED) + return FALSE; + + if (xtensa_format_length (isa, fmt) != 3 + || xtensa_format_length (isa, o_fmt) != 2) + return FALSE; + + xtensa_format_encode (isa, o_fmt, o_slotbuf); + xtensa_format_encode (isa, o_fmt, o_insnbuf); + operand_count = xtensa_opcode_num_operands (isa, opcode); + o_operand_count = xtensa_opcode_num_operands (isa, o_opcode); + + if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0) + return FALSE; + + if (!is_or) + { + if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count) + return FALSE; + } + else + { + uint32 rawval0, rawval1, rawval2; + + if (o_operand_count + 1 != operand_count) + return FALSE; + if (xtensa_operand_get_field (isa, opcode, 0, + fmt, 0, slotbuf, &rawval0) != 0) + return FALSE; + if (xtensa_operand_get_field (isa, opcode, 1, + fmt, 0, slotbuf, &rawval1) != 0) + return FALSE; + if (xtensa_operand_get_field (isa, opcode, 2, + fmt, 0, slotbuf, &rawval2) != 0) + return FALSE; + + if (rawval1 != rawval2) + return FALSE; + if (rawval0 == rawval1) /* it is a nop */ + return FALSE; + } + + for (i = 0; i < o_operand_count; ++i) + { + if (xtensa_operand_get_field (isa, opcode, i, fmt, 0, + slotbuf, &value) + || xtensa_operand_decode (isa, opcode, i, &value)) + return FALSE; + + /* PC-relative branches need adjustment, but + the PC-rel operand will always have a relocation. */ + newval = value; + if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval, + self_address) + || xtensa_operand_encode (isa, o_opcode, i, &newval) + || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0, + o_slotbuf, newval)) + return FALSE; + } + + if (xtensa_format_set_slot (isa, o_fmt, 0, + o_insnbuf, o_slotbuf) != 0) + return FALSE; + + if (do_it) + xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset, + content_length - offset); + return TRUE; + } + } + return FALSE; +} + + +/* Attempt to widen an instruction. Return true if the widening is + valid. If the do_it parameter is non-zero, then the action should + be performed inplace into the contents. Otherwise, do not modify + the contents. The set of valid widenings are specified by a string + table but require some special case operand checks in some + cases. */ + +static bfd_boolean +widen_instruction (contents, content_length, offset, do_it) + bfd_byte *contents; + bfd_size_type content_length; + bfd_size_type offset; + bfd_boolean do_it; +{ + xtensa_opcode opcode; + bfd_size_type insn_len, opi; + xtensa_isa isa = xtensa_default_isa; + xtensa_format fmt, o_fmt; + + static xtensa_insnbuf insnbuf = NULL; + static xtensa_insnbuf slotbuf = NULL; + static xtensa_insnbuf o_insnbuf = NULL; + static xtensa_insnbuf o_slotbuf = NULL; + + if (insnbuf == NULL) + { + insnbuf = xtensa_insnbuf_alloc (isa); + slotbuf = xtensa_insnbuf_alloc (isa); + o_insnbuf = xtensa_insnbuf_alloc (isa); + o_slotbuf = xtensa_insnbuf_alloc (isa); + } + + BFD_ASSERT (offset < content_length); + + if (content_length < 2) + return FALSE; + + /* We will hand code a few of these for a little while. + These have all been specified in the assembler aleady. */ + xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset], + content_length - offset); + fmt = xtensa_format_decode (isa, insnbuf); + if (xtensa_format_num_slots (isa, fmt) != 1) + return FALSE; + + if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0) + return FALSE; + + opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf); + if (opcode == XTENSA_UNDEFINED) + return FALSE; + insn_len = xtensa_format_length (isa, fmt); + if (insn_len > content_length) + return FALSE; + + for (opi = 0; opi < (sizeof (widenable)/sizeof (struct string_pair)); ++opi) + { + bfd_boolean is_or = (strcmp ("or", widenable[opi].wide) == 0); + bfd_boolean is_branch = (strcmp ("beqz", widenable[opi].wide) == 0 + || strcmp ("bnez", widenable[opi].wide) == 0); + + if (opcode == xtensa_opcode_lookup (isa, widenable[opi].narrow)) + { + uint32 value, newval; + int i, operand_count, o_operand_count, check_operand_count; + xtensa_opcode o_opcode; + + /* Address does not matter in this case. We might need to fix it + to handle branches/jumps. */ + bfd_vma self_address = 0; + + o_opcode = xtensa_opcode_lookup (isa, widenable[opi].wide); + if (o_opcode == XTENSA_UNDEFINED) + return FALSE; + o_fmt = get_single_format (o_opcode); + if (o_fmt == XTENSA_UNDEFINED) + return FALSE; + + if (xtensa_format_length (isa, fmt) != 2 + || xtensa_format_length (isa, o_fmt) != 3) + return FALSE; + + xtensa_format_encode (isa, o_fmt, o_slotbuf); + xtensa_format_encode (isa, o_fmt, o_insnbuf); + operand_count = xtensa_opcode_num_operands (isa, opcode); + o_operand_count = xtensa_opcode_num_operands (isa, o_opcode); + check_operand_count = o_operand_count; + + if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0) + return FALSE; + + if (!is_or) + { + if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count) + return FALSE; + } + else + { + uint32 rawval0, rawval1; + + if (o_operand_count != operand_count + 1) + return FALSE; + if (xtensa_operand_get_field (isa, opcode, 0, + fmt, 0, slotbuf, &rawval0) != 0) + return FALSE; + if (xtensa_operand_get_field (isa, opcode, 1, + fmt, 0, slotbuf, &rawval1) != 0) + return FALSE; + if (rawval0 == rawval1) /* it is a nop */ + return FALSE; + } + if (is_branch) + check_operand_count--; + + for (i = 0; i < check_operand_count; ++i) + { + int new_i = i; + if (is_or && i == o_operand_count - 1) + new_i = i - 1; + if (xtensa_operand_get_field (isa, opcode, new_i, fmt, 0, + slotbuf, &value) + || xtensa_operand_decode (isa, opcode, new_i, &value)) + return FALSE; + + /* PC-relative branches need adjustment, but + the PC-rel operand will always have a relocation. */ + newval = value; + if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval, + self_address) + || xtensa_operand_encode (isa, o_opcode, i, &newval) + || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0, + o_slotbuf, newval)) + return FALSE; + } + + if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf)) + return FALSE; + + if (do_it) + xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset, + content_length - offset); + return TRUE; + } + } + return FALSE; +} + + +/* When FLIX is available we need to access certain instructions only + when they are 16-bit or 24-bit instructions. This table caches + information about such instructions by walking through all the + opcodes and finding the smallest single-slot format into which each + can be encoded. */ + +static xtensa_format *op_single_fmt_table = NULL; + + +static xtensa_format +get_single_format (opcode) + xtensa_opcode opcode; +{ + init_op_single_format_table (); + return op_single_fmt_table[opcode]; +} + + +static void +init_op_single_format_table () +{ + xtensa_isa isa = xtensa_default_isa; + xtensa_insnbuf ibuf; + xtensa_opcode opcode; + xtensa_format fmt; + int num_opcodes; + + if (op_single_fmt_table != NULL) + return; + + ibuf = xtensa_insnbuf_alloc (isa); + num_opcodes = xtensa_isa_num_opcodes (isa); + + op_single_fmt_table = (xtensa_format *) + bfd_malloc (sizeof (xtensa_format) * num_opcodes); + for (opcode = 0; opcode < num_opcodes; opcode++) + { + op_single_fmt_table[opcode] = XTENSA_UNDEFINED; + for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++) + { + if (xtensa_format_num_slots (isa, fmt) == 1 + && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0) + { + xtensa_opcode old_fmt = op_single_fmt_table[opcode]; + int fmt_length = xtensa_format_length (isa, fmt); + if (old_fmt == XTENSA_UNDEFINED + || fmt_length < xtensa_format_length (isa, old_fmt)) + op_single_fmt_table[opcode] = fmt; + } + } + } + xtensa_insnbuf_free (isa, ibuf); +} + /* Code for transforming CALLs at link-time. */ static bfd_reloc_status_type -elf_xtensa_do_asm_simplify (contents, address, content_length) +elf_xtensa_do_asm_simplify (contents, address, content_length, error_message) bfd_byte *contents; bfd_vma address; bfd_vma content_length; + char **error_message; { static xtensa_insnbuf insnbuf = NULL; + static xtensa_insnbuf slotbuf = NULL; + xtensa_format core_format = XTENSA_UNDEFINED; xtensa_opcode opcode; - xtensa_operand operand; xtensa_opcode direct_call_opcode; xtensa_isa isa = xtensa_default_isa; bfd_byte *chbuf = contents + address; int opn; if (insnbuf == NULL) - insnbuf = xtensa_insnbuf_alloc (isa); + { + insnbuf = xtensa_insnbuf_alloc (isa); + slotbuf = xtensa_insnbuf_alloc (isa); + } if (content_length < address) { - (*_bfd_error_handler) - ("Attempt to convert L32R/CALLX to CALL failed"); + *error_message = _("Attempt to convert L32R/CALLX to CALL failed"); return bfd_reloc_other; } - opcode = get_expanded_call_opcode (chbuf, content_length - address); + opcode = get_expanded_call_opcode (chbuf, content_length - address, 0); direct_call_opcode = swap_callx_for_call_opcode (opcode); if (direct_call_opcode == XTENSA_UNDEFINED) { - (*_bfd_error_handler) - ("Attempt to convert L32R/CALLX to CALL failed"); + *error_message = _("Attempt to convert L32R/CALLX to CALL failed"); return bfd_reloc_other; } /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset. */ + core_format = xtensa_format_lookup (isa, "x24"); opcode = xtensa_opcode_lookup (isa, "or"); - xtensa_encode_insn (isa, opcode, insnbuf); + xtensa_opcode_encode (isa, core_format, 0, slotbuf, opcode); for (opn = 0; opn < 3; opn++) { - operand = xtensa_get_operand (isa, opcode, opn); - xtensa_operand_set_field (operand, insnbuf, 1); + uint32 regno = 1; + xtensa_operand_encode (isa, opcode, opn, ®no); + xtensa_operand_set_field (isa, opcode, opn, core_format, 0, + slotbuf, regno); } - xtensa_insnbuf_to_chars (isa, insnbuf, chbuf); + xtensa_format_encode (isa, core_format, insnbuf); + xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf); + xtensa_insnbuf_to_chars (isa, insnbuf, chbuf, content_length - address); /* Assemble a CALL ("callN 0") into the 3 byte offset. */ - xtensa_encode_insn (isa, direct_call_opcode, insnbuf); - operand = xtensa_get_operand (isa, opcode, 0); - xtensa_operand_set_field (operand, insnbuf, 0); - xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3); + xtensa_opcode_encode (isa, core_format, 0, slotbuf, direct_call_opcode); + xtensa_operand_set_field (isa, opcode, 0, core_format, 0, slotbuf, 0); + + xtensa_format_encode (isa, core_format, insnbuf); + xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf); + xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3, + content_length - address - 3); return bfd_reloc_ok; } static bfd_reloc_status_type -contract_asm_expansion (contents, content_length, irel) +contract_asm_expansion (contents, content_length, irel, error_message) bfd_byte *contents; bfd_vma content_length; Elf_Internal_Rela *irel; + char **error_message; { bfd_reloc_status_type retval = - elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length); + elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length, + error_message); if (retval != bfd_reloc_ok) - return retval; + return bfd_reloc_dangerous; /* Update the irel->r_offset field so that the right immediate and the right instruction are modified during the relocation. */ irel->r_offset += 3; - irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_XTENSA_OP0); + irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_XTENSA_SLOT0_OP); return bfd_reloc_ok; } @@ -3126,54 +4179,106 @@ swap_callx_for_call_opcode (opcode) } -/* Check if "buf" is pointing to a "L32R aN; CALLX aN" sequence, and - if so, return the CALLX opcode. If not, return XTENSA_UNDEFINED. */ +/* Check if "buf" is pointing to a "L32R aN; CALLX aN" or "CONST16 aN; + CONST16 aN; CALLX aN" sequence, and if so, return the CALLX opcode. + If not, return XTENSA_UNDEFINED. */ #define L32R_TARGET_REG_OPERAND 0 +#define CONST16_TARGET_REG_OPERAND 0 #define CALLN_SOURCE_OPERAND 0 static xtensa_opcode -get_expanded_call_opcode (buf, bufsize) +get_expanded_call_opcode (buf, bufsize, p_uses_l32r) bfd_byte *buf; int bufsize; + bfd_boolean *p_uses_l32r; { static xtensa_insnbuf insnbuf = NULL; + static xtensa_insnbuf slotbuf = NULL; + xtensa_format fmt; xtensa_opcode opcode; - xtensa_operand operand; xtensa_isa isa = xtensa_default_isa; - uint32 regno, call_regno; - - /* Buffer must be at least 6 bytes. */ - if (bufsize < 6) - return XTENSA_UNDEFINED; + uint32 regno, const16_regno, call_regno; + int offset = 0; if (insnbuf == NULL) - insnbuf = xtensa_insnbuf_alloc (isa); - - xtensa_insnbuf_from_chars (isa, insnbuf, buf); - opcode = xtensa_decode_insn (isa, insnbuf); - - if (opcode != get_l32r_opcode ()) + { + insnbuf = xtensa_insnbuf_alloc (isa); + slotbuf = xtensa_insnbuf_alloc (isa); + } + + xtensa_insnbuf_from_chars (isa, insnbuf, buf, bufsize); + fmt = xtensa_format_decode (isa, insnbuf); + if (fmt == XTENSA_UNDEFINED + || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf)) return XTENSA_UNDEFINED; - - operand = xtensa_get_operand (isa, opcode, L32R_TARGET_REG_OPERAND); - regno = xtensa_operand_decode - (operand, xtensa_operand_get_field (operand, insnbuf)); - + + opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf); + if (opcode == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + + if (opcode == get_l32r_opcode ()) + { + if (p_uses_l32r) + *p_uses_l32r = TRUE; + if (xtensa_operand_get_field (isa, opcode, L32R_TARGET_REG_OPERAND, + fmt, 0, slotbuf, ®no) + || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND, + ®no)) + return XTENSA_UNDEFINED; + } + else if (opcode == get_const16_opcode ()) + { + if (p_uses_l32r) + *p_uses_l32r = FALSE; + if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND, + fmt, 0, slotbuf, ®no) + || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND, + ®no)) + return XTENSA_UNDEFINED; + + /* Check that the next instruction is also CONST16. */ + offset += xtensa_format_length (isa, fmt); + xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset); + fmt = xtensa_format_decode (isa, insnbuf); + if (fmt == XTENSA_UNDEFINED + || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf)) + return XTENSA_UNDEFINED; + opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf); + if (opcode != get_const16_opcode ()) + return XTENSA_UNDEFINED; + + if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND, + fmt, 0, slotbuf, &const16_regno) + || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND, + &const16_regno) + || const16_regno != regno) + return XTENSA_UNDEFINED; + } + else + return XTENSA_UNDEFINED; + /* Next instruction should be an CALLXn with operand 0 == regno. */ - xtensa_insnbuf_from_chars (isa, insnbuf, - buf + xtensa_insn_length (isa, opcode)); - opcode = xtensa_decode_insn (isa, insnbuf); - - if (!is_indirect_call_opcode (opcode)) + offset += xtensa_format_length (isa, fmt); + xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset); + fmt = xtensa_format_decode (isa, insnbuf); + if (fmt == XTENSA_UNDEFINED + || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf)) return XTENSA_UNDEFINED; - - operand = xtensa_get_operand (isa, opcode, CALLN_SOURCE_OPERAND); - call_regno = xtensa_operand_decode - (operand, xtensa_operand_get_field (operand, insnbuf)); + opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf); + if (opcode == XTENSA_UNDEFINED + || !is_indirect_call_opcode (opcode)) + return XTENSA_UNDEFINED; + + if (xtensa_operand_get_field (isa, opcode, CALLN_SOURCE_OPERAND, + fmt, 0, slotbuf, &call_regno) + || xtensa_operand_decode (isa, opcode, CALLN_SOURCE_OPERAND, + &call_regno)) + return XTENSA_UNDEFINED; + if (call_regno != regno) return XTENSA_UNDEFINED; - + return opcode; } @@ -3191,7 +4296,11 @@ get_expanded_call_opcode (buf, bufsize) For efficiency, an r_reloc also contains a "target_offset" field to cache the target-section-relative offset value that is represented by - the relocation. */ + the relocation. + + The r_reloc also contains a virtual offset that allows multiple + inserted literals to be placed at the same "address" with + different offsets. */ typedef struct r_reloc_struct r_reloc; @@ -3200,12 +4309,13 @@ struct r_reloc_struct bfd *abfd; Elf_Internal_Rela rela; bfd_vma target_offset; + bfd_vma virtual_offset; }; static bfd_boolean r_reloc_is_const PARAMS ((const r_reloc *)); static void r_reloc_init - PARAMS ((r_reloc *, bfd *, Elf_Internal_Rela *)); + PARAMS ((r_reloc *, bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_size_type)); static bfd_vma r_reloc_get_target_offset PARAMS ((const r_reloc *)); static asection *r_reloc_get_section @@ -3214,6 +4324,10 @@ static bfd_boolean r_reloc_is_defined PARAMS ((const r_reloc *)); static struct elf_link_hash_entry *r_reloc_get_hash_entry PARAMS ((const r_reloc *)); +#if DEBUG +static void print_r_reloc + PARAMS ((FILE *fp, const r_reloc *r)); +#endif /* DEBUG */ /* The r_reloc structure is included by value in literal_value, but not @@ -3231,16 +4345,32 @@ r_reloc_is_const (r_rel) static void -r_reloc_init (r_rel, abfd, irel) +r_reloc_init (r_rel, abfd, irel, contents, content_length) r_reloc *r_rel; bfd *abfd; Elf_Internal_Rela *irel; + bfd_byte *contents; + bfd_size_type content_length; { + int r_type; + reloc_howto_type *howto; + if (irel != NULL) { r_rel->rela = *irel; r_rel->abfd = abfd; r_rel->target_offset = r_reloc_get_target_offset (r_rel); + r_rel->virtual_offset = 0; + r_type = ELF32_R_TYPE (r_rel->rela.r_info); + howto = &elf_howto_table[r_type]; + if (howto->partial_inplace) + { + bfd_vma inplace_val; + BFD_ASSERT (r_rel->rela.r_offset < content_length); + + inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]); + r_rel->target_offset += inplace_val; + } } else memset (r_rel, 0, sizeof (r_reloc)); @@ -3283,7 +4413,11 @@ static bfd_boolean r_reloc_is_defined (r_rel) const r_reloc *r_rel; { - asection *sec = r_reloc_get_section (r_rel); + asection *sec; + if (r_rel == NULL) + return FALSE; + + sec = r_reloc_get_section (r_rel); if (sec == bfd_abs_section_ptr || sec == bfd_com_section_ptr || sec == bfd_und_section_ptr) @@ -3291,8 +4425,38 @@ r_reloc_is_defined (r_rel) return TRUE; } + +#if DEBUG + +static void +print_r_reloc (fp, r_rel) + FILE *fp; + const r_reloc *r_rel; +{ + if (r_reloc_is_defined (r_rel)) + { + asection *sec = r_reloc_get_section (r_rel); + fprintf (fp, " %s(%s + ", sec->owner->filename, sec->name); + } + else if (r_reloc_get_hash_entry (r_rel)) + fprintf (fp, " %s + ", r_reloc_get_hash_entry (r_rel)->root.root.string); + else + fprintf (fp, " ?? + "); + + fprintf_vma (fp, r_rel->target_offset); + if (r_rel->virtual_offset) + { + fprintf (fp, " + "); + fprintf_vma (fp, r_rel->virtual_offset); + } + + fprintf (fp, ")"); +} + +#endif /* DEBUG */ + -/* source_reloc: relocations that reference literal sections. */ +/* source_reloc: relocations that reference literals. */ /* To determine whether literals can be coalesced, we need to first record all the relocations that reference the literals. The @@ -3315,13 +4479,16 @@ struct source_reloc_struct { asection *source_sec; r_reloc r_rel; - xtensa_operand opnd; + xtensa_opcode opcode; + int opnd; bfd_boolean is_null; + bfd_boolean is_abs_literal; }; static void init_source_reloc - PARAMS ((source_reloc *, asection *, const r_reloc *, xtensa_operand)); + PARAMS ((source_reloc *, asection *, const r_reloc *, + xtensa_opcode, int, bfd_boolean)); static source_reloc *find_source_reloc PARAMS ((source_reloc *, int, asection *, Elf_Internal_Rela *)); static int source_reloc_compare @@ -3329,16 +4496,20 @@ static int source_reloc_compare static void -init_source_reloc (reloc, source_sec, r_rel, opnd) +init_source_reloc (reloc, source_sec, r_rel, opcode, opnd, is_abs_literal) source_reloc *reloc; asection *source_sec; const r_reloc *r_rel; - xtensa_operand opnd; + xtensa_opcode opcode; + int opnd; + bfd_boolean is_abs_literal; { reloc->source_sec = source_sec; reloc->r_rel = *r_rel; + reloc->opcode = opcode; reloc->opnd = opnd; reloc->is_null = FALSE; + reloc->is_abs_literal = is_abs_literal; } @@ -3376,7 +4547,19 @@ source_reloc_compare (ap, bp) const source_reloc *a = (const source_reloc *) ap; const source_reloc *b = (const source_reloc *) bp; - return (a->r_rel.target_offset - b->r_rel.target_offset); + if (a->r_rel.target_offset != b->r_rel.target_offset) + return (a->r_rel.target_offset - b->r_rel.target_offset); + + /* We don't need to sort on these criteria for correctness, + but enforcing a more strict ordering prevents unstable qsort + from behaving differently with different implementations. + Without the code below we get correct but different results + on Solaris 2.7 and 2.8. We would like to always produce the + same results no matter the host. */ + + if ((!a->is_null) - (!b->is_null)) + return ((!a->is_null) - (!b->is_null)); + return internal_reloc_compare (&a->r_rel.rela, &b->r_rel.rela); } @@ -3401,6 +4584,7 @@ struct literal_value_struct { r_reloc r_rel; unsigned long value; + bfd_boolean is_abs_literal; }; struct value_map_struct @@ -3415,26 +4599,45 @@ struct value_map_hash_table_struct unsigned bucket_count; value_map **buckets; unsigned count; + bfd_boolean has_last_loc; + r_reloc last_loc; }; -static bfd_boolean is_same_value +static void init_literal_value + PARAMS ((literal_value *, const r_reloc *, unsigned long, bfd_boolean)); +static bfd_boolean literal_value_equal PARAMS ((const literal_value *, const literal_value *, bfd_boolean)); static value_map_hash_table *value_map_hash_table_init PARAMS ((void)); -static unsigned hash_literal_value +static void value_map_hash_table_delete + PARAMS ((value_map_hash_table *)); +static unsigned literal_value_hash PARAMS ((const literal_value *)); static unsigned hash_bfd_vma PARAMS ((bfd_vma)); -static value_map *get_cached_value +static value_map *value_map_get_cached_value PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean)); static value_map *add_value_map PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *, bfd_boolean)); +static void +init_literal_value (lit, r_rel, value, is_abs_literal) + literal_value *lit; + const r_reloc *r_rel; + unsigned long value; + bfd_boolean is_abs_literal; +{ + lit->r_rel = *r_rel; + lit->value = value; + lit->is_abs_literal = is_abs_literal; +} + + static bfd_boolean -is_same_value (src1, src2, final_static_link) +literal_value_equal (src1, src2, final_static_link) const literal_value *src1; const literal_value *src2; bfd_boolean final_static_link; @@ -3451,8 +4654,10 @@ is_same_value (src1, src2, final_static_link) != ELF32_R_TYPE (src2->r_rel.rela.r_info)) return FALSE; - if (r_reloc_get_target_offset (&src1->r_rel) - != r_reloc_get_target_offset (&src2->r_rel)) + if (src1->r_rel.target_offset != src2->r_rel.target_offset) + return FALSE; + + if (src1->r_rel.virtual_offset != src2->r_rel.virtual_offset) return FALSE; if (src1->value != src2->value) @@ -3478,6 +4683,9 @@ is_same_value (src1, src2, final_static_link) return FALSE; } + if (src1->is_abs_literal != src2->is_abs_literal) + return FALSE; + return TRUE; } @@ -3491,17 +4699,31 @@ value_map_hash_table_init () value_map_hash_table *values; values = (value_map_hash_table *) - bfd_malloc (sizeof (value_map_hash_table)); - + bfd_zmalloc (sizeof (value_map_hash_table)); values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT; values->count = 0; values->buckets = (value_map **) bfd_zmalloc (sizeof (value_map *) * values->bucket_count); + if (values->buckets == NULL) + { + free (values); + return NULL; + } + values->has_last_loc = FALSE; return values; } +static void +value_map_hash_table_delete (table) + value_map_hash_table *table; +{ + free (table->buckets); + free (table); +} + + static unsigned hash_bfd_vma (val) bfd_vma val; @@ -3511,23 +4733,27 @@ hash_bfd_vma (val) static unsigned -hash_literal_value (src) +literal_value_hash (src) const literal_value *src; { unsigned hash_val; - if (r_reloc_is_const (&src->r_rel)) - return hash_bfd_vma (src->value); + hash_val = hash_bfd_vma (src->value); + if (!r_reloc_is_const (&src->r_rel)) + { + void *sec_or_hash; - hash_val = (hash_bfd_vma (r_reloc_get_target_offset (&src->r_rel)) - + hash_bfd_vma (src->value)); + hash_val += hash_bfd_vma (src->is_abs_literal * 1000); + hash_val += hash_bfd_vma (src->r_rel.target_offset); + hash_val += hash_bfd_vma (src->r_rel.virtual_offset); - /* Now check for the same section and the same elf_hash. */ - if (r_reloc_is_defined (&src->r_rel)) - hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_section (&src->r_rel)); - else - hash_val += hash_bfd_vma ((bfd_vma) (unsigned) r_reloc_get_hash_entry (&src->r_rel)); - + /* Now check for the same section and the same elf_hash. */ + if (r_reloc_is_defined (&src->r_rel)) + sec_or_hash = r_reloc_get_section (&src->r_rel); + else + sec_or_hash = r_reloc_get_hash_entry (&src->r_rel); + hash_val += hash_bfd_vma ((bfd_vma) (unsigned) sec_or_hash); + } return hash_val; } @@ -3535,7 +4761,7 @@ hash_literal_value (src) /* Check if the specified literal_value has been seen before. */ static value_map * -get_cached_value (map, val, final_static_link) +value_map_get_cached_value (map, val, final_static_link) value_map_hash_table *map; const literal_value *val; bfd_boolean final_static_link; @@ -3544,12 +4770,12 @@ get_cached_value (map, val, final_static_link) value_map *bucket; unsigned idx; - idx = hash_literal_value (val); + idx = literal_value_hash (val); idx = idx & (map->bucket_count - 1); bucket = map->buckets[idx]; for (map_e = bucket; map_e; map_e = map_e->next) { - if (is_same_value (&map_e->val, val, final_static_link)) + if (literal_value_equal (&map_e->val, val, final_static_link)) return map_e; } return NULL; @@ -3570,24 +4796,388 @@ add_value_map (map, val, loc, final_static_link) unsigned idx; value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map)); + if (val_e == NULL) + { + bfd_set_error (bfd_error_no_memory); + return NULL; + } - BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL); + BFD_ASSERT (!value_map_get_cached_value (map, val, final_static_link)); val_e->val = *val; val_e->loc = *loc; - idx = hash_literal_value (val); + idx = literal_value_hash (val); idx = idx & (map->bucket_count - 1); bucket_p = &map->buckets[idx]; val_e->next = *bucket_p; *bucket_p = val_e; map->count++; - /* FIXME: consider resizing the hash table if we get too many entries */ + /* FIXME: Consider resizing the hash table if we get too many entries. */ return val_e; } +/* Lists of text actions (ta_) for narrowing, widening, longcall + conversion, space fill, code & literal removal, etc. */ + +/* The following text actions are generated: + + "ta_remove_insn" remove an instruction or instructions + "ta_remove_longcall" convert longcall to call + "ta_convert_longcall" convert longcall to nop/call + "ta_narrow_insn" narrow a wide instruction + "ta_widen" widen a narrow instruction + "ta_fill" add fill or remove fill + removed < 0 is a fill; branches to the fill address will be + changed to address + fill size (e.g., address - removed) + removed >= 0 branches to the fill address will stay unchanged + "ta_remove_literal" remove a literal; this action is + indicated when a literal is removed + or replaced. + "ta_add_literal" insert a new literal; this action is + indicated when a literal has been moved. + It may use a virtual_offset because + multiple literals can be placed at the + same location. + + For each of these text actions, we also record the number of bytes + removed by performing the text action. In the case of a "ta_widen" + or a "ta_fill" that adds space, the removed_bytes will be negative. */ + +typedef struct text_action_struct text_action; +typedef struct text_action_list_struct text_action_list; +typedef enum text_action_enum_t text_action_t; + +enum text_action_enum_t +{ + ta_none, + ta_remove_insn, /* removed = -size */ + ta_remove_longcall, /* removed = -size */ + ta_convert_longcall, /* removed = 0 */ + ta_narrow_insn, /* removed = -1 */ + ta_widen_insn, /* removed = +1 */ + ta_fill, /* removed = +size */ + ta_remove_literal, + ta_add_literal +}; + + +/* Structure for a text action record. */ +struct text_action_struct +{ + text_action_t action; + asection *sec; /* Optional */ + bfd_vma offset; + bfd_vma virtual_offset; /* Zero except for adding literals. */ + int removed_bytes; + literal_value value; /* Only valid when adding literals. */ + + text_action *next; +}; + + +/* List of all of the actions taken on a text section. */ +struct text_action_list_struct +{ + text_action *head; +}; + + +static text_action *find_fill_action + PARAMS ((text_action_list *, asection *, bfd_vma)); +static int compute_removed_action_diff + PARAMS ((const text_action *, asection *, bfd_vma, int, int)); +static void adjust_fill_action + PARAMS ((text_action *, int)); +static void text_action_add + PARAMS ((text_action_list *, text_action_t, asection *, bfd_vma, int)); +static void text_action_add_literal + PARAMS ((text_action_list *, text_action_t, const r_reloc *, + const literal_value *, int)); +static bfd_vma offset_with_removed_text + PARAMS ((text_action_list *, bfd_vma)); +static bfd_vma offset_with_removed_text_before_fill + PARAMS ((text_action_list *, bfd_vma)); +static text_action *find_insn_action + PARAMS ((text_action_list *, bfd_vma)); +#if DEBUG +static void print_action_list + PARAMS ((FILE *, text_action_list *)); +#endif + + +text_action * +find_fill_action (l, sec, offset) + text_action_list *l; + asection *sec; + bfd_vma offset; +{ + text_action **m_p; + + /* It is not necessary to fill at the end of a section. */ + if (sec->size == offset) + return NULL; + + for (m_p = &l->head; + *m_p != NULL && (*m_p)->offset <= offset; + m_p = &(*m_p)->next) + { + text_action *t = *m_p; + /* When the action is another fill at the same address, + just increase the size. */ + if (t->offset == offset && t->action == ta_fill) + return t; + } + return NULL; +} + + +static int +compute_removed_action_diff (ta, sec, offset, removed, removable_space) + const text_action *ta; + asection *sec; + bfd_vma offset; + int removed; + int removable_space; +{ + int new_removed; + int current_removed = 0; + + if (ta != NULL) + current_removed = ta->removed_bytes; + + BFD_ASSERT (ta == NULL || ta->offset == offset); + BFD_ASSERT (ta == NULL || ta->action == ta_fill); + + /* It is not necessary to fill at the end of a section. Clean this up. */ + if (sec->size == offset) + new_removed = removable_space - 0; + else + { + int space; + int added = -removed - current_removed; + /* Ignore multiples of the section alignment. */ + added = ((1 << sec->alignment_power) - 1) & added; + new_removed = (-added); + + /* Modify for removable. */ + space = removable_space - new_removed; + new_removed = (removable_space + - (((1 << sec->alignment_power) - 1) & space)); + } + return (new_removed - current_removed); +} + + +void +adjust_fill_action (ta, fill_diff) + text_action *ta; + int fill_diff; +{ + ta->removed_bytes += fill_diff; +} + + +/* Add a modification action to the text. For the case of adding or + removing space, modify any current fill and assume that + "unreachable_space" bytes can be freely contracted. Note that a + negative removed value is a fill. */ + +static void +text_action_add (l, action, sec, offset, removed) + text_action_list *l; + text_action_t action; + asection *sec; + bfd_vma offset; + int removed; +{ + text_action **m_p; + text_action *ta; + + /* It is not necessary to fill at the end of a section. */ + if (action == ta_fill && sec->size == offset) + return; + + /* It is not necessary to fill 0 bytes. */ + if (action == ta_fill && removed == 0) + return; + + for (m_p = &l->head; + *m_p != NULL && (*m_p)->offset <= offset; + m_p = &(*m_p)->next) + { + text_action *t = *m_p; + /* When the action is another fill at the same address, + just increase the size. */ + if (t->offset == offset && t->action == ta_fill && action == ta_fill) + { + t->removed_bytes += removed; + return; + } + } + + /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; + ta->sec = sec; + ta->offset = offset; + ta->removed_bytes = removed; + ta->next = (*m_p); + *m_p = ta; +} + + +static void +text_action_add_literal (l, action, loc, value, removed) + text_action_list *l; + text_action_t action; + const r_reloc *loc; + const literal_value *value; + int removed; +{ + text_action **m_p; + text_action *ta; + asection *sec = r_reloc_get_section (loc); + bfd_vma offset = loc->target_offset; + bfd_vma virtual_offset = loc->virtual_offset; + + BFD_ASSERT (action == ta_add_literal); + + for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next) + { + if ((*m_p)->offset > offset + && ((*m_p)->offset != offset + || (*m_p)->virtual_offset > virtual_offset)) + break; + } + + /* Create a new record and fill it up. */ + ta = (text_action *) bfd_zmalloc (sizeof (text_action)); + ta->action = action; + ta->sec = sec; + ta->offset = offset; + ta->virtual_offset = virtual_offset; + ta->value = *value; + ta->removed_bytes = removed; + ta->next = (*m_p); + *m_p = ta; +} + + +bfd_vma +offset_with_removed_text (action_list, offset) + text_action_list *action_list; + bfd_vma offset; +{ + text_action *r; + int removed = 0; + + for (r = action_list->head; r && r->offset <= offset; r = r->next) + { + if (r->offset < offset + || (r->action == ta_fill && r->removed_bytes < 0)) + removed += r->removed_bytes; + } + + return (offset - removed); +} + + +bfd_vma +offset_with_removed_text_before_fill (action_list, offset) + text_action_list *action_list; + bfd_vma offset; +{ + text_action *r; + int removed = 0; + + for (r = action_list->head; r && r->offset < offset; r = r->next) + removed += r->removed_bytes; + + return (offset - removed); +} + + +/* The find_insn_action routine will only find non-fill actions. */ + +text_action * +find_insn_action (action_list, offset) + text_action_list *action_list; + bfd_vma offset; +{ + text_action *t; + for (t = action_list->head; t; t = t->next) + { + if (t->offset == offset) + { + switch (t->action) + { + case ta_none: + case ta_fill: + break; + case ta_remove_insn: + case ta_remove_longcall: + case ta_convert_longcall: + case ta_narrow_insn: + case ta_widen_insn: + return t; + case ta_remove_literal: + case ta_add_literal: + BFD_ASSERT (0); + break; + } + } + } + return NULL; +} + + +#if DEBUG + +static void +print_action_list (fp, action_list) + FILE *fp; + text_action_list *action_list; +{ + text_action *r; + + fprintf (fp, "Text Action\n"); + for (r = action_list->head; r != NULL; r = r->next) + { + const char *t = "unknown"; + switch (r->action) + { + case ta_remove_insn: + t = "remove_insn"; break; + case ta_remove_longcall: + t = "remove_longcall"; break; + case ta_convert_longcall: + t = "remove_longcall"; break; + case ta_narrow_insn: + t = "narrow_insn"; break; + case ta_widen_insn: + t = "widen_insn"; break; + case ta_fill: + t = "fill"; break; + case ta_none: + t = "none"; break; + case ta_remove_literal: + t = "remove_literal"; break; + case ta_add_literal: + t = "add_literal"; break; + } + + fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n", + r->sec->owner->filename, + r->sec->name, r->offset, t, r->removed_bytes); + } +} + +#endif /* DEBUG */ + + /* Lists of literals being coalesced or removed. */ /* In the usual case, the literal identified by "from" is being @@ -3617,8 +5207,10 @@ static void add_removed_literal PARAMS ((removed_literal_list *, const r_reloc *, const r_reloc *)); static removed_literal *find_removed_literal PARAMS ((removed_literal_list *, bfd_vma)); -static bfd_vma offset_with_removed_literals - PARAMS ((removed_literal_list *, bfd_vma)); +#if DEBUG +static void print_removed_literals + PARAMS ((FILE *, removed_literal_list *)); +#endif /* DEBUG */ /* Record that the literal at "from" is being removed. If "to" is not @@ -3686,29 +5278,133 @@ find_removed_literal (removed_list, addr) } -/* Adjust an offset in a section to compensate for literals that are - being removed. Search the list of removed literals and subtract - 4 bytes for every removed literal prior to the given address. */ +#if DEBUG -static bfd_vma -offset_with_removed_literals (removed_list, addr) +static void +print_removed_literals (fp, removed_list) + FILE *fp; removed_literal_list *removed_list; - bfd_vma addr; { - removed_literal *r = removed_list->head; - unsigned num_bytes = 0; - - if (r == NULL) - return addr; - - while (r && r->from.target_offset <= addr) + removed_literal *r; + r = removed_list->head; + if (r) + fprintf (fp, "Removed Literals\n"); + for (; r != NULL; r = r->next) { - num_bytes += 4; - r = r->next; + print_r_reloc (fp, &r->from); + fprintf (fp, " => "); + if (r->to.abfd == NULL) + fprintf (fp, "REMOVED"); + else + print_r_reloc (fp, &r->to); + fprintf (fp, "\n"); } - if (num_bytes > addr) - return 0; - return (addr - num_bytes); +} + +#endif /* DEBUG */ + + +/* Per-section data for relaxation. */ + +typedef struct reloc_bfd_fix_struct reloc_bfd_fix; + +struct xtensa_relax_info_struct +{ + bfd_boolean is_relaxable_literal_section; + bfd_boolean is_relaxable_asm_section; + int visited; /* Number of times visited. */ + + source_reloc *src_relocs; /* Array[src_count]. */ + int src_count; + int src_next; /* Next src_relocs entry to assign. */ + + removed_literal_list removed_list; + text_action_list action_list; + + reloc_bfd_fix *fix_list; + reloc_bfd_fix *fix_array; + unsigned fix_array_count; + + /* Support for expanding the reloc array that is stored + in the section structure. If the relocations have been + reallocated, the newly allocated relocations will be referenced + here along with the actual size allocated. The relocation + count will always be found in the section structure. */ + Elf_Internal_Rela *allocated_relocs; + unsigned relocs_count; + unsigned allocated_relocs_count; +}; + +struct elf_xtensa_section_data +{ + struct bfd_elf_section_data elf; + xtensa_relax_info relax_info; +}; + +static void init_xtensa_relax_info + PARAMS ((asection *)); +static xtensa_relax_info *get_xtensa_relax_info + PARAMS ((asection *)); + + +static bfd_boolean +elf_xtensa_new_section_hook (abfd, sec) + bfd *abfd; + asection *sec; +{ + struct elf_xtensa_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); + + sdata = (struct elf_xtensa_section_data *) bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = (PTR) sdata; + + return _bfd_elf_new_section_hook (abfd, sec); +} + + +static void +init_xtensa_relax_info (sec) + asection *sec; +{ + xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); + + relax_info->is_relaxable_literal_section = FALSE; + relax_info->is_relaxable_asm_section = FALSE; + relax_info->visited = 0; + + relax_info->src_relocs = NULL; + relax_info->src_count = 0; + relax_info->src_next = 0; + + relax_info->removed_list.head = NULL; + relax_info->removed_list.tail = NULL; + + relax_info->action_list.head = NULL; + + relax_info->fix_list = NULL; + relax_info->fix_array = NULL; + relax_info->fix_array_count = 0; + + relax_info->allocated_relocs = NULL; + relax_info->relocs_count = 0; + relax_info->allocated_relocs_count = 0; +} + + +static xtensa_relax_info * +get_xtensa_relax_info (sec) + asection *sec; +{ + struct elf_xtensa_section_data *section_data; + + /* No info available if no section or if it is an output section. */ + if (!sec || sec == sec->output_section) + return NULL; + + section_data = (struct elf_xtensa_section_data *) elf_section_data (sec); + return §ion_data->relax_info; } @@ -3721,8 +5417,6 @@ offset_with_removed_literals (removed_list, addr) the same location. FIXME: This is ugly; an alternative might be to add new symbols with the "owner" field to some other input file. */ -typedef struct reloc_bfd_fix_struct reloc_bfd_fix; - struct reloc_bfd_fix_struct { asection *src_sec; @@ -3732,26 +5426,35 @@ struct reloc_bfd_fix_struct bfd *target_abfd; asection *target_sec; bfd_vma target_offset; + bfd_boolean translated; reloc_bfd_fix *next; }; static reloc_bfd_fix *reloc_bfd_fix_init - PARAMS ((asection *, bfd_vma, unsigned, bfd *, asection *, bfd_vma)); + PARAMS ((asection *, bfd_vma, unsigned, bfd *, asection *, bfd_vma, + bfd_boolean)); +static void add_fix + PARAMS ((asection *, reloc_bfd_fix *)); +static int fix_compare + PARAMS ((const PTR, const PTR)); +static void cache_fix_array + PARAMS ((asection *)); static reloc_bfd_fix *get_bfd_fix - PARAMS ((reloc_bfd_fix *, asection *, bfd_vma, unsigned)); + PARAMS ((asection *, bfd_vma, unsigned)); static reloc_bfd_fix * reloc_bfd_fix_init (src_sec, src_offset, src_type, - target_abfd, target_sec, target_offset) + target_abfd, target_sec, target_offset, translated) asection *src_sec; bfd_vma src_offset; unsigned src_type; bfd *target_abfd; asection *target_sec; bfd_vma target_offset; + bfd_boolean translated; { reloc_bfd_fix *fix; @@ -3762,123 +5465,595 @@ reloc_bfd_fix_init (src_sec, src_offset, src_type, fix->target_abfd = target_abfd; fix->target_sec = target_sec; fix->target_offset = target_offset; + fix->translated = translated; return fix; } +static void +add_fix (src_sec, fix) + asection *src_sec; + reloc_bfd_fix *fix; +{ + xtensa_relax_info *relax_info; + + relax_info = get_xtensa_relax_info (src_sec); + fix->next = relax_info->fix_list; + relax_info->fix_list = fix; +} + + +static int +fix_compare (ap, bp) + const PTR ap; + const PTR bp; +{ + const reloc_bfd_fix *a = (const reloc_bfd_fix *) ap; + const reloc_bfd_fix *b = (const reloc_bfd_fix *) bp; + + if (a->src_offset != b->src_offset) + return (a->src_offset - b->src_offset); + return (a->src_type - b->src_type); +} + + +static void +cache_fix_array (sec) + asection *sec; +{ + unsigned i, count = 0; + reloc_bfd_fix *r; + xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); + + if (relax_info == NULL) + return; + if (relax_info->fix_list == NULL) + return; + + for (r = relax_info->fix_list; r != NULL; r = r->next) + count++; + + relax_info->fix_array = + (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix) * count); + relax_info->fix_array_count = count; + + r = relax_info->fix_list; + for (i = 0; i < count; i++, r = r->next) + { + relax_info->fix_array[count - 1 - i] = *r; + relax_info->fix_array[count - 1 - i].next = NULL; + } + + qsort (relax_info->fix_array, relax_info->fix_array_count, + sizeof (reloc_bfd_fix), fix_compare); +} + + static reloc_bfd_fix * -get_bfd_fix (fix_list, sec, offset, type) - reloc_bfd_fix *fix_list; +get_bfd_fix (sec, offset, type) asection *sec; bfd_vma offset; unsigned type; { - reloc_bfd_fix *r; + xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); + reloc_bfd_fix *rv; + reloc_bfd_fix key; + + if (relax_info == NULL) + return NULL; + if (relax_info->fix_list == NULL) + return NULL; + + if (relax_info->fix_array == NULL) + cache_fix_array (sec); + + key.src_offset = offset; + key.src_type = type; + rv = bsearch (&key, relax_info->fix_array, relax_info->fix_array_count, + sizeof (reloc_bfd_fix), fix_compare); + return rv; +} + + +/* Section caching. */ + +typedef struct section_cache_struct section_cache_t; + +struct section_cache_struct +{ + asection *sec; + + bfd_byte *contents; /* Cache of the section contents. */ + bfd_size_type content_length; + + property_table_entry *ptbl; /* Cache of the section property table. */ + unsigned pte_count; - for (r = fix_list; r != NULL; r = r->next) + Elf_Internal_Rela *relocs; /* Cache of the section relocations. */ + unsigned reloc_count; +}; + + +static void init_section_cache + PARAMS ((section_cache_t *)); +static bfd_boolean section_cache_section + PARAMS ((section_cache_t *, asection *, struct bfd_link_info *)); +static void clear_section_cache + PARAMS ((section_cache_t *)); + + +static void +init_section_cache (sec_cache) + section_cache_t *sec_cache; +{ + memset (sec_cache, 0, sizeof (*sec_cache)); +} + + +static bfd_boolean +section_cache_section (sec_cache, sec, link_info) + section_cache_t *sec_cache; + asection *sec; + struct bfd_link_info *link_info; +{ + bfd *abfd; + property_table_entry *prop_table = NULL; + int ptblsize = 0; + bfd_byte *contents = NULL; + Elf_Internal_Rela *internal_relocs = NULL; + bfd_size_type sec_size; + + if (sec == NULL) + return FALSE; + if (sec == sec_cache->sec) + return TRUE; + + abfd = sec->owner; + sec_size = bfd_get_section_limit (abfd, sec); + + /* Get the contents. */ + contents = retrieve_contents (abfd, sec, link_info->keep_memory); + if (contents == NULL && sec_size != 0) + goto err; + + /* Get the relocations. */ + internal_relocs = retrieve_internal_relocs (abfd, sec, + link_info->keep_memory); + + /* Get the entry table. */ + ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table, + XTENSA_PROP_SEC_NAME, FALSE); + if (ptblsize < 0) + goto err; + + /* Fill in the new section cache. */ + clear_section_cache (sec_cache); + memset (sec_cache, 0, sizeof (sec_cache)); + + sec_cache->sec = sec; + sec_cache->contents = contents; + sec_cache->content_length = sec_size; + sec_cache->relocs = internal_relocs; + sec_cache->reloc_count = sec->reloc_count; + sec_cache->pte_count = ptblsize; + sec_cache->ptbl = prop_table; + + return TRUE; + + err: + release_contents (sec, contents); + release_internal_relocs (sec, internal_relocs); + if (prop_table) + free (prop_table); + return FALSE; +} + + +static void +clear_section_cache (sec_cache) + section_cache_t *sec_cache; +{ + if (sec_cache->sec) { - if (r->src_sec == sec - && r->src_offset == offset - && r->src_type == type) - return r; + release_contents (sec_cache->sec, sec_cache->contents); + release_internal_relocs (sec_cache->sec, sec_cache->relocs); + if (sec_cache->ptbl) + free (sec_cache->ptbl); + memset (sec_cache, 0, sizeof (sec_cache)); } - return NULL; } -/* Per-section data for relaxation. */ +/* Extended basic blocks. */ -struct xtensa_relax_info_struct +/* An ebb_struct represents an Extended Basic Block. Within this + range, we guarantee that all instructions are decodable, the + property table entries are contiguous, and no property table + specifies a segment that cannot have instructions moved. This + structure contains caches of the contents, property table and + relocations for the specified section for easy use. The range is + specified by ranges of indices for the byte offset, property table + offsets and relocation offsets. These must be consistent. */ + +typedef struct ebb_struct ebb_t; + +struct ebb_struct { - bfd_boolean is_relaxable_literal_section; - int visited; /* Number of times visited. */ + asection *sec; - source_reloc *src_relocs; /* Array[src_count]. */ - int src_count; - int src_next; /* Next src_relocs entry to assign. */ + bfd_byte *contents; /* Cache of the section contents. */ + bfd_size_type content_length; - removed_literal_list removed_list; + property_table_entry *ptbl; /* Cache of the section property table. */ + unsigned pte_count; - reloc_bfd_fix *fix_list; + Elf_Internal_Rela *relocs; /* Cache of the section relocations. */ + unsigned reloc_count; + + bfd_vma start_offset; /* Offset in section. */ + unsigned start_ptbl_idx; /* Offset in the property table. */ + unsigned start_reloc_idx; /* Offset in the relocations. */ + + bfd_vma end_offset; + unsigned end_ptbl_idx; + unsigned end_reloc_idx; + + bfd_boolean ends_section; /* Is this the last ebb in a section? */ + + /* The unreachable property table at the end of this set of blocks; + NULL if the end is not an unreachable block. */ + property_table_entry *ends_unreachable; }; -struct elf_xtensa_section_data + +enum ebb_target_enum { - struct bfd_elf_section_data elf; - xtensa_relax_info relax_info; + EBB_NO_ALIGN = 0, + EBB_DESIRE_TGT_ALIGN, + EBB_REQUIRE_TGT_ALIGN, + EBB_REQUIRE_LOOP_ALIGN, + EBB_REQUIRE_ALIGN }; -static void init_xtensa_relax_info - PARAMS ((asection *)); -static xtensa_relax_info *get_xtensa_relax_info - PARAMS ((asection *)); -static void add_fix - PARAMS ((asection *, reloc_bfd_fix *)); +/* proposed_action_struct is similar to the text_action_struct except + that is represents a potential transformation, not one that will + occur. We build a list of these for an extended basic block + and use them to compute the actual actions desired. We must be + careful that the entire set of actual actions we perform do not + break any relocations that would fit if the actions were not + performed. */ -static bfd_boolean -elf_xtensa_new_section_hook (abfd, sec) - bfd *abfd; - asection *sec; +typedef struct proposed_action_struct proposed_action; + +struct proposed_action_struct { - struct elf_xtensa_section_data *sdata; - bfd_size_type amt = sizeof (*sdata); + enum ebb_target_enum align_type; /* for the target alignment */ + bfd_vma alignment_pow; + text_action_t action; + bfd_vma offset; + int removed_bytes; + bfd_boolean do_action; /* If false, then we will not perform the action. */ +}; - sdata = (struct elf_xtensa_section_data *) bfd_zalloc (abfd, amt); - if (sdata == NULL) - return FALSE; - sec->used_by_bfd = (PTR) sdata; - return _bfd_elf_new_section_hook (abfd, sec); +/* The ebb_constraint_struct keeps a set of proposed actions for an + extended basic block. */ + +typedef struct ebb_constraint_struct ebb_constraint; + +struct ebb_constraint_struct +{ + ebb_t ebb; + bfd_boolean start_movable; + + /* Bytes of extra space at the beginning if movable. */ + int start_extra_space; + + enum ebb_target_enum start_align; + + bfd_boolean end_movable; + + /* Bytes of extra space at the end if movable. */ + int end_extra_space; + + unsigned action_count; + unsigned action_allocated; + + /* Array of proposed actions. */ + proposed_action *actions; + + /* Action alignments -- one for each proposed action. */ + enum ebb_target_enum *action_aligns; +}; + + +static void init_ebb_constraint + PARAMS ((ebb_constraint *)); +static void free_ebb_constraint + PARAMS ((ebb_constraint *)); +static void init_ebb + PARAMS ((ebb_t *, asection *, bfd_byte *, bfd_size_type, + property_table_entry *, unsigned, Elf_Internal_Rela *, unsigned)); +static bfd_boolean extend_ebb_bounds + PARAMS ((ebb_t *)); +static bfd_boolean extend_ebb_bounds_forward + PARAMS ((ebb_t *)); +static bfd_boolean extend_ebb_bounds_backward + PARAMS ((ebb_t *)); +static bfd_size_type insn_block_decodable_len + PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type)); +static void ebb_propose_action + PARAMS ((ebb_constraint *, enum ebb_target_enum, bfd_vma, text_action_t, + bfd_vma, int, bfd_boolean)); +static void ebb_add_proposed_action + PARAMS ((ebb_constraint *, proposed_action *)); + + +static void +init_ebb_constraint (c) + ebb_constraint *c; +{ + memset (c, 0, sizeof (ebb_constraint)); } static void -init_xtensa_relax_info (sec) +free_ebb_constraint (c) + ebb_constraint *c; +{ + if (c->actions != NULL) + free (c->actions); +} + + +static void +init_ebb (ebb, sec, contents, content_length, prop_table, ptblsize, + internal_relocs, reloc_count) + ebb_t *ebb; asection *sec; + bfd_byte *contents; + bfd_size_type content_length; + property_table_entry *prop_table; + unsigned ptblsize; + Elf_Internal_Rela *internal_relocs; + unsigned reloc_count; { - xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); + memset (ebb, 0, sizeof (ebb_t)); + ebb->sec = sec; + ebb->contents = contents; + ebb->content_length = content_length; + ebb->ptbl = prop_table; + ebb->pte_count = ptblsize; + ebb->relocs = internal_relocs; + ebb->reloc_count = reloc_count; + ebb->start_offset = 0; + ebb->end_offset = ebb->content_length - 1; + ebb->start_ptbl_idx = 0; + ebb->end_ptbl_idx = ptblsize; + ebb->start_reloc_idx = 0; + ebb->end_reloc_idx = reloc_count; +} - relax_info->is_relaxable_literal_section = FALSE; - relax_info->visited = 0; - relax_info->src_relocs = NULL; - relax_info->src_count = 0; - relax_info->src_next = 0; +/* Extend the ebb to all decodable contiguous sections. The algorithm + for building a basic block around an instruction is to push it + forward until we hit the end of a section, an unreachable block or + a block that cannot be transformed. Then we push it backwards + searching for similar conditions. */ - relax_info->removed_list.head = NULL; - relax_info->removed_list.tail = NULL; +static bfd_boolean +extend_ebb_bounds (ebb) + ebb_t *ebb; +{ + if (!extend_ebb_bounds_forward (ebb)) + return FALSE; + if (!extend_ebb_bounds_backward (ebb)) + return FALSE; + return TRUE; +} - relax_info->fix_list = NULL; + +static bfd_boolean +extend_ebb_bounds_forward (ebb) + ebb_t *ebb; +{ + property_table_entry *the_entry, *new_entry; + + the_entry = &ebb->ptbl[ebb->end_ptbl_idx]; + + /* Stop when (1) we cannot decode an instruction, (2) we are at + the end of the property tables, (3) we hit a non-contiguous property + table entry, (4) we hit a NO_TRANSFORM region. */ + + while (1) + { + bfd_vma entry_end; + bfd_size_type insn_block_len; + + entry_end = the_entry->address - ebb->sec->vma + the_entry->size; + insn_block_len = + insn_block_decodable_len (ebb->contents, ebb->content_length, + ebb->end_offset, + entry_end - ebb->end_offset); + if (insn_block_len != (entry_end - ebb->end_offset)) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"), + ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len); + return FALSE; + } + ebb->end_offset += insn_block_len; + + if (ebb->end_offset == ebb->sec->size) + ebb->ends_section = TRUE; + + /* Update the reloc counter. */ + while (ebb->end_reloc_idx + 1 < ebb->reloc_count + && (ebb->relocs[ebb->end_reloc_idx + 1].r_offset + < ebb->end_offset)) + { + ebb->end_reloc_idx++; + } + + if (ebb->end_ptbl_idx + 1 == ebb->pte_count) + return TRUE; + + new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1]; + if (((new_entry->flags & XTENSA_PROP_INSN) == 0) + || ((new_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) != 0) + || ((the_entry->flags & XTENSA_PROP_ALIGN) != 0)) + break; + + if (the_entry->address + the_entry->size != new_entry->address) + break; + + the_entry = new_entry; + ebb->end_ptbl_idx++; + } + + /* Quick check for an unreachable or end of file just at the end. */ + if (ebb->end_ptbl_idx + 1 == ebb->pte_count) + { + if (ebb->end_offset == ebb->content_length) + ebb->ends_section = TRUE; + } + else + { + new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1]; + if ((new_entry->flags & XTENSA_PROP_UNREACHABLE) != 0 + && the_entry->address + the_entry->size == new_entry->address) + ebb->ends_unreachable = new_entry; + } + + /* Any other ending requires exact alignment. */ + return TRUE; } -static xtensa_relax_info * -get_xtensa_relax_info (sec) - asection *sec; +static bfd_boolean +extend_ebb_bounds_backward (ebb) + ebb_t *ebb; { - struct elf_xtensa_section_data *section_data; + property_table_entry *the_entry, *new_entry; - /* No info available if no section or if it is an output section. */ - if (!sec || sec == sec->output_section) - return NULL; + the_entry = &ebb->ptbl[ebb->start_ptbl_idx]; - section_data = (struct elf_xtensa_section_data *) elf_section_data (sec); - return §ion_data->relax_info; + /* Stop when (1) we cannot decode the instructions in the current entry. + (2) we are at the beginning of the property tables, (3) we hit a + non-contiguous property table entry, (4) we hit a NO_TRANSFORM region. */ + + while (1) + { + bfd_vma block_begin; + bfd_size_type insn_block_len; + + block_begin = the_entry->address - ebb->sec->vma; + insn_block_len = + insn_block_decodable_len (ebb->contents, ebb->content_length, + block_begin, + ebb->start_offset - block_begin); + if (insn_block_len != ebb->start_offset - block_begin) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"), + ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len); + return FALSE; + } + ebb->start_offset -= insn_block_len; + + /* Update the reloc counter. */ + while (ebb->start_reloc_idx > 0 + && (ebb->relocs[ebb->start_reloc_idx - 1].r_offset + >= ebb->start_offset)) + { + ebb->start_reloc_idx--; + } + + if (ebb->start_ptbl_idx == 0) + return TRUE; + + new_entry = &ebb->ptbl[ebb->start_ptbl_idx - 1]; + if ((new_entry->flags & XTENSA_PROP_INSN) == 0 + || ((new_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) != 0) + || ((new_entry->flags & XTENSA_PROP_ALIGN) != 0)) + return TRUE; + if (new_entry->address + new_entry->size != the_entry->address) + return TRUE; + + the_entry = new_entry; + ebb->start_ptbl_idx--; + } + return TRUE; +} + + +static bfd_size_type +insn_block_decodable_len (contents, content_len, block_offset, block_len) + bfd_byte *contents; + bfd_size_type content_len; + bfd_vma block_offset; + bfd_size_type block_len; +{ + bfd_vma offset = block_offset; + + while (offset < block_offset + block_len) + { + bfd_size_type insn_len = 0; + + insn_len = insn_decode_len (contents, content_len, offset); + if (insn_len == 0) + return (offset - block_offset); + offset += insn_len; + } + return (offset - block_offset); } static void -add_fix (src_sec, fix) - asection *src_sec; - reloc_bfd_fix *fix; +ebb_propose_action (c, align_type, alignment_pow, action, offset, + removed_bytes, do_action) + ebb_constraint *c; + bfd_vma alignment_pow; + enum ebb_target_enum align_type; + text_action_t action; + bfd_vma offset; + int removed_bytes; + bfd_boolean do_action; { - xtensa_relax_info *relax_info; + proposed_action paction; + paction.align_type = align_type; + paction.alignment_pow = alignment_pow; + paction.action = action; + paction.offset = offset; + paction.removed_bytes = removed_bytes; + paction.do_action = do_action; + ebb_add_proposed_action (c, &paction); +} - relax_info = get_xtensa_relax_info (src_sec); - fix->next = relax_info->fix_list; - relax_info->fix_list = fix; + +static void +ebb_add_proposed_action (c, action) + ebb_constraint *c; + proposed_action *action; +{ + unsigned i; + if (c->action_allocated <= c->action_count) + { + unsigned new_allocated = (c->action_count + 2) * 2; + proposed_action *new_actions = (proposed_action *) + bfd_zmalloc (sizeof (proposed_action) * new_allocated); + + for (i = 0; i < c->action_count; i++) + new_actions[i] = c->actions[i]; + if (c->actions != NULL) + free (c->actions); + c->actions = new_actions; + c->action_allocated = new_allocated; + } + c->actions[c->action_count] = *action; + c->action_count++; } @@ -3938,10 +6113,12 @@ retrieve_contents (abfd, sec, keep_memory) bfd_boolean keep_memory; { bfd_byte *contents; + bfd_size_type sec_size; + sec_size = bfd_get_section_limit (abfd, sec); contents = elf_section_data (sec)->this_hdr.contents; - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { if (!bfd_malloc_and_get_section (abfd, sec, &contents)) { @@ -3970,8 +6147,7 @@ release_contents (sec, contents) asection *sec; bfd_byte *contents; { - if (contents && - elf_section_data (sec)->this_hdr.contents != contents) + if (contents && elf_section_data (sec)->this_hdr.contents != contents) free (contents); } @@ -4002,7 +6178,7 @@ retrieve_local_syms (input_bfd) /* Code for link-time relaxation. */ -/* Local helper functions. */ +/* Initialization for relaxation: */ static bfd_boolean analyze_relocations PARAMS ((struct bfd_link_info *)); static bfd_boolean find_relaxable_sections @@ -4012,25 +6188,70 @@ static bfd_boolean collect_source_relocs static bfd_boolean is_resolvable_asm_expansion PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, struct bfd_link_info *, bfd_boolean *)); -static bfd_boolean remove_literals - PARAMS ((bfd *, asection *, struct bfd_link_info *, value_map_hash_table *)); -static bfd_boolean relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *)); -static bfd_boolean relax_property_section +static Elf_Internal_Rela *find_associated_l32r_irel + PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, + Elf_Internal_Rela *)); +static bfd_boolean compute_text_actions PARAMS ((bfd *, asection *, struct bfd_link_info *)); -static bfd_boolean relax_section_symbols - PARAMS ((bfd *, asection *)); +static bfd_boolean compute_ebb_proposed_actions + PARAMS ((ebb_constraint *)); +static bfd_boolean compute_ebb_actions + PARAMS ((ebb_constraint *)); +static bfd_boolean check_section_ebb_pcrels_fit + PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, + const ebb_constraint *)); +static bfd_boolean check_section_ebb_reduces + PARAMS ((const ebb_constraint *)); +static void text_action_add_proposed + PARAMS ((text_action_list *, const ebb_constraint *, asection *)); +static int compute_fill_extra_space + PARAMS ((property_table_entry *)); + +/* First pass: */ +static bfd_boolean compute_removed_literals + PARAMS ((bfd *, asection *, struct bfd_link_info *, value_map_hash_table *)); +static Elf_Internal_Rela *get_irel_at_offset + PARAMS ((asection *, Elf_Internal_Rela *, bfd_vma)); +static bfd_boolean is_removable_literal + PARAMS ((const source_reloc *, int, const source_reloc *, int)); +static bfd_boolean remove_dead_literal + PARAMS ((bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *, + Elf_Internal_Rela *, source_reloc *, property_table_entry *, int)); +static bfd_boolean identify_literal_placement + PARAMS ((bfd *, asection *, bfd_byte *, struct bfd_link_info *, + value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int, + source_reloc *, property_table_entry *, int, section_cache_t *, + bfd_boolean)); static bfd_boolean relocations_reach PARAMS ((source_reloc *, int, const r_reloc *)); +static bfd_boolean coalesce_shared_literal + PARAMS ((asection *, source_reloc *, property_table_entry *, int, + value_map *)); +static bfd_boolean move_shared_literal + PARAMS ((asection *, struct bfd_link_info *, source_reloc *, + property_table_entry *, int, const r_reloc *, + const literal_value *, section_cache_t *)); + +/* Second pass: */ +static bfd_boolean relax_section + PARAMS ((bfd *, asection *, struct bfd_link_info *)); +static bfd_boolean translate_section_fixes + PARAMS ((asection *)); +static bfd_boolean translate_reloc_bfd_fix + PARAMS ((reloc_bfd_fix *)); static void translate_reloc PARAMS ((const r_reloc *, r_reloc *)); -static Elf_Internal_Rela *get_irel_at_offset - PARAMS ((asection *, Elf_Internal_Rela *, bfd_vma)); -static Elf_Internal_Rela *find_associated_l32r_irel - PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *, - Elf_Internal_Rela *)); static void shrink_dynamic_reloc_sections PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *)); +static bfd_boolean move_literal + PARAMS ((bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *, + xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *)); +static bfd_boolean relax_property_section + PARAMS ((bfd *, asection *, struct bfd_link_info *)); + +/* Third pass: */ +static bfd_boolean relax_section_symbols + PARAMS ((bfd *, asection *)); static bfd_boolean @@ -4041,15 +6262,19 @@ elf_xtensa_relax_section (abfd, sec, link_info, again) bfd_boolean *again; { static value_map_hash_table *values = NULL; + static bfd_boolean relocations_analyzed = FALSE; xtensa_relax_info *relax_info; - if (!values) + if (!relocations_analyzed) { /* Do some overall initialization for relaxation. */ values = value_map_hash_table_init (); + if (values == NULL) + return FALSE; relaxing_section = TRUE; if (!analyze_relocations (link_info)) return FALSE; + relocations_analyzed = TRUE; } *again = FALSE; @@ -4066,12 +6291,15 @@ elf_xtensa_relax_section (abfd, sec, link_info, again) /* Note: It would be nice to fold this pass into analyze_relocations, but it is important for this step that the sections be examined in link order. */ - if (!remove_literals (abfd, sec, link_info, values)) + if (!compute_removed_literals (abfd, sec, link_info, values)) return FALSE; *again = TRUE; break; case 1: + if (values) + value_map_hash_table_delete (values); + values = NULL; if (!relax_section (abfd, sec, link_info)) return FALSE; *again = TRUE; @@ -4087,13 +6315,20 @@ elf_xtensa_relax_section (abfd, sec, link_info, again) return TRUE; } + /* Initialization for relaxation. */ /* This function is called once at the start of relaxation. It scans all the input sections and marks the ones that are relaxable (i.e., - literal sections with L32R relocations against them). It then - collect source_reloc information for all the relocations against - those relaxable sections. */ + literal sections with L32R relocations against them), and then + collects source_reloc information for all the relocations against + those relaxable sections. During this process, it also detects + longcalls, i.e., calls relaxed by the assembler into indirect + calls, that can be optimized back into direct calls. Within each + extended basic block (ebb) containing an optimized longcall, it + computes a set of "text actions" that can be performed to remove + the L32R associated with the longcall while optionally preserving + branch target alignments. */ static bfd_boolean analyze_relocations (link_info) @@ -4129,7 +6364,8 @@ analyze_relocations (link_info) xtensa_relax_info *relax_info; relax_info = get_xtensa_relax_info (sec); - if (relax_info->is_relaxable_literal_section) + if (relax_info->is_relaxable_literal_section + || relax_info->is_relaxable_asm_section) { relax_info->src_relocs = (source_reloc *) bfd_malloc (relax_info->src_count * sizeof (source_reloc)); @@ -4144,15 +6380,23 @@ analyze_relocations (link_info) return FALSE; } + /* Compute the text actions. */ + for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next) + for (sec = abfd->sections; sec != NULL; sec = sec->next) + { + if (!compute_text_actions (abfd, sec, link_info)) + return FALSE; + } + return TRUE; } -/* Find all the literal sections that might be relaxed. The motivation - for this pass is that collect_source_relocs() needs to record _all_ - the relocations that target each relaxable section. That is - expensive and unnecessary unless the target section is actually going - to be relaxed. This pass identifies all such sections by checking if +/* Find all the sections that might be relaxed. The motivation for + this pass is that collect_source_relocs() needs to record _all_ the + relocations that target each relaxable section. That is expensive + and unnecessary unless the target section is actually going to be + relaxed. This pass identifies all such sections by checking if they have L32Rs pointing to them. In the process, the total number of relocations targeting each section is also counted so that we know how much space to allocate for source_relocs against each @@ -4169,6 +6413,7 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) bfd_byte *contents; bfd_boolean ok = TRUE; unsigned i; + xtensa_relax_info *source_relax_info; internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); @@ -4182,6 +6427,7 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) goto error_return; } + source_relax_info = get_xtensa_relax_info (sec); for (i = 0; i < sec->reloc_count; i++) { Elf_Internal_Rela *irel = &internal_relocs[i]; @@ -4189,18 +6435,41 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) asection *target_sec; xtensa_relax_info *target_relax_info; - r_reloc_init (&r_rel, abfd, irel); + /* If this section has not already been marked as "relaxable", and + if it contains any ASM_EXPAND relocations (marking expanded + longcalls) that can be optimized into direct calls, then mark + the section as "relaxable". */ + if (source_relax_info + && !source_relax_info->is_relaxable_asm_section + && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_EXPAND) + { + bfd_boolean is_reachable = FALSE; + if (is_resolvable_asm_expansion (abfd, sec, contents, irel, + link_info, &is_reachable) + && is_reachable) + { + source_relax_info->is_relaxable_asm_section = TRUE; + *is_relaxable_p = TRUE; + } + } + + r_reloc_init (&r_rel, abfd, irel, contents, + bfd_get_section_limit (abfd, sec)); target_sec = r_reloc_get_section (&r_rel); target_relax_info = get_xtensa_relax_info (target_sec); if (!target_relax_info) continue; - /* Count relocations against the target section. */ - target_relax_info->src_count++; + /* Count PC-relative operand relocations against the target section. + Note: The conditions tested here must match the conditions under + which init_source_reloc is called in collect_source_relocs(). */ + if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)) + && (!is_alt_relocation (ELF32_R_TYPE (irel->r_info)) + || is_l32r_relocation (abfd, sec, contents, irel))) + target_relax_info->src_count++; - if (is_literal_section (target_sec) - && is_l32r_relocation (sec, contents, irel) + if (is_l32r_relocation (abfd, sec, contents, irel) && r_reloc_is_defined (&r_rel)) { /* Mark the target section as relaxable. */ @@ -4216,9 +6485,9 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) } -/* Record _all_ the relocations that point to relaxable literal - sections, and get rid of ASM_EXPAND relocs by either converting them - to ASM_SIMPLIFY or by removing them. */ +/* Record _all_ the relocations that point to relaxable sections, and + get rid of ASM_EXPAND relocs by either converting them to + ASM_SIMPLIFY or by removing them. */ static bfd_boolean collect_source_relocs (abfd, sec, link_info) @@ -4230,14 +6499,16 @@ collect_source_relocs (abfd, sec, link_info) bfd_byte *contents; bfd_boolean ok = TRUE; unsigned i; + bfd_size_type sec_size; internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); if (internal_relocs == NULL) return ok; + sec_size = bfd_get_section_limit (abfd, sec); contents = retrieve_contents (abfd, sec, link_info->keep_memory); - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { ok = FALSE; goto error_return; @@ -4251,30 +6522,48 @@ collect_source_relocs (abfd, sec, link_info) asection *target_sec; xtensa_relax_info *target_relax_info; - r_reloc_init (&r_rel, abfd, irel); + r_reloc_init (&r_rel, abfd, irel, contents, sec_size); target_sec = r_reloc_get_section (&r_rel); target_relax_info = get_xtensa_relax_info (target_sec); if (target_relax_info - && target_relax_info->is_relaxable_literal_section) + && (target_relax_info->is_relaxable_literal_section + || target_relax_info->is_relaxable_asm_section)) { - xtensa_opcode opcode; - xtensa_operand opnd; - source_reloc *s_reloc; - int src_next; + xtensa_opcode opcode = XTENSA_UNDEFINED; + int opnd = -1; + bfd_boolean is_abs_literal = FALSE; - src_next = target_relax_info->src_next++; - s_reloc = &target_relax_info->src_relocs[src_next]; + if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) + { + /* None of the current alternate relocs are PC-relative, + and only PC-relative relocs matter here. However, we + still need to record the opcode for literal + coalescing. */ + opcode = get_relocation_opcode (abfd, sec, contents, irel); + if (opcode == get_l32r_opcode ()) + { + is_abs_literal = TRUE; + opnd = 1; + } + else + opcode = XTENSA_UNDEFINED; + } + else if (is_operand_relocation (ELF32_R_TYPE (irel->r_info))) + { + opcode = get_relocation_opcode (abfd, sec, contents, irel); + opnd = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); + } - opcode = get_relocation_opcode (sec, contents, irel); - if (opcode == XTENSA_UNDEFINED) - opnd = NULL; - else - opnd = xtensa_get_operand (xtensa_default_isa, opcode, - get_relocation_opnd (irel)); + if (opcode != XTENSA_UNDEFINED) + { + int src_next = target_relax_info->src_next++; + source_reloc *s_reloc = &target_relax_info->src_relocs[src_next]; - init_source_reloc (s_reloc, sec, &r_rel, opnd); + init_source_reloc (s_reloc, sec, &r_rel, opcode, opnd, + is_abs_literal); + } } } @@ -4301,20 +6590,21 @@ collect_source_relocs (abfd, sec, link_info) xtensa_relax_info *target_relax_info; /* Mark the source_reloc for the L32R so that it will be - removed in remove_literals(), along with the associated - literal. */ - l32r_irel = find_associated_l32r_irel (sec, contents, + removed in compute_removed_literals(), along with the + associated literal. */ + l32r_irel = find_associated_l32r_irel (abfd, sec, contents, irel, internal_relocs); if (l32r_irel == NULL) continue; - r_reloc_init (&r_rel, abfd, l32r_irel); + r_reloc_init (&r_rel, abfd, l32r_irel, contents, sec_size); target_sec = r_reloc_get_section (&r_rel); target_relax_info = get_xtensa_relax_info (target_sec); if (target_relax_info - && target_relax_info->is_relaxable_literal_section) + && (target_relax_info->is_relaxable_literal_section + || target_relax_info->is_relaxable_asm_section)) { source_reloc *s_reloc; @@ -4375,6 +6665,8 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, xtensa_opcode opcode, direct_call_opcode; bfd_vma self_address; bfd_vma dest_address; + bfd_boolean uses_l32r; + bfd_size_type sec_size; *is_reachable_p = FALSE; @@ -4383,21 +6675,25 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND) return FALSE; - + + sec_size = bfd_get_section_limit (abfd, sec); opcode = get_expanded_call_opcode (contents + irel->r_offset, - sec->size - irel->r_offset); + sec_size - irel->r_offset, &uses_l32r); + /* Optimization of longcalls that use CONST16 is not yet implemented. */ + if (!uses_l32r) + return FALSE; direct_call_opcode = swap_callx_for_call_opcode (opcode); if (direct_call_opcode == XTENSA_UNDEFINED) return FALSE; /* Check and see that the target resolves. */ - r_reloc_init (&r_rel, abfd, irel); + r_reloc_init (&r_rel, abfd, irel, contents, sec_size); if (!r_reloc_is_defined (&r_rel)) return FALSE; target_sec = r_reloc_get_section (&r_rel); - target_offset = r_reloc_get_target_offset (&r_rel); + target_offset = r_rel.target_offset; /* If the target is in a shared library, then it doesn't reach. This isn't supposed to come up because the compiler should never generate @@ -4410,7 +6706,8 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, section of the target is the same as the output section of the source. */ if (link_info->relocatable - && (target_sec->output_section != sec->output_section)) + && (target_sec->output_section != sec->output_section + || is_reloc_sym_weak (abfd, irel))) return FALSE; self_address = (sec->output_section->vma @@ -4418,9 +6715,8 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, dest_address = (target_sec->output_section->vma + target_sec->output_offset + target_offset); - *is_reachable_p = pcrel_reloc_fits - (xtensa_get_operand (xtensa_default_isa, direct_call_opcode, 0), - self_address, dest_address); + *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0, + self_address, dest_address); if ((self_address >> CALL_SEGMENT_BITS) != (dest_address >> CALL_SEGMENT_BITS)) @@ -4431,7 +6727,8 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, static Elf_Internal_Rela * -find_associated_l32r_irel (sec, contents, other_irel, internal_relocs) +find_associated_l32r_irel (abfd, sec, contents, other_irel, internal_relocs) + bfd *abfd; asection *sec; bfd_byte *contents; Elf_Internal_Rela *other_irel; @@ -4447,23 +6744,778 @@ find_associated_l32r_irel (sec, contents, other_irel, internal_relocs) continue; if (irel->r_offset != other_irel->r_offset) continue; - if (is_l32r_relocation (sec, contents, irel)) + if (is_l32r_relocation (abfd, sec, contents, irel)) return irel; } return NULL; } + +/* The compute_text_actions function will build a list of potential + transformation actions for code in the extended basic block of each + longcall that is optimized to a direct call. From this list we + generate a set of actions to actually perform that optimizes for + space and, if not using size_opt, maintains branch target + alignments. + + These actions to be performed are placed on a per-section list. + The actual changes are performed by relax_section() in the second + pass. */ + +bfd_boolean +compute_text_actions (abfd, sec, link_info) + bfd *abfd; + asection *sec; + struct bfd_link_info *link_info; +{ + xtensa_relax_info *relax_info; + bfd_byte *contents; + Elf_Internal_Rela *internal_relocs; + bfd_boolean ok = TRUE; + unsigned i; + property_table_entry *prop_table = 0; + int ptblsize = 0; + bfd_size_type sec_size; + static bfd_boolean no_insn_move = FALSE; + + if (no_insn_move) + return ok; + + /* Do nothing if the section contains no optimized longcalls. */ + relax_info = get_xtensa_relax_info (sec); + BFD_ASSERT (relax_info); + if (!relax_info->is_relaxable_asm_section) + return ok; + + internal_relocs = retrieve_internal_relocs (abfd, sec, + link_info->keep_memory); + + if (internal_relocs) + qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela), + internal_reloc_compare); + + sec_size = bfd_get_section_limit (abfd, sec); + contents = retrieve_contents (abfd, sec, link_info->keep_memory); + if (contents == NULL && sec_size != 0) + { + ok = FALSE; + goto error_return; + } + + ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table, + XTENSA_PROP_SEC_NAME, FALSE); + if (ptblsize < 0) + { + ok = FALSE; + goto error_return; + } + + for (i = 0; i < sec->reloc_count; i++) + { + Elf_Internal_Rela *irel = &internal_relocs[i]; + bfd_vma r_offset; + property_table_entry *the_entry; + int ptbl_idx; + ebb_t *ebb; + ebb_constraint ebb_table; + bfd_size_type simplify_size; + + if (irel && ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_SIMPLIFY) + continue; + r_offset = irel->r_offset; + + simplify_size = get_asm_simplify_size (contents, sec_size, r_offset); + if (simplify_size == 0) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"), + sec->owner, sec, r_offset); + continue; + } + + /* If the instruction table is not around, then don't do this + relaxation. */ + the_entry = elf_xtensa_find_property_entry (prop_table, ptblsize, + sec->vma + irel->r_offset); + if (the_entry == NULL || XTENSA_NO_NOP_REMOVAL) + { + text_action_add (&relax_info->action_list, + ta_convert_longcall, sec, r_offset, + 0); + continue; + } + + /* If the next longcall happens to be at the same address as an + unreachable section of size 0, then skip forward. */ + ptbl_idx = the_entry - prop_table; + while ((the_entry->flags & XTENSA_PROP_UNREACHABLE) + && the_entry->size == 0 + && ptbl_idx + 1 < ptblsize + && (prop_table[ptbl_idx + 1].address + == prop_table[ptbl_idx].address)) + { + ptbl_idx++; + the_entry++; + } + + if (the_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) + /* NO_REORDER is OK */ + continue; + + init_ebb_constraint (&ebb_table); + ebb = &ebb_table.ebb; + init_ebb (ebb, sec, contents, sec_size, prop_table, ptblsize, + internal_relocs, sec->reloc_count); + ebb->start_offset = r_offset + simplify_size; + ebb->end_offset = r_offset + simplify_size; + ebb->start_ptbl_idx = ptbl_idx; + ebb->end_ptbl_idx = ptbl_idx; + ebb->start_reloc_idx = i; + ebb->end_reloc_idx = i; + + if (!extend_ebb_bounds (ebb) + || !compute_ebb_proposed_actions (&ebb_table) + || !compute_ebb_actions (&ebb_table) + || !check_section_ebb_pcrels_fit (abfd, sec, contents, + internal_relocs, &ebb_table) + || !check_section_ebb_reduces (&ebb_table)) + { + /* If anything goes wrong or we get unlucky and something does + not fit, with our plan because of expansion between + critical branches, just convert to a NOP. */ + + text_action_add (&relax_info->action_list, + ta_convert_longcall, sec, r_offset, 0); + i = ebb_table.ebb.end_reloc_idx; + free_ebb_constraint (&ebb_table); + continue; + } + + text_action_add_proposed (&relax_info->action_list, &ebb_table, sec); + + /* Update the index so we do not go looking at the relocations + we have already processed. */ + i = ebb_table.ebb.end_reloc_idx; + free_ebb_constraint (&ebb_table); + } + +#if DEBUG + if (relax_info->action_list.head != NULL) + print_action_list (stderr, &relax_info->action_list); +#endif + +error_return: + release_contents (sec, contents); + release_internal_relocs (sec, internal_relocs); + if (prop_table) + free (prop_table); + + return ok; +} + + +/* Find all of the possible actions for an extended basic block. */ + +bfd_boolean +compute_ebb_proposed_actions (ebb_table) + ebb_constraint *ebb_table; +{ + const ebb_t *ebb = &ebb_table->ebb; + unsigned rel_idx = ebb->start_reloc_idx; + property_table_entry *entry, *start_entry, *end_entry; + + start_entry = &ebb->ptbl[ebb->start_ptbl_idx]; + end_entry = &ebb->ptbl[ebb->end_ptbl_idx]; + + for (entry = start_entry; entry <= end_entry; entry++) + { + bfd_vma offset, start_offset, end_offset; + bfd_size_type insn_len; + + start_offset = entry->address - ebb->sec->vma; + end_offset = entry->address + entry->size - ebb->sec->vma; + + if (entry == start_entry) + start_offset = ebb->start_offset; + if (entry == end_entry) + end_offset = ebb->end_offset; + offset = start_offset; + + if (offset == entry->address - ebb->sec->vma + && (entry->flags & XTENSA_PROP_INSN_BRANCH_TARGET) != 0) + { + enum ebb_target_enum align_type = EBB_DESIRE_TGT_ALIGN; + BFD_ASSERT (offset != end_offset); + if (offset == end_offset) + return FALSE; + + insn_len = insn_decode_len (ebb->contents, ebb->content_length, + offset); + + /* Propose no actions for a section with an undecodable offset. */ + if (insn_len == 0) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"), + ebb->sec->owner, ebb->sec, offset); + return FALSE; + } + if (check_branch_target_aligned_address (offset, insn_len)) + align_type = EBB_REQUIRE_TGT_ALIGN; + + ebb_propose_action (ebb_table, align_type, 0, + ta_none, offset, 0, TRUE); + } + + while (offset != end_offset) + { + Elf_Internal_Rela *irel; + xtensa_opcode opcode; + + while (rel_idx < ebb->end_reloc_idx + && (ebb->relocs[rel_idx].r_offset < offset + || (ebb->relocs[rel_idx].r_offset == offset + && (ELF32_R_TYPE (ebb->relocs[rel_idx].r_info) + != R_XTENSA_ASM_SIMPLIFY)))) + rel_idx++; + + /* Check for longcall. */ + irel = &ebb->relocs[rel_idx]; + if (irel->r_offset == offset + && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY) + { + bfd_size_type simplify_size; + + simplify_size = get_asm_simplify_size (ebb->contents, + ebb->content_length, + irel->r_offset); + if (simplify_size == 0) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"), + ebb->sec->owner, ebb->sec, offset); + return FALSE; + } + + ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0, + ta_convert_longcall, offset, 0, TRUE); + + offset += simplify_size; + continue; + } + + insn_len = insn_decode_len (ebb->contents, ebb->content_length, + offset); + /* If the instruction is undecodable, then report an error. */ + if (insn_len == 0) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"), + ebb->sec->owner, ebb->sec, offset); + return FALSE; + } + + if ((entry->flags & XTENSA_PROP_INSN_NO_DENSITY) == 0 + && (entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) == 0 + && narrow_instruction (ebb->contents, ebb->content_length, + offset, FALSE)) + { + /* Add an instruction narrow action. */ + ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0, + ta_narrow_insn, offset, 0, FALSE); + offset += insn_len; + continue; + } + if ((entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) == 0 + && widen_instruction (ebb->contents, ebb->content_length, + offset, FALSE)) + { + /* Add an instruction widen action. */ + ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0, + ta_widen_insn, offset, 0, FALSE); + offset += insn_len; + continue; + } + opcode = insn_decode_opcode (ebb->contents, ebb->content_length, + offset, 0); + if (xtensa_opcode_is_loop (xtensa_default_isa, opcode)) + { + /* Check for branch targets. */ + ebb_propose_action (ebb_table, EBB_REQUIRE_LOOP_ALIGN, 0, + ta_none, offset, 0, TRUE); + offset += insn_len; + continue; + } + + offset += insn_len; + } + } + + if (ebb->ends_unreachable) + { + ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0, + ta_fill, ebb->end_offset, 0, TRUE); + } + + return TRUE; +} + + +/* After all of the information has collected about the + transformations possible in an EBB, compute the appropriate actions + here in compute_ebb_actions. We still must check later to make + sure that the actions do not break any relocations. The algorithm + used here is pretty greedy. Basically, it removes as many no-ops + as possible so that the end of the EBB has the same alignment + characteristics as the original. First, it uses narrowing, then + fill space at the end of the EBB, and finally widenings. If that + does not work, it tries again with one fewer no-op removed. The + optimization will only be performed if all of the branch targets + that were aligned before transformation are also aligned after the + transformation. + + When the size_opt flag is set, ignore the branch target alignments, + narrow all wide instructions, and remove all no-ops unless the end + of the EBB prevents it. */ + +bfd_boolean +compute_ebb_actions (ebb_table) + ebb_constraint *ebb_table; +{ + unsigned i = 0; + unsigned j; + int removed_bytes = 0; + ebb_t *ebb = &ebb_table->ebb; + unsigned seg_idx_start = 0; + unsigned seg_idx_end = 0; + + /* We perform this like the assembler relaxation algorithm: Start by + assuming all instructions are narrow and all no-ops removed; then + walk through.... */ + + /* For each segment of this that has a solid constraint, check to + see if there are any combinations that will keep the constraint. + If so, use it. */ + for (seg_idx_end = 0; seg_idx_end < ebb_table->action_count; seg_idx_end++) + { + bfd_boolean requires_text_end_align = FALSE; + unsigned longcall_count = 0; + unsigned longcall_convert_count = 0; + unsigned narrowable_count = 0; + unsigned narrowable_convert_count = 0; + unsigned widenable_count = 0; + unsigned widenable_convert_count = 0; + + proposed_action *action = NULL; + int align = (1 << ebb_table->ebb.sec->alignment_power); + + seg_idx_start = seg_idx_end; + + for (i = seg_idx_start; i < ebb_table->action_count; i++) + { + action = &ebb_table->actions[i]; + if (action->action == ta_convert_longcall) + longcall_count++; + if (action->action == ta_narrow_insn) + narrowable_count++; + if (action->action == ta_widen_insn) + widenable_count++; + if (action->action == ta_fill) + break; + if (action->align_type == EBB_REQUIRE_LOOP_ALIGN) + break; + if (action->align_type == EBB_REQUIRE_TGT_ALIGN + && !elf32xtensa_size_opt) + break; + } + seg_idx_end = i; + + if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable) + requires_text_end_align = TRUE; + + if (elf32xtensa_size_opt && !requires_text_end_align + && action->align_type != EBB_REQUIRE_LOOP_ALIGN + && action->align_type != EBB_REQUIRE_TGT_ALIGN) + { + longcall_convert_count = longcall_count; + narrowable_convert_count = narrowable_count; + widenable_convert_count = 0; + } + else + { + /* There is a constraint. Convert the max number of longcalls. */ + narrowable_convert_count = 0; + longcall_convert_count = 0; + widenable_convert_count = 0; + + for (j = 0; j < longcall_count; j++) + { + int removed = (longcall_count - j) * 3 & (align - 1); + unsigned desire_narrow = (align - removed) & (align - 1); + unsigned desire_widen = removed; + if (desire_narrow <= narrowable_count) + { + narrowable_convert_count = desire_narrow; + narrowable_convert_count += + (align * ((narrowable_count - narrowable_convert_count) + / align)); + longcall_convert_count = (longcall_count - j); + widenable_convert_count = 0; + break; + } + if (desire_widen <= widenable_count && !elf32xtensa_size_opt) + { + narrowable_convert_count = 0; + longcall_convert_count = longcall_count - j; + widenable_convert_count = desire_widen; + break; + } + } + } + + /* Now the number of conversions are saved. Do them. */ + for (i = seg_idx_start; i < seg_idx_end; i++) + { + action = &ebb_table->actions[i]; + switch (action->action) + { + case ta_convert_longcall: + if (longcall_convert_count != 0) + { + action->action = ta_remove_longcall; + action->do_action = TRUE; + action->removed_bytes += 3; + longcall_convert_count--; + } + break; + case ta_narrow_insn: + if (narrowable_convert_count != 0) + { + action->do_action = TRUE; + action->removed_bytes += 1; + narrowable_convert_count--; + } + break; + case ta_widen_insn: + if (widenable_convert_count != 0) + { + action->do_action = TRUE; + action->removed_bytes -= 1; + widenable_convert_count--; + } + break; + default: + break; + } + } + } + + /* Now we move on to some local opts. Try to remove each of the + remaining longcalls. */ + + if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable) + { + removed_bytes = 0; + for (i = 0; i < ebb_table->action_count; i++) + { + int old_removed_bytes = removed_bytes; + proposed_action *action = &ebb_table->actions[i]; + + if (action->do_action && action->action == ta_convert_longcall) + { + bfd_boolean bad_alignment = FALSE; + removed_bytes += 3; + for (j = i + 1; j < ebb_table->action_count; j++) + { + proposed_action *new_action = &ebb_table->actions[j]; + bfd_vma offset = new_action->offset; + if (new_action->align_type == EBB_REQUIRE_TGT_ALIGN) + { + if (!check_branch_target_aligned + (ebb_table->ebb.contents, + ebb_table->ebb.content_length, + offset, offset - removed_bytes)) + { + bad_alignment = TRUE; + break; + } + } + if (new_action->align_type == EBB_REQUIRE_LOOP_ALIGN) + { + if (!check_loop_aligned (ebb_table->ebb.contents, + ebb_table->ebb.content_length, + offset, + offset - removed_bytes)) + { + bad_alignment = TRUE; + break; + } + } + if (new_action->action == ta_narrow_insn + && !new_action->do_action + && ebb_table->ebb.sec->alignment_power == 2) + { + /* Narrow an instruction and we are done. */ + new_action->do_action = TRUE; + new_action->removed_bytes += 1; + bad_alignment = FALSE; + break; + } + if (new_action->action == ta_widen_insn + && new_action->do_action + && ebb_table->ebb.sec->alignment_power == 2) + { + /* Narrow an instruction and we are done. */ + new_action->do_action = FALSE; + new_action->removed_bytes += 1; + bad_alignment = FALSE; + break; + } + } + if (!bad_alignment) + { + action->removed_bytes += 3; + action->action = ta_remove_longcall; + action->do_action = TRUE; + } + } + removed_bytes = old_removed_bytes; + if (action->do_action) + removed_bytes += action->removed_bytes; + } + } + + removed_bytes = 0; + for (i = 0; i < ebb_table->action_count; ++i) + { + proposed_action *action = &ebb_table->actions[i]; + if (action->do_action) + removed_bytes += action->removed_bytes; + } + + if ((removed_bytes % (1 << ebb_table->ebb.sec->alignment_power)) != 0 + && ebb->ends_unreachable) + { + proposed_action *action; + int br; + int extra_space; + + BFD_ASSERT (ebb_table->action_count != 0); + action = &ebb_table->actions[ebb_table->action_count - 1]; + BFD_ASSERT (action->action == ta_fill); + BFD_ASSERT (ebb->ends_unreachable->flags & XTENSA_PROP_UNREACHABLE); + + extra_space = compute_fill_extra_space (ebb->ends_unreachable); + br = action->removed_bytes + removed_bytes + extra_space; + br = br & ((1 << ebb->sec->alignment_power ) - 1); + + action->removed_bytes = extra_space - br; + } + return TRUE; +} + + +/* Use check_section_ebb_pcrels_fit to make sure that all of the + relocations in a section will fit if a proposed set of actions + are performed. */ + +static bfd_boolean +check_section_ebb_pcrels_fit (abfd, sec, contents, internal_relocs, constraint) + bfd *abfd; + asection *sec; + bfd_byte *contents; + Elf_Internal_Rela *internal_relocs; + const ebb_constraint *constraint; +{ + unsigned i, j; + Elf_Internal_Rela *irel; + xtensa_relax_info *relax_info; + + relax_info = get_xtensa_relax_info (sec); + + for (i = 0; i < sec->reloc_count; i++) + { + r_reloc r_rel; + bfd_vma orig_self_offset, orig_target_offset; + bfd_vma self_offset, target_offset; + int r_type; + reloc_howto_type *howto; + int self_removed_bytes, target_removed_bytes; + + irel = &internal_relocs[i]; + r_type = ELF32_R_TYPE (irel->r_info); + + howto = &elf_howto_table[r_type]; + /* We maintain the required invariant: PC-relative relocations + that fit before linking must fit after linking. Thus we only + need to deal with relocations to the same section that are + PC-relative. */ + if (ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY + || !howto->pc_relative) + continue; + + r_reloc_init (&r_rel, abfd, irel, contents, + bfd_get_section_limit (abfd, sec)); + + if (r_reloc_get_section (&r_rel) != sec) + continue; + + orig_self_offset = irel->r_offset; + orig_target_offset = r_rel.target_offset; + + self_offset = orig_self_offset; + target_offset = orig_target_offset; + + if (relax_info) + { + self_offset = offset_with_removed_text (&relax_info->action_list, + orig_self_offset); + target_offset = offset_with_removed_text (&relax_info->action_list, + orig_target_offset); + } + + self_removed_bytes = 0; + target_removed_bytes = 0; + + for (j = 0; j < constraint->action_count; ++j) + { + proposed_action *action = &constraint->actions[j]; + bfd_vma offset = action->offset; + int removed_bytes = action->removed_bytes; + if (offset < orig_self_offset + || (offset == orig_self_offset && action->action == ta_fill + && action->removed_bytes < 0)) + self_removed_bytes += removed_bytes; + if (offset < orig_target_offset + || (offset == orig_target_offset && action->action == ta_fill + && action->removed_bytes < 0)) + target_removed_bytes += removed_bytes; + } + self_offset -= self_removed_bytes; + target_offset -= target_removed_bytes; + + /* Try to encode it. Get the operand and check. */ + if (is_alt_relocation (ELF32_R_TYPE (irel->r_info))) + { + /* None of the current alternate relocs are PC-relative, + and only PC-relative relocs matter here. */ + } + else + { + xtensa_opcode opcode; + int opnum; + + opcode = get_relocation_opcode (abfd, sec, contents, irel); + if (opcode == XTENSA_UNDEFINED) + return FALSE; + + opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info)); + if (opnum == XTENSA_UNDEFINED) + return FALSE; + + if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset)) + return FALSE; + } + } + + return TRUE; +} + + +static bfd_boolean +check_section_ebb_reduces (constraint) + const ebb_constraint *constraint; +{ + int removed = 0; + unsigned i; + + for (i = 0; i < constraint->action_count; i++) + { + const proposed_action *action = &constraint->actions[i]; + if (action->do_action) + removed += action->removed_bytes; + } + if (removed < 0) + return FALSE; + + return TRUE; +} + + +void +text_action_add_proposed (l, ebb_table, sec) + text_action_list *l; + const ebb_constraint *ebb_table; + asection *sec; +{ + unsigned i; + + for (i = 0; i < ebb_table->action_count; i++) + { + proposed_action *action = &ebb_table->actions[i]; + + if (!action->do_action) + continue; + switch (action->action) + { + case ta_remove_insn: + case ta_remove_longcall: + case ta_convert_longcall: + case ta_narrow_insn: + case ta_widen_insn: + case ta_fill: + case ta_remove_literal: + text_action_add (l, action->action, sec, action->offset, + action->removed_bytes); + break; + case ta_none: + break; + default: + BFD_ASSERT (0); + break; + } + } +} + + +int +compute_fill_extra_space (entry) + property_table_entry *entry; +{ + int fill_extra_space; + + if (!entry) + return 0; + + if ((entry->flags & XTENSA_PROP_UNREACHABLE) == 0) + return 0; + + fill_extra_space = entry->size; + if ((entry->flags & XTENSA_PROP_ALIGN) != 0) + { + /* Fill bytes for alignment: + (2**n)-1 - (addr + (2**n)-1) & (2**n -1) */ + int pow = GET_XTENSA_PROP_ALIGNMENT (entry->flags); + int nsm = (1 << pow) - 1; + bfd_vma addr = entry->address + entry->size; + bfd_vma align_fill = nsm - ((addr + nsm) & nsm); + fill_extra_space += align_fill; + } + return fill_extra_space; +} + + /* First relaxation pass. */ -/* If the section is relaxable (i.e., a literal section), check each - literal to see if it has the same value as another literal that has - already been seen, either in the current section or a previous one. - If so, add an entry to the per-section list of removed literals. The +/* If the section contains relaxable literals, check each literal to + see if it has the same value as another literal that has already + been seen, either in the current section or a previous one. If so, + add an entry to the per-section list of removed literals. The actual changes are deferred until the next pass. */ static bfd_boolean -remove_literals (abfd, sec, link_info, values) +compute_removed_literals (abfd, sec, link_info, values) bfd *abfd; asection *sec; struct bfd_link_info *link_info; @@ -4472,118 +7524,381 @@ remove_literals (abfd, sec, link_info, values) xtensa_relax_info *relax_info; bfd_byte *contents; Elf_Internal_Rela *internal_relocs; - source_reloc *src_relocs; - bfd_boolean final_static_link; + source_reloc *src_relocs, *rel; bfd_boolean ok = TRUE; - int i; + property_table_entry *prop_table = NULL; + int ptblsize; + int i, prev_i; + bfd_boolean last_loc_is_prev = FALSE; + bfd_vma last_target_offset = 0; + section_cache_t target_sec_cache; + bfd_size_type sec_size; + + init_section_cache (&target_sec_cache); /* Do nothing if it is not a relaxable literal section. */ relax_info = get_xtensa_relax_info (sec); BFD_ASSERT (relax_info); - if (!relax_info->is_relaxable_literal_section) return ok; internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); + sec_size = bfd_get_section_limit (abfd, sec); contents = retrieve_contents (abfd, sec, link_info->keep_memory); - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { ok = FALSE; goto error_return; } - final_static_link = - (!link_info->relocatable - && !elf_hash_table (link_info)->dynamic_sections_created); - /* Sort the source_relocs by target offset. */ src_relocs = relax_info->src_relocs; qsort (src_relocs, relax_info->src_count, sizeof (source_reloc), source_reloc_compare); + qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela), + internal_reloc_compare); + ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table, + XTENSA_PROP_SEC_NAME, FALSE); + if (ptblsize < 0) + { + ok = FALSE; + goto error_return; + } + + prev_i = -1; for (i = 0; i < relax_info->src_count; i++) { - source_reloc *rel; Elf_Internal_Rela *irel = NULL; - literal_value val; - value_map *val_map; rel = &src_relocs[i]; + if (get_l32r_opcode () != rel->opcode) + continue; irel = get_irel_at_offset (sec, internal_relocs, rel->r_rel.target_offset); + /* If the relocation on this is not a simple R_XTENSA_32 or + R_XTENSA_PLT then do not consider it. This may happen when + the difference of two symbols is used in a literal. */ + if (irel && (ELF32_R_TYPE (irel->r_info) != R_XTENSA_32 + && ELF32_R_TYPE (irel->r_info) != R_XTENSA_PLT)) + continue; + /* If the target_offset for this relocation is the same as the previous relocation, then we've already considered whether the literal can be coalesced. Skip to the next one.... */ - if (i != 0 && (src_relocs[i-1].r_rel.target_offset - == rel->r_rel.target_offset)) + if (i != 0 && prev_i != -1 + && src_relocs[i-1].r_rel.target_offset == rel->r_rel.target_offset) continue; + prev_i = i; + + if (last_loc_is_prev && + last_target_offset + 4 != rel->r_rel.target_offset) + last_loc_is_prev = FALSE; /* Check if the relocation was from an L32R that is being removed because a CALLX was converted to a direct CALL, and check if there are no other relocations to the literal. */ - if (rel->is_null - && (i == relax_info->src_count - 1 - || (src_relocs[i+1].r_rel.target_offset - != rel->r_rel.target_offset))) + if (is_removable_literal (rel, i, src_relocs, relax_info->src_count)) { - /* Mark the unused literal so that it will be removed. */ - add_removed_literal (&relax_info->removed_list, &rel->r_rel, NULL); - - /* Zero out the relocation on this literal location. */ - if (irel) + if (!remove_dead_literal (abfd, sec, link_info, internal_relocs, + irel, rel, prop_table, ptblsize)) { - if (elf_hash_table (link_info)->dynamic_sections_created) - shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); - - irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); + ok = FALSE; + goto error_return; } - + last_target_offset = rel->r_rel.target_offset; continue; } - /* Find the literal value. */ - r_reloc_init (&val.r_rel, abfd, irel); - BFD_ASSERT (rel->r_rel.target_offset < sec->size); - val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset); - - /* Check if we've seen another literal with the same value. */ - val_map = get_cached_value (values, &val, final_static_link); - if (val_map != NULL) - { - /* First check that THIS and all the other relocs to this - literal will FIT if we move them to the new address. */ - - if (relocations_reach (rel, relax_info->src_count - i, - &val_map->loc)) - { - /* Mark that the literal will be coalesced. */ - add_removed_literal (&relax_info->removed_list, - &rel->r_rel, &val_map->loc); - } - else - { - /* Relocations do not reach -- do not remove this literal. */ - val_map->loc = rel->r_rel; - } - } - else + if (!identify_literal_placement (abfd, sec, contents, link_info, + values, + &last_loc_is_prev, irel, + relax_info->src_count - i, rel, + prop_table, ptblsize, + &target_sec_cache, rel->is_abs_literal)) { - /* This is the first time we've seen this literal value. */ - BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel)); - add_value_map (values, &val, &rel->r_rel, final_static_link); + ok = FALSE; + goto error_return; } + last_target_offset = rel->r_rel.target_offset; } +#if DEBUG + print_removed_literals (stderr, &relax_info->removed_list); + print_action_list (stderr, &relax_info->action_list); +#endif /* DEBUG */ + error_return: + if (prop_table) free (prop_table); + clear_section_cache (&target_sec_cache); + release_contents (sec, contents); release_internal_relocs (sec, internal_relocs); return ok; } +static Elf_Internal_Rela * +get_irel_at_offset (sec, internal_relocs, offset) + asection *sec; + Elf_Internal_Rela *internal_relocs; + bfd_vma offset; +{ + unsigned i; + Elf_Internal_Rela *irel; + unsigned r_type; + Elf_Internal_Rela key; + + if (!internal_relocs) + return NULL; + + key.r_offset = offset; + irel = bsearch (&key, internal_relocs, sec->reloc_count, + sizeof (Elf_Internal_Rela), internal_reloc_matches); + if (!irel) + return NULL; + + /* bsearch does not guarantee which will be returned if there are + multiple matches. We need the first that is not an alignment. */ + i = irel - internal_relocs; + while (i > 0) + { + if (internal_relocs[i-1].r_offset != offset) + break; + i--; + } + for ( ; i < sec->reloc_count; i++) + { + irel = &internal_relocs[i]; + r_type = ELF32_R_TYPE (irel->r_info); + if (irel->r_offset == offset && r_type != R_XTENSA_NONE) + return irel; + } + + return NULL; +} + + +bfd_boolean +is_removable_literal (rel, i, src_relocs, src_count) + const source_reloc *rel; + int i; + const source_reloc *src_relocs; + int src_count; +{ + const source_reloc *curr_rel; + if (!rel->is_null) + return FALSE; + + for (++i; i < src_count; ++i) + { + curr_rel = &src_relocs[i]; + /* If all others have the same target offset.... */ + if (curr_rel->r_rel.target_offset != rel->r_rel.target_offset) + return TRUE; + + if (!curr_rel->is_null + && !xtensa_is_property_section (curr_rel->source_sec) + && !(curr_rel->source_sec->flags & SEC_DEBUGGING)) + return FALSE; + } + return TRUE; +} + + +bfd_boolean +remove_dead_literal (abfd, sec, link_info, internal_relocs, + irel, rel, prop_table, ptblsize) + bfd *abfd; + asection *sec; + struct bfd_link_info *link_info; + Elf_Internal_Rela *internal_relocs; + Elf_Internal_Rela *irel; + source_reloc *rel; + property_table_entry *prop_table; + int ptblsize; +{ + property_table_entry *entry; + xtensa_relax_info *relax_info; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + return FALSE; + + entry = elf_xtensa_find_property_entry (prop_table, ptblsize, + sec->vma + rel->r_rel.target_offset); + + /* Mark the unused literal so that it will be removed. */ + add_removed_literal (&relax_info->removed_list, &rel->r_rel, NULL); + + text_action_add (&relax_info->action_list, + ta_remove_literal, sec, rel->r_rel.target_offset, 4); + + /* If the section is 4-byte aligned, do not add fill. */ + if (sec->alignment_power > 2) + { + int fill_extra_space; + bfd_vma entry_sec_offset; + text_action *fa; + property_table_entry *the_add_entry; + int removed_diff; + + if (entry) + entry_sec_offset = entry->address - sec->vma + entry->size; + else + entry_sec_offset = rel->r_rel.target_offset + 4; + + /* If the literal range is at the end of the section, + do not add fill. */ + the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize, + entry_sec_offset); + fill_extra_space = compute_fill_extra_space (the_add_entry); + + fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset); + removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset, + -4, fill_extra_space); + if (fa) + adjust_fill_action (fa, removed_diff); + else + text_action_add (&relax_info->action_list, + ta_fill, sec, entry_sec_offset, removed_diff); + } + + /* Zero out the relocation on this literal location. */ + if (irel) + { + if (elf_hash_table (link_info)->dynamic_sections_created) + shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); + + irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); + pin_internal_relocs (sec, internal_relocs); + } + + /* Do not modify "last_loc_is_prev". */ + return TRUE; +} + + +bfd_boolean +identify_literal_placement (abfd, sec, contents, link_info, values, + last_loc_is_prev_p, irel, remaining_src_rels, + rel, prop_table, ptblsize, target_sec_cache, + is_abs_literal) + bfd *abfd; + asection *sec; + bfd_byte *contents; + struct bfd_link_info *link_info; + value_map_hash_table *values; + bfd_boolean *last_loc_is_prev_p; + Elf_Internal_Rela *irel; + int remaining_src_rels; + source_reloc *rel; + property_table_entry *prop_table; + int ptblsize; + section_cache_t *target_sec_cache; + bfd_boolean is_abs_literal; +{ + literal_value val; + value_map *val_map; + xtensa_relax_info *relax_info; + bfd_boolean literal_placed = FALSE; + r_reloc r_rel; + unsigned long value; + bfd_boolean final_static_link; + bfd_size_type sec_size; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + return FALSE; + + sec_size = bfd_get_section_limit (abfd, sec); + + final_static_link = + (!link_info->relocatable + && !elf_hash_table (link_info)->dynamic_sections_created); + + /* The placement algorithm first checks to see if the literal is + already in the value map. If so and the value map is reachable + from all uses, then the literal is moved to that location. If + not, then we identify the last location where a fresh literal was + placed. If the literal can be safely moved there, then we do so. + If not, then we assume that the literal is not to move and leave + the literal where it is, marking it as the last literal + location. */ + + /* Find the literal value. */ + value = 0; + r_reloc_init (&r_rel, abfd, irel, contents, sec_size); + if (!irel) + { + BFD_ASSERT (rel->r_rel.target_offset < sec_size); + value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset); + } + init_literal_value (&val, &r_rel, value, is_abs_literal); + + /* Check if we've seen another literal with the same value that + is in the same output section. */ + val_map = value_map_get_cached_value (values, &val, final_static_link); + + if (val_map + && (r_reloc_get_section (&val_map->loc)->output_section + == sec->output_section) + && relocations_reach (rel, remaining_src_rels, &val_map->loc) + && coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map)) + { + /* No change to last_loc_is_prev. */ + literal_placed = TRUE; + } + + /* For relocatable links, do not try to move literals. To do it + correctly might increase the number of relocations in an input + section making the default relocatable linking fail. */ + if (!link_info->relocatable && !literal_placed + && values->has_last_loc && !(*last_loc_is_prev_p)) + { + asection *target_sec = r_reloc_get_section (&values->last_loc); + if (target_sec && target_sec->output_section == sec->output_section) + { + /* Increment the virtual offset. */ + r_reloc try_loc = values->last_loc; + try_loc.virtual_offset += 4; + + /* There is a last loc that was in the same output section. */ + if (relocations_reach (rel, remaining_src_rels, &try_loc) + && move_shared_literal (sec, link_info, rel, + prop_table, ptblsize, + &try_loc, &val, target_sec_cache)) + { + values->last_loc.virtual_offset += 4; + literal_placed = TRUE; + if (!val_map) + val_map = add_value_map (values, &val, &try_loc, + final_static_link); + else + val_map->loc = try_loc; + } + } + } + + if (!literal_placed) + { + /* Nothing worked, leave the literal alone but update the last loc. */ + values->has_last_loc = TRUE; + values->last_loc = rel->r_rel; + if (!val_map) + val_map = add_value_map (values, &val, &rel->r_rel, final_static_link); + else + val_map->loc = rel->r_rel; + *last_loc_is_prev_p = TRUE; + } + + return TRUE; +} + + /* Check if the original relocations (presumably on L32R instructions) identified by reloc[0..N] can be changed to reference the literal identified by r_rel. If r_rel is out of range for any of the @@ -4626,9 +7941,8 @@ relocations_reach (reloc, remaining_relocs, r_rel) != sec->output_section) return FALSE; - /* A NULL operand means it is not a PC-relative relocation, so - the literal can be moved anywhere. */ - if (reloc[i].opnd) + /* A literal with no PC-relative relocations can be moved anywhere. */ + if (reloc[i].opnd != -1) { /* Otherwise, check to see that it fits. */ source_address = (reloc[i].source_sec->output_section->vma @@ -4638,7 +7952,8 @@ relocations_reach (reloc, remaining_relocs, r_rel) + sec->output_offset + r_rel->target_offset); - if (!pcrel_reloc_fits (reloc[i].opnd, source_address, dest_address)) + if (!pcrel_reloc_fits (reloc[i].opcode, reloc[i].opnd, + source_address, dest_address)) return FALSE; } } @@ -4647,27 +7962,222 @@ relocations_reach (reloc, remaining_relocs, r_rel) } -/* WARNING: linear search here. If the relocation are in order by - address, we can use a faster binary search. ALSO, we assume that - there is only 1 non-NONE relocation per address. */ +/* Move a literal to another literal location because it is + the same as the other literal value. */ -static Elf_Internal_Rela * -get_irel_at_offset (sec, internal_relocs, offset) +static bfd_boolean +coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map) asection *sec; - Elf_Internal_Rela *internal_relocs; - bfd_vma offset; + source_reloc *rel; + property_table_entry *prop_table; + int ptblsize; + value_map *val_map; { - unsigned i; - if (!internal_relocs) - return NULL; - for (i = 0; i < sec->reloc_count; i++) + property_table_entry *entry; + text_action *fa; + property_table_entry *the_add_entry; + int removed_diff; + xtensa_relax_info *relax_info; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + return FALSE; + + entry = elf_xtensa_find_property_entry + (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset); + if (entry && (entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM)) + return TRUE; + + /* Mark that the literal will be coalesced. */ + add_removed_literal (&relax_info->removed_list, &rel->r_rel, &val_map->loc); + + text_action_add (&relax_info->action_list, + ta_remove_literal, sec, rel->r_rel.target_offset, 4); + + /* If the section is 4-byte aligned, do not add fill. */ + if (sec->alignment_power > 2) { - Elf_Internal_Rela *irel = &internal_relocs[i]; - if (irel->r_offset == offset - && ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE) - return irel; + int fill_extra_space; + bfd_vma entry_sec_offset; + + if (entry) + entry_sec_offset = entry->address - sec->vma + entry->size; + else + entry_sec_offset = rel->r_rel.target_offset + 4; + + /* If the literal range is at the end of the section, + do not add fill. */ + fill_extra_space = 0; + the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize, + entry_sec_offset); + if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE)) + fill_extra_space = the_add_entry->size; + + fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset); + removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset, + -4, fill_extra_space); + if (fa) + adjust_fill_action (fa, removed_diff); + else + text_action_add (&relax_info->action_list, + ta_fill, sec, entry_sec_offset, removed_diff); } - return NULL; + + return TRUE; +} + + +/* Move a literal to another location. This may actually increase the + total amount of space used because of alignments so we need to do + this carefully. Also, it may make a branch go out of range. */ + +static bfd_boolean +move_shared_literal (sec, link_info, rel, prop_table, ptblsize, + target_loc, lit_value, target_sec_cache) + asection *sec; + struct bfd_link_info *link_info; + source_reloc *rel; + property_table_entry *prop_table; + int ptblsize; + const r_reloc *target_loc; + const literal_value *lit_value; + section_cache_t *target_sec_cache; +{ + property_table_entry *the_add_entry, *src_entry, *target_entry = NULL; + text_action *fa, *target_fa; + int removed_diff; + xtensa_relax_info *relax_info, *target_relax_info; + asection *target_sec; + ebb_t *ebb; + ebb_constraint ebb_table; + bfd_boolean relocs_fit; + + /* If this routine always returns FALSE, the literals that cannot be + coalesced will not be moved. */ + if (elf32xtensa_no_literal_movement) + return FALSE; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + return FALSE; + + target_sec = r_reloc_get_section (target_loc); + target_relax_info = get_xtensa_relax_info (target_sec); + + /* Literals to undefined sections may not be moved because they + must report an error. */ + if (bfd_is_und_section (target_sec)) + return FALSE; + + src_entry = elf_xtensa_find_property_entry + (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset); + + if (!section_cache_section (target_sec_cache, target_sec, link_info)) + return FALSE; + + target_entry = elf_xtensa_find_property_entry + (target_sec_cache->ptbl, target_sec_cache->pte_count, + target_sec->vma + target_loc->target_offset); + + if (!target_entry) + return FALSE; + + /* Make sure that we have not broken any branches. */ + relocs_fit = FALSE; + + init_ebb_constraint (&ebb_table); + ebb = &ebb_table.ebb; + init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents, + target_sec_cache->content_length, + target_sec_cache->ptbl, target_sec_cache->pte_count, + target_sec_cache->relocs, target_sec_cache->reloc_count); + + /* Propose to add 4 bytes + worst-case alignment size increase to + destination. */ + ebb_propose_action (&ebb_table, EBB_NO_ALIGN, 0, + ta_fill, target_loc->target_offset, + -4 - (1 << target_sec->alignment_power), TRUE); + + /* Check all of the PC-relative relocations to make sure they still fit. */ + relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, + target_sec_cache->contents, + target_sec_cache->relocs, + &ebb_table); + + if (!relocs_fit) + return FALSE; + + text_action_add_literal (&target_relax_info->action_list, + ta_add_literal, target_loc, lit_value, -4); + + if (target_sec->alignment_power > 2 && target_entry != src_entry) + { + /* May need to add or remove some fill to maintain alignment. */ + int fill_extra_space; + bfd_vma entry_sec_offset; + + entry_sec_offset = + target_entry->address - target_sec->vma + target_entry->size; + + /* If the literal range is at the end of the section, + do not add fill. */ + fill_extra_space = 0; + the_add_entry = + elf_xtensa_find_property_entry (target_sec_cache->ptbl, + target_sec_cache->pte_count, + entry_sec_offset); + if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE)) + fill_extra_space = the_add_entry->size; + + target_fa = find_fill_action (&target_relax_info->action_list, + target_sec, entry_sec_offset); + removed_diff = compute_removed_action_diff (target_fa, target_sec, + entry_sec_offset, 4, + fill_extra_space); + if (target_fa) + adjust_fill_action (target_fa, removed_diff); + else + text_action_add (&target_relax_info->action_list, + ta_fill, target_sec, entry_sec_offset, removed_diff); + } + + /* Mark that the literal will be moved to the new location. */ + add_removed_literal (&relax_info->removed_list, &rel->r_rel, target_loc); + + /* Remove the literal. */ + text_action_add (&relax_info->action_list, + ta_remove_literal, sec, rel->r_rel.target_offset, 4); + + /* If the section is 4-byte aligned, do not add fill. */ + if (sec->alignment_power > 2 && target_entry != src_entry) + { + int fill_extra_space; + bfd_vma entry_sec_offset; + + if (src_entry) + entry_sec_offset = src_entry->address - sec->vma + src_entry->size; + else + entry_sec_offset = rel->r_rel.target_offset+4; + + /* If the literal range is at the end of the section, + do not add fill. */ + fill_extra_space = 0; + the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize, + entry_sec_offset); + if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE)) + fill_extra_space = the_add_entry->size; + + fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset); + removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset, + -4, fill_extra_space); + if (fa) + adjust_fill_action (fa, removed_diff); + else + text_action_add (&relax_info->action_list, + ta_fill, sec, entry_sec_offset, removed_diff); + } + + return TRUE; } @@ -4675,9 +8185,9 @@ get_irel_at_offset (sec, internal_relocs, offset) /* Modify all of the relocations to point to the right spot, and if this is a relaxable section, delete the unwanted literals and fix the - cooked_size. */ + section size. */ -bfd_boolean +bfd_boolean relax_section (abfd, sec, link_info) bfd *abfd; asection *sec; @@ -4688,10 +8198,17 @@ relax_section (abfd, sec, link_info) bfd_byte *contents; bfd_boolean ok = TRUE; unsigned i; + bfd_boolean rv = FALSE; + bfd_boolean virtual_action; + bfd_size_type sec_size; + sec_size = bfd_get_section_limit (abfd, sec); relax_info = get_xtensa_relax_info (sec); BFD_ASSERT (relax_info); + /* First translate any of the fixes that have been added already. */ + translate_section_fixes (sec); + /* Handle property sections (e.g., literal tables) specially. */ if (xtensa_is_property_section (sec)) { @@ -4702,7 +8219,7 @@ relax_section (abfd, sec, link_info) internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); contents = retrieve_contents (abfd, sec, link_info->keep_memory); - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { ok = FALSE; goto error_return; @@ -4710,11 +8227,11 @@ relax_section (abfd, sec, link_info) if (internal_relocs) { - for (i = 0; i < sec->reloc_count; i++) + for (i = 0; i < sec->reloc_count; i++) { Elf_Internal_Rela *irel; xtensa_relax_info *target_relax_info; - bfd_vma source_offset; + bfd_vma source_offset, old_source_offset; r_reloc r_rel; unsigned r_type; asection *target_sec; @@ -4727,11 +8244,17 @@ relax_section (abfd, sec, link_info) irel = &internal_relocs[i]; source_offset = irel->r_offset; + old_source_offset = source_offset; r_type = ELF32_R_TYPE (irel->r_info); - r_reloc_init (&r_rel, abfd, irel); - - if (relax_info->is_relaxable_literal_section) + r_reloc_init (&r_rel, abfd, irel, contents, + bfd_get_section_limit (abfd, sec)); + + /* If this section could have changed then we may need to + change the relocation's offset. */ + + if (relax_info->is_relaxable_literal_section + || relax_info->is_relaxable_asm_section) { if (r_type != R_XTENSA_NONE && find_removed_literal (&relax_info->removed_list, @@ -4741,34 +8264,141 @@ relax_section (abfd, sec, link_info) if (elf_hash_table (link_info)->dynamic_sections_created) shrink_dynamic_reloc_sections (link_info, abfd, sec, irel); irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE); - irel->r_offset = offset_with_removed_literals - (&relax_info->removed_list, irel->r_offset); + irel->r_offset = offset_with_removed_text + (&relax_info->action_list, irel->r_offset); + pin_internal_relocs (sec, internal_relocs); continue; } - source_offset = - offset_with_removed_literals (&relax_info->removed_list, - irel->r_offset); + + if (r_type == R_XTENSA_ASM_SIMPLIFY) + { + text_action *action = + find_insn_action (&relax_info->action_list, + irel->r_offset); + if (action && (action->action == ta_convert_longcall + || action->action == ta_remove_longcall)) + { + bfd_reloc_status_type retval; + char *error_message = NULL; + + retval = contract_asm_expansion (contents, sec_size, + irel, &error_message); + if (retval != bfd_reloc_ok) + { + (*link_info->callbacks->reloc_dangerous) + (link_info, error_message, abfd, sec, + irel->r_offset); + goto error_return; + } + /* Update the action so that the code that moves + the contents will do the right thing. */ + if (action->action == ta_remove_longcall) + action->action = ta_remove_insn; + else + action->action = ta_none; + /* Refresh the info in the r_rel. */ + r_reloc_init (&r_rel, abfd, irel, contents, sec_size); + r_type = ELF32_R_TYPE (irel->r_info); + } + } + + source_offset = offset_with_removed_text + (&relax_info->action_list, irel->r_offset); irel->r_offset = source_offset; } + /* If the target section could have changed then + we may need to change the relocation's target offset. */ + target_sec = r_reloc_get_section (&r_rel); target_relax_info = get_xtensa_relax_info (target_sec); if (target_relax_info - && target_relax_info->is_relaxable_literal_section) + && (target_relax_info->is_relaxable_literal_section + || target_relax_info->is_relaxable_asm_section)) { - r_reloc new_rel; + r_reloc new_reloc; reloc_bfd_fix *fix; + bfd_vma addend_displacement; - translate_reloc (&r_rel, &new_rel); + translate_reloc (&r_rel, &new_reloc); + + if (r_type == R_XTENSA_DIFF8 + || r_type == R_XTENSA_DIFF16 + || r_type == R_XTENSA_DIFF32) + { + bfd_vma diff_value = 0, new_end_offset, diff_mask = 0; + + if (bfd_get_section_limit (abfd, sec) < old_source_offset) + { + (*link_info->callbacks->reloc_dangerous) + (link_info, _("invalid relocation address"), + abfd, sec, old_source_offset); + goto error_return; + } + + switch (r_type) + { + case R_XTENSA_DIFF8: + diff_value = + bfd_get_8 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: + diff_value = + bfd_get_16 (abfd, &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: + diff_value = + bfd_get_32 (abfd, &contents[old_source_offset]); + break; + } + + new_end_offset = offset_with_removed_text + (&target_relax_info->action_list, + r_rel.target_offset + diff_value); + diff_value = new_end_offset - new_reloc.target_offset; + + switch (r_type) + { + case R_XTENSA_DIFF8: + diff_mask = 0xff; + bfd_put_8 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF16: + diff_mask = 0xffff; + bfd_put_16 (abfd, diff_value, + &contents[old_source_offset]); + break; + case R_XTENSA_DIFF32: + diff_mask = 0xffffffff; + bfd_put_32 (abfd, diff_value, + &contents[old_source_offset]); + break; + } + + /* Check for overflow. */ + if ((diff_value & ~diff_mask) != 0) + { + (*link_info->callbacks->reloc_dangerous) + (link_info, _("overflow after relaxation"), + abfd, sec, old_source_offset); + goto error_return; + } + + pin_contents (sec, contents); + } /* FIXME: If the relocation still references a section in the same input file, the relocation should be modified directly instead of adding a "fix" record. */ + addend_displacement = + new_reloc.target_offset + new_reloc.virtual_offset; + fix = reloc_bfd_fix_init (sec, source_offset, r_type, 0, - r_reloc_get_section (&new_rel), - new_rel.target_offset); + r_reloc_get_section (&new_reloc), + addend_displacement, TRUE); add_fix (sec, fix); } @@ -4776,37 +8406,217 @@ relax_section (abfd, sec, link_info) } } - if (relax_info->is_relaxable_literal_section) + if ((relax_info->is_relaxable_literal_section + || relax_info->is_relaxable_asm_section) + && relax_info->action_list.head) { - /* Walk through the contents and delete literals that are not needed - anymore. */ + /* Walk through the planned actions and build up a table + of move, copy and fill records. Use the move, copy and + fill records to perform the actions once. */ + + bfd_size_type size = sec->size; + int removed = 0; + bfd_size_type final_size, copy_size, orig_insn_size; + bfd_byte *scratch = NULL; + bfd_byte *dup_contents = NULL; + bfd_size_type orig_size = size; + bfd_vma orig_dot = 0; + bfd_vma orig_dot_copied = 0; /* Byte copied already from + orig dot in physical memory. */ + bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot. */ + bfd_vma dup_dot = 0; + + text_action *action = relax_info->action_list.head; + + final_size = sec->size; + for (action = relax_info->action_list.head; action; + action = action->next) + { + final_size -= action->removed_bytes; + } + + scratch = (bfd_byte *) bfd_zmalloc (final_size); + dup_contents = (bfd_byte *) bfd_zmalloc (final_size); - unsigned long size = sec->size; - unsigned long removed = 0; + /* The dot is the current fill location. */ +#if DEBUG + print_action_list (stderr, &relax_info->action_list); +#endif - removed_literal *reloc = relax_info->removed_list.head; - for (; reloc; reloc = reloc->next) + for (action = relax_info->action_list.head; action; + action = action->next) { - unsigned long upper = sec->size; - bfd_vma start = reloc->from.target_offset + 4; - if (reloc->next) - upper = reloc->next->from.target_offset; - if (upper - start != 0) + virtual_action = FALSE; + if (action->offset > orig_dot) { - BFD_ASSERT (start <= upper); - memmove (contents + start - removed - 4, - contents + start, - upper - start ); + orig_dot += orig_dot_copied; + orig_dot_copied = 0; + orig_dot_vo = 0; + /* Out of the virtual world. */ + } + + if (action->offset > orig_dot) + { + copy_size = action->offset - orig_dot; + memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size); + orig_dot += copy_size; + dup_dot += copy_size; + BFD_ASSERT (action->offset == orig_dot); + } + else if (action->offset < orig_dot) + { + if (action->action == ta_fill + && action->offset - action->removed_bytes == orig_dot) + { + /* This is OK because the fill only effects the dup_dot. */ + } + else if (action->action == ta_add_literal) + { + /* TBD. Might need to handle this. */ + } + } + if (action->offset == orig_dot) + { + if (action->virtual_offset > orig_dot_vo) + { + if (orig_dot_vo == 0) + { + /* Need to copy virtual_offset bytes. Probably four. */ + copy_size = action->virtual_offset - orig_dot_vo; + memmove (&dup_contents[dup_dot], + &contents[orig_dot], copy_size); + orig_dot_copied = copy_size; + dup_dot += copy_size; + } + virtual_action = TRUE; + } + else + BFD_ASSERT (action->virtual_offset <= orig_dot_vo); + } + switch (action->action) + { + case ta_remove_literal: + case ta_remove_insn: + BFD_ASSERT (action->removed_bytes >= 0); + orig_dot += action->removed_bytes; + break; + + case ta_narrow_insn: + orig_insn_size = 3; + copy_size = 2; + memmove (scratch, &contents[orig_dot], orig_insn_size); + BFD_ASSERT (action->removed_bytes == 1); + rv = narrow_instruction (scratch, final_size, 0, TRUE); + BFD_ASSERT (rv); + memmove (&dup_contents[dup_dot], scratch, copy_size); + orig_dot += orig_insn_size; + dup_dot += copy_size; + break; + + case ta_fill: + if (action->removed_bytes >= 0) + orig_dot += action->removed_bytes; + else + { + /* Already zeroed in dup_contents. Just bump the + counters. */ + dup_dot += (-action->removed_bytes); + } + break; + + case ta_none: + BFD_ASSERT (action->removed_bytes == 0); + break; + + case ta_convert_longcall: + case ta_remove_longcall: + /* These will be removed or converted before we get here. */ + BFD_ASSERT (0); + break; + + case ta_widen_insn: + orig_insn_size = 2; + copy_size = 3; + memmove (scratch, &contents[orig_dot], orig_insn_size); + BFD_ASSERT (action->removed_bytes == -1); + rv = widen_instruction (scratch, final_size, 0, TRUE); + BFD_ASSERT (rv); + memmove (&dup_contents[dup_dot], scratch, copy_size); + orig_dot += orig_insn_size; + dup_dot += copy_size; + break; + + case ta_add_literal: + orig_insn_size = 0; + copy_size = 4; + BFD_ASSERT (action->removed_bytes == -4); + /* TBD -- place the literal value here and insert + into the table. */ + memset (&dup_contents[dup_dot], 0, 4); + pin_internal_relocs (sec, internal_relocs); pin_contents (sec, contents); + + if (!move_literal (abfd, link_info, sec, dup_dot, dup_contents, + relax_info, &internal_relocs, &action->value)) + goto error_return; + + if (virtual_action) + orig_dot_vo += copy_size; + + orig_dot += orig_insn_size; + dup_dot += copy_size; + break; + + default: + /* Not implemented yet. */ + BFD_ASSERT (0); + break; } - removed += 4; - size -= 4; + + size -= action->removed_bytes; + removed += action->removed_bytes; + BFD_ASSERT (dup_dot <= final_size); + BFD_ASSERT (orig_dot <= orig_size); + } + + orig_dot += orig_dot_copied; + orig_dot_copied = 0; + + if (orig_dot != orig_size) + { + copy_size = orig_size - orig_dot; + BFD_ASSERT (orig_size > orig_dot); + BFD_ASSERT (dup_dot + copy_size == final_size); + memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size); + orig_dot += copy_size; + dup_dot += copy_size; + } + BFD_ASSERT (orig_size == orig_dot); + BFD_ASSERT (final_size == dup_dot); + + /* Move the dup_contents back. */ + if (final_size > orig_size) + { + /* Contents need to be reallocated. Swap the dup_contents into + contents. */ + sec->contents = dup_contents; + free (contents); + contents = dup_contents; + pin_contents (sec, contents); + } + else + { + BFD_ASSERT (final_size <= orig_size); + memset (contents, 0, orig_size); + memcpy (contents, dup_contents, final_size); + free (dup_contents); } + free (scratch); + pin_contents (sec, contents); - /* Change the section size. */ - sec->size = size; + sec->size = final_size; } - + error_return: release_internal_relocs (sec, internal_relocs); release_contents (sec, contents); @@ -4814,6 +8624,117 @@ relax_section (abfd, sec, link_info) } +static bfd_boolean +translate_section_fixes (sec) + asection *sec; +{ + xtensa_relax_info *relax_info; + reloc_bfd_fix *r; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + return TRUE; + + for (r = relax_info->fix_list; r != NULL; r = r->next) + if (!translate_reloc_bfd_fix (r)) + return FALSE; + + return TRUE; +} + + +/* Translate a fix given the mapping in the relax info for the target + section. If it has already been translated, no work is required. */ + +static bfd_boolean +translate_reloc_bfd_fix (fix) + reloc_bfd_fix *fix; +{ + reloc_bfd_fix new_fix; + asection *sec; + xtensa_relax_info *relax_info; + removed_literal *removed; + bfd_vma new_offset, target_offset; + + if (fix->translated) + return TRUE; + + sec = fix->target_sec; + target_offset = fix->target_offset; + + relax_info = get_xtensa_relax_info (sec); + if (!relax_info) + { + fix->translated = TRUE; + return TRUE; + } + + new_fix = *fix; + + /* The fix does not need to be translated if the section cannot change. */ + if (!relax_info->is_relaxable_literal_section + && !relax_info->is_relaxable_asm_section) + { + fix->translated = TRUE; + return TRUE; + } + + /* If the literal has been moved and this relocation was on an + opcode, then the relocation should move to the new literal + location. Otherwise, the relocation should move within the + section. */ + + removed = FALSE; + if (is_operand_relocation (fix->src_type)) + { + /* Check if the original relocation is against a literal being + removed. */ + removed = find_removed_literal (&relax_info->removed_list, + target_offset); + } + + if (removed) + { + asection *new_sec; + + /* The fact that there is still a relocation to this literal indicates + that the literal is being coalesced, not simply removed. */ + BFD_ASSERT (removed->to.abfd != NULL); + + /* This was moved to some other address (possibly another section). */ + new_sec = r_reloc_get_section (&removed->to); + if (new_sec != sec) + { + sec = new_sec; + relax_info = get_xtensa_relax_info (sec); + if (!relax_info || + (!relax_info->is_relaxable_literal_section + && !relax_info->is_relaxable_asm_section)) + { + target_offset = removed->to.target_offset; + new_fix.target_sec = new_sec; + new_fix.target_offset = target_offset; + new_fix.translated = TRUE; + *fix = new_fix; + return TRUE; + } + } + target_offset = removed->to.target_offset; + new_fix.target_sec = new_sec; + } + + /* The target address may have been moved within its section. */ + new_offset = offset_with_removed_text (&relax_info->action_list, + target_offset); + + new_fix.target_offset = new_offset; + new_fix.target_offset = new_offset; + new_fix.translated = TRUE; + *fix = new_fix; + return TRUE; +} + + /* Fix up a relocation to take account of removed literals. */ static void @@ -4824,7 +8745,7 @@ translate_reloc (orig_rel, new_rel) asection *sec; xtensa_relax_info *relax_info; removed_literal *removed; - unsigned long new_offset; + bfd_vma new_offset, target_offset, removed_bytes; *new_rel = *orig_rel; @@ -4835,13 +8756,21 @@ translate_reloc (orig_rel, new_rel) relax_info = get_xtensa_relax_info (sec); BFD_ASSERT (relax_info); - if (!relax_info->is_relaxable_literal_section) + if (!relax_info->is_relaxable_literal_section + && !relax_info->is_relaxable_asm_section) return; - /* Check if the original relocation is against a literal being removed. */ - removed = find_removed_literal (&relax_info->removed_list, - orig_rel->target_offset); - if (removed) + target_offset = orig_rel->target_offset; + + removed = FALSE; + if (is_operand_relocation (ELF32_R_TYPE (orig_rel->rela.r_info))) + { + /* Check if the original relocation is against a literal being + removed. */ + removed = find_removed_literal (&relax_info->removed_list, + target_offset); + } + if (removed && removed->to.abfd) { asection *new_sec; @@ -4849,25 +8778,30 @@ translate_reloc (orig_rel, new_rel) that the literal is being coalesced, not simply removed. */ BFD_ASSERT (removed->to.abfd != NULL); - /* This was moved to some other address (possibly in another section). */ + /* This was moved to some other address + (possibly in another section). */ *new_rel = removed->to; new_sec = r_reloc_get_section (new_rel); - if (new_sec != sec) + if (new_sec != sec) { sec = new_sec; relax_info = get_xtensa_relax_info (sec); - if (!relax_info || !relax_info->is_relaxable_literal_section) + if (!relax_info + || (!relax_info->is_relaxable_literal_section + && !relax_info->is_relaxable_asm_section)) return; } + target_offset = new_rel->target_offset; } /* ...and the target address may have been moved within its section. */ - new_offset = offset_with_removed_literals (&relax_info->removed_list, - new_rel->target_offset); + new_offset = offset_with_removed_text (&relax_info->action_list, + target_offset); /* Modify the offset and addend. */ + removed_bytes = target_offset - new_offset; new_rel->target_offset = new_offset; - new_rel->rela.r_addend += (new_offset - new_rel->target_offset); + new_rel->rela.r_addend -= removed_bytes; } @@ -4977,12 +8911,149 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel) } +/* Take an r_rel and move it to another section. This usually + requires extending the interal_relocation array and pinning it. If + the original r_rel is from the same BFD, we can complete this here. + Otherwise, we add a fix record to let the final link fix the + appropriate address. Contents and internal relocations for the + section must be pinned after calling this routine. */ + +static bfd_boolean +move_literal (abfd, link_info, sec, offset, contents, relax_info, + internal_relocs_p, lit) + bfd *abfd; + struct bfd_link_info *link_info; + asection *sec; + bfd_vma offset; + bfd_byte *contents; + xtensa_relax_info *relax_info; + Elf_Internal_Rela **internal_relocs_p; + const literal_value *lit; +{ + Elf_Internal_Rela *new_relocs = NULL; + size_t new_relocs_count = 0; + Elf_Internal_Rela this_rela; + const r_reloc *r_rel; + + r_rel = &lit->r_rel; + BFD_ASSERT (elf_section_data (sec)->relocs == *internal_relocs_p); + + if (r_reloc_is_const (r_rel)) + bfd_put_32 (abfd, lit->value, contents + offset); + else + { + int r_type; + unsigned i; + asection *target_sec; + reloc_bfd_fix *fix; + unsigned insert_at; + + r_type = ELF32_R_TYPE (r_rel->rela.r_info); + target_sec = r_reloc_get_section (r_rel); + + /* This is the difficult case. We have to create a fix up. */ + this_rela.r_offset = offset; + this_rela.r_info = ELF32_R_INFO (0, r_type); + this_rela.r_addend = + r_rel->target_offset - r_reloc_get_target_offset (r_rel); + bfd_put_32 (abfd, lit->value, contents + offset); + + /* Currently, we cannot move relocations during a relocatable link. */ + BFD_ASSERT (!link_info->relocatable); + fix = reloc_bfd_fix_init (sec, offset, r_type, r_rel->abfd, + r_reloc_get_section (r_rel), + r_rel->target_offset + r_rel->virtual_offset, + FALSE); + /* We also need to mark that relocations are needed here. */ + sec->flags |= SEC_RELOC; + + translate_reloc_bfd_fix (fix); + /* This fix has not yet been translated. */ + add_fix (sec, fix); + + /* Add the relocation. If we have already allocated our own + space for the relocations and we have room for more, then use + it. Otherwise, allocate new space and move the literals. */ + insert_at = sec->reloc_count; + for (i = 0; i < sec->reloc_count; ++i) + { + if (this_rela.r_offset < (*internal_relocs_p)[i].r_offset) + { + insert_at = i; + break; + } + } + + if (*internal_relocs_p != relax_info->allocated_relocs + || sec->reloc_count + 1 > relax_info->allocated_relocs_count) + { + BFD_ASSERT (relax_info->allocated_relocs == NULL + || sec->reloc_count == relax_info->relocs_count); + + if (relax_info->allocated_relocs_count == 0) + new_relocs_count = (sec->reloc_count + 2) * 2; + else + new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2; + + new_relocs = (Elf_Internal_Rela *) + bfd_zmalloc (sizeof (Elf_Internal_Rela) * (new_relocs_count)); + if (!new_relocs) + return FALSE; + + /* We could handle this more quickly by finding the split point. */ + if (insert_at != 0) + memcpy (new_relocs, *internal_relocs_p, + insert_at * sizeof (Elf_Internal_Rela)); + + new_relocs[insert_at] = this_rela; + + if (insert_at != sec->reloc_count) + memcpy (new_relocs + insert_at + 1, + (*internal_relocs_p) + insert_at, + (sec->reloc_count - insert_at) + * sizeof (Elf_Internal_Rela)); + + if (*internal_relocs_p != relax_info->allocated_relocs) + { + /* The first time we re-allocate, we can only free the + old relocs if they were allocated with bfd_malloc. + This is not true when keep_memory is in effect. */ + if (!link_info->keep_memory) + free (*internal_relocs_p); + } + else + free (*internal_relocs_p); + relax_info->allocated_relocs = new_relocs; + relax_info->allocated_relocs_count = new_relocs_count; + elf_section_data (sec)->relocs = new_relocs; + sec->reloc_count++; + relax_info->relocs_count = sec->reloc_count; + *internal_relocs_p = new_relocs; + } + else + { + if (insert_at != sec->reloc_count) + { + unsigned idx; + for (idx = sec->reloc_count; idx > insert_at; idx--) + (*internal_relocs_p)[idx] = (*internal_relocs_p)[idx-1]; + } + (*internal_relocs_p)[insert_at] = this_rela; + sec->reloc_count++; + if (relax_info->allocated_relocs) + relax_info->relocs_count = sec->reloc_count; + } + } + return TRUE; +} + + /* This is similar to relax_section except that when a target is moved, we shift addresses up. We also need to modify the size. This algorithm does NOT allow for relocations into the middle of the property sections. */ -static bfd_boolean +static bfd_boolean relax_property_section (abfd, sec, link_info) bfd *abfd; asection *sec; @@ -4992,25 +9063,36 @@ relax_property_section (abfd, sec, link_info) bfd_byte *contents; unsigned i, nexti; bfd_boolean ok = TRUE; + bfd_boolean is_full_prop_section; + size_t last_zfill_target_offset = 0; + asection *last_zfill_target_sec = NULL; + bfd_size_type sec_size; + sec_size = bfd_get_section_limit (abfd, sec); internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); contents = retrieve_contents (abfd, sec, link_info->keep_memory); - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { ok = FALSE; goto error_return; } - if (internal_relocs) + is_full_prop_section = + ((strcmp (sec->name, XTENSA_PROP_SEC_NAME) == 0) + || (strncmp (sec->name, ".gnu.linkonce.prop.", + sizeof ".gnu.linkonce.prop." - 1) == 0)); + + if (internal_relocs) { - for (i = 0; i < sec->reloc_count; i++) + for (i = 0; i < sec->reloc_count; i++) { Elf_Internal_Rela *irel; xtensa_relax_info *target_relax_info; - r_reloc r_rel; unsigned r_type; asection *target_sec; + literal_value val; + bfd_byte *size_p, *flags_p; /* Locally change the source address. Translate the target to the new target address. @@ -5023,42 +9105,88 @@ relax_property_section (abfd, sec, link_info) if (r_type == R_XTENSA_NONE) continue; - r_reloc_init (&r_rel, abfd, irel); + /* Find the literal value. */ + r_reloc_init (&val.r_rel, abfd, irel, contents, sec_size); + size_p = &contents[irel->r_offset + 4]; + flags_p = NULL; + if (is_full_prop_section) + { + flags_p = &contents[irel->r_offset + 8]; + BFD_ASSERT (irel->r_offset + 12 <= sec_size); + } + else + BFD_ASSERT (irel->r_offset + 8 <= sec_size); - target_sec = r_reloc_get_section (&r_rel); + target_sec = r_reloc_get_section (&val.r_rel); target_relax_info = get_xtensa_relax_info (target_sec); if (target_relax_info - && target_relax_info->is_relaxable_literal_section) + && (target_relax_info->is_relaxable_literal_section + || target_relax_info->is_relaxable_asm_section )) { /* Translate the relocation's destination. */ - bfd_vma new_offset; - bfd_vma new_end_offset; - bfd_byte *size_p; + bfd_vma new_offset, new_end_offset; long old_size, new_size; - new_offset = - offset_with_removed_literals (&target_relax_info->removed_list, - r_rel.target_offset); + new_offset = offset_with_removed_text + (&target_relax_info->action_list, val.r_rel.target_offset); /* Assert that we are not out of bounds. */ - size_p = &contents[irel->r_offset + 4]; - old_size = bfd_get_32 (abfd, &contents[irel->r_offset + 4]); + old_size = bfd_get_32 (abfd, size_p); + + if (old_size == 0) + { + /* Only the first zero-sized unreachable entry is + allowed to expand. In this case the new offset + should be the offset before the fill and the new + size is the expansion size. For other zero-sized + entries the resulting size should be zero with an + offset before or after the fill address depending + on whether the expanding unreachable entry + preceeds it. */ + if (last_zfill_target_sec + && last_zfill_target_sec == target_sec + && last_zfill_target_offset == val.r_rel.target_offset) + new_end_offset = new_offset; + else + { + new_end_offset = new_offset; + new_offset = offset_with_removed_text_before_fill + (&target_relax_info->action_list, + val.r_rel.target_offset); + + /* If it is not unreachable and we have not yet + seen an unreachable at this address, place it + before the fill address. */ + if (!flags_p + || (bfd_get_32 (abfd, flags_p) + & XTENSA_PROP_UNREACHABLE) == 0) + new_end_offset = new_offset; + else + { + last_zfill_target_sec = target_sec; + last_zfill_target_offset = val.r_rel.target_offset; + } + } + } + else + { + new_end_offset = offset_with_removed_text_before_fill + (&target_relax_info->action_list, + val.r_rel.target_offset + old_size); + } - new_end_offset = - offset_with_removed_literals (&target_relax_info->removed_list, - r_rel.target_offset + old_size); - new_size = new_end_offset - new_offset; + if (new_size != old_size) { bfd_put_32 (abfd, new_size, size_p); pin_contents (sec, contents); } - - if (new_offset != r_rel.target_offset) + + if (new_offset != val.r_rel.target_offset) { - bfd_vma diff = new_offset - r_rel.target_offset; + bfd_vma diff = new_offset - val.r_rel.target_offset; irel->r_addend += diff; pin_internal_relocs (sec, internal_relocs); } @@ -5070,12 +9198,22 @@ relax_property_section (abfd, sec, link_info) finish_dynamic_sections() but at that point it's too late to reclaim the space in the output section, so we do this twice. */ - if (internal_relocs) + if (internal_relocs && (!link_info->relocatable + || strcmp (sec->name, XTENSA_LIT_SEC_NAME) == 0)) { Elf_Internal_Rela *last_irel = NULL; int removed_bytes = 0; bfd_vma offset, last_irel_offset; bfd_vma section_size; + bfd_size_type entry_size; + flagword predef_flags; + + if (is_full_prop_section) + entry_size = 12; + else + entry_size = 8; + + predef_flags = xtensa_get_property_predef_flags (sec); /* Walk over memory and irels at the same time. This REQUIRES that the internal_relocs be sorted by offset. */ @@ -5088,13 +9226,14 @@ relax_property_section (abfd, sec, link_info) last_irel_offset = (bfd_vma) -1; section_size = sec->size; - BFD_ASSERT (section_size % 8 == 0); + BFD_ASSERT (section_size % entry_size == 0); - for (offset = 0; offset < section_size; offset += 8) + for (offset = 0; offset < section_size; offset += entry_size) { Elf_Internal_Rela *irel, *next_irel; bfd_vma bytes_to_remove, size, actual_offset; bfd_boolean remove_this_irel; + flagword flags; irel = NULL; next_irel = NULL; @@ -5132,28 +9271,38 @@ relax_property_section (abfd, sec, link_info) actual_offset = offset - removed_bytes; size = bfd_get_32 (abfd, &contents[actual_offset + 4]); + if (is_full_prop_section) + flags = bfd_get_32 (abfd, &contents[actual_offset + 8]); + else + flags = predef_flags; + /* Check that the irels are sorted by offset, with only one per address. */ BFD_ASSERT (!irel || (int) irel->r_offset > (int) last_irel_offset); BFD_ASSERT (!next_irel || next_irel->r_offset > irel->r_offset); - /* Make sure there isn't a reloc on the size field. */ - if (irel && irel->r_offset == offset + 4) + /* Make sure there aren't relocs on the size or flag fields. */ + if ((irel && irel->r_offset == offset + 4) + || (is_full_prop_section + && irel && irel->r_offset == offset + 8)) { irel->r_offset -= removed_bytes; last_irel_offset = irel->r_offset; } - else if (next_irel && next_irel->r_offset == offset + 4) + else if (next_irel && (next_irel->r_offset == offset + 4 + || (is_full_prop_section + && next_irel->r_offset == offset + 8))) { nexti += 1; irel->r_offset -= removed_bytes; next_irel->r_offset -= removed_bytes; last_irel_offset = next_irel->r_offset; } - else if (size == 0) + else if (size == 0 && (flags & XTENSA_PROP_ALIGN) == 0 + && (flags & XTENSA_PROP_UNREACHABLE) == 0) { - /* Always remove entries with zero size. */ - bytes_to_remove = 8; + /* Always remove entries with zero size and no alignment. */ + bytes_to_remove = entry_size; if (irel && irel->r_offset == offset) { remove_this_irel = TRUE; @@ -5168,23 +9317,32 @@ relax_property_section (abfd, sec, link_info) { if (last_irel) { - bfd_vma old_size = + flagword old_flags; + bfd_vma old_size = bfd_get_32 (abfd, &contents[last_irel->r_offset + 4]); - bfd_vma old_address = - (last_irel->r_addend + bfd_vma old_address = + (last_irel->r_addend + bfd_get_32 (abfd, &contents[last_irel->r_offset])); - bfd_vma new_address = - (irel->r_addend + bfd_vma new_address = + (irel->r_addend + bfd_get_32 (abfd, &contents[actual_offset])); - - if ((ELF32_R_SYM (irel->r_info) == - ELF32_R_SYM (last_irel->r_info)) - && (old_address + old_size == new_address)) + if (is_full_prop_section) + old_flags = bfd_get_32 + (abfd, &contents[last_irel->r_offset + 8]); + else + old_flags = predef_flags; + + if ((ELF32_R_SYM (irel->r_info) + == ELF32_R_SYM (last_irel->r_info)) + && old_address + old_size == new_address + && old_flags == flags + && (old_flags & XTENSA_PROP_INSN_BRANCH_TARGET) == 0 + && (old_flags & XTENSA_PROP_INSN_LOOP_TARGET) == 0) { - /* fix the old size */ + /* Fix the old size. */ bfd_put_32 (abfd, old_size + size, &contents[last_irel->r_offset + 4]); - bytes_to_remove = 8; + bytes_to_remove = entry_size; remove_this_irel = TRUE; } else @@ -5207,14 +9365,14 @@ relax_property_section (abfd, sec, link_info) if (bytes_to_remove != 0) { removed_bytes += bytes_to_remove; - if (offset + 8 < section_size) + if (offset + bytes_to_remove < section_size) memmove (&contents[actual_offset], - &contents[actual_offset+8], - section_size - offset - 8); + &contents[actual_offset + bytes_to_remove], + section_size - offset - bytes_to_remove); } } - if (removed_bytes) + if (removed_bytes) { /* Clear the removed bytes. */ memset (&contents[section_size - removed_bytes], 0, removed_bytes); @@ -5246,7 +9404,7 @@ relax_property_section (abfd, sec, link_info) /* Change symbol values to account for removed literals. */ -bfd_boolean +bfd_boolean relax_section_symbols (abfd, sec) bfd *abfd; asection *sec; @@ -5260,7 +9418,8 @@ relax_section_symbols (abfd, sec) relax_info = get_xtensa_relax_info (sec); BFD_ASSERT (relax_info); - if (!relax_info->is_relaxable_literal_section) + if (!relax_info->is_relaxable_literal_section + && !relax_info->is_relaxable_asm_section) return TRUE; sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec); @@ -5278,10 +9437,19 @@ relax_section_symbols (abfd, sec) if (isym->st_shndx == sec_shndx) { - bfd_vma new_address = offset_with_removed_literals - (&relax_info->removed_list, isym->st_value); - if (new_address != isym->st_value) - isym->st_value = new_address; + bfd_vma new_address = offset_with_removed_text + (&relax_info->action_list, isym->st_value); + bfd_vma new_size = isym->st_size; + + if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC) + { + bfd_vma new_end = offset_with_removed_text + (&relax_info->action_list, isym->st_value + isym->st_size); + new_size = new_end - new_address; + } + + isym->st_value = new_address; + isym->st_size = new_size; } } @@ -5299,10 +9467,20 @@ relax_section_symbols (abfd, sec) || sym_hash->root.type == bfd_link_hash_defweak) && sym_hash->root.u.def.section == sec) { - bfd_vma new_address = offset_with_removed_literals - (&relax_info->removed_list, sym_hash->root.u.def.value); - if (new_address != sym_hash->root.u.def.value) - sym_hash->root.u.def.value = new_address; + bfd_vma new_address = offset_with_removed_text + (&relax_info->action_list, sym_hash->root.u.def.value); + bfd_vma new_size = sym_hash->size; + + if (sym_hash->type == STT_FUNC) + { + bfd_vma new_end = offset_with_removed_text + (&relax_info->action_list, + sym_hash->root.u.def.value + sym_hash->size); + new_size = new_end - new_address; + } + + sym_hash->root.u.def.value = new_address; + sym_hash->size = new_size; } } @@ -5312,37 +9490,41 @@ relax_section_symbols (abfd, sec) /* "Fix" handling functions, called while performing relocations. */ -static void -do_fix_for_relocatable_link (rel, input_bfd, input_section) +static bfd_boolean +do_fix_for_relocatable_link (rel, input_bfd, input_section, contents) Elf_Internal_Rela *rel; bfd *input_bfd; asection *input_section; + bfd_byte *contents; { r_reloc r_rel; asection *sec, *old_sec; bfd_vma old_offset; int r_type = ELF32_R_TYPE (rel->r_info); - reloc_bfd_fix *fix_list; reloc_bfd_fix *fix; if (r_type == R_XTENSA_NONE) - return; - - fix_list = (get_xtensa_relax_info (input_section))->fix_list; - if (fix_list == NULL) - return; + return TRUE; - fix = get_bfd_fix (fix_list, input_section, rel->r_offset, r_type); - if (fix == NULL) - return; + fix = get_bfd_fix (input_section, rel->r_offset, r_type); + if (!fix) + return TRUE; - r_reloc_init (&r_rel, input_bfd, rel); + r_reloc_init (&r_rel, input_bfd, rel, contents, + bfd_get_section_limit (input_bfd, input_section)); old_sec = r_reloc_get_section (&r_rel); - old_offset = r_reloc_get_target_offset (&r_rel); - - if (old_sec == NULL || !r_reloc_is_defined (&r_rel)) + old_offset = r_rel.target_offset; + + if (!old_sec || !r_reloc_is_defined (&r_rel)) { - BFD_ASSERT (r_type == R_XTENSA_ASM_EXPAND); + if (r_type != R_XTENSA_ASM_EXPAND) + { + (*_bfd_error_handler) + (_("%B(%A+0x%lx): unexpected fix for %s relocation"), + input_bfd, input_section, rel->r_offset, + elf_howto_table[r_type].name); + return FALSE; + } /* Leave it be. Resolution will happen in a later stage. */ } else @@ -5351,35 +9533,45 @@ do_fix_for_relocatable_link (rel, input_bfd, input_section) rel->r_addend += ((sec->output_offset + fix->target_offset) - (old_sec->output_offset + old_offset)); } + return TRUE; } static void -do_fix_for_final_link (rel, input_section, relocationp) +do_fix_for_final_link (rel, input_bfd, input_section, contents, relocationp) Elf_Internal_Rela *rel; + bfd *input_bfd; asection *input_section; + bfd_byte *contents; bfd_vma *relocationp; { asection *sec; int r_type = ELF32_R_TYPE (rel->r_info); - reloc_bfd_fix *fix_list; reloc_bfd_fix *fix; + bfd_vma fixup_diff; if (r_type == R_XTENSA_NONE) return; - fix_list = (get_xtensa_relax_info (input_section))->fix_list; - if (fix_list == NULL) - return; - - fix = get_bfd_fix (fix_list, input_section, rel->r_offset, r_type); - if (fix == NULL) + fix = get_bfd_fix (input_section, rel->r_offset, r_type); + if (!fix) return; sec = fix->target_sec; + + fixup_diff = rel->r_addend; + if (elf_howto_table[fix->src_type].partial_inplace) + { + bfd_vma inplace_val; + BFD_ASSERT (fix->src_offset + < bfd_get_section_limit (input_bfd, input_section)); + inplace_val = bfd_get_32 (input_bfd, &contents[fix->src_offset]); + fixup_diff += inplace_val; + } + *relocationp = (sec->output_section->vma + sec->output_offset - + fix->target_offset - rel->r_addend); + + fix->target_offset - fixup_diff); } @@ -5430,7 +9622,7 @@ get_elf_r_symndx_section (abfd, r_symndx) { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; asection *target_sec = NULL; - if (r_symndx < symtab_hdr->sh_info) + if (r_symndx < symtab_hdr->sh_info) { Elf_Internal_Sym *isymbuf; unsigned int section_index; @@ -5446,7 +9638,7 @@ get_elf_r_symndx_section (abfd, r_symndx) target_sec = bfd_abs_section_ptr; else if (section_index == SHN_COMMON) target_sec = bfd_com_section_ptr; - else + else /* Who knows? */ target_sec = NULL; } @@ -5492,7 +9684,7 @@ get_elf_r_symndx_hash_entry (abfd, r_symndx) if (r_symndx < symtab_hdr->sh_info) return NULL; - + indx = r_symndx - symtab_hdr->sh_info; h = elf_sym_hashes (abfd)[indx]; while (h->root.type == bfd_link_hash_indirect @@ -5512,7 +9704,7 @@ get_elf_r_symndx_offset (abfd, r_symndx) Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; bfd_vma offset = 0; - if (r_symndx < symtab_hdr->sh_info) + if (r_symndx < symtab_hdr->sh_info) { Elf_Internal_Sym *isymbuf; isymbuf = retrieve_local_syms (abfd); @@ -5536,21 +9728,40 @@ get_elf_r_symndx_offset (abfd, r_symndx) static bfd_boolean -pcrel_reloc_fits (opnd, self_address, dest_address) - xtensa_operand opnd; +is_reloc_sym_weak (abfd, rel) + bfd *abfd; + Elf_Internal_Rela *rel; +{ + unsigned long r_symndx = ELF32_R_SYM (rel->r_info); + struct elf_link_hash_entry *h; + + h = get_elf_r_symndx_hash_entry (abfd, r_symndx); + if (h && h->root.type == bfd_link_hash_defweak) + return TRUE; + return FALSE; +} + + +static bfd_boolean +pcrel_reloc_fits (opc, opnd, self_address, dest_address) + xtensa_opcode opc; + int opnd; bfd_vma self_address; bfd_vma dest_address; { - uint32 new_address = - xtensa_operand_do_reloc (opnd, dest_address, self_address); - return (xtensa_operand_encode (opnd, &new_address) - == xtensa_encode_result_ok); + xtensa_isa isa = xtensa_default_isa; + uint32 valp = dest_address; + if (xtensa_operand_do_reloc (isa, opc, opnd, &valp, self_address) + || xtensa_operand_encode (isa, opc, opnd, &valp)) + return FALSE; + return TRUE; } static int linkonce_len = sizeof (".gnu.linkonce.") - 1; static int insn_sec_len = sizeof (XTENSA_INSN_SEC_NAME) - 1; static int lit_sec_len = sizeof (XTENSA_LIT_SEC_NAME) - 1; +static int prop_sec_len = sizeof (XTENSA_PROP_SEC_NAME) - 1; static bfd_boolean @@ -5558,13 +9769,14 @@ xtensa_is_property_section (sec) asection *sec; { if (strncmp (XTENSA_INSN_SEC_NAME, sec->name, insn_sec_len) == 0 - || strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0) + || strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0 + || strncmp (XTENSA_PROP_SEC_NAME, sec->name, prop_sec_len) == 0) return TRUE; if (strncmp (".gnu.linkonce.", sec->name, linkonce_len) == 0 - && (sec->name[linkonce_len] == 'x' - || sec->name[linkonce_len] == 'p') - && sec->name[linkonce_len + 1] == '.') + && (strncmp (&sec->name[linkonce_len], "x.", 2) == 0 + || strncmp (&sec->name[linkonce_len], "p.", 2) == 0 + || strncmp (&sec->name[linkonce_len], "prop.", 5) == 0)) return TRUE; return FALSE; @@ -5587,25 +9799,41 @@ xtensa_is_littable_section (sec) } -static bfd_boolean -is_literal_section (sec) - asection *sec; +static int +internal_reloc_compare (ap, bp) + const PTR ap; + const PTR bp; { - /* FIXME: the current definition of this leaves a lot to be desired.... */ - if (sec == NULL || sec->name == NULL) - return FALSE; - return (strstr (sec->name, "literal") != NULL); + const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap; + const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp; + + if (a->r_offset != b->r_offset) + return (a->r_offset - b->r_offset); + + /* We don't need to sort on these criteria for correctness, + but enforcing a more strict ordering prevents unstable qsort + from behaving differently with different implementations. + Without the code below we get correct but different results + on Solaris 2.7 and 2.8. We would like to always produce the + same results no matter the host. */ + + if (a->r_info != b->r_info) + return (a->r_info - b->r_info); + + return (a->r_addend - b->r_addend); } static int -internal_reloc_compare (ap, bp) +internal_reloc_matches (ap, bp) const PTR ap; const PTR bp; { const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap; const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp; + /* Check if one entry overlaps with the other; this shouldn't happen + except when searching for a match. */ return (a->r_offset - b->r_offset); } @@ -5619,26 +9847,28 @@ xtensa_get_property_section_name (sec, base_name) { char *prop_sec_name; const char *suffix; - char linkonce_kind = 0; + char *linkonce_kind = 0; if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0) - linkonce_kind = 'x'; + linkonce_kind = "x"; else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0) - linkonce_kind = 'p'; + linkonce_kind = "p"; + else if (strcmp (base_name, XTENSA_PROP_SEC_NAME) == 0) + linkonce_kind = "prop."; else abort (); - prop_sec_name = (char *) bfd_malloc (strlen (sec->name) + 1); + prop_sec_name = (char *) bfd_malloc (strlen (sec->name) + + strlen (linkonce_kind) + 1); memcpy (prop_sec_name, ".gnu.linkonce.", linkonce_len); - prop_sec_name[linkonce_len] = linkonce_kind; - prop_sec_name[linkonce_len + 1] = '.'; + strcpy (prop_sec_name + linkonce_len, linkonce_kind); suffix = sec->name + linkonce_len; /* For backward compatibility, replace "t." instead of inserting - the new linkonce_kind. */ - if (strncmp (suffix, "t.", 2) == 0) - suffix += 2; - strcpy (prop_sec_name + linkonce_len + 2, suffix); + the new linkonce_kind (but not for "prop" sections). */ + if (strncmp (suffix, "t.", 2) == 0 && linkonce_kind[1] == '.') + suffix += 2; + strcat (prop_sec_name + linkonce_len, suffix); return prop_sec_name; } @@ -5646,6 +9876,26 @@ xtensa_get_property_section_name (sec, base_name) return strdup (base_name); } + +flagword +xtensa_get_property_predef_flags (sec) + asection *sec; +{ + if (strcmp (sec->name, XTENSA_INSN_SEC_NAME) == 0 + || strncmp (sec->name, ".gnu.linkonce.x.", + sizeof ".gnu.linkonce.x." - 1) == 0) + return (XTENSA_PROP_INSN + | XTENSA_PROP_INSN_NO_TRANSFORM + | XTENSA_PROP_INSN_NO_REORDER); + + if (xtensa_is_littable_section (sec)) + return (XTENSA_PROP_LITERAL + | XTENSA_PROP_INSN_NO_TRANSFORM + | XTENSA_PROP_INSN_NO_REORDER); + + return 0; +} + /* Other functions called directly by the linker. */ @@ -5661,6 +9911,9 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure) bfd_byte *contents; unsigned i; bfd_boolean ok = TRUE; + bfd_size_type sec_size; + + sec_size = bfd_get_section_limit (abfd, sec); /* ".plt*" sections have no explicit relocations but they contain L32R instructions that reference the corresponding ".got.plt*" sections. */ @@ -5688,43 +9941,43 @@ xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure) /* Assume worst-case offsets: L32R at the very end of the ".plt" section referencing a literal at the very beginning of ".got.plt". This is very close to the real dependence, anyway. */ - (*callback) (sec, sec->size, sgotplt, 0, closure); + (*callback) (sec, sec_size, sgotplt, 0, closure); } internal_relocs = retrieve_internal_relocs (abfd, sec, link_info->keep_memory); if (internal_relocs == NULL - || sec->reloc_count == 0) + || sec->reloc_count == 0) return ok; /* Cache the contents for the duration of this scan. */ contents = retrieve_contents (abfd, sec, link_info->keep_memory); - if (contents == NULL && sec->size != 0) + if (contents == NULL && sec_size != 0) { ok = FALSE; goto error_return; } - if (xtensa_default_isa == NULL) - xtensa_isa_init (); + if (!xtensa_default_isa) + xtensa_default_isa = xtensa_isa_init (0, 0); - for (i = 0; i < sec->reloc_count; i++) + for (i = 0; i < sec->reloc_count; i++) { Elf_Internal_Rela *irel = &internal_relocs[i]; - if (is_l32r_relocation (sec, contents, irel)) + if (is_l32r_relocation (abfd, sec, contents, irel)) { r_reloc l32r_rel; asection *target_sec; bfd_vma target_offset; - - r_reloc_init (&l32r_rel, abfd, irel); + + r_reloc_init (&l32r_rel, abfd, irel, contents, sec_size); target_sec = NULL; target_offset = 0; /* L32Rs must be local to the input file. */ if (r_reloc_is_defined (&l32r_rel)) { target_sec = r_reloc_get_section (&l32r_rel); - target_offset = r_reloc_get_target_offset (&l32r_rel); + target_offset = l32r_rel.target_offset; } (*callback) (sec, irel->r_offset, target_sec, target_offset, closure); @@ -5761,7 +10014,7 @@ static struct bfd_elf_special_section const elf_xtensa_special_sections[]= value so that pre-T1040 tools can read the files. As soon as we stop caring about pre-T1040 tools, the following two values should be swapped. At the same time, any other code that uses EM_XTENSA_OLD - (e.g., prep_headers() in elf.c) should be changed to use EM_XTENSA. */ + should be changed to use EM_XTENSA. */ #define ELF_MACHINE_CODE EM_XTENSA_OLD #define ELF_MACHINE_ALT1 EM_XTENSA diff --git a/bfd/libbfd.h b/bfd/libbfd.h index c079a6a..c811de5 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1650,6 +1650,39 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_XTENSA_JMP_SLOT", "BFD_RELOC_XTENSA_RELATIVE", "BFD_RELOC_XTENSA_PLT", + "BFD_RELOC_XTENSA_DIFF8", + "BFD_RELOC_XTENSA_DIFF16", + "BFD_RELOC_XTENSA_DIFF32", + "BFD_RELOC_XTENSA_SLOT0_OP", + "BFD_RELOC_XTENSA_SLOT1_OP", + "BFD_RELOC_XTENSA_SLOT2_OP", + "BFD_RELOC_XTENSA_SLOT3_OP", + "BFD_RELOC_XTENSA_SLOT4_OP", + "BFD_RELOC_XTENSA_SLOT5_OP", + "BFD_RELOC_XTENSA_SLOT6_OP", + "BFD_RELOC_XTENSA_SLOT7_OP", + "BFD_RELOC_XTENSA_SLOT8_OP", + "BFD_RELOC_XTENSA_SLOT9_OP", + "BFD_RELOC_XTENSA_SLOT10_OP", + "BFD_RELOC_XTENSA_SLOT11_OP", + "BFD_RELOC_XTENSA_SLOT12_OP", + "BFD_RELOC_XTENSA_SLOT13_OP", + "BFD_RELOC_XTENSA_SLOT14_OP", + "BFD_RELOC_XTENSA_SLOT0_ALT", + "BFD_RELOC_XTENSA_SLOT1_ALT", + "BFD_RELOC_XTENSA_SLOT2_ALT", + "BFD_RELOC_XTENSA_SLOT3_ALT", + "BFD_RELOC_XTENSA_SLOT4_ALT", + "BFD_RELOC_XTENSA_SLOT5_ALT", + "BFD_RELOC_XTENSA_SLOT6_ALT", + "BFD_RELOC_XTENSA_SLOT7_ALT", + "BFD_RELOC_XTENSA_SLOT8_ALT", + "BFD_RELOC_XTENSA_SLOT9_ALT", + "BFD_RELOC_XTENSA_SLOT10_ALT", + "BFD_RELOC_XTENSA_SLOT11_ALT", + "BFD_RELOC_XTENSA_SLOT12_ALT", + "BFD_RELOC_XTENSA_SLOT13_ALT", + "BFD_RELOC_XTENSA_SLOT14_ALT", "BFD_RELOC_XTENSA_OP0", "BFD_RELOC_XTENSA_OP1", "BFD_RELOC_XTENSA_OP2", diff --git a/bfd/reloc.c b/bfd/reloc.c index 0069841..1df1840 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -4143,15 +4143,95 @@ ENUMDOC Xtensa relocation used in ELF object files for symbols that may require PLT entries. Otherwise, this is just a generic 32-bit relocation. ENUM + BFD_RELOC_XTENSA_DIFF8 +ENUMX + BFD_RELOC_XTENSA_DIFF16 +ENUMX + BFD_RELOC_XTENSA_DIFF32 +ENUMDOC + Xtensa relocations to mark the difference of two local symbols. + These are only needed to support linker relaxation and can be ignored + when not relaxing. The field is set to the value of the difference + assuming no relaxation. The relocation encodes the position of the + first symbol so the linker can determine whether to adjust the field + value. +ENUM + BFD_RELOC_XTENSA_SLOT0_OP +ENUMX + BFD_RELOC_XTENSA_SLOT1_OP +ENUMX + BFD_RELOC_XTENSA_SLOT2_OP +ENUMX + BFD_RELOC_XTENSA_SLOT3_OP +ENUMX + BFD_RELOC_XTENSA_SLOT4_OP +ENUMX + BFD_RELOC_XTENSA_SLOT5_OP +ENUMX + BFD_RELOC_XTENSA_SLOT6_OP +ENUMX + BFD_RELOC_XTENSA_SLOT7_OP +ENUMX + BFD_RELOC_XTENSA_SLOT8_OP +ENUMX + BFD_RELOC_XTENSA_SLOT9_OP +ENUMX + BFD_RELOC_XTENSA_SLOT10_OP +ENUMX + BFD_RELOC_XTENSA_SLOT11_OP +ENUMX + BFD_RELOC_XTENSA_SLOT12_OP +ENUMX + BFD_RELOC_XTENSA_SLOT13_OP +ENUMX + BFD_RELOC_XTENSA_SLOT14_OP +ENUMDOC + Generic Xtensa relocations for instruction operands. Only the slot + number is encoded in the relocation. The relocation applies to the + last PC-relative immediate operand, or if there are no PC-relative + immediates, to the last immediate operand. +ENUM + BFD_RELOC_XTENSA_SLOT0_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT1_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT2_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT3_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT4_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT5_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT6_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT7_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT8_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT9_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT10_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT11_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT12_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT13_ALT +ENUMX + BFD_RELOC_XTENSA_SLOT14_ALT +ENUMDOC + Alternate Xtensa relocations. Only the slot is encoded in the + relocation. The meaning of these relocations is opcode-specific. +ENUM BFD_RELOC_XTENSA_OP0 ENUMX BFD_RELOC_XTENSA_OP1 ENUMX BFD_RELOC_XTENSA_OP2 ENUMDOC - Generic Xtensa relocations. Only the operand number is encoded - in the relocation. The details are determined by extracting the - instruction opcode. + Xtensa relocations for backward compatibility. These have all been + replaced by BFD_RELOC_XTENSA_SLOT0_OP. ENUM BFD_RELOC_XTENSA_ASM_EXPAND ENUMDOC diff --git a/bfd/xtensa-isa.c b/bfd/xtensa-isa.c index 761e5c6..30ad80c 100644 --- a/bfd/xtensa-isa.c +++ b/bfd/xtensa-isa.c @@ -1,5 +1,5 @@ /* Configurable Xtensa ISA support. - Copyright 2003 Free Software Foundation, Inc. + Copyright 2003, 2004 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -17,342 +17,709 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <string.h> - +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" #include "xtensa-isa.h" #include "xtensa-isa-internal.h" -xtensa_isa xtensa_default_isa = NULL; +xtensa_isa_status xtisa_errno; +char xtisa_error_msg[1024]; + -static int -opname_lookup_compare (const void *v1, const void *v2) +xtensa_isa_status +xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused))) { - opname_lookup_entry *e1 = (opname_lookup_entry *)v1; - opname_lookup_entry *e2 = (opname_lookup_entry *)v2; + return xtisa_errno; +} - return strcmp (e1->key, e2->key); + +char * +xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused))) +{ + return xtisa_error_msg; } -xtensa_isa -xtensa_isa_init (void) +#define CHECK_ALLOC(MEM,ERRVAL) \ + do { \ + if ((MEM) == 0) \ + { \ + xtisa_errno = xtensa_isa_out_of_memory; \ + strcpy (xtisa_error_msg, "out of memory"); \ + return (ERRVAL); \ + } \ + } while (0) + +#define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \ + do { \ + if ((MEM) == 0) \ + { \ + xtisa_errno = xtensa_isa_out_of_memory; \ + strcpy (xtisa_error_msg, "out of memory"); \ + if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \ + if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \ + return (ERRVAL); \ + } \ + } while (0) + + +/* Instruction buffers. */ + +int +xtensa_insnbuf_size (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->insnbuf_size; +} + + +xtensa_insnbuf +xtensa_insnbuf_alloc (xtensa_isa isa) +{ + xtensa_insnbuf result = (xtensa_insnbuf) + malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word)); + CHECK_ALLOC (result, 0); + return result; +} + + +void +xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)), + xtensa_insnbuf buf) +{ + free (buf); +} + + +/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our + internal representation of a xtensa instruction word, return the index of + its word and the bit index of its low order byte in the xtensa_insnbuf. */ + +static inline int +byte_to_word_index (int byte_index) +{ + return byte_index / sizeof (xtensa_insnbuf_word); +} + + +static inline int +byte_to_bit_index (int byte_index) +{ + return (byte_index & 0x3) * 8; +} + + +/* Copy an instruction in the 32-bit words pointed at by "insn" to + characters pointed at by "cp". This is more complicated than you + might think because we want 16-bit instructions in bytes 2 & 3 for + big-endian configurations. This function allows us to specify + which byte in "insn" to start with and which way to increment, + allowing trivial implementation for both big- and little-endian + configurations....and it seems to make pretty good code for + both. */ + +int +xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn, char *cp, + int num_chars) { - xtensa_isa isa; - int mod; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int insn_size = xtensa_isa_maxlength (isa); + int fence_post, start, increment, i, byte_count; + xtensa_format fmt; + + if (num_chars == 0) + num_chars = insn_size; - isa = xtensa_load_isa (0); - if (isa == 0) + if (intisa->is_big_endian) { - fprintf (stderr, "Failed to initialize Xtensa base ISA module\n"); - return NULL; + start = insn_size - 1; + increment = -1; + } + else + { + start = 0; + increment = 1; } - for (mod = 1; xtensa_isa_modules[mod].get_num_opcodes_fn; mod++) + /* Find the instruction format. Do nothing if the buffer does not contain + a valid instruction since we need to know how many bytes to copy. */ + fmt = xtensa_format_decode (isa, insn); + if (fmt == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + + byte_count = xtensa_format_length (isa, fmt); + if (byte_count == XTENSA_UNDEFINED) + return XTENSA_UNDEFINED; + + if (byte_count > num_chars) { - if (!xtensa_extend_isa (isa, mod)) - { - fprintf (stderr, "Failed to initialize Xtensa TIE ISA module\n"); - return NULL; - } + xtisa_errno = xtensa_isa_buffer_overflow; + strcpy (xtisa_error_msg, "output buffer too small for instruction"); + return XTENSA_UNDEFINED; } - return isa; + fence_post = start + (byte_count * increment); + + for (i = start; i != fence_post; i += increment, ++cp) + { + int word_inx = byte_to_word_index (i); + int bit_inx = byte_to_bit_index (i); + + *cp = (insn[word_inx] >> bit_inx) & 0xff; + } + + return byte_count; } -/* ISA information. */ -static int -xtensa_check_isa_config (xtensa_isa_internal *isa, - struct config_struct *config_table) +/* Inward conversion from byte stream to xtensa_insnbuf. See + xtensa_insnbuf_to_chars for a discussion of why this is complicated + by endianness. */ + +void +xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn, const char *cp, + int num_chars) { - int i, j; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int max_size, insn_size, fence_post, start, increment, i; + + max_size = xtensa_isa_maxlength (isa); + + /* Decode the instruction length so we know how many bytes to read. */ + insn_size = (intisa->length_decode_fn) (cp); + if (insn_size == XTENSA_UNDEFINED) + { + /* This should never happen when the byte stream contains a + valid instruction. Just read the maximum number of bytes.... */ + insn_size = max_size; + } + + if (num_chars == 0 || num_chars > insn_size) + num_chars = insn_size; - if (!config_table) + if (intisa->is_big_endian) + { + start = max_size - 1; + increment = -1; + } + else { - fprintf (stderr, "Error: Empty configuration table in ISA DLL\n"); - return 0; + start = 0; + increment = 1; } - /* For the first module, save a pointer to the table and record the - specified endianness and availability of the density option. */ + fence_post = start + (num_chars * increment); + memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word)); - if (isa->num_modules == 0) + for (i = start; i != fence_post; i += increment, ++cp) { - int found_memory_order = 0; + int word_inx = byte_to_word_index (i); + int bit_inx = byte_to_bit_index (i); + + insn[word_inx] |= (*cp & 0xff) << bit_inx; + } +} - isa->config = config_table; - isa->has_density = 1; /* Default to have density option. */ - for (i = 0; config_table[i].param_name; i++) - { - if (!strcmp (config_table[i].param_name, "IsaMemoryOrder")) - { - isa->is_big_endian = - (strcmp (config_table[i].param_value, "BigEndian") == 0); - found_memory_order = 1; - } - if (!strcmp (config_table[i].param_name, "IsaUseDensityInstruction")) - { - isa->has_density = atoi (config_table[i].param_value); - } - } - if (!found_memory_order) - { - fprintf (stderr, "Error: \"IsaMemoryOrder\" missing from " - "configuration table in ISA DLL\n"); - return 0; - } + +/* ISA information. */ - return 1; +extern xtensa_isa_internal xtensa_modules; + +xtensa_isa +xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p) +{ + xtensa_isa_internal *isa = &xtensa_modules; + int n, is_user; + + /* Set up the opcode name lookup table. */ + isa->opname_lookup_table = + bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry)); + CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p); + for (n = 0; n < isa->num_opcodes; n++) + { + isa->opname_lookup_table[n].key = isa->opcodes[n].name; + isa->opname_lookup_table[n].u.opcode = n; } + qsort (isa->opname_lookup_table, isa->num_opcodes, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); - /* For subsequent modules, check that the parameters match. Note: This - code is sufficient to handle the current model where there are never - more than 2 modules; we might at some point want to handle cases where - module N > 0 specifies some parameters not included in the base table, - and we would then add those to isa->config so that subsequent modules - would check against them. */ + /* Set up the state name lookup table. */ + isa->state_lookup_table = + bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry)); + CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p); + for (n = 0; n < isa->num_states; n++) + { + isa->state_lookup_table[n].key = isa->states[n].name; + isa->state_lookup_table[n].u.state = n; + } + qsort (isa->state_lookup_table, isa->num_states, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + /* Set up the sysreg name lookup table. */ + isa->sysreg_lookup_table = + bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry)); + CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p); + for (n = 0; n < isa->num_sysregs; n++) + { + isa->sysreg_lookup_table[n].key = isa->sysregs[n].name; + isa->sysreg_lookup_table[n].u.sysreg = n; + } + qsort (isa->sysreg_lookup_table, isa->num_sysregs, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); - for (i = 0; config_table[i].param_name; i++) + /* Set up the user & system sysreg number tables. */ + for (is_user = 0; is_user < 2; is_user++) { - for (j = 0; isa->config[j].param_name; j++) - { - if (!strcmp (config_table[i].param_name, isa->config[j].param_name)) - { - int mismatch; - if (!strcmp (config_table[i].param_name, "IsaCoprocessorCount")) - { - /* Only require the coprocessor count to be <= the base. */ - int tiecnt = atoi (config_table[i].param_value); - int basecnt = atoi (isa->config[j].param_value); - mismatch = (tiecnt > basecnt); - } - else - mismatch = strcmp (config_table[i].param_value, - isa->config[j].param_value); - if (mismatch) - { -#define MISMATCH_MESSAGE \ -"Error: Configuration mismatch in the \"%s\" parameter:\n\ -the configuration used when the TIE file was compiled had a value of\n\ -\"%s\", while the current configuration has a value of\n\ -\"%s\". Please rerun the TIE compiler with a matching\n\ -configuration.\n" - fprintf (stderr, MISMATCH_MESSAGE, - config_table[i].param_name, - config_table[i].param_value, - isa->config[j].param_value); - return 0; - } - break; - } - } + isa->sysreg_table[is_user] = + bfd_malloc ((isa->max_sysreg_num[is_user] + 1) + * sizeof (xtensa_sysreg)); + CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL, + errno_p, error_msg_p); + + for (n = 0; n <= isa->max_sysreg_num[is_user]; n++) + isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED; + } + for (n = 0; n < isa->num_sysregs; n++) + { + xtensa_sysreg_internal *sreg = &isa->sysregs[n]; + is_user = sreg->is_user; + + isa->sysreg_table[is_user][sreg->number] = n; + } + + /* Set up the interface lookup table. */ + isa->interface_lookup_table = + bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry)); + CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p, + error_msg_p); + for (n = 0; n < isa->num_interfaces; n++) + { + isa->interface_lookup_table[n].key = isa->interfaces[n].name; + isa->interface_lookup_table[n].u.intf = n; + } + qsort (isa->interface_lookup_table, isa->num_interfaces, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + /* Set up the funcUnit lookup table. */ + isa->funcUnit_lookup_table = + bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry)); + CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p, + error_msg_p); + for (n = 0; n < isa->num_funcUnits; n++) + { + isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name; + isa->funcUnit_lookup_table[n].u.fun = n; } + qsort (isa->funcUnit_lookup_table, isa->num_funcUnits, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); - return 1; + isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) / + sizeof (xtensa_insnbuf_word)); + + return (xtensa_isa) isa; } -static int -xtensa_add_isa (xtensa_isa_internal *isa, libisa_module_specifier libisa) +void +xtensa_isa_free (xtensa_isa isa) { - int (*get_num_opcodes_fn) (void); - struct config_struct *(*get_config_table_fn) (void); - xtensa_opcode_internal **(*get_opcodes_fn) (void); - int (*decode_insn_fn) (const xtensa_insnbuf); - xtensa_opcode_internal **opcodes; - int opc, insn_size, prev_num_opcodes, new_num_opcodes, this_module; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int n; - get_num_opcodes_fn = xtensa_isa_modules[libisa].get_num_opcodes_fn; - get_opcodes_fn = xtensa_isa_modules[libisa].get_opcodes_fn; - decode_insn_fn = xtensa_isa_modules[libisa].decode_insn_fn; - get_config_table_fn = xtensa_isa_modules[libisa].get_config_table_fn; + /* With this version of the code, the xtensa_isa structure is not + dynamically allocated, so this function is not essential. Free + the memory allocated by xtensa_isa_init and restore the xtensa_isa + structure to its initial state. */ - if (!get_num_opcodes_fn || !get_opcodes_fn || !decode_insn_fn - || (!get_config_table_fn && isa->num_modules == 0)) - return 0; - - if (get_config_table_fn - && !xtensa_check_isa_config (isa, get_config_table_fn ())) - return 0; + if (intisa->opname_lookup_table) + { + free (intisa->opname_lookup_table); + intisa->opname_lookup_table = 0; + } - prev_num_opcodes = isa->num_opcodes; - new_num_opcodes = (*get_num_opcodes_fn) (); + if (intisa->state_lookup_table) + { + free (intisa->state_lookup_table); + intisa->state_lookup_table = 0; + } - isa->num_opcodes += new_num_opcodes; - isa->opcode_table = (xtensa_opcode_internal **) - realloc (isa->opcode_table, isa->num_opcodes * - sizeof (xtensa_opcode_internal *)); - isa->opname_lookup_table = (opname_lookup_entry *) - realloc (isa->opname_lookup_table, isa->num_opcodes * - sizeof (opname_lookup_entry)); + if (intisa->sysreg_lookup_table) + { + free (intisa->sysreg_lookup_table); + intisa->sysreg_lookup_table = 0; + } + for (n = 0; n < 2; n++) + { + if (intisa->sysreg_table[n]) + { + free (intisa->sysreg_table[n]); + intisa->sysreg_table[n] = 0; + } + } - opcodes = (*get_opcodes_fn) (); + if (intisa->interface_lookup_table) + { + free (intisa->interface_lookup_table); + intisa->interface_lookup_table = 0; + } - insn_size = isa->insn_size; - for (opc = 0; opc < new_num_opcodes; opc++) + if (intisa->funcUnit_lookup_table) { - xtensa_opcode_internal *intopc = opcodes[opc]; - int newopc = prev_num_opcodes + opc; - isa->opcode_table[newopc] = intopc; - isa->opname_lookup_table[newopc].key = intopc->name; - isa->opname_lookup_table[newopc].opcode = newopc; - if (intopc->length > insn_size) - insn_size = intopc->length; + free (intisa->funcUnit_lookup_table); + intisa->funcUnit_lookup_table = 0; } +} - isa->insn_size = insn_size; - isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) / - sizeof (xtensa_insnbuf_word)); - qsort (isa->opname_lookup_table, isa->num_opcodes, - sizeof (opname_lookup_entry), opname_lookup_compare); +int +xtensa_isa_name_compare (const void *v1, const void *v2) +{ + xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1; + xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2; + + return strcasecmp (e1->key, e2->key); +} + + +int +xtensa_isa_maxlength (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->insn_size; +} + + +int +xtensa_isa_length_from_chars (xtensa_isa isa, const char *cp) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return (intisa->length_decode_fn) (cp); +} + + +int +xtensa_isa_num_pipe_stages (xtensa_isa isa) +{ + int num_opcodes, num_uses; + xtensa_opcode opcode; + xtensa_funcUnit_use *use; + int i, stage, max_stage = XTENSA_UNDEFINED; - /* Check for duplicate opcode names. */ - for (opc = 1; opc < isa->num_opcodes; opc++) + num_opcodes = xtensa_isa_num_opcodes (isa); + for (opcode = 0; opcode < num_opcodes; opcode++) { - if (!opname_lookup_compare (&isa->opname_lookup_table[opc-1], - &isa->opname_lookup_table[opc])) + num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode); + for (i = 0; i < num_uses; i++) { - fprintf (stderr, "Error: Duplicate TIE opcode \"%s\"\n", - isa->opname_lookup_table[opc].key); - return 0; + use = xtensa_opcode_funcUnit_use (isa, opcode, i); + stage = use->stage; + if (stage > max_stage) + max_stage = stage; } } - this_module = isa->num_modules; - isa->num_modules += 1; + return max_stage + 1; +} + + +int +xtensa_isa_num_formats (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_formats; +} - isa->module_opcode_base = (int *) realloc (isa->module_opcode_base, - isa->num_modules * sizeof (int)); - isa->module_decode_fn = (xtensa_insn_decode_fn *) - realloc (isa->module_decode_fn, isa->num_modules * - sizeof (xtensa_insn_decode_fn)); - isa->module_opcode_base[this_module] = prev_num_opcodes; - isa->module_decode_fn[this_module] = decode_insn_fn; +int +xtensa_isa_num_opcodes (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_opcodes; +} - xtensa_default_isa = isa; - return 1; /* Library was successfully added. */ +int +xtensa_isa_num_regfiles (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_regfiles; } -xtensa_isa -xtensa_load_isa (libisa_module_specifier libisa) +int +xtensa_isa_num_states (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_states; +} + + +int +xtensa_isa_num_sysregs (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_sysregs; +} + + +int +xtensa_isa_num_interfaces (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_interfaces; +} + + +int +xtensa_isa_num_funcUnits (xtensa_isa isa) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + return intisa->num_funcUnits; +} + + + +/* Instruction formats. */ + + +#define CHECK_FORMAT(INTISA,FMT,ERRVAL) \ + do { \ + if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \ + { \ + xtisa_errno = xtensa_isa_bad_format; \ + strcpy (xtisa_error_msg, "invalid format specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +#define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \ + do { \ + if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \ + { \ + xtisa_errno = xtensa_isa_bad_slot; \ + strcpy (xtisa_error_msg, "invalid slot specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +const char * +xtensa_format_name (xtensa_isa isa, xtensa_format fmt) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_FORMAT (intisa, fmt, NULL); + return intisa->formats[fmt].name; +} + + +xtensa_format +xtensa_format_lookup (xtensa_isa isa, const char *fmtname) { - xtensa_isa_internal *isa; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int fmt; - isa = (xtensa_isa_internal *) malloc (sizeof (xtensa_isa_internal)); - memset (isa, 0, sizeof (xtensa_isa_internal)); - if (!xtensa_add_isa (isa, libisa)) + if (!fmtname || !*fmtname) { - xtensa_isa_free (isa); - return NULL; + xtisa_errno = xtensa_isa_bad_format; + strcpy (xtisa_error_msg, "invalid format name"); + return XTENSA_UNDEFINED; } - return (xtensa_isa) isa; + + for (fmt = 0; fmt < intisa->num_formats; fmt++) + { + if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0) + return fmt; + } + + xtisa_errno = xtensa_isa_bad_format; + sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname); + return XTENSA_UNDEFINED; +} + + +xtensa_format +xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_format fmt; + + fmt = (intisa->format_decode_fn) (insn); + if (fmt != XTENSA_UNDEFINED) + return fmt; + + xtisa_errno = xtensa_isa_bad_format; + strcpy (xtisa_error_msg, "cannot decode instruction format"); + return XTENSA_UNDEFINED; } int -xtensa_extend_isa (xtensa_isa isa, libisa_module_specifier libisa) +xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return xtensa_add_isa (intisa, libisa); + CHECK_FORMAT (intisa, fmt, -1); + (*intisa->formats[fmt].encode_fn) (insn); + return 0; } -void -xtensa_isa_free (xtensa_isa isa) +int +xtensa_format_length (xtensa_isa isa, xtensa_format fmt) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - if (intisa->opcode_table) - free (intisa->opcode_table); - if (intisa->opname_lookup_table) - free (intisa->opname_lookup_table); - if (intisa->module_opcode_base) - free (intisa->module_opcode_base); - if (intisa->module_decode_fn) - free (intisa->module_decode_fn); - free (intisa); + CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); + return intisa->formats[fmt].length; } int -xtensa_insn_maxlength (xtensa_isa isa) +xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return intisa->insn_size; + CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); + return intisa->formats[fmt].num_slots; +} + + +xtensa_opcode +xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int slot_id; + + CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); + CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED); + + slot_id = intisa->formats[fmt].slot_id[slot]; + return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name); } int -xtensa_insnbuf_size (xtensa_isa isa) +xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot, + const xtensa_insnbuf insn, xtensa_insnbuf slotbuf) { - xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa; - return intisa->insnbuf_size; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int slot_id; + + CHECK_FORMAT (intisa, fmt, -1); + CHECK_SLOT (intisa, fmt, slot, -1); + + slot_id = intisa->formats[fmt].slot_id[slot]; + (*intisa->slots[slot_id].get_fn) (insn, slotbuf); + return 0; } int -xtensa_num_opcodes (xtensa_isa isa) +xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot, + xtensa_insnbuf insn, const xtensa_insnbuf slotbuf) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return intisa->num_opcodes; + int slot_id; + + CHECK_FORMAT (intisa, fmt, -1); + CHECK_SLOT (intisa, fmt, slot, -1); + + slot_id = intisa->formats[fmt].slot_id[slot]; + (*intisa->slots[slot_id].set_fn) (insn, slotbuf); + return 0; } + +/* Opcode information. */ + + +#define CHECK_OPCODE(INTISA,OPC,ERRVAL) \ + do { \ + if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \ + { \ + xtisa_errno = xtensa_isa_bad_opcode; \ + strcpy (xtisa_error_msg, "invalid opcode specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + xtensa_opcode xtensa_opcode_lookup (xtensa_isa isa, const char *opname) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - opname_lookup_entry entry, *result; + xtensa_lookup_entry entry, *result; + + if (!opname || !*opname) + { + xtisa_errno = xtensa_isa_bad_opcode; + strcpy (xtisa_error_msg, "invalid opcode name"); + return XTENSA_UNDEFINED; + } entry.key = opname; result = bsearch (&entry, intisa->opname_lookup_table, intisa->num_opcodes, - sizeof (opname_lookup_entry), opname_lookup_compare); - if (!result) return XTENSA_UNDEFINED; - return result->opcode; + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + if (!result) + { + xtisa_errno = xtensa_isa_bad_opcode; + sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname); + return XTENSA_UNDEFINED; + } + + return result->u.opcode; } xtensa_opcode -xtensa_decode_insn (xtensa_isa isa, const xtensa_insnbuf insn) +xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot, + const xtensa_insnbuf slotbuf) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - int n, opc; - for (n = 0; n < intisa->num_modules; n++) { - opc = (intisa->module_decode_fn[n]) (insn); - if (opc != XTENSA_UNDEFINED) - return intisa->module_opcode_base[n] + opc; - } - return XTENSA_UNDEFINED; -} + int slot_id; + xtensa_opcode opc; + CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); + CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED); -/* Opcode information. */ + slot_id = intisa->formats[fmt].slot_id[slot]; -void -xtensa_encode_insn (xtensa_isa isa, xtensa_opcode opc, xtensa_insnbuf insn) + opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf); + if (opc == XTENSA_UNDEFINED) + { + xtisa_errno = xtensa_isa_bad_opcode; + strcpy (xtisa_error_msg, "cannot decode opcode"); + } + return opc; +} + + +int +xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot, + xtensa_insnbuf slotbuf, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - xtensa_insnbuf template = intisa->opcode_table[opc]->template(); - int len = intisa->opcode_table[opc]->length; - int n; + int slot_id; + xtensa_opcode_encode_fn encode_fn; - /* Convert length to 32-bit words. */ - len = (len + 3) / 4; + CHECK_FORMAT (intisa, fmt, -1); + CHECK_SLOT (intisa, fmt, slot, -1); + CHECK_OPCODE (intisa, opc, -1); - /* Copy the template. */ - for (n = 0; n < len; n++) - insn[n] = template[n]; - - /* Fill any unused buffer space with zeros. */ - for ( ; n < intisa->insnbuf_size; n++) - insn[n] = 0; + slot_id = intisa->formats[fmt].slot_id[slot]; + encode_fn = intisa->opcodes[opc].encode_fns[slot_id]; + if (!encode_fn) + { + xtisa_errno = xtensa_isa_wrong_slot; + sprintf (xtisa_error_msg, + "opcode \"%s\" is not allowed in slot %d of format \"%s\"", + intisa->opcodes[opc].name, slot, intisa->formats[fmt].name); + return -1; + } + (*encode_fn) (slotbuf); + return 0; } @@ -360,234 +727,1015 @@ const char * xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return intisa->opcode_table[opc]->name; + CHECK_OPCODE (intisa, opc, NULL); + return intisa->opcodes[opc].name; +} + + +int +xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0) + return 1; + return 0; +} + + +int +xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0) + return 1; + return 0; +} + + +int +xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0) + return 1; + return 0; } int -xtensa_insn_length (xtensa_isa isa, xtensa_opcode opc) +xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return intisa->opcode_table[opc]->length; + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0) + return 1; + return 0; } int -xtensa_insn_length_from_first_byte (xtensa_isa isa, char first_byte) +xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - int is_density = (first_byte & (intisa->is_big_endian ? 0x80 : 0x08)) != 0; - return (intisa->has_density && is_density ? 2 : 3); + int iclass_id; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + return intisa->iclasses[iclass_id].num_operands; } int -xtensa_num_operands (xtensa_isa isa, xtensa_opcode opc) +xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - return intisa->opcode_table[opc]->iclass->num_operands; + int iclass_id; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + return intisa->iclasses[iclass_id].num_stateOperands; } -xtensa_operand -xtensa_get_operand (xtensa_isa isa, xtensa_opcode opc, int opnd) +int +xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - xtensa_iclass_internal *iclass = intisa->opcode_table[opc]->iclass; - if (opnd >= iclass->num_operands) - return NULL; - return (xtensa_operand) iclass->operands[opnd]; + int iclass_id; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + return intisa->iclasses[iclass_id].num_interfaceOperands; } +int +xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + return intisa->opcodes[opc].num_funcUnit_uses; +} + + +xtensa_funcUnit_use * +xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_OPCODE (intisa, opc, NULL); + if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses) + { + xtisa_errno = xtensa_isa_bad_funcUnit; + sprintf (xtisa_error_msg, "invalid functional unit use number (%d); " + "opcode \"%s\" has %d", u, intisa->opcodes[opc].name, + intisa->opcodes[opc].num_funcUnit_uses); + return NULL; + } + return &intisa->opcodes[opc].funcUnit_uses[u]; +} + + + /* Operand information. */ -char * -xtensa_operand_kind (xtensa_operand opnd) + +#define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \ + do { \ + if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \ + { \ + xtisa_errno = xtensa_isa_bad_operand; \ + sprintf (xtisa_error_msg, "invalid operand number (%d); " \ + "opcode \"%s\" has %d operands", (OPND), \ + (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \ + return (ERRVAL); \ + } \ + } while (0) + + +static xtensa_operand_internal * +get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return intop->operand_kind; + xtensa_iclass_internal *iclass; + int iclass_id, operand_id; + + CHECK_OPCODE (intisa, opc, NULL); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_OPERAND (intisa, opc, iclass, opnd, NULL); + operand_id = iclass->operands[opnd].u.operand_id; + return &intisa->operands[operand_id]; +} + + +const char * +xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return NULL; + return intop->name; +} + + +int +xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_iclass_internal *iclass; + int iclass_id, operand_id; + xtensa_operand_internal *intop; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED); + + /* Special case for "sout" operands. */ + if (iclass->operands[opnd].inout == 's') + return 0; + + operand_id = iclass->operands[opnd].u.operand_id; + intop = &intisa->operands[operand_id]; + + if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0) + return 1; + return 0; } char -xtensa_operand_inout (xtensa_operand opnd) +xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return intop->inout; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_iclass_internal *iclass; + int iclass_id; + char inout; + + CHECK_OPCODE (intisa, opc, 0); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_OPERAND (intisa, opc, iclass, opnd, 0); + inout = iclass->operands[opnd].inout; + + /* Special case for "sout" operands. */ + if (inout == 's') + return 'o'; + + return inout; } -uint32 -xtensa_operand_get_field (xtensa_operand opnd, const xtensa_insnbuf insn) +int +xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd, + xtensa_format fmt, int slot, + const xtensa_insnbuf slotbuf, uint32 *valp) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return (*intop->get_field) (insn); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + int slot_id; + xtensa_get_field_fn get_fn; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + CHECK_FORMAT (intisa, fmt, -1); + CHECK_SLOT (intisa, fmt, slot, -1); + + slot_id = intisa->formats[fmt].slot_id[slot]; + if (intop->field_id == XTENSA_UNDEFINED) + { + xtisa_errno = xtensa_isa_no_field; + strcpy (xtisa_error_msg, "implicit operand has no field"); + return -1; + } + get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id]; + if (!get_fn) + { + xtisa_errno = xtensa_isa_wrong_slot; + sprintf (xtisa_error_msg, + "operand \"%s\" does not exist in slot %d of format \"%s\"", + intop->name, slot, intisa->formats[fmt].name); + return -1; + } + *valp = (*get_fn) (slotbuf); + return 0; } -void -xtensa_operand_set_field (xtensa_operand opnd, xtensa_insnbuf insn, uint32 val) +int +xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd, + xtensa_format fmt, int slot, + xtensa_insnbuf slotbuf, uint32 val) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return (*intop->set_field) (insn, val); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + int slot_id; + xtensa_set_field_fn set_fn; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + CHECK_FORMAT (intisa, fmt, -1); + CHECK_SLOT (intisa, fmt, slot, -1); + + slot_id = intisa->formats[fmt].slot_id[slot]; + if (intop->field_id == XTENSA_UNDEFINED) + { + xtisa_errno = xtensa_isa_no_field; + strcpy (xtisa_error_msg, "implicit operand has no field"); + return -1; + } + set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id]; + if (!set_fn) + { + xtisa_errno = xtensa_isa_wrong_slot; + sprintf (xtisa_error_msg, + "operand \"%s\" does not exist in slot %d of format \"%s\"", + intop->name, slot, intisa->formats[fmt].name); + return -1; + } + (*set_fn) (slotbuf, val); + return 0; } -xtensa_encode_result -xtensa_operand_encode (xtensa_operand opnd, uint32 *valp) +int +xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd, + uint32 *valp) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return (*intop->encode) (valp); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + uint32 test_val, orig_val; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + if (!intop->encode) + { + /* This is a default operand for a field. How can we tell if the + value fits in the field? Write the value into the field, + read it back, and then make sure we get the same value. */ + + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + static xtensa_insnbuf tmpbuf = 0; + int slot_id; + + if (!tmpbuf) + { + tmpbuf = xtensa_insnbuf_alloc (isa); + CHECK_ALLOC (tmpbuf, -1); + } + + /* A default operand is always associated with a field, + but check just to be sure.... */ + if (intop->field_id == XTENSA_UNDEFINED) + { + xtisa_errno = xtensa_isa_internal_error; + strcpy (xtisa_error_msg, "operand has no field"); + return -1; + } + + /* Find some slot that includes the field. */ + for (slot_id = 0; slot_id < intisa->num_slots; slot_id++) + { + xtensa_get_field_fn get_fn = + intisa->slots[slot_id].get_field_fns[intop->field_id]; + xtensa_set_field_fn set_fn = + intisa->slots[slot_id].set_field_fns[intop->field_id]; + + if (get_fn && set_fn) + { + (*set_fn) (tmpbuf, *valp); + return ((*get_fn) (tmpbuf) != *valp); + } + } + + /* Couldn't find any slot containing the field.... */ + xtisa_errno = xtensa_isa_no_field; + strcpy (xtisa_error_msg, "field does not exist in any slot"); + return -1; + } + + /* Encode the value. In some cases, the encoding function may detect + errors, but most of the time the only way to determine if the value + was successfully encoded is to decode it and check if it matches + the original value. */ + orig_val = *valp; + if ((*intop->encode) (valp) || + (test_val = *valp, (*intop->decode) (&test_val)) || + test_val != orig_val) + { + xtisa_errno = xtensa_isa_bad_value; + sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp); + return -1; + } + + return 0; } -uint32 -xtensa_operand_decode (xtensa_operand opnd, uint32 val) +int +xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd, + uint32 *valp) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return (*intop->decode) (val); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + /* Use identity function for "default" operands. */ + if (!intop->decode) + return 0; + + if ((*intop->decode) (valp)) + { + xtisa_errno = xtensa_isa_bad_value; + sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp); + return -1; + } + return 0; } int -xtensa_operand_isPCRelative (xtensa_operand opnd) +xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - return intop->isPCRelative; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return XTENSA_UNDEFINED; + + if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0) + return 1; + return 0; } -uint32 -xtensa_operand_do_reloc (xtensa_operand opnd, uint32 addr, uint32 pc) +xtensa_regfile +xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - if (!intop->isPCRelative) - return addr; - return (*intop->do_reloc) (addr, pc); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return XTENSA_UNDEFINED; + + return intop->regfile; } -uint32 -xtensa_operand_undo_reloc (xtensa_operand opnd, uint32 offset, uint32 pc) +int +xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd) { - xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd; - if (!intop->isPCRelative) - return offset; - return (*intop->undo_reloc) (offset, pc); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return XTENSA_UNDEFINED; + + return intop->num_regs; } -/* Instruction buffers. */ +int +xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; -xtensa_insnbuf -xtensa_insnbuf_alloc (xtensa_isa isa) + intop = get_operand (intisa, opc, opnd); + if (!intop) return XTENSA_UNDEFINED; + + if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0) + return 1; + return 0; +} + + +int +xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return XTENSA_UNDEFINED; + + if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0) + return 1; + return 0; +} + + +int +xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd, + uint32 *valp, uint32 pc) { - return (xtensa_insnbuf) malloc (xtensa_insnbuf_size (isa) * - sizeof (xtensa_insnbuf_word)); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) + return 0; + + if (!intop->do_reloc) + { + xtisa_errno = xtensa_isa_internal_error; + strcpy (xtisa_error_msg, "operand missing do_reloc function"); + return -1; + } + + if ((*intop->do_reloc) (valp, pc)) + { + xtisa_errno = xtensa_isa_bad_value; + sprintf (xtisa_error_msg, + "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc); + return -1; + } + + return 0; } -void -xtensa_insnbuf_free (xtensa_insnbuf buf) +int +xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd, + uint32 *valp, uint32 pc) { - free( buf ); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_operand_internal *intop; + + intop = get_operand (intisa, opc, opnd); + if (!intop) return -1; + + if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) + return 0; + + if (!intop->undo_reloc) + { + xtisa_errno = xtensa_isa_internal_error; + strcpy (xtisa_error_msg, "operand missing undo_reloc function"); + return -1; + } + + if ((*intop->undo_reloc) (valp, pc)) + { + xtisa_errno = xtensa_isa_bad_value; + sprintf (xtisa_error_msg, + "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc); + return -1; + } + + return 0; } -/* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our - internal representation of a xtensa instruction word, return the index of - its word and the bit index of its low order byte in the xtensa_insnbuf. */ + +/* State Operands. */ -static inline int -byte_to_word_index (int byte_index) + +#define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \ + do { \ + if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \ + { \ + xtisa_errno = xtensa_isa_bad_operand; \ + sprintf (xtisa_error_msg, "invalid state operand number (%d); " \ + "opcode \"%s\" has %d state operands", (STOP), \ + (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_state +xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp) { - return byte_index / sizeof (xtensa_insnbuf_word); + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_iclass_internal *iclass; + int iclass_id; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED); + return iclass->stateOperands[stOp].u.state; } -static inline int -byte_to_bit_index (int byte_index) +char +xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp) { - return (byte_index & 0x3) * 8; + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_iclass_internal *iclass; + int iclass_id; + + CHECK_OPCODE (intisa, opc, 0); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0); + return iclass->stateOperands[stOp].inout; } + +/* Interface Operands. */ -/* Copy an instruction in the 32 bit words pointed at by <insn> to characters - pointed at by <cp>. This is more complicated than you might think because - we want 16 bit instructions in bytes 2,3 for big endian. This function - allows us to specify which byte in <insn> to start with and which way to - increment, allowing trivial implementation for both big and little endian. - And it seems to make pretty good code for both. */ -void -xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn, char *cp) +#define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \ + do { \ + if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \ + { \ + xtisa_errno = xtensa_isa_bad_operand; \ + sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \ + "opcode \"%s\" has %d interface operands", (IFOP), \ + (INTISA)->opcodes[(OPC)].name, \ + (ICLASS)->num_interfaceOperands); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_interface +xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc, + int ifOp) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - int insn_size = xtensa_insn_maxlength (intisa); - int fence_post, start, increment, i, byte_count; - xtensa_opcode opc; + xtensa_iclass_internal *iclass; + int iclass_id; + + CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); + iclass_id = intisa->opcodes[opc].iclass_id; + iclass = &intisa->iclasses[iclass_id]; + CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED); + return iclass->interfaceOperands[ifOp]; +} - if (intisa->is_big_endian) + + +/* Register Files. */ + + +#define CHECK_REGFILE(INTISA,RF,ERRVAL) \ + do { \ + if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \ + { \ + xtisa_errno = xtensa_isa_bad_regfile; \ + strcpy (xtisa_error_msg, "invalid regfile specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_regfile +xtensa_regfile_lookup (xtensa_isa isa, const char *name) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int n; + + if (!name || !*name) { - start = insn_size - 1; - increment = -1; + xtisa_errno = xtensa_isa_bad_regfile; + strcpy (xtisa_error_msg, "invalid regfile name"); + return XTENSA_UNDEFINED; } - else + + /* The expected number of regfiles is small; use a linear search. */ + for (n = 0; n < intisa->num_regfiles; n++) { - start = 0; - increment = 1; + if (!strcmp (intisa->regfiles[n].name, name)) + return n; } - /* Find the opcode; do nothing if the buffer does not contain a valid - instruction since we need to know how many bytes to copy. */ - opc = xtensa_decode_insn (isa, insn); - if (opc == XTENSA_UNDEFINED) - return; + xtisa_errno = xtensa_isa_bad_regfile; + sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name); + return XTENSA_UNDEFINED; +} - byte_count = xtensa_insn_length (isa, opc); - fence_post = start + (byte_count * increment); - for (i = start; i != fence_post; i += increment, ++cp) +xtensa_regfile +xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + int n; + + if (!shortname || !*shortname) { - int word_inx = byte_to_word_index (i); - int bit_inx = byte_to_bit_index (i); + xtisa_errno = xtensa_isa_bad_regfile; + strcpy (xtisa_error_msg, "invalid regfile shortname"); + return XTENSA_UNDEFINED; + } - *cp = (insn[word_inx] >> bit_inx) & 0xff; + /* The expected number of regfiles is small; use a linear search. */ + for (n = 0; n < intisa->num_regfiles; n++) + { + /* Ignore regfile views since they always have the same shortnames + as their parents. */ + if (intisa->regfiles[n].parent != n) + continue; + if (!strcmp (intisa->regfiles[n].shortname, shortname)) + return n; } + + xtisa_errno = xtensa_isa_bad_regfile; + sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized", + shortname); + return XTENSA_UNDEFINED; } -/* Inward conversion from byte stream to xtensa_insnbuf. See - xtensa_insnbuf_to_chars for a discussion of why this is - complicated by endianness. */ - -void -xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn, const char* cp) + +const char * +xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf) { xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; - int insn_size = xtensa_insn_maxlength (intisa); - int fence_post, start, increment, i; + CHECK_REGFILE (intisa, rf, NULL); + return intisa->regfiles[rf].name; +} - if (intisa->is_big_endian) + +const char * +xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_REGFILE (intisa, rf, NULL); + return intisa->regfiles[rf].shortname; +} + + +xtensa_regfile +xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); + return intisa->regfiles[rf].parent; +} + + +int +xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); + return intisa->regfiles[rf].num_bits; +} + + +int +xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); + return intisa->regfiles[rf].num_entries; +} + + +/* Processor States. */ + + +#define CHECK_STATE(INTISA,ST,ERRVAL) \ + do { \ + if ((ST) < 0 || (ST) >= (INTISA)->num_states) \ + { \ + xtisa_errno = xtensa_isa_bad_state; \ + strcpy (xtisa_error_msg, "invalid state specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_state +xtensa_state_lookup (xtensa_isa isa, const char *name) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_lookup_entry entry, *result; + + if (!name || !*name) { - start = insn_size - 1; - increment = -1; + xtisa_errno = xtensa_isa_bad_state; + strcpy (xtisa_error_msg, "invalid state name"); + return XTENSA_UNDEFINED; } - else + + entry.key = name; + result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + if (!result) { - start = 0; - increment = 1; + xtisa_errno = xtensa_isa_bad_state; + sprintf (xtisa_error_msg, "state \"%s\" not recognized", name); + return XTENSA_UNDEFINED; } - fence_post = start + (insn_size * increment); - memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word)); + return result->u.state; +} - for ( i = start; i != fence_post; i += increment, ++cp ) + +const char * +xtensa_state_name (xtensa_isa isa, xtensa_state st) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_STATE (intisa, st, NULL); + return intisa->states[st].name; +} + + +int +xtensa_state_num_bits (xtensa_isa isa, xtensa_state st) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_STATE (intisa, st, XTENSA_UNDEFINED); + return intisa->states[st].num_bits; +} + + +int +xtensa_state_is_exported (xtensa_isa isa, xtensa_state st) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_STATE (intisa, st, XTENSA_UNDEFINED); + if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0) + return 1; + return 0; +} + + +/* Sysregs. */ + + +#define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \ + do { \ + if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \ + { \ + xtisa_errno = xtensa_isa_bad_sysreg; \ + strcpy (xtisa_error_msg, "invalid sysreg specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_sysreg +xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + + if (is_user != 0) + is_user = 1; + + if (num < 0 || num > intisa->max_sysreg_num[is_user] + || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED) { - int word_inx = byte_to_word_index (i); - int bit_inx = byte_to_bit_index (i); + xtisa_errno = xtensa_isa_bad_sysreg; + strcpy (xtisa_error_msg, "sysreg not recognized"); + return XTENSA_UNDEFINED; + } - insn[word_inx] |= (*cp & 0xff) << bit_inx; + return intisa->sysreg_table[is_user][num]; +} + + +xtensa_sysreg +xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_lookup_entry entry, *result; + + if (!name || !*name) + { + xtisa_errno = xtensa_isa_bad_sysreg; + strcpy (xtisa_error_msg, "invalid sysreg name"); + return XTENSA_UNDEFINED; + } + + entry.key = name; + result = bsearch (&entry, intisa->sysreg_lookup_table, intisa->num_sysregs, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + if (!result) + { + xtisa_errno = xtensa_isa_bad_sysreg; + sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name); + return XTENSA_UNDEFINED; } + + return result->u.sysreg; +} + + +const char * +xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_SYSREG (intisa, sysreg, NULL); + return intisa->sysregs[sysreg].name; +} + + +int +xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED); + return intisa->sysregs[sysreg].number; +} + + +int +xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED); + if (intisa->sysregs[sysreg].is_user) + return 1; + return 0; +} + + +/* Interfaces. */ + + +#define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \ + do { \ + if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \ + { \ + xtisa_errno = xtensa_isa_bad_interface; \ + strcpy (xtisa_error_msg, "invalid interface specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_interface +xtensa_interface_lookup (xtensa_isa isa, const char *ifname) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_lookup_entry entry, *result; + + if (!ifname || !*ifname) + { + xtisa_errno = xtensa_isa_bad_interface; + strcpy (xtisa_error_msg, "invalid interface name"); + return XTENSA_UNDEFINED; + } + + entry.key = ifname; + result = bsearch (&entry, intisa->interface_lookup_table, + intisa->num_interfaces, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + if (!result) + { + xtisa_errno = xtensa_isa_bad_interface; + sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname); + return XTENSA_UNDEFINED; + } + + return result->u.intf; +} + + +const char * +xtensa_interface_name (xtensa_isa isa, xtensa_interface intf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_INTERFACE (intisa, intf, NULL); + return intisa->interfaces[intf].name; +} + + +int +xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED); + return intisa->interfaces[intf].num_bits; +} + + +char +xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_INTERFACE (intisa, intf, 0); + return intisa->interfaces[intf].inout; +} + + +int +xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED); + if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0) + return 1; + return 0; +} + + +/* Functional Units. */ + + +#define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \ + do { \ + if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \ + { \ + xtisa_errno = xtensa_isa_bad_funcUnit; \ + strcpy (xtisa_error_msg, "invalid functional unit specifier"); \ + return (ERRVAL); \ + } \ + } while (0) + + +xtensa_funcUnit +xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + xtensa_lookup_entry entry, *result; + + if (!fname || !*fname) + { + xtisa_errno = xtensa_isa_bad_funcUnit; + strcpy (xtisa_error_msg, "invalid functional unit name"); + return XTENSA_UNDEFINED; + } + + entry.key = fname; + result = bsearch (&entry, intisa->funcUnit_lookup_table, + intisa->num_funcUnits, + sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); + + if (!result) + { + xtisa_errno = xtensa_isa_bad_funcUnit; + sprintf (xtisa_error_msg, + "functional unit \"%s\" not recognized", fname); + return XTENSA_UNDEFINED; + } + + return result->u.fun; +} + + +const char * +xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_FUNCUNIT (intisa, fun, NULL); + return intisa->funcUnits[fun].name; +} + + +int +xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun) +{ + xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; + CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED); + return intisa->funcUnits[fun].num_copies; } diff --git a/bfd/xtensa-modules.c b/bfd/xtensa-modules.c index e5d7682..bc0cf73 100644 --- a/bfd/xtensa-modules.c +++ b/bfd/xtensa-modules.c @@ -1,6088 +1,9101 @@ /* Xtensa configuration-specific ISA information. - Copyright 2003 Free Software Foundation, Inc. + Copyright 2003, 2004 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ +#include "ansidecl.h" #include <xtensa-isa.h> #include "xtensa-isa-internal.h" -#include "ansidecl.h" - -#define BPW 32 -#define WINDEX(_n) ((_n) / BPW) -#define BINDEX(_n) ((_n) %% BPW) - -static uint32 tie_do_reloc_l (uint32, uint32) ATTRIBUTE_UNUSED; -static uint32 tie_undo_reloc_l (uint32, uint32) ATTRIBUTE_UNUSED; - -static uint32 -tie_do_reloc_l (uint32 addr, uint32 pc) -{ - return (addr - pc); -} - -static uint32 -tie_undo_reloc_l (uint32 offset, uint32 pc) -{ - return (pc + offset); -} - -xtensa_opcode_internal** get_opcodes (void); -int get_num_opcodes (void); -int decode_insn (const xtensa_insnbuf); -int interface_version (void); - -uint32 get_bbi_field (const xtensa_insnbuf); -void set_bbi_field (xtensa_insnbuf, uint32); -uint32 get_bbi4_field (const xtensa_insnbuf); -void set_bbi4_field (xtensa_insnbuf, uint32); -uint32 get_i_field (const xtensa_insnbuf); -void set_i_field (xtensa_insnbuf, uint32); -uint32 get_imm12_field (const xtensa_insnbuf); -void set_imm12_field (xtensa_insnbuf, uint32); -uint32 get_imm12b_field (const xtensa_insnbuf); -void set_imm12b_field (xtensa_insnbuf, uint32); -uint32 get_imm16_field (const xtensa_insnbuf); -void set_imm16_field (xtensa_insnbuf, uint32); -uint32 get_imm4_field (const xtensa_insnbuf); -void set_imm4_field (xtensa_insnbuf, uint32); -uint32 get_imm6_field (const xtensa_insnbuf); -void set_imm6_field (xtensa_insnbuf, uint32); -uint32 get_imm6hi_field (const xtensa_insnbuf); -void set_imm6hi_field (xtensa_insnbuf, uint32); -uint32 get_imm6lo_field (const xtensa_insnbuf); -void set_imm6lo_field (xtensa_insnbuf, uint32); -uint32 get_imm7_field (const xtensa_insnbuf); -void set_imm7_field (xtensa_insnbuf, uint32); -uint32 get_imm7hi_field (const xtensa_insnbuf); -void set_imm7hi_field (xtensa_insnbuf, uint32); -uint32 get_imm7lo_field (const xtensa_insnbuf); -void set_imm7lo_field (xtensa_insnbuf, uint32); -uint32 get_imm8_field (const xtensa_insnbuf); -void set_imm8_field (xtensa_insnbuf, uint32); -uint32 get_m_field (const xtensa_insnbuf); -void set_m_field (xtensa_insnbuf, uint32); -uint32 get_mn_field (const xtensa_insnbuf); -void set_mn_field (xtensa_insnbuf, uint32); -uint32 get_n_field (const xtensa_insnbuf); -void set_n_field (xtensa_insnbuf, uint32); -uint32 get_none_field (const xtensa_insnbuf); -void set_none_field (xtensa_insnbuf, uint32); -uint32 get_offset_field (const xtensa_insnbuf); -void set_offset_field (xtensa_insnbuf, uint32); -uint32 get_op0_field (const xtensa_insnbuf); -void set_op0_field (xtensa_insnbuf, uint32); -uint32 get_op1_field (const xtensa_insnbuf); -void set_op1_field (xtensa_insnbuf, uint32); -uint32 get_op2_field (const xtensa_insnbuf); -void set_op2_field (xtensa_insnbuf, uint32); -uint32 get_r_field (const xtensa_insnbuf); -void set_r_field (xtensa_insnbuf, uint32); -uint32 get_s_field (const xtensa_insnbuf); -void set_s_field (xtensa_insnbuf, uint32); -uint32 get_sa4_field (const xtensa_insnbuf); -void set_sa4_field (xtensa_insnbuf, uint32); -uint32 get_sae_field (const xtensa_insnbuf); -void set_sae_field (xtensa_insnbuf, uint32); -uint32 get_sae4_field (const xtensa_insnbuf); -void set_sae4_field (xtensa_insnbuf, uint32); -uint32 get_sal_field (const xtensa_insnbuf); -void set_sal_field (xtensa_insnbuf, uint32); -uint32 get_sar_field (const xtensa_insnbuf); -void set_sar_field (xtensa_insnbuf, uint32); -uint32 get_sas_field (const xtensa_insnbuf); -void set_sas_field (xtensa_insnbuf, uint32); -uint32 get_sas4_field (const xtensa_insnbuf); -void set_sas4_field (xtensa_insnbuf, uint32); -uint32 get_sr_field (const xtensa_insnbuf); -void set_sr_field (xtensa_insnbuf, uint32); -uint32 get_t_field (const xtensa_insnbuf); -void set_t_field (xtensa_insnbuf, uint32); -uint32 get_thi3_field (const xtensa_insnbuf); -void set_thi3_field (xtensa_insnbuf, uint32); -uint32 get_z_field (const xtensa_insnbuf); -void set_z_field (xtensa_insnbuf, uint32); - -uint32 -get_bbi_field (const xtensa_insnbuf insn) + +/* Sysregs. */ + +static xtensa_sysreg_internal sysregs[] = { + { "LBEG", 0, 0 }, + { "LEND", 1, 0 }, + { "LCOUNT", 2, 0 }, + { "DDR", 104, 0 }, + { "176", 176, 0 }, + { "208", 208, 0 }, + { "INTERRUPT", 226, 0 }, + { "INTCLEAR", 227, 0 }, + { "CCOUNT", 234, 0 }, + { "PRID", 235, 0 }, + { "ICOUNT", 236, 0 }, + { "CCOMPARE0", 240, 0 }, + { "CCOMPARE1", 241, 0 }, + { "CCOMPARE2", 242, 0 }, + { "EPC1", 177, 0 }, + { "EPC2", 178, 0 }, + { "EPC3", 179, 0 }, + { "EPC4", 180, 0 }, + { "EXCSAVE1", 209, 0 }, + { "EXCSAVE2", 210, 0 }, + { "EXCSAVE3", 211, 0 }, + { "EXCSAVE4", 212, 0 }, + { "EPS2", 194, 0 }, + { "EPS3", 195, 0 }, + { "EPS4", 196, 0 }, + { "EXCCAUSE", 232, 0 }, + { "DEPC", 192, 0 }, + { "EXCVADDR", 238, 0 }, + { "WINDOWBASE", 72, 0 }, + { "WINDOWSTART", 73, 0 }, + { "SAR", 3, 0 }, + { "LITBASE", 5, 0 }, + { "PS", 230, 0 }, + { "MISC0", 244, 0 }, + { "MISC1", 245, 0 }, + { "INTENABLE", 228, 0 }, + { "DBREAKA0", 144, 0 }, + { "DBREAKC0", 160, 0 }, + { "DBREAKA1", 145, 0 }, + { "DBREAKC1", 161, 0 }, + { "IBREAKA0", 128, 0 }, + { "IBREAKA1", 129, 0 }, + { "IBREAKENABLE", 96, 0 }, + { "ICOUNTLEVEL", 237, 0 }, + { "DEBUGCAUSE", 233, 0 } +}; + +#define NUM_SYSREGS 45 +#define MAX_SPECIAL_REG 245 +#define MAX_USER_REG 0 + + +/* Processor states. */ + +static xtensa_state_internal states[] = { + { "LCOUNT", 32, 0 }, + { "PC", 32, 0 }, + { "ICOUNT", 32, 0 }, + { "DDR", 32, 0 }, + { "INTERRUPT", 17, 0 }, + { "CCOUNT", 32, 0 }, + { "XTSYNC", 1, 0 }, + { "EPC1", 32, 0 }, + { "EPC2", 32, 0 }, + { "EPC3", 32, 0 }, + { "EPC4", 32, 0 }, + { "EXCSAVE1", 32, 0 }, + { "EXCSAVE2", 32, 0 }, + { "EXCSAVE3", 32, 0 }, + { "EXCSAVE4", 32, 0 }, + { "EPS2", 13, 0 }, + { "EPS3", 13, 0 }, + { "EPS4", 13, 0 }, + { "EXCCAUSE", 6, 0 }, + { "PSINTLEVEL", 4, 0 }, + { "PSUM", 1, 0 }, + { "PSWOE", 1, 0 }, + { "PSEXCM", 1, 0 }, + { "DEPC", 32, 0 }, + { "EXCVADDR", 32, 0 }, + { "WindowBase", 4, 0 }, + { "WindowStart", 16, 0 }, + { "PSCALLINC", 2, 0 }, + { "PSOWB", 4, 0 }, + { "LBEG", 32, 0 }, + { "LEND", 32, 0 }, + { "SAR", 6, 0 }, + { "LITBADDR", 20, 0 }, + { "LITBEN", 1, 0 }, + { "MISC0", 32, 0 }, + { "MISC1", 32, 0 }, + { "InOCDMode", 1, 0 }, + { "INTENABLE", 17, 0 }, + { "DBREAKA0", 32, 0 }, + { "DBREAKC0", 8, 0 }, + { "DBREAKA1", 32, 0 }, + { "DBREAKC1", 8, 0 }, + { "IBREAKA0", 32, 0 }, + { "IBREAKA1", 32, 0 }, + { "IBREAKENABLE", 2, 0 }, + { "ICOUNTLEVEL", 4, 0 }, + { "DEBUGCAUSE", 6, 0 }, + { "DBNUM", 4, 0 }, + { "CCOMPARE0", 32, 0 }, + { "CCOMPARE1", 32, 0 }, + { "CCOMPARE2", 32, 0 } +}; + +#define NUM_STATES 51 + +/* Macros for xtensa_state numbers (for use in iclasses because the + state numbers are not available when the iclass table is generated). */ + +#define STATE_LCOUNT 0 +#define STATE_PC 1 +#define STATE_ICOUNT 2 +#define STATE_DDR 3 +#define STATE_INTERRUPT 4 +#define STATE_CCOUNT 5 +#define STATE_XTSYNC 6 +#define STATE_EPC1 7 +#define STATE_EPC2 8 +#define STATE_EPC3 9 +#define STATE_EPC4 10 +#define STATE_EXCSAVE1 11 +#define STATE_EXCSAVE2 12 +#define STATE_EXCSAVE3 13 +#define STATE_EXCSAVE4 14 +#define STATE_EPS2 15 +#define STATE_EPS3 16 +#define STATE_EPS4 17 +#define STATE_EXCCAUSE 18 +#define STATE_PSINTLEVEL 19 +#define STATE_PSUM 20 +#define STATE_PSWOE 21 +#define STATE_PSEXCM 22 +#define STATE_DEPC 23 +#define STATE_EXCVADDR 24 +#define STATE_WindowBase 25 +#define STATE_WindowStart 26 +#define STATE_PSCALLINC 27 +#define STATE_PSOWB 28 +#define STATE_LBEG 29 +#define STATE_LEND 30 +#define STATE_SAR 31 +#define STATE_LITBADDR 32 +#define STATE_LITBEN 33 +#define STATE_MISC0 34 +#define STATE_MISC1 35 +#define STATE_InOCDMode 36 +#define STATE_INTENABLE 37 +#define STATE_DBREAKA0 38 +#define STATE_DBREAKC0 39 +#define STATE_DBREAKA1 40 +#define STATE_DBREAKC1 41 +#define STATE_IBREAKA0 42 +#define STATE_IBREAKA1 43 +#define STATE_IBREAKENABLE 44 +#define STATE_ICOUNTLEVEL 45 +#define STATE_DEBUGCAUSE 46 +#define STATE_DBNUM 47 +#define STATE_CCOMPARE0 48 +#define STATE_CCOMPARE1 49 +#define STATE_CCOMPARE2 50 + + +/* Field definitions. */ + +static unsigned +Field_t_Slot_inst_get (const xtensa_insnbuf insn) +{ + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28); + return tie_t; +} + +static void +Field_t_Slot_inst_set (xtensa_insnbuf insn, uint32 val) +{ + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16); +} + +static unsigned +Field_s_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf0000) >> 16) | - ((insn[0] & 0x100) >> 4); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_bbi_field (xtensa_insnbuf insn, uint32 val) +static void +Field_s_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff0ffff) | ((val << 16) & 0xf0000); - insn[0] = (insn[0] & 0xfffffeff) | ((val << 4) & 0x100); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -get_bbi4_field (const xtensa_insnbuf insn) +static unsigned +Field_r_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x100) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -void -set_bbi4_field (xtensa_insnbuf insn, uint32 val) +static void +Field_r_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffffeff) | ((val << 8) & 0x100); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); } -uint32 -get_i_field (const xtensa_insnbuf insn) +static unsigned +Field_op2_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x80000) >> 19); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -void -set_i_field (xtensa_insnbuf insn, uint32 val) +static void +Field_op2_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff7ffff) | ((val << 19) & 0x80000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -get_imm12_field (const xtensa_insnbuf insn) +static unsigned +Field_op1_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xfff)); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + return tie_t; } -void -set_imm12_field (xtensa_insnbuf insn, uint32 val) +static void +Field_op1_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff000) | (val & 0xfff); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -get_imm12b_field (const xtensa_insnbuf insn) +static unsigned +Field_op0_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xff)) | - ((insn[0] & 0xf000) >> 4); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 8) >> 28); + return tie_t; } -void -set_imm12b_field (xtensa_insnbuf insn, uint32 val) +static void +Field_op0_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffffff00) | (val & 0xff); - insn[0] = (insn[0] & 0xffff0fff) | ((val << 4) & 0xf000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00000) | (tie_t << 20); } -uint32 -get_imm16_field (const xtensa_insnbuf insn) +static unsigned +Field_n_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xffff)); + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 12) >> 30); + return tie_t; } -void -set_imm16_field (xtensa_insnbuf insn, uint32 val) +static void +Field_n_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffff0000) | (val & 0xffff); + uint32 tie_t; + tie_t = (val << 30) >> 30; + insn[0] = (insn[0] & ~0xc0000) | (tie_t << 18); } -uint32 -get_imm4_field (const xtensa_insnbuf insn) +static unsigned +Field_m_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 14) >> 30); + return tie_t; } -void -set_imm4_field (xtensa_insnbuf insn, uint32 val) +static void +Field_m_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); + uint32 tie_t; + tie_t = (val << 30) >> 30; + insn[0] = (insn[0] & ~0x30000) | (tie_t << 16); } -uint32 -get_imm6_field (const xtensa_insnbuf insn) +static unsigned +Field_sr_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8) | - ((insn[0] & 0x30000) >> 12); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -void -set_imm6_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sr_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); - insn[0] = (insn[0] & 0xfffcffff) | ((val << 12) & 0x30000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -get_imm6hi_field (const xtensa_insnbuf insn) +static unsigned +Field_thi3_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x30000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 3) | ((insn[0] << 12) >> 29); + return tie_t; } -void -set_imm6hi_field (xtensa_insnbuf insn, uint32 val) +static void +Field_thi3_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffcffff) | ((val << 16) & 0x30000); + uint32 tie_t; + tie_t = (val << 29) >> 29; + insn[0] = (insn[0] & ~0xe0000) | (tie_t << 17); } -uint32 -get_imm6lo_field (const xtensa_insnbuf insn) +static unsigned +Field_op0_Slot_inst16a_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_imm6lo_field (xtensa_insnbuf insn, uint32 val) +static void +Field_op0_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -get_imm7_field (const xtensa_insnbuf insn) +static unsigned +Field_t_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8) | - ((insn[0] & 0x70000) >> 12); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -void -set_imm7_field (xtensa_insnbuf insn, uint32 val) +static void +Field_t_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); - insn[0] = (insn[0] & 0xfff8ffff) | ((val << 12) & 0x70000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); } -uint32 -get_imm7hi_field (const xtensa_insnbuf insn) +static unsigned +Field_r_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x70000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -void -set_imm7hi_field (xtensa_insnbuf insn, uint32 val) +static void +Field_r_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff8ffff) | ((val << 16) & 0x70000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -get_imm7lo_field (const xtensa_insnbuf insn) +static unsigned +Field_op0_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_imm7lo_field (xtensa_insnbuf insn, uint32 val) +static void +Field_op0_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -get_imm8_field (const xtensa_insnbuf insn) +static unsigned +Field_z_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xff)); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 21) >> 31); + return tie_t; } -void -set_imm8_field (xtensa_insnbuf insn, uint32 val) +static void +Field_z_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffffff00) | (val & 0xff); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x400) | (tie_t << 10); } -uint32 -get_m_field (const xtensa_insnbuf insn) +static unsigned +Field_i_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x30000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31); + return tie_t; } -void -set_m_field (xtensa_insnbuf insn, uint32 val) +static void +Field_i_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffcffff) | ((val << 16) & 0x30000); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x800) | (tie_t << 11); } -uint32 -get_mn_field (const xtensa_insnbuf insn) +static unsigned +Field_s_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x30000) >> 16) | - ((insn[0] & 0xc0000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + return tie_t; } -void -set_mn_field (xtensa_insnbuf insn, uint32 val) +static void +Field_s_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffcffff) | ((val << 16) & 0x30000); - insn[0] = (insn[0] & 0xfff3ffff) | ((val << 16) & 0xc0000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -get_n_field (const xtensa_insnbuf insn) +static unsigned +Field_t_Slot_inst16a_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xc0000) >> 18); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -void -set_n_field (xtensa_insnbuf insn, uint32 val) +static void +Field_t_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff3ffff) | ((val << 18) & 0xc0000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); } -uint32 -get_none_field (const xtensa_insnbuf insn) +static unsigned +Field_bbi4_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x0)); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 23) >> 31); + return tie_t; } -void -set_none_field (xtensa_insnbuf insn, uint32 val) +static void +Field_bbi4_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffffffff) | (val & 0x0); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x100) | (tie_t << 8); } -uint32 -get_offset_field (const xtensa_insnbuf insn) +static unsigned +Field_bbi_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x3ffff)); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 23) >> 31); + tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28); + return tie_t; } -void -set_offset_field (xtensa_insnbuf insn, uint32 val) +static void +Field_bbi_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffc0000) | (val & 0x3ffff); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16); + tie_t = (val << 27) >> 31; + insn[0] = (insn[0] & ~0x100) | (tie_t << 8); } -uint32 -get_op0_field (const xtensa_insnbuf insn) +static unsigned +Field_imm12_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00000) >> 20); + unsigned tie_t = 0; + tie_t = (tie_t << 12) | ((insn[0] << 20) >> 20); + return tie_t; } -void -set_op0_field (xtensa_insnbuf insn, uint32 val) +static void +Field_imm12_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xff0fffff) | ((val << 20) & 0xf00000); + uint32 tie_t; + tie_t = (val << 20) >> 20; + insn[0] = (insn[0] & ~0xfff) | (tie_t << 0); } -uint32 -get_op1_field (const xtensa_insnbuf insn) +static unsigned +Field_imm8_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf0) >> 4); + unsigned tie_t = 0; + tie_t = (tie_t << 8) | ((insn[0] << 24) >> 24); + return tie_t; } -void -set_op1_field (xtensa_insnbuf insn, uint32 val) +static void +Field_imm8_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffffff0f) | ((val << 4) & 0xf0); + uint32 tie_t; + tie_t = (val << 24) >> 24; + insn[0] = (insn[0] & ~0xff) | (tie_t << 0); } -uint32 -get_op2_field (const xtensa_insnbuf insn) +static unsigned +Field_s_Slot_inst16a_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf)); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + return tie_t; } -void -set_op2_field (xtensa_insnbuf insn, uint32 val) +static void +Field_s_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffffff0) | (val & 0xf); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -get_r_field (const xtensa_insnbuf insn) +static unsigned +Field_imm12b_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + tie_t = (tie_t << 8) | ((insn[0] << 24) >> 24); + return tie_t; } -void -set_r_field (xtensa_insnbuf insn, uint32 val) +static void +Field_imm12b_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); + uint32 tie_t; + tie_t = (val << 24) >> 24; + insn[0] = (insn[0] & ~0xff) | (tie_t << 0); + tie_t = (val << 20) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -get_s_field (const xtensa_insnbuf insn) +static unsigned +Field_imm16_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf000) >> 12); + unsigned tie_t = 0; + tie_t = (tie_t << 16) | ((insn[0] << 16) >> 16); + return tie_t; } -void -set_s_field (xtensa_insnbuf insn, uint32 val) +static void +Field_imm16_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffff0fff) | ((val << 12) & 0xf000); + uint32 tie_t; + tie_t = (val << 16) >> 16; + insn[0] = (insn[0] & ~0xffff) | (tie_t << 0); } -uint32 -get_sa4_field (const xtensa_insnbuf insn) +static unsigned +Field_offset_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x1)); + unsigned tie_t = 0; + tie_t = (tie_t << 18) | ((insn[0] << 14) >> 14); + return tie_t; } -void -set_sa4_field (xtensa_insnbuf insn, uint32 val) +static void +Field_offset_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffffffe) | (val & 0x1); + uint32 tie_t; + tie_t = (val << 14) >> 14; + insn[0] = (insn[0] & ~0x3ffff) | (tie_t << 0); } -uint32 -get_sae_field (const xtensa_insnbuf insn) +static unsigned +Field_r_Slot_inst16a_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf000) >> 12) | - ((insn[0] & 0x10)); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -void -set_sae_field (xtensa_insnbuf insn, uint32 val) +static void +Field_r_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffff0fff) | ((val << 12) & 0xf000); - insn[0] = (insn[0] & 0xffffffef) | (val & 0x10); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -get_sae4_field (const xtensa_insnbuf insn) +static unsigned +Field_sa4_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x10) >> 4); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 31) >> 31); + return tie_t; } -void -set_sae4_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sa4_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffffffef) | ((val << 4) & 0x10); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x1) | (tie_t << 0); } -uint32 -get_sal_field (const xtensa_insnbuf insn) +static unsigned +Field_sae4_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf0000) >> 16) | - ((insn[0] & 0x1) << 4); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31); + return tie_t; } -void -set_sal_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sae4_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff0ffff) | ((val << 16) & 0xf0000); - insn[0] = (insn[0] & 0xfffffffe) | ((val >> 4) & 0x1); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x10) | (tie_t << 4); } -uint32 -get_sar_field (const xtensa_insnbuf insn) +static unsigned +Field_sae_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf000) >> 12) | - ((insn[0] & 0x1) << 4); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 27) >> 31); + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_sar_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sae_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffff0fff) | ((val << 12) & 0xf000); - insn[0] = (insn[0] & 0xfffffffe) | ((val >> 4) & 0x1); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); + tie_t = (val << 27) >> 31; + insn[0] = (insn[0] & ~0x10) | (tie_t << 4); } -uint32 -get_sas_field (const xtensa_insnbuf insn) +static unsigned +Field_sal_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf000) >> 12) | - ((insn[0] & 0x10000) >> 12); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 31) >> 31); + tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28); + return tie_t; } -void -set_sas_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sal_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xffff0fff) | ((val << 12) & 0xf000); - insn[0] = (insn[0] & 0xfffeffff) | ((val << 12) & 0x10000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16); + tie_t = (val << 27) >> 31; + insn[0] = (insn[0] & ~0x1) | (tie_t << 0); } -uint32 -get_sas4_field (const xtensa_insnbuf insn) +static unsigned +Field_sargt_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x10000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 31) >> 31); + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_sas4_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sargt_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffeffff) | ((val << 16) & 0x10000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); + tie_t = (val << 27) >> 31; + insn[0] = (insn[0] & ~0x1) | (tie_t << 0); } -uint32 -get_sr_field (const xtensa_insnbuf insn) +static unsigned +Field_sas4_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf00) >> 8) | - ((insn[0] & 0xf000) >> 8); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31); + return tie_t; } -void -set_sr_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sas4_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfffff0ff) | ((val << 8) & 0xf00); - insn[0] = (insn[0] & 0xffff0fff) | ((val << 8) & 0xf000); + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x10000) | (tie_t << 16); } -uint32 -get_t_field (const xtensa_insnbuf insn) +static unsigned +Field_sas_Slot_inst_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xf0000) >> 16); + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 15) >> 31); + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + return tie_t; } -void -set_t_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sas_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff0ffff) | ((val << 16) & 0xf0000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); + tie_t = (val << 27) >> 31; + insn[0] = (insn[0] & ~0x10000) | (tie_t << 16); } -uint32 -get_thi3_field (const xtensa_insnbuf insn) +static unsigned +Field_sr_Slot_inst16a_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0xe0000) >> 17); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -void -set_thi3_field (xtensa_insnbuf insn, uint32 val) +static void +Field_sr_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - insn[0] = (insn[0] & 0xfff1ffff) | ((val << 17) & 0xe0000); + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -get_z_field (const xtensa_insnbuf insn) +static unsigned +Field_sr_Slot_inst16b_get (const xtensa_insnbuf insn) { - return ((insn[0] & 0x40000) >> 18); + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -void -set_z_field (xtensa_insnbuf insn, uint32 val) -{ - insn[0] = (insn[0] & 0xfffbffff) | ((val << 18) & 0x40000); -} - -uint32 decode_b4constu (uint32); -xtensa_encode_result encode_b4constu (uint32 *); -uint32 decode_simm8x256 (uint32); -xtensa_encode_result encode_simm8x256 (uint32 *); -uint32 decode_soffset (uint32); -xtensa_encode_result encode_soffset (uint32 *); -uint32 decode_imm4 (uint32); -xtensa_encode_result encode_imm4 (uint32 *); -uint32 decode_op0 (uint32); -xtensa_encode_result encode_op0 (uint32 *); -uint32 decode_op1 (uint32); -xtensa_encode_result encode_op1 (uint32 *); -uint32 decode_imm6 (uint32); -xtensa_encode_result encode_imm6 (uint32 *); -uint32 decode_op2 (uint32); -xtensa_encode_result encode_op2 (uint32 *); -uint32 decode_imm7 (uint32); -xtensa_encode_result encode_imm7 (uint32 *); -uint32 decode_simm4 (uint32); -xtensa_encode_result encode_simm4 (uint32 *); -uint32 decode_ai4const (uint32); -xtensa_encode_result encode_ai4const (uint32 *); -uint32 decode_imm8 (uint32); -xtensa_encode_result encode_imm8 (uint32 *); -uint32 decode_sae (uint32); -xtensa_encode_result encode_sae (uint32 *); -uint32 decode_imm7lo (uint32); -xtensa_encode_result encode_imm7lo (uint32 *); -uint32 decode_simm7 (uint32); -xtensa_encode_result encode_simm7 (uint32 *); -uint32 decode_simm8 (uint32); -xtensa_encode_result encode_simm8 (uint32 *); -uint32 decode_uimm12x8 (uint32); -xtensa_encode_result encode_uimm12x8 (uint32 *); -uint32 decode_sal (uint32); -xtensa_encode_result encode_sal (uint32 *); -uint32 decode_uimm6 (uint32); -xtensa_encode_result encode_uimm6 (uint32 *); -uint32 decode_sas4 (uint32); -xtensa_encode_result encode_sas4 (uint32 *); -uint32 decode_uimm8 (uint32); -xtensa_encode_result encode_uimm8 (uint32 *); -uint32 decode_uimm16x4 (uint32); -xtensa_encode_result encode_uimm16x4 (uint32 *); -uint32 decode_sar (uint32); -xtensa_encode_result encode_sar (uint32 *); -uint32 decode_sa4 (uint32); -xtensa_encode_result encode_sa4 (uint32 *); -uint32 decode_sas (uint32); -xtensa_encode_result encode_sas (uint32 *); -uint32 decode_imm6hi (uint32); -xtensa_encode_result encode_imm6hi (uint32 *); -uint32 decode_bbi (uint32); -xtensa_encode_result encode_bbi (uint32 *); -uint32 decode_uimm8x2 (uint32); -xtensa_encode_result encode_uimm8x2 (uint32 *); -uint32 decode_uimm8x4 (uint32); -xtensa_encode_result encode_uimm8x4 (uint32 *); -uint32 decode_msalp32 (uint32); -xtensa_encode_result encode_msalp32 (uint32 *); -uint32 decode_bbi4 (uint32); -xtensa_encode_result encode_bbi4 (uint32 *); -uint32 decode_op2p1 (uint32); -xtensa_encode_result encode_op2p1 (uint32 *); -uint32 decode_soffsetx4 (uint32); -xtensa_encode_result encode_soffsetx4 (uint32 *); -uint32 decode_imm6lo (uint32); -xtensa_encode_result encode_imm6lo (uint32 *); -uint32 decode_imm12 (uint32); -xtensa_encode_result encode_imm12 (uint32 *); -uint32 decode_b4const (uint32); -xtensa_encode_result encode_b4const (uint32 *); -uint32 decode_i (uint32); -xtensa_encode_result encode_i (uint32 *); -uint32 decode_imm16 (uint32); -xtensa_encode_result encode_imm16 (uint32 *); -uint32 decode_mn (uint32); -xtensa_encode_result encode_mn (uint32 *); -uint32 decode_m (uint32); -xtensa_encode_result encode_m (uint32 *); -uint32 decode_n (uint32); -xtensa_encode_result encode_n (uint32 *); -uint32 decode_none (uint32); -xtensa_encode_result encode_none (uint32 *); -uint32 decode_imm12b (uint32); -xtensa_encode_result encode_imm12b (uint32 *); -uint32 decode_r (uint32); -xtensa_encode_result encode_r (uint32 *); -uint32 decode_s (uint32); -xtensa_encode_result encode_s (uint32 *); -uint32 decode_t (uint32); -xtensa_encode_result encode_t (uint32 *); -uint32 decode_thi3 (uint32); -xtensa_encode_result encode_thi3 (uint32 *); -uint32 decode_sae4 (uint32); -xtensa_encode_result encode_sae4 (uint32 *); -uint32 decode_offset (uint32); -xtensa_encode_result encode_offset (uint32 *); -uint32 decode_imm7hi (uint32); -xtensa_encode_result encode_imm7hi (uint32 *); -uint32 decode_uimm4x16 (uint32); -xtensa_encode_result encode_uimm4x16 (uint32 *); -uint32 decode_simm12b (uint32); -xtensa_encode_result encode_simm12b (uint32 *); -uint32 decode_lsi4x4 (uint32); -xtensa_encode_result encode_lsi4x4 (uint32 *); -uint32 decode_z (uint32); -xtensa_encode_result encode_z (uint32 *); -uint32 decode_simm12 (uint32); -xtensa_encode_result encode_simm12 (uint32 *); -uint32 decode_sr (uint32); -xtensa_encode_result encode_sr (uint32 *); -uint32 decode_nimm4x2 (uint32); -xtensa_encode_result encode_nimm4x2 (uint32 *); - - -static const uint32 b4constu_table[] = { - 32768, - 65536, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 10, - 12, - 16, - 32, - 64, - 128, - 256 -}; +static void +Field_sr_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) +{ + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); +} -uint32 -decode_b4constu (uint32 val) +static unsigned +Field_st_Slot_inst_get (const xtensa_insnbuf insn) { - val = b4constu_table[val]; - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 16) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 12) >> 28); + return tie_t; } -xtensa_encode_result -encode_b4constu (uint32 *valp) +static void +Field_st_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - unsigned i; - for (i = 0; i < (1 << 4); i += 1) - if (b4constu_table[i] == val) goto found; - return xtensa_encode_result_not_in_table; - found: - val = i; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf0000) | (tie_t << 16); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf000) | (tie_t << 12); } -uint32 -decode_simm8x256 (uint32 val) +static unsigned +Field_st_Slot_inst16a_get (const xtensa_insnbuf insn) { - val = (val ^ 0x80) - 0x80; - val <<= 8; - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -xtensa_encode_result -encode_simm8x256 (uint32 *valp) +static void +Field_st_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val & ((1 << 8) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 8; - if (((val + (1 << 7)) >> 8) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -decode_soffset (uint32 val) +static unsigned +Field_st_Slot_inst16b_get (const xtensa_insnbuf insn) { - val = (val ^ 0x20000) - 0x20000; - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 24) >> 28); + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -xtensa_encode_result -encode_soffset (uint32 *valp) +static void +Field_st_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if (((val + (1 << 17)) >> 18) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); + tie_t = (val << 24) >> 28; + insn[0] = (insn[0] & ~0xf0) | (tie_t << 4); } -uint32 -decode_imm4 (uint32 val) +static unsigned +Field_imm4_Slot_inst_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 20) >> 28); + return tie_t; } -xtensa_encode_result -encode_imm4 (uint32 *valp) +static void +Field_imm4_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf00) | (tie_t << 8); } -uint32 -decode_op0 (uint32 val) +static unsigned +Field_imm4_Slot_inst16a_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -xtensa_encode_result -encode_op0 (uint32 *valp) +static void +Field_imm4_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -decode_op1 (uint32 val) +static unsigned +Field_imm4_Slot_inst16b_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -xtensa_encode_result -encode_op1 (uint32 *valp) +static void +Field_imm4_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -decode_imm6 (uint32 val) +static unsigned +Field_mn_Slot_inst_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 12) >> 30); + tie_t = (tie_t << 2) | ((insn[0] << 14) >> 30); + return tie_t; } -xtensa_encode_result -encode_imm6 (uint32 *valp) +static void +Field_mn_Slot_inst_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 6) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 30) >> 30; + insn[0] = (insn[0] & ~0x30000) | (tie_t << 16); + tie_t = (val << 28) >> 30; + insn[0] = (insn[0] & ~0xc0000) | (tie_t << 18); } -uint32 -decode_op2 (uint32 val) +static unsigned +Field_i_Slot_inst16a_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 20) >> 31); + return tie_t; } -xtensa_encode_result -encode_op2 (uint32 *valp) +static void +Field_i_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x800) | (tie_t << 11); } -uint32 -decode_imm7 (uint32 val) +static unsigned +Field_imm6lo_Slot_inst16a_get (const xtensa_insnbuf insn) { - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -xtensa_encode_result -encode_imm7 (uint32 *valp) +static void +Field_imm6lo_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if ((val >> 7) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -uint32 -decode_simm4 (uint32 val) +static unsigned +Field_imm6lo_Slot_inst16b_get (const xtensa_insnbuf insn) { - val = (val ^ 0x8) - 0x8; - return val; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -xtensa_encode_result -encode_simm4 (uint32 *valp) +static void +Field_imm6lo_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - uint32 val = *valp; - if (((val + (1 << 3)) >> 4) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -static const uint32 ai4const_table[] = { - -1, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15 -}; +static unsigned +Field_imm6hi_Slot_inst16a_get (const xtensa_insnbuf insn) +{ + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30); + return tie_t; +} -uint32 -decode_ai4const (uint32 val) +static void +Field_imm6hi_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - val = ai4const_table[val]; - return val; + uint32 tie_t; + tie_t = (val << 30) >> 30; + insn[0] = (insn[0] & ~0x300) | (tie_t << 8); } -xtensa_encode_result -encode_ai4const (uint32 *valp) +static unsigned +Field_imm6hi_Slot_inst16b_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - unsigned i; - for (i = 0; i < (1 << 4); i += 1) - if (ai4const_table[i] == val) goto found; - return xtensa_encode_result_not_in_table; - found: - val = i; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30); + return tie_t; } -uint32 -decode_imm8 (uint32 val) +static void +Field_imm6hi_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 30) >> 30; + insn[0] = (insn[0] & ~0x300) | (tie_t << 8); } -xtensa_encode_result -encode_imm8 (uint32 *valp) +static unsigned +Field_imm7lo_Slot_inst16a_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 8) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_sae (uint32 val) +static void +Field_imm7lo_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -xtensa_encode_result -encode_sae (uint32 *valp) +static unsigned +Field_imm7lo_Slot_inst16b_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 5) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_imm7lo (uint32 val) +static void +Field_imm7lo_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); } -xtensa_encode_result -encode_imm7lo (uint32 *valp) +static unsigned +Field_imm7hi_Slot_inst16a_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29); + return tie_t; } -uint32 -decode_simm7 (uint32 val) +static void +Field_imm7hi_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - if (val > 95) - val |= -32; - return val; + uint32 tie_t; + tie_t = (val << 29) >> 29; + insn[0] = (insn[0] & ~0x700) | (tie_t << 8); } -xtensa_encode_result -encode_simm7 (uint32 *valp) +static unsigned +Field_imm7hi_Slot_inst16b_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((signed int) val < -32) - return xtensa_encode_result_too_low; - if ((signed int) val > 95) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29); + return tie_t; } -uint32 -decode_simm8 (uint32 val) +static void +Field_imm7hi_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - val = (val ^ 0x80) - 0x80; - return val; + uint32 tie_t; + tie_t = (val << 29) >> 29; + insn[0] = (insn[0] & ~0x700) | (tie_t << 8); } -xtensa_encode_result -encode_simm8 (uint32 *valp) +static unsigned +Field_z_Slot_inst16a_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if (((val + (1 << 7)) >> 8) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 1) | ((insn[0] << 21) >> 31); + return tie_t; } -uint32 -decode_uimm12x8 (uint32 val) +static void +Field_z_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - val <<= 3; - return val; + uint32 tie_t; + tie_t = (val << 31) >> 31; + insn[0] = (insn[0] & ~0x400) | (tie_t << 10); } -xtensa_encode_result -encode_uimm12x8 (uint32 *valp) +static unsigned +Field_imm6_Slot_inst16a_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val & ((1 << 3) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 3; - if ((val >> 12) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_sal (uint32 val) +static void +Field_imm6_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 26) >> 30; + insn[0] = (insn[0] & ~0x300) | (tie_t << 8); } -xtensa_encode_result -encode_sal (uint32 *valp) +static unsigned +Field_imm6_Slot_inst16b_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 5) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 2) | ((insn[0] << 22) >> 30); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_uimm6 (uint32 val) +static void +Field_imm6_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 26) >> 30; + insn[0] = (insn[0] & ~0x300) | (tie_t << 8); } -xtensa_encode_result -encode_uimm6 (uint32 *valp) +static unsigned +Field_imm7_Slot_inst16a_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 6) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_sas4 (uint32 val) +static void +Field_imm7_Slot_inst16a_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 25) >> 29; + insn[0] = (insn[0] & ~0x700) | (tie_t << 8); } -xtensa_encode_result -encode_sas4 (uint32 *valp) +static unsigned +Field_imm7_Slot_inst16b_get (const xtensa_insnbuf insn) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned tie_t = 0; + tie_t = (tie_t << 3) | ((insn[0] << 21) >> 29); + tie_t = (tie_t << 4) | ((insn[0] << 28) >> 28); + return tie_t; } -uint32 -decode_uimm8 (uint32 val) +static void +Field_imm7_Slot_inst16b_set (xtensa_insnbuf insn, uint32 val) { - return val; + uint32 tie_t; + tie_t = (val << 28) >> 28; + insn[0] = (insn[0] & ~0xf) | (tie_t << 0); + tie_t = (val << 25) >> 29; + insn[0] = (insn[0] & ~0x700) | (tie_t << 8); } -xtensa_encode_result -encode_uimm8 (uint32 *valp) +static void +Implicit_Field_set (xtensa_insnbuf insn ATTRIBUTE_UNUSED, + uint32 val ATTRIBUTE_UNUSED) { - uint32 val = *valp; - if ((val >> 8) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + /* Do nothing. */ } -uint32 -decode_uimm16x4 (uint32 val) +static unsigned +Implicit_Field_ar0_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED) { - val |= -1 << 16; - val <<= 2; - return val; + return 0; } -xtensa_encode_result -encode_uimm16x4 (uint32 *valp) +static unsigned +Implicit_Field_ar4_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED) { - uint32 val = *valp; - if ((val & ((1 << 2) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 2; - if ((signed int) val >> 16 != -1) - { - if ((signed int) val >= 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + return 4; } -uint32 -decode_sar (uint32 val) +static unsigned +Implicit_Field_ar8_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED) { - return val; + return 8; } -xtensa_encode_result -encode_sar (uint32 *valp) +static unsigned +Implicit_Field_ar12_get (const xtensa_insnbuf insn ATTRIBUTE_UNUSED) { - uint32 val = *valp; - if ((val >> 5) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + return 12; } -uint32 -decode_sa4 (uint32 val) + +/* Functional units. */ + +static xtensa_funcUnit_internal funcUnits[] = { + +}; + + +/* Register files. */ + +static xtensa_regfile_internal regfiles[] = { + { "AR", "a", 0, 32, 64 } +}; + + +/* Interfaces. */ + +static xtensa_interface_internal interfaces[] = { + +}; + + +/* Constant tables. */ + +/* constant table ai4c */ +static const unsigned CONST_TBL_ai4c_0[] = { + 0xffffffff, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0x9, + 0xa, + 0xb, + 0xc, + 0xd, + 0xe, + 0xf, + 0 +}; + +/* constant table b4c */ +static const unsigned CONST_TBL_b4c_0[] = { + 0xffffffff, + 0x1, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0xa, + 0xc, + 0x10, + 0x20, + 0x40, + 0x80, + 0x100, + 0 +}; + +/* constant table b4cu */ +static const unsigned CONST_TBL_b4cu_0[] = { + 0x8000, + 0x10000, + 0x2, + 0x3, + 0x4, + 0x5, + 0x6, + 0x7, + 0x8, + 0xa, + 0xc, + 0x10, + 0x20, + 0x40, + 0x80, + 0x100, + 0 +}; + + +/* Instruction operands. */ + +static int +Operand_soffsetx4_decode (uint32 *valp) { - return val; + unsigned soffsetx4_0, offset_0; + offset_0 = *valp & 0x3ffff; + soffsetx4_0 = 0x4 + ((((int) offset_0 << 14) >> 14) << 2); + *valp = soffsetx4_0; + return 0; } -xtensa_encode_result -encode_sa4 (uint32 *valp) +static int +Operand_soffsetx4_encode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned offset_0, soffsetx4_0; + soffsetx4_0 = *valp; + offset_0 = ((soffsetx4_0 - 0x4) >> 2) & 0x3ffff; + *valp = offset_0; + return 0; } -uint32 -decode_sas (uint32 val) +static int +Operand_soffsetx4_ator (uint32 *valp, uint32 pc) { - return val; + *valp -= (pc & ~0x3); + return 0; } -xtensa_encode_result -encode_sas (uint32 *valp) +static int +Operand_soffsetx4_rtoa (uint32 *valp, uint32 pc) { - uint32 val = *valp; - if ((val >> 5) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + *valp += (pc & ~0x3); + return 0; } -uint32 -decode_imm6hi (uint32 val) +static int +Operand_uimm12x8_decode (uint32 *valp) { - return val; + unsigned uimm12x8_0, imm12_0; + imm12_0 = *valp & 0xfff; + uimm12x8_0 = imm12_0 << 3; + *valp = uimm12x8_0; + return 0; } -xtensa_encode_result -encode_imm6hi (uint32 *valp) +static int +Operand_uimm12x8_encode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 2) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned imm12_0, uimm12x8_0; + uimm12x8_0 = *valp; + imm12_0 = ((uimm12x8_0 >> 3) & 0xfff); + *valp = imm12_0; + return 0; } -uint32 -decode_bbi (uint32 val) +static int +Operand_simm4_decode (uint32 *valp) { - return val; + unsigned simm4_0, mn_0; + mn_0 = *valp & 0xf; + simm4_0 = ((int) mn_0 << 28) >> 28; + *valp = simm4_0; + return 0; } -xtensa_encode_result -encode_bbi (uint32 *valp) +static int +Operand_simm4_encode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 5) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned mn_0, simm4_0; + simm4_0 = *valp; + mn_0 = (simm4_0 & 0xf); + *valp = mn_0; + return 0; } -uint32 -decode_uimm8x2 (uint32 val) +static int +Operand_arr_decode (uint32 *valp ATTRIBUTE_UNUSED) { - val <<= 1; - return val; + return 0; } -xtensa_encode_result -encode_uimm8x2 (uint32 *valp) +static int +Operand_arr_encode (uint32 *valp) { - uint32 val = *valp; - if ((val & ((1 << 1) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 1; - if ((val >> 8) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + int error; + error = (*valp & ~0xf) != 0; + return error; } -uint32 -decode_uimm8x4 (uint32 val) +static int +Operand_ars_decode (uint32 *valp ATTRIBUTE_UNUSED) { - val <<= 2; - return val; + return 0; } -xtensa_encode_result -encode_uimm8x4 (uint32 *valp) +static int +Operand_ars_encode (uint32 *valp) { - uint32 val = *valp; - if ((val & ((1 << 2) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 2; - if ((val >> 8) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + int error; + error = (*valp & ~0xf) != 0; + return error; } -static const uint32 mip32const_table[] = { - 32, - 31, - 30, - 29, - 28, - 27, - 26, - 25, - 24, - 23, - 22, - 21, - 20, - 19, - 18, - 17, - 16, - 15, - 14, - 13, - 12, - 11, - 10, - 9, - 8, - 7, - 6, - 5, - 4, - 3, - 2, - 1 -}; +static int +Operand_art_decode (uint32 *valp ATTRIBUTE_UNUSED) +{ + return 0; +} -uint32 -decode_msalp32 (uint32 val) +static int +Operand_art_encode (uint32 *valp) { - val = mip32const_table[val]; - return val; + int error; + error = (*valp & ~0xf) != 0; + return error; } -xtensa_encode_result -encode_msalp32 (uint32 *valp) +static int +Operand_ar0_decode (uint32 *valp ATTRIBUTE_UNUSED) { - uint32 val = *valp; - unsigned i; - for (i = 0; i < (1 << 5); i += 1) - if (mip32const_table[i] == val) goto found; - return xtensa_encode_result_not_in_table; - found: - val = i; - *valp = val; - return xtensa_encode_result_ok; + return 0; } -uint32 -decode_bbi4 (uint32 val) +static int +Operand_ar0_encode (uint32 *valp) { - return val; + int error; + error = (*valp & ~0x3f) != 0; + return error; } -xtensa_encode_result -encode_bbi4 (uint32 *valp) +static int +Operand_ar4_decode (uint32 *valp ATTRIBUTE_UNUSED) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + return 0; } -static const uint32 i4p1const_table[] = { - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16 -}; - -uint32 -decode_op2p1 (uint32 val) -{ - val = i4p1const_table[val]; - return val; -} - -xtensa_encode_result -encode_op2p1 (uint32 *valp) -{ - uint32 val = *valp; - unsigned i; - for (i = 0; i < (1 << 4); i += 1) - if (i4p1const_table[i] == val) goto found; - return xtensa_encode_result_not_in_table; - found: - val = i; - *valp = val; - return xtensa_encode_result_ok; -} - -uint32 -decode_soffsetx4 (uint32 val) -{ - val = (val ^ 0x20000) - 0x20000; - val <<= 2; - return val; -} - -xtensa_encode_result -encode_soffsetx4 (uint32 *valp) -{ - uint32 val = *valp; - if ((val & ((1 << 2) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 2; - if (((val + (1 << 17)) >> 18) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; +static int +Operand_ar4_encode (uint32 *valp) +{ + int error; + error = (*valp & ~0x3f) != 0; + return error; } -uint32 -decode_imm6lo (uint32 val) +static int +Operand_ar8_decode (uint32 *valp ATTRIBUTE_UNUSED) { - return val; + return 0; } -xtensa_encode_result -encode_imm6lo (uint32 *valp) +static int +Operand_ar8_encode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + int error; + error = (*valp & ~0x3f) != 0; + return error; } -uint32 -decode_imm12 (uint32 val) +static int +Operand_ar12_decode (uint32 *valp ATTRIBUTE_UNUSED) { - return val; + return 0; } -xtensa_encode_result -encode_imm12 (uint32 *valp) +static int +Operand_ar12_encode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 12) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + int error; + error = (*valp & ~0x3f) != 0; + return error; } -static const uint32 b4const_table[] = { - -1, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 10, - 12, - 16, - 32, - 64, - 128, - 256 -}; +static int +Operand_ars_entry_decode (uint32 *valp ATTRIBUTE_UNUSED) +{ + return 0; +} -uint32 -decode_b4const (uint32 val) +static int +Operand_ars_entry_encode (uint32 *valp) { - val = b4const_table[val]; - return val; + int error; + error = (*valp & ~0x3f) != 0; + return error; } -xtensa_encode_result -encode_b4const (uint32 *valp) +static int +Operand_immrx4_decode (uint32 *valp) { - uint32 val = *valp; - unsigned i; - for (i = 0; i < (1 << 4); i += 1) - if (b4const_table[i] == val) goto found; - return xtensa_encode_result_not_in_table; - found: - val = i; - *valp = val; - return xtensa_encode_result_ok; + unsigned immrx4_0, r_0; + r_0 = *valp & 0xf; + immrx4_0 = ((((0xfffffff)) << 4) | r_0) << 2; + *valp = immrx4_0; + return 0; } -uint32 -decode_i (uint32 val) +static int +Operand_immrx4_encode (uint32 *valp) { - return val; + unsigned r_0, immrx4_0; + immrx4_0 = *valp; + r_0 = ((immrx4_0 >> 2) & 0xf); + *valp = r_0; + return 0; } -xtensa_encode_result -encode_i (uint32 *valp) +static int +Operand_lsi4x4_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned lsi4x4_0, r_0; + r_0 = *valp & 0xf; + lsi4x4_0 = r_0 << 2; + *valp = lsi4x4_0; + return 0; } -uint32 -decode_imm16 (uint32 val) +static int +Operand_lsi4x4_encode (uint32 *valp) { - return val; + unsigned r_0, lsi4x4_0; + lsi4x4_0 = *valp; + r_0 = ((lsi4x4_0 >> 2) & 0xf); + *valp = r_0; + return 0; } -xtensa_encode_result -encode_imm16 (uint32 *valp) +static int +Operand_simm7_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 16) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned simm7_0, imm7_0; + imm7_0 = *valp & 0x7f; + simm7_0 = ((((-((((imm7_0 >> 6) & 1)) & (((imm7_0 >> 5) & 1)))) & 0x1ffffff)) << 7) | imm7_0; + *valp = simm7_0; + return 0; } -uint32 -decode_mn (uint32 val) +static int +Operand_simm7_encode (uint32 *valp) { - return val; + unsigned imm7_0, simm7_0; + simm7_0 = *valp; + imm7_0 = (simm7_0 & 0x7f); + *valp = imm7_0; + return 0; } -xtensa_encode_result -encode_mn (uint32 *valp) +static int +Operand_uimm6_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned uimm6_0, imm6_0; + imm6_0 = *valp & 0x3f; + uimm6_0 = 0x4 + ((((0)) << 6) | imm6_0); + *valp = uimm6_0; + return 0; } -uint32 -decode_m (uint32 val) +static int +Operand_uimm6_encode (uint32 *valp) { - return val; + unsigned imm6_0, uimm6_0; + uimm6_0 = *valp; + imm6_0 = (uimm6_0 - 0x4) & 0x3f; + *valp = imm6_0; + return 0; } -xtensa_encode_result -encode_m (uint32 *valp) +static int +Operand_uimm6_ator (uint32 *valp, uint32 pc) { - uint32 val = *valp; - if ((val >> 2) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + *valp -= pc; + return 0; } -uint32 -decode_n (uint32 val) +static int +Operand_uimm6_rtoa (uint32 *valp, uint32 pc) { - return val; + *valp += pc; + return 0; } -xtensa_encode_result -encode_n (uint32 *valp) +static int +Operand_ai4const_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 2) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned ai4const_0, t_0; + t_0 = *valp & 0xf; + ai4const_0 = CONST_TBL_ai4c_0[t_0 & 0xf]; + *valp = ai4const_0; + return 0; } -uint32 -decode_none (uint32 val) +static int +Operand_ai4const_encode (uint32 *valp) { - return val; + unsigned t_0, ai4const_0; + ai4const_0 = *valp; + switch (ai4const_0) + { + case 0xffffffff: t_0 = 0; break; + case 0x1: t_0 = 0x1; break; + case 0x2: t_0 = 0x2; break; + case 0x3: t_0 = 0x3; break; + case 0x4: t_0 = 0x4; break; + case 0x5: t_0 = 0x5; break; + case 0x6: t_0 = 0x6; break; + case 0x7: t_0 = 0x7; break; + case 0x8: t_0 = 0x8; break; + case 0x9: t_0 = 0x9; break; + case 0xa: t_0 = 0xa; break; + case 0xb: t_0 = 0xb; break; + case 0xc: t_0 = 0xc; break; + case 0xd: t_0 = 0xd; break; + case 0xe: t_0 = 0xe; break; + default: t_0 = 0xf; break; + } + *valp = t_0; + return 0; } -xtensa_encode_result -encode_none (uint32 *valp) +static int +Operand_b4const_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 0) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned b4const_0, r_0; + r_0 = *valp & 0xf; + b4const_0 = CONST_TBL_b4c_0[r_0 & 0xf]; + *valp = b4const_0; + return 0; } -uint32 -decode_imm12b (uint32 val) +static int +Operand_b4const_encode (uint32 *valp) { - return val; + unsigned r_0, b4const_0; + b4const_0 = *valp; + switch (b4const_0) + { + case 0xffffffff: r_0 = 0; break; + case 0x1: r_0 = 0x1; break; + case 0x2: r_0 = 0x2; break; + case 0x3: r_0 = 0x3; break; + case 0x4: r_0 = 0x4; break; + case 0x5: r_0 = 0x5; break; + case 0x6: r_0 = 0x6; break; + case 0x7: r_0 = 0x7; break; + case 0x8: r_0 = 0x8; break; + case 0xa: r_0 = 0x9; break; + case 0xc: r_0 = 0xa; break; + case 0x10: r_0 = 0xb; break; + case 0x20: r_0 = 0xc; break; + case 0x40: r_0 = 0xd; break; + case 0x80: r_0 = 0xe; break; + default: r_0 = 0xf; break; + } + *valp = r_0; + return 0; } -xtensa_encode_result -encode_imm12b (uint32 *valp) +static int +Operand_b4constu_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 12) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned b4constu_0, r_0; + r_0 = *valp & 0xf; + b4constu_0 = CONST_TBL_b4cu_0[r_0 & 0xf]; + *valp = b4constu_0; + return 0; } -uint32 -decode_r (uint32 val) +static int +Operand_b4constu_encode (uint32 *valp) { - return val; + unsigned r_0, b4constu_0; + b4constu_0 = *valp; + switch (b4constu_0) + { + case 0x8000: r_0 = 0; break; + case 0x10000: r_0 = 0x1; break; + case 0x2: r_0 = 0x2; break; + case 0x3: r_0 = 0x3; break; + case 0x4: r_0 = 0x4; break; + case 0x5: r_0 = 0x5; break; + case 0x6: r_0 = 0x6; break; + case 0x7: r_0 = 0x7; break; + case 0x8: r_0 = 0x8; break; + case 0xa: r_0 = 0x9; break; + case 0xc: r_0 = 0xa; break; + case 0x10: r_0 = 0xb; break; + case 0x20: r_0 = 0xc; break; + case 0x40: r_0 = 0xd; break; + case 0x80: r_0 = 0xe; break; + default: r_0 = 0xf; break; + } + *valp = r_0; + return 0; } -xtensa_encode_result -encode_r (uint32 *valp) +static int +Operand_uimm8_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned uimm8_0, imm8_0; + imm8_0 = *valp & 0xff; + uimm8_0 = imm8_0; + *valp = uimm8_0; + return 0; } -uint32 -decode_s (uint32 val) +static int +Operand_uimm8_encode (uint32 *valp) { - return val; + unsigned imm8_0, uimm8_0; + uimm8_0 = *valp; + imm8_0 = (uimm8_0 & 0xff); + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_s (uint32 *valp) +static int +Operand_uimm8x2_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned uimm8x2_0, imm8_0; + imm8_0 = *valp & 0xff; + uimm8x2_0 = imm8_0 << 1; + *valp = uimm8x2_0; + return 0; } -uint32 -decode_t (uint32 val) +static int +Operand_uimm8x2_encode (uint32 *valp) { - return val; + unsigned imm8_0, uimm8x2_0; + uimm8x2_0 = *valp; + imm8_0 = ((uimm8x2_0 >> 1) & 0xff); + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_t (uint32 *valp) +static int +Operand_uimm8x4_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned uimm8x4_0, imm8_0; + imm8_0 = *valp & 0xff; + uimm8x4_0 = imm8_0 << 2; + *valp = uimm8x4_0; + return 0; } -uint32 -decode_thi3 (uint32 val) +static int +Operand_uimm8x4_encode (uint32 *valp) { - return val; + unsigned imm8_0, uimm8x4_0; + uimm8x4_0 = *valp; + imm8_0 = ((uimm8x4_0 >> 2) & 0xff); + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_thi3 (uint32 *valp) +static int +Operand_uimm4x16_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 3) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned uimm4x16_0, op2_0; + op2_0 = *valp & 0xf; + uimm4x16_0 = op2_0 << 4; + *valp = uimm4x16_0; + return 0; } -uint32 -decode_sae4 (uint32 val) +static int +Operand_uimm4x16_encode (uint32 *valp) { - return val; + unsigned op2_0, uimm4x16_0; + uimm4x16_0 = *valp; + op2_0 = ((uimm4x16_0 >> 4) & 0xf); + *valp = op2_0; + return 0; } -xtensa_encode_result -encode_sae4 (uint32 *valp) +static int +Operand_simm8_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned simm8_0, imm8_0; + imm8_0 = *valp & 0xff; + simm8_0 = ((int) imm8_0 << 24) >> 24; + *valp = simm8_0; + return 0; } -uint32 -decode_offset (uint32 val) +static int +Operand_simm8_encode (uint32 *valp) { - return val; + unsigned imm8_0, simm8_0; + simm8_0 = *valp; + imm8_0 = (simm8_0 & 0xff); + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_offset (uint32 *valp) +static int +Operand_simm8x256_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 18) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned simm8x256_0, imm8_0; + imm8_0 = *valp & 0xff; + simm8x256_0 = (((int) imm8_0 << 24) >> 24) << 8; + *valp = simm8x256_0; + return 0; } -uint32 -decode_imm7hi (uint32 val) +static int +Operand_simm8x256_encode (uint32 *valp) { - return val; + unsigned imm8_0, simm8x256_0; + simm8x256_0 = *valp; + imm8_0 = ((simm8x256_0 >> 8) & 0xff); + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_imm7hi (uint32 *valp) +static int +Operand_simm12b_decode (uint32 *valp) { - uint32 val = *valp; - if ((val >> 3) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned simm12b_0, imm12b_0; + imm12b_0 = *valp & 0xfff; + simm12b_0 = ((int) imm12b_0 << 20) >> 20; + *valp = simm12b_0; + return 0; } -uint32 -decode_uimm4x16 (uint32 val) +static int +Operand_simm12b_encode (uint32 *valp) { - val <<= 4; - return val; + unsigned imm12b_0, simm12b_0; + simm12b_0 = *valp; + imm12b_0 = (simm12b_0 & 0xfff); + *valp = imm12b_0; + return 0; } -xtensa_encode_result -encode_uimm4x16 (uint32 *valp) +static int +Operand_msalp32_decode (uint32 *valp) { - uint32 val = *valp; - if ((val & ((1 << 4) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 4; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned msalp32_0, sal_0; + sal_0 = *valp & 0x1f; + msalp32_0 = 0x20 - sal_0; + *valp = msalp32_0; + return 0; } -uint32 -decode_simm12b (uint32 val) +static int +Operand_msalp32_encode (uint32 *valp) { - val = (val ^ 0x800) - 0x800; - return val; + unsigned sal_0, msalp32_0; + msalp32_0 = *valp; + sal_0 = (0x20 - msalp32_0) & 0x1f; + *valp = sal_0; + return 0; } -xtensa_encode_result -encode_simm12b (uint32 *valp) +static int +Operand_op2p1_decode (uint32 *valp) { - uint32 val = *valp; - if (((val + (1 << 11)) >> 12) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + unsigned op2p1_0, op2_0; + op2_0 = *valp & 0xf; + op2p1_0 = op2_0 + 0x1; + *valp = op2p1_0; + return 0; } -uint32 -decode_lsi4x4 (uint32 val) +static int +Operand_op2p1_encode (uint32 *valp) { - val <<= 2; - return val; + unsigned op2_0, op2p1_0; + op2p1_0 = *valp; + op2_0 = (op2p1_0 - 0x1) & 0xf; + *valp = op2_0; + return 0; } -xtensa_encode_result -encode_lsi4x4 (uint32 *valp) +static int +Operand_label8_decode (uint32 *valp) { - uint32 val = *valp; - if ((val & ((1 << 2) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 2; - if ((val >> 4) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + unsigned label8_0, imm8_0; + imm8_0 = *valp & 0xff; + label8_0 = 0x4 + (((int) imm8_0 << 24) >> 24); + *valp = label8_0; + return 0; } -uint32 -decode_z (uint32 val) +static int +Operand_label8_encode (uint32 *valp) { - return val; + unsigned imm8_0, label8_0; + label8_0 = *valp; + imm8_0 = (label8_0 - 0x4) & 0xff; + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_z (uint32 *valp) +static int +Operand_label8_ator (uint32 *valp, uint32 pc) { - uint32 val = *valp; - if ((val >> 1) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + *valp -= pc; + return 0; } -uint32 -decode_simm12 (uint32 val) +static int +Operand_label8_rtoa (uint32 *valp, uint32 pc) { - val = (val ^ 0x800) - 0x800; - return val; + *valp += pc; + return 0; } -xtensa_encode_result -encode_simm12 (uint32 *valp) +static int +Operand_ulabel8_decode (uint32 *valp) { - uint32 val = *valp; - if (((val + (1 << 11)) >> 12) != 0) - { - if ((signed int) val > 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + unsigned ulabel8_0, imm8_0; + imm8_0 = *valp & 0xff; + ulabel8_0 = 0x4 + ((((0)) << 8) | imm8_0); + *valp = ulabel8_0; + return 0; } -uint32 -decode_sr (uint32 val) +static int +Operand_ulabel8_encode (uint32 *valp) { - return val; + unsigned imm8_0, ulabel8_0; + ulabel8_0 = *valp; + imm8_0 = (ulabel8_0 - 0x4) & 0xff; + *valp = imm8_0; + return 0; } -xtensa_encode_result -encode_sr (uint32 *valp) +static int +Operand_ulabel8_ator (uint32 *valp, uint32 pc) { - uint32 val = *valp; - if ((val >> 8) != 0) - return xtensa_encode_result_too_high; - *valp = val; - return xtensa_encode_result_ok; + *valp -= pc; + return 0; } -uint32 -decode_nimm4x2 (uint32 val) +static int +Operand_ulabel8_rtoa (uint32 *valp, uint32 pc) { - val |= -1 << 4; - val <<= 2; - return val; + *valp += pc; + return 0; } -xtensa_encode_result -encode_nimm4x2 (uint32 *valp) +static int +Operand_label12_decode (uint32 *valp) { - uint32 val = *valp; - if ((val & ((1 << 2) - 1)) != 0) - return xtensa_encode_result_align; - val = (signed int) val >> 2; - if ((signed int) val >> 4 != -1) - { - if ((signed int) val >= 0) - return xtensa_encode_result_too_high; - else - return xtensa_encode_result_too_low; - } - *valp = val; - return xtensa_encode_result_ok; + unsigned label12_0, imm12_0; + imm12_0 = *valp & 0xfff; + label12_0 = 0x4 + (((int) imm12_0 << 20) >> 20); + *valp = label12_0; + return 0; } +static int +Operand_label12_encode (uint32 *valp) +{ + unsigned imm12_0, label12_0; + label12_0 = *valp; + imm12_0 = (label12_0 - 0x4) & 0xfff; + *valp = imm12_0; + return 0; +} +static int +Operand_label12_ator (uint32 *valp, uint32 pc) +{ + *valp -= pc; + return 0; +} -uint32 do_reloc_l (uint32, uint32); -uint32 undo_reloc_l (uint32, uint32); -uint32 do_reloc_L (uint32, uint32); -uint32 undo_reloc_L (uint32, uint32); -uint32 do_reloc_r (uint32, uint32); -uint32 undo_reloc_r (uint32, uint32); +static int +Operand_label12_rtoa (uint32 *valp, uint32 pc) +{ + *valp += pc; + return 0; +} +static int +Operand_soffset_decode (uint32 *valp) +{ + unsigned soffset_0, offset_0; + offset_0 = *valp & 0x3ffff; + soffset_0 = 0x4 + (((int) offset_0 << 14) >> 14); + *valp = soffset_0; + return 0; +} -uint32 -do_reloc_l (uint32 addr, uint32 pc) +static int +Operand_soffset_encode (uint32 *valp) { - return addr - pc - 4; + unsigned offset_0, soffset_0; + soffset_0 = *valp; + offset_0 = (soffset_0 - 0x4) & 0x3ffff; + *valp = offset_0; + return 0; } -uint32 -undo_reloc_l (uint32 offset, uint32 pc) +static int +Operand_soffset_ator (uint32 *valp, uint32 pc) { - return pc + offset + 4; + *valp -= pc; + return 0; } -uint32 -do_reloc_L (uint32 addr, uint32 pc) +static int +Operand_soffset_rtoa (uint32 *valp, uint32 pc) { - return addr - (pc & -4) - 4; + *valp += pc; + return 0; } -uint32 -undo_reloc_L (uint32 offset, uint32 pc) +static int +Operand_uimm16x4_decode (uint32 *valp) { - return (pc & -4) + offset + 4; + unsigned uimm16x4_0, imm16_0; + imm16_0 = *valp & 0xffff; + uimm16x4_0 = ((((0xffff)) << 16) | imm16_0) << 2; + *valp = uimm16x4_0; + return 0; } -uint32 -do_reloc_r (uint32 addr, uint32 pc) +static int +Operand_uimm16x4_encode (uint32 *valp) { - return addr - ((pc+3) & -4); + unsigned imm16_0, uimm16x4_0; + uimm16x4_0 = *valp; + imm16_0 = (uimm16x4_0 >> 2) & 0xffff; + *valp = imm16_0; + return 0; } -uint32 -undo_reloc_r (uint32 offset, uint32 pc) +static int +Operand_uimm16x4_ator (uint32 *valp, uint32 pc) { - return ((pc+3) & -4) + offset; + *valp -= ((pc + 3) & ~0x3); + return 0; } -static xtensa_operand_internal iib4const_operand = { - "i", - '<', - 0, - get_r_field, - set_r_field, - encode_b4const, - decode_b4const, - 0, - 0 +static int +Operand_uimm16x4_rtoa (uint32 *valp, uint32 pc) +{ + *valp += ((pc + 3) & ~0x3); + return 0; +} + +static int +Operand_immt_decode (uint32 *valp) +{ + unsigned immt_0, t_0; + t_0 = *valp & 0xf; + immt_0 = t_0; + *valp = immt_0; + return 0; +} + +static int +Operand_immt_encode (uint32 *valp) +{ + unsigned t_0, immt_0; + immt_0 = *valp; + t_0 = immt_0 & 0xf; + *valp = t_0; + return 0; +} + +static int +Operand_imms_decode (uint32 *valp) +{ + unsigned imms_0, s_0; + s_0 = *valp & 0xf; + imms_0 = s_0; + *valp = imms_0; + return 0; +} + +static int +Operand_imms_encode (uint32 *valp) +{ + unsigned s_0, imms_0; + imms_0 = *valp; + s_0 = imms_0 & 0xf; + *valp = s_0; + return 0; +} + +static xtensa_operand_internal operands[] = { + { "soffsetx4", 10, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_soffsetx4_encode, Operand_soffsetx4_decode, + Operand_soffsetx4_ator, Operand_soffsetx4_rtoa }, + { "uimm12x8", 3, -1, 0, + 0, + Operand_uimm12x8_encode, Operand_uimm12x8_decode, + 0, 0 }, + { "simm4", 26, -1, 0, + 0, + Operand_simm4_encode, Operand_simm4_decode, + 0, 0 }, + { "arr", 14, 0, 1, + XTENSA_OPERAND_IS_REGISTER, + Operand_arr_encode, Operand_arr_decode, + 0, 0 }, + { "ars", 5, 0, 1, + XTENSA_OPERAND_IS_REGISTER, + Operand_ars_encode, Operand_ars_decode, + 0, 0 }, + { "*ars_invisible", 5, 0, 1, + XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE, + Operand_ars_encode, Operand_ars_decode, + 0, 0 }, + { "art", 0, 0, 1, + XTENSA_OPERAND_IS_REGISTER, + Operand_art_encode, Operand_art_decode, + 0, 0 }, + { "ar0", 35, 0, 1, + XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE, + Operand_ar0_encode, Operand_ar0_decode, + 0, 0 }, + { "ar4", 36, 0, 1, + XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE, + Operand_ar4_encode, Operand_ar4_decode, + 0, 0 }, + { "ar8", 37, 0, 1, + XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE, + Operand_ar8_encode, Operand_ar8_decode, + 0, 0 }, + { "ar12", 38, 0, 1, + XTENSA_OPERAND_IS_REGISTER | XTENSA_OPERAND_IS_INVISIBLE, + Operand_ar12_encode, Operand_ar12_decode, + 0, 0 }, + { "ars_entry", 5, 0, 1, + XTENSA_OPERAND_IS_REGISTER, + Operand_ars_entry_encode, Operand_ars_entry_decode, + 0, 0 }, + { "immrx4", 14, -1, 0, + 0, + Operand_immrx4_encode, Operand_immrx4_decode, + 0, 0 }, + { "lsi4x4", 14, -1, 0, + 0, + Operand_lsi4x4_encode, Operand_lsi4x4_decode, + 0, 0 }, + { "simm7", 34, -1, 0, + 0, + Operand_simm7_encode, Operand_simm7_decode, + 0, 0 }, + { "uimm6", 33, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_uimm6_encode, Operand_uimm6_decode, + Operand_uimm6_ator, Operand_uimm6_rtoa }, + { "ai4const", 0, -1, 0, + 0, + Operand_ai4const_encode, Operand_ai4const_decode, + 0, 0 }, + { "b4const", 14, -1, 0, + 0, + Operand_b4const_encode, Operand_b4const_decode, + 0, 0 }, + { "b4constu", 14, -1, 0, + 0, + Operand_b4constu_encode, Operand_b4constu_decode, + 0, 0 }, + { "uimm8", 4, -1, 0, + 0, + Operand_uimm8_encode, Operand_uimm8_decode, + 0, 0 }, + { "uimm8x2", 4, -1, 0, + 0, + Operand_uimm8x2_encode, Operand_uimm8x2_decode, + 0, 0 }, + { "uimm8x4", 4, -1, 0, + 0, + Operand_uimm8x4_encode, Operand_uimm8x4_decode, + 0, 0 }, + { "uimm4x16", 13, -1, 0, + 0, + Operand_uimm4x16_encode, Operand_uimm4x16_decode, + 0, 0 }, + { "simm8", 4, -1, 0, + 0, + Operand_simm8_encode, Operand_simm8_decode, + 0, 0 }, + { "simm8x256", 4, -1, 0, + 0, + Operand_simm8x256_encode, Operand_simm8x256_decode, + 0, 0 }, + { "simm12b", 6, -1, 0, + 0, + Operand_simm12b_encode, Operand_simm12b_decode, + 0, 0 }, + { "msalp32", 18, -1, 0, + 0, + Operand_msalp32_encode, Operand_msalp32_decode, + 0, 0 }, + { "op2p1", 13, -1, 0, + 0, + Operand_op2p1_encode, Operand_op2p1_decode, + 0, 0 }, + { "label8", 4, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_label8_encode, Operand_label8_decode, + Operand_label8_ator, Operand_label8_rtoa }, + { "ulabel8", 4, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_ulabel8_encode, Operand_ulabel8_decode, + Operand_ulabel8_ator, Operand_ulabel8_rtoa }, + { "label12", 3, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_label12_encode, Operand_label12_decode, + Operand_label12_ator, Operand_label12_rtoa }, + { "soffset", 10, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_soffset_encode, Operand_soffset_decode, + Operand_soffset_ator, Operand_soffset_rtoa }, + { "uimm16x4", 7, -1, 0, + XTENSA_OPERAND_IS_PCRELATIVE, + Operand_uimm16x4_encode, Operand_uimm16x4_decode, + Operand_uimm16x4_ator, Operand_uimm16x4_rtoa }, + { "immt", 0, -1, 0, + 0, + Operand_immt_encode, Operand_immt_decode, + 0, 0 }, + { "imms", 5, -1, 0, + 0, + Operand_imms_encode, Operand_imms_decode, + 0, 0 }, + { "t", 0, -1, 0, 0, 0, 0, 0, 0 }, + { "bbi4", 1, -1, 0, 0, 0, 0, 0, 0 }, + { "bbi", 2, -1, 0, 0, 0, 0, 0, 0 }, + { "imm12", 3, -1, 0, 0, 0, 0, 0, 0 }, + { "imm8", 4, -1, 0, 0, 0, 0, 0, 0 }, + { "s", 5, -1, 0, 0, 0, 0, 0, 0 }, + { "imm12b", 6, -1, 0, 0, 0, 0, 0, 0 }, + { "imm16", 7, -1, 0, 0, 0, 0, 0, 0 }, + { "m", 8, -1, 0, 0, 0, 0, 0, 0 }, + { "n", 9, -1, 0, 0, 0, 0, 0, 0 }, + { "offset", 10, -1, 0, 0, 0, 0, 0, 0 }, + { "op0", 11, -1, 0, 0, 0, 0, 0, 0 }, + { "op1", 12, -1, 0, 0, 0, 0, 0, 0 }, + { "op2", 13, -1, 0, 0, 0, 0, 0, 0 }, + { "r", 14, -1, 0, 0, 0, 0, 0, 0 }, + { "sa4", 15, -1, 0, 0, 0, 0, 0, 0 }, + { "sae4", 16, -1, 0, 0, 0, 0, 0, 0 }, + { "sae", 17, -1, 0, 0, 0, 0, 0, 0 }, + { "sal", 18, -1, 0, 0, 0, 0, 0, 0 }, + { "sargt", 19, -1, 0, 0, 0, 0, 0, 0 }, + { "sas4", 20, -1, 0, 0, 0, 0, 0, 0 }, + { "sas", 21, -1, 0, 0, 0, 0, 0, 0 }, + { "sr", 22, -1, 0, 0, 0, 0, 0, 0 }, + { "st", 23, -1, 0, 0, 0, 0, 0, 0 }, + { "thi3", 24, -1, 0, 0, 0, 0, 0, 0 }, + { "imm4", 25, -1, 0, 0, 0, 0, 0, 0 }, + { "mn", 26, -1, 0, 0, 0, 0, 0, 0 }, + { "i", 27, -1, 0, 0, 0, 0, 0, 0 }, + { "imm6lo", 28, -1, 0, 0, 0, 0, 0, 0 }, + { "imm6hi", 29, -1, 0, 0, 0, 0, 0, 0 }, + { "imm7lo", 30, -1, 0, 0, 0, 0, 0, 0 }, + { "imm7hi", 31, -1, 0, 0, 0, 0, 0, 0 }, + { "z", 32, -1, 0, 0, 0, 0, 0, 0 }, + { "imm6", 33, -1, 0, 0, 0, 0, 0, 0 }, + { "imm7", 34, -1, 0, 0, 0, 0, 0, 0 } +}; + + +/* Iclass table. */ + +static xtensa_arg_internal Iclass_xt_iclass_rfe_stateArgs[] = { + { { STATE_PSEXCM }, 'o' }, + { { STATE_EPC1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rfde_stateArgs[] = { + { { STATE_DEPC }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_call12_args[] = { + { { 0 /* soffsetx4 */ }, 'i' }, + { { 10 /* ar12 */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_call12_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_call8_args[] = { + { { 0 /* soffsetx4 */ }, 'i' }, + { { 9 /* ar8 */ }, 'o' } }; -static xtensa_operand_internal iiuimm8_operand = { - "i", - '<', - 0, - get_imm8_field, - set_imm8_field, - encode_uimm8, - decode_uimm8, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_call8_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } }; -static xtensa_operand_internal lisoffsetx4_operand = { - "L", - '<', - 1, - get_offset_field, - set_offset_field, - encode_soffsetx4, - decode_soffsetx4, - do_reloc_L, - undo_reloc_L, +static xtensa_arg_internal Iclass_xt_iclass_call4_args[] = { + { { 0 /* soffsetx4 */ }, 'i' }, + { { 8 /* ar4 */ }, 'o' } }; -static xtensa_operand_internal iisimm8x256_operand = { - "i", - '<', - 0, - get_imm8_field, - set_imm8_field, - encode_simm8x256, - decode_simm8x256, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_call4_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } }; -static xtensa_operand_internal lisimm12_operand = { - "l", - '<', - 1, - get_imm12_field, - set_imm12_field, - encode_simm12, - decode_simm12, - do_reloc_l, - undo_reloc_l, +static xtensa_arg_internal Iclass_xt_iclass_callx12_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 10 /* ar12 */ }, 'o' } }; -static xtensa_operand_internal iiop2p1_operand = { - "i", - '<', - 0, - get_op2_field, - set_op2_field, - encode_op2p1, - decode_op2p1, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_callx12_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } }; -static xtensa_operand_internal iisae_operand = { - "i", - '<', - 0, - get_sae_field, - set_sae_field, - encode_sae, - decode_sae, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_callx8_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 9 /* ar8 */ }, 'o' } }; -static xtensa_operand_internal iis_operand = { - "i", - '<', - 0, - get_s_field, - set_s_field, - encode_s, - decode_s, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_callx8_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } }; -static xtensa_operand_internal iit_operand = { - "i", - '<', - 0, - get_t_field, - set_t_field, - encode_t, - decode_t, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_callx4_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 8 /* ar4 */ }, 'o' } }; -static xtensa_operand_internal iisimm12b_operand = { - "i", - '<', - 0, - get_imm12b_field, - set_imm12b_field, - encode_simm12b, - decode_simm12b, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_callx4_stateArgs[] = { + { { STATE_PSCALLINC }, 'o' } }; -static xtensa_operand_internal iinimm4x2_operand = { - "i", - '<', - 0, - get_imm4_field, - set_imm4_field, - encode_nimm4x2, - decode_nimm4x2, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_entry_args[] = { + { { 11 /* ars_entry */ }, 's' }, + { { 4 /* ars */ }, 'i' }, + { { 1 /* uimm12x8 */ }, 'i' } }; -static xtensa_operand_internal iiuimm4x16_operand = { - "i", - '<', - 0, - get_op2_field, - set_op2_field, - encode_uimm4x16, - decode_uimm4x16, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_entry_stateArgs[] = { + { { STATE_PSCALLINC }, 'i' }, + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSWOE }, 'i' }, + { { STATE_WindowBase }, 'm' }, + { { STATE_WindowStart }, 'm' } }; -static xtensa_operand_internal abs_operand = { - "a", - '=', - 0, - get_s_field, - set_s_field, - encode_s, - decode_s, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_movsp_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } }; -static xtensa_operand_internal iisar_operand = { - "i", - '<', - 0, - get_sar_field, - set_sar_field, - encode_sar, - decode_sar, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_movsp_stateArgs[] = { + { { STATE_WindowBase }, 'i' }, + { { STATE_WindowStart }, 'i' } }; -static xtensa_operand_internal abt_operand = { - "a", - '=', - 0, - get_t_field, - set_t_field, - encode_t, - decode_t, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rotw_args[] = { + { { 2 /* simm4 */ }, 'i' } }; -static xtensa_operand_internal iisas_operand = { - "i", - '<', - 0, - get_sas_field, - set_sas_field, - encode_sas, - decode_sas, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rotw_stateArgs[] = { + { { STATE_WindowBase }, 'm' } }; -static xtensa_operand_internal amr_operand = { - "a", - '=', - 0, - get_r_field, - set_r_field, - encode_r, - decode_r, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_retw_args[] = { + { { 5 /* *ars_invisible */ }, 'i' } }; -static xtensa_operand_internal iib4constu_operand = { - "i", - '<', - 0, - get_r_field, - set_r_field, - encode_b4constu, - decode_b4constu, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_retw_stateArgs[] = { + { { STATE_WindowBase }, 'm' }, + { { STATE_WindowStart }, 'm' }, + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSWOE }, 'i' } }; -static xtensa_operand_internal iisr_operand = { - "i", - '<', - 0, - get_sr_field, - set_sr_field, - encode_sr, - decode_sr, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rfwou_stateArgs[] = { + { { STATE_EPC1 }, 'i' }, + { { STATE_PSEXCM }, 'o' }, + { { STATE_WindowBase }, 'm' }, + { { STATE_WindowStart }, 'm' }, + { { STATE_PSOWB }, 'i' } }; -static xtensa_operand_internal iibbi_operand = { - "i", - '<', - 0, - get_bbi_field, - set_bbi_field, - encode_bbi, - decode_bbi, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_l32e_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 12 /* immrx4 */ }, 'i' } }; -static xtensa_operand_internal iiai4const_operand = { - "i", - '<', - 0, - get_t_field, - set_t_field, - encode_ai4const, - decode_ai4const, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_s32e_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' }, + { { 12 /* immrx4 */ }, 'i' } }; -static xtensa_operand_internal iiuimm12x8_operand = { - "i", - '<', - 0, - get_imm12_field, - set_imm12_field, - encode_uimm12x8, - decode_uimm12x8, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rsr_windowbase_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal riuimm16x4_operand = { - "r", - '<', - 1, - get_imm16_field, - set_imm16_field, - encode_uimm16x4, - decode_uimm16x4, - do_reloc_r, - undo_reloc_r, -}; - -static xtensa_operand_internal lisimm8_operand = { - "l", - '<', - 1, - get_imm8_field, - set_imm8_field, - encode_simm8, - decode_simm8, - do_reloc_l, - undo_reloc_l, -}; - -static xtensa_operand_internal iilsi4x4_operand = { - "i", - '<', - 0, - get_r_field, - set_r_field, - encode_lsi4x4, - decode_lsi4x4, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rsr_windowbase_stateArgs[] = { + { { STATE_WindowBase }, 'i' } }; -static xtensa_operand_internal iiuimm8x2_operand = { - "i", - '<', - 0, - get_imm8_field, - set_imm8_field, - encode_uimm8x2, - decode_uimm8x2, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_windowbase_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal iisimm4_operand = { - "i", - '<', - 0, - get_mn_field, - set_mn_field, - encode_simm4, - decode_simm4, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_windowbase_stateArgs[] = { + { { STATE_WindowBase }, 'o' } }; -static xtensa_operand_internal iimsalp32_operand = { - "i", - '<', - 0, - get_sal_field, - set_sal_field, - encode_msalp32, - decode_msalp32, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_xsr_windowbase_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal liuimm6_operand = { - "l", - '<', - 1, - get_imm6_field, - set_imm6_field, - encode_uimm6, - decode_uimm6, - do_reloc_l, - undo_reloc_l, +static xtensa_arg_internal Iclass_xt_iclass_xsr_windowbase_stateArgs[] = { + { { STATE_WindowBase }, 'm' } }; -static xtensa_operand_internal iiuimm8x4_operand = { - "i", - '<', - 0, - get_imm8_field, - set_imm8_field, - encode_uimm8x4, - decode_uimm8x4, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rsr_windowstart_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal lisoffset_operand = { - "l", - '<', - 1, - get_offset_field, - set_offset_field, - encode_soffset, - decode_soffset, - do_reloc_l, - undo_reloc_l, +static xtensa_arg_internal Iclass_xt_iclass_rsr_windowstart_stateArgs[] = { + { { STATE_WindowStart }, 'i' } }; -static xtensa_operand_internal iisimm7_operand = { - "i", - '<', - 0, - get_imm7_field, - set_imm7_field, - encode_simm7, - decode_simm7, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_windowstart_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal ais_operand = { - "a", - '<', - 0, - get_s_field, - set_s_field, - encode_s, - decode_s, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_windowstart_stateArgs[] = { + { { STATE_WindowStart }, 'o' } }; -static xtensa_operand_internal liuimm8_operand = { - "l", - '<', - 1, - get_imm8_field, - set_imm8_field, - encode_uimm8, - decode_uimm8, - do_reloc_l, - undo_reloc_l, +static xtensa_arg_internal Iclass_xt_iclass_xsr_windowstart_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal ait_operand = { - "a", - '<', - 0, - get_t_field, - set_t_field, - encode_t, - decode_t, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_xsr_windowstart_stateArgs[] = { + { { STATE_WindowStart }, 'm' } }; -static xtensa_operand_internal iisimm8_operand = { - "i", - '<', - 0, - get_imm8_field, - set_imm8_field, - encode_simm8, - decode_simm8, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_add_n_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal aor_operand = { - "a", - '>', - 0, - get_r_field, - set_r_field, - encode_r, - decode_r, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_addi_n_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 16 /* ai4const */ }, 'i' } }; -static xtensa_operand_internal aos_operand = { - "a", - '>', - 0, - get_s_field, - set_s_field, - encode_s, - decode_s, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_bz6_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 15 /* uimm6 */ }, 'i' } }; -static xtensa_operand_internal aot_operand = { - "a", - '>', - 0, - get_t_field, - set_t_field, - encode_t, - decode_t, - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_loadi4_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 13 /* lsi4x4 */ }, 'i' } }; -static xtensa_iclass_internal nopn_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_mov_n_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } }; -static xtensa_operand_internal *movi_operand_list[] = { - &aot_operand, - &iisimm12b_operand +static xtensa_arg_internal Iclass_xt_iclass_movi_n_args[] = { + { { 4 /* ars */ }, 'o' }, + { { 14 /* simm7 */ }, 'i' } }; -static xtensa_iclass_internal movi_iclass = { - 2, - &movi_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_retn_args[] = { + { { 5 /* *ars_invisible */ }, 'i' } }; -static xtensa_operand_internal *bsi8u_operand_list[] = { - &ais_operand, - &iib4constu_operand, - &lisimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_storei4_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' }, + { { 13 /* lsi4x4 */ }, 'i' } }; -static xtensa_iclass_internal bsi8u_iclass = { - 3, - &bsi8u_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_addi_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 23 /* simm8 */ }, 'i' } }; -static xtensa_operand_internal *itlb_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_addmi_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 24 /* simm8x256 */ }, 'i' } }; -static xtensa_iclass_internal itlb_iclass = { - 1, - &itlb_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_addsub_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *shiftst_operand_list[] = { - &aor_operand, - &ais_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_bit_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal shiftst_iclass = { - 3, - &shiftst_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_bsi8_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 17 /* b4const */ }, 'i' }, + { { 28 /* label8 */ }, 'i' } }; -static xtensa_operand_internal *l32r_operand_list[] = { - &aot_operand, - &riuimm16x4_operand +static xtensa_arg_internal Iclass_xt_iclass_bsi8b_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 37 /* bbi */ }, 'i' }, + { { 28 /* label8 */ }, 'i' } }; -static xtensa_iclass_internal l32r_iclass = { - 2, - &l32r_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_bsi8u_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 18 /* b4constu */ }, 'i' }, + { { 28 /* label8 */ }, 'i' } }; -static xtensa_iclass_internal rfe_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_bst8_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' }, + { { 28 /* label8 */ }, 'i' } }; -static xtensa_operand_internal *wait_operand_list[] = { - &iis_operand +static xtensa_arg_internal Iclass_xt_iclass_bsz12_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 30 /* label12 */ }, 'i' } }; -static xtensa_iclass_internal wait_iclass = { - 1, - &wait_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_call0_args[] = { + { { 0 /* soffsetx4 */ }, 'i' }, + { { 7 /* ar0 */ }, 'o' } }; -static xtensa_operand_internal *rfi_operand_list[] = { - &iis_operand +static xtensa_arg_internal Iclass_xt_iclass_callx0_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 7 /* ar0 */ }, 'o' } }; -static xtensa_iclass_internal rfi_iclass = { - 1, - &rfi_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_exti_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 6 /* art */ }, 'i' }, + { { 52 /* sae */ }, 'i' }, + { { 27 /* op2p1 */ }, 'i' } }; -static xtensa_operand_internal *movz_operand_list[] = { - &amr_operand, - &ais_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_jump_args[] = { + { { 31 /* soffset */ }, 'i' } }; -static xtensa_iclass_internal movz_iclass = { - 3, - &movz_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_jumpx_args[] = { + { { 4 /* ars */ }, 'i' } }; -static xtensa_operand_internal *callx_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_l16ui_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 20 /* uimm8x2 */ }, 'i' } }; -static xtensa_iclass_internal callx_iclass = { - 1, - &callx_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_l16si_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 20 /* uimm8x2 */ }, 'i' } }; -static xtensa_operand_internal *mov_n_operand_list[] = { - &aot_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_l32i_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } }; -static xtensa_iclass_internal mov_n_iclass = { - 2, - &mov_n_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_l32r_args[] = { + { { 6 /* art */ }, 'o' }, + { { 32 /* uimm16x4 */ }, 'i' } }; -static xtensa_operand_internal *loadi4_operand_list[] = { - &aot_operand, - &ais_operand, - &iilsi4x4_operand +static xtensa_arg_internal Iclass_xt_iclass_l32r_stateArgs[] = { + { { STATE_LITBADDR }, 'i' }, + { { STATE_LITBEN }, 'i' } }; -static xtensa_iclass_internal loadi4_iclass = { - 3, - &loadi4_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_l8i_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 19 /* uimm8 */ }, 'i' } }; -static xtensa_operand_internal *exti_operand_list[] = { - &aor_operand, - &ait_operand, - &iisae_operand, - &iiop2p1_operand +static xtensa_arg_internal Iclass_xt_iclass_loop_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 29 /* ulabel8 */ }, 'i' } }; -static xtensa_iclass_internal exti_iclass = { - 4, - &exti_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_loop_stateArgs[] = { + { { STATE_LBEG }, 'o' }, + { { STATE_LEND }, 'o' }, + { { STATE_LCOUNT }, 'o' } }; -static xtensa_operand_internal *break_operand_list[] = { - &iis_operand, - &iit_operand +static xtensa_arg_internal Iclass_xt_iclass_loopz_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 29 /* ulabel8 */ }, 'i' } }; -static xtensa_iclass_internal break_iclass = { - 2, - &break_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_loopz_stateArgs[] = { + { { STATE_LBEG }, 'o' }, + { { STATE_LEND }, 'o' }, + { { STATE_LCOUNT }, 'o' } }; -static xtensa_operand_internal *slli_operand_list[] = { - &aor_operand, - &ais_operand, - &iimsalp32_operand +static xtensa_arg_internal Iclass_xt_iclass_movi_args[] = { + { { 6 /* art */ }, 'o' }, + { { 25 /* simm12b */ }, 'i' } }; -static xtensa_iclass_internal slli_iclass = { - 3, - &slli_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_movz_args[] = { + { { 3 /* arr */ }, 'm' }, + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *s16i_operand_list[] = { - &ait_operand, - &ais_operand, - &iiuimm8x2_operand +static xtensa_arg_internal Iclass_xt_iclass_neg_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal s16i_iclass = { - 3, - &s16i_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_return_args[] = { + { { 5 /* *ars_invisible */ }, 'i' } }; -static xtensa_operand_internal *call_operand_list[] = { - &lisoffsetx4_operand +static xtensa_arg_internal Iclass_xt_iclass_s16i_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' }, + { { 20 /* uimm8x2 */ }, 'i' } }; -static xtensa_iclass_internal call_iclass = { - 1, - &call_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_s32i_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } }; -static xtensa_operand_internal *shifts_operand_list[] = { - &aor_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_s8i_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' }, + { { 19 /* uimm8 */ }, 'i' } }; -static xtensa_iclass_internal shifts_iclass = { - 2, - &shifts_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_sar_args[] = { + { { 4 /* ars */ }, 'i' } }; -static xtensa_operand_internal *shiftt_operand_list[] = { - &aor_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_sar_stateArgs[] = { + { { STATE_SAR }, 'o' } }; -static xtensa_iclass_internal shiftt_iclass = { - 2, - &shiftt_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_sari_args[] = { + { { 56 /* sas */ }, 'i' } }; -static xtensa_operand_internal *rotw_operand_list[] = { - &iisimm4_operand +static xtensa_arg_internal Iclass_xt_iclass_sari_stateArgs[] = { + { { STATE_SAR }, 'o' } }; -static xtensa_iclass_internal rotw_iclass = { - 1, - &rotw_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_shifts_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' } }; -static xtensa_operand_internal *addsub_operand_list[] = { - &aor_operand, - &ais_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_shifts_stateArgs[] = { + { { STATE_SAR }, 'i' } }; -static xtensa_iclass_internal addsub_iclass = { - 3, - &addsub_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_shiftst_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *l8i_operand_list[] = { - &aot_operand, - &ais_operand, - &iiuimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_shiftst_stateArgs[] = { + { { STATE_SAR }, 'i' } }; -static xtensa_iclass_internal l8i_iclass = { - 3, - &l8i_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_shiftt_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *sari_operand_list[] = { - &iisas_operand +static xtensa_arg_internal Iclass_xt_iclass_shiftt_stateArgs[] = { + { { STATE_SAR }, 'i' } }; -static xtensa_iclass_internal sari_iclass = { - 1, - &sari_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_slli_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 4 /* ars */ }, 'i' }, + { { 26 /* msalp32 */ }, 'i' } }; -static xtensa_operand_internal *xsr_operand_list[] = { - &abt_operand, - &iisr_operand +static xtensa_arg_internal Iclass_xt_iclass_srai_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 6 /* art */ }, 'i' }, + { { 54 /* sargt */ }, 'i' } }; -static xtensa_iclass_internal xsr_iclass = { - 2, - &xsr_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_srli_args[] = { + { { 3 /* arr */ }, 'o' }, + { { 6 /* art */ }, 'i' }, + { { 40 /* s */ }, 'i' } }; -static xtensa_operand_internal *rsil_operand_list[] = { - &aot_operand, - &iis_operand +static xtensa_arg_internal Iclass_xt_iclass_sync_stateArgs[] = { + { { STATE_XTSYNC }, 'i' } }; -static xtensa_iclass_internal rsil_iclass = { - 2, - &rsil_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsil_args[] = { + { { 6 /* art */ }, 'o' }, + { { 40 /* s */ }, 'i' } }; -static xtensa_operand_internal *bst8_operand_list[] = { - &ais_operand, - &ait_operand, - &lisimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_rsil_stateArgs[] = { + { { STATE_PSWOE }, 'i' }, + { { STATE_PSCALLINC }, 'i' }, + { { STATE_PSOWB }, 'i' }, + { { STATE_PSUM }, 'i' }, + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSINTLEVEL }, 'm' } }; -static xtensa_iclass_internal bst8_iclass = { - 3, - &bst8_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_lend_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *addi_operand_list[] = { - &aot_operand, - &ais_operand, - &iisimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_lend_stateArgs[] = { + { { STATE_LEND }, 'i' } }; -static xtensa_iclass_internal addi_iclass = { - 3, - &addi_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_lend_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *callx12_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_lend_stateArgs[] = { + { { STATE_LEND }, 'o' } }; -static xtensa_iclass_internal callx12_iclass = { - 1, - &callx12_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_lend_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *bsi8_operand_list[] = { - &ais_operand, - &iib4const_operand, - &lisimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_lend_stateArgs[] = { + { { STATE_LEND }, 'm' } }; -static xtensa_iclass_internal bsi8_iclass = { - 3, - &bsi8_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_lcount_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *jumpx_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_lcount_stateArgs[] = { + { { STATE_LCOUNT }, 'i' } }; -static xtensa_iclass_internal jumpx_iclass = { - 1, - &jumpx_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_lcount_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal retn_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_lcount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_LCOUNT }, 'o' } }; -static xtensa_operand_internal *nsa_operand_list[] = { - &aot_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_lcount_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal nsa_iclass = { - 2, - &nsa_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_lcount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_LCOUNT }, 'm' } }; -static xtensa_operand_internal *storei4_operand_list[] = { - &ait_operand, - &ais_operand, - &iilsi4x4_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_lbeg_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal storei4_iclass = { - 3, - &storei4_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_lbeg_stateArgs[] = { + { { STATE_LBEG }, 'i' } }; -static xtensa_operand_internal *wtlb_operand_list[] = { - &ait_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_lbeg_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal wtlb_iclass = { - 2, - &wtlb_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_lbeg_stateArgs[] = { + { { STATE_LBEG }, 'o' } }; -static xtensa_operand_internal *dce_operand_list[] = { - &ais_operand, - &iiuimm4x16_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_lbeg_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal dce_iclass = { - 2, - &dce_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_lbeg_stateArgs[] = { + { { STATE_LBEG }, 'm' } }; -static xtensa_operand_internal *l16i_operand_list[] = { - &aot_operand, - &ais_operand, - &iiuimm8x2_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_sar_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal l16i_iclass = { - 3, - &l16i_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_sar_stateArgs[] = { + { { STATE_SAR }, 'i' } }; -static xtensa_operand_internal *callx4_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_sar_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal callx4_iclass = { - 1, - &callx4_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_sar_stateArgs[] = { + { { STATE_SAR }, 'o' }, + { { STATE_XTSYNC }, 'o' } }; -static xtensa_operand_internal *callx8_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_sar_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal callx8_iclass = { - 1, - &callx8_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_sar_stateArgs[] = { + { { STATE_SAR }, 'm' } }; -static xtensa_operand_internal *movsp_operand_list[] = { - &aot_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_litbase_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal movsp_iclass = { - 2, - &movsp_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_litbase_stateArgs[] = { + { { STATE_LITBADDR }, 'i' }, + { { STATE_LITBEN }, 'i' } }; -static xtensa_operand_internal *wsr_operand_list[] = { - &ait_operand, - &iisr_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_litbase_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal wsr_iclass = { - 2, - &wsr_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_litbase_stateArgs[] = { + { { STATE_LITBADDR }, 'o' }, + { { STATE_LITBEN }, 'o' } }; -static xtensa_operand_internal *call12_operand_list[] = { - &lisoffsetx4_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_litbase_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal call12_iclass = { - 1, - &call12_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_litbase_stateArgs[] = { + { { STATE_LITBADDR }, 'm' }, + { { STATE_LITBEN }, 'm' } }; -static xtensa_operand_internal *call4_operand_list[] = { - &lisoffsetx4_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_176_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal call4_iclass = { - 1, - &call4_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_208_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *addmi_operand_list[] = { - &aot_operand, - &ais_operand, - &iisimm8x256_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_ps_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal addmi_iclass = { - 3, - &addmi_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_ps_stateArgs[] = { + { { STATE_PSWOE }, 'i' }, + { { STATE_PSCALLINC }, 'i' }, + { { STATE_PSOWB }, 'i' }, + { { STATE_PSUM }, 'i' }, + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSINTLEVEL }, 'i' } }; -static xtensa_operand_internal *bit_operand_list[] = { - &aor_operand, - &ais_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_ps_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal bit_iclass = { - 3, - &bit_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_ps_stateArgs[] = { + { { STATE_PSWOE }, 'o' }, + { { STATE_PSCALLINC }, 'o' }, + { { STATE_PSOWB }, 'o' }, + { { STATE_PSUM }, 'o' }, + { { STATE_PSEXCM }, 'o' }, + { { STATE_PSINTLEVEL }, 'o' } }; -static xtensa_operand_internal *call8_operand_list[] = { - &lisoffsetx4_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_ps_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal call8_iclass = { - 1, - &call8_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_ps_stateArgs[] = { + { { STATE_PSWOE }, 'm' }, + { { STATE_PSCALLINC }, 'm' }, + { { STATE_PSOWB }, 'm' }, + { { STATE_PSUM }, 'm' }, + { { STATE_PSEXCM }, 'm' }, + { { STATE_PSINTLEVEL }, 'm' } }; -static xtensa_iclass_internal itlba_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc1_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *break_n_operand_list[] = { - &iis_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc1_stateArgs[] = { + { { STATE_EPC1 }, 'i' } }; -static xtensa_iclass_internal break_n_iclass = { - 1, - &break_n_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc1_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *sar_operand_list[] = { - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc1_stateArgs[] = { + { { STATE_EPC1 }, 'o' } }; -static xtensa_iclass_internal sar_iclass = { - 1, - &sar_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc1_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *s32e_operand_list[] = { - &ait_operand, - &ais_operand, - &iinimm4x2_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc1_stateArgs[] = { + { { STATE_EPC1 }, 'm' } }; -static xtensa_iclass_internal s32e_iclass = { - 3, - &s32e_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave1_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *bz6_operand_list[] = { - &ais_operand, - &liuimm6_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave1_stateArgs[] = { + { { STATE_EXCSAVE1 }, 'i' } }; -static xtensa_iclass_internal bz6_iclass = { - 2, - &bz6_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave1_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *loop_operand_list[] = { - &ais_operand, - &liuimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave1_stateArgs[] = { + { { STATE_EXCSAVE1 }, 'o' } }; -static xtensa_iclass_internal loop_iclass = { - 2, - &loop_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave1_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *rsr_operand_list[] = { - &aot_operand, - &iisr_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave1_stateArgs[] = { + { { STATE_EXCSAVE1 }, 'm' } }; -static xtensa_iclass_internal rsr_iclass = { - 2, - &rsr_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc2_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *icache_operand_list[] = { - &ais_operand, - &iiuimm8x4_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc2_stateArgs[] = { + { { STATE_EPC2 }, 'i' } }; -static xtensa_iclass_internal icache_iclass = { - 2, - &icache_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc2_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *s8i_operand_list[] = { - &ait_operand, - &ais_operand, - &iiuimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc2_stateArgs[] = { + { { STATE_EPC2 }, 'o' } }; -static xtensa_iclass_internal s8i_iclass = { - 3, - &s8i_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc2_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal return_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc2_stateArgs[] = { + { { STATE_EPC2 }, 'm' } }; -static xtensa_operand_internal *dcache_operand_list[] = { - &ais_operand, - &iiuimm8x4_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave2_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal dcache_iclass = { - 2, - &dcache_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave2_stateArgs[] = { + { { STATE_EXCSAVE2 }, 'i' } }; -static xtensa_operand_internal *s32i_operand_list[] = { - &ait_operand, - &ais_operand, - &iiuimm8x4_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave2_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_iclass_internal s32i_iclass = { - 3, - &s32i_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave2_stateArgs[] = { + { { STATE_EXCSAVE2 }, 'o' } }; -static xtensa_operand_internal *jump_operand_list[] = { - &lisoffset_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave2_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal jump_iclass = { - 1, - &jump_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave2_stateArgs[] = { + { { STATE_EXCSAVE2 }, 'm' } }; -static xtensa_operand_internal *addi_n_operand_list[] = { - &aor_operand, - &ais_operand, - &iiai4const_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc3_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal addi_n_iclass = { - 3, - &addi_n_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc3_stateArgs[] = { + { { STATE_EPC3 }, 'i' } }; -static xtensa_iclass_internal sync_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc3_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *neg_operand_list[] = { - &aor_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc3_stateArgs[] = { + { { STATE_EPC3 }, 'o' } }; -static xtensa_iclass_internal neg_iclass = { - 2, - &neg_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc3_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_iclass_internal syscall_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc3_stateArgs[] = { + { { STATE_EPC3 }, 'm' } }; -static xtensa_operand_internal *bsz12_operand_list[] = { - &ais_operand, - &lisimm12_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave3_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_iclass_internal bsz12_iclass = { - 2, - &bsz12_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave3_stateArgs[] = { + { { STATE_EXCSAVE3 }, 'i' } }; -static xtensa_iclass_internal excw_iclass = { - 0, - 0 +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave3_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *movi_n_operand_list[] = { - &aos_operand, - &iisimm7_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave3_stateArgs[] = { + { { STATE_EXCSAVE3 }, 'o' } }; -static xtensa_iclass_internal movi_n_iclass = { - 2, - &movi_n_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave3_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *rtlb_operand_list[] = { - &aot_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave3_stateArgs[] = { + { { STATE_EXCSAVE3 }, 'm' } }; -static xtensa_iclass_internal rtlb_iclass = { - 2, - &rtlb_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc4_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *actl_operand_list[] = { - &aot_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_epc4_stateArgs[] = { + { { STATE_EPC4 }, 'i' } }; -static xtensa_iclass_internal actl_iclass = { - 2, - &actl_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc4_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *srli_operand_list[] = { - &aor_operand, - &ait_operand, - &iis_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_epc4_stateArgs[] = { + { { STATE_EPC4 }, 'o' } }; -static xtensa_iclass_internal srli_iclass = { - 3, - &srli_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc4_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *bsi8b_operand_list[] = { - &ais_operand, - &iibbi_operand, - &lisimm8_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_epc4_stateArgs[] = { + { { STATE_EPC4 }, 'm' } }; -static xtensa_iclass_internal bsi8b_iclass = { - 3, - &bsi8b_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave4_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *acts_operand_list[] = { - &ait_operand, - &ais_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_excsave4_stateArgs[] = { + { { STATE_EXCSAVE4 }, 'i' } }; -static xtensa_iclass_internal acts_iclass = { - 2, - &acts_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave4_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *add_n_operand_list[] = { - &aor_operand, - &ais_operand, - &ait_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_excsave4_stateArgs[] = { + { { STATE_EXCSAVE4 }, 'o' } }; -static xtensa_iclass_internal add_n_iclass = { - 3, - &add_n_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave4_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *srai_operand_list[] = { - &aor_operand, - &ait_operand, - &iisar_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_excsave4_stateArgs[] = { + { { STATE_EXCSAVE4 }, 'm' } }; -static xtensa_iclass_internal srai_iclass = { - 3, - &srai_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps2_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *entry_operand_list[] = { - &abs_operand, - &iiuimm12x8_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps2_stateArgs[] = { + { { STATE_EPS2 }, 'i' } }; -static xtensa_iclass_internal entry_iclass = { - 2, - &entry_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps2_args[] = { + { { 6 /* art */ }, 'i' } }; -static xtensa_operand_internal *l32e_operand_list[] = { - &aot_operand, - &ais_operand, - &iinimm4x2_operand +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps2_stateArgs[] = { + { { STATE_EPS2 }, 'o' } }; -static xtensa_iclass_internal l32e_iclass = { - 3, - &l32e_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps2_args[] = { + { { 6 /* art */ }, 'm' } }; -static xtensa_operand_internal *dpf_operand_list[] = { - &ais_operand, - &iiuimm8x4_operand +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps2_stateArgs[] = { + { { STATE_EPS2 }, 'm' } }; -static xtensa_iclass_internal dpf_iclass = { - 2, - &dpf_operand_list[0] +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps3_args[] = { + { { 6 /* art */ }, 'o' } }; -static xtensa_operand_internal *l32i_operand_list[] = { - &aot_operand, - &ais_operand, - &iiuimm8x4_operand +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps3_stateArgs[] = { + { { STATE_EPS3 }, 'i' } }; -static xtensa_iclass_internal l32i_iclass = { - 3, - &l32i_operand_list[0] -}; - -static xtensa_insnbuf abs_template (void); -static xtensa_insnbuf add_template (void); -static xtensa_insnbuf add_n_template (void); -static xtensa_insnbuf addi_template (void); -static xtensa_insnbuf addi_n_template (void); -static xtensa_insnbuf addmi_template (void); -static xtensa_insnbuf addx2_template (void); -static xtensa_insnbuf addx4_template (void); -static xtensa_insnbuf addx8_template (void); -static xtensa_insnbuf and_template (void); -static xtensa_insnbuf ball_template (void); -static xtensa_insnbuf bany_template (void); -static xtensa_insnbuf bbc_template (void); -static xtensa_insnbuf bbci_template (void); -static xtensa_insnbuf bbs_template (void); -static xtensa_insnbuf bbsi_template (void); -static xtensa_insnbuf beq_template (void); -static xtensa_insnbuf beqi_template (void); -static xtensa_insnbuf beqz_template (void); -static xtensa_insnbuf beqz_n_template (void); -static xtensa_insnbuf bge_template (void); -static xtensa_insnbuf bgei_template (void); -static xtensa_insnbuf bgeu_template (void); -static xtensa_insnbuf bgeui_template (void); -static xtensa_insnbuf bgez_template (void); -static xtensa_insnbuf blt_template (void); -static xtensa_insnbuf blti_template (void); -static xtensa_insnbuf bltu_template (void); -static xtensa_insnbuf bltui_template (void); -static xtensa_insnbuf bltz_template (void); -static xtensa_insnbuf bnall_template (void); -static xtensa_insnbuf bne_template (void); -static xtensa_insnbuf bnei_template (void); -static xtensa_insnbuf bnez_template (void); -static xtensa_insnbuf bnez_n_template (void); -static xtensa_insnbuf bnone_template (void); -static xtensa_insnbuf break_template (void); -static xtensa_insnbuf break_n_template (void); -static xtensa_insnbuf call0_template (void); -static xtensa_insnbuf call12_template (void); -static xtensa_insnbuf call4_template (void); -static xtensa_insnbuf call8_template (void); -static xtensa_insnbuf callx0_template (void); -static xtensa_insnbuf callx12_template (void); -static xtensa_insnbuf callx4_template (void); -static xtensa_insnbuf callx8_template (void); -static xtensa_insnbuf dhi_template (void); -static xtensa_insnbuf dhwb_template (void); -static xtensa_insnbuf dhwbi_template (void); -static xtensa_insnbuf dii_template (void); -static xtensa_insnbuf diwb_template (void); -static xtensa_insnbuf diwbi_template (void); -static xtensa_insnbuf dpfr_template (void); -static xtensa_insnbuf dpfro_template (void); -static xtensa_insnbuf dpfw_template (void); -static xtensa_insnbuf dpfwo_template (void); -static xtensa_insnbuf dsync_template (void); -static xtensa_insnbuf entry_template (void); -static xtensa_insnbuf esync_template (void); -static xtensa_insnbuf excw_template (void); -static xtensa_insnbuf extui_template (void); -static xtensa_insnbuf idtlb_template (void); -static xtensa_insnbuf idtlba_template (void); -static xtensa_insnbuf ihi_template (void); -static xtensa_insnbuf iii_template (void); -static xtensa_insnbuf iitlb_template (void); -static xtensa_insnbuf iitlba_template (void); -static xtensa_insnbuf ipf_template (void); -static xtensa_insnbuf isync_template (void); -static xtensa_insnbuf j_template (void); -static xtensa_insnbuf jx_template (void); -static xtensa_insnbuf l16si_template (void); -static xtensa_insnbuf l16ui_template (void); -static xtensa_insnbuf l32e_template (void); -static xtensa_insnbuf l32i_template (void); -static xtensa_insnbuf l32i_n_template (void); -static xtensa_insnbuf l32r_template (void); -static xtensa_insnbuf l8ui_template (void); -static xtensa_insnbuf ldct_template (void); -static xtensa_insnbuf lict_template (void); -static xtensa_insnbuf licw_template (void); -static xtensa_insnbuf loop_template (void); -static xtensa_insnbuf loopgtz_template (void); -static xtensa_insnbuf loopnez_template (void); -static xtensa_insnbuf memw_template (void); -static xtensa_insnbuf mov_n_template (void); -static xtensa_insnbuf moveqz_template (void); -static xtensa_insnbuf movgez_template (void); -static xtensa_insnbuf movi_template (void); -static xtensa_insnbuf movi_n_template (void); -static xtensa_insnbuf movltz_template (void); -static xtensa_insnbuf movnez_template (void); -static xtensa_insnbuf movsp_template (void); -static xtensa_insnbuf neg_template (void); -static xtensa_insnbuf nop_n_template (void); -static xtensa_insnbuf nsa_template (void); -static xtensa_insnbuf nsau_template (void); -static xtensa_insnbuf or_template (void); -static xtensa_insnbuf pdtlb_template (void); -static xtensa_insnbuf pitlb_template (void); -static xtensa_insnbuf rdtlb0_template (void); -static xtensa_insnbuf rdtlb1_template (void); -static xtensa_insnbuf ret_template (void); -static xtensa_insnbuf ret_n_template (void); -static xtensa_insnbuf retw_template (void); -static xtensa_insnbuf retw_n_template (void); -static xtensa_insnbuf rfde_template (void); -static xtensa_insnbuf rfe_template (void); -static xtensa_insnbuf rfi_template (void); -static xtensa_insnbuf rfwo_template (void); -static xtensa_insnbuf rfwu_template (void); -static xtensa_insnbuf ritlb0_template (void); -static xtensa_insnbuf ritlb1_template (void); -static xtensa_insnbuf rotw_template (void); -static xtensa_insnbuf rsil_template (void); -static xtensa_insnbuf rsr_template (void); -static xtensa_insnbuf rsync_template (void); -static xtensa_insnbuf s16i_template (void); -static xtensa_insnbuf s32e_template (void); -static xtensa_insnbuf s32i_template (void); -static xtensa_insnbuf s32i_n_template (void); -static xtensa_insnbuf s8i_template (void); -static xtensa_insnbuf sdct_template (void); -static xtensa_insnbuf sict_template (void); -static xtensa_insnbuf sicw_template (void); -static xtensa_insnbuf simcall_template (void); -static xtensa_insnbuf sll_template (void); -static xtensa_insnbuf slli_template (void); -static xtensa_insnbuf sra_template (void); -static xtensa_insnbuf srai_template (void); -static xtensa_insnbuf src_template (void); -static xtensa_insnbuf srl_template (void); -static xtensa_insnbuf srli_template (void); -static xtensa_insnbuf ssa8b_template (void); -static xtensa_insnbuf ssa8l_template (void); -static xtensa_insnbuf ssai_template (void); -static xtensa_insnbuf ssl_template (void); -static xtensa_insnbuf ssr_template (void); -static xtensa_insnbuf sub_template (void); -static xtensa_insnbuf subx2_template (void); -static xtensa_insnbuf subx4_template (void); -static xtensa_insnbuf subx8_template (void); -static xtensa_insnbuf syscall_template (void); -static xtensa_insnbuf waiti_template (void); -static xtensa_insnbuf wdtlb_template (void); -static xtensa_insnbuf witlb_template (void); -static xtensa_insnbuf wsr_template (void); -static xtensa_insnbuf xor_template (void); -static xtensa_insnbuf xsr_template (void); - -static xtensa_insnbuf -abs_template (void) -{ - static xtensa_insnbuf_word template[] = { 0x00001006 }; - return &template[0]; -} - -static xtensa_insnbuf -add_template (void) -{ - static xtensa_insnbuf_word template[] = { 0x00000008 }; - return &template[0]; -} - -static xtensa_insnbuf -add_n_template (void) +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_stateArgs[] = { + { { STATE_EPS3 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps3_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps3_stateArgs[] = { + { { STATE_EPS3 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps4_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_eps4_stateArgs[] = { + { { STATE_EPS4 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps4_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_eps4_stateArgs[] = { + { { STATE_EPS4 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps4_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_eps4_stateArgs[] = { + { { STATE_EPS4 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_excvaddr_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_excvaddr_stateArgs[] = { + { { STATE_EXCVADDR }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_excvaddr_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_excvaddr_stateArgs[] = { + { { STATE_EXCVADDR }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_excvaddr_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_excvaddr_stateArgs[] = { + { { STATE_EXCVADDR }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_depc_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_depc_stateArgs[] = { + { { STATE_DEPC }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_depc_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_depc_stateArgs[] = { + { { STATE_DEPC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_depc_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_depc_stateArgs[] = { + { { STATE_DEPC }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_exccause_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_exccause_stateArgs[] = { + { { STATE_EXCCAUSE }, 'i' }, + { { STATE_XTSYNC }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_exccause_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_exccause_stateArgs[] = { + { { STATE_EXCCAUSE }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_exccause_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_exccause_stateArgs[] = { + { { STATE_EXCCAUSE }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_misc0_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_misc0_stateArgs[] = { + { { STATE_MISC0 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_misc0_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_misc0_stateArgs[] = { + { { STATE_MISC0 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_misc0_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_misc0_stateArgs[] = { + { { STATE_MISC0 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_misc1_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_misc1_stateArgs[] = { + { { STATE_MISC1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_misc1_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_misc1_stateArgs[] = { + { { STATE_MISC1 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_misc1_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_misc1_stateArgs[] = { + { { STATE_MISC1 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_prid_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rfi_args[] = { + { { 40 /* s */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rfi_stateArgs[] = { + { { STATE_PSWOE }, 'o' }, + { { STATE_PSCALLINC }, 'o' }, + { { STATE_PSOWB }, 'o' }, + { { STATE_PSUM }, 'o' }, + { { STATE_PSEXCM }, 'o' }, + { { STATE_PSINTLEVEL }, 'o' }, + { { STATE_EPC1 }, 'i' }, + { { STATE_EPC2 }, 'i' }, + { { STATE_EPC3 }, 'i' }, + { { STATE_EPC4 }, 'i' }, + { { STATE_EPS2 }, 'i' }, + { { STATE_EPS3 }, 'i' }, + { { STATE_EPS4 }, 'i' }, + { { STATE_InOCDMode }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wait_args[] = { + { { 40 /* s */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wait_stateArgs[] = { + { { STATE_PSINTLEVEL }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_interrupt_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_interrupt_stateArgs[] = { + { { STATE_INTERRUPT }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intset_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intset_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intclear_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intclear_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_intenable_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_intenable_stateArgs[] = { + { { STATE_INTENABLE }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intenable_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_intenable_stateArgs[] = { + { { STATE_INTENABLE }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_intenable_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_intenable_stateArgs[] = { + { { STATE_INTENABLE }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_break_args[] = { + { { 34 /* imms */ }, 'i' }, + { { 33 /* immt */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_break_stateArgs[] = { + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSINTLEVEL }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_break_n_args[] = { + { { 34 /* imms */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_break_n_stateArgs[] = { + { { STATE_PSEXCM }, 'i' }, + { { STATE_PSINTLEVEL }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka0_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka0_stateArgs[] = { + { { STATE_DBREAKA0 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka0_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka0_stateArgs[] = { + { { STATE_DBREAKA0 }, 'o' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka0_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka0_stateArgs[] = { + { { STATE_DBREAKA0 }, 'm' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc0_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc0_stateArgs[] = { + { { STATE_DBREAKC0 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc0_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc0_stateArgs[] = { + { { STATE_DBREAKC0 }, 'o' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc0_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc0_stateArgs[] = { + { { STATE_DBREAKC0 }, 'm' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka1_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreaka1_stateArgs[] = { + { { STATE_DBREAKA1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka1_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreaka1_stateArgs[] = { + { { STATE_DBREAKA1 }, 'o' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka1_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreaka1_stateArgs[] = { + { { STATE_DBREAKA1 }, 'm' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc1_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_dbreakc1_stateArgs[] = { + { { STATE_DBREAKC1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc1_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_dbreakc1_stateArgs[] = { + { { STATE_DBREAKC1 }, 'o' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc1_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_dbreakc1_stateArgs[] = { + { { STATE_DBREAKC1 }, 'm' }, + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka0_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka0_stateArgs[] = { + { { STATE_IBREAKA0 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka0_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka0_stateArgs[] = { + { { STATE_IBREAKA0 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka0_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka0_stateArgs[] = { + { { STATE_IBREAKA0 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka1_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreaka1_stateArgs[] = { + { { STATE_IBREAKA1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka1_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreaka1_stateArgs[] = { + { { STATE_IBREAKA1 }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka1_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreaka1_stateArgs[] = { + { { STATE_IBREAKA1 }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreakenable_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ibreakenable_stateArgs[] = { + { { STATE_IBREAKENABLE }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreakenable_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ibreakenable_stateArgs[] = { + { { STATE_IBREAKENABLE }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreakenable_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ibreakenable_stateArgs[] = { + { { STATE_IBREAKENABLE }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_debugcause_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_debugcause_stateArgs[] = { + { { STATE_DEBUGCAUSE }, 'i' }, + { { STATE_DBNUM }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_debugcause_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_debugcause_stateArgs[] = { + { { STATE_DEBUGCAUSE }, 'o' }, + { { STATE_DBNUM }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_debugcause_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_debugcause_stateArgs[] = { + { { STATE_DEBUGCAUSE }, 'm' }, + { { STATE_DBNUM }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_icount_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_icount_stateArgs[] = { + { { STATE_ICOUNT }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_icount_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_icount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_ICOUNT }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_icount_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_icount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_ICOUNT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_icountlevel_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_icountlevel_stateArgs[] = { + { { STATE_ICOUNTLEVEL }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_icountlevel_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_icountlevel_stateArgs[] = { + { { STATE_ICOUNTLEVEL }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_icountlevel_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_icountlevel_stateArgs[] = { + { { STATE_ICOUNTLEVEL }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ddr_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ddr_stateArgs[] = { + { { STATE_DDR }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ddr_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ddr_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_DDR }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ddr_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ddr_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_DDR }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rfdo_stateArgs[] = { + { { STATE_InOCDMode }, 'm' }, + { { STATE_EPC4 }, 'i' }, + { { STATE_PSWOE }, 'o' }, + { { STATE_PSCALLINC }, 'o' }, + { { STATE_PSOWB }, 'o' }, + { { STATE_PSUM }, 'o' }, + { { STATE_PSEXCM }, 'o' }, + { { STATE_PSINTLEVEL }, 'o' }, + { { STATE_EPS4 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rfdd_stateArgs[] = { + { { STATE_InOCDMode }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccount_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccount_stateArgs[] = { + { { STATE_CCOUNT }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccount_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_CCOUNT }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccount_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccount_stateArgs[] = { + { { STATE_XTSYNC }, 'o' }, + { { STATE_CCOUNT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare0_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare0_stateArgs[] = { + { { STATE_CCOMPARE0 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare0_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare0_stateArgs[] = { + { { STATE_CCOMPARE0 }, 'o' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare0_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare0_stateArgs[] = { + { { STATE_CCOMPARE0 }, 'm' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare1_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare1_stateArgs[] = { + { { STATE_CCOMPARE1 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare1_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare1_stateArgs[] = { + { { STATE_CCOMPARE1 }, 'o' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare1_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare1_stateArgs[] = { + { { STATE_CCOMPARE1 }, 'm' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare2_args[] = { + { { 6 /* art */ }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rsr_ccompare2_stateArgs[] = { + { { STATE_CCOMPARE2 }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare2_args[] = { + { { 6 /* art */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wsr_ccompare2_stateArgs[] = { + { { STATE_CCOMPARE2 }, 'o' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare2_args[] = { + { { 6 /* art */ }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_xsr_ccompare2_stateArgs[] = { + { { STATE_CCOMPARE2 }, 'm' }, + { { STATE_INTERRUPT }, 'm' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_icache_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_icache_inv_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_licx_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_sicx_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_dcache_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_dcache_ind_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 22 /* uimm4x16 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_dcache_inv_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_dpf_args[] = { + { { 4 /* ars */ }, 'i' }, + { { 21 /* uimm8x4 */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_sdct_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_ldct_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_idtlb_args[] = { + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_idtlb_stateArgs[] = { + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_rdtlb_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wdtlb_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_wdtlb_stateArgs[] = { + { { STATE_XTSYNC }, 'o' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_iitlb_args[] = { + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_ritlb_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_witlb_args[] = { + { { 6 /* art */ }, 'i' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_arg_internal Iclass_xt_iclass_nsa_args[] = { + { { 6 /* art */ }, 'o' }, + { { 4 /* ars */ }, 'i' } +}; + +static xtensa_iclass_internal iclasses[] = { + { 0, 0 /* xt_iclass_excw */, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_rfe */, + 2, Iclass_xt_iclass_rfe_stateArgs, 0, 0 }, + { 0, 0 /* xt_iclass_rfde */, + 1, Iclass_xt_iclass_rfde_stateArgs, 0, 0 }, + { 0, 0 /* xt_iclass_syscall */, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_simcall */, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_call12_args, + 1, Iclass_xt_iclass_call12_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_call8_args, + 1, Iclass_xt_iclass_call8_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_call4_args, + 1, Iclass_xt_iclass_call4_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_callx12_args, + 1, Iclass_xt_iclass_callx12_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_callx8_args, + 1, Iclass_xt_iclass_callx8_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_callx4_args, + 1, Iclass_xt_iclass_callx4_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_entry_args, + 5, Iclass_xt_iclass_entry_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_movsp_args, + 2, Iclass_xt_iclass_movsp_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rotw_args, + 1, Iclass_xt_iclass_rotw_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_retw_args, + 4, Iclass_xt_iclass_retw_stateArgs, 0, 0 }, + { 0, 0 /* xt_iclass_rfwou */, + 5, Iclass_xt_iclass_rfwou_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_l32e_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_s32e_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_windowbase_args, + 1, Iclass_xt_iclass_rsr_windowbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_windowbase_args, + 1, Iclass_xt_iclass_wsr_windowbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_windowbase_args, + 1, Iclass_xt_iclass_xsr_windowbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_windowstart_args, + 1, Iclass_xt_iclass_rsr_windowstart_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_windowstart_args, + 1, Iclass_xt_iclass_wsr_windowstart_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_windowstart_args, + 1, Iclass_xt_iclass_xsr_windowstart_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_add_n_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_addi_n_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_bz6_args, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_ill_n */, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_loadi4_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_mov_n_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_movi_n_args, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_nopn */, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_retn_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_storei4_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_addi_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_addmi_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_addsub_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_bit_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_bsi8_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_bsi8b_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_bsi8u_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_bst8_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_bsz12_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_call0_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_callx0_args, + 0, 0, 0, 0 }, + { 4, Iclass_xt_iclass_exti_args, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_ill */, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_jump_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_jumpx_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_l16ui_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_l16si_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_l32i_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_l32r_args, + 2, Iclass_xt_iclass_l32r_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_l8i_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_loop_args, + 3, Iclass_xt_iclass_loop_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_loopz_args, + 3, Iclass_xt_iclass_loopz_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_movi_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_movz_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_neg_args, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_nop */, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_return_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_s16i_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_s32i_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_s8i_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_sar_args, + 1, Iclass_xt_iclass_sar_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_sari_args, + 1, Iclass_xt_iclass_sari_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_shifts_args, + 1, Iclass_xt_iclass_shifts_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_shiftst_args, + 1, Iclass_xt_iclass_shiftst_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_shiftt_args, + 1, Iclass_xt_iclass_shiftt_stateArgs, 0, 0 }, + { 3, Iclass_xt_iclass_slli_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_srai_args, + 0, 0, 0, 0 }, + { 3, Iclass_xt_iclass_srli_args, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_memw */, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_extw */, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_isync */, + 0, 0, 0, 0 }, + { 0, 0 /* xt_iclass_sync */, + 1, Iclass_xt_iclass_sync_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_rsil_args, + 6, Iclass_xt_iclass_rsil_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_lend_args, + 1, Iclass_xt_iclass_rsr_lend_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_lend_args, + 1, Iclass_xt_iclass_wsr_lend_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_lend_args, + 1, Iclass_xt_iclass_xsr_lend_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_lcount_args, + 1, Iclass_xt_iclass_rsr_lcount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_lcount_args, + 2, Iclass_xt_iclass_wsr_lcount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_lcount_args, + 2, Iclass_xt_iclass_xsr_lcount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_lbeg_args, + 1, Iclass_xt_iclass_rsr_lbeg_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_lbeg_args, + 1, Iclass_xt_iclass_wsr_lbeg_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_lbeg_args, + 1, Iclass_xt_iclass_xsr_lbeg_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_sar_args, + 1, Iclass_xt_iclass_rsr_sar_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_sar_args, + 2, Iclass_xt_iclass_wsr_sar_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_sar_args, + 1, Iclass_xt_iclass_xsr_sar_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_litbase_args, + 2, Iclass_xt_iclass_rsr_litbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_litbase_args, + 2, Iclass_xt_iclass_wsr_litbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_litbase_args, + 2, Iclass_xt_iclass_xsr_litbase_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_176_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_208_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ps_args, + 6, Iclass_xt_iclass_rsr_ps_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ps_args, + 6, Iclass_xt_iclass_wsr_ps_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ps_args, + 6, Iclass_xt_iclass_xsr_ps_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_epc1_args, + 1, Iclass_xt_iclass_rsr_epc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_epc1_args, + 1, Iclass_xt_iclass_wsr_epc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_epc1_args, + 1, Iclass_xt_iclass_xsr_epc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_excsave1_args, + 1, Iclass_xt_iclass_rsr_excsave1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_excsave1_args, + 1, Iclass_xt_iclass_wsr_excsave1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_excsave1_args, + 1, Iclass_xt_iclass_xsr_excsave1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_epc2_args, + 1, Iclass_xt_iclass_rsr_epc2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_epc2_args, + 1, Iclass_xt_iclass_wsr_epc2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_epc2_args, + 1, Iclass_xt_iclass_xsr_epc2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_excsave2_args, + 1, Iclass_xt_iclass_rsr_excsave2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_excsave2_args, + 1, Iclass_xt_iclass_wsr_excsave2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_excsave2_args, + 1, Iclass_xt_iclass_xsr_excsave2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_epc3_args, + 1, Iclass_xt_iclass_rsr_epc3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_epc3_args, + 1, Iclass_xt_iclass_wsr_epc3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_epc3_args, + 1, Iclass_xt_iclass_xsr_epc3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_excsave3_args, + 1, Iclass_xt_iclass_rsr_excsave3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_excsave3_args, + 1, Iclass_xt_iclass_wsr_excsave3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_excsave3_args, + 1, Iclass_xt_iclass_xsr_excsave3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_epc4_args, + 1, Iclass_xt_iclass_rsr_epc4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_epc4_args, + 1, Iclass_xt_iclass_wsr_epc4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_epc4_args, + 1, Iclass_xt_iclass_xsr_epc4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_excsave4_args, + 1, Iclass_xt_iclass_rsr_excsave4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_excsave4_args, + 1, Iclass_xt_iclass_wsr_excsave4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_excsave4_args, + 1, Iclass_xt_iclass_xsr_excsave4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_eps2_args, + 1, Iclass_xt_iclass_rsr_eps2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_eps2_args, + 1, Iclass_xt_iclass_wsr_eps2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_eps2_args, + 1, Iclass_xt_iclass_xsr_eps2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_eps3_args, + 1, Iclass_xt_iclass_rsr_eps3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_eps3_args, + 1, Iclass_xt_iclass_wsr_eps3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_eps3_args, + 1, Iclass_xt_iclass_xsr_eps3_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_eps4_args, + 1, Iclass_xt_iclass_rsr_eps4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_eps4_args, + 1, Iclass_xt_iclass_wsr_eps4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_eps4_args, + 1, Iclass_xt_iclass_xsr_eps4_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_excvaddr_args, + 1, Iclass_xt_iclass_rsr_excvaddr_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_excvaddr_args, + 1, Iclass_xt_iclass_wsr_excvaddr_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_excvaddr_args, + 1, Iclass_xt_iclass_xsr_excvaddr_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_depc_args, + 1, Iclass_xt_iclass_rsr_depc_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_depc_args, + 1, Iclass_xt_iclass_wsr_depc_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_depc_args, + 1, Iclass_xt_iclass_xsr_depc_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_exccause_args, + 2, Iclass_xt_iclass_rsr_exccause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_exccause_args, + 1, Iclass_xt_iclass_wsr_exccause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_exccause_args, + 1, Iclass_xt_iclass_xsr_exccause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_misc0_args, + 1, Iclass_xt_iclass_rsr_misc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_misc0_args, + 1, Iclass_xt_iclass_wsr_misc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_misc0_args, + 1, Iclass_xt_iclass_xsr_misc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_misc1_args, + 1, Iclass_xt_iclass_rsr_misc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_misc1_args, + 1, Iclass_xt_iclass_wsr_misc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_misc1_args, + 1, Iclass_xt_iclass_xsr_misc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_prid_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_rfi_args, + 14, Iclass_xt_iclass_rfi_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wait_args, + 1, Iclass_xt_iclass_wait_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_interrupt_args, + 1, Iclass_xt_iclass_rsr_interrupt_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_intset_args, + 2, Iclass_xt_iclass_wsr_intset_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_intclear_args, + 2, Iclass_xt_iclass_wsr_intclear_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_intenable_args, + 1, Iclass_xt_iclass_rsr_intenable_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_intenable_args, + 1, Iclass_xt_iclass_wsr_intenable_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_intenable_args, + 1, Iclass_xt_iclass_xsr_intenable_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_break_args, + 2, Iclass_xt_iclass_break_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_break_n_args, + 2, Iclass_xt_iclass_break_n_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_dbreaka0_args, + 1, Iclass_xt_iclass_rsr_dbreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_dbreaka0_args, + 2, Iclass_xt_iclass_wsr_dbreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_dbreaka0_args, + 2, Iclass_xt_iclass_xsr_dbreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_dbreakc0_args, + 1, Iclass_xt_iclass_rsr_dbreakc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_dbreakc0_args, + 2, Iclass_xt_iclass_wsr_dbreakc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_dbreakc0_args, + 2, Iclass_xt_iclass_xsr_dbreakc0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_dbreaka1_args, + 1, Iclass_xt_iclass_rsr_dbreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_dbreaka1_args, + 2, Iclass_xt_iclass_wsr_dbreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_dbreaka1_args, + 2, Iclass_xt_iclass_xsr_dbreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_dbreakc1_args, + 1, Iclass_xt_iclass_rsr_dbreakc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_dbreakc1_args, + 2, Iclass_xt_iclass_wsr_dbreakc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_dbreakc1_args, + 2, Iclass_xt_iclass_xsr_dbreakc1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ibreaka0_args, + 1, Iclass_xt_iclass_rsr_ibreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ibreaka0_args, + 1, Iclass_xt_iclass_wsr_ibreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ibreaka0_args, + 1, Iclass_xt_iclass_xsr_ibreaka0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ibreaka1_args, + 1, Iclass_xt_iclass_rsr_ibreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ibreaka1_args, + 1, Iclass_xt_iclass_wsr_ibreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ibreaka1_args, + 1, Iclass_xt_iclass_xsr_ibreaka1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ibreakenable_args, + 1, Iclass_xt_iclass_rsr_ibreakenable_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ibreakenable_args, + 1, Iclass_xt_iclass_wsr_ibreakenable_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ibreakenable_args, + 1, Iclass_xt_iclass_xsr_ibreakenable_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_debugcause_args, + 2, Iclass_xt_iclass_rsr_debugcause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_debugcause_args, + 2, Iclass_xt_iclass_wsr_debugcause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_debugcause_args, + 2, Iclass_xt_iclass_xsr_debugcause_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_icount_args, + 1, Iclass_xt_iclass_rsr_icount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_icount_args, + 2, Iclass_xt_iclass_wsr_icount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_icount_args, + 2, Iclass_xt_iclass_xsr_icount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_icountlevel_args, + 1, Iclass_xt_iclass_rsr_icountlevel_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_icountlevel_args, + 1, Iclass_xt_iclass_wsr_icountlevel_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_icountlevel_args, + 1, Iclass_xt_iclass_xsr_icountlevel_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ddr_args, + 1, Iclass_xt_iclass_rsr_ddr_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ddr_args, + 2, Iclass_xt_iclass_wsr_ddr_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ddr_args, + 2, Iclass_xt_iclass_xsr_ddr_stateArgs, 0, 0 }, + { 0, 0 /* xt_iclass_rfdo */, + 9, Iclass_xt_iclass_rfdo_stateArgs, 0, 0 }, + { 0, 0 /* xt_iclass_rfdd */, + 1, Iclass_xt_iclass_rfdd_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ccount_args, + 1, Iclass_xt_iclass_rsr_ccount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ccount_args, + 2, Iclass_xt_iclass_wsr_ccount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ccount_args, + 2, Iclass_xt_iclass_xsr_ccount_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ccompare0_args, + 1, Iclass_xt_iclass_rsr_ccompare0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ccompare0_args, + 2, Iclass_xt_iclass_wsr_ccompare0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ccompare0_args, + 2, Iclass_xt_iclass_xsr_ccompare0_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ccompare1_args, + 1, Iclass_xt_iclass_rsr_ccompare1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ccompare1_args, + 2, Iclass_xt_iclass_wsr_ccompare1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ccompare1_args, + 2, Iclass_xt_iclass_xsr_ccompare1_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_rsr_ccompare2_args, + 1, Iclass_xt_iclass_rsr_ccompare2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_wsr_ccompare2_args, + 2, Iclass_xt_iclass_wsr_ccompare2_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_xsr_ccompare2_args, + 2, Iclass_xt_iclass_xsr_ccompare2_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_icache_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_icache_inv_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_licx_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_sicx_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_dcache_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_dcache_ind_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_dcache_inv_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_dpf_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_sdct_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_ldct_args, + 0, 0, 0, 0 }, + { 1, Iclass_xt_iclass_idtlb_args, + 1, Iclass_xt_iclass_idtlb_stateArgs, 0, 0 }, + { 2, Iclass_xt_iclass_rdtlb_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_wdtlb_args, + 1, Iclass_xt_iclass_wdtlb_stateArgs, 0, 0 }, + { 1, Iclass_xt_iclass_iitlb_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_ritlb_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_witlb_args, + 0, 0, 0, 0 }, + { 2, Iclass_xt_iclass_nsa_args, + 0, 0, 0, 0 } +}; + + +/* Opcode encodings. */ + +static void +Opcode_excw_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00a00000 }; - return &template[0]; + slotbuf[0] = 0x80200; } -static xtensa_insnbuf -addi_template (void) +static void +Opcode_rfe_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200c00 }; - return &template[0]; + slotbuf[0] = 0x300; } -static xtensa_insnbuf -addi_n_template (void) +static void +Opcode_rfde_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00b00000 }; - return &template[0]; + slotbuf[0] = 0x2300; } -static xtensa_insnbuf -addmi_template (void) +static void +Opcode_syscall_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200d00 }; - return &template[0]; + slotbuf[0] = 0x500; } -static xtensa_insnbuf -addx2_template (void) +static void +Opcode_simcall_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000009 }; - return &template[0]; + slotbuf[0] = 0x1500; } -static xtensa_insnbuf -addx4_template (void) +static void +Opcode_call12_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000a }; - return &template[0]; + slotbuf[0] = 0x5c0000; } -static xtensa_insnbuf -addx8_template (void) +static void +Opcode_call8_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000b }; - return &template[0]; + slotbuf[0] = 0x580000; } -static xtensa_insnbuf -and_template (void) +static void +Opcode_call4_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000001 }; - return &template[0]; + slotbuf[0] = 0x540000; } -static xtensa_insnbuf -ball_template (void) +static void +Opcode_callx12_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700400 }; - return &template[0]; + slotbuf[0] = 0xf0000; } -static xtensa_insnbuf -bany_template (void) +static void +Opcode_callx8_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700800 }; - return &template[0]; + slotbuf[0] = 0xb0000; } -static xtensa_insnbuf -bbc_template (void) +static void +Opcode_callx4_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700500 }; - return &template[0]; + slotbuf[0] = 0x70000; } -static xtensa_insnbuf -bbci_template (void) +static void +Opcode_entry_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700600 }; - return &template[0]; + slotbuf[0] = 0x6c0000; } -static xtensa_insnbuf -bbs_template (void) +static void +Opcode_movsp_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700d00 }; - return &template[0]; + slotbuf[0] = 0x100; } -static xtensa_insnbuf -bbsi_template (void) +static void +Opcode_rotw_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700e00 }; - return &template[0]; + slotbuf[0] = 0x804; } -static xtensa_insnbuf -beq_template (void) +static void +Opcode_retw_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700100 }; - return &template[0]; + slotbuf[0] = 0x60000; } -static xtensa_insnbuf -beqi_template (void) +static void +Opcode_retw_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00680000 }; - return &template[0]; + slotbuf[0] = 0xd10f; } -static xtensa_insnbuf -beqz_template (void) +static void +Opcode_rfwo_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00640000 }; - return &template[0]; + slotbuf[0] = 0x4300; } -static xtensa_insnbuf -beqz_n_template (void) +static void +Opcode_rfwu_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00c80000 }; - return &template[0]; + slotbuf[0] = 0x5300; } -static xtensa_insnbuf -bge_template (void) +static void +Opcode_l32e_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700a00 }; - return &template[0]; + slotbuf[0] = 0x90; } -static xtensa_insnbuf -bgei_template (void) +static void +Opcode_s32e_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006b0000 }; - return &template[0]; + slotbuf[0] = 0x94; } -static xtensa_insnbuf -bgeu_template (void) +static void +Opcode_rsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700b00 }; - return &template[0]; + slotbuf[0] = 0x4830; } -static xtensa_insnbuf -bgeui_template (void) +static void +Opcode_wsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006f0000 }; - return &template[0]; + slotbuf[0] = 0x4831; } -static xtensa_insnbuf -bgez_template (void) +static void +Opcode_xsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00670000 }; - return &template[0]; + slotbuf[0] = 0x4816; } -static xtensa_insnbuf -blt_template (void) +static void +Opcode_rsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700200 }; - return &template[0]; + slotbuf[0] = 0x4930; } -static xtensa_insnbuf -blti_template (void) +static void +Opcode_wsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006a0000 }; - return &template[0]; + slotbuf[0] = 0x4931; } -static xtensa_insnbuf -bltu_template (void) +static void +Opcode_xsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700300 }; - return &template[0]; + slotbuf[0] = 0x4916; } -static xtensa_insnbuf -bltui_template (void) +static void +Opcode_add_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006e0000 }; - return &template[0]; + slotbuf[0] = 0xa000; } -static xtensa_insnbuf -bltz_template (void) +static void +Opcode_addi_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00660000 }; - return &template[0]; + slotbuf[0] = 0xb000; } -static xtensa_insnbuf -bnall_template (void) +static void +Opcode_beqz_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700c00 }; - return &template[0]; + slotbuf[0] = 0xc800; } -static xtensa_insnbuf -bne_template (void) +static void +Opcode_bnez_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700900 }; - return &template[0]; + slotbuf[0] = 0xcc00; } -static xtensa_insnbuf -bnei_template (void) +static void +Opcode_ill_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00690000 }; - return &template[0]; + slotbuf[0] = 0xd60f; } -static xtensa_insnbuf -bnez_template (void) +static void +Opcode_l32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00650000 }; - return &template[0]; + slotbuf[0] = 0x8000; } -static xtensa_insnbuf -bnez_n_template (void) +static void +Opcode_mov_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00cc0000 }; - return &template[0]; + slotbuf[0] = 0xd000; } -static xtensa_insnbuf -bnone_template (void) +static void +Opcode_movi_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00700000 }; - return &template[0]; + slotbuf[0] = 0xc000; } -static xtensa_insnbuf -break_template (void) +static void +Opcode_nop_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000400 }; - return &template[0]; + slotbuf[0] = 0xd30f; } -static xtensa_insnbuf -break_n_template (void) +static void +Opcode_ret_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00d20f00 }; - return &template[0]; + slotbuf[0] = 0xd00f; } -static xtensa_insnbuf -call0_template (void) +static void +Opcode_s32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00500000 }; - return &template[0]; + slotbuf[0] = 0x9000; } -static xtensa_insnbuf -call12_template (void) +static void +Opcode_addi_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x005c0000 }; - return &template[0]; + slotbuf[0] = 0x200c00; } -static xtensa_insnbuf -call4_template (void) +static void +Opcode_addmi_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00540000 }; - return &template[0]; + slotbuf[0] = 0x200d00; } -static xtensa_insnbuf -call8_template (void) +static void +Opcode_add_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00580000 }; - return &template[0]; + slotbuf[0] = 0x8; } -static xtensa_insnbuf -callx0_template (void) +static void +Opcode_sub_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00030000 }; - return &template[0]; + slotbuf[0] = 0xc; } -static xtensa_insnbuf -callx12_template (void) +static void +Opcode_addx2_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x000f0000 }; - return &template[0]; + slotbuf[0] = 0x9; } -static xtensa_insnbuf -callx4_template (void) +static void +Opcode_addx4_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00070000 }; - return &template[0]; + slotbuf[0] = 0xa; } -static xtensa_insnbuf -callx8_template (void) +static void +Opcode_addx8_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x000b0000 }; - return &template[0]; + slotbuf[0] = 0xb; } -static xtensa_insnbuf -dhi_template (void) +static void +Opcode_subx2_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00260700 }; - return &template[0]; + slotbuf[0] = 0xd; } -static xtensa_insnbuf -dhwb_template (void) +static void +Opcode_subx4_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00240700 }; - return &template[0]; + slotbuf[0] = 0xe; } -static xtensa_insnbuf -dhwbi_template (void) +static void +Opcode_subx8_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00250700 }; - return &template[0]; + slotbuf[0] = 0xf; } -static xtensa_insnbuf -dii_template (void) +static void +Opcode_and_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00270700 }; - return &template[0]; + slotbuf[0] = 0x1; } -static xtensa_insnbuf -diwb_template (void) +static void +Opcode_or_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00280740 }; - return &template[0]; + slotbuf[0] = 0x2; } -static xtensa_insnbuf -diwbi_template (void) +static void +Opcode_xor_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00280750 }; - return &template[0]; + slotbuf[0] = 0x3; } -static xtensa_insnbuf -dpfr_template (void) +static void +Opcode_beqi_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200700 }; - return &template[0]; + slotbuf[0] = 0x680000; } -static xtensa_insnbuf -dpfro_template (void) +static void +Opcode_bnei_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00220700 }; - return &template[0]; + slotbuf[0] = 0x690000; } -static xtensa_insnbuf -dpfw_template (void) +static void +Opcode_bgei_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00210700 }; - return &template[0]; + slotbuf[0] = 0x6b0000; } -static xtensa_insnbuf -dpfwo_template (void) +static void +Opcode_blti_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00230700 }; - return &template[0]; + slotbuf[0] = 0x6a0000; } -static xtensa_insnbuf -dsync_template (void) +static void +Opcode_bbci_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00030200 }; - return &template[0]; + slotbuf[0] = 0x700600; } -static xtensa_insnbuf -entry_template (void) +static void +Opcode_bbsi_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006c0000 }; - return &template[0]; + slotbuf[0] = 0x700e00; } -static xtensa_insnbuf -esync_template (void) +static void +Opcode_bgeui_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00020200 }; - return &template[0]; + slotbuf[0] = 0x6f0000; } -static xtensa_insnbuf -excw_template (void) +static void +Opcode_bltui_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00080200 }; - return &template[0]; + slotbuf[0] = 0x6e0000; } -static xtensa_insnbuf -extui_template (void) +static void +Opcode_beq_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000040 }; - return &template[0]; + slotbuf[0] = 0x700100; } -static xtensa_insnbuf -idtlb_template (void) +static void +Opcode_bne_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000c05 }; - return &template[0]; + slotbuf[0] = 0x700900; } -static xtensa_insnbuf -idtlba_template (void) +static void +Opcode_bge_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000805 }; - return &template[0]; + slotbuf[0] = 0x700a00; } -static xtensa_insnbuf -ihi_template (void) +static void +Opcode_blt_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x002e0700 }; - return &template[0]; + slotbuf[0] = 0x700200; } -static xtensa_insnbuf -iii_template (void) +static void +Opcode_bgeu_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x002f0700 }; - return &template[0]; + slotbuf[0] = 0x700b00; } -static xtensa_insnbuf -iitlb_template (void) +static void +Opcode_bltu_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000405 }; - return &template[0]; + slotbuf[0] = 0x700300; } -static xtensa_insnbuf -iitlba_template (void) +static void +Opcode_bany_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000005 }; - return &template[0]; + slotbuf[0] = 0x700800; } -static xtensa_insnbuf -ipf_template (void) +static void +Opcode_bnone_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x002c0700 }; - return &template[0]; + slotbuf[0] = 0x700000; } -static xtensa_insnbuf -isync_template (void) +static void +Opcode_ball_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000200 }; - return &template[0]; + slotbuf[0] = 0x700400; } -static xtensa_insnbuf -j_template (void) +static void +Opcode_bnall_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00600000 }; - return &template[0]; + slotbuf[0] = 0x700c00; } -static xtensa_insnbuf -jx_template (void) +static void +Opcode_bbc_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x000a0000 }; - return &template[0]; + slotbuf[0] = 0x700500; } -static xtensa_insnbuf -l16si_template (void) +static void +Opcode_bbs_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200900 }; - return &template[0]; + slotbuf[0] = 0x700d00; } -static xtensa_insnbuf -l16ui_template (void) +static void +Opcode_beqz_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200100 }; - return &template[0]; + slotbuf[0] = 0x640000; } -static xtensa_insnbuf -l32e_template (void) +static void +Opcode_bnez_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000090 }; - return &template[0]; + slotbuf[0] = 0x650000; } -static xtensa_insnbuf -l32i_template (void) +static void +Opcode_bgez_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200200 }; - return &template[0]; + slotbuf[0] = 0x670000; } -static xtensa_insnbuf -l32i_n_template (void) +static void +Opcode_bltz_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00800000 }; - return &template[0]; + slotbuf[0] = 0x660000; } -static xtensa_insnbuf -l32r_template (void) +static void +Opcode_call0_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00100000 }; - return &template[0]; + slotbuf[0] = 0x500000; } -static xtensa_insnbuf -l8ui_template (void) +static void +Opcode_callx0_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200000 }; - return &template[0]; + slotbuf[0] = 0x30000; } -static xtensa_insnbuf -ldct_template (void) +static void +Opcode_extui_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000081f }; - return &template[0]; + slotbuf[0] = 0x40; } -static xtensa_insnbuf -lict_template (void) +static void +Opcode_ill_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000001f }; - return &template[0]; + slotbuf[0] = 0; } -static xtensa_insnbuf -licw_template (void) +static void +Opcode_j_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000021f }; - return &template[0]; + slotbuf[0] = 0x600000; } -static xtensa_insnbuf -loop_template (void) +static void +Opcode_jx_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006d0800 }; - return &template[0]; + slotbuf[0] = 0xa0000; } -static xtensa_insnbuf -loopgtz_template (void) +static void +Opcode_l16ui_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006d0a00 }; - return &template[0]; + slotbuf[0] = 0x200100; } -static xtensa_insnbuf -loopnez_template (void) +static void +Opcode_l16si_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x006d0900 }; - return &template[0]; + slotbuf[0] = 0x200900; } -static xtensa_insnbuf -memw_template (void) +static void +Opcode_l32i_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x000c0200 }; - return &template[0]; + slotbuf[0] = 0x200200; } -static xtensa_insnbuf -mov_n_template (void) +static void +Opcode_l32r_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00d00000 }; - return &template[0]; + slotbuf[0] = 0x100000; } -static xtensa_insnbuf -moveqz_template (void) +static void +Opcode_l8ui_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000038 }; - return &template[0]; + slotbuf[0] = 0x200000; } -static xtensa_insnbuf -movgez_template (void) +static void +Opcode_loop_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000003b }; - return &template[0]; + slotbuf[0] = 0x6d0800; } -static xtensa_insnbuf -movi_template (void) +static void +Opcode_loopnez_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200a00 }; - return &template[0]; + slotbuf[0] = 0x6d0900; } -static xtensa_insnbuf -movi_n_template (void) +static void +Opcode_loopgtz_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00c00000 }; - return &template[0]; + slotbuf[0] = 0x6d0a00; } -static xtensa_insnbuf -movltz_template (void) +static void +Opcode_movi_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000003a }; - return &template[0]; + slotbuf[0] = 0x200a00; } -static xtensa_insnbuf -movnez_template (void) +static void +Opcode_moveqz_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000039 }; - return &template[0]; + slotbuf[0] = 0x38; } -static xtensa_insnbuf -movsp_template (void) +static void +Opcode_movnez_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000100 }; - return &template[0]; + slotbuf[0] = 0x39; } -static xtensa_insnbuf -neg_template (void) +static void +Opcode_movltz_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000006 }; - return &template[0]; + slotbuf[0] = 0x3a; } -static xtensa_insnbuf -nop_n_template (void) +static void +Opcode_movgez_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00d30f00 }; - return &template[0]; + slotbuf[0] = 0x3b; } -static xtensa_insnbuf -nsa_template (void) +static void +Opcode_neg_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000e04 }; - return &template[0]; + slotbuf[0] = 0x6; } -static xtensa_insnbuf -nsau_template (void) +static void +Opcode_abs_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000f04 }; - return &template[0]; + slotbuf[0] = 0x1006; } -static xtensa_insnbuf -or_template (void) +static void +Opcode_nop_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000002 }; - return &template[0]; + slotbuf[0] = 0xf0200; } -static xtensa_insnbuf -pdtlb_template (void) +static void +Opcode_ret_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000d05 }; - return &template[0]; + slotbuf[0] = 0x20000; } -static xtensa_insnbuf -pitlb_template (void) +static void +Opcode_s16i_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000505 }; - return &template[0]; + slotbuf[0] = 0x200500; } -static xtensa_insnbuf -rdtlb0_template (void) +static void +Opcode_s32i_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000b05 }; - return &template[0]; + slotbuf[0] = 0x200600; } -static xtensa_insnbuf -rdtlb1_template (void) +static void +Opcode_s8i_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000f05 }; - return &template[0]; + slotbuf[0] = 0x200400; } -static xtensa_insnbuf -ret_template (void) +static void +Opcode_ssr_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00020000 }; - return &template[0]; + slotbuf[0] = 0x4; } -static xtensa_insnbuf -ret_n_template (void) +static void +Opcode_ssl_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00d00f00 }; - return &template[0]; + slotbuf[0] = 0x104; } -static xtensa_insnbuf -retw_template (void) +static void +Opcode_ssa8l_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00060000 }; - return &template[0]; + slotbuf[0] = 0x204; } -static xtensa_insnbuf -retw_n_template (void) +static void +Opcode_ssa8b_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00d10f00 }; - return &template[0]; + slotbuf[0] = 0x304; } -static xtensa_insnbuf -rfde_template (void) +static void +Opcode_ssai_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00002300 }; - return &template[0]; + slotbuf[0] = 0x404; } -static xtensa_insnbuf -rfe_template (void) +static void +Opcode_sll_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000300 }; - return &template[0]; + slotbuf[0] = 0x1a; } -static xtensa_insnbuf -rfi_template (void) +static void +Opcode_src_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00010300 }; - return &template[0]; + slotbuf[0] = 0x18; } -static xtensa_insnbuf -rfwo_template (void) +static void +Opcode_srl_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00004300 }; - return &template[0]; + slotbuf[0] = 0x19; } -static xtensa_insnbuf -rfwu_template (void) +static void +Opcode_sra_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00005300 }; - return &template[0]; + slotbuf[0] = 0x1b; } -static xtensa_insnbuf -ritlb0_template (void) +static void +Opcode_slli_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000305 }; - return &template[0]; + slotbuf[0] = 0x10; } -static xtensa_insnbuf -ritlb1_template (void) +static void +Opcode_srai_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000705 }; - return &template[0]; + slotbuf[0] = 0x12; } -static xtensa_insnbuf -rotw_template (void) +static void +Opcode_srli_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000804 }; - return &template[0]; + slotbuf[0] = 0x14; } -static xtensa_insnbuf -rsil_template (void) +static void +Opcode_memw_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000600 }; - return &template[0]; + slotbuf[0] = 0xc0200; } -static xtensa_insnbuf -rsr_template (void) +static void +Opcode_extw_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000030 }; - return &template[0]; + slotbuf[0] = 0xd0200; } -static xtensa_insnbuf -rsync_template (void) +static void +Opcode_isync_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00010200 }; - return &template[0]; + slotbuf[0] = 0x200; } -static xtensa_insnbuf -s16i_template (void) +static void +Opcode_rsync_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200500 }; - return &template[0]; + slotbuf[0] = 0x10200; } -static xtensa_insnbuf -s32e_template (void) +static void +Opcode_esync_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000094 }; - return &template[0]; + slotbuf[0] = 0x20200; } -static xtensa_insnbuf -s32i_template (void) +static void +Opcode_dsync_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200600 }; - return &template[0]; + slotbuf[0] = 0x30200; } -static xtensa_insnbuf -s32i_n_template (void) +static void +Opcode_rsil_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00900000 }; - return &template[0]; + slotbuf[0] = 0x600; } -static xtensa_insnbuf -s8i_template (void) +static void +Opcode_rsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00200400 }; - return &template[0]; + slotbuf[0] = 0x130; } -static xtensa_insnbuf -sdct_template (void) +static void +Opcode_wsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000091f }; - return &template[0]; + slotbuf[0] = 0x131; } -static xtensa_insnbuf -sict_template (void) +static void +Opcode_xsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000011f }; - return &template[0]; + slotbuf[0] = 0x116; } -static xtensa_insnbuf -sicw_template (void) +static void +Opcode_rsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000031f }; - return &template[0]; + slotbuf[0] = 0x230; } -static xtensa_insnbuf -simcall_template (void) +static void +Opcode_wsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00001500 }; - return &template[0]; + slotbuf[0] = 0x231; } -static xtensa_insnbuf -sll_template (void) +static void +Opcode_xsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000001a }; - return &template[0]; + slotbuf[0] = 0x216; } -static xtensa_insnbuf -slli_template (void) +static void +Opcode_rsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000010 }; - return &template[0]; + slotbuf[0] = 0x30; } -static xtensa_insnbuf -sra_template (void) +static void +Opcode_wsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000001b }; - return &template[0]; + slotbuf[0] = 0x31; } -static xtensa_insnbuf -srai_template (void) +static void +Opcode_xsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000012 }; - return &template[0]; + slotbuf[0] = 0x16; } -static xtensa_insnbuf -src_template (void) +static void +Opcode_rsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000018 }; - return &template[0]; + slotbuf[0] = 0x330; } -static xtensa_insnbuf -srl_template (void) +static void +Opcode_wsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000019 }; - return &template[0]; + slotbuf[0] = 0x331; } -static xtensa_insnbuf -srli_template (void) +static void +Opcode_xsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000014 }; - return &template[0]; + slotbuf[0] = 0x316; } -static xtensa_insnbuf -ssa8b_template (void) +static void +Opcode_rsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000304 }; - return &template[0]; + slotbuf[0] = 0x530; } -static xtensa_insnbuf -ssa8l_template (void) +static void +Opcode_wsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000204 }; - return &template[0]; + slotbuf[0] = 0x531; } -static xtensa_insnbuf -ssai_template (void) +static void +Opcode_xsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000404 }; - return &template[0]; + slotbuf[0] = 0x516; } -static xtensa_insnbuf -ssl_template (void) +static void +Opcode_rsr_176_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000104 }; - return &template[0]; + slotbuf[0] = 0xb030; } -static xtensa_insnbuf -ssr_template (void) +static void +Opcode_rsr_208_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000004 }; - return &template[0]; + slotbuf[0] = 0xd030; } -static xtensa_insnbuf -sub_template (void) +static void +Opcode_rsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000c }; - return &template[0]; + slotbuf[0] = 0xe630; } -static xtensa_insnbuf -subx2_template (void) +static void +Opcode_wsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000d }; - return &template[0]; + slotbuf[0] = 0xe631; } -static xtensa_insnbuf -subx4_template (void) +static void +Opcode_xsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000e }; - return &template[0]; + slotbuf[0] = 0xe616; } -static xtensa_insnbuf -subx8_template (void) +static void +Opcode_rsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x0000000f }; - return &template[0]; + slotbuf[0] = 0xb130; } -static xtensa_insnbuf -syscall_template (void) +static void +Opcode_wsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000500 }; - return &template[0]; + slotbuf[0] = 0xb131; } -static xtensa_insnbuf -waiti_template (void) +static void +Opcode_xsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000700 }; - return &template[0]; + slotbuf[0] = 0xb116; } -static xtensa_insnbuf -wdtlb_template (void) +static void +Opcode_rsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000e05 }; - return &template[0]; + slotbuf[0] = 0xd130; } -static xtensa_insnbuf -witlb_template (void) +static void +Opcode_wsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000605 }; - return &template[0]; + slotbuf[0] = 0xd131; } -static xtensa_insnbuf -wsr_template (void) +static void +Opcode_xsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000031 }; - return &template[0]; + slotbuf[0] = 0xd116; } -static xtensa_insnbuf -xor_template (void) +static void +Opcode_rsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000003 }; - return &template[0]; + slotbuf[0] = 0xb230; } -static xtensa_insnbuf -xsr_template (void) +static void +Opcode_wsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf) { - static xtensa_insnbuf_word template[] = { 0x00000016 }; - return &template[0]; + slotbuf[0] = 0xb231; } -static xtensa_opcode_internal abs_opcode = { - "abs", - 3, - abs_template, - &neg_iclass +static void +Opcode_xsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb216; +} + +static void +Opcode_rsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd230; +} + +static void +Opcode_wsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd231; +} + +static void +Opcode_xsr_excsave2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd216; +} + +static void +Opcode_rsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb330; +} + +static void +Opcode_wsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb331; +} + +static void +Opcode_xsr_epc3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb316; +} + +static void +Opcode_rsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd330; +} + +static void +Opcode_wsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd331; +} + +static void +Opcode_xsr_excsave3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd316; +} + +static void +Opcode_rsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb430; +} + +static void +Opcode_wsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb431; +} + +static void +Opcode_xsr_epc4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb416; +} + +static void +Opcode_rsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd430; +} + +static void +Opcode_wsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd431; +} + +static void +Opcode_xsr_excsave4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd416; +} + +static void +Opcode_rsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc230; +} + +static void +Opcode_wsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc231; +} + +static void +Opcode_xsr_eps2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc216; +} + +static void +Opcode_rsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc330; +} + +static void +Opcode_wsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc331; +} + +static void +Opcode_xsr_eps3_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc316; +} + +static void +Opcode_rsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc430; +} + +static void +Opcode_wsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc431; +} + +static void +Opcode_xsr_eps4_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc416; +} + +static void +Opcode_rsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xee30; +} + +static void +Opcode_wsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xee31; +} + +static void +Opcode_xsr_excvaddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xee16; +} + +static void +Opcode_rsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc030; +} + +static void +Opcode_wsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc031; +} + +static void +Opcode_xsr_depc_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc016; +} + +static void +Opcode_rsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe830; +} + +static void +Opcode_wsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe831; +} + +static void +Opcode_xsr_exccause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe816; +} + +static void +Opcode_rsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf430; +} + +static void +Opcode_wsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf431; +} + +static void +Opcode_xsr_misc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf416; +} + +static void +Opcode_rsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf530; +} + +static void +Opcode_wsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf531; +} + +static void +Opcode_xsr_misc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf516; +} + +static void +Opcode_rsr_prid_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xeb30; +} + +static void +Opcode_rfi_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x10300; +} + +static void +Opcode_waiti_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x700; +} + +static void +Opcode_rsr_interrupt_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe230; +} + +static void +Opcode_wsr_intset_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe231; +} + +static void +Opcode_wsr_intclear_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe331; +} + +static void +Opcode_rsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe430; +} + +static void +Opcode_wsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe431; +} + +static void +Opcode_xsr_intenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe416; +} + +static void +Opcode_break_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x400; +} + +static void +Opcode_break_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd20f; +} + +static void +Opcode_rsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9030; +} + +static void +Opcode_wsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9031; +} + +static void +Opcode_xsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9016; +} + +static void +Opcode_rsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa030; +} + +static void +Opcode_wsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa031; +} + +static void +Opcode_xsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa016; +} + +static void +Opcode_rsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9130; +} + +static void +Opcode_wsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9131; +} + +static void +Opcode_xsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x9116; +} + +static void +Opcode_rsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa130; +} + +static void +Opcode_wsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa131; +} + +static void +Opcode_xsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xa116; +} + +static void +Opcode_rsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8030; +} + +static void +Opcode_wsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8031; +} + +static void +Opcode_xsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8016; +} + +static void +Opcode_rsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8130; +} + +static void +Opcode_wsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8131; +} + +static void +Opcode_xsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x8116; +} + +static void +Opcode_rsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6030; +} + +static void +Opcode_wsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6031; +} + +static void +Opcode_xsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6016; +} + +static void +Opcode_rsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe930; +} + +static void +Opcode_wsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe931; +} + +static void +Opcode_xsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe916; +} + +static void +Opcode_rsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xec30; +} + +static void +Opcode_wsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xec31; +} + +static void +Opcode_xsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xec16; +} + +static void +Opcode_rsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xed30; +} + +static void +Opcode_wsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xed31; +} + +static void +Opcode_xsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xed16; +} + +static void +Opcode_rsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6830; +} + +static void +Opcode_wsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6831; +} + +static void +Opcode_xsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x6816; +} + +static void +Opcode_rfdo_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe1f; +} + +static void +Opcode_rfdd_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x10e1f; +} + +static void +Opcode_rsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xea30; +} + +static void +Opcode_wsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xea31; +} + +static void +Opcode_xsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xea16; +} + +static void +Opcode_rsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf030; +} + +static void +Opcode_wsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf031; +} + +static void +Opcode_xsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf016; +} + +static void +Opcode_rsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf130; +} + +static void +Opcode_wsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf131; +} + +static void +Opcode_xsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf116; +} + +static void +Opcode_rsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf230; +} + +static void +Opcode_wsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf231; +} + +static void +Opcode_xsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf216; +} + +static void +Opcode_ipf_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x2c0700; +} + +static void +Opcode_ihi_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x2e0700; +} + +static void +Opcode_iii_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x2f0700; +} + +static void +Opcode_lict_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x1f; +} + +static void +Opcode_licw_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x21f; +} + +static void +Opcode_sict_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x11f; +} + +static void +Opcode_sicw_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x31f; +} + +static void +Opcode_dhwb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x240700; +} + +static void +Opcode_dhwbi_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x250700; +} + +static void +Opcode_diwb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x280740; +} + +static void +Opcode_diwbi_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x280750; +} + +static void +Opcode_dhi_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x260700; +} + +static void +Opcode_dii_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x270700; +} + +static void +Opcode_dpfr_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x200700; +} + +static void +Opcode_dpfw_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x210700; +} + +static void +Opcode_dpfro_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x220700; +} + +static void +Opcode_dpfwo_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x230700; +} + +static void +Opcode_sdct_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x91f; +} + +static void +Opcode_ldct_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x81f; +} + +static void +Opcode_idtlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xc05; +} + +static void +Opcode_pdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xd05; +} + +static void +Opcode_rdtlb0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xb05; +} + +static void +Opcode_rdtlb1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf05; +} + +static void +Opcode_wdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe05; +} + +static void +Opcode_iitlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x405; +} + +static void +Opcode_pitlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x505; +} + +static void +Opcode_ritlb0_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x305; +} + +static void +Opcode_ritlb1_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x705; +} + +static void +Opcode_witlb_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0x605; +} + +static void +Opcode_nsa_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xe04; +} + +static void +Opcode_nsau_Slot_inst_encode (xtensa_insnbuf slotbuf) +{ + slotbuf[0] = 0xf04; +} + +xtensa_opcode_encode_fn Opcode_excw_encode_fns[] = { + Opcode_excw_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal add_opcode = { - "add", - 3, - add_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_rfe_encode_fns[] = { + Opcode_rfe_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal add_n_opcode = { - "add.n", - 2, - add_n_template, - &add_n_iclass +xtensa_opcode_encode_fn Opcode_rfde_encode_fns[] = { + Opcode_rfde_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addi_opcode = { - "addi", - 3, - addi_template, - &addi_iclass +xtensa_opcode_encode_fn Opcode_syscall_encode_fns[] = { + Opcode_syscall_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addi_n_opcode = { - "addi.n", - 2, - addi_n_template, - &addi_n_iclass +xtensa_opcode_encode_fn Opcode_simcall_encode_fns[] = { + Opcode_simcall_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addmi_opcode = { - "addmi", - 3, - addmi_template, - &addmi_iclass +xtensa_opcode_encode_fn Opcode_call12_encode_fns[] = { + Opcode_call12_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addx2_opcode = { - "addx2", - 3, - addx2_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_call8_encode_fns[] = { + Opcode_call8_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addx4_opcode = { - "addx4", - 3, - addx4_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_call4_encode_fns[] = { + Opcode_call4_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal addx8_opcode = { - "addx8", - 3, - addx8_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_callx12_encode_fns[] = { + Opcode_callx12_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal and_opcode = { - "and", - 3, - and_template, - &bit_iclass +xtensa_opcode_encode_fn Opcode_callx8_encode_fns[] = { + Opcode_callx8_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ball_opcode = { - "ball", - 3, - ball_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_callx4_encode_fns[] = { + Opcode_callx4_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bany_opcode = { - "bany", - 3, - bany_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_entry_encode_fns[] = { + Opcode_entry_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bbc_opcode = { - "bbc", - 3, - bbc_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_movsp_encode_fns[] = { + Opcode_movsp_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bbci_opcode = { - "bbci", - 3, - bbci_template, - &bsi8b_iclass +xtensa_opcode_encode_fn Opcode_rotw_encode_fns[] = { + Opcode_rotw_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bbs_opcode = { - "bbs", - 3, - bbs_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_retw_encode_fns[] = { + Opcode_retw_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bbsi_opcode = { - "bbsi", - 3, - bbsi_template, - &bsi8b_iclass +xtensa_opcode_encode_fn Opcode_retw_n_encode_fns[] = { + 0, 0, Opcode_retw_n_Slot_inst16b_encode }; -static xtensa_opcode_internal beq_opcode = { - "beq", - 3, - beq_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_rfwo_encode_fns[] = { + Opcode_rfwo_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal beqi_opcode = { - "beqi", - 3, - beqi_template, - &bsi8_iclass +xtensa_opcode_encode_fn Opcode_rfwu_encode_fns[] = { + Opcode_rfwu_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal beqz_opcode = { - "beqz", - 3, - beqz_template, - &bsz12_iclass +xtensa_opcode_encode_fn Opcode_l32e_encode_fns[] = { + Opcode_l32e_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal beqz_n_opcode = { - "beqz.n", - 2, - beqz_n_template, - &bz6_iclass +xtensa_opcode_encode_fn Opcode_s32e_encode_fns[] = { + Opcode_s32e_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bge_opcode = { - "bge", - 3, - bge_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_rsr_windowbase_encode_fns[] = { + Opcode_rsr_windowbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bgei_opcode = { - "bgei", - 3, - bgei_template, - &bsi8_iclass +xtensa_opcode_encode_fn Opcode_wsr_windowbase_encode_fns[] = { + Opcode_wsr_windowbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bgeu_opcode = { - "bgeu", - 3, - bgeu_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_xsr_windowbase_encode_fns[] = { + Opcode_xsr_windowbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bgeui_opcode = { - "bgeui", - 3, - bgeui_template, - &bsi8u_iclass +xtensa_opcode_encode_fn Opcode_rsr_windowstart_encode_fns[] = { + Opcode_rsr_windowstart_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal bgez_opcode = { - "bgez", - 3, - bgez_template, - &bsz12_iclass +xtensa_opcode_encode_fn Opcode_wsr_windowstart_encode_fns[] = { + Opcode_wsr_windowstart_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal blt_opcode = { - "blt", - 3, - blt_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_xsr_windowstart_encode_fns[] = { + Opcode_xsr_windowstart_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal blti_opcode = { - "blti", - 3, - blti_template, - &bsi8_iclass +xtensa_opcode_encode_fn Opcode_add_n_encode_fns[] = { + 0, Opcode_add_n_Slot_inst16a_encode, 0 }; -static xtensa_opcode_internal bltu_opcode = { - "bltu", - 3, - bltu_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_addi_n_encode_fns[] = { + 0, Opcode_addi_n_Slot_inst16a_encode, 0 }; -static xtensa_opcode_internal bltui_opcode = { - "bltui", - 3, - bltui_template, - &bsi8u_iclass +xtensa_opcode_encode_fn Opcode_beqz_n_encode_fns[] = { + 0, 0, Opcode_beqz_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bltz_opcode = { - "bltz", - 3, - bltz_template, - &bsz12_iclass +xtensa_opcode_encode_fn Opcode_bnez_n_encode_fns[] = { + 0, 0, Opcode_bnez_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bnall_opcode = { - "bnall", - 3, - bnall_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_ill_n_encode_fns[] = { + 0, 0, Opcode_ill_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bne_opcode = { - "bne", - 3, - bne_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_l32i_n_encode_fns[] = { + 0, Opcode_l32i_n_Slot_inst16a_encode, 0 }; -static xtensa_opcode_internal bnei_opcode = { - "bnei", - 3, - bnei_template, - &bsi8_iclass +xtensa_opcode_encode_fn Opcode_mov_n_encode_fns[] = { + 0, 0, Opcode_mov_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bnez_opcode = { - "bnez", - 3, - bnez_template, - &bsz12_iclass +xtensa_opcode_encode_fn Opcode_movi_n_encode_fns[] = { + 0, 0, Opcode_movi_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bnez_n_opcode = { - "bnez.n", - 2, - bnez_n_template, - &bz6_iclass +xtensa_opcode_encode_fn Opcode_nop_n_encode_fns[] = { + 0, 0, Opcode_nop_n_Slot_inst16b_encode }; -static xtensa_opcode_internal bnone_opcode = { - "bnone", - 3, - bnone_template, - &bst8_iclass +xtensa_opcode_encode_fn Opcode_ret_n_encode_fns[] = { + 0, 0, Opcode_ret_n_Slot_inst16b_encode }; -static xtensa_opcode_internal break_opcode = { - "break", - 3, - break_template, - &break_iclass +xtensa_opcode_encode_fn Opcode_s32i_n_encode_fns[] = { + 0, Opcode_s32i_n_Slot_inst16a_encode, 0 }; -static xtensa_opcode_internal break_n_opcode = { - "break.n", - 2, - break_n_template, - &break_n_iclass +xtensa_opcode_encode_fn Opcode_addi_encode_fns[] = { + Opcode_addi_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal call0_opcode = { - "call0", - 3, - call0_template, - &call_iclass +xtensa_opcode_encode_fn Opcode_addmi_encode_fns[] = { + Opcode_addmi_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal call12_opcode = { - "call12", - 3, - call12_template, - &call12_iclass +xtensa_opcode_encode_fn Opcode_add_encode_fns[] = { + Opcode_add_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal call4_opcode = { - "call4", - 3, - call4_template, - &call4_iclass +xtensa_opcode_encode_fn Opcode_sub_encode_fns[] = { + Opcode_sub_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal call8_opcode = { - "call8", - 3, - call8_template, - &call8_iclass +xtensa_opcode_encode_fn Opcode_addx2_encode_fns[] = { + Opcode_addx2_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal callx0_opcode = { - "callx0", - 3, - callx0_template, - &callx_iclass +xtensa_opcode_encode_fn Opcode_addx4_encode_fns[] = { + Opcode_addx4_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal callx12_opcode = { - "callx12", - 3, - callx12_template, - &callx12_iclass +xtensa_opcode_encode_fn Opcode_addx8_encode_fns[] = { + Opcode_addx8_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal callx4_opcode = { - "callx4", - 3, - callx4_template, - &callx4_iclass +xtensa_opcode_encode_fn Opcode_subx2_encode_fns[] = { + Opcode_subx2_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal callx8_opcode = { - "callx8", - 3, - callx8_template, - &callx8_iclass +xtensa_opcode_encode_fn Opcode_subx4_encode_fns[] = { + Opcode_subx4_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dhi_opcode = { - "dhi", - 3, - dhi_template, - &dcache_iclass +xtensa_opcode_encode_fn Opcode_subx8_encode_fns[] = { + Opcode_subx8_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dhwb_opcode = { - "dhwb", - 3, - dhwb_template, - &dcache_iclass +xtensa_opcode_encode_fn Opcode_and_encode_fns[] = { + Opcode_and_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dhwbi_opcode = { - "dhwbi", - 3, - dhwbi_template, - &dcache_iclass +xtensa_opcode_encode_fn Opcode_or_encode_fns[] = { + Opcode_or_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dii_opcode = { - "dii", - 3, - dii_template, - &dcache_iclass +xtensa_opcode_encode_fn Opcode_xor_encode_fns[] = { + Opcode_xor_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal diwb_opcode = { - "diwb", - 3, - diwb_template, - &dce_iclass +xtensa_opcode_encode_fn Opcode_beqi_encode_fns[] = { + Opcode_beqi_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal diwbi_opcode = { - "diwbi", - 3, - diwbi_template, - &dce_iclass +xtensa_opcode_encode_fn Opcode_bnei_encode_fns[] = { + Opcode_bnei_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dpfr_opcode = { - "dpfr", - 3, - dpfr_template, - &dpf_iclass +xtensa_opcode_encode_fn Opcode_bgei_encode_fns[] = { + Opcode_bgei_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dpfro_opcode = { - "dpfro", - 3, - dpfro_template, - &dpf_iclass +xtensa_opcode_encode_fn Opcode_blti_encode_fns[] = { + Opcode_blti_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dpfw_opcode = { - "dpfw", - 3, - dpfw_template, - &dpf_iclass +xtensa_opcode_encode_fn Opcode_bbci_encode_fns[] = { + Opcode_bbci_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dpfwo_opcode = { - "dpfwo", - 3, - dpfwo_template, - &dpf_iclass +xtensa_opcode_encode_fn Opcode_bbsi_encode_fns[] = { + Opcode_bbsi_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal dsync_opcode = { - "dsync", - 3, - dsync_template, - &sync_iclass +xtensa_opcode_encode_fn Opcode_bgeui_encode_fns[] = { + Opcode_bgeui_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal entry_opcode = { - "entry", - 3, - entry_template, - &entry_iclass +xtensa_opcode_encode_fn Opcode_bltui_encode_fns[] = { + Opcode_bltui_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal esync_opcode = { - "esync", - 3, - esync_template, - &sync_iclass +xtensa_opcode_encode_fn Opcode_beq_encode_fns[] = { + Opcode_beq_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal excw_opcode = { - "excw", - 3, - excw_template, - &excw_iclass +xtensa_opcode_encode_fn Opcode_bne_encode_fns[] = { + Opcode_bne_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal extui_opcode = { - "extui", - 3, - extui_template, - &exti_iclass +xtensa_opcode_encode_fn Opcode_bge_encode_fns[] = { + Opcode_bge_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal idtlb_opcode = { - "idtlb", - 3, - idtlb_template, - &itlb_iclass +xtensa_opcode_encode_fn Opcode_blt_encode_fns[] = { + Opcode_blt_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal idtlba_opcode = { - "idtlba", - 3, - idtlba_template, - &itlba_iclass +xtensa_opcode_encode_fn Opcode_bgeu_encode_fns[] = { + Opcode_bgeu_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ihi_opcode = { - "ihi", - 3, - ihi_template, - &icache_iclass +xtensa_opcode_encode_fn Opcode_bltu_encode_fns[] = { + Opcode_bltu_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal iii_opcode = { - "iii", - 3, - iii_template, - &icache_iclass +xtensa_opcode_encode_fn Opcode_bany_encode_fns[] = { + Opcode_bany_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal iitlb_opcode = { - "iitlb", - 3, - iitlb_template, - &itlb_iclass +xtensa_opcode_encode_fn Opcode_bnone_encode_fns[] = { + Opcode_bnone_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal iitlba_opcode = { - "iitlba", - 3, - iitlba_template, - &itlba_iclass +xtensa_opcode_encode_fn Opcode_ball_encode_fns[] = { + Opcode_ball_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ipf_opcode = { - "ipf", - 3, - ipf_template, - &icache_iclass +xtensa_opcode_encode_fn Opcode_bnall_encode_fns[] = { + Opcode_bnall_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal isync_opcode = { - "isync", - 3, - isync_template, - &sync_iclass +xtensa_opcode_encode_fn Opcode_bbc_encode_fns[] = { + Opcode_bbc_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal j_opcode = { - "j", - 3, - j_template, - &jump_iclass +xtensa_opcode_encode_fn Opcode_bbs_encode_fns[] = { + Opcode_bbs_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal jx_opcode = { - "jx", - 3, - jx_template, - &jumpx_iclass +xtensa_opcode_encode_fn Opcode_beqz_encode_fns[] = { + Opcode_beqz_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l16si_opcode = { - "l16si", - 3, - l16si_template, - &l16i_iclass +xtensa_opcode_encode_fn Opcode_bnez_encode_fns[] = { + Opcode_bnez_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l16ui_opcode = { - "l16ui", - 3, - l16ui_template, - &l16i_iclass +xtensa_opcode_encode_fn Opcode_bgez_encode_fns[] = { + Opcode_bgez_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l32e_opcode = { - "l32e", - 3, - l32e_template, - &l32e_iclass +xtensa_opcode_encode_fn Opcode_bltz_encode_fns[] = { + Opcode_bltz_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l32i_opcode = { - "l32i", - 3, - l32i_template, - &l32i_iclass +xtensa_opcode_encode_fn Opcode_call0_encode_fns[] = { + Opcode_call0_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l32i_n_opcode = { - "l32i.n", - 2, - l32i_n_template, - &loadi4_iclass +xtensa_opcode_encode_fn Opcode_callx0_encode_fns[] = { + Opcode_callx0_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l32r_opcode = { - "l32r", - 3, - l32r_template, - &l32r_iclass +xtensa_opcode_encode_fn Opcode_extui_encode_fns[] = { + Opcode_extui_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal l8ui_opcode = { - "l8ui", - 3, - l8ui_template, - &l8i_iclass +xtensa_opcode_encode_fn Opcode_ill_encode_fns[] = { + Opcode_ill_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ldct_opcode = { - "ldct", - 3, - ldct_template, - &actl_iclass +xtensa_opcode_encode_fn Opcode_j_encode_fns[] = { + Opcode_j_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal lict_opcode = { - "lict", - 3, - lict_template, - &actl_iclass +xtensa_opcode_encode_fn Opcode_jx_encode_fns[] = { + Opcode_jx_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal licw_opcode = { - "licw", - 3, - licw_template, - &actl_iclass +xtensa_opcode_encode_fn Opcode_l16ui_encode_fns[] = { + Opcode_l16ui_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal loop_opcode = { - "loop", - 3, - loop_template, - &loop_iclass +xtensa_opcode_encode_fn Opcode_l16si_encode_fns[] = { + Opcode_l16si_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal loopgtz_opcode = { - "loopgtz", - 3, - loopgtz_template, - &loop_iclass +xtensa_opcode_encode_fn Opcode_l32i_encode_fns[] = { + Opcode_l32i_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal loopnez_opcode = { - "loopnez", - 3, - loopnez_template, - &loop_iclass +xtensa_opcode_encode_fn Opcode_l32r_encode_fns[] = { + Opcode_l32r_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal memw_opcode = { - "memw", - 3, - memw_template, - &sync_iclass +xtensa_opcode_encode_fn Opcode_l8ui_encode_fns[] = { + Opcode_l8ui_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal mov_n_opcode = { - "mov.n", - 2, - mov_n_template, - &mov_n_iclass +xtensa_opcode_encode_fn Opcode_loop_encode_fns[] = { + Opcode_loop_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal moveqz_opcode = { - "moveqz", - 3, - moveqz_template, - &movz_iclass +xtensa_opcode_encode_fn Opcode_loopnez_encode_fns[] = { + Opcode_loopnez_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movgez_opcode = { - "movgez", - 3, - movgez_template, - &movz_iclass +xtensa_opcode_encode_fn Opcode_loopgtz_encode_fns[] = { + Opcode_loopgtz_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movi_opcode = { - "movi", - 3, - movi_template, - &movi_iclass +xtensa_opcode_encode_fn Opcode_movi_encode_fns[] = { + Opcode_movi_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movi_n_opcode = { - "movi.n", - 2, - movi_n_template, - &movi_n_iclass +xtensa_opcode_encode_fn Opcode_moveqz_encode_fns[] = { + Opcode_moveqz_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movltz_opcode = { - "movltz", - 3, - movltz_template, - &movz_iclass +xtensa_opcode_encode_fn Opcode_movnez_encode_fns[] = { + Opcode_movnez_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movnez_opcode = { - "movnez", - 3, - movnez_template, - &movz_iclass +xtensa_opcode_encode_fn Opcode_movltz_encode_fns[] = { + Opcode_movltz_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal movsp_opcode = { - "movsp", - 3, - movsp_template, - &movsp_iclass +xtensa_opcode_encode_fn Opcode_movgez_encode_fns[] = { + Opcode_movgez_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal neg_opcode = { - "neg", - 3, - neg_template, - &neg_iclass +xtensa_opcode_encode_fn Opcode_neg_encode_fns[] = { + Opcode_neg_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal nop_n_opcode = { - "nop.n", - 2, - nop_n_template, - &nopn_iclass +xtensa_opcode_encode_fn Opcode_abs_encode_fns[] = { + Opcode_abs_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal nsa_opcode = { - "nsa", - 3, - nsa_template, - &nsa_iclass +xtensa_opcode_encode_fn Opcode_nop_encode_fns[] = { + Opcode_nop_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal nsau_opcode = { - "nsau", - 3, - nsau_template, - &nsa_iclass +xtensa_opcode_encode_fn Opcode_ret_encode_fns[] = { + Opcode_ret_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal or_opcode = { - "or", - 3, - or_template, - &bit_iclass +xtensa_opcode_encode_fn Opcode_s16i_encode_fns[] = { + Opcode_s16i_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal pdtlb_opcode = { - "pdtlb", - 3, - pdtlb_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_s32i_encode_fns[] = { + Opcode_s32i_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal pitlb_opcode = { - "pitlb", - 3, - pitlb_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_s8i_encode_fns[] = { + Opcode_s8i_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rdtlb0_opcode = { - "rdtlb0", - 3, - rdtlb0_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_ssr_encode_fns[] = { + Opcode_ssr_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rdtlb1_opcode = { - "rdtlb1", - 3, - rdtlb1_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_ssl_encode_fns[] = { + Opcode_ssl_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ret_opcode = { - "ret", - 3, - ret_template, - &return_iclass +xtensa_opcode_encode_fn Opcode_ssa8l_encode_fns[] = { + Opcode_ssa8l_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ret_n_opcode = { - "ret.n", - 2, - ret_n_template, - &retn_iclass +xtensa_opcode_encode_fn Opcode_ssa8b_encode_fns[] = { + Opcode_ssa8b_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal retw_opcode = { - "retw", - 3, - retw_template, - &return_iclass +xtensa_opcode_encode_fn Opcode_ssai_encode_fns[] = { + Opcode_ssai_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal retw_n_opcode = { - "retw.n", - 2, - retw_n_template, - &retn_iclass +xtensa_opcode_encode_fn Opcode_sll_encode_fns[] = { + Opcode_sll_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rfde_opcode = { - "rfde", - 3, - rfde_template, - &rfe_iclass +xtensa_opcode_encode_fn Opcode_src_encode_fns[] = { + Opcode_src_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rfe_opcode = { - "rfe", - 3, - rfe_template, - &rfe_iclass +xtensa_opcode_encode_fn Opcode_srl_encode_fns[] = { + Opcode_srl_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rfi_opcode = { - "rfi", - 3, - rfi_template, - &rfi_iclass +xtensa_opcode_encode_fn Opcode_sra_encode_fns[] = { + Opcode_sra_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rfwo_opcode = { - "rfwo", - 3, - rfwo_template, - &rfe_iclass +xtensa_opcode_encode_fn Opcode_slli_encode_fns[] = { + Opcode_slli_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rfwu_opcode = { - "rfwu", - 3, - rfwu_template, - &rfe_iclass +xtensa_opcode_encode_fn Opcode_srai_encode_fns[] = { + Opcode_srai_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ritlb0_opcode = { - "ritlb0", - 3, - ritlb0_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_srli_encode_fns[] = { + Opcode_srli_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ritlb1_opcode = { - "ritlb1", - 3, - ritlb1_template, - &rtlb_iclass +xtensa_opcode_encode_fn Opcode_memw_encode_fns[] = { + Opcode_memw_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rotw_opcode = { - "rotw", - 3, - rotw_template, - &rotw_iclass +xtensa_opcode_encode_fn Opcode_extw_encode_fns[] = { + Opcode_extw_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rsil_opcode = { - "rsil", - 3, - rsil_template, - &rsil_iclass +xtensa_opcode_encode_fn Opcode_isync_encode_fns[] = { + Opcode_isync_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rsr_opcode = { - "rsr", - 3, - rsr_template, - &rsr_iclass +xtensa_opcode_encode_fn Opcode_rsync_encode_fns[] = { + Opcode_rsync_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal rsync_opcode = { - "rsync", - 3, - rsync_template, - &sync_iclass +xtensa_opcode_encode_fn Opcode_esync_encode_fns[] = { + Opcode_esync_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal s16i_opcode = { - "s16i", - 3, - s16i_template, - &s16i_iclass +xtensa_opcode_encode_fn Opcode_dsync_encode_fns[] = { + Opcode_dsync_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal s32e_opcode = { - "s32e", - 3, - s32e_template, - &s32e_iclass +xtensa_opcode_encode_fn Opcode_rsil_encode_fns[] = { + Opcode_rsil_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal s32i_opcode = { - "s32i", - 3, - s32i_template, - &s32i_iclass +xtensa_opcode_encode_fn Opcode_rsr_lend_encode_fns[] = { + Opcode_rsr_lend_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal s32i_n_opcode = { - "s32i.n", - 2, - s32i_n_template, - &storei4_iclass +xtensa_opcode_encode_fn Opcode_wsr_lend_encode_fns[] = { + Opcode_wsr_lend_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal s8i_opcode = { - "s8i", - 3, - s8i_template, - &s8i_iclass +xtensa_opcode_encode_fn Opcode_xsr_lend_encode_fns[] = { + Opcode_xsr_lend_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sdct_opcode = { - "sdct", - 3, - sdct_template, - &acts_iclass +xtensa_opcode_encode_fn Opcode_rsr_lcount_encode_fns[] = { + Opcode_rsr_lcount_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sict_opcode = { - "sict", - 3, - sict_template, - &acts_iclass +xtensa_opcode_encode_fn Opcode_wsr_lcount_encode_fns[] = { + Opcode_wsr_lcount_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sicw_opcode = { - "sicw", - 3, - sicw_template, - &acts_iclass +xtensa_opcode_encode_fn Opcode_xsr_lcount_encode_fns[] = { + Opcode_xsr_lcount_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal simcall_opcode = { - "simcall", - 3, - simcall_template, - &syscall_iclass +xtensa_opcode_encode_fn Opcode_rsr_lbeg_encode_fns[] = { + Opcode_rsr_lbeg_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sll_opcode = { - "sll", - 3, - sll_template, - &shifts_iclass +xtensa_opcode_encode_fn Opcode_wsr_lbeg_encode_fns[] = { + Opcode_wsr_lbeg_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal slli_opcode = { - "slli", - 3, - slli_template, - &slli_iclass +xtensa_opcode_encode_fn Opcode_xsr_lbeg_encode_fns[] = { + Opcode_xsr_lbeg_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sra_opcode = { - "sra", - 3, - sra_template, - &shiftt_iclass +xtensa_opcode_encode_fn Opcode_rsr_sar_encode_fns[] = { + Opcode_rsr_sar_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal srai_opcode = { - "srai", - 3, - srai_template, - &srai_iclass +xtensa_opcode_encode_fn Opcode_wsr_sar_encode_fns[] = { + Opcode_wsr_sar_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal src_opcode = { - "src", - 3, - src_template, - &shiftst_iclass +xtensa_opcode_encode_fn Opcode_xsr_sar_encode_fns[] = { + Opcode_xsr_sar_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal srl_opcode = { - "srl", - 3, - srl_template, - &shiftt_iclass +xtensa_opcode_encode_fn Opcode_rsr_litbase_encode_fns[] = { + Opcode_rsr_litbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal srli_opcode = { - "srli", - 3, - srli_template, - &srli_iclass +xtensa_opcode_encode_fn Opcode_wsr_litbase_encode_fns[] = { + Opcode_wsr_litbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ssa8b_opcode = { - "ssa8b", - 3, - ssa8b_template, - &sar_iclass +xtensa_opcode_encode_fn Opcode_xsr_litbase_encode_fns[] = { + Opcode_xsr_litbase_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ssa8l_opcode = { - "ssa8l", - 3, - ssa8l_template, - &sar_iclass +xtensa_opcode_encode_fn Opcode_rsr_176_encode_fns[] = { + Opcode_rsr_176_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ssai_opcode = { - "ssai", - 3, - ssai_template, - &sari_iclass +xtensa_opcode_encode_fn Opcode_rsr_208_encode_fns[] = { + Opcode_rsr_208_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ssl_opcode = { - "ssl", - 3, - ssl_template, - &sar_iclass +xtensa_opcode_encode_fn Opcode_rsr_ps_encode_fns[] = { + Opcode_rsr_ps_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal ssr_opcode = { - "ssr", - 3, - ssr_template, - &sar_iclass +xtensa_opcode_encode_fn Opcode_wsr_ps_encode_fns[] = { + Opcode_wsr_ps_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal sub_opcode = { - "sub", - 3, - sub_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_xsr_ps_encode_fns[] = { + Opcode_xsr_ps_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal subx2_opcode = { - "subx2", - 3, - subx2_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_rsr_epc1_encode_fns[] = { + Opcode_rsr_epc1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal subx4_opcode = { - "subx4", - 3, - subx4_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_wsr_epc1_encode_fns[] = { + Opcode_wsr_epc1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal subx8_opcode = { - "subx8", - 3, - subx8_template, - &addsub_iclass +xtensa_opcode_encode_fn Opcode_xsr_epc1_encode_fns[] = { + Opcode_xsr_epc1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal syscall_opcode = { - "syscall", - 3, - syscall_template, - &syscall_iclass +xtensa_opcode_encode_fn Opcode_rsr_excsave1_encode_fns[] = { + Opcode_rsr_excsave1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal waiti_opcode = { - "waiti", - 3, - waiti_template, - &wait_iclass +xtensa_opcode_encode_fn Opcode_wsr_excsave1_encode_fns[] = { + Opcode_wsr_excsave1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal wdtlb_opcode = { - "wdtlb", - 3, - wdtlb_template, - &wtlb_iclass +xtensa_opcode_encode_fn Opcode_xsr_excsave1_encode_fns[] = { + Opcode_xsr_excsave1_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal witlb_opcode = { - "witlb", - 3, - witlb_template, - &wtlb_iclass +xtensa_opcode_encode_fn Opcode_rsr_epc2_encode_fns[] = { + Opcode_rsr_epc2_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal wsr_opcode = { - "wsr", - 3, - wsr_template, - &wsr_iclass +xtensa_opcode_encode_fn Opcode_wsr_epc2_encode_fns[] = { + Opcode_wsr_epc2_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal xor_opcode = { - "xor", - 3, - xor_template, - &bit_iclass +xtensa_opcode_encode_fn Opcode_xsr_epc2_encode_fns[] = { + Opcode_xsr_epc2_Slot_inst_encode, 0, 0 }; -static xtensa_opcode_internal xsr_opcode = { - "xsr", - 3, - xsr_template, - &xsr_iclass -}; - -static xtensa_opcode_internal * opcodes[149] = { - &abs_opcode, - &add_opcode, - &add_n_opcode, - &addi_opcode, - &addi_n_opcode, - &addmi_opcode, - &addx2_opcode, - &addx4_opcode, - &addx8_opcode, - &and_opcode, - &ball_opcode, - &bany_opcode, - &bbc_opcode, - &bbci_opcode, - &bbs_opcode, - &bbsi_opcode, - &beq_opcode, - &beqi_opcode, - &beqz_opcode, - &beqz_n_opcode, - &bge_opcode, - &bgei_opcode, - &bgeu_opcode, - &bgeui_opcode, - &bgez_opcode, - &blt_opcode, - &blti_opcode, - &bltu_opcode, - &bltui_opcode, - &bltz_opcode, - &bnall_opcode, - &bne_opcode, - &bnei_opcode, - &bnez_opcode, - &bnez_n_opcode, - &bnone_opcode, - &break_opcode, - &break_n_opcode, - &call0_opcode, - &call12_opcode, - &call4_opcode, - &call8_opcode, - &callx0_opcode, - &callx12_opcode, - &callx4_opcode, - &callx8_opcode, - &dhi_opcode, - &dhwb_opcode, - &dhwbi_opcode, - &dii_opcode, - &diwb_opcode, - &diwbi_opcode, - &dpfr_opcode, - &dpfro_opcode, - &dpfw_opcode, - &dpfwo_opcode, - &dsync_opcode, - &entry_opcode, - &esync_opcode, - &excw_opcode, - &extui_opcode, - &idtlb_opcode, - &idtlba_opcode, - &ihi_opcode, - &iii_opcode, - &iitlb_opcode, - &iitlba_opcode, - &ipf_opcode, - &isync_opcode, - &j_opcode, - &jx_opcode, - &l16si_opcode, - &l16ui_opcode, - &l32e_opcode, - &l32i_opcode, - &l32i_n_opcode, - &l32r_opcode, - &l8ui_opcode, - &ldct_opcode, - &lict_opcode, - &licw_opcode, - &loop_opcode, - &loopgtz_opcode, - &loopnez_opcode, - &memw_opcode, - &mov_n_opcode, - &moveqz_opcode, - &movgez_opcode, - &movi_opcode, - &movi_n_opcode, - &movltz_opcode, - &movnez_opcode, - &movsp_opcode, - &neg_opcode, - &nop_n_opcode, - &nsa_opcode, - &nsau_opcode, - &or_opcode, - &pdtlb_opcode, - &pitlb_opcode, - &rdtlb0_opcode, - &rdtlb1_opcode, - &ret_opcode, - &ret_n_opcode, - &retw_opcode, - &retw_n_opcode, - &rfde_opcode, - &rfe_opcode, - &rfi_opcode, - &rfwo_opcode, - &rfwu_opcode, - &ritlb0_opcode, - &ritlb1_opcode, - &rotw_opcode, - &rsil_opcode, - &rsr_opcode, - &rsync_opcode, - &s16i_opcode, - &s32e_opcode, - &s32i_opcode, - &s32i_n_opcode, - &s8i_opcode, - &sdct_opcode, - &sict_opcode, - &sicw_opcode, - &simcall_opcode, - &sll_opcode, - &slli_opcode, - &sra_opcode, - &srai_opcode, - &src_opcode, - &srl_opcode, - &srli_opcode, - &ssa8b_opcode, - &ssa8l_opcode, - &ssai_opcode, - &ssl_opcode, - &ssr_opcode, - &sub_opcode, - &subx2_opcode, - &subx4_opcode, - &subx8_opcode, - &syscall_opcode, - &waiti_opcode, - &wdtlb_opcode, - &witlb_opcode, - &wsr_opcode, - &xor_opcode, - &xsr_opcode -}; - -xtensa_opcode_internal ** -get_opcodes (void) -{ - return &opcodes[0]; -} - -int -get_num_opcodes (void) -{ - return 149; -} - -#define xtensa_abs_op 0 -#define xtensa_add_op 1 -#define xtensa_add_n_op 2 -#define xtensa_addi_op 3 -#define xtensa_addi_n_op 4 -#define xtensa_addmi_op 5 -#define xtensa_addx2_op 6 -#define xtensa_addx4_op 7 -#define xtensa_addx8_op 8 -#define xtensa_and_op 9 -#define xtensa_ball_op 10 -#define xtensa_bany_op 11 -#define xtensa_bbc_op 12 -#define xtensa_bbci_op 13 -#define xtensa_bbs_op 14 -#define xtensa_bbsi_op 15 -#define xtensa_beq_op 16 -#define xtensa_beqi_op 17 -#define xtensa_beqz_op 18 -#define xtensa_beqz_n_op 19 -#define xtensa_bge_op 20 -#define xtensa_bgei_op 21 -#define xtensa_bgeu_op 22 -#define xtensa_bgeui_op 23 -#define xtensa_bgez_op 24 -#define xtensa_blt_op 25 -#define xtensa_blti_op 26 -#define xtensa_bltu_op 27 -#define xtensa_bltui_op 28 -#define xtensa_bltz_op 29 -#define xtensa_bnall_op 30 -#define xtensa_bne_op 31 -#define xtensa_bnei_op 32 -#define xtensa_bnez_op 33 -#define xtensa_bnez_n_op 34 -#define xtensa_bnone_op 35 -#define xtensa_break_op 36 -#define xtensa_break_n_op 37 -#define xtensa_call0_op 38 -#define xtensa_call12_op 39 -#define xtensa_call4_op 40 -#define xtensa_call8_op 41 -#define xtensa_callx0_op 42 -#define xtensa_callx12_op 43 -#define xtensa_callx4_op 44 -#define xtensa_callx8_op 45 -#define xtensa_dhi_op 46 -#define xtensa_dhwb_op 47 -#define xtensa_dhwbi_op 48 -#define xtensa_dii_op 49 -#define xtensa_diwb_op 50 -#define xtensa_diwbi_op 51 -#define xtensa_dpfr_op 52 -#define xtensa_dpfro_op 53 -#define xtensa_dpfw_op 54 -#define xtensa_dpfwo_op 55 -#define xtensa_dsync_op 56 -#define xtensa_entry_op 57 -#define xtensa_esync_op 58 -#define xtensa_excw_op 59 -#define xtensa_extui_op 60 -#define xtensa_idtlb_op 61 -#define xtensa_idtlba_op 62 -#define xtensa_ihi_op 63 -#define xtensa_iii_op 64 -#define xtensa_iitlb_op 65 -#define xtensa_iitlba_op 66 -#define xtensa_ipf_op 67 -#define xtensa_isync_op 68 -#define xtensa_j_op 69 -#define xtensa_jx_op 70 -#define xtensa_l16si_op 71 -#define xtensa_l16ui_op 72 -#define xtensa_l32e_op 73 -#define xtensa_l32i_op 74 -#define xtensa_l32i_n_op 75 -#define xtensa_l32r_op 76 -#define xtensa_l8ui_op 77 -#define xtensa_ldct_op 78 -#define xtensa_lict_op 79 -#define xtensa_licw_op 80 -#define xtensa_loop_op 81 -#define xtensa_loopgtz_op 82 -#define xtensa_loopnez_op 83 -#define xtensa_memw_op 84 -#define xtensa_mov_n_op 85 -#define xtensa_moveqz_op 86 -#define xtensa_movgez_op 87 -#define xtensa_movi_op 88 -#define xtensa_movi_n_op 89 -#define xtensa_movltz_op 90 -#define xtensa_movnez_op 91 -#define xtensa_movsp_op 92 -#define xtensa_neg_op 93 -#define xtensa_nop_n_op 94 -#define xtensa_nsa_op 95 -#define xtensa_nsau_op 96 -#define xtensa_or_op 97 -#define xtensa_pdtlb_op 98 -#define xtensa_pitlb_op 99 -#define xtensa_rdtlb0_op 100 -#define xtensa_rdtlb1_op 101 -#define xtensa_ret_op 102 -#define xtensa_ret_n_op 103 -#define xtensa_retw_op 104 -#define xtensa_retw_n_op 105 -#define xtensa_rfde_op 106 -#define xtensa_rfe_op 107 -#define xtensa_rfi_op 108 -#define xtensa_rfwo_op 109 -#define xtensa_rfwu_op 110 -#define xtensa_ritlb0_op 111 -#define xtensa_ritlb1_op 112 -#define xtensa_rotw_op 113 -#define xtensa_rsil_op 114 -#define xtensa_rsr_op 115 -#define xtensa_rsync_op 116 -#define xtensa_s16i_op 117 -#define xtensa_s32e_op 118 -#define xtensa_s32i_op 119 -#define xtensa_s32i_n_op 120 -#define xtensa_s8i_op 121 -#define xtensa_sdct_op 122 -#define xtensa_sict_op 123 -#define xtensa_sicw_op 124 -#define xtensa_simcall_op 125 -#define xtensa_sll_op 126 -#define xtensa_slli_op 127 -#define xtensa_sra_op 128 -#define xtensa_srai_op 129 -#define xtensa_src_op 130 -#define xtensa_srl_op 131 -#define xtensa_srli_op 132 -#define xtensa_ssa8b_op 133 -#define xtensa_ssa8l_op 134 -#define xtensa_ssai_op 135 -#define xtensa_ssl_op 136 -#define xtensa_ssr_op 137 -#define xtensa_sub_op 138 -#define xtensa_subx2_op 139 -#define xtensa_subx4_op 140 -#define xtensa_subx8_op 141 -#define xtensa_syscall_op 142 -#define xtensa_waiti_op 143 -#define xtensa_wdtlb_op 144 -#define xtensa_witlb_op 145 -#define xtensa_wsr_op 146 -#define xtensa_xor_op 147 -#define xtensa_xsr_op 148 - -int -decode_insn (const xtensa_insnbuf insn) -{ - switch (get_op0_field (insn)) { - case 0: /* QRST: op0=0000 */ - switch (get_op1_field (insn)) { - case 3: /* RST3: op1=0011 */ - switch (get_op2_field (insn)) { - case 8: /* MOVEQZ: op2=1000 */ - return xtensa_moveqz_op; - case 9: /* MOVNEZ: op2=1001 */ - return xtensa_movnez_op; - case 10: /* MOVLTZ: op2=1010 */ - return xtensa_movltz_op; - case 11: /* MOVGEZ: op2=1011 */ - return xtensa_movgez_op; - case 0: /* RSR: op2=0000 */ - return xtensa_rsr_op; - case 1: /* WSR: op2=0001 */ - return xtensa_wsr_op; - } +xtensa_opcode_encode_fn Opcode_rsr_excsave2_encode_fns[] = { + Opcode_rsr_excsave2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_excsave2_encode_fns[] = { + Opcode_wsr_excsave2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_excsave2_encode_fns[] = { + Opcode_xsr_excsave2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_epc3_encode_fns[] = { + Opcode_rsr_epc3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_epc3_encode_fns[] = { + Opcode_wsr_epc3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_epc3_encode_fns[] = { + Opcode_xsr_epc3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_excsave3_encode_fns[] = { + Opcode_rsr_excsave3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_excsave3_encode_fns[] = { + Opcode_wsr_excsave3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_excsave3_encode_fns[] = { + Opcode_xsr_excsave3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_epc4_encode_fns[] = { + Opcode_rsr_epc4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_epc4_encode_fns[] = { + Opcode_wsr_epc4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_epc4_encode_fns[] = { + Opcode_xsr_epc4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_excsave4_encode_fns[] = { + Opcode_rsr_excsave4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_excsave4_encode_fns[] = { + Opcode_wsr_excsave4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_excsave4_encode_fns[] = { + Opcode_xsr_excsave4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_eps2_encode_fns[] = { + Opcode_rsr_eps2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_eps2_encode_fns[] = { + Opcode_wsr_eps2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_eps2_encode_fns[] = { + Opcode_xsr_eps2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_eps3_encode_fns[] = { + Opcode_rsr_eps3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_eps3_encode_fns[] = { + Opcode_wsr_eps3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_eps3_encode_fns[] = { + Opcode_xsr_eps3_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_eps4_encode_fns[] = { + Opcode_rsr_eps4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_eps4_encode_fns[] = { + Opcode_wsr_eps4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_eps4_encode_fns[] = { + Opcode_xsr_eps4_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_excvaddr_encode_fns[] = { + Opcode_rsr_excvaddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_excvaddr_encode_fns[] = { + Opcode_wsr_excvaddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_excvaddr_encode_fns[] = { + Opcode_xsr_excvaddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_depc_encode_fns[] = { + Opcode_rsr_depc_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_depc_encode_fns[] = { + Opcode_wsr_depc_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_depc_encode_fns[] = { + Opcode_xsr_depc_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_exccause_encode_fns[] = { + Opcode_rsr_exccause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_exccause_encode_fns[] = { + Opcode_wsr_exccause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_exccause_encode_fns[] = { + Opcode_xsr_exccause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_misc0_encode_fns[] = { + Opcode_rsr_misc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_misc0_encode_fns[] = { + Opcode_wsr_misc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_misc0_encode_fns[] = { + Opcode_xsr_misc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_misc1_encode_fns[] = { + Opcode_rsr_misc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_misc1_encode_fns[] = { + Opcode_wsr_misc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_misc1_encode_fns[] = { + Opcode_xsr_misc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_prid_encode_fns[] = { + Opcode_rsr_prid_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rfi_encode_fns[] = { + Opcode_rfi_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_waiti_encode_fns[] = { + Opcode_waiti_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_interrupt_encode_fns[] = { + Opcode_rsr_interrupt_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_intset_encode_fns[] = { + Opcode_wsr_intset_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_intclear_encode_fns[] = { + Opcode_wsr_intclear_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_intenable_encode_fns[] = { + Opcode_rsr_intenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_intenable_encode_fns[] = { + Opcode_wsr_intenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_intenable_encode_fns[] = { + Opcode_xsr_intenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_break_encode_fns[] = { + Opcode_break_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_break_n_encode_fns[] = { + 0, 0, Opcode_break_n_Slot_inst16b_encode +}; + +xtensa_opcode_encode_fn Opcode_rsr_dbreaka0_encode_fns[] = { + Opcode_rsr_dbreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_dbreaka0_encode_fns[] = { + Opcode_wsr_dbreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_dbreaka0_encode_fns[] = { + Opcode_xsr_dbreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_dbreakc0_encode_fns[] = { + Opcode_rsr_dbreakc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_dbreakc0_encode_fns[] = { + Opcode_wsr_dbreakc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_dbreakc0_encode_fns[] = { + Opcode_xsr_dbreakc0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_dbreaka1_encode_fns[] = { + Opcode_rsr_dbreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_dbreaka1_encode_fns[] = { + Opcode_wsr_dbreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_dbreaka1_encode_fns[] = { + Opcode_xsr_dbreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_dbreakc1_encode_fns[] = { + Opcode_rsr_dbreakc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_dbreakc1_encode_fns[] = { + Opcode_wsr_dbreakc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_dbreakc1_encode_fns[] = { + Opcode_xsr_dbreakc1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ibreaka0_encode_fns[] = { + Opcode_rsr_ibreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ibreaka0_encode_fns[] = { + Opcode_wsr_ibreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ibreaka0_encode_fns[] = { + Opcode_xsr_ibreaka0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ibreaka1_encode_fns[] = { + Opcode_rsr_ibreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ibreaka1_encode_fns[] = { + Opcode_wsr_ibreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ibreaka1_encode_fns[] = { + Opcode_xsr_ibreaka1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ibreakenable_encode_fns[] = { + Opcode_rsr_ibreakenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ibreakenable_encode_fns[] = { + Opcode_wsr_ibreakenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ibreakenable_encode_fns[] = { + Opcode_xsr_ibreakenable_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_debugcause_encode_fns[] = { + Opcode_rsr_debugcause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_debugcause_encode_fns[] = { + Opcode_wsr_debugcause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_debugcause_encode_fns[] = { + Opcode_xsr_debugcause_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_icount_encode_fns[] = { + Opcode_rsr_icount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_icount_encode_fns[] = { + Opcode_wsr_icount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_icount_encode_fns[] = { + Opcode_xsr_icount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_icountlevel_encode_fns[] = { + Opcode_rsr_icountlevel_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_icountlevel_encode_fns[] = { + Opcode_wsr_icountlevel_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_icountlevel_encode_fns[] = { + Opcode_xsr_icountlevel_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ddr_encode_fns[] = { + Opcode_rsr_ddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ddr_encode_fns[] = { + Opcode_wsr_ddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ddr_encode_fns[] = { + Opcode_xsr_ddr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rfdo_encode_fns[] = { + Opcode_rfdo_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rfdd_encode_fns[] = { + Opcode_rfdd_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ccount_encode_fns[] = { + Opcode_rsr_ccount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ccount_encode_fns[] = { + Opcode_wsr_ccount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ccount_encode_fns[] = { + Opcode_xsr_ccount_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ccompare0_encode_fns[] = { + Opcode_rsr_ccompare0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ccompare0_encode_fns[] = { + Opcode_wsr_ccompare0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ccompare0_encode_fns[] = { + Opcode_xsr_ccompare0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ccompare1_encode_fns[] = { + Opcode_rsr_ccompare1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ccompare1_encode_fns[] = { + Opcode_wsr_ccompare1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ccompare1_encode_fns[] = { + Opcode_xsr_ccompare1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rsr_ccompare2_encode_fns[] = { + Opcode_rsr_ccompare2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wsr_ccompare2_encode_fns[] = { + Opcode_wsr_ccompare2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_xsr_ccompare2_encode_fns[] = { + Opcode_xsr_ccompare2_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_ipf_encode_fns[] = { + Opcode_ipf_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_ihi_encode_fns[] = { + Opcode_ihi_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_iii_encode_fns[] = { + Opcode_iii_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_lict_encode_fns[] = { + Opcode_lict_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_licw_encode_fns[] = { + Opcode_licw_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_sict_encode_fns[] = { + Opcode_sict_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_sicw_encode_fns[] = { + Opcode_sicw_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dhwb_encode_fns[] = { + Opcode_dhwb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dhwbi_encode_fns[] = { + Opcode_dhwbi_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_diwb_encode_fns[] = { + Opcode_diwb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_diwbi_encode_fns[] = { + Opcode_diwbi_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dhi_encode_fns[] = { + Opcode_dhi_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dii_encode_fns[] = { + Opcode_dii_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dpfr_encode_fns[] = { + Opcode_dpfr_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dpfw_encode_fns[] = { + Opcode_dpfw_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dpfro_encode_fns[] = { + Opcode_dpfro_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_dpfwo_encode_fns[] = { + Opcode_dpfwo_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_sdct_encode_fns[] = { + Opcode_sdct_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_ldct_encode_fns[] = { + Opcode_ldct_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_idtlb_encode_fns[] = { + Opcode_idtlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_pdtlb_encode_fns[] = { + Opcode_pdtlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rdtlb0_encode_fns[] = { + Opcode_rdtlb0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_rdtlb1_encode_fns[] = { + Opcode_rdtlb1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_wdtlb_encode_fns[] = { + Opcode_wdtlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_iitlb_encode_fns[] = { + Opcode_iitlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_pitlb_encode_fns[] = { + Opcode_pitlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_ritlb0_encode_fns[] = { + Opcode_ritlb0_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_ritlb1_encode_fns[] = { + Opcode_ritlb1_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_witlb_encode_fns[] = { + Opcode_witlb_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_nsa_encode_fns[] = { + Opcode_nsa_Slot_inst_encode, 0, 0 +}; + +xtensa_opcode_encode_fn Opcode_nsau_encode_fns[] = { + Opcode_nsau_Slot_inst_encode, 0, 0 +}; + + +/* Opcode table. */ + +static xtensa_opcode_internal opcodes[] = { + { "excw", 0 /* xt_iclass_excw */, + 0, + Opcode_excw_encode_fns, 0, 0 }, + { "rfe", 1 /* xt_iclass_rfe */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfe_encode_fns, 0, 0 }, + { "rfde", 2 /* xt_iclass_rfde */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfde_encode_fns, 0, 0 }, + { "syscall", 3 /* xt_iclass_syscall */, + 0, + Opcode_syscall_encode_fns, 0, 0 }, + { "simcall", 4 /* xt_iclass_simcall */, + 0, + Opcode_simcall_encode_fns, 0, 0 }, + { "call12", 5 /* xt_iclass_call12 */, + XTENSA_OPCODE_IS_CALL, + Opcode_call12_encode_fns, 0, 0 }, + { "call8", 6 /* xt_iclass_call8 */, + XTENSA_OPCODE_IS_CALL, + Opcode_call8_encode_fns, 0, 0 }, + { "call4", 7 /* xt_iclass_call4 */, + XTENSA_OPCODE_IS_CALL, + Opcode_call4_encode_fns, 0, 0 }, + { "callx12", 8 /* xt_iclass_callx12 */, + XTENSA_OPCODE_IS_CALL, + Opcode_callx12_encode_fns, 0, 0 }, + { "callx8", 9 /* xt_iclass_callx8 */, + XTENSA_OPCODE_IS_CALL, + Opcode_callx8_encode_fns, 0, 0 }, + { "callx4", 10 /* xt_iclass_callx4 */, + XTENSA_OPCODE_IS_CALL, + Opcode_callx4_encode_fns, 0, 0 }, + { "entry", 11 /* xt_iclass_entry */, + 0, + Opcode_entry_encode_fns, 0, 0 }, + { "movsp", 12 /* xt_iclass_movsp */, + 0, + Opcode_movsp_encode_fns, 0, 0 }, + { "rotw", 13 /* xt_iclass_rotw */, + 0, + Opcode_rotw_encode_fns, 0, 0 }, + { "retw", 14 /* xt_iclass_retw */, + XTENSA_OPCODE_IS_JUMP, + Opcode_retw_encode_fns, 0, 0 }, + { "retw.n", 14 /* xt_iclass_retw */, + XTENSA_OPCODE_IS_JUMP, + Opcode_retw_n_encode_fns, 0, 0 }, + { "rfwo", 15 /* xt_iclass_rfwou */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfwo_encode_fns, 0, 0 }, + { "rfwu", 15 /* xt_iclass_rfwou */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfwu_encode_fns, 0, 0 }, + { "l32e", 16 /* xt_iclass_l32e */, + 0, + Opcode_l32e_encode_fns, 0, 0 }, + { "s32e", 17 /* xt_iclass_s32e */, + 0, + Opcode_s32e_encode_fns, 0, 0 }, + { "rsr.windowbase", 18 /* xt_iclass_rsr.windowbase */, + 0, + Opcode_rsr_windowbase_encode_fns, 0, 0 }, + { "wsr.windowbase", 19 /* xt_iclass_wsr.windowbase */, + 0, + Opcode_wsr_windowbase_encode_fns, 0, 0 }, + { "xsr.windowbase", 20 /* xt_iclass_xsr.windowbase */, + 0, + Opcode_xsr_windowbase_encode_fns, 0, 0 }, + { "rsr.windowstart", 21 /* xt_iclass_rsr.windowstart */, + 0, + Opcode_rsr_windowstart_encode_fns, 0, 0 }, + { "wsr.windowstart", 22 /* xt_iclass_wsr.windowstart */, + 0, + Opcode_wsr_windowstart_encode_fns, 0, 0 }, + { "xsr.windowstart", 23 /* xt_iclass_xsr.windowstart */, + 0, + Opcode_xsr_windowstart_encode_fns, 0, 0 }, + { "add.n", 24 /* xt_iclass_add.n */, + 0, + Opcode_add_n_encode_fns, 0, 0 }, + { "addi.n", 25 /* xt_iclass_addi.n */, + 0, + Opcode_addi_n_encode_fns, 0, 0 }, + { "beqz.n", 26 /* xt_iclass_bz6 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_beqz_n_encode_fns, 0, 0 }, + { "bnez.n", 26 /* xt_iclass_bz6 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bnez_n_encode_fns, 0, 0 }, + { "ill.n", 27 /* xt_iclass_ill.n */, + 0, + Opcode_ill_n_encode_fns, 0, 0 }, + { "l32i.n", 28 /* xt_iclass_loadi4 */, + 0, + Opcode_l32i_n_encode_fns, 0, 0 }, + { "mov.n", 29 /* xt_iclass_mov.n */, + 0, + Opcode_mov_n_encode_fns, 0, 0 }, + { "movi.n", 30 /* xt_iclass_movi.n */, + 0, + Opcode_movi_n_encode_fns, 0, 0 }, + { "nop.n", 31 /* xt_iclass_nopn */, + 0, + Opcode_nop_n_encode_fns, 0, 0 }, + { "ret.n", 32 /* xt_iclass_retn */, + XTENSA_OPCODE_IS_JUMP, + Opcode_ret_n_encode_fns, 0, 0 }, + { "s32i.n", 33 /* xt_iclass_storei4 */, + 0, + Opcode_s32i_n_encode_fns, 0, 0 }, + { "addi", 34 /* xt_iclass_addi */, + 0, + Opcode_addi_encode_fns, 0, 0 }, + { "addmi", 35 /* xt_iclass_addmi */, + 0, + Opcode_addmi_encode_fns, 0, 0 }, + { "add", 36 /* xt_iclass_addsub */, + 0, + Opcode_add_encode_fns, 0, 0 }, + { "sub", 36 /* xt_iclass_addsub */, + 0, + Opcode_sub_encode_fns, 0, 0 }, + { "addx2", 36 /* xt_iclass_addsub */, + 0, + Opcode_addx2_encode_fns, 0, 0 }, + { "addx4", 36 /* xt_iclass_addsub */, + 0, + Opcode_addx4_encode_fns, 0, 0 }, + { "addx8", 36 /* xt_iclass_addsub */, + 0, + Opcode_addx8_encode_fns, 0, 0 }, + { "subx2", 36 /* xt_iclass_addsub */, + 0, + Opcode_subx2_encode_fns, 0, 0 }, + { "subx4", 36 /* xt_iclass_addsub */, + 0, + Opcode_subx4_encode_fns, 0, 0 }, + { "subx8", 36 /* xt_iclass_addsub */, + 0, + Opcode_subx8_encode_fns, 0, 0 }, + { "and", 37 /* xt_iclass_bit */, + 0, + Opcode_and_encode_fns, 0, 0 }, + { "or", 37 /* xt_iclass_bit */, + 0, + Opcode_or_encode_fns, 0, 0 }, + { "xor", 37 /* xt_iclass_bit */, + 0, + Opcode_xor_encode_fns, 0, 0 }, + { "beqi", 38 /* xt_iclass_bsi8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_beqi_encode_fns, 0, 0 }, + { "bnei", 38 /* xt_iclass_bsi8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bnei_encode_fns, 0, 0 }, + { "bgei", 38 /* xt_iclass_bsi8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bgei_encode_fns, 0, 0 }, + { "blti", 38 /* xt_iclass_bsi8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_blti_encode_fns, 0, 0 }, + { "bbci", 39 /* xt_iclass_bsi8b */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bbci_encode_fns, 0, 0 }, + { "bbsi", 39 /* xt_iclass_bsi8b */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bbsi_encode_fns, 0, 0 }, + { "bgeui", 40 /* xt_iclass_bsi8u */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bgeui_encode_fns, 0, 0 }, + { "bltui", 40 /* xt_iclass_bsi8u */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bltui_encode_fns, 0, 0 }, + { "beq", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_beq_encode_fns, 0, 0 }, + { "bne", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bne_encode_fns, 0, 0 }, + { "bge", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bge_encode_fns, 0, 0 }, + { "blt", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_blt_encode_fns, 0, 0 }, + { "bgeu", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bgeu_encode_fns, 0, 0 }, + { "bltu", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bltu_encode_fns, 0, 0 }, + { "bany", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bany_encode_fns, 0, 0 }, + { "bnone", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bnone_encode_fns, 0, 0 }, + { "ball", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_ball_encode_fns, 0, 0 }, + { "bnall", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bnall_encode_fns, 0, 0 }, + { "bbc", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bbc_encode_fns, 0, 0 }, + { "bbs", 41 /* xt_iclass_bst8 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bbs_encode_fns, 0, 0 }, + { "beqz", 42 /* xt_iclass_bsz12 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_beqz_encode_fns, 0, 0 }, + { "bnez", 42 /* xt_iclass_bsz12 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bnez_encode_fns, 0, 0 }, + { "bgez", 42 /* xt_iclass_bsz12 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bgez_encode_fns, 0, 0 }, + { "bltz", 42 /* xt_iclass_bsz12 */, + XTENSA_OPCODE_IS_BRANCH, + Opcode_bltz_encode_fns, 0, 0 }, + { "call0", 43 /* xt_iclass_call0 */, + XTENSA_OPCODE_IS_CALL, + Opcode_call0_encode_fns, 0, 0 }, + { "callx0", 44 /* xt_iclass_callx0 */, + XTENSA_OPCODE_IS_CALL, + Opcode_callx0_encode_fns, 0, 0 }, + { "extui", 45 /* xt_iclass_exti */, + 0, + Opcode_extui_encode_fns, 0, 0 }, + { "ill", 46 /* xt_iclass_ill */, + 0, + Opcode_ill_encode_fns, 0, 0 }, + { "j", 47 /* xt_iclass_jump */, + XTENSA_OPCODE_IS_JUMP, + Opcode_j_encode_fns, 0, 0 }, + { "jx", 48 /* xt_iclass_jumpx */, + XTENSA_OPCODE_IS_JUMP, + Opcode_jx_encode_fns, 0, 0 }, + { "l16ui", 49 /* xt_iclass_l16ui */, + 0, + Opcode_l16ui_encode_fns, 0, 0 }, + { "l16si", 50 /* xt_iclass_l16si */, + 0, + Opcode_l16si_encode_fns, 0, 0 }, + { "l32i", 51 /* xt_iclass_l32i */, + 0, + Opcode_l32i_encode_fns, 0, 0 }, + { "l32r", 52 /* xt_iclass_l32r */, + 0, + Opcode_l32r_encode_fns, 0, 0 }, + { "l8ui", 53 /* xt_iclass_l8i */, + 0, + Opcode_l8ui_encode_fns, 0, 0 }, + { "loop", 54 /* xt_iclass_loop */, + XTENSA_OPCODE_IS_LOOP, + Opcode_loop_encode_fns, 0, 0 }, + { "loopnez", 55 /* xt_iclass_loopz */, + XTENSA_OPCODE_IS_LOOP, + Opcode_loopnez_encode_fns, 0, 0 }, + { "loopgtz", 55 /* xt_iclass_loopz */, + XTENSA_OPCODE_IS_LOOP, + Opcode_loopgtz_encode_fns, 0, 0 }, + { "movi", 56 /* xt_iclass_movi */, + 0, + Opcode_movi_encode_fns, 0, 0 }, + { "moveqz", 57 /* xt_iclass_movz */, + 0, + Opcode_moveqz_encode_fns, 0, 0 }, + { "movnez", 57 /* xt_iclass_movz */, + 0, + Opcode_movnez_encode_fns, 0, 0 }, + { "movltz", 57 /* xt_iclass_movz */, + 0, + Opcode_movltz_encode_fns, 0, 0 }, + { "movgez", 57 /* xt_iclass_movz */, + 0, + Opcode_movgez_encode_fns, 0, 0 }, + { "neg", 58 /* xt_iclass_neg */, + 0, + Opcode_neg_encode_fns, 0, 0 }, + { "abs", 58 /* xt_iclass_neg */, + 0, + Opcode_abs_encode_fns, 0, 0 }, + { "nop", 59 /* xt_iclass_nop */, + 0, + Opcode_nop_encode_fns, 0, 0 }, + { "ret", 60 /* xt_iclass_return */, + XTENSA_OPCODE_IS_JUMP, + Opcode_ret_encode_fns, 0, 0 }, + { "s16i", 61 /* xt_iclass_s16i */, + 0, + Opcode_s16i_encode_fns, 0, 0 }, + { "s32i", 62 /* xt_iclass_s32i */, + 0, + Opcode_s32i_encode_fns, 0, 0 }, + { "s8i", 63 /* xt_iclass_s8i */, + 0, + Opcode_s8i_encode_fns, 0, 0 }, + { "ssr", 64 /* xt_iclass_sar */, + 0, + Opcode_ssr_encode_fns, 0, 0 }, + { "ssl", 64 /* xt_iclass_sar */, + 0, + Opcode_ssl_encode_fns, 0, 0 }, + { "ssa8l", 64 /* xt_iclass_sar */, + 0, + Opcode_ssa8l_encode_fns, 0, 0 }, + { "ssa8b", 64 /* xt_iclass_sar */, + 0, + Opcode_ssa8b_encode_fns, 0, 0 }, + { "ssai", 65 /* xt_iclass_sari */, + 0, + Opcode_ssai_encode_fns, 0, 0 }, + { "sll", 66 /* xt_iclass_shifts */, + 0, + Opcode_sll_encode_fns, 0, 0 }, + { "src", 67 /* xt_iclass_shiftst */, + 0, + Opcode_src_encode_fns, 0, 0 }, + { "srl", 68 /* xt_iclass_shiftt */, + 0, + Opcode_srl_encode_fns, 0, 0 }, + { "sra", 68 /* xt_iclass_shiftt */, + 0, + Opcode_sra_encode_fns, 0, 0 }, + { "slli", 69 /* xt_iclass_slli */, + 0, + Opcode_slli_encode_fns, 0, 0 }, + { "srai", 70 /* xt_iclass_srai */, + 0, + Opcode_srai_encode_fns, 0, 0 }, + { "srli", 71 /* xt_iclass_srli */, + 0, + Opcode_srli_encode_fns, 0, 0 }, + { "memw", 72 /* xt_iclass_memw */, + 0, + Opcode_memw_encode_fns, 0, 0 }, + { "extw", 73 /* xt_iclass_extw */, + 0, + Opcode_extw_encode_fns, 0, 0 }, + { "isync", 74 /* xt_iclass_isync */, + 0, + Opcode_isync_encode_fns, 0, 0 }, + { "rsync", 75 /* xt_iclass_sync */, + 0, + Opcode_rsync_encode_fns, 0, 0 }, + { "esync", 75 /* xt_iclass_sync */, + 0, + Opcode_esync_encode_fns, 0, 0 }, + { "dsync", 75 /* xt_iclass_sync */, + 0, + Opcode_dsync_encode_fns, 0, 0 }, + { "rsil", 76 /* xt_iclass_rsil */, + 0, + Opcode_rsil_encode_fns, 0, 0 }, + { "rsr.lend", 77 /* xt_iclass_rsr.lend */, + 0, + Opcode_rsr_lend_encode_fns, 0, 0 }, + { "wsr.lend", 78 /* xt_iclass_wsr.lend */, + 0, + Opcode_wsr_lend_encode_fns, 0, 0 }, + { "xsr.lend", 79 /* xt_iclass_xsr.lend */, + 0, + Opcode_xsr_lend_encode_fns, 0, 0 }, + { "rsr.lcount", 80 /* xt_iclass_rsr.lcount */, + 0, + Opcode_rsr_lcount_encode_fns, 0, 0 }, + { "wsr.lcount", 81 /* xt_iclass_wsr.lcount */, + 0, + Opcode_wsr_lcount_encode_fns, 0, 0 }, + { "xsr.lcount", 82 /* xt_iclass_xsr.lcount */, + 0, + Opcode_xsr_lcount_encode_fns, 0, 0 }, + { "rsr.lbeg", 83 /* xt_iclass_rsr.lbeg */, + 0, + Opcode_rsr_lbeg_encode_fns, 0, 0 }, + { "wsr.lbeg", 84 /* xt_iclass_wsr.lbeg */, + 0, + Opcode_wsr_lbeg_encode_fns, 0, 0 }, + { "xsr.lbeg", 85 /* xt_iclass_xsr.lbeg */, + 0, + Opcode_xsr_lbeg_encode_fns, 0, 0 }, + { "rsr.sar", 86 /* xt_iclass_rsr.sar */, + 0, + Opcode_rsr_sar_encode_fns, 0, 0 }, + { "wsr.sar", 87 /* xt_iclass_wsr.sar */, + 0, + Opcode_wsr_sar_encode_fns, 0, 0 }, + { "xsr.sar", 88 /* xt_iclass_xsr.sar */, + 0, + Opcode_xsr_sar_encode_fns, 0, 0 }, + { "rsr.litbase", 89 /* xt_iclass_rsr.litbase */, + 0, + Opcode_rsr_litbase_encode_fns, 0, 0 }, + { "wsr.litbase", 90 /* xt_iclass_wsr.litbase */, + 0, + Opcode_wsr_litbase_encode_fns, 0, 0 }, + { "xsr.litbase", 91 /* xt_iclass_xsr.litbase */, + 0, + Opcode_xsr_litbase_encode_fns, 0, 0 }, + { "rsr.176", 92 /* xt_iclass_rsr.176 */, + 0, + Opcode_rsr_176_encode_fns, 0, 0 }, + { "rsr.208", 93 /* xt_iclass_rsr.208 */, + 0, + Opcode_rsr_208_encode_fns, 0, 0 }, + { "rsr.ps", 94 /* xt_iclass_rsr.ps */, + 0, + Opcode_rsr_ps_encode_fns, 0, 0 }, + { "wsr.ps", 95 /* xt_iclass_wsr.ps */, + 0, + Opcode_wsr_ps_encode_fns, 0, 0 }, + { "xsr.ps", 96 /* xt_iclass_xsr.ps */, + 0, + Opcode_xsr_ps_encode_fns, 0, 0 }, + { "rsr.epc1", 97 /* xt_iclass_rsr.epc1 */, + 0, + Opcode_rsr_epc1_encode_fns, 0, 0 }, + { "wsr.epc1", 98 /* xt_iclass_wsr.epc1 */, + 0, + Opcode_wsr_epc1_encode_fns, 0, 0 }, + { "xsr.epc1", 99 /* xt_iclass_xsr.epc1 */, + 0, + Opcode_xsr_epc1_encode_fns, 0, 0 }, + { "rsr.excsave1", 100 /* xt_iclass_rsr.excsave1 */, + 0, + Opcode_rsr_excsave1_encode_fns, 0, 0 }, + { "wsr.excsave1", 101 /* xt_iclass_wsr.excsave1 */, + 0, + Opcode_wsr_excsave1_encode_fns, 0, 0 }, + { "xsr.excsave1", 102 /* xt_iclass_xsr.excsave1 */, + 0, + Opcode_xsr_excsave1_encode_fns, 0, 0 }, + { "rsr.epc2", 103 /* xt_iclass_rsr.epc2 */, + 0, + Opcode_rsr_epc2_encode_fns, 0, 0 }, + { "wsr.epc2", 104 /* xt_iclass_wsr.epc2 */, + 0, + Opcode_wsr_epc2_encode_fns, 0, 0 }, + { "xsr.epc2", 105 /* xt_iclass_xsr.epc2 */, + 0, + Opcode_xsr_epc2_encode_fns, 0, 0 }, + { "rsr.excsave2", 106 /* xt_iclass_rsr.excsave2 */, + 0, + Opcode_rsr_excsave2_encode_fns, 0, 0 }, + { "wsr.excsave2", 107 /* xt_iclass_wsr.excsave2 */, + 0, + Opcode_wsr_excsave2_encode_fns, 0, 0 }, + { "xsr.excsave2", 108 /* xt_iclass_xsr.excsave2 */, + 0, + Opcode_xsr_excsave2_encode_fns, 0, 0 }, + { "rsr.epc3", 109 /* xt_iclass_rsr.epc3 */, + 0, + Opcode_rsr_epc3_encode_fns, 0, 0 }, + { "wsr.epc3", 110 /* xt_iclass_wsr.epc3 */, + 0, + Opcode_wsr_epc3_encode_fns, 0, 0 }, + { "xsr.epc3", 111 /* xt_iclass_xsr.epc3 */, + 0, + Opcode_xsr_epc3_encode_fns, 0, 0 }, + { "rsr.excsave3", 112 /* xt_iclass_rsr.excsave3 */, + 0, + Opcode_rsr_excsave3_encode_fns, 0, 0 }, + { "wsr.excsave3", 113 /* xt_iclass_wsr.excsave3 */, + 0, + Opcode_wsr_excsave3_encode_fns, 0, 0 }, + { "xsr.excsave3", 114 /* xt_iclass_xsr.excsave3 */, + 0, + Opcode_xsr_excsave3_encode_fns, 0, 0 }, + { "rsr.epc4", 115 /* xt_iclass_rsr.epc4 */, + 0, + Opcode_rsr_epc4_encode_fns, 0, 0 }, + { "wsr.epc4", 116 /* xt_iclass_wsr.epc4 */, + 0, + Opcode_wsr_epc4_encode_fns, 0, 0 }, + { "xsr.epc4", 117 /* xt_iclass_xsr.epc4 */, + 0, + Opcode_xsr_epc4_encode_fns, 0, 0 }, + { "rsr.excsave4", 118 /* xt_iclass_rsr.excsave4 */, + 0, + Opcode_rsr_excsave4_encode_fns, 0, 0 }, + { "wsr.excsave4", 119 /* xt_iclass_wsr.excsave4 */, + 0, + Opcode_wsr_excsave4_encode_fns, 0, 0 }, + { "xsr.excsave4", 120 /* xt_iclass_xsr.excsave4 */, + 0, + Opcode_xsr_excsave4_encode_fns, 0, 0 }, + { "rsr.eps2", 121 /* xt_iclass_rsr.eps2 */, + 0, + Opcode_rsr_eps2_encode_fns, 0, 0 }, + { "wsr.eps2", 122 /* xt_iclass_wsr.eps2 */, + 0, + Opcode_wsr_eps2_encode_fns, 0, 0 }, + { "xsr.eps2", 123 /* xt_iclass_xsr.eps2 */, + 0, + Opcode_xsr_eps2_encode_fns, 0, 0 }, + { "rsr.eps3", 124 /* xt_iclass_rsr.eps3 */, + 0, + Opcode_rsr_eps3_encode_fns, 0, 0 }, + { "wsr.eps3", 125 /* xt_iclass_wsr.eps3 */, + 0, + Opcode_wsr_eps3_encode_fns, 0, 0 }, + { "xsr.eps3", 126 /* xt_iclass_xsr.eps3 */, + 0, + Opcode_xsr_eps3_encode_fns, 0, 0 }, + { "rsr.eps4", 127 /* xt_iclass_rsr.eps4 */, + 0, + Opcode_rsr_eps4_encode_fns, 0, 0 }, + { "wsr.eps4", 128 /* xt_iclass_wsr.eps4 */, + 0, + Opcode_wsr_eps4_encode_fns, 0, 0 }, + { "xsr.eps4", 129 /* xt_iclass_xsr.eps4 */, + 0, + Opcode_xsr_eps4_encode_fns, 0, 0 }, + { "rsr.excvaddr", 130 /* xt_iclass_rsr.excvaddr */, + 0, + Opcode_rsr_excvaddr_encode_fns, 0, 0 }, + { "wsr.excvaddr", 131 /* xt_iclass_wsr.excvaddr */, + 0, + Opcode_wsr_excvaddr_encode_fns, 0, 0 }, + { "xsr.excvaddr", 132 /* xt_iclass_xsr.excvaddr */, + 0, + Opcode_xsr_excvaddr_encode_fns, 0, 0 }, + { "rsr.depc", 133 /* xt_iclass_rsr.depc */, + 0, + Opcode_rsr_depc_encode_fns, 0, 0 }, + { "wsr.depc", 134 /* xt_iclass_wsr.depc */, + 0, + Opcode_wsr_depc_encode_fns, 0, 0 }, + { "xsr.depc", 135 /* xt_iclass_xsr.depc */, + 0, + Opcode_xsr_depc_encode_fns, 0, 0 }, + { "rsr.exccause", 136 /* xt_iclass_rsr.exccause */, + 0, + Opcode_rsr_exccause_encode_fns, 0, 0 }, + { "wsr.exccause", 137 /* xt_iclass_wsr.exccause */, + 0, + Opcode_wsr_exccause_encode_fns, 0, 0 }, + { "xsr.exccause", 138 /* xt_iclass_xsr.exccause */, + 0, + Opcode_xsr_exccause_encode_fns, 0, 0 }, + { "rsr.misc0", 139 /* xt_iclass_rsr.misc0 */, + 0, + Opcode_rsr_misc0_encode_fns, 0, 0 }, + { "wsr.misc0", 140 /* xt_iclass_wsr.misc0 */, + 0, + Opcode_wsr_misc0_encode_fns, 0, 0 }, + { "xsr.misc0", 141 /* xt_iclass_xsr.misc0 */, + 0, + Opcode_xsr_misc0_encode_fns, 0, 0 }, + { "rsr.misc1", 142 /* xt_iclass_rsr.misc1 */, + 0, + Opcode_rsr_misc1_encode_fns, 0, 0 }, + { "wsr.misc1", 143 /* xt_iclass_wsr.misc1 */, + 0, + Opcode_wsr_misc1_encode_fns, 0, 0 }, + { "xsr.misc1", 144 /* xt_iclass_xsr.misc1 */, + 0, + Opcode_xsr_misc1_encode_fns, 0, 0 }, + { "rsr.prid", 145 /* xt_iclass_rsr.prid */, + 0, + Opcode_rsr_prid_encode_fns, 0, 0 }, + { "rfi", 146 /* xt_iclass_rfi */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfi_encode_fns, 0, 0 }, + { "waiti", 147 /* xt_iclass_wait */, + 0, + Opcode_waiti_encode_fns, 0, 0 }, + { "rsr.interrupt", 148 /* xt_iclass_rsr.interrupt */, + 0, + Opcode_rsr_interrupt_encode_fns, 0, 0 }, + { "wsr.intset", 149 /* xt_iclass_wsr.intset */, + 0, + Opcode_wsr_intset_encode_fns, 0, 0 }, + { "wsr.intclear", 150 /* xt_iclass_wsr.intclear */, + 0, + Opcode_wsr_intclear_encode_fns, 0, 0 }, + { "rsr.intenable", 151 /* xt_iclass_rsr.intenable */, + 0, + Opcode_rsr_intenable_encode_fns, 0, 0 }, + { "wsr.intenable", 152 /* xt_iclass_wsr.intenable */, + 0, + Opcode_wsr_intenable_encode_fns, 0, 0 }, + { "xsr.intenable", 153 /* xt_iclass_xsr.intenable */, + 0, + Opcode_xsr_intenable_encode_fns, 0, 0 }, + { "break", 154 /* xt_iclass_break */, + 0, + Opcode_break_encode_fns, 0, 0 }, + { "break.n", 155 /* xt_iclass_break.n */, + 0, + Opcode_break_n_encode_fns, 0, 0 }, + { "rsr.dbreaka0", 156 /* xt_iclass_rsr.dbreaka0 */, + 0, + Opcode_rsr_dbreaka0_encode_fns, 0, 0 }, + { "wsr.dbreaka0", 157 /* xt_iclass_wsr.dbreaka0 */, + 0, + Opcode_wsr_dbreaka0_encode_fns, 0, 0 }, + { "xsr.dbreaka0", 158 /* xt_iclass_xsr.dbreaka0 */, + 0, + Opcode_xsr_dbreaka0_encode_fns, 0, 0 }, + { "rsr.dbreakc0", 159 /* xt_iclass_rsr.dbreakc0 */, + 0, + Opcode_rsr_dbreakc0_encode_fns, 0, 0 }, + { "wsr.dbreakc0", 160 /* xt_iclass_wsr.dbreakc0 */, + 0, + Opcode_wsr_dbreakc0_encode_fns, 0, 0 }, + { "xsr.dbreakc0", 161 /* xt_iclass_xsr.dbreakc0 */, + 0, + Opcode_xsr_dbreakc0_encode_fns, 0, 0 }, + { "rsr.dbreaka1", 162 /* xt_iclass_rsr.dbreaka1 */, + 0, + Opcode_rsr_dbreaka1_encode_fns, 0, 0 }, + { "wsr.dbreaka1", 163 /* xt_iclass_wsr.dbreaka1 */, + 0, + Opcode_wsr_dbreaka1_encode_fns, 0, 0 }, + { "xsr.dbreaka1", 164 /* xt_iclass_xsr.dbreaka1 */, + 0, + Opcode_xsr_dbreaka1_encode_fns, 0, 0 }, + { "rsr.dbreakc1", 165 /* xt_iclass_rsr.dbreakc1 */, + 0, + Opcode_rsr_dbreakc1_encode_fns, 0, 0 }, + { "wsr.dbreakc1", 166 /* xt_iclass_wsr.dbreakc1 */, + 0, + Opcode_wsr_dbreakc1_encode_fns, 0, 0 }, + { "xsr.dbreakc1", 167 /* xt_iclass_xsr.dbreakc1 */, + 0, + Opcode_xsr_dbreakc1_encode_fns, 0, 0 }, + { "rsr.ibreaka0", 168 /* xt_iclass_rsr.ibreaka0 */, + 0, + Opcode_rsr_ibreaka0_encode_fns, 0, 0 }, + { "wsr.ibreaka0", 169 /* xt_iclass_wsr.ibreaka0 */, + 0, + Opcode_wsr_ibreaka0_encode_fns, 0, 0 }, + { "xsr.ibreaka0", 170 /* xt_iclass_xsr.ibreaka0 */, + 0, + Opcode_xsr_ibreaka0_encode_fns, 0, 0 }, + { "rsr.ibreaka1", 171 /* xt_iclass_rsr.ibreaka1 */, + 0, + Opcode_rsr_ibreaka1_encode_fns, 0, 0 }, + { "wsr.ibreaka1", 172 /* xt_iclass_wsr.ibreaka1 */, + 0, + Opcode_wsr_ibreaka1_encode_fns, 0, 0 }, + { "xsr.ibreaka1", 173 /* xt_iclass_xsr.ibreaka1 */, + 0, + Opcode_xsr_ibreaka1_encode_fns, 0, 0 }, + { "rsr.ibreakenable", 174 /* xt_iclass_rsr.ibreakenable */, + 0, + Opcode_rsr_ibreakenable_encode_fns, 0, 0 }, + { "wsr.ibreakenable", 175 /* xt_iclass_wsr.ibreakenable */, + 0, + Opcode_wsr_ibreakenable_encode_fns, 0, 0 }, + { "xsr.ibreakenable", 176 /* xt_iclass_xsr.ibreakenable */, + 0, + Opcode_xsr_ibreakenable_encode_fns, 0, 0 }, + { "rsr.debugcause", 177 /* xt_iclass_rsr.debugcause */, + 0, + Opcode_rsr_debugcause_encode_fns, 0, 0 }, + { "wsr.debugcause", 178 /* xt_iclass_wsr.debugcause */, + 0, + Opcode_wsr_debugcause_encode_fns, 0, 0 }, + { "xsr.debugcause", 179 /* xt_iclass_xsr.debugcause */, + 0, + Opcode_xsr_debugcause_encode_fns, 0, 0 }, + { "rsr.icount", 180 /* xt_iclass_rsr.icount */, + 0, + Opcode_rsr_icount_encode_fns, 0, 0 }, + { "wsr.icount", 181 /* xt_iclass_wsr.icount */, + 0, + Opcode_wsr_icount_encode_fns, 0, 0 }, + { "xsr.icount", 182 /* xt_iclass_xsr.icount */, + 0, + Opcode_xsr_icount_encode_fns, 0, 0 }, + { "rsr.icountlevel", 183 /* xt_iclass_rsr.icountlevel */, + 0, + Opcode_rsr_icountlevel_encode_fns, 0, 0 }, + { "wsr.icountlevel", 184 /* xt_iclass_wsr.icountlevel */, + 0, + Opcode_wsr_icountlevel_encode_fns, 0, 0 }, + { "xsr.icountlevel", 185 /* xt_iclass_xsr.icountlevel */, + 0, + Opcode_xsr_icountlevel_encode_fns, 0, 0 }, + { "rsr.ddr", 186 /* xt_iclass_rsr.ddr */, + 0, + Opcode_rsr_ddr_encode_fns, 0, 0 }, + { "wsr.ddr", 187 /* xt_iclass_wsr.ddr */, + 0, + Opcode_wsr_ddr_encode_fns, 0, 0 }, + { "xsr.ddr", 188 /* xt_iclass_xsr.ddr */, + 0, + Opcode_xsr_ddr_encode_fns, 0, 0 }, + { "rfdo", 189 /* xt_iclass_rfdo */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfdo_encode_fns, 0, 0 }, + { "rfdd", 190 /* xt_iclass_rfdd */, + XTENSA_OPCODE_IS_JUMP, + Opcode_rfdd_encode_fns, 0, 0 }, + { "rsr.ccount", 191 /* xt_iclass_rsr.ccount */, + 0, + Opcode_rsr_ccount_encode_fns, 0, 0 }, + { "wsr.ccount", 192 /* xt_iclass_wsr.ccount */, + 0, + Opcode_wsr_ccount_encode_fns, 0, 0 }, + { "xsr.ccount", 193 /* xt_iclass_xsr.ccount */, + 0, + Opcode_xsr_ccount_encode_fns, 0, 0 }, + { "rsr.ccompare0", 194 /* xt_iclass_rsr.ccompare0 */, + 0, + Opcode_rsr_ccompare0_encode_fns, 0, 0 }, + { "wsr.ccompare0", 195 /* xt_iclass_wsr.ccompare0 */, + 0, + Opcode_wsr_ccompare0_encode_fns, 0, 0 }, + { "xsr.ccompare0", 196 /* xt_iclass_xsr.ccompare0 */, + 0, + Opcode_xsr_ccompare0_encode_fns, 0, 0 }, + { "rsr.ccompare1", 197 /* xt_iclass_rsr.ccompare1 */, + 0, + Opcode_rsr_ccompare1_encode_fns, 0, 0 }, + { "wsr.ccompare1", 198 /* xt_iclass_wsr.ccompare1 */, + 0, + Opcode_wsr_ccompare1_encode_fns, 0, 0 }, + { "xsr.ccompare1", 199 /* xt_iclass_xsr.ccompare1 */, + 0, + Opcode_xsr_ccompare1_encode_fns, 0, 0 }, + { "rsr.ccompare2", 200 /* xt_iclass_rsr.ccompare2 */, + 0, + Opcode_rsr_ccompare2_encode_fns, 0, 0 }, + { "wsr.ccompare2", 201 /* xt_iclass_wsr.ccompare2 */, + 0, + Opcode_wsr_ccompare2_encode_fns, 0, 0 }, + { "xsr.ccompare2", 202 /* xt_iclass_xsr.ccompare2 */, + 0, + Opcode_xsr_ccompare2_encode_fns, 0, 0 }, + { "ipf", 203 /* xt_iclass_icache */, + 0, + Opcode_ipf_encode_fns, 0, 0 }, + { "ihi", 203 /* xt_iclass_icache */, + 0, + Opcode_ihi_encode_fns, 0, 0 }, + { "iii", 204 /* xt_iclass_icache_inv */, + 0, + Opcode_iii_encode_fns, 0, 0 }, + { "lict", 205 /* xt_iclass_licx */, + 0, + Opcode_lict_encode_fns, 0, 0 }, + { "licw", 205 /* xt_iclass_licx */, + 0, + Opcode_licw_encode_fns, 0, 0 }, + { "sict", 206 /* xt_iclass_sicx */, + 0, + Opcode_sict_encode_fns, 0, 0 }, + { "sicw", 206 /* xt_iclass_sicx */, + 0, + Opcode_sicw_encode_fns, 0, 0 }, + { "dhwb", 207 /* xt_iclass_dcache */, + 0, + Opcode_dhwb_encode_fns, 0, 0 }, + { "dhwbi", 207 /* xt_iclass_dcache */, + 0, + Opcode_dhwbi_encode_fns, 0, 0 }, + { "diwb", 208 /* xt_iclass_dcache_ind */, + 0, + Opcode_diwb_encode_fns, 0, 0 }, + { "diwbi", 208 /* xt_iclass_dcache_ind */, + 0, + Opcode_diwbi_encode_fns, 0, 0 }, + { "dhi", 209 /* xt_iclass_dcache_inv */, + 0, + Opcode_dhi_encode_fns, 0, 0 }, + { "dii", 209 /* xt_iclass_dcache_inv */, + 0, + Opcode_dii_encode_fns, 0, 0 }, + { "dpfr", 210 /* xt_iclass_dpf */, + 0, + Opcode_dpfr_encode_fns, 0, 0 }, + { "dpfw", 210 /* xt_iclass_dpf */, + 0, + Opcode_dpfw_encode_fns, 0, 0 }, + { "dpfro", 210 /* xt_iclass_dpf */, + 0, + Opcode_dpfro_encode_fns, 0, 0 }, + { "dpfwo", 210 /* xt_iclass_dpf */, + 0, + Opcode_dpfwo_encode_fns, 0, 0 }, + { "sdct", 211 /* xt_iclass_sdct */, + 0, + Opcode_sdct_encode_fns, 0, 0 }, + { "ldct", 212 /* xt_iclass_ldct */, + 0, + Opcode_ldct_encode_fns, 0, 0 }, + { "idtlb", 213 /* xt_iclass_idtlb */, + 0, + Opcode_idtlb_encode_fns, 0, 0 }, + { "pdtlb", 214 /* xt_iclass_rdtlb */, + 0, + Opcode_pdtlb_encode_fns, 0, 0 }, + { "rdtlb0", 214 /* xt_iclass_rdtlb */, + 0, + Opcode_rdtlb0_encode_fns, 0, 0 }, + { "rdtlb1", 214 /* xt_iclass_rdtlb */, + 0, + Opcode_rdtlb1_encode_fns, 0, 0 }, + { "wdtlb", 215 /* xt_iclass_wdtlb */, + 0, + Opcode_wdtlb_encode_fns, 0, 0 }, + { "iitlb", 216 /* xt_iclass_iitlb */, + 0, + Opcode_iitlb_encode_fns, 0, 0 }, + { "pitlb", 217 /* xt_iclass_ritlb */, + 0, + Opcode_pitlb_encode_fns, 0, 0 }, + { "ritlb0", 217 /* xt_iclass_ritlb */, + 0, + Opcode_ritlb0_encode_fns, 0, 0 }, + { "ritlb1", 217 /* xt_iclass_ritlb */, + 0, + Opcode_ritlb1_encode_fns, 0, 0 }, + { "witlb", 218 /* xt_iclass_witlb */, + 0, + Opcode_witlb_encode_fns, 0, 0 }, + { "nsa", 219 /* xt_iclass_nsa */, + 0, + Opcode_nsa_encode_fns, 0, 0 }, + { "nsau", 219 /* xt_iclass_nsa */, + 0, + Opcode_nsau_encode_fns, 0, 0 } +}; + + +/* Slot-specific opcode decode functions. */ + +static int +Slot_inst_decode (const xtensa_insnbuf insn) +{ + switch (Field_op0_Slot_inst_get (insn)) + { + case 0: + switch (Field_op1_Slot_inst_get (insn)) + { + case 0: + switch (Field_op2_Slot_inst_get (insn)) + { + case 0: + switch (Field_r_Slot_inst_get (insn)) + { + case 0: + switch (Field_m_Slot_inst_get (insn)) + { + case 0: + return 77; /* ill */ + case 2: + switch (Field_n_Slot_inst_get (insn)) + { + case 0: + return 96; /* ret */ + case 1: + return 14; /* retw */ + case 2: + return 79; /* jx */ + } + break; + case 3: + switch (Field_n_Slot_inst_get (insn)) + { + case 0: + return 75; /* callx0 */ + case 1: + return 10; /* callx4 */ + case 2: + return 9; /* callx8 */ + case 3: + return 8; /* callx12 */ + } + break; + } + break; + case 1: + return 12; /* movsp */ + case 2: + if (Field_s_Slot_inst_get (insn) == 0) + { + switch (Field_t_Slot_inst_get (insn)) + { + case 0: + return 114; /* isync */ + case 1: + return 115; /* rsync */ + case 2: + return 116; /* esync */ + case 3: + return 117; /* dsync */ + case 8: + return 0; /* excw */ + case 12: + return 112; /* memw */ + case 13: + return 113; /* extw */ + case 15: + return 95; /* nop */ + } + } + break; + case 3: + switch (Field_t_Slot_inst_get (insn)) + { + case 0: + switch (Field_s_Slot_inst_get (insn)) + { + case 0: + return 1; /* rfe */ + case 2: + return 2; /* rfde */ + case 4: + return 16; /* rfwo */ + case 5: + return 17; /* rfwu */ + } + break; + case 1: + return 188; /* rfi */ + } + break; + case 4: + return 196; /* break */ + case 5: + switch (Field_s_Slot_inst_get (insn)) + { + case 0: + if (Field_t_Slot_inst_get (insn) == 0) + return 3; /* syscall */ + break; + case 1: + if (Field_t_Slot_inst_get (insn) == 0) + return 4; /* simcall */ + break; + } + break; + case 6: + return 118; /* rsil */ + case 7: + if (Field_t_Slot_inst_get (insn) == 0) + return 189; /* waiti */ + break; + } + break; + case 1: + return 47; /* and */ + case 2: + return 48; /* or */ + case 3: + return 49; /* xor */ + case 4: + switch (Field_r_Slot_inst_get (insn)) + { + case 0: + if (Field_t_Slot_inst_get (insn) == 0) + return 100; /* ssr */ + break; + case 1: + if (Field_t_Slot_inst_get (insn) == 0) + return 101; /* ssl */ + break; + case 2: + if (Field_t_Slot_inst_get (insn) == 0) + return 102; /* ssa8l */ + break; + case 3: + if (Field_t_Slot_inst_get (insn) == 0) + return 103; /* ssa8b */ + break; + case 4: + if (Field_thi3_Slot_inst_get (insn) == 0) + return 104; /* ssai */ + break; + case 8: + if (Field_s_Slot_inst_get (insn) == 0) + return 13; /* rotw */ + break; + case 14: + return 274; /* nsa */ + case 15: + return 275; /* nsau */ + } + break; + case 5: + switch (Field_r_Slot_inst_get (insn)) + { + case 3: + return 271; /* ritlb0 */ + case 4: + return 269; /* iitlb */ + case 5: + return 270; /* pitlb */ + case 6: + return 273; /* witlb */ + case 7: + return 272; /* ritlb1 */ + case 11: + return 266; /* rdtlb0 */ + case 12: + return 264; /* idtlb */ + case 13: + return 265; /* pdtlb */ + case 14: + return 268; /* wdtlb */ + case 15: + return 267; /* rdtlb1 */ + } + break; + case 6: + switch (Field_s_Slot_inst_get (insn)) + { + case 0: + return 93; /* neg */ + case 1: + return 94; /* abs */ + } + break; + case 8: + return 39; /* add */ + case 9: + return 41; /* addx2 */ + case 10: + return 42; /* addx4 */ + case 11: + return 43; /* addx8 */ + case 12: + return 40; /* sub */ + case 13: + return 44; /* subx2 */ + case 14: + return 45; /* subx4 */ + case 15: + return 46; /* subx8 */ + } + break; + case 1: + switch (Field_op2_Slot_inst_get (insn)) + { + case 0: + case 1: + return 109; /* slli */ + case 2: + case 3: + return 110; /* srai */ + case 4: + return 111; /* srli */ + case 6: + switch (Field_sr_Slot_inst_get (insn)) + { + case 0: + return 127; /* xsr.lbeg */ + case 1: + return 121; /* xsr.lend */ + case 2: + return 124; /* xsr.lcount */ + case 3: + return 130; /* xsr.sar */ + case 5: + return 133; /* xsr.litbase */ + case 72: + return 22; /* xsr.windowbase */ + case 73: + return 25; /* xsr.windowstart */ + case 96: + return 218; /* xsr.ibreakenable */ + case 104: + return 230; /* xsr.ddr */ + case 128: + return 212; /* xsr.ibreaka0 */ + case 129: + return 215; /* xsr.ibreaka1 */ + case 144: + return 200; /* xsr.dbreaka0 */ + case 145: + return 206; /* xsr.dbreaka1 */ + case 160: + return 203; /* xsr.dbreakc0 */ + case 161: + return 209; /* xsr.dbreakc1 */ + case 177: + return 141; /* xsr.epc1 */ + case 178: + return 147; /* xsr.epc2 */ + case 179: + return 153; /* xsr.epc3 */ + case 180: + return 159; /* xsr.epc4 */ + case 192: + return 177; /* xsr.depc */ + case 194: + return 165; /* xsr.eps2 */ + case 195: + return 168; /* xsr.eps3 */ + case 196: + return 171; /* xsr.eps4 */ + case 209: + return 144; /* xsr.excsave1 */ + case 210: + return 150; /* xsr.excsave2 */ + case 211: + return 156; /* xsr.excsave3 */ + case 212: + return 162; /* xsr.excsave4 */ + case 228: + return 195; /* xsr.intenable */ + case 230: + return 138; /* xsr.ps */ + case 232: + return 180; /* xsr.exccause */ + case 233: + return 221; /* xsr.debugcause */ + case 234: + return 235; /* xsr.ccount */ + case 236: + return 224; /* xsr.icount */ + case 237: + return 227; /* xsr.icountlevel */ + case 238: + return 174; /* xsr.excvaddr */ + case 240: + return 238; /* xsr.ccompare0 */ + case 241: + return 241; /* xsr.ccompare1 */ + case 242: + return 244; /* xsr.ccompare2 */ + case 244: + return 183; /* xsr.misc0 */ + case 245: + return 186; /* xsr.misc1 */ + } + break; + case 8: + return 106; /* src */ + case 9: + if (Field_s_Slot_inst_get (insn) == 0) + return 107; /* srl */ + break; + case 10: + if (Field_t_Slot_inst_get (insn) == 0) + return 105; /* sll */ + break; + case 11: + if (Field_s_Slot_inst_get (insn) == 0) + return 108; /* sra */ + break; + case 15: + switch (Field_r_Slot_inst_get (insn)) + { + case 0: + return 248; /* lict */ + case 1: + return 250; /* sict */ + case 2: + return 249; /* licw */ + case 3: + return 251; /* sicw */ + case 8: + return 263; /* ldct */ + case 9: + return 262; /* sdct */ + case 14: + if (Field_t_Slot_inst_get (insn) == 0) + return 231; /* rfdo */ + if (Field_t_Slot_inst_get (insn) == 1) + return 232; /* rfdd */ + break; + } + break; + } + break; + case 3: + switch (Field_op2_Slot_inst_get (insn)) + { + case 0: + switch (Field_sr_Slot_inst_get (insn)) + { + case 0: + return 125; /* rsr.lbeg */ + case 1: + return 119; /* rsr.lend */ + case 2: + return 122; /* rsr.lcount */ + case 3: + return 128; /* rsr.sar */ + case 5: + return 131; /* rsr.litbase */ + case 72: + return 20; /* rsr.windowbase */ + case 73: + return 23; /* rsr.windowstart */ + case 96: + return 216; /* rsr.ibreakenable */ + case 104: + return 228; /* rsr.ddr */ + case 128: + return 210; /* rsr.ibreaka0 */ + case 129: + return 213; /* rsr.ibreaka1 */ + case 144: + return 198; /* rsr.dbreaka0 */ + case 145: + return 204; /* rsr.dbreaka1 */ + case 160: + return 201; /* rsr.dbreakc0 */ + case 161: + return 207; /* rsr.dbreakc1 */ + case 176: + return 134; /* rsr.176 */ + case 177: + return 139; /* rsr.epc1 */ + case 178: + return 145; /* rsr.epc2 */ + case 179: + return 151; /* rsr.epc3 */ + case 180: + return 157; /* rsr.epc4 */ + case 192: + return 175; /* rsr.depc */ + case 194: + return 163; /* rsr.eps2 */ + case 195: + return 166; /* rsr.eps3 */ + case 196: + return 169; /* rsr.eps4 */ + case 208: + return 135; /* rsr.208 */ + case 209: + return 142; /* rsr.excsave1 */ + case 210: + return 148; /* rsr.excsave2 */ + case 211: + return 154; /* rsr.excsave3 */ + case 212: + return 160; /* rsr.excsave4 */ + case 226: + return 190; /* rsr.interrupt */ + case 228: + return 193; /* rsr.intenable */ + case 230: + return 136; /* rsr.ps */ + case 232: + return 178; /* rsr.exccause */ + case 233: + return 219; /* rsr.debugcause */ + case 234: + return 233; /* rsr.ccount */ + case 235: + return 187; /* rsr.prid */ + case 236: + return 222; /* rsr.icount */ + case 237: + return 225; /* rsr.icountlevel */ + case 238: + return 172; /* rsr.excvaddr */ + case 240: + return 236; /* rsr.ccompare0 */ + case 241: + return 239; /* rsr.ccompare1 */ + case 242: + return 242; /* rsr.ccompare2 */ + case 244: + return 181; /* rsr.misc0 */ + case 245: + return 184; /* rsr.misc1 */ + } + break; + case 1: + switch (Field_sr_Slot_inst_get (insn)) + { + case 0: + return 126; /* wsr.lbeg */ + case 1: + return 120; /* wsr.lend */ + case 2: + return 123; /* wsr.lcount */ + case 3: + return 129; /* wsr.sar */ + case 5: + return 132; /* wsr.litbase */ + case 72: + return 21; /* wsr.windowbase */ + case 73: + return 24; /* wsr.windowstart */ + case 96: + return 217; /* wsr.ibreakenable */ + case 104: + return 229; /* wsr.ddr */ + case 128: + return 211; /* wsr.ibreaka0 */ + case 129: + return 214; /* wsr.ibreaka1 */ + case 144: + return 199; /* wsr.dbreaka0 */ + case 145: + return 205; /* wsr.dbreaka1 */ + case 160: + return 202; /* wsr.dbreakc0 */ + case 161: + return 208; /* wsr.dbreakc1 */ + case 177: + return 140; /* wsr.epc1 */ + case 178: + return 146; /* wsr.epc2 */ + case 179: + return 152; /* wsr.epc3 */ + case 180: + return 158; /* wsr.epc4 */ + case 192: + return 176; /* wsr.depc */ + case 194: + return 164; /* wsr.eps2 */ + case 195: + return 167; /* wsr.eps3 */ + case 196: + return 170; /* wsr.eps4 */ + case 209: + return 143; /* wsr.excsave1 */ + case 210: + return 149; /* wsr.excsave2 */ + case 211: + return 155; /* wsr.excsave3 */ + case 212: + return 161; /* wsr.excsave4 */ + case 226: + return 191; /* wsr.intset */ + case 227: + return 192; /* wsr.intclear */ + case 228: + return 194; /* wsr.intenable */ + case 230: + return 137; /* wsr.ps */ + case 232: + return 179; /* wsr.exccause */ + case 233: + return 220; /* wsr.debugcause */ + case 234: + return 234; /* wsr.ccount */ + case 236: + return 223; /* wsr.icount */ + case 237: + return 226; /* wsr.icountlevel */ + case 238: + return 173; /* wsr.excvaddr */ + case 240: + return 237; /* wsr.ccompare0 */ + case 241: + return 240; /* wsr.ccompare1 */ + case 242: + return 243; /* wsr.ccompare2 */ + case 244: + return 182; /* wsr.misc0 */ + case 245: + return 185; /* wsr.misc1 */ + } + break; + case 8: + return 89; /* moveqz */ + case 9: + return 90; /* movnez */ + case 10: + return 91; /* movltz */ + case 11: + return 92; /* movgez */ + } + break; + case 4: + case 5: + return 76; /* extui */ + case 9: + switch (Field_op2_Slot_inst_get (insn)) + { + case 0: + return 18; /* l32e */ + case 4: + return 19; /* s32e */ + } + break; + } break; - case 9: /* LSI4: op1=1001 */ - switch (get_op2_field (insn)) { - case 4: /* S32E: op2=0100 */ - return xtensa_s32e_op; - case 0: /* L32E: op2=0000 */ - return xtensa_l32e_op; - } + case 1: + return 83; /* l32r */ + case 2: + switch (Field_r_Slot_inst_get (insn)) + { + case 0: + return 84; /* l8ui */ + case 1: + return 80; /* l16ui */ + case 2: + return 82; /* l32i */ + case 4: + return 99; /* s8i */ + case 5: + return 97; /* s16i */ + case 6: + return 98; /* s32i */ + case 7: + switch (Field_t_Slot_inst_get (insn)) + { + case 0: + return 258; /* dpfr */ + case 1: + return 259; /* dpfw */ + case 2: + return 260; /* dpfro */ + case 3: + return 261; /* dpfwo */ + case 4: + return 252; /* dhwb */ + case 5: + return 253; /* dhwbi */ + case 6: + return 256; /* dhi */ + case 7: + return 257; /* dii */ + case 8: + switch (Field_op1_Slot_inst_get (insn)) + { + case 4: + return 254; /* diwb */ + case 5: + return 255; /* diwbi */ + } + break; + case 12: + return 245; /* ipf */ + case 14: + return 246; /* ihi */ + case 15: + return 247; /* iii */ + } + break; + case 9: + return 81; /* l16si */ + case 10: + return 88; /* movi */ + case 12: + return 37; /* addi */ + case 13: + return 38; /* addmi */ + } break; - case 4: /* EXTUI: op1=010x */ - case 5: /* EXTUI: op1=010x */ - return xtensa_extui_op; - case 0: /* RST0: op1=0000 */ - switch (get_op2_field (insn)) { - case 15: /* SUBX8: op2=1111 */ - return xtensa_subx8_op; - case 0: /* ST0: op2=0000 */ - switch (get_r_field (insn)) { - case 0: /* SNM0: r=0000 */ - switch (get_m_field (insn)) { - case 2: /* JR: m=10 */ - switch (get_n_field (insn)) { - case 0: /* RET: n=00 */ - return xtensa_ret_op; - case 1: /* RETW: n=01 */ - return xtensa_retw_op; - case 2: /* JX: n=10 */ - return xtensa_jx_op; - } - break; - case 3: /* CALLX: m=11 */ - switch (get_n_field (insn)) { - case 0: /* CALLX0: n=00 */ - return xtensa_callx0_op; - case 1: /* CALLX4: n=01 */ - return xtensa_callx4_op; - case 2: /* CALLX8: n=10 */ - return xtensa_callx8_op; - case 3: /* CALLX12: n=11 */ - return xtensa_callx12_op; - } - break; - } - break; - case 1: /* MOVSP: r=0001 */ - return xtensa_movsp_op; - case 2: /* SYNC: r=0010 */ - switch (get_s_field (insn)) { - case 0: /* SYNCT: s=0000 */ - switch (get_t_field (insn)) { - case 2: /* ESYNC: t=0010 */ - return xtensa_esync_op; - case 3: /* DSYNC: t=0011 */ - return xtensa_dsync_op; - case 8: /* EXCW: t=1000 */ - return xtensa_excw_op; - case 12: /* MEMW: t=1100 */ - return xtensa_memw_op; - case 0: /* ISYNC: t=0000 */ - return xtensa_isync_op; - case 1: /* RSYNC: t=0001 */ - return xtensa_rsync_op; - } - break; - } - break; - case 4: /* BREAK: r=0100 */ - return xtensa_break_op; - case 3: /* RFEI: r=0011 */ - switch (get_t_field (insn)) { - case 0: /* RFET: t=0000 */ - switch (get_s_field (insn)) { - case 2: /* RFDE: s=0010 */ - return xtensa_rfde_op; - case 4: /* RFWO: s=0100 */ - return xtensa_rfwo_op; - case 5: /* RFWU: s=0101 */ - return xtensa_rfwu_op; - case 0: /* RFE: s=0000 */ - return xtensa_rfe_op; - } - break; - case 1: /* RFI: t=0001 */ - return xtensa_rfi_op; - } - break; - case 5: /* SCALL: r=0101 */ - switch (get_s_field (insn)) { - case 0: /* SYSCALL: s=0000 */ - return xtensa_syscall_op; - case 1: /* SIMCALL: s=0001 */ - return xtensa_simcall_op; - } - break; - case 6: /* RSIL: r=0110 */ - return xtensa_rsil_op; - case 7: /* WAITI: r=0111 */ - return xtensa_waiti_op; - } - break; - case 1: /* AND: op2=0001 */ - return xtensa_and_op; - case 2: /* OR: op2=0010 */ - return xtensa_or_op; - case 3: /* XOR: op2=0011 */ - return xtensa_xor_op; - case 4: /* ST1: op2=0100 */ - switch (get_r_field (insn)) { - case 15: /* NSAU: r=1111 */ - return xtensa_nsau_op; - case 0: /* SSR: r=0000 */ - return xtensa_ssr_op; - case 1: /* SSL: r=0001 */ - return xtensa_ssl_op; - case 2: /* SSA8L: r=0010 */ - return xtensa_ssa8l_op; - case 3: /* SSA8B: r=0011 */ - return xtensa_ssa8b_op; - case 4: /* SSAI: r=0100 */ - return xtensa_ssai_op; - case 8: /* ROTW: r=1000 */ - return xtensa_rotw_op; - case 14: /* NSA: r=1110 */ - return xtensa_nsa_op; - } - break; - case 8: /* ADD: op2=1000 */ - return xtensa_add_op; - case 5: /* ST4: op2=0101 */ - switch (get_r_field (insn)) { - case 15: /* RDTLB1: r=1111 */ - return xtensa_rdtlb1_op; - case 0: /* IITLBA: r=0000 */ - return xtensa_iitlba_op; - case 3: /* RITLB0: r=0011 */ - return xtensa_ritlb0_op; - case 4: /* IITLB: r=0100 */ - return xtensa_iitlb_op; - case 8: /* IDTLBA: r=1000 */ - return xtensa_idtlba_op; - case 5: /* PITLB: r=0101 */ - return xtensa_pitlb_op; - case 6: /* WITLB: r=0110 */ - return xtensa_witlb_op; - case 7: /* RITLB1: r=0111 */ - return xtensa_ritlb1_op; - case 11: /* RDTLB0: r=1011 */ - return xtensa_rdtlb0_op; - case 12: /* IDTLB: r=1100 */ - return xtensa_idtlb_op; - case 13: /* PDTLB: r=1101 */ - return xtensa_pdtlb_op; - case 14: /* WDTLB: r=1110 */ - return xtensa_wdtlb_op; - } - break; - case 6: /* RT0: op2=0110 */ - switch (get_s_field (insn)) { - case 0: /* NEG: s=0000 */ - return xtensa_neg_op; - case 1: /* ABS: s=0001 */ - return xtensa_abs_op; - } - break; - case 9: /* ADDX2: op2=1001 */ - return xtensa_addx2_op; - case 10: /* ADDX4: op2=1010 */ - return xtensa_addx4_op; - case 11: /* ADDX8: op2=1011 */ - return xtensa_addx8_op; - case 12: /* SUB: op2=1100 */ - return xtensa_sub_op; - case 13: /* SUBX2: op2=1101 */ - return xtensa_subx2_op; - case 14: /* SUBX4: op2=1110 */ - return xtensa_subx4_op; - } + case 5: + switch (Field_n_Slot_inst_get (insn)) + { + case 0: + return 74; /* call0 */ + case 1: + return 7; /* call4 */ + case 2: + return 6; /* call8 */ + case 3: + return 5; /* call12 */ + } break; - case 1: /* RST1: op1=0001 */ - switch (get_op2_field (insn)) { - case 15: /* IMP: op2=1111 */ - switch (get_r_field (insn)) { - case 0: /* LICT: r=0000 */ - return xtensa_lict_op; - case 1: /* SICT: r=0001 */ - return xtensa_sict_op; - case 2: /* LICW: r=0010 */ - return xtensa_licw_op; - case 3: /* SICW: r=0011 */ - return xtensa_sicw_op; - case 8: /* LDCT: r=1000 */ - return xtensa_ldct_op; - case 9: /* SDCT: r=1001 */ - return xtensa_sdct_op; - } - break; - case 0: /* SLLI: op2=000x */ - case 1: /* SLLI: op2=000x */ - return xtensa_slli_op; - case 2: /* SRAI: op2=001x */ - case 3: /* SRAI: op2=001x */ - return xtensa_srai_op; - case 4: /* SRLI: op2=0100 */ - return xtensa_srli_op; - case 8: /* SRC: op2=1000 */ - return xtensa_src_op; - case 9: /* SRL: op2=1001 */ - return xtensa_srl_op; - case 6: /* XSR: op2=0110 */ - return xtensa_xsr_op; - case 10: /* SLL: op2=1010 */ - return xtensa_sll_op; - case 11: /* SRA: op2=1011 */ - return xtensa_sra_op; - } + case 6: + switch (Field_n_Slot_inst_get (insn)) + { + case 0: + return 78; /* j */ + case 1: + switch (Field_m_Slot_inst_get (insn)) + { + case 0: + return 70; /* beqz */ + case 1: + return 71; /* bnez */ + case 2: + return 73; /* bltz */ + case 3: + return 72; /* bgez */ + } + break; + case 2: + switch (Field_m_Slot_inst_get (insn)) + { + case 0: + return 50; /* beqi */ + case 1: + return 51; /* bnei */ + case 2: + return 53; /* blti */ + case 3: + return 52; /* bgei */ + } + break; + case 3: + switch (Field_m_Slot_inst_get (insn)) + { + case 0: + return 11; /* entry */ + case 1: + switch (Field_r_Slot_inst_get (insn)) + { + case 8: + return 85; /* loop */ + case 9: + return 86; /* loopnez */ + case 10: + return 87; /* loopgtz */ + } + break; + case 2: + return 57; /* bltui */ + case 3: + return 56; /* bgeui */ + } + break; + } break; - } - break; - case 1: /* L32R: op0=0001 */ - return xtensa_l32r_op; - case 2: /* LSAI: op0=0010 */ - switch (get_r_field (insn)) { - case 0: /* L8UI: r=0000 */ - return xtensa_l8ui_op; - case 1: /* L16UI: r=0001 */ - return xtensa_l16ui_op; - case 2: /* L32I: r=0010 */ - return xtensa_l32i_op; - case 4: /* S8I: r=0100 */ - return xtensa_s8i_op; - case 5: /* S16I: r=0101 */ - return xtensa_s16i_op; - case 9: /* L16SI: r=1001 */ - return xtensa_l16si_op; - case 6: /* S32I: r=0110 */ - return xtensa_s32i_op; - case 7: /* CACHE: r=0111 */ - switch (get_t_field (insn)) { - case 15: /* III: t=1111 */ - return xtensa_iii_op; - case 0: /* DPFR: t=0000 */ - return xtensa_dpfr_op; - case 1: /* DPFW: t=0001 */ - return xtensa_dpfw_op; - case 2: /* DPFRO: t=0010 */ - return xtensa_dpfro_op; - case 4: /* DHWB: t=0100 */ - return xtensa_dhwb_op; - case 3: /* DPFWO: t=0011 */ - return xtensa_dpfwo_op; - case 8: /* DCE: t=1000 */ - switch (get_op1_field (insn)) { - case 4: /* DIWB: op1=0100 */ - return xtensa_diwb_op; - case 5: /* DIWBI: op1=0101 */ - return xtensa_diwbi_op; - } - break; - case 5: /* DHWBI: t=0101 */ - return xtensa_dhwbi_op; - case 6: /* DHI: t=0110 */ - return xtensa_dhi_op; - case 7: /* DII: t=0111 */ - return xtensa_dii_op; - case 12: /* IPF: t=1100 */ - return xtensa_ipf_op; - case 14: /* IHI: t=1110 */ - return xtensa_ihi_op; - } + case 7: + switch (Field_r_Slot_inst_get (insn)) + { + case 0: + return 65; /* bnone */ + case 1: + return 58; /* beq */ + case 2: + return 61; /* blt */ + case 3: + return 63; /* bltu */ + case 4: + return 66; /* ball */ + case 5: + return 68; /* bbc */ + case 6: + case 7: + return 54; /* bbci */ + case 8: + return 64; /* bany */ + case 9: + return 59; /* bne */ + case 10: + return 60; /* bge */ + case 11: + return 62; /* bgeu */ + case 12: + return 67; /* bnall */ + case 13: + return 69; /* bbs */ + case 14: + case 15: + return 55; /* bbsi */ + } break; - case 10: /* MOVI: r=1010 */ - return xtensa_movi_op; - case 12: /* ADDI: r=1100 */ - return xtensa_addi_op; - case 13: /* ADDMI: r=1101 */ - return xtensa_addmi_op; - } - break; - case 8: /* L32I.N: op0=1000 */ - return xtensa_l32i_n_op; - case 5: /* CALL: op0=0101 */ - switch (get_n_field (insn)) { - case 0: /* CALL0: n=00 */ - return xtensa_call0_op; - case 1: /* CALL4: n=01 */ - return xtensa_call4_op; - case 2: /* CALL8: n=10 */ - return xtensa_call8_op; - case 3: /* CALL12: n=11 */ - return xtensa_call12_op; } - break; - case 6: /* SI: op0=0110 */ - switch (get_n_field (insn)) { - case 0: /* J: n=00 */ - return xtensa_j_op; - case 1: /* BZ: n=01 */ - switch (get_m_field (insn)) { - case 0: /* BEQZ: m=00 */ - return xtensa_beqz_op; - case 1: /* BNEZ: m=01 */ - return xtensa_bnez_op; - case 2: /* BLTZ: m=10 */ - return xtensa_bltz_op; - case 3: /* BGEZ: m=11 */ - return xtensa_bgez_op; - } - break; - case 2: /* BI0: n=10 */ - switch (get_m_field (insn)) { - case 0: /* BEQI: m=00 */ - return xtensa_beqi_op; - case 1: /* BNEI: m=01 */ - return xtensa_bnei_op; - case 2: /* BLTI: m=10 */ - return xtensa_blti_op; - case 3: /* BGEI: m=11 */ - return xtensa_bgei_op; - } - break; - case 3: /* BI1: n=11 */ - switch (get_m_field (insn)) { - case 0: /* ENTRY: m=00 */ - return xtensa_entry_op; - case 1: /* B1: m=01 */ - switch (get_r_field (insn)) { - case 8: /* LOOP: r=1000 */ - return xtensa_loop_op; - case 9: /* LOOPNEZ: r=1001 */ - return xtensa_loopnez_op; - case 10: /* LOOPGTZ: r=1010 */ - return xtensa_loopgtz_op; - } - break; - case 2: /* BLTUI: m=10 */ - return xtensa_bltui_op; - case 3: /* BGEUI: m=11 */ - return xtensa_bgeui_op; - } + return 0; +} + +static int +Slot_inst16b_decode (const xtensa_insnbuf insn) +{ + switch (Field_op0_Slot_inst16b_get (insn)) + { + case 12: + switch (Field_i_Slot_inst16b_get (insn)) + { + case 0: + return 33; /* movi.n */ + case 1: + switch (Field_z_Slot_inst16b_get (insn)) + { + case 0: + return 28; /* beqz.n */ + case 1: + return 29; /* bnez.n */ + } + break; + } break; - } - break; - case 9: /* S32I.N: op0=1001 */ - return xtensa_s32i_n_op; - case 10: /* ADD.N: op0=1010 */ - return xtensa_add_n_op; - case 7: /* B: op0=0111 */ - switch (get_r_field (insn)) { - case 6: /* BBCI: r=011x */ - case 7: /* BBCI: r=011x */ - return xtensa_bbci_op; - case 0: /* BNONE: r=0000 */ - return xtensa_bnone_op; - case 1: /* BEQ: r=0001 */ - return xtensa_beq_op; - case 2: /* BLT: r=0010 */ - return xtensa_blt_op; - case 4: /* BALL: r=0100 */ - return xtensa_ball_op; - case 14: /* BBSI: r=111x */ - case 15: /* BBSI: r=111x */ - return xtensa_bbsi_op; - case 3: /* BLTU: r=0011 */ - return xtensa_bltu_op; - case 5: /* BBC: r=0101 */ - return xtensa_bbc_op; - case 8: /* BANY: r=1000 */ - return xtensa_bany_op; - case 9: /* BNE: r=1001 */ - return xtensa_bne_op; - case 10: /* BGE: r=1010 */ - return xtensa_bge_op; - case 11: /* BGEU: r=1011 */ - return xtensa_bgeu_op; - case 12: /* BNALL: r=1100 */ - return xtensa_bnall_op; - case 13: /* BBS: r=1101 */ - return xtensa_bbs_op; - } - break; - case 11: /* ADDI.N: op0=1011 */ - return xtensa_addi_n_op; - case 12: /* ST2: op0=1100 */ - switch (get_i_field (insn)) { - case 0: /* MOVI.N: i=0 */ - return xtensa_movi_n_op; - case 1: /* BZ6: i=1 */ - switch (get_z_field (insn)) { - case 0: /* BEQZ.N: z=0 */ - return xtensa_beqz_n_op; - case 1: /* BNEZ.N: z=1 */ - return xtensa_bnez_n_op; - } + case 13: + switch (Field_r_Slot_inst16b_get (insn)) + { + case 0: + return 32; /* mov.n */ + case 15: + switch (Field_t_Slot_inst16b_get (insn)) + { + case 0: + return 35; /* ret.n */ + case 1: + return 15; /* retw.n */ + case 2: + return 197; /* break.n */ + case 3: + if (Field_s_Slot_inst16b_get (insn) == 0) + return 34; /* nop.n */ + break; + case 6: + return 30; /* ill.n */ + } + break; + } break; } - break; - case 13: /* ST3: op0=1101 */ - switch (get_r_field (insn)) { - case 15: /* S3: r=1111 */ - switch (get_t_field (insn)) { - case 0: /* RET.N: t=0000 */ - return xtensa_ret_n_op; - case 1: /* RETW.N: t=0001 */ - return xtensa_retw_n_op; - case 2: /* BREAK.N: t=0010 */ - return xtensa_break_n_op; - case 3: /* NOP.N: t=0011 */ - return xtensa_nop_n_op; - } - break; - case 0: /* MOV.N: r=0000 */ - return xtensa_mov_n_op; + return 0; +} + +static int +Slot_inst16a_decode (const xtensa_insnbuf insn) +{ + switch (Field_op0_Slot_inst16a_get (insn)) + { + case 8: + return 31; /* l32i.n */ + case 9: + return 36; /* s32i.n */ + case 10: + return 26; /* add.n */ + case 11: + return 27; /* addi.n */ } - break; - } - return XTENSA_UNDEFINED; + return 0; +} + + +/* Instruction slots. */ + +static void +Slot_x24_Format_inst_0_get (const xtensa_insnbuf insn, + xtensa_insnbuf slotbuf) +{ + slotbuf[0] = (insn[0] & 0xffffff); +} + +static void +Slot_x24_Format_inst_0_set (xtensa_insnbuf insn, + const xtensa_insnbuf slotbuf) +{ + insn[0] = (insn[0] & ~0xffffff) | (slotbuf[0] & 0xffffff); +} + +static void +Slot_x16a_Format_inst16a_0_get (const xtensa_insnbuf insn, + xtensa_insnbuf slotbuf) +{ + slotbuf[0] = ((insn[0] & 0xffff00) >> 8); +} + +static void +Slot_x16a_Format_inst16a_0_set (xtensa_insnbuf insn, + const xtensa_insnbuf slotbuf) +{ + insn[0] = (insn[0] & ~0xffff00) | ((slotbuf[0] & 0xffff) << 8); +} + +static void +Slot_x16b_Format_inst16b_0_get (const xtensa_insnbuf insn, + xtensa_insnbuf slotbuf) +{ + slotbuf[0] = ((insn[0] & 0xffff00) >> 8); +} + +static void +Slot_x16b_Format_inst16b_0_set (xtensa_insnbuf insn, + const xtensa_insnbuf slotbuf) +{ + insn[0] = (insn[0] & ~0xffff00) | ((slotbuf[0] & 0xffff) << 8); +} + +static xtensa_get_field_fn +Slot_inst_get_field_fns[] = { + Field_t_Slot_inst_get, + Field_bbi4_Slot_inst_get, + Field_bbi_Slot_inst_get, + Field_imm12_Slot_inst_get, + Field_imm8_Slot_inst_get, + Field_s_Slot_inst_get, + Field_imm12b_Slot_inst_get, + Field_imm16_Slot_inst_get, + Field_m_Slot_inst_get, + Field_n_Slot_inst_get, + Field_offset_Slot_inst_get, + Field_op0_Slot_inst_get, + Field_op1_Slot_inst_get, + Field_op2_Slot_inst_get, + Field_r_Slot_inst_get, + Field_sa4_Slot_inst_get, + Field_sae4_Slot_inst_get, + Field_sae_Slot_inst_get, + Field_sal_Slot_inst_get, + Field_sargt_Slot_inst_get, + Field_sas4_Slot_inst_get, + Field_sas_Slot_inst_get, + Field_sr_Slot_inst_get, + Field_st_Slot_inst_get, + Field_thi3_Slot_inst_get, + Field_imm4_Slot_inst_get, + Field_mn_Slot_inst_get, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Implicit_Field_ar0_get, + Implicit_Field_ar4_get, + Implicit_Field_ar8_get, + Implicit_Field_ar12_get +}; + +static xtensa_set_field_fn +Slot_inst_set_field_fns[] = { + Field_t_Slot_inst_set, + Field_bbi4_Slot_inst_set, + Field_bbi_Slot_inst_set, + Field_imm12_Slot_inst_set, + Field_imm8_Slot_inst_set, + Field_s_Slot_inst_set, + Field_imm12b_Slot_inst_set, + Field_imm16_Slot_inst_set, + Field_m_Slot_inst_set, + Field_n_Slot_inst_set, + Field_offset_Slot_inst_set, + Field_op0_Slot_inst_set, + Field_op1_Slot_inst_set, + Field_op2_Slot_inst_set, + Field_r_Slot_inst_set, + Field_sa4_Slot_inst_set, + Field_sae4_Slot_inst_set, + Field_sae_Slot_inst_set, + Field_sal_Slot_inst_set, + Field_sargt_Slot_inst_set, + Field_sas4_Slot_inst_set, + Field_sas_Slot_inst_set, + Field_sr_Slot_inst_set, + Field_st_Slot_inst_set, + Field_thi3_Slot_inst_set, + Field_imm4_Slot_inst_set, + Field_mn_Slot_inst_set, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set +}; + +static xtensa_get_field_fn +Slot_inst16a_get_field_fns[] = { + Field_t_Slot_inst16a_get, + 0, + 0, + 0, + 0, + Field_s_Slot_inst16a_get, + 0, + 0, + 0, + 0, + 0, + Field_op0_Slot_inst16a_get, + 0, + 0, + Field_r_Slot_inst16a_get, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Field_sr_Slot_inst16a_get, + Field_st_Slot_inst16a_get, + 0, + Field_imm4_Slot_inst16a_get, + 0, + Field_i_Slot_inst16a_get, + Field_imm6lo_Slot_inst16a_get, + Field_imm6hi_Slot_inst16a_get, + Field_imm7lo_Slot_inst16a_get, + Field_imm7hi_Slot_inst16a_get, + Field_z_Slot_inst16a_get, + Field_imm6_Slot_inst16a_get, + Field_imm7_Slot_inst16a_get, + Implicit_Field_ar0_get, + Implicit_Field_ar4_get, + Implicit_Field_ar8_get, + Implicit_Field_ar12_get +}; + +static xtensa_set_field_fn +Slot_inst16a_set_field_fns[] = { + Field_t_Slot_inst16a_set, + 0, + 0, + 0, + 0, + Field_s_Slot_inst16a_set, + 0, + 0, + 0, + 0, + 0, + Field_op0_Slot_inst16a_set, + 0, + 0, + Field_r_Slot_inst16a_set, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Field_sr_Slot_inst16a_set, + Field_st_Slot_inst16a_set, + 0, + Field_imm4_Slot_inst16a_set, + 0, + Field_i_Slot_inst16a_set, + Field_imm6lo_Slot_inst16a_set, + Field_imm6hi_Slot_inst16a_set, + Field_imm7lo_Slot_inst16a_set, + Field_imm7hi_Slot_inst16a_set, + Field_z_Slot_inst16a_set, + Field_imm6_Slot_inst16a_set, + Field_imm7_Slot_inst16a_set, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set +}; + +static xtensa_get_field_fn +Slot_inst16b_get_field_fns[] = { + Field_t_Slot_inst16b_get, + 0, + 0, + 0, + 0, + Field_s_Slot_inst16b_get, + 0, + 0, + 0, + 0, + 0, + Field_op0_Slot_inst16b_get, + 0, + 0, + Field_r_Slot_inst16b_get, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Field_sr_Slot_inst16b_get, + Field_st_Slot_inst16b_get, + 0, + Field_imm4_Slot_inst16b_get, + 0, + Field_i_Slot_inst16b_get, + Field_imm6lo_Slot_inst16b_get, + Field_imm6hi_Slot_inst16b_get, + Field_imm7lo_Slot_inst16b_get, + Field_imm7hi_Slot_inst16b_get, + Field_z_Slot_inst16b_get, + Field_imm6_Slot_inst16b_get, + Field_imm7_Slot_inst16b_get, + Implicit_Field_ar0_get, + Implicit_Field_ar4_get, + Implicit_Field_ar8_get, + Implicit_Field_ar12_get +}; + +static xtensa_set_field_fn +Slot_inst16b_set_field_fns[] = { + Field_t_Slot_inst16b_set, + 0, + 0, + 0, + 0, + Field_s_Slot_inst16b_set, + 0, + 0, + 0, + 0, + 0, + Field_op0_Slot_inst16b_set, + 0, + 0, + Field_r_Slot_inst16b_set, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + Field_sr_Slot_inst16b_set, + Field_st_Slot_inst16b_set, + 0, + Field_imm4_Slot_inst16b_set, + 0, + Field_i_Slot_inst16b_set, + Field_imm6lo_Slot_inst16b_set, + Field_imm6hi_Slot_inst16b_set, + Field_imm7lo_Slot_inst16b_set, + Field_imm7hi_Slot_inst16b_set, + Field_z_Slot_inst16b_set, + Field_imm6_Slot_inst16b_set, + Field_imm7_Slot_inst16b_set, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set, + Implicit_Field_set +}; + +static xtensa_slot_internal slots[] = { + { "Inst", "x24", 0, + Slot_x24_Format_inst_0_get, Slot_x24_Format_inst_0_set, + Slot_inst_get_field_fns, Slot_inst_set_field_fns, + Slot_inst_decode, "nop" }, + { "Inst16a", "x16a", 0, + Slot_x16a_Format_inst16a_0_get, Slot_x16a_Format_inst16a_0_set, + Slot_inst16a_get_field_fns, Slot_inst16a_set_field_fns, + Slot_inst16a_decode, "" }, + { "Inst16b", "x16b", 0, + Slot_x16b_Format_inst16b_0_get, Slot_x16b_Format_inst16b_0_set, + Slot_inst16b_get_field_fns, Slot_inst16b_set_field_fns, + Slot_inst16b_decode, "nop.n" } +}; + + +/* Instruction formats. */ + +static void +Format_x24_encode (xtensa_insnbuf insn) +{ + insn[0] = 0; +} + +static void +Format_x16a_encode (xtensa_insnbuf insn) +{ + insn[0] = 0x800000; } -int -interface_version (void) +static void +Format_x16b_encode (xtensa_insnbuf insn) { - return 3; + insn[0] = 0xc00000; } -static struct config_struct config_table[] = { - {"IsaMemoryOrder", "BigEndian"}, - {"PIFReadDataBits", "128"}, - {"PIFWriteDataBits", "128"}, - {"IsaCoprocessorCount", "0"}, - {"IsaUseBooleans", "0"}, - {"IsaUseDensityInstruction", "1"}, - {0, 0} +static int Format_x24_slots[] = { 0 }; + +static int Format_x16a_slots[] = { 1 }; + +static int Format_x16b_slots[] = { 2 }; + +static xtensa_format_internal formats[] = { + { "x24", 3, Format_x24_encode, 1, Format_x24_slots }, + { "x16a", 2, Format_x16a_encode, 1, Format_x16a_slots }, + { "x16b", 2, Format_x16b_encode, 1, Format_x16b_slots } }; -struct config_struct * get_config_table (void); -struct config_struct * -get_config_table (void) +static int +format_decoder (const xtensa_insnbuf insn) { - return config_table; + if ((insn[0] & 0x800000) == 0) + return 0; /* x24 */ + if ((insn[0] & 0xc00000) == 0x800000) + return 1; /* x16a */ + if ((insn[0] & 0xe00000) == 0xc00000) + return 2; /* x16b */ + return -1; } -xtensa_isa_module xtensa_isa_modules[] = { - { get_num_opcodes, get_opcodes, decode_insn, get_config_table }, - { 0, 0, 0, 0 } +static int length_table[16] = { + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 3, + 2, + 2, + 2, + 2, + 2, + 2, + -1, + -1 +}; + +static int +length_decoder (const char *insn) +{ + int op0 = (insn[0] >> 4) & 0xf; + return length_table[op0]; +} + + +/* Top-level ISA structure. */ + +xtensa_isa_internal xtensa_modules = { + 1 /* big-endian */, + 3 /* insn_size */, 0, + 3, formats, format_decoder, length_decoder, + 3, slots, + 39 /* num_fields */, + 70, operands, + 220, iclasses, + 276, opcodes, 0, + 1, regfiles, + NUM_STATES, states, 0, + NUM_SYSREGS, sysregs, 0, + { MAX_SPECIAL_REG, MAX_USER_REG }, { 0, 0 }, + 0, interfaces, 0, + 0, funcUnits, 0 }; |