OSDN Git Service

bfd ChangeLog
authorBob Wilson <bob.wilson@acm.org>
Fri, 8 Oct 2004 00:22:15 +0000 (00:22 +0000)
committerBob Wilson <bob.wilson@acm.org>
Fri, 8 Oct 2004 00:22:15 +0000 (00:22 +0000)
* 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.

gas ChangeLog

* config/tc-xtensa.c (absolute_literals_supported): New global flag.
(UNREACHABLE_MAX_WIDTH): Define.
(XTENSA_FETCH_WIDTH): Delete.
(cur_vinsn, xtensa_fetch_width, xt_saved_debug_type, past_xtensa_end,
prefer_const16, prefer_l32r): New global variables.
(LIT4_SECTION_NAME): Define.
(lit4_state struct): Add lit4_seg_name and lit4_seg fields.
(XTENSA_PROP_*, GET_XTENSA_PROP_*, SET_XTENSA_PROP_*): Define.
(frag_flags struct): New.
(xtensa_block_info struct): Move from tc-xtensa.h.  Add flags field.
(subseg_map struct): Add cur_total_freq and cur_target_freq fields.
(bitfield, bit_is_set, set_bit, clear_bit): Define.
(MAX_FORMATS): Define.
(op_placement_info struct, op_placement_table): New.
(O_pltrel, O_hi16, O_lo16): Define.
(directiveE enum): Rename directive_generics to directive_transform.
Delete directive_relax.  Add directive_schedule,
directive_absolute_literals, and directive_last_directive.
(directive_info): Rename "generics" to "transform".  Delete "relax".
Add "schedule" and "absolute-literals".
(directive_state): Adjust entries to match changes in directive_info.
(xtensa_relax_statesE, RELAX_IMMED_MAXSTEPS): Move to tc-xtensa.h.
(xtensa_const16_opcode, xtensa_movi_opcode, xtensa_movi_n_opcode,
xtensa_l32r_opcode, xtensa_nop_opcode, xtensa_rsr_lcount_opcode): New.
(xtensa_j_opcode, xtensa_rsr_opcode): Delete.
(align_only_targets, software_a0_b_retw_interlock,
software_avoid_b_j_loop_end, maybe_has_b_j_loop_end,
software_avoid_short_loop, software_avoid_close_loop_end,
software_avoid_all_short_loops, specific_opcode): Delete.
(warn_unaligned_branch_targets): New.
(workaround_a0_b_retw, workaround_b_j_loop_end, workaround_short_loop,
workaround_close_loop_end, workaround_all_short_loops): Default FALSE.
(option_[no_]link_relax, option_[no_]transform,
option_[no_]absolute_literals, option_warn_unaligned_targets,
option_prefer_l32r, option_prefer_const16, option_target_hardware):
New enum values.
(option_[no_]align_only_targets, option_literal_section_name,
option_text_section_name, option_data_section_name,
option_bss_section_name, option_eb, option_el): Delete.
(md_longopts): Add entries for: [no-]transform, [no-]absolute-literals,
warn-unaligned-targets, prefer-l32r, prefer-const16, [no-]link-relax,
and target-hardware.  Delete entries for [no-]target-align-only,
literal-section-name, text-section-name, data-section-name, and
bss-section-name.
(md_parse_option): Handle new options and remove old ones.  Accept but
ignore [no-]density options.  Warn for [no-]generics and [no-]relax
and treat them as [no-]transform.
(md_show_usage): Add new options and remove old ones.
(xtensa_setup_hw_workarounds): New.
(md_pseudo_table): Change "word" entry to use xtensa_elf_cons.  Add
"long", "short", "loc" and "frequency" entries.
(use_generics): Rename to ...
(use_transform): ... this function.  Add past_xtensa_end check.
(use_longcalls): Add past_xtensa_end check.
(code_density_available, can_relax): Delete.
(do_align_targets): New.
(get_directive): Accept dashes in directive names.  Warn about
[no-]generics and [no-]relax directives and treat them as
[no-]transform.
(xtensa_begin_directive): Call md_flush_pending_output only for some
directives.  Check for directives inside instruction bundles.  Warn
about deprecated ".begin literal" usage.  Warn and ignore [no-]density
directives.  Handle new directives.  Check generating_literals flag
for literal_prefix.
(xtensa_end_directive): Check for directives inside instruction
bundles.  Warn and ignore [no-]density directives.  Handle new
directives.  Call xtensa_set_frag_assembly_state.
(xtensa_loc_directive_seen, xtensa_dwarf2_directive_loc,
xtensa_dwarf2_emit_insn): New.
(xtensa_literal_position): Call md_flush_pending_output.  Do not check
use_literal_section flag.
(xtensa_literal_pseudo): Call md_flush_pending_output.  Handle absolute
literals.  Use xtensa_elf_cons to parse the expression.
(xtensa_literal_prefix): Do not check use_literal_section.  Support
".lit4" sections for absolute literals.  Change prefix convention to
replace ".text" (or ".t" in a linkonce section).  No need to call
subseg_set.
(xtensa_frequency_pseudo, xtensa_elf_cons, xtensa_elf_suffix): New.
(expression_end): Handle closing braces and colons.
(PLT_SUFFIX, plt_suffix): Delete.
(expression_maybe_register): Use new xtensa-isa.h functions.  Use
xtensa_elf_suffix instead of checking for plt suffix, and handle O_lo16
and O_hi16 expressions as well.
(tokenize_arguments): Handle closing braces and colons.
(parse_arguments): Use new xtensa-isa.h functions.  Handle "invisible"
operands and paired register syntax.
(get_invisible_operands): New.
(xg_translate_sysreg_op): Handle new Xtensa LX RSR/WSR/XSR syntax.  Use
new xtensa-isa.h functions.
(xtensa_translate_old_userreg_ops, xtensa_translate_zero_immed): New.
(xg_translate_idioms): Check if inside bundle.  Use use_transform.
Handle new Xtensa LX RSR/WSR/XSR syntax.  Remove code to widen density
instructions.  Use xtensa_translate_zero_immed.
(operand_is_immed, operand_is_pcrel_label): Delete.
(get_relaxable_immed): Use new xtensa-isa.h functions.
(get_opcode_from_buf): Add slot parameter.  Use new xtensa-isa.h
functions.
(xtensa_print_insn_table, print_vliw_insn): New.
(is_direct_call_opcode): Use new xtensa-isa.h functions.
(is_call_opcode, is_loop_opcode, is_conditional_branch_opcode,
is_branch_or_jump_opcode): Delete.
(is_movi_opcode, decode_reloc, encode_reloc, encode_alt_reloc): New.
(opnum_to_reloc, reloc_to_opnum): Delete.
(xtensa_insnbuf_set_operand, xtensa_insnbuf_get_operand): Use new
xtensa-isa.h functions.  Operate on one slot of an instruction.
(xtensa_insnbuf_set_immediate_field, is_negatable_branch,
xg_get_insn_size): Delete.
(xg_get_build_instr_size): Use xg_get_single_size.
(xg_is_narrow_insn, xg_is_single_relaxable_insn): Update calls to
xg_build_widen_table.  Use xg_get_single_size.
(xg_get_max_narrow_insn_size): Delete.
(xg_get_max_insn_widen_size, xg_get_max_insn_widen_literal_size,
xg_is_relaxable_insn): Update calls to xg_build_widen_table.  Use
xg_get_single_size.
(xg_build_to_insn): Record the loc field.  Handle OP_OPERAND_HI16U and
OP_OPERAND_LOW16U.  Check xg_valid_literal_expression.
(xg_expand_to_stack, xg_expand_narrow): Update calls to
xg_build_widen_table.  Use xg_get_single_size.
(xg_immeds_fit): Use new xtensa-isa.h functions.  Update call to
xg_check_operand.
(xg_symbolic_immeds_fit): Likewise.  Also handle O_lo16 and O_hi16, and
treat weak symbols conservatively.
(xg_check_operand): Use new xtensa-isa.h functions.
(is_dnrange): Delete.
(xg_assembly_relax): Inline previous calls to tinsn_copy.
(xg_finish_frag): Specify separate relax states for the frag and slot0.
(is_branch_jmp_to_next, xg_add_branch_and_loop_targets): Use new
xtensa-isa.h functions.
(xg_instruction_matches_option_term, xg_instruction_matches_or_options,
xg_instruction_matches_options): New.
(xg_instruction_matches_rule): Handle O_register expressions.  Call
xg_instruction_matches_options.
(transition_rule_cmp): New.
(xg_instruction_match): Update call to xg_build_simplify_table.
(xg_build_token_insn): Record loc fields.
(xg_simplify_insn): Check is_specific_opcode field and
density_supported flag.
(xg_expand_assembly_insn): Skip checking code_density_available.  Use
new xtensa-isa.h functions.  Call use_transform instead of can_relax.
(xg_assemble_literal): Add error handling for O_big.  Call
record_alignment.  Handle O_pltrel.
(xg_valid_literal_expression): New.
(xg_assemble_literal_space): Add slot parameter.  Remove call to
set_expr_symbol_offset.  Add call to record_alignment.  Update call to
xg_finish_frag.
(xg_emit_insn): Delete.
(xg_emit_insn_to_buf): Add format parameter.  Update calls to
xg_add_opcode_fix and xtensa_insnbuf_to_chars.
(xg_add_opcode_fix): Change opcode parameter to tinsn and add format
and slot parameters.  Handle new "alternate" relocations for absolute
literals and CONST16 instructions.  Check for bad uses of O_lo16 and
O_hi16.  Use new xtensa-isa.h functions.
(xg_assemble_tokens): Delete.
(is_register_writer): Use new xtensa-isa.h functions.
(is_bad_loopend_opcode): Check for xtensa_rsr_lcount_opcode instead of
old-style RSR from LCOUNT.
(next_frag_opcode): Delete.
(next_frag_opcode_is_loop, next_frag_format_size, frag_format_size,
update_next_frag_state): New.
(update_next_frag_nop_state): Delete.
(next_frag_pre_opcode_bytes): Use next_frag_opcode_is_loop.
(xtensa_mark_literal_pool_location): Check use_literal_section flag and
the state of the absolute-literals directive.  Add calls to
record_alignment and xtensa_set_frag_assembly_state.  Call
xtensa_switch_to_non_abs_literal_fragment instead of
xtensa_switch_to_literal_fragment.
(build_nop): New.
(assemble_nop): Use build_nop.  Update call to xtensa_insnbuf_to_chars.
(get_expanded_loop_offset): Change check for undefined opcode to an
assertion.
(xtensa_set_frag_assembly_state, relaxable_section,
xtensa_find_unmarked_state_frags, xtensa_find_unaligned_branch_targets,
xtensa_find_unaligned_loops, xg_apply_tentative_value): New.
(md_begin): Update call to xtensa_isa_init.  Initialize linkrelax to 1.
Set lit4_seg_name.  Call xg_init_vinsn.  Initialize new global opcodes.
Call init_op_placement_info_table and xtensa_set_frag_assembly_state.
(xtensa_init_fix_data): New.
(xtensa_frob_label): Reset label symbol to the current frag.  Check
do_align_targets and generating_literals flag.  Propagate frequency
info to new alignment frag.  Call xtensa_set_frag_assembly_state.
(xtensa_unrecognized_line): New.
(xtensa_flush_pending_output): Check if inside a bundle.  Add a call
to xtensa_set_frag_assembly_state.
(error_reset_cur_vinsn): New.
(md_assemble): Remove check for literal frag.  Remove call to
istack_init.  Call use_transform instead of use_generics.  Parse
explicit instruction format specifiers.  Move code for
a0_b_retw_interlock workaround to xg_assemble_vliw_tokens.  Call
error_reset_cur_vinsn on errors.  Add call to get_invisible_operands.
Add dwarf2_where call.  Remote automatic alignment for ENTRY
instructions.  Move call to xtensa_clear_insn_labels to the end.
Rearrange to handle bundles.
(xtensa_cons_fix_new): Delete.
(xtensa_handle_align): New.
(xtensa_frag_init): Call xtensa_set_frag_assembly_state.  Remove
assignment to is_no_density field.
(md_pcrel_from): Use new xtensa-isa.h functions.  Use decode_reloc
instead of reloc_to_opnum.  Handle "alternate" relocations.
(xtensa_force_relocation, xtensa_check_inside_bundle,
xtensa_elf_section_change_hook): New.
(xtensa_symbol_new_hook): Delete.
(xtensa_fix_adjustable): Check for difference of symbols with an
offset.  Check for external and weak symbols.
(md_apply_fix3): Remove cases for XTENSA_OP{0,1,2} relocs.
(md_estimate_size_before_relax): Return expansion for the first slot.
(tc_gen_reloc): Handle difference of symbols by producing
XTENSA_DIFF{8,16,32} relocs and by writing the value of the difference
into the output.  Handle new XTENSA_SLOT*_OP relocs by storing the
tentative values into the output when linkrelax is set.
(XTENSA_PROP_SEC_NAME): Define.
(xtensa_post_relax_hook): Call xtensa_find_unmarked_state_frags.
Create literal tables only if using literal sections.  Create new
property tables instead of old instruction tables.  Check for unaligned
branch targets and loops.
(finish_vinsn, find_vinsn_conflicts, check_t1_t2_reads_and_writes,
new_resource_table, clear_resource_table, resize_resource_table,
resources_available, reserve_resources, release_resources,
opcode_funcUnit_use_unit, opcode_funcUnit_use_stage,
resources_conflict, xg_find_narrowest_format, relaxation_requirements,
bundle_single_op, emit_single_op, xg_assemble_vliw_tokens): New.
(xtensa_end): Call xtensa_flush_pending_output.  Set past_xtensa_end
flag.  Update checks for workaround options.  Call
xtensa_mark_narrow_branches and xtensa_mark_zcl_first_insns.
(xtensa_cleanup_align_frags): Add special case for branch targets.
Check for and mark unreachable frags.
(xtensa_fix_target_frags): Remove use of align_only_targets flag.
Use RELAX_LOOP_END_BYTES in special case for negatable branch at the
end of a zero-overhead loop body.
(frag_can_negate_branch): Handle instructions with multiple slots.
Use new xtensa-isa.h functions
(xtensa_mark_narrow_branches, is_narrow_branch_guaranteed_in_range,
xtensa_mark_zcl_first_insns): New.
(xtensa_fix_a0_b_retw_frags, xtensa_fix_b_j_loop_end_frags): Error if
transformations are disabled.
(next_instrs_are_b_retw): Use new xtensa-isa.h functions.  Handle
multislot instructions.
(xtensa_fix_close_loop_end_frags, xtensa_fix_short_loop_frags):
Likewise.  Also error if transformations are disabled.
(unrelaxed_frag_max_size): New.
(unrelaxed_frag_min_insn_count, unrelax_frag_has_b_j): Use new
xtensa-isa.h functions.
(xtensa_sanity_check, is_empty_loop, is_local_forward_loop): Use
xtensa_opcode_is_loop instead of is_loop_opcode.
(get_text_align_power): Replace as_fatal with assertion.
(get_text_align_fill_size): Iterate instead of using modulus when
use_nops is false.
(get_noop_aligned_address): Assert that this is for a machine-dependent
RELAX_ALIGN_NEXT_OPCODE frag.  Use next_frag_opcode_is_loop,
xg_get_single_size, and frag_format_size.
(get_widen_aligned_address): Rename to ...
(get_aligned_diff): ... this function.  Add max_diff parameter.
Remove handling of rs_align/rs_align_code frags.  Use
next_frag_format_size, get_text_align_power, get_text_align_fill_size,
next_frag_opcode_is_loop, and xg_get_single_size.  Compute max_diff
and pass it back to caller.
(xtensa_relax_frag): Use relax_frag_loop_align.  Add code for new
RELAX_SLOTS, RELAX_MAYBE_UNREACHABLE, RELAX_MAYBE_DESIRE_ALIGN,
RELAX_FILL_NOP, and RELAX_UNREACHABLE frag types.  Check relax_seen.
(relax_frag_text_align): Rename to ...
(relax_frag_loop_align): ... this function.  Assume loops can only be
in the first slot of an instruction.
(relax_frag_add_nop): Use assemble_nop instead of constructing an OR
instruction.  Remove call to frag_wane.
(relax_frag_narrow): Rename to ...
(relax_frag_for_align): ... this function.  Extend to handle
RELAX_FILL_NOP and RELAX_UNREACHABLE, as well as RELAX_SLOTS with
RELAX_NARROW for the first slot.
(find_address_of_next_align_frag, bytes_to_stretch): New.
(future_alignment_required): Use find_address_of_next_align_frag and
bytes_to_stretch.  Look ahead to subsequent frags to make smarter
alignment decisions.
(relax_frag_immed): Add format, slot, and estimate_only parameters.
Check if transformations are enabled for b_j_loop_end workaround.
Use new xtensa-isa.h functions and handle multislot instructions.
Update call to xg_assembly_relax.
(md_convert_frag): Handle new RELAX_SLOTS, RELAX_UNREACHABLE,
RELAX_MAYBE_UNREACHABLE, RELAX_MAYBE_DESIRE_ALIGN, and RELAX_FILL_NOP
frag types.
(convert_frag_narrow): Add segP, format and slot parameters.  Call
convert_frag_immed for branch instructions.  Adjust calls to
tinsn_from_chars, tinsn_immed_from_frag, and xg_emit_insn_to_buf.  Use
xg_get_single_size and xg_get_single_format.
(convert_frag_fill_nop): New.
(convert_frag_immed): Add format and slot parameters.  Handle multislot
instructions and use new xtensa-isa.h functions.  Update calls to
tinsn_immed_from_frag and xg_assembly_relax.  Check if transformations
enabled for b_j_loop_end workaround.  Use build_nop instead of
assemble_nop.  Check is_specific_opcode flag.  Check for unreachable
frags.  Use xg_get_single_size.  Handle O_pltrel.
(fix_new_exp_in_seg): Remove check for old plt flag.
(convert_frag_immed_finish_loop): Update calls to tinsn_from_chars and
xtensa_insnbuf_to_chars.  Call tinsn_immed_from_frag.  Change check
for loop opcode to an assertion.  Mark all frags up to the end of the
loop as not transformable.
(get_last_insn_flags, set_last_insn_flags): Use get_subseg_info.
(get_subseg_info): New.
(xtensa_move_literals): Call xtensa_set_frag_assembly_state.  Add null
check for dest_seg.
(xtensa_switch_to_literal_fragment): Rewrite to handle absolute
literals and use xtensa_switch_to_non_abs_literal_fragment otherwise.
(xtensa_switch_to_non_abs_literal_fragment): New.
(cache_literal_section): Add is_code parameter and pass it through to
retrieve_literal_seg.
(retrieve_literal_seg): Add is_code parameter and use it to set the
flags on the literal section.  Handle case where head parameter is 0.
(get_frag_is_no_transform, set_frag_is_specific_opcode,
set_frag_is_no_transform): New.
(xtensa_create_property_segments): Add end_property_function parameter
and pass it through to add_xt_block_frags.  Call bfd_get_section_flags
and skip SEC_DEBUGGING and !SEC_ALLOC sections.
(xtensa_create_xproperty_segments, section_has_xproperty): New.
(add_xt_block_frags): Add end_property_function parameter and call it
if it is non-zero.  Call xtensa_frag_flags_init.
(xtensa_frag_flags_is_empty, xtensa_frag_flags_init,
get_frag_property_flags, frag_flags_to_number,
xtensa_frag_flags_combinable, xt_block_aligned_size,
xtensa_xt_block_combine, add_xt_prop_frags,
init_op_placement_info_table, opcode_fits_format_slot,
xg_get_single_size, xg_get_single_format): New.
(istack_push): Inline call to tinsn_copy.
(tinsn_copy): Delete.
(tinsn_has_invalid_symbolic_operands): Handle O_hi16 and O_lo16 and
CONST16 opcodes.  Handle O_big, O_illegal, and O_absent.
(tinsn_has_complex_operands): Handle O_hi16 and O_lo16.
(tinsn_to_insnbuf): Use xg_get_single_format and new xtensa-isa.h
functions.  Handle invisible operands.
(tinsn_to_slotbuf): New.
(tinsn_check_arguments): Use new xtensa-isa.h functions.
(tinsn_from_chars): Add slot parameter.  Rewrite using xg_init_vinsn,
vinsn_from_chars, and xg_free_vinsn.
(tinsn_from_insnbuf): New.
(tinsn_immed_from_frag): Add slot parameter and handle multislot
instructions.  Handle symbol differences.
(get_num_stack_text_bytes): Use xg_get_single_size.
(xg_init_vinsn, xg_clear_vinsn, vinsn_has_specific_opcodes,
xg_free_vinsn, vinsn_to_insnbuf, vinsn_from_chars, expr_is_register,
get_expr_register, set_expr_symbol_offset_diff): New.
* config/tc-xtensa.h (MAX_SLOTS): Define.
(xtensa_relax_statesE): Move from tc-xtensa.c. Add
RELAX_CHECK_ALIGN_NEXT_OPCODE, RELAX_MAYBE_DESIRE_ALIGN, RELAX_SLOTS,
RELAX_FILL_NOP, RELAX_UNREACHABLE, RELAX_MAYBE_UNREACHABLE, and
RELAX_NONE types.
(RELAX_IMMED_MAXSTEPS): Move from tc-xtensa.c.
(xtensa_frag_type struct): Add is_assembly_state_set,
use_absolute_literals, relax_seen, is_unreachable, is_specific_opcode,
is_align, is_text_align, alignment, and is_first_loop_insn fields.
Replace is_generics and is_relax fields by is_no_transform field.
Delete is_text and is_longcalls fields.  Change text_expansion and
literal_expansion to arrays of MAX_SLOTS entries.  Add arrays of
per-slot information: literal_frags, slot_subtypes, slot_symbols,
slot_sub_symbols, and slot_offsets.  Add fr_prev field.
(xtensa_fix_data struct): New.
(xtensa_symfield_type struct): Delete plt field.
(xtensa_block_info struct): Move definition to tc-xtensa.h.  Add
forward declaration here.
(xt_section_type enum): Delete xt_insn_sec.  Add xt_prop_sec.
(XTENSA_SECTION_RENAME): Undefine.
(TC_FIX_TYPE, TC_INIT_FIX_DATA, TC_FORCE_RELOCATION, NO_PSEUDO_DOT,
tc_unrecognized_line, md_do_align, md_elf_section_change_hook,
HANDLE_ALIGN, TC_LINKRELAX_FIXUP, SUB_SEGMENT_ALIGN): Define.
(TC_CONS_FIX_NEW, tc_symbol_new_hook): Delete.
(unit_num_copies_func, opcode_num_units_func,
opcode_funcUnit_use_unit_func, opcode_funcUnit_use_stage_func): New.
(resource_table struct): New.
* config/xtensa-istack.h (MAX_INSN_ARGS): Increase from 6 to 10.
(TInsn struct): Add keep_wide, loc, fixup, record_fix, subtype,
literal_space, symbol, sub_symbol, offset, and literal_frag fields.
(tinsn_copy): Delete prototype.
(vliw_insn struct): New.
* config/xtensa-relax.c (insn_pattern_struct): Add options field.
(widen_spec_list): Add option conditions for density and boolean
instructions.  Add expansions using CONST16 and conditions for using
CONST16 vs. L32R.  Use new Xtensa LX RSR/WSR syntax.  Add entries for
predicted branches.
(simplify_spec_list): Add option conditions for density instructions.
Add entry for NOP instruction.
(append_transition): Add cmp function pointer parameter and use it to
insert the new entry in order.
(operand_function_LOW16U, operand_function_HI16U): New.
(xg_has_userdef_op_fn, xg_apply_userdef_op_fn): Handle
OP_OPERAND_LOW16U and OP_OPERAND_HI16U.
(enter_opname, split_string): Use xstrdup instead of strdup.
(init_insn_pattern): Initialize new options field.
(clear_req_or_option_list, clear_req_option_list,
clone_req_or_option_list, clone_req_option_list, parse_option_cond):
New.
(parse_insn_pattern): Parse option conditions.
(transition_applies): New.
(build_transition): Use new xtensa-isa.h functions.  Fix incorrectly
swapped last arguments in calls to append_constant_value_condition.
Call clone_req_option_list.  Add warning about invalid opcode.
Handle LOW16U and HI16U function names.
(build_transition_table): Add cmp parameter and use it in calls to
append_transition.  Use new xtensa-isa.h functions.  Check
transition_applies before adding entries.
(xg_build_widen_table, xg_build_simplify_table): Add cmp parameter and
pass it through to build_transition_table.
* config/xtensa-relax.h (ReqOrOptionList, ReqOrOption, ReqOptionList,
ReqOption, transition_cmp_fn): New types.
(OpType enum): Add OP_OPERAND_LOW16U and OP_OPERAND_HI16U.
(transition_rule struct): Add options field.
* doc/as.texinfo (Overview): Update Xtensa options.
* doc/c-xtensa.texi (Xtensa Options): Delete --[no-]density,
--[no-]relax, and --[no-]generics options.  Update descriptions of
--text-section-literals and --[no-]longcalls.  Add
--[no-]absolute-literals and --[no-]transform.
(Xtensa Syntax): Add description of syntax for FLIX instructions.
Remove use of "generic" and "specific" terminology for opcodes.
(Xtensa Registers): Generalize the syntax description to include
user-defined register files.
(Xtensa Automatic Alignment): Update.
(Xtensa Branch Relaxation): Mention limitation of unconditional jumps.
(Xtensa Call Relaxation): Linker can now remove most of the overhead.
(Xtensa Directives): Remove confusing rules about precedence.
(Density Directive, Relax Directive): Delete.
(Schedule Directive): New.
(Generics Directive): Rename to ...
(Transform Directive): ... this node.
(Literal Directive): Update for absolute literals.  Missing
literal_position directive is now an error.
(Literal Position Directive): Update for absolute literals.
(Freeregs Directive): Delete.
(Absolute Literals Directive): New.
(Frame Directive): Minor editing.
* Makefile.am (DEPTC_xtensa_elf, DEPOBJ_xtensa_elf, DEP_xtensa_elf):
Update dependencies.
* Makefile.in: Regenerate.

gas/testsuite ChangeLog

* gas/xtensa/all.exp: Adjust expected error message for j_too_far.
Change entry_align test to expect an error.
* gas/xtensa/entry_misalign2.s: Use no-transform instead of
no-generics directives.

include ChangeLog

* xtensa-config.h (XSHAL_USE_ABSOLUTE_LITERALS,
XCHAL_HAVE_PREDICTED_BRANCHES, XCHAL_INST_FETCH_WIDTH): New.
(XCHAL_EXTRA_SA_SIZE, XCHAL_EXTRA_SA_ALIGN): Delete.
* xtensa-isa-internal.h (ISA_INTERFACE_VERSION): Delete.
(config_sturct struct): Delete.
(XTENSA_OPERAND_IS_REGISTER, XTENSA_OPERAND_IS_PCRELATIVE,
XTENSA_OPERAND_IS_INVISIBLE, XTENSA_OPERAND_IS_UNKNOWN,
XTENSA_OPCODE_IS_BRANCH, XTENSA_OPCODE_IS_JUMP,
XTENSA_OPCODE_IS_LOOP, XTENSA_OPCODE_IS_CALL,
XTENSA_STATE_IS_EXPORTED, XTENSA_INTERFACE_HAS_SIDE_EFFECT): Define.
(xtensa_format_encode_fn, xtensa_get_slot_fn, xtensa_set_slot_fn): New.
(xtensa_insn_decode_fn): Rename to ...
(xtensa_opcode_decode_fn): ... this.
(xtensa_immed_decode_fn, xtensa_immed_encode_fn, xtensa_do_reloc_fn,
xtensa_undo_reloc_fn): Update.
(xtensa_encoding_template_fn): Delete.
(xtensa_opcode_encode_fn, xtensa_format_decode_fn,
xtensa_length_decode_fn): New.
(xtensa_format_internal, xtensa_slot_internal): New types.
(xtensa_operand_internal): Delete operand_kind, inout, isPCRelative,
get_field, and set_field fields.  Add name, field_id, regfile,
num_regs, and flags fields.
(xtensa_arg_internal): New type.
(xtensa_iclass_internal): Change operands field to array of
xtensa_arg_internal.  Add num_stateOperands, stateOperands,
num_interfaceOperands, and interfaceOperands fields.
(xtensa_opcode_internal): Delete length, template, and iclass fields.
Add iclass_id, flags, encode_fns, num_funcUnit_uses, and funcUnit_uses.
(opname_lookup_entry): Delete.
(xtensa_regfile_internal, xtensa_interface_internal,
xtensa_funcUnit_internal, xtensa_state_internal,
xtensa_sysreg_internal, xtensa_lookup_entry): New.
(xtensa_isa_internal): Replace opcode_table field with opcodes field.
Change type of opname_lookup_table.  Delete num_modules,
module_opcode_base, module_decode_fn, config, and has_density fields.
Add num_formats, formats, format_decode_fn, length_decode_fn,
num_slots, slots, num_fields, num_operands, operands, num_iclasses,
iclasses, num_regfiles, regfiles, num_states, states,
state_lookup_table, num_sysregs, sysregs, sysreg_lookup_table,
max_sysreg_num, sysreg_table, num_interfaces, interfaces,
interface_lookup_table, num_funcUnits, funcUnits and
funcUnit_lookup_table fields.
(xtensa_isa_module, xtensa_isa_modules): Delete.
(xtensa_isa_name_compare): New prototype.
(xtisa_errno, xtisa_error_msg): New.
* xtensa-isa.h (XTENSA_ISA_VERSION): Define.
(xtensa_isa): Change type.
(xtensa_operand): Delete.
(xtensa_format, xtensa_regfile, xtensa_state, xtensa_sysreg,
xtensa_interface, xtensa_funcUnit, xtensa_isa_status,
xtensa_funcUnit_use): New types.
(libisa_module_specifier): Delete.
(xtensa_isa_errno, xtensa_isa_error_msg): New prototypes.
(xtensa_insnbuf_free, xtensa_insnbuf_to_chars,
xtensa_insnbuf_from_chars): Update prototypes.
(xtensa_load_isa, xtensa_extend_isa, xtensa_default_isa,
xtensa_insn_maxlength, xtensa_num_opcodes, xtensa_decode_insn,
xtensa_encode_insn, xtensa_insn_length,
xtensa_insn_length_from_first_byte, xtensa_num_operands,
xtensa_operand_kind, xtensa_encode_result,
xtensa_operand_isPCRelative): Delete.
(xtensa_isa_init, xtensa_operand_inout, xtensa_operand_get_field,
xtensa_operand_set_field, xtensa_operand_encode,
xtensa_operand_decode, xtensa_operand_do_reloc,
xtensa_operand_undo_reloc): Update prototypes.
(xtensa_isa_maxlength, xtensa_isa_length_from_chars,
xtensa_isa_num_pipe_stages, xtensa_isa_num_formats,
xtensa_isa_num_opcodes, xtensa_isa_num_regfiles, xtensa_isa_num_states,
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, xtensa_opcode_decode,
xtensa_opcode_encode, xtensa_opcode_is_branch, xtensa_opcode_is_jump,
xtensa_opcode_is_loop, xtensa_opcode_is_call,
xtensa_opcode_num_operands, xtensa_opcode_num_stateOperands,
xtensa_opcode_num_interfaceOperands, xtensa_opcode_num_funcUnit_uses,
xtensa_opcode_funcUnit_use, xtensa_operand_name,
xtensa_operand_is_visible, xtensa_operand_is_register,
xtensa_operand_regfile, xtensa_operand_num_regs,
xtensa_operand_is_known_reg, xtensa_operand_is_PCrelative,
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 prototypes.
* elf/xtensa.h (R_XTENSA_DIFF8, R_XTENSA_DIFF16, R_XTENSA_DIFF32,
R_XTENSA_SLOT*_OP, R_XTENSA_SLOT*_ALT): New relocations.
(XTENSA_PROP_SEC_NAME): Define.
(property_table_entry): Add flags field.
(XTENSA_PROP_*, GET_XTENSA_PROP_*, SET_XTENSA_PROP_*): Define.

ld ChangeLog

* ld.texinfo (Xtensa): Describe new linker relaxation to optimize
assembler-generated longcall sequences.  Describe new --size-opt
option.
* emulparams/elf32xtensa.sh (OTHER_SECTIONS): Add .xt.prop section.
* emultempl/xtensaelf.em (remove_section,
replace_insn_sec_with_prop_sec, replace_instruction_table_sections,
elf_xtensa_after_open): New.
(OPTION_OPT_SIZEOPT, OPTION_LITERAL_MOVEMENT,
OPTION_NO_LITERAL_MOVEMENT): Define.
(elf32xtensa_size_opt, elf32xtensa_no_literal_movement): New globals.
(PARSE_AND_LIST_LONGOPTS): Add size-opt and [no-]literal-movement.
(PARSE_AND_LIST_OPTIONS): Add --size-opt.
(PARSE_AND_LIST_ARGS_CASES): Handle OPTION_OPT_SIZEOPT,
OPTION_LITERAL_MOVEMENT, and OPTION_NO_LITERAL_MOVEMENT.
(LDEMUL_AFTER_OPEN): Set to elf_xtensa_after_open.
* scripttempl/elfxtensa.sc: Update with changes from elf.sc.
* Makefile.am (eelf32xtensa.c): Update dependencies.
* Makefile.in: Regenerate.

ld/testsuite ChangeLog

* ld-xtensa/lcall1.s: Use .literal directive.
* ld-xtensa/lcall2.s: Align function entry.
* ld-xtensa/coalesce2.s: Likewise.

opcodes ChangeLog

* xtensa-dis.c (state_names): Delete.
(fetch_data): Use xtensa_isa_maxlength.
(print_xtensa_operand): Replace operand parameter with opcode/operand
pair.  Remove print_sr_name parameter.  Use new xtensa-isa.h functions.
(print_insn_xtensa): Use new xtensa-isa.h functions.  Handle multislot
instruction bundles.  Use xmalloc instead of malloc.

16 files changed:
bfd/ChangeLog
bfd/Makefile.am
bfd/Makefile.in
bfd/bfd-in2.h
bfd/elf32-xtensa.c
bfd/libbfd.h
bfd/reloc.c
bfd/xtensa-isa.c
bfd/xtensa-modules.c
include/ChangeLog
include/elf/xtensa.h
include/xtensa-config.h
include/xtensa-isa-internal.h
include/xtensa-isa.h
opcodes/ChangeLog
opcodes/xtensa-dis.c

index eefb123..df81821 100644 (file)
@@ -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
index a7eabfc..966aff3 100644 (file)
@@ -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 \
index ac92e49..5a551cd 100644 (file)
@@ -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 \
index 6feb83e..2e851a9 100644 (file)
@@ -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,
index 0755e09..09ef0e1 100644 (file)
 #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;
+
 \f
 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.... */
+
+         /* 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;
+           }
+
+         if (!howto->pc_relative)
+           {
+             *error_message = "expected PC-relative relocation";
+             return bfd_reloc_dangerous;
+           }
 
-  /* 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);
+         /* Calculate the PC address for this instruction.  */
+         self_address = (input_section->output_section->vma
+                         + input_section->output_offset
+                         + address);
 
-  /* Write the modified instruction back out of the buffer.  */
-  xtensa_insnbuf_to_chars (isa, ibuff, contents + address);
-  free (ibuff);
+         newval = relocation;
+       }
+    }
 
-  if (encode_result != xtensa_encode_result_ok)
+  /* 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,1494 +3365,4157 @@ 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 ());
 }
 
-\f
-/* Code for transforming CALLs at link-time.  */
 
-static bfd_reloc_status_type
-elf_xtensa_do_asm_simplify (contents, address, content_length)
+static bfd_size_type
+get_asm_simplify_size (contents, content_len, offset)
      bfd_byte *contents;
-     bfd_vma address;
-     bfd_vma content_length;
+     bfd_size_type content_len;
+     bfd_size_type offset;
 {
-  static xtensa_insnbuf insnbuf = NULL;
-  xtensa_opcode opcode;
-  xtensa_operand operand;
-  xtensa_opcode direct_call_opcode;
-  xtensa_isa isa = xtensa_default_isa;
-  bfd_byte *chbuf = contents + address;
-  int opn;
+  bfd_size_type insnlen, size = 0;
 
-  if (insnbuf == NULL)
-    insnbuf = xtensa_insnbuf_alloc (isa);
+  /* Decode the size of the next two instructions.  */
+  insnlen = insn_decode_len (contents, content_len, offset);
+  if (insnlen == 0)
+    return 0;
 
-  if (content_length < address)
-    {
-      (*_bfd_error_handler)
-       ("Attempt to convert L32R/CALLX to CALL failed");
-      return bfd_reloc_other;
-    }
-
-  opcode = get_expanded_call_opcode (chbuf, content_length - address);
-  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");
-      return bfd_reloc_other;
-    }
+  size += insnlen;
   
-  /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset.  */
-  opcode = xtensa_opcode_lookup (isa, "or");
-  xtensa_encode_insn (isa, opcode, insnbuf);
-  for (opn = 0; opn < 3; opn++) 
-    {
-      operand = xtensa_get_operand (isa, opcode, opn);
-      xtensa_operand_set_field (operand, insnbuf, 1);
-    }
-  xtensa_insnbuf_to_chars (isa, insnbuf, chbuf);
+  insnlen = insn_decode_len (contents, content_len, offset + size);
+  if (insnlen == 0)
+    return 0;
 
-  /* 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);
+  size += insnlen;
+  return size;
+}
 
-  return bfd_reloc_ok;
+
+bfd_boolean
+is_alt_relocation (r_type)
+     int r_type;
+{
+  return (r_type >= R_XTENSA_SLOT0_ALT
+         && r_type <= R_XTENSA_SLOT14_ALT);
 }
 
 
-static bfd_reloc_status_type
-contract_asm_expansion (contents, content_length, irel)
-     bfd_byte *contents;
-     bfd_vma content_length;
-     Elf_Internal_Rela *irel;
+bfd_boolean
+is_operand_relocation (r_type)
+     int r_type;
 {
-  bfd_reloc_status_type retval =
-    elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length);
+  switch (r_type)
+    {
+    case R_XTENSA_OP0:
+    case R_XTENSA_OP1:
+    case R_XTENSA_OP2:
+      return TRUE;
 
-  if (retval != bfd_reloc_ok)
-    return retval;
+    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;
+    }
 
-  /* 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);
-  return bfd_reloc_ok;
+  return FALSE;
 }
 
+      
+#define MIN_INSN_LENGTH 2
 
-static xtensa_opcode
-swap_callx_for_call_opcode (opcode)
-     xtensa_opcode opcode;
+/* 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;
 {
-  init_call_opcodes ();
+  int insn_len;
+  xtensa_isa isa = xtensa_default_isa;
+  xtensa_format fmt;
+  static xtensa_insnbuf ibuff = NULL;
 
-  if (opcode == callx0_op) return call0_op;
-  if (opcode == callx4_op) return call4_op;
-  if (opcode == callx8_op) return call8_op;
-  if (opcode == callx12_op) return call12_op;
+  if (offset + MIN_INSN_LENGTH > content_len)
+    return 0;
 
-  /* Return XTENSA_UNDEFINED if the opcode is not an indirect call.  */
-  return XTENSA_UNDEFINED;
+  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;
 }
 
 
-/* Check if "buf" is pointing to a "L32R aN; CALLX aN" sequence, and
-   if so, return the CALLX opcode.  If not, return XTENSA_UNDEFINED.  */
+/* Decode the opcode for a single slot instruction.
+   Return 0 if it fails to decode or the instruction is multi-slot.  */
 
-#define L32R_TARGET_REG_OPERAND 0
-#define CALLN_SOURCE_OPERAND 0
-
-static xtensa_opcode 
-get_expanded_call_opcode (buf, bufsize)
-     bfd_byte *buf;
-     int bufsize;
+xtensa_opcode
+insn_decode_opcode (contents, content_len, offset, slot)
+     bfd_byte *contents;
+     bfd_size_type content_len;
+     bfd_size_type offset;
+     int slot;
 {
-  static xtensa_insnbuf insnbuf = NULL;
-  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)
+  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);
-      
-  xtensa_insnbuf_from_chars (isa, insnbuf, buf);
-  opcode = xtensa_decode_insn (isa, insnbuf);
-  
-  if (opcode != get_l32r_opcode ())
-    return XTENSA_UNDEFINED;
-  
-  operand = xtensa_get_operand (isa, opcode, L32R_TARGET_REG_OPERAND);
-  regno = xtensa_operand_decode
-    (operand, xtensa_operand_get_field (operand, insnbuf));
-  
-  /* 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))
+    {
+      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;
-  
-  operand = xtensa_get_operand (isa, opcode, CALLN_SOURCE_OPERAND);
-  call_regno = xtensa_operand_decode
-    (operand, xtensa_operand_get_field (operand, insnbuf));
-  if (call_regno != regno)
+
+  if (slot >= xtensa_format_num_slots (isa, fmt))
     return XTENSA_UNDEFINED;
-  
-  return opcode;
-}
 
-\f
-/* Data structures used during relaxation.  */
+  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
+  return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
+}
 
-/* r_reloc: relocation values.  */
 
-/* Through the relaxation process, we need to keep track of the values
-   that will result from evaluating relocations.  The standard ELF
-   relocation structure is not sufficient for this purpose because we're
-   operating on multiple input files at once, so we need to know which
-   input file a relocation refers to.  The r_reloc structure thus
-   records both the input file (bfd) and ELF relocation.
+/* The offset is the offset in the contents.
+   The address is the address of that offset.  */
 
-   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.  */
+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);
+}
 
-typedef struct r_reloc_struct r_reloc;
 
-struct r_reloc_struct
+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 *abfd;
-  Elf_Internal_Rela rela;
-  bfd_vma target_offset;
-};
+  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;
 
-static bfd_boolean r_reloc_is_const
-  PARAMS ((const r_reloc *));
-static void r_reloc_init
-  PARAMS ((r_reloc *, bfd *, Elf_Internal_Rela *));
-static bfd_vma r_reloc_get_target_offset
-  PARAMS ((const r_reloc *));
-static asection *r_reloc_get_section
-  PARAMS ((const r_reloc *));
-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 *));
+  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);
+}
 
-/* The r_reloc structure is included by value in literal_value, but not
-   every literal_value has an associated relocation -- some are simple
-   constants.  In such cases, we set all the fields in the r_reloc
-   struct to zero.  The r_reloc_is_const function should be used to
-   detect this case.  */
 
 static bfd_boolean
-r_reloc_is_const (r_rel)
-     const r_reloc *r_rel;
+check_branch_target_aligned_address (addr, len)
+     bfd_vma addr;
+     int len;
 {
-  return (r_rel->abfd == NULL);
+  if (len == 8)
+    return (addr % 8 == 0);
+  return ((addr >> 2) == ((addr + len - 1) >> 2));
 }
 
+\f
+/* Instruction widening and narrowing.  */
 
-static void
-r_reloc_init (r_rel, abfd, irel) 
-     r_reloc *r_rel;
-     bfd *abfd;
-     Elf_Internal_Rela *irel;
-{
-  if (irel != NULL)
-    {
-      r_rel->rela = *irel;
-      r_rel->abfd = abfd;
-      r_rel->target_offset = r_reloc_get_target_offset (r_rel);
-    }
-  else
-    memset (r_rel, 0, sizeof (r_reloc));
-}
+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));
 
 
-static bfd_vma
-r_reloc_get_target_offset (r_rel)
-     const r_reloc *r_rel;
+struct string_pair
 {
-  bfd_vma target_offset;
-  unsigned long r_symndx;
+  const char *wide;
+  const char *narrow;
+};
 
-  BFD_ASSERT (!r_reloc_is_const (r_rel));
-  r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
-  target_offset = get_elf_r_symndx_offset (r_rel->abfd, r_symndx);
-  return (target_offset + r_rel->rela.r_addend);
-}
 
+/* 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.  */
 
-static struct elf_link_hash_entry *
-r_reloc_get_hash_entry (r_rel)
-     const r_reloc *r_rel;
+struct string_pair narrowable[] =
 {
-  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
-  return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx);
-}
-
+  { "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 */
+};
 
-static asection *
-r_reloc_get_section (r_rel)
-     const r_reloc *r_rel;
+struct string_pair widenable[] =
 {
-  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
-  return get_elf_r_symndx_section (r_rel->abfd, r_symndx);
-}
+  { "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
-r_reloc_is_defined (r_rel)
-     const r_reloc *r_rel;
+narrow_instruction (contents, content_length, offset, do_it)
+     bfd_byte *contents;
+     bfd_size_type content_length;
+     bfd_size_type offset;
+     bfd_boolean do_it;
 {
-  asection *sec = r_reloc_get_section (r_rel);
-  if (sec == bfd_abs_section_ptr
-      || sec == bfd_com_section_ptr
-      || sec == bfd_und_section_ptr)
-    return FALSE;
-  return TRUE;
-}
+  xtensa_opcode opcode;
+  bfd_size_type insn_len, opi;
+  xtensa_isa isa = xtensa_default_isa;
+  xtensa_format fmt, o_fmt;
 
-\f
-/* source_reloc: relocations that reference literal sections.  */
+  static xtensa_insnbuf insnbuf = NULL;
+  static xtensa_insnbuf slotbuf = NULL;
+  static xtensa_insnbuf o_insnbuf = NULL;
+  static xtensa_insnbuf o_slotbuf = NULL;
 
-/* To determine whether literals can be coalesced, we need to first
-   record all the relocations that reference the literals.  The
-   source_reloc structure below is used for this purpose.  The
-   source_reloc entries are kept in a per-literal-section array, sorted
-   by offset within the literal section (i.e., target offset).
+  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);
+    }
 
-   The source_sec and r_rel.rela.r_offset fields identify the source of
-   the relocation.  The r_rel field records the relocation value, i.e.,
-   the offset of the literal being referenced.  The opnd field is needed
-   to determine the range of the immediate field to which the relocation
-   applies, so we can determine whether another literal with the same
-   value is within range.  The is_null field is true when the relocation
-   is being removed (e.g., when an L32R is being removed due to a CALLX
-   that is converted to a direct CALL).  */
+  BFD_ASSERT (offset < content_length);
 
-typedef struct source_reloc_struct source_reloc;
+  if (content_length < 2)
+    return FALSE;
 
-struct source_reloc_struct
-{
-  asection *source_sec;
-  r_reloc r_rel;
-  xtensa_operand opnd;
-  bfd_boolean is_null;
-};
+  /* 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;
 
-static void init_source_reloc
-  PARAMS ((source_reloc *, asection *, const r_reloc *, xtensa_operand));
-static source_reloc *find_source_reloc
-  PARAMS ((source_reloc *, int, asection *, Elf_Internal_Rela *));
-static int source_reloc_compare
-  PARAMS ((const PTR, const PTR));
+  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);
 
-static void
-init_source_reloc (reloc, source_sec, r_rel, opnd)
-     source_reloc *reloc;
-     asection *source_sec;
-     const r_reloc *r_rel;
-     xtensa_operand opnd;
-{
-  reloc->source_sec = source_sec;
-  reloc->r_rel = *r_rel;
-  reloc->opnd = opnd;
-  reloc->is_null = FALSE;
-}
+      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;
 
-/* Find the source_reloc for a particular source offset and relocation
-   type.  Note that the array is sorted by _target_ offset, so this is
-   just a linear search.  */
+         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;
 
-static source_reloc *
-find_source_reloc (src_relocs, src_count, sec, irel)
-     source_reloc *src_relocs;
-     int src_count;
-     asection *sec;
-     Elf_Internal_Rela *irel;
-{
-  int i;
+         if (xtensa_format_length (isa, fmt) != 3
+             || xtensa_format_length (isa, o_fmt) != 2)
+           return FALSE;
 
-  for (i = 0; i < src_count; i++)
-    {
-      if (src_relocs[i].source_sec == sec
-         && src_relocs[i].r_rel.rela.r_offset == irel->r_offset
-         && (ELF32_R_TYPE (src_relocs[i].r_rel.rela.r_info)
-             == ELF32_R_TYPE (irel->r_info)))
-       return &src_relocs[i];
-    }
+         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);
 
-  return NULL;
-}
+         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;
 
-static int
-source_reloc_compare (ap, bp)
-     const PTR ap;
-     const PTR bp;
-{
-  const source_reloc *a = (const source_reloc *) ap;
-  const source_reloc *b = (const source_reloc *) bp;
+             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;
 
-  return (a->r_rel.target_offset - b->r_rel.target_offset);
-}
+             if (rawval1 != rawval2)
+               return FALSE;
+             if (rawval0 == rawval1) /* it is a nop */
+               return FALSE;
+           }
 
-\f
-/* Literal values and value hash tables.  */
+         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;
 
-/* Literals with the same value can be coalesced.  The literal_value
-   structure records the value of a literal: the "r_rel" field holds the
-   information from the relocation on the literal (if there is one) and
-   the "value" field holds the contents of the literal word itself.
+             /* 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;
+           }
 
-   The value_map structure records a literal value along with the
-   location of a literal holding that value.  The value_map hash table
-   is indexed by the literal value, so that we can quickly check if a
-   particular literal value has been seen before and is thus a candidate
-   for coalescing.  */
+         if (xtensa_format_set_slot (isa, o_fmt, 0,
+                                     o_insnbuf, o_slotbuf) != 0)
+           return FALSE;
 
-typedef struct literal_value_struct literal_value;
-typedef struct value_map_struct value_map;
-typedef struct value_map_hash_table_struct value_map_hash_table;
+         if (do_it)
+           xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
+                                    content_length - offset);
+         return TRUE;
+       }
+    }
+  return FALSE;
+}
 
-struct literal_value_struct
-{
-  r_reloc r_rel; 
-  unsigned long value;
-};
 
-struct value_map_struct
-{
-  literal_value val;                   /* The literal value.  */
-  r_reloc loc;                         /* Location of the literal.  */
-  value_map *next;
-};
+/* 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.  */
 
-struct value_map_hash_table_struct
+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;
 {
-  unsigned bucket_count;
-  value_map **buckets;
-  unsigned count;
-};
-
+  xtensa_opcode opcode;
+  bfd_size_type insn_len, opi;
+  xtensa_isa isa = xtensa_default_isa;
+  xtensa_format fmt, o_fmt;
 
-static bfd_boolean is_same_value
-  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
-  PARAMS ((const literal_value *));
-static unsigned hash_bfd_vma
-  PARAMS ((bfd_vma));
-static 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 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);
+    }
 
-static bfd_boolean
-is_same_value (src1, src2, final_static_link)
-     const literal_value *src1;
-     const literal_value *src2;
-     bfd_boolean final_static_link;
-{
-  struct elf_link_hash_entry *h1, *h2;
+  BFD_ASSERT (offset < content_length);
 
-  if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) 
+  if (content_length < 2)
     return FALSE;
 
-  if (r_reloc_is_const (&src1->r_rel))
-    return (src1->value == src2->value);
-
-  if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
-      != ELF32_R_TYPE (src2->r_rel.rela.r_info))
+  /* 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 (r_reloc_get_target_offset (&src1->r_rel)
-      != r_reloc_get_target_offset (&src2->r_rel))
+  if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
     return FALSE;
 
-  if (src1->value != src2->value)
+  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+  if (opcode == XTENSA_UNDEFINED)
     return FALSE;
-  
-  /* Now check for the same section (if defined) or the same elf_hash
-     (if undefined or weak).  */
-  h1 = r_reloc_get_hash_entry (&src1->r_rel);
-  h2 = r_reloc_get_hash_entry (&src2->r_rel);
-  if (r_reloc_is_defined (&src1->r_rel)
-      && (final_static_link
-         || ((!h1 || h1->root.type != bfd_link_hash_defweak)
-             && (!h2 || h2->root.type != bfd_link_hash_defweak))))
-    {
-      if (r_reloc_get_section (&src1->r_rel)
-         != r_reloc_get_section (&src2->r_rel))
-       return FALSE;
-    }
-  else
+  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)
     {
-      /* Require that the hash entries (i.e., symbols) be identical.  */
-      if (h1 != h2 || h1 == 0)
-       return FALSE;
-    }
+      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);
 
-  return TRUE;
-}
+      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;
 
-/* Must be power of 2.  */
-#define INITIAL_HASH_RELOC_BUCKET_COUNT 1024
+         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;
 
-static value_map_hash_table *
-value_map_hash_table_init ()
-{
-  value_map_hash_table *values;
+         if (xtensa_format_length (isa, fmt) != 2
+             || xtensa_format_length (isa, o_fmt) != 3)
+           return FALSE;
 
-  values = (value_map_hash_table *)
-    bfd_malloc (sizeof (value_map_hash_table));
+         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;
 
-  values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT;
-  values->count = 0;
-  values->buckets = (value_map **)
-    bfd_zmalloc (sizeof (value_map *) * values->bucket_count);
+         if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
+           return FALSE;
 
-  return values;
+         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;
 }
 
 
-static unsigned
-hash_bfd_vma (val) 
-     bfd_vma val;
+/* 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;
 {
-  return (val >> 2) + (val >> 10);
+  init_op_single_format_table ();
+  return op_single_fmt_table[opcode];
 }
 
 
-static unsigned
-hash_literal_value (src)
-     const literal_value *src;
+static void
+init_op_single_format_table ()
 {
-  unsigned hash_val;
+  xtensa_isa isa = xtensa_default_isa;
+  xtensa_insnbuf ibuf;
+  xtensa_opcode opcode;
+  xtensa_format fmt;
+  int num_opcodes;
 
-  if (r_reloc_is_const (&src->r_rel))
-    return hash_bfd_vma (src->value);
+  if (op_single_fmt_table != NULL)
+    return;
 
-  hash_val = (hash_bfd_vma (r_reloc_get_target_offset (&src->r_rel))
-             + hash_bfd_vma (src->value));
-  
-  /* 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));
+  ibuf = xtensa_insnbuf_alloc (isa);
+  num_opcodes = xtensa_isa_num_opcodes (isa);
 
-  return hash_val;
+  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);
 }
 
+\f
+/* Code for transforming CALLs at link-time.  */
 
-/* Check if the specified literal_value has been seen before.  */
-
-static value_map *
-get_cached_value (map, val, final_static_link)
-     value_map_hash_table *map;
-     const literal_value *val;
-     bfd_boolean final_static_link;
+static bfd_reloc_status_type
+elf_xtensa_do_asm_simplify (contents, address, content_length, error_message)
+     bfd_byte *contents;
+     bfd_vma address;
+     bfd_vma content_length;
+     char **error_message;
 {
-  value_map *map_e;
-  value_map *bucket;
-  unsigned idx;
+  static xtensa_insnbuf insnbuf = NULL;
+  static xtensa_insnbuf slotbuf = NULL;
+  xtensa_format core_format = XTENSA_UNDEFINED;
+  xtensa_opcode opcode;
+  xtensa_opcode direct_call_opcode;
+  xtensa_isa isa = xtensa_default_isa;
+  bfd_byte *chbuf = contents + address;
+  int opn;
 
-  idx = hash_literal_value (val);
-  idx = idx & (map->bucket_count - 1);
-  bucket = map->buckets[idx];
-  for (map_e = bucket; map_e; map_e = map_e->next)
+  if (insnbuf == NULL)
     {
-      if (is_same_value (&map_e->val, val, final_static_link))
-       return map_e;
+      insnbuf = xtensa_insnbuf_alloc (isa);
+      slotbuf = xtensa_insnbuf_alloc (isa);
     }
-  return NULL;
-}
 
+  if (content_length < address)
+    {
+      *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
+      return bfd_reloc_other;
+    }
 
-/* Record a new literal value.  It is illegal to call this if VALUE
-   already has an entry here.  */
+  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)
+    {
+      *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_opcode_encode (isa, core_format, 0, slotbuf, opcode);
+  for (opn = 0; opn < 3; opn++) 
+    {
+      uint32 regno = 1;
+      xtensa_operand_encode (isa, opcode, opn, &regno);
+      xtensa_operand_set_field (isa, opcode, opn, core_format, 0,
+                               slotbuf, regno);
+    }
+  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);
 
-static value_map *
-add_value_map (map, val, loc, final_static_link)
-     value_map_hash_table *map;
-     const literal_value *val;
-     const r_reloc *loc;
-     bfd_boolean final_static_link;
-{
-  value_map **bucket_p;
-  unsigned idx;
+  /* Assemble a CALL ("callN 0") into the 3 byte offset.  */
+  xtensa_opcode_encode (isa, core_format, 0, slotbuf, direct_call_opcode);
+  xtensa_operand_set_field (isa, opcode, 0, core_format, 0, slotbuf, 0);
 
-  value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
+  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);
 
-  BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL);
-  val_e->val = *val;
-  val_e->loc = *loc;
+  return bfd_reloc_ok;
+}
 
-  idx = hash_literal_value (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 */
-  
-  return val_e;
-}
+static bfd_reloc_status_type
+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,
+                               error_message);
 
-\f
-/* Lists of literals being coalesced or removed.  */
+  if (retval != bfd_reloc_ok)
+    return bfd_reloc_dangerous;
 
-/* In the usual case, the literal identified by "from" is being
-   coalesced with another literal identified by "to".  If the literal is
-   unused and is being removed altogether, "to.abfd" will be NULL.
-   The removed_literal entries are kept on a per-section list, sorted
-   by the "from" offset field.  */
+  /* 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_SLOT0_OP);
+  return bfd_reloc_ok;
+}
 
-typedef struct removed_literal_struct removed_literal;
-typedef struct removed_literal_list_struct removed_literal_list;
 
-struct removed_literal_struct
+static xtensa_opcode
+swap_callx_for_call_opcode (opcode)
+     xtensa_opcode opcode;
 {
-  r_reloc from;
-  r_reloc to;
-  removed_literal *next;
-};
+  init_call_opcodes ();
 
-struct removed_literal_list_struct
-{
-  removed_literal *head;
-  removed_literal *tail;
-};
+  if (opcode == callx0_op) return call0_op;
+  if (opcode == callx4_op) return call4_op;
+  if (opcode == callx8_op) return call8_op;
+  if (opcode == callx12_op) return call12_op;
 
+  /* Return XTENSA_UNDEFINED if the opcode is not an indirect call.  */
+  return XTENSA_UNDEFINED;
+}
 
-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));
 
+/* 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.  */
 
-/* Record that the literal at "from" is being removed.  If "to" is not
-   NULL, the "from" literal is being coalesced with the "to" literal.  */
+#define L32R_TARGET_REG_OPERAND 0
+#define CONST16_TARGET_REG_OPERAND 0
+#define CALLN_SOURCE_OPERAND 0
 
-static void
-add_removed_literal (removed_list, from, to)
-     removed_literal_list *removed_list;
-     const r_reloc *from;
-     const r_reloc *to;
+static xtensa_opcode 
+get_expanded_call_opcode (buf, bufsize, p_uses_l32r)
+     bfd_byte *buf;
+     int bufsize;
+     bfd_boolean *p_uses_l32r;
 {
-  removed_literal *r, *new_r, *next_r;
-
-  new_r = (removed_literal *) bfd_zmalloc (sizeof (removed_literal));
+  static xtensa_insnbuf insnbuf = NULL;
+  static xtensa_insnbuf slotbuf = NULL;
+  xtensa_format fmt;
+  xtensa_opcode opcode;
+  xtensa_isa isa = xtensa_default_isa;
+  uint32 regno, const16_regno, call_regno;
+  int offset = 0;
 
-  new_r->from = *from;
-  if (to)
-    new_r->to = *to;
-  else
-    new_r->to.abfd = NULL;
-  new_r->next = NULL;
-  
-  r = removed_list->head;
-  if (r == NULL) 
+  if (insnbuf == NULL)
     {
-      removed_list->head = new_r;
-      removed_list->tail = new_r;
+      insnbuf = xtensa_insnbuf_alloc (isa);
+      slotbuf = xtensa_insnbuf_alloc (isa);
     }
-  /* Special check for common case of append.  */
-  else if (removed_list->tail->from.target_offset < from->target_offset)
+
+  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;
+
+  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+  if (opcode == XTENSA_UNDEFINED)
+    return XTENSA_UNDEFINED;
+
+  if (opcode == get_l32r_opcode ())
     {
-      removed_list->tail->next = new_r;
-      removed_list->tail = new_r;
+      if (p_uses_l32r)
+       *p_uses_l32r = TRUE;
+      if (xtensa_operand_get_field (isa, opcode, L32R_TARGET_REG_OPERAND,
+                                   fmt, 0, slotbuf, &regno)
+         || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND,
+                                   &regno))
+       return XTENSA_UNDEFINED;
     }
-  else
+  else if (opcode == get_const16_opcode ())
     {
-      while (r->from.target_offset < from->target_offset
-            && r->next != NULL) 
-       {
-         r = r->next;
-       }
-      next_r = r->next;
-      r->next = new_r;
-      new_r->next = next_r;
-      if (next_r == NULL)
-       removed_list->tail = new_r;
+      if (p_uses_l32r)
+       *p_uses_l32r = FALSE;
+      if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
+                                   fmt, 0, slotbuf, &regno)
+         || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
+                                   &regno))
+       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;
 
-/* Check if the list of removed literals contains an entry for the
-   given address.  Return the entry if found.  */
+  /* Next instruction should be an CALLXn with operand 0 == regno.  */
+  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 == XTENSA_UNDEFINED 
+      || !is_indirect_call_opcode (opcode))
+    return XTENSA_UNDEFINED;
 
-static removed_literal *
-find_removed_literal (removed_list, addr)
-     removed_literal_list *removed_list;
-     bfd_vma addr;
-{
-  removed_literal *r = removed_list->head;
-  while (r && r->from.target_offset < addr)
-    r = r->next;
-  if (r && r->from.target_offset == addr)
-    return r;
-  return NULL;
-}
+  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;
 
-/* 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.  */
+  return opcode;
+}
 
-static bfd_vma 
-offset_with_removed_literals (removed_list, addr)
-     removed_literal_list *removed_list;
-     bfd_vma addr;
-{
-  removed_literal *r = removed_list->head;
-  unsigned num_bytes = 0;
+\f
+/* Data structures used during relaxation.  */
 
-  if (r == NULL)
-    return addr;
+/* r_reloc: relocation values.  */
 
-  while (r && r->from.target_offset <= addr)
-    {
-      num_bytes += 4;
-      r = r->next;
-    }
-  if (num_bytes > addr)
-    return 0;
-  return (addr - num_bytes);
-}
+/* Through the relaxation process, we need to keep track of the values
+   that will result from evaluating relocations.  The standard ELF
+   relocation structure is not sufficient for this purpose because we're
+   operating on multiple input files at once, so we need to know which
+   input file a relocation refers to.  The r_reloc structure thus
+   records both the input file (bfd) and ELF relocation.
 
-\f
-/* Coalescing literals may require a relocation to refer to a section in
-   a different input file, but the standard relocation information
-   cannot express that.  Instead, the reloc_bfd_fix structures are used
-   to "fix" the relocations that refer to sections in other input files.
-   These structures are kept on per-section lists.  The "src_type" field
-   records the relocation type in case there are multiple relocations on
-   the same location.  FIXME: This is ugly; an alternative might be to
-   add new symbols with the "owner" field to some other input file.  */
+   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 r_reloc also contains a virtual offset that allows multiple
+   inserted literals to be placed at the same "address" with
+   different offsets.  */
 
-typedef struct reloc_bfd_fix_struct reloc_bfd_fix;
+typedef struct r_reloc_struct r_reloc;
 
-struct reloc_bfd_fix_struct
+struct r_reloc_struct
 {
-  asection *src_sec;
-  bfd_vma src_offset;
-  unsigned src_type;                   /* Relocation type.  */
-  
-  bfd *target_abfd;
-  asection *target_sec;
+  bfd *abfd;
+  Elf_Internal_Rela rela;
   bfd_vma target_offset;
-  
-  reloc_bfd_fix *next;
+  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 *, bfd_byte *, bfd_size_type));
+static bfd_vma r_reloc_get_target_offset
+  PARAMS ((const r_reloc *));
+static asection *r_reloc_get_section
+  PARAMS ((const r_reloc *));
+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 */
 
-static reloc_bfd_fix *reloc_bfd_fix_init
-  PARAMS ((asection *, bfd_vma, unsigned, bfd *, asection *, bfd_vma));
-static reloc_bfd_fix *get_bfd_fix
-  PARAMS ((reloc_bfd_fix *, asection *, bfd_vma, unsigned));
 
+/* The r_reloc structure is included by value in literal_value, but not
+   every literal_value has an associated relocation -- some are simple
+   constants.  In such cases, we set all the fields in the r_reloc
+   struct to zero.  The r_reloc_is_const function should be used to
+   detect this case.  */
 
-static reloc_bfd_fix *
-reloc_bfd_fix_init (src_sec, src_offset, src_type,
-                   target_abfd, target_sec, target_offset)
-     asection *src_sec;
-     bfd_vma src_offset;
-     unsigned src_type;
-     bfd *target_abfd;
-     asection *target_sec;
-     bfd_vma target_offset;
+static bfd_boolean
+r_reloc_is_const (r_rel)
+     const r_reloc *r_rel;
 {
-  reloc_bfd_fix *fix;
-
-  fix = (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix));
-  fix->src_sec = src_sec;
-  fix->src_offset = src_offset;
-  fix->src_type = src_type;
-  fix->target_abfd = target_abfd;
-  fix->target_sec = target_sec;
-  fix->target_offset = target_offset;
-
-  return fix;
+  return (r_rel->abfd == NULL);
 }
 
 
-static reloc_bfd_fix *
-get_bfd_fix (fix_list, sec, offset, type)
-     reloc_bfd_fix *fix_list;
-     asection *sec;
-     bfd_vma offset;
-     unsigned type;
+static void
+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;
 {
-  reloc_bfd_fix *r;
+  int r_type;
+  reloc_howto_type *howto;
 
-  for (r = fix_list; r != NULL; r = r->next) 
+  if (irel != NULL)
     {
-      if (r->src_sec == sec
-         && r->src_offset == offset
-         && r->src_type == type)
-       return r;
+      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;
+       }
     }
-  return NULL;
+  else
+    memset (r_rel, 0, sizeof (r_reloc));
 }
 
-\f
-/* Per-section data for relaxation.  */
 
-struct xtensa_relax_info_struct
+static bfd_vma
+r_reloc_get_target_offset (r_rel)
+     const r_reloc *r_rel;
 {
-  bfd_boolean is_relaxable_literal_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.  */
+  bfd_vma target_offset;
+  unsigned long r_symndx;
 
-  removed_literal_list removed_list;
+  BFD_ASSERT (!r_reloc_is_const (r_rel));
+  r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+  target_offset = get_elf_r_symndx_offset (r_rel->abfd, r_symndx);
+  return (target_offset + r_rel->rela.r_addend);
+}
 
-  reloc_bfd_fix *fix_list;
-};
 
-struct elf_xtensa_section_data
+static struct elf_link_hash_entry *
+r_reloc_get_hash_entry (r_rel)
+     const r_reloc *r_rel;
 {
-  struct bfd_elf_section_data elf;
-  xtensa_relax_info relax_info;
-};
+  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+  return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx);
+}
 
-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 *));
+
+static asection *
+r_reloc_get_section (r_rel)
+     const r_reloc *r_rel;
+{
+  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
+  return get_elf_r_symndx_section (r_rel->abfd, r_symndx);
+}
 
 
 static bfd_boolean
-elf_xtensa_new_section_hook (abfd, sec)
-     bfd *abfd;
-     asection *sec;
+r_reloc_is_defined (r_rel)
+     const r_reloc *r_rel;
 {
-  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)
+  asection *sec;
+  if (r_rel == NULL)
     return FALSE;
-  sec->used_by_bfd = (PTR) sdata;
 
-  return _bfd_elf_new_section_hook (abfd, sec);
+  sec = r_reloc_get_section (r_rel);
+  if (sec == bfd_abs_section_ptr
+      || sec == bfd_com_section_ptr
+      || sec == bfd_und_section_ptr)
+    return FALSE;
+  return TRUE;
 }
 
 
+#if DEBUG
+
 static void
-init_xtensa_relax_info (sec)
-     asection *sec;
+print_r_reloc (fp, r_rel)
+     FILE *fp;
+     const r_reloc *r_rel;
 {
-  xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
+  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, " ?? + ");
 
-  relax_info->is_relaxable_literal_section = FALSE;
-  relax_info->visited = 0;
+  fprintf_vma (fp, r_rel->target_offset);
+  if (r_rel->virtual_offset)
+    {
+      fprintf (fp, " + ");
+      fprintf_vma (fp, r_rel->virtual_offset);
+    }
+    
+  fprintf (fp, ")");
+}
 
-  relax_info->src_relocs = NULL;
-  relax_info->src_count = 0;
-  relax_info->src_next = 0;
+#endif /* DEBUG */
 
-  relax_info->removed_list.head = NULL;
-  relax_info->removed_list.tail = NULL;
+\f
+/* source_reloc: relocations that reference literals.  */
 
-  relax_info->fix_list = NULL;
-}
+/* To determine whether literals can be coalesced, we need to first
+   record all the relocations that reference the literals.  The
+   source_reloc structure below is used for this purpose.  The
+   source_reloc entries are kept in a per-literal-section array, sorted
+   by offset within the literal section (i.e., target offset).
 
+   The source_sec and r_rel.rela.r_offset fields identify the source of
+   the relocation.  The r_rel field records the relocation value, i.e.,
+   the offset of the literal being referenced.  The opnd field is needed
+   to determine the range of the immediate field to which the relocation
+   applies, so we can determine whether another literal with the same
+   value is within range.  The is_null field is true when the relocation
+   is being removed (e.g., when an L32R is being removed due to a CALLX
+   that is converted to a direct CALL).  */
 
-static xtensa_relax_info *
-get_xtensa_relax_info (sec)
-     asection *sec;
+typedef struct source_reloc_struct source_reloc;
+
+struct source_reloc_struct
 {
-  struct elf_xtensa_section_data *section_data;
+  asection *source_sec;
+  r_reloc r_rel;
+  xtensa_opcode opcode;
+  int opnd;
+  bfd_boolean is_null;
+  bfd_boolean is_abs_literal;
+};
 
-  /* 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 &section_data->relax_info;
-}
+static void init_source_reloc
+  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
+  PARAMS ((const PTR, const PTR));
 
 
 static void
-add_fix (src_sec, fix)
-     asection *src_sec;
-     reloc_bfd_fix *fix;
+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_opcode opcode;
+     int opnd;
+     bfd_boolean is_abs_literal;
 {
-  xtensa_relax_info *relax_info;
-
-  relax_info = get_xtensa_relax_info (src_sec);
-  fix->next = relax_info->fix_list;
-  relax_info->fix_list = fix;
+  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;
 }
 
-\f
-/* Access to internal relocations, section contents and symbols.  */
 
-/* During relaxation, we need to modify relocations, section contents,
-   and symbol definitions, and we need to keep the original values from
-   being reloaded from the input files, i.e., we need to "pin" the
-   modified values in memory.  We also want to continue to observe the
-   setting of the "keep-memory" flag.  The following functions wrap the
-   standard BFD functions to take care of this for us.  */
+/* Find the source_reloc for a particular source offset and relocation
+   type.  Note that the array is sorted by _target_ offset, so this is
+   just a linear search.  */
 
-static Elf_Internal_Rela *
-retrieve_internal_relocs (abfd, sec, keep_memory)
-     bfd *abfd;
+static source_reloc *
+find_source_reloc (src_relocs, src_count, sec, irel)
+     source_reloc *src_relocs;
+     int src_count;
      asection *sec;
-     bfd_boolean keep_memory;
+     Elf_Internal_Rela *irel;
 {
-  Elf_Internal_Rela *internal_relocs;
+  int i;
 
-  if ((sec->flags & SEC_LINKER_CREATED) != 0)
-    return NULL;
+  for (i = 0; i < src_count; i++)
+    {
+      if (src_relocs[i].source_sec == sec
+         && src_relocs[i].r_rel.rela.r_offset == irel->r_offset
+         && (ELF32_R_TYPE (src_relocs[i].r_rel.rela.r_info)
+             == ELF32_R_TYPE (irel->r_info)))
+       return &src_relocs[i];
+    }
 
-  internal_relocs = elf_section_data (sec)->relocs;
-  if (internal_relocs == NULL)
-    internal_relocs = (_bfd_elf_link_read_relocs
-                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
-                       keep_memory));
-  return internal_relocs;
+  return NULL;
 }
 
 
-static void
-pin_internal_relocs (sec, internal_relocs)
-     asection *sec;
-     Elf_Internal_Rela *internal_relocs;
+static int
+source_reloc_compare (ap, bp)
+     const PTR ap;
+     const PTR bp;
 {
-  elf_section_data (sec)->relocs = internal_relocs;
-}
+  const source_reloc *a = (const source_reloc *) ap;
+  const source_reloc *b = (const source_reloc *) bp;
 
+  if (a->r_rel.target_offset != b->r_rel.target_offset)
+    return (a->r_rel.target_offset - b->r_rel.target_offset);
 
-static void
-release_internal_relocs (sec, internal_relocs)
-     asection *sec;
-     Elf_Internal_Rela *internal_relocs;
-{
-  if (internal_relocs
-      && elf_section_data (sec)->relocs != internal_relocs)
-    free (internal_relocs);
+  /* 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);
 }
 
+\f
+/* Literal values and value hash tables.  */
 
-static bfd_byte *
-retrieve_contents (abfd, sec, keep_memory)
-     bfd *abfd;
-     asection *sec;
-     bfd_boolean keep_memory;
-{
-  bfd_byte *contents;
+/* Literals with the same value can be coalesced.  The literal_value
+   structure records the value of a literal: the "r_rel" field holds the
+   information from the relocation on the literal (if there is one) and
+   the "value" field holds the contents of the literal word itself.
 
-  contents = elf_section_data (sec)->this_hdr.contents;
-  
-  if (contents == NULL && sec->size != 0)
-    {
-      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
-       {
-         if (contents != NULL)
-           free (contents);
-         return NULL;
-       }
-      if (keep_memory) 
-       elf_section_data (sec)->this_hdr.contents = contents;
-    }
-  return contents;
-}
+   The value_map structure records a literal value along with the
+   location of a literal holding that value.  The value_map hash table
+   is indexed by the literal value, so that we can quickly check if a
+   particular literal value has been seen before and is thus a candidate
+   for coalescing.  */
 
+typedef struct literal_value_struct literal_value;
+typedef struct value_map_struct value_map;
+typedef struct value_map_hash_table_struct value_map_hash_table;
 
-static void
-pin_contents (sec, contents)
-     asection *sec;
-     bfd_byte *contents;
+struct literal_value_struct
 {
-  elf_section_data (sec)->this_hdr.contents = contents;
-}
+  r_reloc r_rel; 
+  unsigned long value;
+  bfd_boolean is_abs_literal;
+};
+
+struct value_map_struct
+{
+  literal_value val;                   /* The literal value.  */
+  r_reloc loc;                         /* Location of the literal.  */
+  value_map *next;
+};
+
+struct value_map_hash_table_struct
+{
+  unsigned bucket_count;
+  value_map **buckets;
+  unsigned count;
+  bfd_boolean has_last_loc;
+  r_reloc last_loc;
+};
+
+
+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 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 *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
-release_contents (sec, contents)
-     asection *sec;
-     bfd_byte *contents;
+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;
 {
-  if (contents && 
-      elf_section_data (sec)->this_hdr.contents != contents)
-    free (contents);
+  lit->r_rel = *r_rel;
+  lit->value = value;
+  lit->is_abs_literal = is_abs_literal;
 }
 
 
-static Elf_Internal_Sym *
-retrieve_local_syms (input_bfd)
-     bfd *input_bfd;
+static bfd_boolean
+literal_value_equal (src1, src2, final_static_link)
+     const literal_value *src1;
+     const literal_value *src2;
+     bfd_boolean final_static_link;
 {
-  Elf_Internal_Shdr *symtab_hdr;
-  Elf_Internal_Sym *isymbuf;
-  size_t locsymcount;
+  struct elf_link_hash_entry *h1, *h2;
 
-  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
-  locsymcount = symtab_hdr->sh_info;
+  if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) 
+    return FALSE;
 
-  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-  if (isymbuf == NULL && locsymcount != 0)
-    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
-                                   NULL, NULL, NULL);
+  if (r_reloc_is_const (&src1->r_rel))
+    return (src1->value == src2->value);
 
-  /* Save the symbols for this input file so they won't be read again.  */
-  if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents)
-    symtab_hdr->contents = (unsigned char *) isymbuf;
+  if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
+      != ELF32_R_TYPE (src2->r_rel.rela.r_info))
+    return FALSE;
 
-  return isymbuf;
+  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)
+    return FALSE;
+  
+  /* Now check for the same section (if defined) or the same elf_hash
+     (if undefined or weak).  */
+  h1 = r_reloc_get_hash_entry (&src1->r_rel);
+  h2 = r_reloc_get_hash_entry (&src2->r_rel);
+  if (r_reloc_is_defined (&src1->r_rel)
+      && (final_static_link
+         || ((!h1 || h1->root.type != bfd_link_hash_defweak)
+             && (!h2 || h2->root.type != bfd_link_hash_defweak))))
+    {
+      if (r_reloc_get_section (&src1->r_rel)
+         != r_reloc_get_section (&src2->r_rel))
+       return FALSE;
+    }
+  else
+    {
+      /* Require that the hash entries (i.e., symbols) be identical.  */
+      if (h1 != h2 || h1 == 0)
+       return FALSE;
+    }
+
+  if (src1->is_abs_literal != src2->is_abs_literal)
+    return FALSE;
+
+  return TRUE;
 }
 
-\f
-/* Code for link-time relaxation.  */
 
-/* Local helper functions.  */
-static bfd_boolean analyze_relocations
-  PARAMS ((struct bfd_link_info *));
-static bfd_boolean find_relaxable_sections
-  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
-static bfd_boolean collect_source_relocs
-  PARAMS ((bfd *, asection *, struct bfd_link_info *));
-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
-  PARAMS ((bfd *, asection *, struct bfd_link_info *));
-static bfd_boolean relax_section_symbols
-  PARAMS ((bfd *, asection *));
-static bfd_boolean relocations_reach
-  PARAMS ((source_reloc *, int, const r_reloc *));
-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 *));
+/* Must be power of 2.  */
+#define INITIAL_HASH_RELOC_BUCKET_COUNT 1024
 
+static value_map_hash_table *
+value_map_hash_table_init ()
+{
+  value_map_hash_table *values;
 
-static bfd_boolean 
-elf_xtensa_relax_section (abfd, sec, link_info, again)
-     bfd *abfd;
-     asection *sec;
-     struct bfd_link_info *link_info;
-     bfd_boolean *again;
+  values = (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;
 {
-  static value_map_hash_table *values = NULL;
-  xtensa_relax_info *relax_info;
+  free (table->buckets);
+  free (table);
+}
+
+
+static unsigned
+hash_bfd_vma (val) 
+     bfd_vma val;
+{
+  return (val >> 2) + (val >> 10);
+}
+
+
+static unsigned
+literal_value_hash (src)
+     const literal_value *src;
+{
+  unsigned hash_val;
 
-  if (!values)
+  hash_val = hash_bfd_vma (src->value);
+  if (!r_reloc_is_const (&src->r_rel))
     {
-      /* Do some overall initialization for relaxation.  */
-      values = value_map_hash_table_init ();
-      relaxing_section = TRUE;
-      if (!analyze_relocations (link_info))
-       return FALSE;
+      void *sec_or_hash;
+
+      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))
+       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);
     }
-  *again = FALSE;
+  return hash_val;
+}
 
-  /* Don't mess with linker-created sections.  */
-  if ((sec->flags & SEC_LINKER_CREATED) != 0)
-    return TRUE;
 
-  relax_info = get_xtensa_relax_info (sec);
-  BFD_ASSERT (relax_info != NULL);
+/* Check if the specified literal_value has been seen before.  */
 
-  switch (relax_info->visited)
+static value_map *
+value_map_get_cached_value (map, val, final_static_link)
+     value_map_hash_table *map;
+     const literal_value *val;
+     bfd_boolean final_static_link;
+{
+  value_map *map_e;
+  value_map *bucket;
+  unsigned idx;
+
+  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)
     {
-    case 0:
-      /* 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))
-       return FALSE;
-      *again = TRUE;
-      break;
+      if (literal_value_equal (&map_e->val, val, final_static_link))
+       return map_e;
+    }
+  return NULL;
+}
 
-    case 1:
-      if (!relax_section (abfd, sec, link_info))
-       return FALSE;
-      *again = TRUE;
-      break;
 
-    case 2:
-      if (!relax_section_symbols (abfd, sec))
-       return FALSE;
-      break;
+/* Record a new literal value.  It is illegal to call this if VALUE
+   already has an entry here.  */
+
+static value_map *
+add_value_map (map, val, loc, final_static_link)
+     value_map_hash_table *map;
+     const literal_value *val;
+     const r_reloc *loc;
+     bfd_boolean final_static_link;
+{
+  value_map **bucket_p;
+  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;
     }
 
-  relax_info->visited++;
-  return TRUE;
+  BFD_ASSERT (!value_map_get_cached_value (map, val, final_static_link));
+  val_e->val = *val;
+  val_e->loc = *loc;
+
+  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.  */
+  
+  return val_e;
 }
 
-/* Initialization for relaxation.  */
+\f
+/* 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
+};
 
-/* 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.  */
 
-static bfd_boolean
-analyze_relocations (link_info)
-     struct bfd_link_info *link_info;
+/* Structure for a text action record.  */
+struct text_action_struct
 {
-  bfd *abfd;
-  asection *sec;
-  bfd_boolean is_relaxable = FALSE;
+  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.  */
 
-  /* Initialize the per-section relaxation info.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
-    for (sec = abfd->sections; sec != NULL; sec = sec->next)
-      {
-       init_xtensa_relax_info (sec);
-      }
+  text_action *next;
+};
 
-  /* Mark relaxable sections (and count relocations against each one).  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
-    for (sec = abfd->sections; sec != NULL; sec = sec->next)
-      {
-       if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
-         return FALSE;
-      }
 
-  /* Bail out if there are no relaxable sections.  */
-  if (!is_relaxable)
-    return TRUE;
+/* List of all of the actions taken on a text section.  */
+struct text_action_list_struct
+{
+  text_action *head;
+};
 
-  /* Allocate space for source_relocs.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
-    for (sec = abfd->sections; sec != NULL; sec = sec->next)
-      {
-       xtensa_relax_info *relax_info;
 
-       relax_info = get_xtensa_relax_info (sec);
-       if (relax_info->is_relaxable_literal_section)
-         {
-           relax_info->src_relocs = (source_reloc *)
-             bfd_malloc (relax_info->src_count * sizeof (source_reloc));
-         }
-      }
+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 */
+
+\f
+/* Lists of literals being coalesced or removed.  */
+
+/* In the usual case, the literal identified by "from" is being
+   coalesced with another literal identified by "to".  If the literal is
+   unused and is being removed altogether, "to.abfd" will be NULL.
+   The removed_literal entries are kept on a per-section list, sorted
+   by the "from" offset field.  */
+
+typedef struct removed_literal_struct removed_literal;
+typedef struct removed_literal_list_struct removed_literal_list;
+
+struct removed_literal_struct
+{
+  r_reloc from;
+  r_reloc to;
+  removed_literal *next;
+};
+
+struct removed_literal_list_struct
+{
+  removed_literal *head;
+  removed_literal *tail;
+};
+
+
+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));
+#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
+   NULL, the "from" literal is being coalesced with the "to" literal.  */
+
+static void
+add_removed_literal (removed_list, from, to)
+     removed_literal_list *removed_list;
+     const r_reloc *from;
+     const r_reloc *to;
+{
+  removed_literal *r, *new_r, *next_r;
+
+  new_r = (removed_literal *) bfd_zmalloc (sizeof (removed_literal));
+
+  new_r->from = *from;
+  if (to)
+    new_r->to = *to;
+  else
+    new_r->to.abfd = NULL;
+  new_r->next = NULL;
+  
+  r = removed_list->head;
+  if (r == NULL) 
+    {
+      removed_list->head = new_r;
+      removed_list->tail = new_r;
+    }
+  /* Special check for common case of append.  */
+  else if (removed_list->tail->from.target_offset < from->target_offset)
+    {
+      removed_list->tail->next = new_r;
+      removed_list->tail = new_r;
+    }
+  else
+    {
+      while (r->from.target_offset < from->target_offset
+            && r->next != NULL) 
+       {
+         r = r->next;
+       }
+      next_r = r->next;
+      r->next = new_r;
+      new_r->next = next_r;
+      if (next_r == NULL)
+       removed_list->tail = new_r;
+    }
+}
+
+
+/* Check if the list of removed literals contains an entry for the
+   given address.  Return the entry if found.  */
+
+static removed_literal *
+find_removed_literal (removed_list, addr)
+     removed_literal_list *removed_list;
+     bfd_vma addr;
+{
+  removed_literal *r = removed_list->head;
+  while (r && r->from.target_offset < addr)
+    r = r->next;
+  if (r && r->from.target_offset == addr)
+    return r;
+  return NULL;
+}
+
+
+#if DEBUG
+
+static void
+print_removed_literals (fp, removed_list)
+     FILE *fp;
+     removed_literal_list *removed_list;
+{
+  removed_literal *r;
+  r = removed_list->head;
+  if (r)
+    fprintf (fp, "Removed Literals\n");
+  for (; r != NULL; 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");
+    }
+}
+
+#endif /* DEBUG */
+
+\f
+/* 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 &section_data->relax_info;
+}
+
+\f
+/* Coalescing literals may require a relocation to refer to a section in
+   a different input file, but the standard relocation information
+   cannot express that.  Instead, the reloc_bfd_fix structures are used
+   to "fix" the relocations that refer to sections in other input files.
+   These structures are kept on per-section lists.  The "src_type" field
+   records the relocation type in case there are multiple relocations on
+   the same location.  FIXME: This is ugly; an alternative might be to
+   add new symbols with the "owner" field to some other input file.  */
+
+struct reloc_bfd_fix_struct
+{
+  asection *src_sec;
+  bfd_vma src_offset;
+  unsigned src_type;                   /* Relocation type.  */
+  
+  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,
+          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 ((asection *, bfd_vma, unsigned));
+
+
+static reloc_bfd_fix *
+reloc_bfd_fix_init (src_sec, src_offset, src_type,
+                   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;
+
+  fix = (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix));
+  fix->src_sec = src_sec;
+  fix->src_offset = src_offset;
+  fix->src_type = 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 (sec, offset, type)
+     asection *sec;
+     bfd_vma offset;
+     unsigned type;
+{
+  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;
+}
+
+\f
+/* 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;
+
+  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)
+    {
+      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));
+    }
+}
+
+\f
+/* Extended basic blocks.  */
+
+/* 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
+{
+  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;
+
+  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;
+};
+
+
+enum ebb_target_enum
+{
+  EBB_NO_ALIGN = 0,
+  EBB_DESIRE_TGT_ALIGN,
+  EBB_REQUIRE_TGT_ALIGN,
+  EBB_REQUIRE_LOOP_ALIGN,
+  EBB_REQUIRE_ALIGN
+};
+
+
+/* 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.  */
+
+typedef struct proposed_action_struct proposed_action;
+
+struct proposed_action_struct
+{
+  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.  */
+};
+
+
+/* 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
+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;
+{
+  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;
+}
+
+
+/* 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.  */
+
+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;
+}
+
+
+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 bfd_boolean
+extend_ebb_bounds_backward (ebb)
+     ebb_t *ebb;
+{
+  property_table_entry *the_entry, *new_entry;
+
+  the_entry = &ebb->ptbl[ebb->start_ptbl_idx];
+
+  /* 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
+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;
+{
+  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);
+}
+
+
+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++;
+}
+
+\f
+/* Access to internal relocations, section contents and symbols.  */
+
+/* During relaxation, we need to modify relocations, section contents,
+   and symbol definitions, and we need to keep the original values from
+   being reloaded from the input files, i.e., we need to "pin" the
+   modified values in memory.  We also want to continue to observe the
+   setting of the "keep-memory" flag.  The following functions wrap the
+   standard BFD functions to take care of this for us.  */
+
+static Elf_Internal_Rela *
+retrieve_internal_relocs (abfd, sec, keep_memory)
+     bfd *abfd;
+     asection *sec;
+     bfd_boolean keep_memory;
+{
+  Elf_Internal_Rela *internal_relocs;
+
+  if ((sec->flags & SEC_LINKER_CREATED) != 0)
+    return NULL;
+
+  internal_relocs = elf_section_data (sec)->relocs;
+  if (internal_relocs == NULL)
+    internal_relocs = (_bfd_elf_link_read_relocs
+                      (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                       keep_memory));
+  return internal_relocs;
+}
+
+
+static void
+pin_internal_relocs (sec, internal_relocs)
+     asection *sec;
+     Elf_Internal_Rela *internal_relocs;
+{
+  elf_section_data (sec)->relocs = internal_relocs;
+}
+
+
+static void
+release_internal_relocs (sec, internal_relocs)
+     asection *sec;
+     Elf_Internal_Rela *internal_relocs;
+{
+  if (internal_relocs
+      && elf_section_data (sec)->relocs != internal_relocs)
+    free (internal_relocs);
+}
+
+
+static bfd_byte *
+retrieve_contents (abfd, sec, keep_memory)
+     bfd *abfd;
+     asection *sec;
+     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 (!bfd_malloc_and_get_section (abfd, sec, &contents))
+       {
+         if (contents != NULL)
+           free (contents);
+         return NULL;
+       }
+      if (keep_memory) 
+       elf_section_data (sec)->this_hdr.contents = contents;
+    }
+  return contents;
+}
+
+
+static void
+pin_contents (sec, contents)
+     asection *sec;
+     bfd_byte *contents;
+{
+  elf_section_data (sec)->this_hdr.contents = contents;
+}
+
+
+static void
+release_contents (sec, contents)
+     asection *sec;
+     bfd_byte *contents;
+{
+  if (contents && elf_section_data (sec)->this_hdr.contents != contents)
+    free (contents);
+}
+
+
+static Elf_Internal_Sym *
+retrieve_local_syms (input_bfd)
+     bfd *input_bfd;
+{
+  Elf_Internal_Shdr *symtab_hdr;
+  Elf_Internal_Sym *isymbuf;
+  size_t locsymcount;
+
+  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+  locsymcount = symtab_hdr->sh_info;
+
+  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
+  if (isymbuf == NULL && locsymcount != 0)
+    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
+                                   NULL, NULL, NULL);
+
+  /* Save the symbols for this input file so they won't be read again.  */
+  if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents)
+    symtab_hdr->contents = (unsigned char *) isymbuf;
+
+  return isymbuf;
+}
+
+\f
+/* Code for link-time relaxation.  */
+
+/* Initialization for relaxation: */
+static bfd_boolean analyze_relocations
+  PARAMS ((struct bfd_link_info *));
+static bfd_boolean find_relaxable_sections
+  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
+static bfd_boolean collect_source_relocs
+  PARAMS ((bfd *, asection *, struct bfd_link_info *));
+static bfd_boolean is_resolvable_asm_expansion
+  PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *,
+          struct bfd_link_info *, bfd_boolean *));
+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 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 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 
+elf_xtensa_relax_section (abfd, sec, link_info, again)
+     bfd *abfd;
+     asection *sec;
+     struct bfd_link_info *link_info;
+     bfd_boolean *again;
+{
+  static value_map_hash_table *values = NULL;
+  static bfd_boolean relocations_analyzed = FALSE;
+  xtensa_relax_info *relax_info;
+
+  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;
+
+  /* Don't mess with linker-created sections.  */
+  if ((sec->flags & SEC_LINKER_CREATED) != 0)
+    return TRUE;
+
+  relax_info = get_xtensa_relax_info (sec);
+  BFD_ASSERT (relax_info != NULL);
+
+  switch (relax_info->visited)
+    {
+    case 0:
+      /* 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 (!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;
+      break;
+
+    case 2:
+      if (!relax_section_symbols (abfd, sec))
+       return FALSE;
+      break;
+    }
+
+  relax_info->visited++;
+  return TRUE;
+}
+
+\f
+/* 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), 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)
+     struct bfd_link_info *link_info;
+{
+  bfd *abfd;
+  asection *sec;
+  bfd_boolean is_relaxable = FALSE;
+
+  /* Initialize the per-section relaxation info.  */
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+    for (sec = abfd->sections; sec != NULL; sec = sec->next)
+      {
+       init_xtensa_relax_info (sec);
+      }
+
+  /* Mark relaxable sections (and count relocations against each one).  */
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+    for (sec = abfd->sections; sec != NULL; sec = sec->next)
+      {
+       if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
+         return FALSE;
+      }
+
+  /* Bail out if there are no relaxable sections.  */
+  if (!is_relaxable)
+    return TRUE;
+
+  /* Allocate space for source_relocs.  */
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+    for (sec = abfd->sections; sec != NULL; sec = sec->next)
+      {
+       xtensa_relax_info *relax_info;
+
+       relax_info = get_xtensa_relax_info (sec);
+       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));
+         }
+      }
+
+  /* Collect info on relocations against each relaxable section.  */
+  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
+    for (sec = abfd->sections; sec != NULL; sec = sec->next)
+      {
+       if (!collect_source_relocs (abfd, sec, 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 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
+   relaxable literal section.  */
+
+static bfd_boolean
+find_relaxable_sections (abfd, sec, link_info, is_relaxable_p)
+     bfd *abfd;
+     asection *sec;
+     struct bfd_link_info *link_info;
+     bfd_boolean *is_relaxable_p;
+{
+  Elf_Internal_Rela *internal_relocs;
+  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);
+  if (internal_relocs == NULL) 
+    return ok;
+
+  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
+  if (contents == NULL && sec->size != 0)
+    {
+      ok = FALSE;
+      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];
+      r_reloc r_rel;
+      asection *target_sec;
+      xtensa_relax_info *target_relax_info;
+
+      /* 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 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_l32r_relocation (abfd, sec, contents, irel)
+         && r_reloc_is_defined (&r_rel))
+       {
+         /* Mark the target section as relaxable.  */
+         target_relax_info->is_relaxable_literal_section = TRUE;
+         *is_relaxable_p = TRUE;
+       }
+    }
+
+ error_return:
+  release_contents (sec, contents);
+  release_internal_relocs (sec, internal_relocs);
+  return ok;
+}
+
+
+/* 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)
+     bfd *abfd;
+     asection *sec;
+     struct bfd_link_info *link_info;
+{
+  Elf_Internal_Rela *internal_relocs;
+  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)
+    {
+      ok = FALSE;
+      goto error_return;
+    }
+
+  /* Record relocations against relaxable literal sections.  */
+  for (i = 0; i < sec->reloc_count; i++) 
+    {
+      Elf_Internal_Rela *irel = &internal_relocs[i];
+      r_reloc r_rel;
+      asection *target_sec;
+      xtensa_relax_info *target_relax_info;
+
+      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_asm_section))
+       {
+         xtensa_opcode opcode = XTENSA_UNDEFINED;
+         int opnd = -1;
+         bfd_boolean is_abs_literal = FALSE;
+
+         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));
+           }
+
+         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, opcode, opnd,
+                                is_abs_literal);
+           }
+       }
+    }
+
+  /* Now get rid of ASM_EXPAND relocations.  At this point, the
+     src_relocs array for the target literal section may still be
+     incomplete, but it must at least contain the entries for the L32R
+     relocations associated with ASM_EXPANDs because they were just
+     added in the preceding loop over the relocations.  */
+
+  for (i = 0; i < sec->reloc_count; i++) 
+    {
+      Elf_Internal_Rela *irel = &internal_relocs[i];
+      bfd_boolean is_reachable;
+
+      if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
+                                       &is_reachable))
+       continue;
+
+      if (is_reachable)
+       {
+         Elf_Internal_Rela *l32r_irel;
+         r_reloc r_rel;
+         asection *target_sec;
+         xtensa_relax_info *target_relax_info;
+
+         /* Mark the source_reloc for the L32R so that it will be
+            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, 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_asm_section))
+           {
+             source_reloc *s_reloc;
+
+             /* Search the source_relocs for the entry corresponding to
+                the l32r_irel.  Note: The src_relocs array is not yet
+                sorted, but it wouldn't matter anyway because we're
+                searching by source offset instead of target offset.  */
+             s_reloc = find_source_reloc (target_relax_info->src_relocs, 
+                                          target_relax_info->src_next,
+                                          sec, l32r_irel);
+             BFD_ASSERT (s_reloc);
+             s_reloc->is_null = TRUE;
+           }
+
+         /* Convert this reloc to ASM_SIMPLIFY.  */
+         irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
+                                      R_XTENSA_ASM_SIMPLIFY);
+         l32r_irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+
+         pin_internal_relocs (sec, internal_relocs);
+       }
+      else
+       {
+         /* It is resolvable but doesn't reach.  We resolve now
+            by eliminating the relocation -- the call will remain
+            expanded into L32R/CALLX.  */
+         irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+         pin_internal_relocs (sec, internal_relocs);
+       }
+    }
+
+ error_return:
+  release_contents (sec, contents);
+  release_internal_relocs (sec, internal_relocs);
+  return ok;
+}
+
+
+/* Return TRUE if the asm expansion can be resolved.  Generally it can
+   be resolved on a final link or when a partial link locates it in the
+   same section as the target.  Set "is_reachable" flag if the target of
+   the call is within the range of a direct call, given the current VMA
+   for this section and the target section.  */
+
+bfd_boolean
+is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
+                            is_reachable_p)
+     bfd *abfd;
+     asection *sec;
+     bfd_byte *contents;
+     Elf_Internal_Rela *irel;
+     struct bfd_link_info *link_info;
+     bfd_boolean *is_reachable_p;
+{
+  asection *target_sec;
+  bfd_vma target_offset;
+  r_reloc r_rel;
+  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;
+
+  if (contents == NULL)
+    return FALSE;
+
+  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, &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, contents, sec_size);
+  if (!r_reloc_is_defined (&r_rel))
+    return FALSE;
+
+  target_sec = r_reloc_get_section (&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
+     non-PIC calls on systems that use shared libraries, but the linker
+     shouldn't crash regardless.  */
+  if (!target_sec->output_section)
+    return FALSE;
+      
+  /* For relocatable sections, we can only simplify when the output
+     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
+         || is_reloc_sym_weak (abfd, irel)))
+    return FALSE;
+
+  self_address = (sec->output_section->vma
+                 + sec->output_offset + irel->r_offset + 3);
+  dest_address = (target_sec->output_section->vma
+                 + target_sec->output_offset + target_offset);
+      
+  *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))
+    return FALSE;
+
+  return TRUE;
+}
+
+
+static Elf_Internal_Rela *
+find_associated_l32r_irel (abfd, sec, contents, other_irel, internal_relocs)
+     bfd *abfd;
+     asection *sec;
+     bfd_byte *contents;
+     Elf_Internal_Rela *other_irel;
+     Elf_Internal_Rela *internal_relocs;
+{
+  unsigned i;
 
-  /* Collect info on relocations against each relaxable section.  */
-  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
-    for (sec = abfd->sections; sec != NULL; sec = sec->next)
-      {
-       if (!collect_source_relocs (abfd, sec, link_info))
-         return FALSE;
-      }
+  for (i = 0; i < sec->reloc_count; i++) 
+    {
+      Elf_Internal_Rela *irel = &internal_relocs[i];
 
-  return TRUE;
+      if (irel == other_irel)
+       continue;
+      if (irel->r_offset != other_irel->r_offset)
+       continue;
+      if (is_l32r_relocation (abfd, sec, contents, irel))
+       return irel;
+    }
+
+  return NULL;
 }
 
 
-/* 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
-   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
-   relaxable literal section.  */
+/* 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.
 
-static bfd_boolean
-find_relaxable_sections (abfd, sec, link_info, is_relaxable_p)
+   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;
-     bfd_boolean *is_relaxable_p;
 {
-  Elf_Internal_Rela *internal_relocs;
+  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 == NULL) 
-    return ok;
 
+  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)
+  if (contents == NULL && sec_size != 0)
     {
       ok = FALSE;
       goto error_return;
     }
 
-  for (i = 0; i < sec->reloc_count; i++) 
+  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];
-      r_reloc r_rel;
-      asection *target_sec;
-      xtensa_relax_info *target_relax_info;
+      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;
 
-      r_reloc_init (&r_rel, abfd, irel);
+      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;
+       }
 
-      target_sec = r_reloc_get_section (&r_rel);
-      target_relax_info = get_xtensa_relax_info (target_sec);
-      if (!target_relax_info)
-       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++;
+       }
 
-      /* Count relocations against the target section.  */
-      target_relax_info->src_count++;
+      if (the_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM)
+         /* NO_REORDER is OK */
+       continue;
 
-      if (is_literal_section (target_sec)
-         && is_l32r_relocation (sec, contents, irel)
-         && r_reloc_is_defined (&r_rel))
+      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))
        {
-         /* Mark the target section as relaxable.  */
-         target_relax_info->is_relaxable_literal_section = TRUE;
-         *is_relaxable_p = TRUE;
+         /* 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);
     }
 
- error_return:
+#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;
 }
 
 
-/* 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.  */
+/* Find all of the possible actions for an extended basic block.  */
 
-static bfd_boolean
-collect_source_relocs (abfd, sec, link_info)
-     bfd *abfd;
-     asection *sec;
-     struct bfd_link_info *link_info;
+bfd_boolean
+compute_ebb_proposed_actions (ebb_table)
+     ebb_constraint *ebb_table;
 {
-  Elf_Internal_Rela *internal_relocs;
-  bfd_byte *contents;
-  bfd_boolean ok = TRUE;
-  unsigned i;
+  const ebb_t *ebb = &ebb_table->ebb;
+  unsigned rel_idx = ebb->start_reloc_idx;
+  property_table_entry *entry, *start_entry, *end_entry;
 
-  internal_relocs = retrieve_internal_relocs (abfd, sec, 
-                                             link_info->keep_memory);
-  if (internal_relocs == NULL) 
-    return ok;
+  start_entry = &ebb->ptbl[ebb->start_ptbl_idx];
+  end_entry = &ebb->ptbl[ebb->end_ptbl_idx];
 
-  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
-  if (contents == NULL && sec->size != 0)
+  for (entry = start_entry; entry <= end_entry; entry++)
     {
-      ok = FALSE;
-      goto error_return;
-    }
+      bfd_vma offset, start_offset, end_offset;
+      bfd_size_type insn_len;
 
-  /* Record relocations against relaxable literal sections.  */
-  for (i = 0; i < sec->reloc_count; i++) 
-    {
-      Elf_Internal_Rela *irel = &internal_relocs[i];
-      r_reloc r_rel;
-      asection *target_sec;
-      xtensa_relax_info *target_relax_info;
+      start_offset = entry->address - ebb->sec->vma;
+      end_offset = entry->address + entry->size - ebb->sec->vma;
 
-      r_reloc_init (&r_rel, abfd, irel);
+      if (entry == start_entry)
+       start_offset = ebb->start_offset;
+      if (entry == end_entry)
+       end_offset = ebb->end_offset;
+      offset = start_offset;
 
-      target_sec = r_reloc_get_section (&r_rel);
-      target_relax_info = get_xtensa_relax_info (target_sec);
+      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;
 
-      if (target_relax_info
-         && target_relax_info->is_relaxable_literal_section)
+         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;
-         xtensa_operand opnd;
-         source_reloc *s_reloc;
-         int src_next;
 
-         src_next = target_relax_info->src_next++;
-         s_reloc = &target_relax_info->src_relocs[src_next];
+         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;
 
-         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));
+             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;
+           }
 
-         init_source_reloc (s_reloc, sec, &r_rel, opnd);
+         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;
        }
     }
 
-  /* Now get rid of ASM_EXPAND relocations.  At this point, the
-     src_relocs array for the target literal section may still be
-     incomplete, but it must at least contain the entries for the L32R
-     relocations associated with ASM_EXPANDs because they were just
-     added in the preceding loop over the relocations.  */
+  if (ebb->ends_unreachable)
+    {
+      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
+                         ta_fill, ebb->end_offset, 0, TRUE);
+    }
 
-  for (i = 0; i < sec->reloc_count; i++) 
+  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++)
     {
-      Elf_Internal_Rela *irel = &internal_relocs[i];
-      bfd_boolean is_reachable;
+      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;
 
-      if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
-                                       &is_reachable))
-       continue;
+      proposed_action *action = NULL;
+      int align = (1 << ebb_table->ebb.sec->alignment_power);
 
-      if (is_reachable)
-       {
-         Elf_Internal_Rela *l32r_irel;
-         r_reloc r_rel;
-         asection *target_sec;
-         xtensa_relax_info *target_relax_info;
+      seg_idx_start = seg_idx_end;
 
-         /* 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,
-                                                irel, internal_relocs);
-         if (l32r_irel == NULL)
-           continue;
+      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;
 
-         r_reloc_init (&r_rel, abfd, l32r_irel);
+      if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable)
+       requires_text_end_align = TRUE;
 
-         target_sec = r_reloc_get_section (&r_rel);
-         target_relax_info = get_xtensa_relax_info (target_sec);
+      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;
 
-         if (target_relax_info
-             && target_relax_info->is_relaxable_literal_section)
+         for (j = 0; j < longcall_count; j++)
            {
-             source_reloc *s_reloc;
+             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;
+               }
+           }
+       }
 
-             /* Search the source_relocs for the entry corresponding to
-                the l32r_irel.  Note: The src_relocs array is not yet
-                sorted, but it wouldn't matter anyway because we're
-                searching by source offset instead of target offset.  */
-             s_reloc = find_source_reloc (target_relax_info->src_relocs, 
-                                          target_relax_info->src_next,
-                                          sec, l32r_irel);
-             BFD_ASSERT (s_reloc);
-             s_reloc->is_null = TRUE;
+      /* 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;
            }
+       }
+    }
 
-         /* Convert this reloc to ASM_SIMPLIFY.  */
-         irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
-                                      R_XTENSA_ASM_SIMPLIFY);
-         l32r_irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
+  /* Now we move on to some local opts.  Try to remove each of the
+     remaining longcalls.  */
 
-         pin_internal_relocs (sec, internal_relocs);
-       }
-      else
+  if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable)
+    {
+      removed_bytes = 0;
+      for (i = 0; i < ebb_table->action_count; i++)
        {
-         /* It is resolvable but doesn't reach.  We resolve now
-            by eliminating the relocation -- the call will remain
-            expanded into L32R/CALLX.  */
-         irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
-         pin_internal_relocs (sec, internal_relocs);
+         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;
        }
     }
 
- error_return:
-  release_contents (sec, contents);
-  release_internal_relocs (sec, internal_relocs);
-  return ok;
+  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;
 }
 
 
-/* Return TRUE if the asm expansion can be resolved.  Generally it can
-   be resolved on a final link or when a partial link locates it in the
-   same section as the target.  Set "is_reachable" flag if the target of
-   the call is within the range of a direct call, given the current VMA
-   for this section and the target section.  */
+/* 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.  */
 
-bfd_boolean
-is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
-                            is_reachable_p)
+static bfd_boolean
+check_section_ebb_pcrels_fit (abfd, sec, contents, internal_relocs, constraint)
      bfd *abfd;
      asection *sec;
      bfd_byte *contents;
-     Elf_Internal_Rela *irel;
-     struct bfd_link_info *link_info;
-     bfd_boolean *is_reachable_p;
+     Elf_Internal_Rela *internal_relocs;
+     const ebb_constraint *constraint;
 {
-  asection *target_sec;
-  bfd_vma target_offset;
-  r_reloc r_rel;
-  xtensa_opcode opcode, direct_call_opcode;
-  bfd_vma self_address;
-  bfd_vma dest_address;
+  unsigned i, j;
+  Elf_Internal_Rela *irel;
+  xtensa_relax_info *relax_info;
 
-  *is_reachable_p = FALSE;
+  relax_info = get_xtensa_relax_info (sec);
 
-  if (contents == NULL)
-    return FALSE;
+  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;
 
-  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND) 
-    return FALSE;
-  
-  opcode = get_expanded_call_opcode (contents + irel->r_offset,
-                                    sec->size - irel->r_offset);
-  
-  direct_call_opcode = swap_callx_for_call_opcode (opcode);
-  if (direct_call_opcode == XTENSA_UNDEFINED)
-    return FALSE;
+      irel = &internal_relocs[i];
+      r_type = ELF32_R_TYPE (irel->r_info);
 
-  /* Check and see that the target resolves.  */
-  r_reloc_init (&r_rel, abfd, irel);
-  if (!r_reloc_is_defined (&r_rel))
-    return FALSE;
+      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;
 
-  target_sec = r_reloc_get_section (&r_rel);
-  target_offset = r_reloc_get_target_offset (&r_rel);
+      r_reloc_init (&r_rel, abfd, irel, contents,
+                   bfd_get_section_limit (abfd, sec));
 
-  /* 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
-     non-PIC calls on systems that use shared libraries, but the linker
-     shouldn't crash regardless.  */
-  if (!target_sec->output_section)
-    return FALSE;
-      
-  /* For relocatable sections, we can only simplify when the output
-     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))
-    return FALSE;
+      if (r_reloc_get_section (&r_rel) != sec)
+       continue;
 
-  self_address = (sec->output_section->vma
-                 + sec->output_offset + irel->r_offset + 3);
-  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);
+      orig_self_offset = irel->r_offset;
+      orig_target_offset = r_rel.target_offset;
 
-  if ((self_address >> CALL_SEGMENT_BITS) !=
-      (dest_address >> CALL_SEGMENT_BITS))
+      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;
 }
 
 
-static Elf_Internal_Rela *
-find_associated_l32r_irel (sec, contents, other_irel, internal_relocs)
+void
+text_action_add_proposed (l, ebb_table, sec)
+     text_action_list *l;
+     const ebb_constraint *ebb_table;
      asection *sec;
-     bfd_byte *contents;
-     Elf_Internal_Rela *other_irel;
-     Elf_Internal_Rela *internal_relocs;
 {
   unsigned i;
 
-  for (i = 0; i < sec->reloc_count; i++) 
+  for (i = 0; i < ebb_table->action_count; i++)
     {
-      Elf_Internal_Rela *irel = &internal_relocs[i];
+      proposed_action *action = &ebb_table->actions[i];
 
-      if (irel == other_irel)
-       continue;
-      if (irel->r_offset != other_irel->r_offset)
+      if (!action->do_action)
        continue;
-      if (is_l32r_relocation (sec, contents, irel))
-       return irel;
+      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;
+       }
     }
+}
 
-  return NULL;
+
+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;
 }
 
+\f
 /* 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,115 +7524,378 @@ 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) 
+      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))
        {
-         /* First check that THIS and all the other relocs to this
-            literal will FIT if we move them to the new address.  */
+         ok = FALSE;
+         goto error_return;
+       }
+      last_target_offset = rel->r_rel.target_offset;
+    }
 
-         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
+#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))
            {
-             /* Relocations do not reach -- do not remove this literal.  */
-             val_map->loc = rel->r_rel;
+             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
-       {
-         /* 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);
-       }
+       val_map->loc = rel->r_rel;
+      *last_loc_is_prev_p = TRUE;
     }
 
-error_return:
-  release_contents (sec, contents);
-  release_internal_relocs (sec, internal_relocs);
-  return ok;
+  return TRUE;
 }
 
 
@@ -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;
 }
 
 \f
@@ -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))
     {
@@ -4699,118 +8216,522 @@ relax_section (abfd, sec, link_info)
       return relax_property_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)
-    {
-      ok = FALSE;
-      goto error_return;
-    }
+  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)
+    {
+      ok = FALSE;
+      goto error_return;
+    }
+
+  if (internal_relocs)
+    {
+      for (i = 0; i < sec->reloc_count; i++)
+       {
+         Elf_Internal_Rela *irel;
+         xtensa_relax_info *target_relax_info;
+         bfd_vma source_offset, old_source_offset;
+         r_reloc r_rel;
+         unsigned r_type;
+         asection *target_sec;
+
+         /* Locally change the source address.
+            Translate the target to the new target address.
+            If it points to this section and has been removed,
+            NULLify it.
+            Write it back.  */
+
+         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, 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,
+                                          irel->r_offset))
+               {
+                 /* Remove this relocation.  */
+                 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_text
+                   (&relax_info->action_list, irel->r_offset);
+                 pin_internal_relocs (sec, internal_relocs);
+                 continue;
+               }
+
+             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_asm_section))
+           {
+             r_reloc new_reloc;
+             reloc_bfd_fix *fix;
+             bfd_vma addend_displacement;
+
+             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_reloc),
+                                       addend_displacement, TRUE);
+             add_fix (sec, fix);
+           }
+
+         pin_internal_relocs (sec, internal_relocs);
+       }
+    }
+
+  if ((relax_info->is_relaxable_literal_section
+       || relax_info->is_relaxable_asm_section)
+      && relax_info->action_list.head)
+    {
+      /* 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);
+
+      /* The dot is the current fill location.  */
+#if DEBUG
+      print_action_list (stderr, &relax_info->action_list);
+#endif
+
+      for (action = relax_info->action_list.head; action;
+          action = action->next)
+       {
+         virtual_action = FALSE;
+         if (action->offset > orig_dot)
+           {
+             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;
+           }
+
+         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);
+
+      sec->size = final_size;
+    }
+
+ error_return:
+  release_internal_relocs (sec, internal_relocs);
+  release_contents (sec, contents);
+  return ok;
+}
+
+
+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;
 
-  if (internal_relocs)
-    {
-      for (i = 0; i < sec->reloc_count; i++) 
-       {
-         Elf_Internal_Rela *irel;
-         xtensa_relax_info *target_relax_info;
-         bfd_vma source_offset;
-         r_reloc r_rel;
-         unsigned r_type;
-         asection *target_sec;
+  return TRUE;
+}
 
-         /* Locally change the source address.
-            Translate the target to the new target address.
-            If it points to this section and has been removed,
-            NULLify it.
-            Write it back.  */
 
-         irel = &internal_relocs[i];
-         source_offset = irel->r_offset;
+/* Translate a fix given the mapping in the relax info for the target
+   section.  If it has already been translated, no work is required.  */
 
-         r_type = ELF32_R_TYPE (irel->r_info);
-         r_reloc_init (&r_rel, abfd, irel);
-       
-         if (relax_info->is_relaxable_literal_section)
-           {
-             if (r_type != R_XTENSA_NONE
-                 && find_removed_literal (&relax_info->removed_list,
-                                          irel->r_offset))
-               {
-                 /* Remove this relocation.  */
-                 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);
-                 continue;
-               }
-             source_offset =
-               offset_with_removed_literals (&relax_info->removed_list,
-                                             irel->r_offset);
-             irel->r_offset = source_offset;
-           }
+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;
 
-         target_sec = r_reloc_get_section (&r_rel);
-         target_relax_info = get_xtensa_relax_info (target_sec);
+  if (fix->translated)
+    return TRUE;
 
-         if (target_relax_info
-             && target_relax_info->is_relaxable_literal_section)
-           {
-             r_reloc new_rel;
-             reloc_bfd_fix *fix;
+  sec = fix->target_sec;
+  target_offset = fix->target_offset;
 
-             translate_reloc (&r_rel, &new_rel);
+  relax_info = get_xtensa_relax_info (sec);
+  if (!relax_info)
+    {
+      fix->translated = TRUE;
+      return TRUE;
+    }
 
-             /* 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.  */
+  new_fix = *fix;
 
-             fix = reloc_bfd_fix_init (sec, source_offset, r_type, 0,
-                                       r_reloc_get_section (&new_rel),
-                                       new_rel.target_offset);
-             add_fix (sec, 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;
+    }
 
-         pin_internal_relocs (sec, internal_relocs);
-       }
+  /* 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 (relax_info->is_relaxable_literal_section)
+  if (removed) 
     {
-      /* Walk through the contents and delete literals that are not needed 
-         anymore.  */
+      asection *new_sec;
 
-      unsigned long size = sec->size;
-      unsigned long removed = 0;
+      /* 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);
 
-      removed_literal *reloc = relax_info->removed_list.head;
-      for (; reloc; reloc = reloc->next) 
+      /* This was moved to some other address (possibly another section).  */
+      new_sec = r_reloc_get_section (&removed->to);
+      if (new_sec != sec) 
        {
-         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) 
+         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))
            {
-             BFD_ASSERT (start <= upper);
-             memmove (contents + start - removed - 4,
-                      contents + start,
-                      upper - start );
-             pin_contents (sec, contents);
+             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;
            }
-         removed += 4;
-         size -= 4;
        }
-
-      /* Change the section size.  */
-      sec->size = size;
+      target_offset = removed->to.target_offset;
+      new_fix.target_sec = new_sec;
     }
-  
- error_return:
-  release_internal_relocs (sec, internal_relocs);
-  release_contents (sec, contents);
-  return ok;
+
+  /* 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;
 }
 
 
@@ -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)
 \f
 /* "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);
 }
 
 \f
@@ -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;
+}
+
 \f
 /* 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
 
index c079a6a..c811de5 100644 (file)
@@ -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",
index 0069841..1df1840 100644 (file)
@@ -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
index 761e5c6..30ad80c 100644 (file)
@@ -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.
 
    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];
+
+
+xtensa_isa_status
+xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused)))
+{
+  return xtisa_errno;
+}
+
 
-static int
-opname_lookup_compare (const void *v1, const void *v2)
+char *
+xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused)))
 {
-  opname_lookup_entry *e1 = (opname_lookup_entry *)v1;
-  opname_lookup_entry *e2 = (opname_lookup_entry *)v2;
+  return xtisa_error_msg;
+}
 
-  return strcmp (e1->key, e2->key);
+
+#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)
+
+\f
+/* 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_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;
+
+  if (intisa->is_big_endian)
+    {
+      start = insn_size - 1;
+      increment = -1;
+    }
+  else
+    {
+      start = 0;
+      increment = 1;
+    }
+
+  /* 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)
+    {
+      xtisa_errno = xtensa_isa_buffer_overflow;
+      strcpy (xtisa_error_msg, "output buffer too small for instruction");
+      return XTENSA_UNDEFINED;
+    }
+
+  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;
+}
+
+
+/* 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)
+{
+  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 (intisa->is_big_endian)
+    {
+      start = max_size - 1;
+      increment = -1;
+    }
+  else
+    {
+      start = 0;
+      increment = 1;
+    }
+
+  fence_post = start + (num_chars * increment);
+  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
+
+  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);
+
+      insn[word_inx] |= (*cp & 0xff) << bit_inx;
+    }
+}
+
+
+\f
+/* ISA information.  */
+
+extern xtensa_isa_internal xtensa_modules;
+
 xtensa_isa
-xtensa_isa_init (void)
+xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p)
 {
-  xtensa_isa isa;
-  int mod;
+  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);
 
-  isa = xtensa_load_isa (0);
-  if (isa == 0)
+  /* 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++)
     {
-      fprintf (stderr, "Failed to initialize Xtensa base ISA module\n");
-      return NULL;
+      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);
+
+  /* Set up the user & system sysreg number tables.  */
+  for (is_user = 0; is_user < 2; is_user++)
+    {
+      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);
+
+  isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) /
+                      sizeof (xtensa_insnbuf_word));
+
+  return (xtensa_isa) isa;
+}
+
+
+void
+xtensa_isa_free (xtensa_isa isa)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  int n;
+
+  /* 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 (intisa->opname_lookup_table)
+    {
+      free (intisa->opname_lookup_table);
+      intisa->opname_lookup_table = 0;
     }
 
-  for (mod = 1; xtensa_isa_modules[mod].get_num_opcodes_fn; mod++)
+  if (intisa->state_lookup_table)
     {
-      if (!xtensa_extend_isa (isa, mod))
+      free (intisa->state_lookup_table);
+      intisa->state_lookup_table = 0;
+    }
+
+  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])
        {
-         fprintf (stderr, "Failed to initialize Xtensa TIE ISA module\n");
-         return NULL;
+         free (intisa->sysreg_table[n]);
+         intisa->sysreg_table[n] = 0;
        }
     }
-
-  return isa;
+
+  if (intisa->interface_lookup_table)
+    {
+      free (intisa->interface_lookup_table);
+      intisa->interface_lookup_table = 0;
+    }
+
+  if (intisa->funcUnit_lookup_table)
+    {
+      free (intisa->funcUnit_lookup_table);
+      intisa->funcUnit_lookup_table = 0;
+    }
+}
+
+
+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;
+
+  num_opcodes = xtensa_isa_num_opcodes (isa);
+  for (opcode = 0; opcode < num_opcodes; opcode++)
+    {
+      num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode);
+      for (i = 0; i < num_uses; i++)
+       {
+         use = xtensa_opcode_funcUnit_use (isa, opcode, i);
+         stage = use->stage;
+         if (stage > max_stage)
+           max_stage = stage;
+       }
+    }
+
+  return max_stage + 1;
+}
+
+
+int
+xtensa_isa_num_formats (xtensa_isa isa)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  return intisa->num_formats;
+}
+
+
+int
+xtensa_isa_num_opcodes (xtensa_isa isa)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  return intisa->num_opcodes;
+}
+
+
+int
+xtensa_isa_num_regfiles (xtensa_isa isa)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  return intisa->num_regfiles;
+}
+
+
+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;
+}
+
+
+\f
+/* 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 *intisa = (xtensa_isa_internal *) isa;
+  int fmt;
+
+  if (!fmtname || !*fmtname)
+    {
+      xtisa_errno = xtensa_isa_bad_format;
+      strcpy (xtisa_error_msg, "invalid format name");
+      return XTENSA_UNDEFINED;
+    }
+
+  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_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_FORMAT (intisa, fmt, -1);
+  (*intisa->formats[fmt].encode_fn) (insn);
+  return 0;
+}
+
+
+int
+xtensa_format_length (xtensa_isa isa, xtensa_format fmt)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+  return intisa->formats[fmt].length;
+}
+
+
+int
+xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  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_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;
+  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_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;
+  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;
+}
+
+
+\f
+/* 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;
+  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 (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_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
+                     const xtensa_insnbuf slotbuf)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  int slot_id;
+  xtensa_opcode opc;
+
+  CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED);
+  CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED);
+
+  slot_id = intisa->formats[fmt].slot_id[slot];
+
+  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;
+  int slot_id;
+  xtensa_opcode_encode_fn encode_fn;
+
+  CHECK_FORMAT (intisa, fmt, -1);
+  CHECK_SLOT (intisa, fmt, slot, -1);
+  CHECK_OPCODE (intisa, opc, -1);
+
+  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;
+}
+
+
+const char *
+xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  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_opcode_is_call (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_CALL) != 0)
+    return 1;
+  return 0;
+}
+
+
+int
+xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  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_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  int iclass_id;
+
+  CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED);
+  iclass_id = intisa->opcodes[opc].iclass_id;
+  return intisa->iclasses[iclass_id].num_stateOperands;
+}
+
+
+int
+xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  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];
+}
+
+
+\f
+/* Operand information.  */
+
+
+#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_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_isa isa, xtensa_opcode opc, int opnd)
+{
+  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;
+}
+
+
+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_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;
+}
+
+
+int
+xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                         xtensa_format fmt, int slot,
+                         xtensa_insnbuf slotbuf, uint32 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;
 }
 
-/* ISA information.  */
 
-static int
-xtensa_check_isa_config (xtensa_isa_internal *isa,
-                        struct config_struct *config_table)
+int
+xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                      uint32 *valp)
 {
-  int i, j;
-
-  if (!config_table)
-    {
-      fprintf (stderr, "Error: Empty configuration table in ISA DLL\n");
-      return 0;
-    }
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_operand_internal *intop;
+  uint32 test_val, orig_val;
 
-  /* For the first module, save a pointer to the table and record the
-     specified endianness and availability of the density option.  */
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return -1;
 
-  if (isa->num_modules == 0)
+  if (!intop->encode)
     {
-      int found_memory_order = 0;
+      /* 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.  */
 
-      isa->config = config_table;
-      isa->has_density = 1;  /* Default to have density option.  */
+      xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+      static xtensa_insnbuf tmpbuf = 0;
+      int slot_id;
 
-      for (i = 0; config_table[i].param_name; i++)
+      if (!tmpbuf)
        {
-         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);
-           }
+         tmpbuf = xtensa_insnbuf_alloc (isa);
+         CHECK_ALLOC (tmpbuf, -1);
        }
-      if (!found_memory_order)
+
+      /* A default operand is always associated with a field,
+        but check just to be sure....  */
+      if (intop->field_id == XTENSA_UNDEFINED)
        {
-         fprintf (stderr, "Error: \"IsaMemoryOrder\" missing from "
-                  "configuration table in ISA DLL\n");
-         return 0;
+         xtisa_errno = xtensa_isa_internal_error;
+         strcpy (xtisa_error_msg, "operand has no field");
+         return -1;
        }
 
-      return 1;
-    }
-
-  /* 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. */
-
-  for (i = 0; config_table[i].param_name; i++)
-    {
-      for (j = 0; isa->config[j].param_name; j++)
+      /* Find some slot that includes the field.  */
+      for (slot_id = 0; slot_id < intisa->num_slots; slot_id++)
        {
-         if (!strcmp (config_table[i].param_name, isa->config[j].param_name))
+         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)
            {
-             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;
+             (*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 1;
+  return 0;
 }
 
 
-static int
-xtensa_add_isa (xtensa_isa_internal *isa, libisa_module_specifier libisa)
+int
+xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                      uint32 *valp)
 {
-  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;
-
-  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;
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_operand_internal *intop;
 
-  if (!get_num_opcodes_fn || !get_opcodes_fn || !decode_insn_fn
-      || (!get_config_table_fn && isa->num_modules == 0))
-    return 0;
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return -1;
 
-  if (get_config_table_fn
-      && !xtensa_check_isa_config (isa, get_config_table_fn ()))
+  /* Use identity function for "default" operands.  */
+  if (!intop->decode)
     return 0;
 
-  prev_num_opcodes = isa->num_opcodes;
-  new_num_opcodes = (*get_num_opcodes_fn) ();
-
-  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));
-
-  opcodes = (*get_opcodes_fn) ();
-
-  insn_size = isa->insn_size;
-  for (opc = 0; opc < new_num_opcodes; opc++)
+  if ((*intop->decode) (valp))
     {
-      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;
+      xtisa_errno = xtensa_isa_bad_value;
+      sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
+      return -1;
     }
+  return 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_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_operand_internal *intop;
 
-  /* Check for duplicate opcode names.  */
-  for (opc = 1; opc < isa->num_opcodes; opc++)
-    {
-      if (!opname_lookup_compare (&isa->opname_lookup_table[opc-1],
-                                 &isa->opname_lookup_table[opc]))
-       {
-         fprintf (stderr, "Error: Duplicate TIE opcode \"%s\"\n",
-                  isa->opname_lookup_table[opc].key);
-         return 0;
-       }
-    }
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return XTENSA_UNDEFINED;
 
-  this_module = isa->num_modules;
-  isa->num_modules += 1;
+  if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0)
+    return 1;
+  return 0;
+}
 
-  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;
+xtensa_regfile
+xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd)
+{
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_operand_internal *intop;
 
-  xtensa_default_isa = isa;
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return XTENSA_UNDEFINED;
 
-  return 1;    /* Library was successfully added.  */
+  return intop->regfile;
 }
 
 
-xtensa_isa
-xtensa_load_isa (libisa_module_specifier libisa)
+int
+xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd)
 {
-  xtensa_isa_internal *isa;
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_operand_internal *intop;
 
-  isa = (xtensa_isa_internal *) malloc (sizeof (xtensa_isa_internal));
-  memset (isa, 0, sizeof (xtensa_isa_internal));
-  if (!xtensa_add_isa (isa, libisa))
-    {
-      xtensa_isa_free (isa);
-      return NULL;
-    }
-  return (xtensa_isa) isa;
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return XTENSA_UNDEFINED;
+
+  return intop->num_regs;
 }
 
 
 int
-xtensa_extend_isa (xtensa_isa isa, libisa_module_specifier libisa)
+xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return xtensa_add_isa (intisa, libisa);
+  xtensa_operand_internal *intop;
+
+  intop = get_operand (intisa, opc, opnd);
+  if (!intop) return XTENSA_UNDEFINED;
+
+  if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0)
+    return 1;
+  return 0;
 }
 
 
-void
-xtensa_isa_free (xtensa_isa isa)
+int
+xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd)
 {
   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);
+  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_insn_maxlength (xtensa_isa isa)
+xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                        uint32 *valp, uint32 pc)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return intisa->insn_size;
+  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;
 }
 
 
 int
-xtensa_insnbuf_size (xtensa_isa isa)
+xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                          uint32 *valp, uint32 pc)
 {
-  xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
-  return intisa->insnbuf_size;
+  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;
 }
 
 
-int
-xtensa_num_opcodes (xtensa_isa isa)
+\f
+/* State Operands.  */
+
+
+#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)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return intisa->num_opcodes;
+  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;
 }
 
 
-xtensa_opcode
-xtensa_opcode_lookup (xtensa_isa isa, const char *opname)
+char
+xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  opname_lookup_entry entry, *result;
+  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;
+}
 
-  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;
+\f
+/* Interface Operands.  */
+
+
+#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;
+  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];
 }
 
 
-xtensa_opcode
-xtensa_decode_insn (xtensa_isa isa, const xtensa_insnbuf insn)
+\f
+/* 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, 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;
-  }
+  int n;
+
+  if (!name || !*name)
+    {
+      xtisa_errno = xtensa_isa_bad_regfile;
+      strcpy (xtisa_error_msg, "invalid regfile name");
+      return XTENSA_UNDEFINED;
+    }
+
+  /* The expected number of regfiles is small; use a linear search.  */
+  for (n = 0; n < intisa->num_regfiles; n++)
+    {
+      if (!strcmp (intisa->regfiles[n].name, name))
+       return n;
+    }
+
+  xtisa_errno = xtensa_isa_bad_regfile;
+  sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name);
   return XTENSA_UNDEFINED;
 }
 
 
-/* Opcode information.  */
-
-void
-xtensa_encode_insn (xtensa_isa isa, xtensa_opcode opc, xtensa_insnbuf insn)
+xtensa_regfile
+xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname)
 {
   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;
 
-  /* Convert length to 32-bit words.  */
-  len = (len + 3) / 4;
+  if (!shortname || !*shortname)
+    {
+      xtisa_errno = xtensa_isa_bad_regfile;
+      strcpy (xtisa_error_msg, "invalid regfile shortname");
+      return XTENSA_UNDEFINED;
+    }
 
-  /* Copy the template.  */
-  for (n = 0; n < len; n++)
-    insn[n] = template[n];
+  /* 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;
+    }
 
-  /* Fill any unused buffer space with zeros.  */
-  for ( ; n < intisa->insnbuf_size; n++)
-    insn[n] = 0;
+  xtisa_errno = xtensa_isa_bad_regfile;
+  sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized",
+          shortname);
+  return XTENSA_UNDEFINED;
 }
 
 
 const char *
-xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc)
+xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return intisa->opcode_table[opc]->name;
+  CHECK_REGFILE (intisa, rf, NULL);
+  return intisa->regfiles[rf].name;
 }
 
 
-int
-xtensa_insn_length (xtensa_isa isa, xtensa_opcode opc)
+const char *
+xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return intisa->opcode_table[opc]->length;
+  CHECK_REGFILE (intisa, rf, NULL);
+  return intisa->regfiles[rf].shortname;
 }
 
 
-int
-xtensa_insn_length_from_first_byte (xtensa_isa isa, char first_byte)
+xtensa_regfile
+xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf)
 {
   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);
+  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+  return intisa->regfiles[rf].parent;
 }
 
 
 int
-xtensa_num_operands (xtensa_isa isa, xtensa_opcode opc)
+xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  return intisa->opcode_table[opc]->iclass->num_operands;
+  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+  return intisa->regfiles[rf].num_bits;
 }
 
 
-xtensa_operand
-xtensa_get_operand (xtensa_isa isa, xtensa_opcode opc, int opnd)
+int
+xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf)
 {
   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];
+  CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED);
+  return intisa->regfiles[rf].num_entries;
 }
 
+\f
+/* Processor States.  */
 
-/* Operand information.  */
 
-char *
-xtensa_operand_kind (xtensa_operand opnd)
-{
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return intop->operand_kind;
-}
+#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)
 
 
-char
-xtensa_operand_inout (xtensa_operand opnd)
+xtensa_state
+xtensa_state_lookup (xtensa_isa isa, const char *name)
 {
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return intop->inout;
-}
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  xtensa_lookup_entry entry, *result;
 
+  if (!name || !*name)
+    {
+      xtisa_errno = xtensa_isa_bad_state;
+      strcpy (xtisa_error_msg, "invalid state name");
+      return XTENSA_UNDEFINED;
+    }
 
-uint32
-xtensa_operand_get_field (xtensa_operand opnd, const xtensa_insnbuf insn)
-{
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return (*intop->get_field) (insn);
-}
+  entry.key = name;
+  result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states,
+                   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
+  if (!result)
+    {
+      xtisa_errno = xtensa_isa_bad_state;
+      sprintf (xtisa_error_msg, "state \"%s\" not recognized", name);
+      return XTENSA_UNDEFINED;
+    }
 
-void
-xtensa_operand_set_field (xtensa_operand opnd, xtensa_insnbuf insn, uint32 val)
-{
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return (*intop->set_field) (insn, val);
+  return result->u.state;
 }
 
 
-xtensa_encode_result
-xtensa_operand_encode (xtensa_operand opnd, uint32 *valp)
+const char *
+xtensa_state_name (xtensa_isa isa, xtensa_state st)
 {
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return (*intop->encode) (valp);
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_STATE (intisa, st, NULL);
+  return intisa->states[st].name;
 }
 
 
-uint32
-xtensa_operand_decode (xtensa_operand opnd, uint32 val)
+int
+xtensa_state_num_bits (xtensa_isa isa, xtensa_state st)
 {
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return (*intop->decode) (val);
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_STATE (intisa, st, XTENSA_UNDEFINED);
+  return intisa->states[st].num_bits;
 }
 
 
 int
-xtensa_operand_isPCRelative (xtensa_operand opnd)
+xtensa_state_is_exported (xtensa_isa isa, xtensa_state st)
 {
-  xtensa_operand_internal *intop = (xtensa_operand_internal *) opnd;
-  return intop->isPCRelative;
+  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;
 }
 
+\f
+/* 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)
 
-uint32
-xtensa_operand_do_reloc (xtensa_operand opnd, uint32 addr, uint32 pc)
+
+xtensa_sysreg
+xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user)
 {
-  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;
+
+  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)
+    {
+      xtisa_errno = xtensa_isa_bad_sysreg;
+      strcpy (xtisa_error_msg, "sysreg not recognized");
+      return XTENSA_UNDEFINED;
+    }
+
+  return intisa->sysreg_table[is_user][num];
 }
 
 
-uint32
-xtensa_operand_undo_reloc (xtensa_operand opnd, uint32 offset, uint32 pc)
+xtensa_sysreg
+xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name)
 {
-  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_lookup_entry entry, *result;
 
+  if (!name || !*name)
+    {
+      xtisa_errno = xtensa_isa_bad_sysreg;
+      strcpy (xtisa_error_msg, "invalid sysreg name");
+      return XTENSA_UNDEFINED;
+    }
 
-/* Instruction buffers.  */
+  entry.key = name;
+  result = bsearch (&entry, intisa->sysreg_lookup_table, intisa->num_sysregs,
+                   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
 
-xtensa_insnbuf
-xtensa_insnbuf_alloc (xtensa_isa isa)
-{
-  return (xtensa_insnbuf) malloc (xtensa_insnbuf_size (isa) *
-                                 sizeof (xtensa_insnbuf_word));
+  if (!result)
+    {
+      xtisa_errno = xtensa_isa_bad_sysreg;
+      sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name);
+      return XTENSA_UNDEFINED;
+    }
+
+  return result->u.sysreg;
 }
 
 
-void
-xtensa_insnbuf_free (xtensa_insnbuf buf)
+const char *
+xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg)
 {
-  free( buf );
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_SYSREG (intisa, sysreg, NULL);
+  return intisa->sysregs[sysreg].name;
 }
 
 
-/* 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)
+int
+xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg)
 {
-  return byte_index / sizeof (xtensa_insnbuf_word);
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
+  return intisa->sysregs[sysreg].number;
 }
 
 
-static inline int
-byte_to_bit_index (int byte_index)
+int
+xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg)
 {
-  return (byte_index & 0x3) * 8;
+  xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
+  CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED);
+  if (intisa->sysregs[sysreg].is_user)
+    return 1;
+  return 0;
 }
 
+\f
+/* Interfaces.  */
 
-/* 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(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;
-  int insn_size = xtensa_insn_maxlength (intisa);
-  int fence_post, start, increment, i, byte_count;
-  xtensa_opcode opc;
+  xtensa_lookup_entry entry, *result;
 
-  if (intisa->is_big_endian)
+  if (!ifname || !*ifname)
     {
-      start = insn_size - 1;
-      increment = -1;
+      xtisa_errno = xtensa_isa_bad_interface;
+      strcpy (xtisa_error_msg, "invalid interface name");
+      return XTENSA_UNDEFINED;
     }
-  else
+
+  entry.key = ifname;
+  result = bsearch (&entry, intisa->interface_lookup_table,
+                   intisa->num_interfaces,
+                   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+  if (!result)
     {
-      start = 0;
-      increment = 1;
+      xtisa_errno = xtensa_isa_bad_interface;
+      sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname);
+      return XTENSA_UNDEFINED;
     }
 
-  /* 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;
+  return result->u.intf;
+}
 
-  byte_count = xtensa_insn_length (isa, opc);
-  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);
+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;
+}
 
-      *cp = (insn[word_inx] >> bit_inx) & 0xff;
-    }
+
+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;
 }
 
-/* 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)
+
+char
+xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf)
 {
   xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa;
-  int insn_size = xtensa_insn_maxlength (intisa);
-  int fence_post, start, increment, i;
+  CHECK_INTERFACE (intisa, intf, 0);
+  return intisa->interfaces[intf].inout;
+}
 
-  if (intisa->is_big_endian)
+
+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;
+}
+
+\f
+/* 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)
     {
-      start = insn_size - 1;
-      increment = -1;
+      xtisa_errno = xtensa_isa_bad_funcUnit;
+      strcpy (xtisa_error_msg, "invalid functional unit name");
+      return XTENSA_UNDEFINED;
     }
-  else
+
+  entry.key = fname;
+  result = bsearch (&entry, intisa->funcUnit_lookup_table,
+                   intisa->num_funcUnits,
+                   sizeof (xtensa_lookup_entry), xtensa_isa_name_compare);
+
+  if (!result)
     {
-      start = 0;
-      increment = 1;
+      xtisa_errno = xtensa_isa_bad_funcUnit;
+      sprintf (xtisa_error_msg,
+              "functional unit \"%s\" not recognized", fname);
+      return XTENSA_UNDEFINED;
     }
 
-  fence_post = start + (insn_size * increment);
-  memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word));
+  return result->u.fun;
+}
 
-  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);
 
-      insn[word_inx] |= (*cp & 0xff) << bit_inx;
-    }
+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;
 }
 
index e5d7682..bc0cf73 100644 (file)
 /* 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)
+\f
+/* 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
+
+\f
+/* 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
+
+\f
+/* 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)
+\f
+/* Functional units.  */
+
+static xtensa_funcUnit_internal funcUnits[] = {
+
+};
+
+\f
+/* Register files.  */
+
+static xtensa_regfile_internal regfiles[] = {
+  { "AR", "a", 0, 32, 64 }
+};
+
+\f
+/* Interfaces.  */
+
+static xtensa_interface_internal interfaces[] = {
+
+};
+
+\f
+/* 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
+};
+
+\f
+/* 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 }
+};
+
+\f
+/* 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_insnbuf_word template[] = { 0x00a00000 };
-  return &template[0];
-}
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_args[] = {
+  { { 6 /* art */ }, 'i' }
+};
 
-static xtensa_insnbuf
-addi_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00200c00 };
-  return &template[0];
-}
+static xtensa_arg_internal Iclass_xt_iclass_wsr_eps3_stateArgs[] = {
+  { { STATE_EPS3 }, 'o' }
+};
 
-static xtensa_insnbuf
-addi_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00b00000 };
-  return &template[0];
-}
+static xtensa_arg_internal Iclass_xt_iclass_xsr_eps3_args[] = {
+  { { 6 /* art */ }, 'm' }
+};
 
-static xtensa_insnbuf
-addmi_template (void)
+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 }
+};
+
+\f
+/*  Opcode encodings.  */
+
+static void
+Opcode_excw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x80200;
+}
+
+static void
+Opcode_rfe_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x300;
+}
+
+static void
+Opcode_rfde_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x2300;
+}
+
+static void
+Opcode_syscall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x500;
+}
+
+static void
+Opcode_simcall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x1500;
+}
+
+static void
+Opcode_call12_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x5c0000;
+}
+
+static void
+Opcode_call8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x580000;
+}
+
+static void
+Opcode_call4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x540000;
+}
+
+static void
+Opcode_callx12_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xf0000;
+}
+
+static void
+Opcode_callx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb0000;
+}
+
+static void
+Opcode_callx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x70000;
+}
+
+static void
+Opcode_entry_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6c0000;
+}
+
+static void
+Opcode_movsp_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x100;
+}
+
+static void
+Opcode_rotw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x804;
+}
+
+static void
+Opcode_retw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x60000;
+}
+
+static void
+Opcode_retw_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd10f;
+}
+
+static void
+Opcode_rfwo_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4300;
+}
+
+static void
+Opcode_rfwu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x5300;
+}
+
+static void
+Opcode_l32e_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x90;
+}
+
+static void
+Opcode_s32e_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x94;
+}
+
+static void
+Opcode_rsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4830;
+}
+
+static void
+Opcode_wsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4831;
+}
+
+static void
+Opcode_xsr_windowbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4816;
+}
+
+static void
+Opcode_rsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4930;
+}
+
+static void
+Opcode_wsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4931;
+}
+
+static void
+Opcode_xsr_windowstart_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4916;
+}
+
+static void
+Opcode_add_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xa000;
+}
+
+static void
+Opcode_addi_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb000;
+}
+
+static void
+Opcode_beqz_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xc800;
+}
+
+static void
+Opcode_bnez_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xcc00;
+}
+
+static void
+Opcode_ill_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd60f;
+}
+
+static void
+Opcode_l32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x8000;
+}
+
+static void
+Opcode_mov_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd000;
+}
+
+static void
+Opcode_movi_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xc000;
+}
+
+static void
+Opcode_nop_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd30f;
+}
+
+static void
+Opcode_ret_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd00f;
+}
+
+static void
+Opcode_s32i_n_Slot_inst16a_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x9000;
+}
+
+static void
+Opcode_addi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200c00;
+}
+
+static void
+Opcode_addmi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200d00;
+}
+
+static void
+Opcode_add_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x8;
+}
+
+static void
+Opcode_sub_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xc;
+}
+
+static void
+Opcode_addx2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x9;
+}
+
+static void
+Opcode_addx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xa;
+}
+
+static void
+Opcode_addx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb;
+}
+
+static void
+Opcode_subx2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd;
+}
+
+static void
+Opcode_subx4_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xe;
+}
+
+static void
+Opcode_subx8_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xf;
+}
+
+static void
+Opcode_and_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x1;
+}
+
+static void
+Opcode_or_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x2;
+}
+
+static void
+Opcode_xor_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x3;
+}
+
+static void
+Opcode_beqi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x680000;
+}
+
+static void
+Opcode_bnei_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x690000;
+}
+
+static void
+Opcode_bgei_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6b0000;
+}
+
+static void
+Opcode_blti_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6a0000;
+}
+
+static void
+Opcode_bbci_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700600;
+}
+
+static void
+Opcode_bbsi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700e00;
+}
+
+static void
+Opcode_bgeui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6f0000;
+}
+
+static void
+Opcode_bltui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6e0000;
+}
+
+static void
+Opcode_beq_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700100;
+}
+
+static void
+Opcode_bne_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700900;
+}
+
+static void
+Opcode_bge_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700a00;
+}
+
+static void
+Opcode_blt_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700200;
+}
+
+static void
+Opcode_bgeu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700b00;
+}
+
+static void
+Opcode_bltu_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700300;
+}
+
+static void
+Opcode_bany_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700800;
+}
+
+static void
+Opcode_bnone_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700000;
+}
+
+static void
+Opcode_ball_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700400;
+}
+
+static void
+Opcode_bnall_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700c00;
+}
+
+static void
+Opcode_bbc_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700500;
+}
+
+static void
+Opcode_bbs_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x700d00;
+}
+
+static void
+Opcode_beqz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x640000;
+}
+
+static void
+Opcode_bnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x650000;
+}
+
+static void
+Opcode_bgez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x670000;
+}
+
+static void
+Opcode_bltz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x660000;
+}
+
+static void
+Opcode_call0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x500000;
+}
+
+static void
+Opcode_callx0_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x30000;
+}
+
+static void
+Opcode_extui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x40;
+}
+
+static void
+Opcode_ill_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0;
+}
+
+static void
+Opcode_j_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x600000;
+}
+
+static void
+Opcode_jx_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xa0000;
+}
+
+static void
+Opcode_l16ui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200100;
+}
+
+static void
+Opcode_l16si_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200900;
+}
+
+static void
+Opcode_l32i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200200;
+}
+
+static void
+Opcode_l32r_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x100000;
+}
+
+static void
+Opcode_l8ui_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200000;
+}
+
+static void
+Opcode_loop_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6d0800;
+}
+
+static void
+Opcode_loopnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6d0900;
+}
+
+static void
+Opcode_loopgtz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6d0a00;
+}
+
+static void
+Opcode_movi_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200a00;
+}
+
+static void
+Opcode_moveqz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x38;
+}
+
+static void
+Opcode_movnez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x39;
+}
+
+static void
+Opcode_movltz_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x3a;
+}
+
+static void
+Opcode_movgez_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x3b;
+}
+
+static void
+Opcode_neg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x6;
+}
+
+static void
+Opcode_abs_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x1006;
+}
+
+static void
+Opcode_nop_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xf0200;
+}
+
+static void
+Opcode_ret_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x20000;
+}
+
+static void
+Opcode_s16i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200500;
+}
+
+static void
+Opcode_s32i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200600;
+}
+
+static void
+Opcode_s8i_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200400;
+}
+
+static void
+Opcode_ssr_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x4;
+}
+
+static void
+Opcode_ssl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x104;
+}
+
+static void
+Opcode_ssa8l_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x204;
+}
+
+static void
+Opcode_ssa8b_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x304;
+}
+
+static void
+Opcode_ssai_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x404;
+}
+
+static void
+Opcode_sll_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x1a;
+}
+
+static void
+Opcode_src_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x18;
+}
+
+static void
+Opcode_srl_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x19;
+}
+
+static void
+Opcode_sra_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x1b;
+}
+
+static void
+Opcode_slli_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x10;
+}
+
+static void
+Opcode_srai_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x12;
+}
+
+static void
+Opcode_srli_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x14;
+}
+
+static void
+Opcode_memw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xc0200;
+}
+
+static void
+Opcode_extw_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd0200;
+}
+
+static void
+Opcode_isync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x200;
+}
+
+static void
+Opcode_rsync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x10200;
+}
+
+static void
+Opcode_esync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x20200;
+}
+
+static void
+Opcode_dsync_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x30200;
+}
+
+static void
+Opcode_rsil_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x600;
+}
+
+static void
+Opcode_rsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x130;
+}
+
+static void
+Opcode_wsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x131;
+}
+
+static void
+Opcode_xsr_lend_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x116;
+}
+
+static void
+Opcode_rsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x230;
+}
+
+static void
+Opcode_wsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x231;
+}
+
+static void
+Opcode_xsr_lcount_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x216;
+}
+
+static void
+Opcode_rsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x30;
+}
+
+static void
+Opcode_wsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x31;
+}
+
+static void
+Opcode_xsr_lbeg_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x16;
+}
+
+static void
+Opcode_rsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x330;
+}
+
+static void
+Opcode_wsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x331;
+}
+
+static void
+Opcode_xsr_sar_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x316;
+}
+
+static void
+Opcode_rsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x530;
+}
+
+static void
+Opcode_wsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x531;
+}
+
+static void
+Opcode_xsr_litbase_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0x516;
+}
+
+static void
+Opcode_rsr_176_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb030;
+}
+
+static void
+Opcode_rsr_208_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd030;
+}
+
+static void
+Opcode_rsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xe630;
+}
+
+static void
+Opcode_wsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xe631;
+}
+
+static void
+Opcode_xsr_ps_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xe616;
+}
+
+static void
+Opcode_rsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb130;
+}
+
+static void
+Opcode_wsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb131;
+}
+
+static void
+Opcode_xsr_epc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb116;
+}
+
+static void
+Opcode_rsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd130;
+}
+
+static void
+Opcode_wsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd131;
+}
+
+static void
+Opcode_xsr_excsave1_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xd116;
+}
+
+static void
+Opcode_rsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb230;
+}
+
+static void
+Opcode_wsr_epc2_Slot_inst_encode (xtensa_insnbuf slotbuf)
+{
+  slotbuf[0] = 0xb231;
+}
+
+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)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200d00 };
-  return &template[0];
+  slotbuf[0] = 0x400;
 }
 
-static xtensa_insnbuf
-addx2_template (void)
+static void
+Opcode_break_n_Slot_inst16b_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000009 };
-  return &template[0];
+  slotbuf[0] = 0xd20f;
 }
 
-static xtensa_insnbuf
-addx4_template (void)
+static void
+Opcode_rsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x0000000a };
-  return &template[0];
+  slotbuf[0] = 0x9030;
 }
 
-static xtensa_insnbuf
-addx8_template (void)
+static void
+Opcode_wsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x0000000b };
-  return &template[0];
+  slotbuf[0] = 0x9031;
 }
 
-static xtensa_insnbuf
-and_template (void)
+static void
+Opcode_xsr_dbreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000001 };
-  return &template[0];
+  slotbuf[0] = 0x9016;
 }
 
-static xtensa_insnbuf
-ball_template (void)
+static void
+Opcode_rsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700400 };
-  return &template[0];
+  slotbuf[0] = 0xa030;
 }
 
-static xtensa_insnbuf
-bany_template (void)
+static void
+Opcode_wsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700800 };
-  return &template[0];
+  slotbuf[0] = 0xa031;
 }
 
-static xtensa_insnbuf
-bbc_template (void)
+static void
+Opcode_xsr_dbreakc0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700500 };
-  return &template[0];
+  slotbuf[0] = 0xa016;
 }
 
-static xtensa_insnbuf
-bbci_template (void)
+static void
+Opcode_rsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700600 };
-  return &template[0];
+  slotbuf[0] = 0x9130;
 }
 
-static xtensa_insnbuf
-bbs_template (void)
+static void
+Opcode_wsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700d00 };
-  return &template[0];
+  slotbuf[0] = 0x9131;
 }
 
-static xtensa_insnbuf
-bbsi_template (void)
+static void
+Opcode_xsr_dbreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700e00 };
-  return &template[0];
+  slotbuf[0] = 0x9116;
 }
 
-static xtensa_insnbuf
-beq_template (void)
+static void
+Opcode_rsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700100 };
-  return &template[0];
+  slotbuf[0] = 0xa130;
 }
 
-static xtensa_insnbuf
-beqi_template (void)
+static void
+Opcode_wsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00680000 };
-  return &template[0];
+  slotbuf[0] = 0xa131;
 }
 
-static xtensa_insnbuf
-beqz_template (void)
+static void
+Opcode_xsr_dbreakc1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00640000 };
-  return &template[0];
+  slotbuf[0] = 0xa116;
 }
 
-static xtensa_insnbuf
-beqz_n_template (void)
+static void
+Opcode_rsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00c80000 };
-  return &template[0];
+  slotbuf[0] = 0x8030;
 }
 
-static xtensa_insnbuf
-bge_template (void)
+static void
+Opcode_wsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700a00 };
-  return &template[0];
+  slotbuf[0] = 0x8031;
 }
 
-static xtensa_insnbuf
-bgei_template (void)
+static void
+Opcode_xsr_ibreaka0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006b0000 };
-  return &template[0];
+  slotbuf[0] = 0x8016;
 }
 
-static xtensa_insnbuf
-bgeu_template (void)
+static void
+Opcode_rsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700b00 };
-  return &template[0];
+  slotbuf[0] = 0x8130;
 }
 
-static xtensa_insnbuf
-bgeui_template (void)
+static void
+Opcode_wsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006f0000 };
-  return &template[0];
+  slotbuf[0] = 0x8131;
 }
 
-static xtensa_insnbuf
-bgez_template (void)
+static void
+Opcode_xsr_ibreaka1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00670000 };
-  return &template[0];
+  slotbuf[0] = 0x8116;
 }
 
-static xtensa_insnbuf
-blt_template (void)
+static void
+Opcode_rsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700200 };
-  return &template[0];
+  slotbuf[0] = 0x6030;
 }
 
-static xtensa_insnbuf
-blti_template (void)
+static void
+Opcode_wsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006a0000 };
-  return &template[0];
+  slotbuf[0] = 0x6031;
 }
 
-static xtensa_insnbuf
-bltu_template (void)
+static void
+Opcode_xsr_ibreakenable_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700300 };
-  return &template[0];
+  slotbuf[0] = 0x6016;
 }
 
-static xtensa_insnbuf
-bltui_template (void)
+static void
+Opcode_rsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006e0000 };
-  return &template[0];
+  slotbuf[0] = 0xe930;
 }
 
-static xtensa_insnbuf
-bltz_template (void)
+static void
+Opcode_wsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00660000 };
-  return &template[0];
+  slotbuf[0] = 0xe931;
 }
 
-static xtensa_insnbuf
-bnall_template (void)
+static void
+Opcode_xsr_debugcause_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700c00 };
-  return &template[0];
+  slotbuf[0] = 0xe916;
 }
 
-static xtensa_insnbuf
-bne_template (void)
+static void
+Opcode_rsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700900 };
-  return &template[0];
+  slotbuf[0] = 0xec30;
 }
 
-static xtensa_insnbuf
-bnei_template (void)
+static void
+Opcode_wsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00690000 };
-  return &template[0];
+  slotbuf[0] = 0xec31;
 }
 
-static xtensa_insnbuf
-bnez_template (void)
+static void
+Opcode_xsr_icount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00650000 };
-  return &template[0];
+  slotbuf[0] = 0xec16;
 }
 
-static xtensa_insnbuf
-bnez_n_template (void)
+static void
+Opcode_rsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00cc0000 };
-  return &template[0];
+  slotbuf[0] = 0xed30;
 }
 
-static xtensa_insnbuf
-bnone_template (void)
+static void
+Opcode_wsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00700000 };
-  return &template[0];
+  slotbuf[0] = 0xed31;
 }
 
-static xtensa_insnbuf
-break_template (void)
+static void
+Opcode_xsr_icountlevel_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000400 };
-  return &template[0];
+  slotbuf[0] = 0xed16;
 }
 
-static xtensa_insnbuf
-break_n_template (void)
+static void
+Opcode_rsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00d20f00 };
-  return &template[0];
+  slotbuf[0] = 0x6830;
 }
 
-static xtensa_insnbuf
-call0_template (void)
+static void
+Opcode_wsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00500000 };
-  return &template[0];
+  slotbuf[0] = 0x6831;
 }
 
-static xtensa_insnbuf
-call12_template (void)
+static void
+Opcode_xsr_ddr_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x005c0000 };
-  return &template[0];
+  slotbuf[0] = 0x6816;
 }
 
-static xtensa_insnbuf
-call4_template (void)
+static void
+Opcode_rfdo_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00540000 };
-  return &template[0];
+  slotbuf[0] = 0xe1f;
 }
 
-static xtensa_insnbuf
-call8_template (void)
+static void
+Opcode_rfdd_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00580000 };
-  return &template[0];
+  slotbuf[0] = 0x10e1f;
 }
 
-static xtensa_insnbuf
-callx0_template (void)
+static void
+Opcode_rsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00030000 };
-  return &template[0];
+  slotbuf[0] = 0xea30;
 }
 
-static xtensa_insnbuf
-callx12_template (void)
+static void
+Opcode_wsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x000f0000 };
-  return &template[0];
+  slotbuf[0] = 0xea31;
 }
 
-static xtensa_insnbuf
-callx4_template (void)
+static void
+Opcode_xsr_ccount_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00070000 };
-  return &template[0];
+  slotbuf[0] = 0xea16;
 }
 
-static xtensa_insnbuf
-callx8_template (void)
+static void
+Opcode_rsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x000b0000 };
-  return &template[0];
+  slotbuf[0] = 0xf030;
 }
 
-static xtensa_insnbuf
-dhi_template (void)
+static void
+Opcode_wsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00260700 };
-  return &template[0];
+  slotbuf[0] = 0xf031;
 }
 
-static xtensa_insnbuf
-dhwb_template (void)
+static void
+Opcode_xsr_ccompare0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00240700 };
-  return &template[0];
+  slotbuf[0] = 0xf016;
 }
 
-static xtensa_insnbuf
-dhwbi_template (void)
+static void
+Opcode_rsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00250700 };
-  return &template[0];
+  slotbuf[0] = 0xf130;
 }
 
-static xtensa_insnbuf
-dii_template (void)
+static void
+Opcode_wsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00270700 };
-  return &template[0];
+  slotbuf[0] = 0xf131;
 }
 
-static xtensa_insnbuf
-diwb_template (void)
+static void
+Opcode_xsr_ccompare1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00280740 };
-  return &template[0];
+  slotbuf[0] = 0xf116;
 }
 
-static xtensa_insnbuf
-diwbi_template (void)
+static void
+Opcode_rsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00280750 };
-  return &template[0];
+  slotbuf[0] = 0xf230;
 }
 
-static xtensa_insnbuf
-dpfr_template (void)
+static void
+Opcode_wsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200700 };
-  return &template[0];
+  slotbuf[0] = 0xf231;
 }
 
-static xtensa_insnbuf
-dpfro_template (void)
+static void
+Opcode_xsr_ccompare2_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00220700 };
-  return &template[0];
+  slotbuf[0] = 0xf216;
 }
 
-static xtensa_insnbuf
-dpfw_template (void)
+static void
+Opcode_ipf_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00210700 };
-  return &template[0];
+  slotbuf[0] = 0x2c0700;
 }
 
-static xtensa_insnbuf
-dpfwo_template (void)
+static void
+Opcode_ihi_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00230700 };
-  return &template[0];
+  slotbuf[0] = 0x2e0700;
 }
 
-static xtensa_insnbuf
-dsync_template (void)
+static void
+Opcode_iii_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00030200 };
-  return &template[0];
+  slotbuf[0] = 0x2f0700;
 }
 
-static xtensa_insnbuf
-entry_template (void)
+static void
+Opcode_lict_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006c0000 };
-  return &template[0];
+  slotbuf[0] = 0x1f;
 }
 
-static xtensa_insnbuf
-esync_template (void)
+static void
+Opcode_licw_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00020200 };
-  return &template[0];
+  slotbuf[0] = 0x21f;
 }
 
-static xtensa_insnbuf
-excw_template (void)
+static void
+Opcode_sict_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00080200 };
-  return &template[0];
+  slotbuf[0] = 0x11f;
 }
 
-static xtensa_insnbuf
-extui_template (void)
+static void
+Opcode_sicw_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000040 };
-  return &template[0];
+  slotbuf[0] = 0x31f;
 }
 
-static xtensa_insnbuf
-idtlb_template (void)
+static void
+Opcode_dhwb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000c05 };
-  return &template[0];
+  slotbuf[0] = 0x240700;
 }
 
-static xtensa_insnbuf
-idtlba_template (void)
+static void
+Opcode_dhwbi_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000805 };
-  return &template[0];
+  slotbuf[0] = 0x250700;
 }
 
-static xtensa_insnbuf
-ihi_template (void)
+static void
+Opcode_diwb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x002e0700 };
-  return &template[0];
+  slotbuf[0] = 0x280740;
 }
 
-static xtensa_insnbuf
-iii_template (void)
+static void
+Opcode_diwbi_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x002f0700 };
-  return &template[0];
+  slotbuf[0] = 0x280750;
 }
 
-static xtensa_insnbuf
-iitlb_template (void)
+static void
+Opcode_dhi_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000405 };
-  return &template[0];
+  slotbuf[0] = 0x260700;
 }
 
-static xtensa_insnbuf
-iitlba_template (void)
+static void
+Opcode_dii_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000005 };
-  return &template[0];
+  slotbuf[0] = 0x270700;
 }
 
-static xtensa_insnbuf
-ipf_template (void)
+static void
+Opcode_dpfr_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x002c0700 };
-  return &template[0];
+  slotbuf[0] = 0x200700;
 }
 
-static xtensa_insnbuf
-isync_template (void)
+static void
+Opcode_dpfw_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000200 };
-  return &template[0];
+  slotbuf[0] = 0x210700;
 }
 
-static xtensa_insnbuf
-j_template (void)
+static void
+Opcode_dpfro_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00600000 };
-  return &template[0];
+  slotbuf[0] = 0x220700;
 }
 
-static xtensa_insnbuf
-jx_template (void)
+static void
+Opcode_dpfwo_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x000a0000 };
-  return &template[0];
+  slotbuf[0] = 0x230700;
 }
 
-static xtensa_insnbuf
-l16si_template (void)
+static void
+Opcode_sdct_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200900 };
-  return &template[0];
+  slotbuf[0] = 0x91f;
 }
 
-static xtensa_insnbuf
-l16ui_template (void)
+static void
+Opcode_ldct_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200100 };
-  return &template[0];
+  slotbuf[0] = 0x81f;
 }
 
-static xtensa_insnbuf
-l32e_template (void)
+static void
+Opcode_idtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00000090 };
-  return &template[0];
+  slotbuf[0] = 0xc05;
 }
 
-static xtensa_insnbuf
-l32i_template (void)
+static void
+Opcode_pdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200200 };
-  return &template[0];
+  slotbuf[0] = 0xd05;
 }
 
-static xtensa_insnbuf
-l32i_n_template (void)
+static void
+Opcode_rdtlb0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00800000 };
-  return &template[0];
+  slotbuf[0] = 0xb05;
 }
 
-static xtensa_insnbuf
-l32r_template (void)
+static void
+Opcode_rdtlb1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00100000 };
-  return &template[0];
+  slotbuf[0] = 0xf05;
 }
 
-static xtensa_insnbuf
-l8ui_template (void)
+static void
+Opcode_wdtlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x00200000 };
-  return &template[0];
+  slotbuf[0] = 0xe05;
 }
 
-static xtensa_insnbuf
-ldct_template (void)
+static void
+Opcode_iitlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x0000081f };
-  return &template[0];
+  slotbuf[0] = 0x405;
 }
 
-static xtensa_insnbuf
-lict_template (void)
+static void
+Opcode_pitlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x0000001f };
-  return &template[0];
+  slotbuf[0] = 0x505;
 }
 
-static xtensa_insnbuf
-licw_template (void)
+static void
+Opcode_ritlb0_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x0000021f };
-  return &template[0];
+  slotbuf[0] = 0x305;
 }
 
-static xtensa_insnbuf
-loop_template (void)
+static void
+Opcode_ritlb1_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006d0800 };
-  return &template[0];
+  slotbuf[0] = 0x705;
 }
 
-static xtensa_insnbuf
-loopgtz_template (void)
+static void
+Opcode_witlb_Slot_inst_encode (xtensa_insnbuf slotbuf)
 {
-  static xtensa_insnbuf_word template[] = { 0x006d0a00 };
-  return &template[0];
+  slotbuf[0] = 0x605;
 }
 
-static xtensa_insnbuf
-loopnez_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x006d0900 };
-  return &template[0];
-}
+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
+};
+
+xtensa_opcode_encode_fn Opcode_rfe_encode_fns[] = {
+  Opcode_rfe_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfde_encode_fns[] = {
+  Opcode_rfde_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_syscall_encode_fns[] = {
+  Opcode_syscall_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_simcall_encode_fns[] = {
+  Opcode_simcall_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call12_encode_fns[] = {
+  Opcode_call12_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call8_encode_fns[] = {
+  Opcode_call8_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_call4_encode_fns[] = {
+  Opcode_call4_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx12_encode_fns[] = {
+  Opcode_callx12_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx8_encode_fns[] = {
+  Opcode_callx8_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_callx4_encode_fns[] = {
+  Opcode_callx4_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_entry_encode_fns[] = {
+  Opcode_entry_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_movsp_encode_fns[] = {
+  Opcode_movsp_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rotw_encode_fns[] = {
+  Opcode_rotw_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_retw_encode_fns[] = {
+  Opcode_retw_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_retw_n_encode_fns[] = {
+  0, 0, Opcode_retw_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_rfwo_encode_fns[] = {
+  Opcode_rfwo_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rfwu_encode_fns[] = {
+  Opcode_rfwu_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_l32e_encode_fns[] = {
+  Opcode_l32e_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_s32e_encode_fns[] = {
+  Opcode_s32e_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_windowbase_encode_fns[] = {
+  Opcode_rsr_windowbase_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_windowbase_encode_fns[] = {
+  Opcode_wsr_windowbase_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_windowbase_encode_fns[] = {
+  Opcode_xsr_windowbase_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_rsr_windowstart_encode_fns[] = {
+  Opcode_rsr_windowstart_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_wsr_windowstart_encode_fns[] = {
+  Opcode_wsr_windowstart_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xsr_windowstart_encode_fns[] = {
+  Opcode_xsr_windowstart_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_add_n_encode_fns[] = {
+  0, Opcode_add_n_Slot_inst16a_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addi_n_encode_fns[] = {
+  0, Opcode_addi_n_Slot_inst16a_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqz_n_encode_fns[] = {
+  0, 0, Opcode_beqz_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_bnez_n_encode_fns[] = {
+  0, 0, Opcode_bnez_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_ill_n_encode_fns[] = {
+  0, 0, Opcode_ill_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_l32i_n_encode_fns[] = {
+  0, Opcode_l32i_n_Slot_inst16a_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_mov_n_encode_fns[] = {
+  0, 0, Opcode_mov_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_movi_n_encode_fns[] = {
+  0, 0, Opcode_movi_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_nop_n_encode_fns[] = {
+  0, 0, Opcode_nop_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_ret_n_encode_fns[] = {
+  0, 0, Opcode_ret_n_Slot_inst16b_encode
+};
+
+xtensa_opcode_encode_fn Opcode_s32i_n_encode_fns[] = {
+  0, Opcode_s32i_n_Slot_inst16a_encode, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addi_encode_fns[] = {
+  Opcode_addi_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addmi_encode_fns[] = {
+  Opcode_addmi_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_add_encode_fns[] = {
+  Opcode_add_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_sub_encode_fns[] = {
+  Opcode_sub_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx2_encode_fns[] = {
+  Opcode_addx2_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx4_encode_fns[] = {
+  Opcode_addx4_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_addx8_encode_fns[] = {
+  Opcode_addx8_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx2_encode_fns[] = {
+  Opcode_subx2_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx4_encode_fns[] = {
+  Opcode_subx4_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_subx8_encode_fns[] = {
+  Opcode_subx8_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_and_encode_fns[] = {
+  Opcode_and_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_or_encode_fns[] = {
+  Opcode_or_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_xor_encode_fns[] = {
+  Opcode_xor_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beqi_encode_fns[] = {
+  Opcode_beqi_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bnei_encode_fns[] = {
+  Opcode_bnei_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgei_encode_fns[] = {
+  Opcode_bgei_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_blti_encode_fns[] = {
+  Opcode_blti_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbci_encode_fns[] = {
+  Opcode_bbci_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bbsi_encode_fns[] = {
+  Opcode_bbsi_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bgeui_encode_fns[] = {
+  Opcode_bgeui_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bltui_encode_fns[] = {
+  Opcode_bltui_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_beq_encode_fns[] = {
+  Opcode_beq_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bne_encode_fns[] = {
+  Opcode_bne_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_bge_encode_fns[] = {
+  Opcode_bge_Slot_inst_encode, 0, 0
+};
+
+xtensa_opcode_encode_fn Opcode_blt_encode_fns[] = {
+  Opcode_blt_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-memw_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x000c0200 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bgeu_encode_fns[] = {
+  Opcode_bgeu_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-mov_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00d00000 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bltu_encode_fns[] = {
+  Opcode_bltu_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-moveqz_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000038 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bany_encode_fns[] = {
+  Opcode_bany_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movgez_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000003b };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bnone_encode_fns[] = {
+  Opcode_bnone_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movi_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00200a00 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ball_encode_fns[] = {
+  Opcode_ball_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movi_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00c00000 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bnall_encode_fns[] = {
+  Opcode_bnall_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movltz_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000003a };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bbc_encode_fns[] = {
+  Opcode_bbc_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movnez_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000039 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bbs_encode_fns[] = {
+  Opcode_bbs_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-movsp_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000100 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_beqz_encode_fns[] = {
+  Opcode_beqz_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-neg_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000006 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bnez_encode_fns[] = {
+  Opcode_bnez_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-nop_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00d30f00 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bgez_encode_fns[] = {
+  Opcode_bgez_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-nsa_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000e04 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_bltz_encode_fns[] = {
+  Opcode_bltz_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-nsau_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000f04 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_call0_encode_fns[] = {
+  Opcode_call0_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-or_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000002 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_callx0_encode_fns[] = {
+  Opcode_callx0_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-pdtlb_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000d05 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_extui_encode_fns[] = {
+  Opcode_extui_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-pitlb_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000505 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ill_encode_fns[] = {
+  Opcode_ill_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rdtlb0_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000b05 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_j_encode_fns[] = {
+  Opcode_j_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rdtlb1_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000f05 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_jx_encode_fns[] = {
+  Opcode_jx_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ret_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00020000 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_l16ui_encode_fns[] = {
+  Opcode_l16ui_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ret_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00d00f00 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_l16si_encode_fns[] = {
+  Opcode_l16si_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-retw_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00060000 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_l32i_encode_fns[] = {
+  Opcode_l32i_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-retw_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00d10f00 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_l32r_encode_fns[] = {
+  Opcode_l32r_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rfde_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00002300 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_l8ui_encode_fns[] = {
+  Opcode_l8ui_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rfe_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000300 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_loop_encode_fns[] = {
+  Opcode_loop_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rfi_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00010300 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_loopnez_encode_fns[] = {
+  Opcode_loopnez_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rfwo_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00004300 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_loopgtz_encode_fns[] = {
+  Opcode_loopgtz_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rfwu_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00005300 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_movi_encode_fns[] = {
+  Opcode_movi_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ritlb0_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000305 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_moveqz_encode_fns[] = {
+  Opcode_moveqz_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ritlb1_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000705 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_movnez_encode_fns[] = {
+  Opcode_movnez_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rotw_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000804 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_movltz_encode_fns[] = {
+  Opcode_movltz_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rsil_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000600 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_movgez_encode_fns[] = {
+  Opcode_movgez_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rsr_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000030 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_neg_encode_fns[] = {
+  Opcode_neg_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-rsync_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00010200 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_abs_encode_fns[] = {
+  Opcode_abs_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-s16i_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00200500 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_nop_encode_fns[] = {
+  Opcode_nop_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-s32e_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000094 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ret_encode_fns[] = {
+  Opcode_ret_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-s32i_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00200600 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_s16i_encode_fns[] = {
+  Opcode_s16i_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-s32i_n_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00900000 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_s32i_encode_fns[] = {
+  Opcode_s32i_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-s8i_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00200400 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_s8i_encode_fns[] = {
+  Opcode_s8i_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sdct_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000091f };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ssr_encode_fns[] = {
+  Opcode_ssr_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sict_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000011f };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ssl_encode_fns[] = {
+  Opcode_ssl_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sicw_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000031f };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ssa8l_encode_fns[] = {
+  Opcode_ssa8l_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-simcall_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00001500 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ssa8b_encode_fns[] = {
+  Opcode_ssa8b_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sll_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000001a };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_ssai_encode_fns[] = {
+  Opcode_ssai_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-slli_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000010 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_sll_encode_fns[] = {
+  Opcode_sll_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sra_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000001b };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_src_encode_fns[] = {
+  Opcode_src_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-srai_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000012 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_srl_encode_fns[] = {
+  Opcode_srl_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-src_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000018 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_sra_encode_fns[] = {
+  Opcode_sra_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-srl_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000019 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_slli_encode_fns[] = {
+  Opcode_slli_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-srli_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000014 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_srai_encode_fns[] = {
+  Opcode_srai_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ssa8b_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000304 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_srli_encode_fns[] = {
+  Opcode_srli_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ssa8l_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000204 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_memw_encode_fns[] = {
+  Opcode_memw_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ssai_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000404 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_extw_encode_fns[] = {
+  Opcode_extw_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ssl_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000104 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_isync_encode_fns[] = {
+  Opcode_isync_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-ssr_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000004 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_rsync_encode_fns[] = {
+  Opcode_rsync_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-sub_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000000c };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_esync_encode_fns[] = {
+  Opcode_esync_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-subx2_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000000d };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_dsync_encode_fns[] = {
+  Opcode_dsync_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-subx4_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000000e };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_rsil_encode_fns[] = {
+  Opcode_rsil_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-subx8_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x0000000f };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_rsr_lend_encode_fns[] = {
+  Opcode_rsr_lend_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-syscall_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000500 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_wsr_lend_encode_fns[] = {
+  Opcode_wsr_lend_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-waiti_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000700 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_xsr_lend_encode_fns[] = {
+  Opcode_xsr_lend_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-wdtlb_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000e05 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_rsr_lcount_encode_fns[] = {
+  Opcode_rsr_lcount_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-witlb_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000605 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_wsr_lcount_encode_fns[] = {
+  Opcode_wsr_lcount_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-wsr_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000031 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_xsr_lcount_encode_fns[] = {
+  Opcode_xsr_lcount_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-xor_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000003 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_rsr_lbeg_encode_fns[] = {
+  Opcode_rsr_lbeg_Slot_inst_encode, 0, 0
+};
 
-static xtensa_insnbuf
-xsr_template (void)
-{
-  static xtensa_insnbuf_word template[] = { 0x00000016 };
-  return &template[0];
-}
+xtensa_opcode_encode_fn Opcode_wsr_lbeg_encode_fns[] = {
+  Opcode_wsr_lbeg_Slot_inst_encode, 0, 0
+};
 
-static xtensa_opcode_internal abs_opcode = {
-  "abs",
-  3,
-  abs_template,
-  &neg_iclass
+xtensa_opcode_encode_fn Opcode_xsr_lbeg_encode_fns[] = {
+  Opcode_xsr_lbeg_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal add_opcode = {
-  "add",
-  3,
-  add_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_rsr_sar_encode_fns[] = {
+  Opcode_rsr_sar_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_wsr_sar_encode_fns[] = {
+  Opcode_wsr_sar_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal addi_opcode = {
-  "addi",
-  3,
-  addi_template,
-  &addi_iclass
+xtensa_opcode_encode_fn Opcode_xsr_sar_encode_fns[] = {
+  Opcode_xsr_sar_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_rsr_litbase_encode_fns[] = {
+  Opcode_rsr_litbase_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal addmi_opcode = {
-  "addmi",
-  3,
-  addmi_template,
-  &addmi_iclass
+xtensa_opcode_encode_fn Opcode_wsr_litbase_encode_fns[] = {
+  Opcode_wsr_litbase_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal addx2_opcode = {
-  "addx2",
-  3,
-  addx2_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_xsr_litbase_encode_fns[] = {
+  Opcode_xsr_litbase_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal addx4_opcode = {
-  "addx4",
-  3,
-  addx4_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_rsr_176_encode_fns[] = {
+  Opcode_rsr_176_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal addx8_opcode = {
-  "addx8",
-  3,
-  addx8_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_rsr_208_encode_fns[] = {
+  Opcode_rsr_208_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal and_opcode = {
-  "and",
-  3,
-  and_template,
-  &bit_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ps_encode_fns[] = {
+  Opcode_rsr_ps_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ball_opcode = {
-  "ball",
-  3,
-  ball_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ps_encode_fns[] = {
+  Opcode_wsr_ps_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bany_opcode = {
-  "bany",
-  3,
-  bany_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ps_encode_fns[] = {
+  Opcode_xsr_ps_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bbc_opcode = {
-  "bbc",
-  3,
-  bbc_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_rsr_epc1_encode_fns[] = {
+  Opcode_rsr_epc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bbci_opcode = {
-  "bbci",
-  3,
-  bbci_template,
-  &bsi8b_iclass
+xtensa_opcode_encode_fn Opcode_wsr_epc1_encode_fns[] = {
+  Opcode_wsr_epc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bbs_opcode = {
-  "bbs",
-  3,
-  bbs_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_epc1_encode_fns[] = {
+  Opcode_xsr_epc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bbsi_opcode = {
-  "bbsi",
-  3,
-  bbsi_template,
-  &bsi8b_iclass
+xtensa_opcode_encode_fn Opcode_rsr_excsave1_encode_fns[] = {
+  Opcode_rsr_excsave1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal beq_opcode = {
-  "beq",
-  3,
-  beq_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_wsr_excsave1_encode_fns[] = {
+  Opcode_wsr_excsave1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal beqi_opcode = {
-  "beqi",
-  3,
-  beqi_template,
-  &bsi8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_excsave1_encode_fns[] = {
+  Opcode_xsr_excsave1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal beqz_opcode = {
-  "beqz",
-  3,
-  beqz_template,
-  &bsz12_iclass
+xtensa_opcode_encode_fn Opcode_rsr_epc2_encode_fns[] = {
+  Opcode_rsr_epc2_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_wsr_epc2_encode_fns[] = {
+  Opcode_wsr_epc2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bge_opcode = {
-  "bge",
-  3,
-  bge_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_epc2_encode_fns[] = {
+  Opcode_xsr_epc2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bgei_opcode = {
-  "bgei",
-  3,
-  bgei_template,
-  &bsi8_iclass
+xtensa_opcode_encode_fn Opcode_rsr_excsave2_encode_fns[] = {
+  Opcode_rsr_excsave2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bgeu_opcode = {
-  "bgeu",
-  3,
-  bgeu_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_wsr_excsave2_encode_fns[] = {
+  Opcode_wsr_excsave2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bgeui_opcode = {
-  "bgeui",
-  3,
-  bgeui_template,
-  &bsi8u_iclass
+xtensa_opcode_encode_fn Opcode_xsr_excsave2_encode_fns[] = {
+  Opcode_xsr_excsave2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bgez_opcode = {
-  "bgez",
-  3,
-  bgez_template,
-  &bsz12_iclass
+xtensa_opcode_encode_fn Opcode_rsr_epc3_encode_fns[] = {
+  Opcode_rsr_epc3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal blt_opcode = {
-  "blt",
-  3,
-  blt_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_wsr_epc3_encode_fns[] = {
+  Opcode_wsr_epc3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal blti_opcode = {
-  "blti",
-  3,
-  blti_template,
-  &bsi8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_epc3_encode_fns[] = {
+  Opcode_xsr_epc3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bltu_opcode = {
-  "bltu",
-  3,
-  bltu_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_rsr_excsave3_encode_fns[] = {
+  Opcode_rsr_excsave3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bltui_opcode = {
-  "bltui",
-  3,
-  bltui_template,
-  &bsi8u_iclass
+xtensa_opcode_encode_fn Opcode_wsr_excsave3_encode_fns[] = {
+  Opcode_wsr_excsave3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bltz_opcode = {
-  "bltz",
-  3,
-  bltz_template,
-  &bsz12_iclass
+xtensa_opcode_encode_fn Opcode_xsr_excsave3_encode_fns[] = {
+  Opcode_xsr_excsave3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bnall_opcode = {
-  "bnall",
-  3,
-  bnall_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_rsr_epc4_encode_fns[] = {
+  Opcode_rsr_epc4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bne_opcode = {
-  "bne",
-  3,
-  bne_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_wsr_epc4_encode_fns[] = {
+  Opcode_wsr_epc4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bnei_opcode = {
-  "bnei",
-  3,
-  bnei_template,
-  &bsi8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_epc4_encode_fns[] = {
+  Opcode_xsr_epc4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bnez_opcode = {
-  "bnez",
-  3,
-  bnez_template,
-  &bsz12_iclass
+xtensa_opcode_encode_fn Opcode_rsr_excsave4_encode_fns[] = {
+  Opcode_rsr_excsave4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bnez_n_opcode = {
-  "bnez.n",
-  2,
-  bnez_n_template,
-  &bz6_iclass
+xtensa_opcode_encode_fn Opcode_wsr_excsave4_encode_fns[] = {
+  Opcode_wsr_excsave4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal bnone_opcode = {
-  "bnone",
-  3,
-  bnone_template,
-  &bst8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_excsave4_encode_fns[] = {
+  Opcode_xsr_excsave4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal break_opcode = {
-  "break",
-  3,
-  break_template,
-  &break_iclass
+xtensa_opcode_encode_fn Opcode_rsr_eps2_encode_fns[] = {
+  Opcode_rsr_eps2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal break_n_opcode = {
-  "break.n",
-  2,
-  break_n_template,
-  &break_n_iclass
+xtensa_opcode_encode_fn Opcode_wsr_eps2_encode_fns[] = {
+  Opcode_wsr_eps2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal call0_opcode = {
-  "call0",
-  3,
-  call0_template,
-  &call_iclass
+xtensa_opcode_encode_fn Opcode_xsr_eps2_encode_fns[] = {
+  Opcode_xsr_eps2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal call12_opcode = {
-  "call12",
-  3,
-  call12_template,
-  &call12_iclass
+xtensa_opcode_encode_fn Opcode_rsr_eps3_encode_fns[] = {
+  Opcode_rsr_eps3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal call4_opcode = {
-  "call4",
-  3,
-  call4_template,
-  &call4_iclass
+xtensa_opcode_encode_fn Opcode_wsr_eps3_encode_fns[] = {
+  Opcode_wsr_eps3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal call8_opcode = {
-  "call8",
-  3,
-  call8_template,
-  &call8_iclass
+xtensa_opcode_encode_fn Opcode_xsr_eps3_encode_fns[] = {
+  Opcode_xsr_eps3_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal callx0_opcode = {
-  "callx0",
-  3,
-  callx0_template,
-  &callx_iclass
+xtensa_opcode_encode_fn Opcode_rsr_eps4_encode_fns[] = {
+  Opcode_rsr_eps4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal callx12_opcode = {
-  "callx12",
-  3,
-  callx12_template,
-  &callx12_iclass
+xtensa_opcode_encode_fn Opcode_wsr_eps4_encode_fns[] = {
+  Opcode_wsr_eps4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal callx4_opcode = {
-  "callx4",
-  3,
-  callx4_template,
-  &callx4_iclass
+xtensa_opcode_encode_fn Opcode_xsr_eps4_encode_fns[] = {
+  Opcode_xsr_eps4_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal callx8_opcode = {
-  "callx8",
-  3,
-  callx8_template,
-  &callx8_iclass
+xtensa_opcode_encode_fn Opcode_rsr_excvaddr_encode_fns[] = {
+  Opcode_rsr_excvaddr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dhi_opcode = {
-  "dhi",
-  3,
-  dhi_template,
-  &dcache_iclass
+xtensa_opcode_encode_fn Opcode_wsr_excvaddr_encode_fns[] = {
+  Opcode_wsr_excvaddr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dhwb_opcode = {
-  "dhwb",
-  3,
-  dhwb_template,
-  &dcache_iclass
+xtensa_opcode_encode_fn Opcode_xsr_excvaddr_encode_fns[] = {
+  Opcode_xsr_excvaddr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dhwbi_opcode = {
-  "dhwbi",
-  3,
-  dhwbi_template,
-  &dcache_iclass
+xtensa_opcode_encode_fn Opcode_rsr_depc_encode_fns[] = {
+  Opcode_rsr_depc_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dii_opcode = {
-  "dii",
-  3,
-  dii_template,
-  &dcache_iclass
+xtensa_opcode_encode_fn Opcode_wsr_depc_encode_fns[] = {
+  Opcode_wsr_depc_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal diwb_opcode = {
-  "diwb",
-  3,
-  diwb_template,
-  &dce_iclass
+xtensa_opcode_encode_fn Opcode_xsr_depc_encode_fns[] = {
+  Opcode_xsr_depc_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal diwbi_opcode = {
-  "diwbi",
-  3,
-  diwbi_template,
-  &dce_iclass
+xtensa_opcode_encode_fn Opcode_rsr_exccause_encode_fns[] = {
+  Opcode_rsr_exccause_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dpfr_opcode = {
-  "dpfr",
-  3,
-  dpfr_template,
-  &dpf_iclass
+xtensa_opcode_encode_fn Opcode_wsr_exccause_encode_fns[] = {
+  Opcode_wsr_exccause_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dpfro_opcode = {
-  "dpfro",
-  3,
-  dpfro_template,
-  &dpf_iclass
+xtensa_opcode_encode_fn Opcode_xsr_exccause_encode_fns[] = {
+  Opcode_xsr_exccause_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dpfw_opcode = {
-  "dpfw",
-  3,
-  dpfw_template,
-  &dpf_iclass
+xtensa_opcode_encode_fn Opcode_rsr_misc0_encode_fns[] = {
+  Opcode_rsr_misc0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal dpfwo_opcode = {
-  "dpfwo",
-  3,
-  dpfwo_template,
-  &dpf_iclass
+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
 };
 
-static xtensa_opcode_internal dsync_opcode = {
-  "dsync",
-  3,
-  dsync_template,
-  &sync_iclass
+xtensa_opcode_encode_fn Opcode_rsr_misc1_encode_fns[] = {
+  Opcode_rsr_misc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal entry_opcode = {
-  "entry",
-  3,
-  entry_template,
-  &entry_iclass
+xtensa_opcode_encode_fn Opcode_wsr_misc1_encode_fns[] = {
+  Opcode_wsr_misc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal esync_opcode = {
-  "esync",
-  3,
-  esync_template,
-  &sync_iclass
+xtensa_opcode_encode_fn Opcode_xsr_misc1_encode_fns[] = {
+  Opcode_xsr_misc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal excw_opcode = {
-  "excw",
-  3,
-  excw_template,
-  &excw_iclass
+xtensa_opcode_encode_fn Opcode_rsr_prid_encode_fns[] = {
+  Opcode_rsr_prid_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal extui_opcode = {
-  "extui",
-  3,
-  extui_template,
-  &exti_iclass
+xtensa_opcode_encode_fn Opcode_rfi_encode_fns[] = {
+  Opcode_rfi_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal idtlb_opcode = {
-  "idtlb",
-  3,
-  idtlb_template,
-  &itlb_iclass
+xtensa_opcode_encode_fn Opcode_waiti_encode_fns[] = {
+  Opcode_waiti_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal idtlba_opcode = {
-  "idtlba",
-  3,
-  idtlba_template,
-  &itlba_iclass
+xtensa_opcode_encode_fn Opcode_rsr_interrupt_encode_fns[] = {
+  Opcode_rsr_interrupt_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ihi_opcode = {
-  "ihi",
-  3,
-  ihi_template,
-  &icache_iclass
+xtensa_opcode_encode_fn Opcode_wsr_intset_encode_fns[] = {
+  Opcode_wsr_intset_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal iii_opcode = {
-  "iii",
-  3,
-  iii_template,
-  &icache_iclass
+xtensa_opcode_encode_fn Opcode_wsr_intclear_encode_fns[] = {
+  Opcode_wsr_intclear_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal iitlb_opcode = {
-  "iitlb",
-  3,
-  iitlb_template,
-  &itlb_iclass
+xtensa_opcode_encode_fn Opcode_rsr_intenable_encode_fns[] = {
+  Opcode_rsr_intenable_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal iitlba_opcode = {
-  "iitlba",
-  3,
-  iitlba_template,
-  &itlba_iclass
+xtensa_opcode_encode_fn Opcode_wsr_intenable_encode_fns[] = {
+  Opcode_wsr_intenable_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ipf_opcode = {
-  "ipf",
-  3,
-  ipf_template,
-  &icache_iclass
+xtensa_opcode_encode_fn Opcode_xsr_intenable_encode_fns[] = {
+  Opcode_xsr_intenable_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal isync_opcode = {
-  "isync",
-  3,
-  isync_template,
-  &sync_iclass
+xtensa_opcode_encode_fn Opcode_break_encode_fns[] = {
+  Opcode_break_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal j_opcode = {
-  "j",
-  3,
-  j_template,
-  &jump_iclass
+xtensa_opcode_encode_fn Opcode_break_n_encode_fns[] = {
+  0, 0, Opcode_break_n_Slot_inst16b_encode
 };
 
-static xtensa_opcode_internal jx_opcode = {
-  "jx",
-  3,
-  jx_template,
-  &jumpx_iclass
+xtensa_opcode_encode_fn Opcode_rsr_dbreaka0_encode_fns[] = {
+  Opcode_rsr_dbreaka0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l16si_opcode = {
-  "l16si",
-  3,
-  l16si_template,
-  &l16i_iclass
+xtensa_opcode_encode_fn Opcode_wsr_dbreaka0_encode_fns[] = {
+  Opcode_wsr_dbreaka0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l16ui_opcode = {
-  "l16ui",
-  3,
-  l16ui_template,
-  &l16i_iclass
+xtensa_opcode_encode_fn Opcode_xsr_dbreaka0_encode_fns[] = {
+  Opcode_xsr_dbreaka0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l32e_opcode = {
-  "l32e",
-  3,
-  l32e_template,
-  &l32e_iclass
+xtensa_opcode_encode_fn Opcode_rsr_dbreakc0_encode_fns[] = {
+  Opcode_rsr_dbreakc0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l32i_opcode = {
-  "l32i",
-  3,
-  l32i_template,
-  &l32i_iclass
+xtensa_opcode_encode_fn Opcode_wsr_dbreakc0_encode_fns[] = {
+  Opcode_wsr_dbreakc0_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_xsr_dbreakc0_encode_fns[] = {
+  Opcode_xsr_dbreakc0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l32r_opcode = {
-  "l32r",
-  3,
-  l32r_template,
-  &l32r_iclass
+xtensa_opcode_encode_fn Opcode_rsr_dbreaka1_encode_fns[] = {
+  Opcode_rsr_dbreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal l8ui_opcode = {
-  "l8ui",
-  3,
-  l8ui_template,
-  &l8i_iclass
+xtensa_opcode_encode_fn Opcode_wsr_dbreaka1_encode_fns[] = {
+  Opcode_wsr_dbreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ldct_opcode = {
-  "ldct",
-  3,
-  ldct_template,
-  &actl_iclass
+xtensa_opcode_encode_fn Opcode_xsr_dbreaka1_encode_fns[] = {
+  Opcode_xsr_dbreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal lict_opcode = {
-  "lict",
-  3,
-  lict_template,
-  &actl_iclass
+xtensa_opcode_encode_fn Opcode_rsr_dbreakc1_encode_fns[] = {
+  Opcode_rsr_dbreakc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal licw_opcode = {
-  "licw",
-  3,
-  licw_template,
-  &actl_iclass
+xtensa_opcode_encode_fn Opcode_wsr_dbreakc1_encode_fns[] = {
+  Opcode_wsr_dbreakc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal loop_opcode = {
-  "loop",
-  3,
-  loop_template,
-  &loop_iclass
+xtensa_opcode_encode_fn Opcode_xsr_dbreakc1_encode_fns[] = {
+  Opcode_xsr_dbreakc1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal loopgtz_opcode = {
-  "loopgtz",
-  3,
-  loopgtz_template,
-  &loop_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ibreaka0_encode_fns[] = {
+  Opcode_rsr_ibreaka0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal loopnez_opcode = {
-  "loopnez",
-  3,
-  loopnez_template,
-  &loop_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ibreaka0_encode_fns[] = {
+  Opcode_wsr_ibreaka0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal memw_opcode = {
-  "memw",
-  3,
-  memw_template,
-  &sync_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ibreaka0_encode_fns[] = {
+  Opcode_xsr_ibreaka0_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_rsr_ibreaka1_encode_fns[] = {
+  Opcode_rsr_ibreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal moveqz_opcode = {
-  "moveqz",
-  3,
-  moveqz_template,
-  &movz_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ibreaka1_encode_fns[] = {
+  Opcode_wsr_ibreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal movgez_opcode = {
-  "movgez",
-  3,
-  movgez_template,
-  &movz_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ibreaka1_encode_fns[] = {
+  Opcode_xsr_ibreaka1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal movi_opcode = {
-  "movi",
-  3,
-  movi_template,
-  &movi_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ibreakenable_encode_fns[] = {
+  Opcode_rsr_ibreakenable_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_wsr_ibreakenable_encode_fns[] = {
+  Opcode_wsr_ibreakenable_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal movltz_opcode = {
-  "movltz",
-  3,
-  movltz_template,
-  &movz_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ibreakenable_encode_fns[] = {
+  Opcode_xsr_ibreakenable_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal movnez_opcode = {
-  "movnez",
-  3,
-  movnez_template,
-  &movz_iclass
+xtensa_opcode_encode_fn Opcode_rsr_debugcause_encode_fns[] = {
+  Opcode_rsr_debugcause_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal movsp_opcode = {
-  "movsp",
-  3,
-  movsp_template,
-  &movsp_iclass
+xtensa_opcode_encode_fn Opcode_wsr_debugcause_encode_fns[] = {
+  Opcode_wsr_debugcause_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal neg_opcode = {
-  "neg",
-  3,
-  neg_template,
-  &neg_iclass
+xtensa_opcode_encode_fn Opcode_xsr_debugcause_encode_fns[] = {
+  Opcode_xsr_debugcause_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_rsr_icount_encode_fns[] = {
+  Opcode_rsr_icount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal nsa_opcode = {
-  "nsa",
-  3,
-  nsa_template,
-  &nsa_iclass
+xtensa_opcode_encode_fn Opcode_wsr_icount_encode_fns[] = {
+  Opcode_wsr_icount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal nsau_opcode = {
-  "nsau",
-  3,
-  nsau_template,
-  &nsa_iclass
+xtensa_opcode_encode_fn Opcode_xsr_icount_encode_fns[] = {
+  Opcode_xsr_icount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal or_opcode = {
-  "or",
-  3,
-  or_template,
-  &bit_iclass
+xtensa_opcode_encode_fn Opcode_rsr_icountlevel_encode_fns[] = {
+  Opcode_rsr_icountlevel_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal pdtlb_opcode = {
-  "pdtlb",
-  3,
-  pdtlb_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_wsr_icountlevel_encode_fns[] = {
+  Opcode_wsr_icountlevel_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal pitlb_opcode = {
-  "pitlb",
-  3,
-  pitlb_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_xsr_icountlevel_encode_fns[] = {
+  Opcode_xsr_icountlevel_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rdtlb0_opcode = {
-  "rdtlb0",
-  3,
-  rdtlb0_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ddr_encode_fns[] = {
+  Opcode_rsr_ddr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rdtlb1_opcode = {
-  "rdtlb1",
-  3,
-  rdtlb1_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ddr_encode_fns[] = {
+  Opcode_wsr_ddr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ret_opcode = {
-  "ret",
-  3,
-  ret_template,
-  &return_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ddr_encode_fns[] = {
+  Opcode_xsr_ddr_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_rfdo_encode_fns[] = {
+  Opcode_rfdo_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal retw_opcode = {
-  "retw",
-  3,
-  retw_template,
-  &return_iclass
+xtensa_opcode_encode_fn Opcode_rfdd_encode_fns[] = {
+  Opcode_rfdd_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_rsr_ccount_encode_fns[] = {
+  Opcode_rsr_ccount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rfde_opcode = {
-  "rfde",
-  3,
-  rfde_template,
-  &rfe_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ccount_encode_fns[] = {
+  Opcode_wsr_ccount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rfe_opcode = {
-  "rfe",
-  3,
-  rfe_template,
-  &rfe_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ccount_encode_fns[] = {
+  Opcode_xsr_ccount_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rfi_opcode = {
-  "rfi",
-  3,
-  rfi_template,
-  &rfi_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ccompare0_encode_fns[] = {
+  Opcode_rsr_ccompare0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rfwo_opcode = {
-  "rfwo",
-  3,
-  rfwo_template,
-  &rfe_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ccompare0_encode_fns[] = {
+  Opcode_wsr_ccompare0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rfwu_opcode = {
-  "rfwu",
-  3,
-  rfwu_template,
-  &rfe_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ccompare0_encode_fns[] = {
+  Opcode_xsr_ccompare0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ritlb0_opcode = {
-  "ritlb0",
-  3,
-  ritlb0_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ccompare1_encode_fns[] = {
+  Opcode_rsr_ccompare1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ritlb1_opcode = {
-  "ritlb1",
-  3,
-  ritlb1_template,
-  &rtlb_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ccompare1_encode_fns[] = {
+  Opcode_wsr_ccompare1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rotw_opcode = {
-  "rotw",
-  3,
-  rotw_template,
-  &rotw_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ccompare1_encode_fns[] = {
+  Opcode_xsr_ccompare1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rsil_opcode = {
-  "rsil",
-  3,
-  rsil_template,
-  &rsil_iclass
+xtensa_opcode_encode_fn Opcode_rsr_ccompare2_encode_fns[] = {
+  Opcode_rsr_ccompare2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rsr_opcode = {
-  "rsr",
-  3,
-  rsr_template,
-  &rsr_iclass
+xtensa_opcode_encode_fn Opcode_wsr_ccompare2_encode_fns[] = {
+  Opcode_wsr_ccompare2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal rsync_opcode = {
-  "rsync",
-  3,
-  rsync_template,
-  &sync_iclass
+xtensa_opcode_encode_fn Opcode_xsr_ccompare2_encode_fns[] = {
+  Opcode_xsr_ccompare2_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal s16i_opcode = {
-  "s16i",
-  3,
-  s16i_template,
-  &s16i_iclass
+xtensa_opcode_encode_fn Opcode_ipf_encode_fns[] = {
+  Opcode_ipf_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal s32e_opcode = {
-  "s32e",
-  3,
-  s32e_template,
-  &s32e_iclass
+xtensa_opcode_encode_fn Opcode_ihi_encode_fns[] = {
+  Opcode_ihi_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal s32i_opcode = {
-  "s32i",
-  3,
-  s32i_template,
-  &s32i_iclass
+xtensa_opcode_encode_fn Opcode_iii_encode_fns[] = {
+  Opcode_iii_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_lict_encode_fns[] = {
+  Opcode_lict_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal s8i_opcode = {
-  "s8i",
-  3,
-  s8i_template,
-  &s8i_iclass
+xtensa_opcode_encode_fn Opcode_licw_encode_fns[] = {
+  Opcode_licw_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sdct_opcode = {
-  "sdct",
-  3,
-  sdct_template,
-  &acts_iclass
+xtensa_opcode_encode_fn Opcode_sict_encode_fns[] = {
+  Opcode_sict_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sict_opcode = {
-  "sict",
-  3,
-  sict_template,
-  &acts_iclass
+xtensa_opcode_encode_fn Opcode_sicw_encode_fns[] = {
+  Opcode_sicw_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sicw_opcode = {
-  "sicw",
-  3,
-  sicw_template,
-  &acts_iclass
+xtensa_opcode_encode_fn Opcode_dhwb_encode_fns[] = {
+  Opcode_dhwb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal simcall_opcode = {
-  "simcall",
-  3,
-  simcall_template,
-  &syscall_iclass
+xtensa_opcode_encode_fn Opcode_dhwbi_encode_fns[] = {
+  Opcode_dhwbi_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sll_opcode = {
-  "sll",
-  3,
-  sll_template,
-  &shifts_iclass
+xtensa_opcode_encode_fn Opcode_diwb_encode_fns[] = {
+  Opcode_diwb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal slli_opcode = {
-  "slli",
-  3,
-  slli_template,
-  &slli_iclass
+xtensa_opcode_encode_fn Opcode_diwbi_encode_fns[] = {
+  Opcode_diwbi_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sra_opcode = {
-  "sra",
-  3,
-  sra_template,
-  &shiftt_iclass
+xtensa_opcode_encode_fn Opcode_dhi_encode_fns[] = {
+  Opcode_dhi_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal srai_opcode = {
-  "srai",
-  3,
-  srai_template,
-  &srai_iclass
+xtensa_opcode_encode_fn Opcode_dii_encode_fns[] = {
+  Opcode_dii_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal src_opcode = {
-  "src",
-  3,
-  src_template,
-  &shiftst_iclass
+xtensa_opcode_encode_fn Opcode_dpfr_encode_fns[] = {
+  Opcode_dpfr_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal srl_opcode = {
-  "srl",
-  3,
-  srl_template,
-  &shiftt_iclass
+xtensa_opcode_encode_fn Opcode_dpfw_encode_fns[] = {
+  Opcode_dpfw_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal srli_opcode = {
-  "srli",
-  3,
-  srli_template,
-  &srli_iclass
+xtensa_opcode_encode_fn Opcode_dpfro_encode_fns[] = {
+  Opcode_dpfro_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ssa8b_opcode = {
-  "ssa8b",
-  3,
-  ssa8b_template,
-  &sar_iclass
+xtensa_opcode_encode_fn Opcode_dpfwo_encode_fns[] = {
+  Opcode_dpfwo_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ssa8l_opcode = {
-  "ssa8l",
-  3,
-  ssa8l_template,
-  &sar_iclass
+xtensa_opcode_encode_fn Opcode_sdct_encode_fns[] = {
+  Opcode_sdct_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ssai_opcode = {
-  "ssai",
-  3,
-  ssai_template,
-  &sari_iclass
+xtensa_opcode_encode_fn Opcode_ldct_encode_fns[] = {
+  Opcode_ldct_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ssl_opcode = {
-  "ssl",
-  3,
-  ssl_template,
-  &sar_iclass
+xtensa_opcode_encode_fn Opcode_idtlb_encode_fns[] = {
+  Opcode_idtlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal ssr_opcode = {
-  "ssr",
-  3,
-  ssr_template,
-  &sar_iclass
+xtensa_opcode_encode_fn Opcode_pdtlb_encode_fns[] = {
+  Opcode_pdtlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal sub_opcode = {
-  "sub",
-  3,
-  sub_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_rdtlb0_encode_fns[] = {
+  Opcode_rdtlb0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal subx2_opcode = {
-  "subx2",
-  3,
-  subx2_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_rdtlb1_encode_fns[] = {
+  Opcode_rdtlb1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal subx4_opcode = {
-  "subx4",
-  3,
-  subx4_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_wdtlb_encode_fns[] = {
+  Opcode_wdtlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal subx8_opcode = {
-  "subx8",
-  3,
-  subx8_template,
-  &addsub_iclass
+xtensa_opcode_encode_fn Opcode_iitlb_encode_fns[] = {
+  Opcode_iitlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal syscall_opcode = {
-  "syscall",
-  3,
-  syscall_template,
-  &syscall_iclass
+xtensa_opcode_encode_fn Opcode_pitlb_encode_fns[] = {
+  Opcode_pitlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal waiti_opcode = {
-  "waiti",
-  3,
-  waiti_template,
-  &wait_iclass
+xtensa_opcode_encode_fn Opcode_ritlb0_encode_fns[] = {
+  Opcode_ritlb0_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal wdtlb_opcode = {
-  "wdtlb",
-  3,
-  wdtlb_template,
-  &wtlb_iclass
+xtensa_opcode_encode_fn Opcode_ritlb1_encode_fns[] = {
+  Opcode_ritlb1_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal witlb_opcode = {
-  "witlb",
-  3,
-  witlb_template,
-  &wtlb_iclass
+xtensa_opcode_encode_fn Opcode_witlb_encode_fns[] = {
+  Opcode_witlb_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal wsr_opcode = {
-  "wsr",
-  3,
-  wsr_template,
-  &wsr_iclass
+xtensa_opcode_encode_fn Opcode_nsa_encode_fns[] = {
+  Opcode_nsa_Slot_inst_encode, 0, 0
 };
 
-static xtensa_opcode_internal xor_opcode = {
-  "xor",
-  3,
-  xor_template,
-  &bit_iclass
+xtensa_opcode_encode_fn Opcode_nsau_encode_fns[] = {
+  Opcode_nsau_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;
-      }
+\f
+/* 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 }
+};
+
+\f
+/* 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;
+}
+
+\f
+/* 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" }
+};
+
+\f
+/* 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];
+}
+
+\f
+/* 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
 };
index 9ddcc72..eb2d804 100644 (file)
@@ -1,3 +1,104 @@
+2004-10-07  Bob Wilson  <bob.wilson@acm.org>
+
+       * xtensa-config.h (XSHAL_USE_ABSOLUTE_LITERALS,
+       XCHAL_HAVE_PREDICTED_BRANCHES, XCHAL_INST_FETCH_WIDTH): New.
+       (XCHAL_EXTRA_SA_SIZE, XCHAL_EXTRA_SA_ALIGN): Delete.
+       * xtensa-isa-internal.h (ISA_INTERFACE_VERSION): Delete.
+       (config_sturct struct): Delete.
+       (XTENSA_OPERAND_IS_REGISTER, XTENSA_OPERAND_IS_PCRELATIVE,
+       XTENSA_OPERAND_IS_INVISIBLE, XTENSA_OPERAND_IS_UNKNOWN,
+       XTENSA_OPCODE_IS_BRANCH, XTENSA_OPCODE_IS_JUMP,
+       XTENSA_OPCODE_IS_LOOP, XTENSA_OPCODE_IS_CALL,
+       XTENSA_STATE_IS_EXPORTED, XTENSA_INTERFACE_HAS_SIDE_EFFECT): Define.
+       (xtensa_format_encode_fn, xtensa_get_slot_fn, xtensa_set_slot_fn): New.
+       (xtensa_insn_decode_fn): Rename to ...
+       (xtensa_opcode_decode_fn): ... this.
+       (xtensa_immed_decode_fn, xtensa_immed_encode_fn, xtensa_do_reloc_fn,
+       xtensa_undo_reloc_fn): Update.
+       (xtensa_encoding_template_fn): Delete.
+       (xtensa_opcode_encode_fn, xtensa_format_decode_fn,
+       xtensa_length_decode_fn): New.
+       (xtensa_format_internal, xtensa_slot_internal): New types.
+       (xtensa_operand_internal): Delete operand_kind, inout, isPCRelative,
+       get_field, and set_field fields.  Add name, field_id, regfile,
+       num_regs, and flags fields.
+       (xtensa_arg_internal): New type.
+       (xtensa_iclass_internal): Change operands field to array of
+       xtensa_arg_internal.  Add num_stateOperands, stateOperands,
+       num_interfaceOperands, and interfaceOperands fields.
+       (xtensa_opcode_internal): Delete length, template, and iclass fields.
+       Add iclass_id, flags, encode_fns, num_funcUnit_uses, and funcUnit_uses.
+       (opname_lookup_entry): Delete.
+       (xtensa_regfile_internal, xtensa_interface_internal,
+       xtensa_funcUnit_internal, xtensa_state_internal,
+       xtensa_sysreg_internal, xtensa_lookup_entry): New.
+       (xtensa_isa_internal): Replace opcode_table field with opcodes field.
+       Change type of opname_lookup_table.  Delete num_modules,
+       module_opcode_base, module_decode_fn, config, and has_density fields.
+       Add num_formats, formats, format_decode_fn, length_decode_fn,
+       num_slots, slots, num_fields, num_operands, operands, num_iclasses,
+       iclasses, num_regfiles, regfiles, num_states, states,
+       state_lookup_table, num_sysregs, sysregs, sysreg_lookup_table,
+       max_sysreg_num, sysreg_table, num_interfaces, interfaces,
+       interface_lookup_table, num_funcUnits, funcUnits and
+       funcUnit_lookup_table fields.
+       (xtensa_isa_module, xtensa_isa_modules): Delete.
+       (xtensa_isa_name_compare): New prototype.
+       (xtisa_errno, xtisa_error_msg): New.
+       * xtensa-isa.h (XTENSA_ISA_VERSION): Define.
+       (xtensa_isa): Change type.
+       (xtensa_operand): Delete.
+       (xtensa_format, xtensa_regfile, xtensa_state, xtensa_sysreg,
+       xtensa_interface, xtensa_funcUnit, xtensa_isa_status,
+       xtensa_funcUnit_use): New types.
+       (libisa_module_specifier): Delete.
+       (xtensa_isa_errno, xtensa_isa_error_msg): New prototypes.
+       (xtensa_insnbuf_free, xtensa_insnbuf_to_chars,
+       xtensa_insnbuf_from_chars): Update prototypes.
+       (xtensa_load_isa, xtensa_extend_isa, xtensa_default_isa,
+       xtensa_insn_maxlength, xtensa_num_opcodes, xtensa_decode_insn,
+       xtensa_encode_insn, xtensa_insn_length,
+       xtensa_insn_length_from_first_byte, xtensa_num_operands,
+       xtensa_operand_kind, xtensa_encode_result,
+       xtensa_operand_isPCRelative): Delete.
+       (xtensa_isa_init, xtensa_operand_inout, xtensa_operand_get_field,
+       xtensa_operand_set_field, xtensa_operand_encode,
+       xtensa_operand_decode, xtensa_operand_do_reloc,
+       xtensa_operand_undo_reloc): Update prototypes.
+       (xtensa_isa_maxlength, xtensa_isa_length_from_chars,
+       xtensa_isa_num_pipe_stages, xtensa_isa_num_formats,
+       xtensa_isa_num_opcodes, xtensa_isa_num_regfiles, xtensa_isa_num_states,
+       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, xtensa_opcode_decode,
+       xtensa_opcode_encode, xtensa_opcode_is_branch, xtensa_opcode_is_jump,
+       xtensa_opcode_is_loop, xtensa_opcode_is_call,
+       xtensa_opcode_num_operands, xtensa_opcode_num_stateOperands,
+       xtensa_opcode_num_interfaceOperands, xtensa_opcode_num_funcUnit_uses,
+       xtensa_opcode_funcUnit_use, xtensa_operand_name,
+       xtensa_operand_is_visible, xtensa_operand_is_register,
+       xtensa_operand_regfile, xtensa_operand_num_regs,
+       xtensa_operand_is_known_reg, xtensa_operand_is_PCrelative,
+       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 prototypes.
+       * elf/xtensa.h (R_XTENSA_DIFF8, R_XTENSA_DIFF16, R_XTENSA_DIFF32,
+       R_XTENSA_SLOT*_OP, R_XTENSA_SLOT*_ALT): New relocations.
+       (XTENSA_PROP_SEC_NAME): Define.
+       (property_table_entry): Add flags field.
+       (XTENSA_PROP_*, GET_XTENSA_PROP_*, SET_XTENSA_PROP_*): Define.
+
 2004-10-07  Jeff Baker  <jbaker@qnx.com>
 
        * bfdlink.h (bfd_link_info): Add bitfield: warn_shared_textrel.
index 6c584c7..14f9913 100644 (file)
@@ -1,5 +1,5 @@
 /* Xtensa ELF support for BFD.
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -42,6 +42,39 @@ START_RELOC_NUMBERS (elf_xtensa_reloc_type)
      RELOC_NUMBER (R_XTENSA_ASM_SIMPLIFY, 12)
      RELOC_NUMBER (R_XTENSA_GNU_VTINHERIT, 15)
      RELOC_NUMBER (R_XTENSA_GNU_VTENTRY, 16)
+     RELOC_NUMBER (R_XTENSA_DIFF8, 17)
+     RELOC_NUMBER (R_XTENSA_DIFF16, 18)
+     RELOC_NUMBER (R_XTENSA_DIFF32, 19)
+     RELOC_NUMBER (R_XTENSA_SLOT0_OP, 20)
+     RELOC_NUMBER (R_XTENSA_SLOT1_OP, 21)
+     RELOC_NUMBER (R_XTENSA_SLOT2_OP, 22)
+     RELOC_NUMBER (R_XTENSA_SLOT3_OP, 23)
+     RELOC_NUMBER (R_XTENSA_SLOT4_OP, 24)
+     RELOC_NUMBER (R_XTENSA_SLOT5_OP, 25)
+     RELOC_NUMBER (R_XTENSA_SLOT6_OP, 26)
+     RELOC_NUMBER (R_XTENSA_SLOT7_OP, 27)
+     RELOC_NUMBER (R_XTENSA_SLOT8_OP, 28)
+     RELOC_NUMBER (R_XTENSA_SLOT9_OP, 29)
+     RELOC_NUMBER (R_XTENSA_SLOT10_OP, 30)
+     RELOC_NUMBER (R_XTENSA_SLOT11_OP, 31)
+     RELOC_NUMBER (R_XTENSA_SLOT12_OP, 32)
+     RELOC_NUMBER (R_XTENSA_SLOT13_OP, 33)
+     RELOC_NUMBER (R_XTENSA_SLOT14_OP, 34)
+     RELOC_NUMBER (R_XTENSA_SLOT0_ALT, 35)
+     RELOC_NUMBER (R_XTENSA_SLOT1_ALT, 36)
+     RELOC_NUMBER (R_XTENSA_SLOT2_ALT, 37)
+     RELOC_NUMBER (R_XTENSA_SLOT3_ALT, 38)
+     RELOC_NUMBER (R_XTENSA_SLOT4_ALT, 39)
+     RELOC_NUMBER (R_XTENSA_SLOT5_ALT, 40)
+     RELOC_NUMBER (R_XTENSA_SLOT6_ALT, 41)
+     RELOC_NUMBER (R_XTENSA_SLOT7_ALT, 42)
+     RELOC_NUMBER (R_XTENSA_SLOT8_ALT, 43)
+     RELOC_NUMBER (R_XTENSA_SLOT9_ALT, 44)
+     RELOC_NUMBER (R_XTENSA_SLOT10_ALT, 45)
+     RELOC_NUMBER (R_XTENSA_SLOT11_ALT, 46)
+     RELOC_NUMBER (R_XTENSA_SLOT12_ALT, 47)
+     RELOC_NUMBER (R_XTENSA_SLOT13_ALT, 48)
+     RELOC_NUMBER (R_XTENSA_SLOT14_ALT, 49)
 END_RELOC_NUMBERS (R_XTENSA_max)
 
 /* Processor-specific flags for the ELF header e_flags field.  */
@@ -78,11 +111,88 @@ END_RELOC_NUMBERS (R_XTENSA_max)
 
 #define XTENSA_INSN_SEC_NAME ".xt.insn"
 #define XTENSA_LIT_SEC_NAME  ".xt.lit"
+#define XTENSA_PROP_SEC_NAME ".xt.prop"
 
 typedef struct property_table_entry_t
 {
   bfd_vma address;
   bfd_vma size;
+  flagword flags;
 } property_table_entry;
 
+/* Flags in the property tables to specify whether blocks of memory are
+   literals, instructions, data, or unreachable.  For instructions,
+   blocks that begin loop targets and branch targets are designated.
+   Blocks that do not allow density instructions, instruction reordering
+   or transformation are also specified.  Finally, for branch targets,
+   branch target alignment priority is included.  Alignment of the next
+   block is specified in the current block and the size of the current
+   block does not include any fill required to align to the next
+   block.  */
+   
+#define XTENSA_PROP_LITERAL            0x00000001
+#define XTENSA_PROP_INSN               0x00000002
+#define XTENSA_PROP_DATA               0x00000004
+#define XTENSA_PROP_UNREACHABLE                0x00000008
+/* Instruction-only properties at beginning of code. */
+#define XTENSA_PROP_INSN_LOOP_TARGET   0x00000010
+#define XTENSA_PROP_INSN_BRANCH_TARGET 0x00000020
+/* Instruction-only properties about code. */
+#define XTENSA_PROP_INSN_NO_DENSITY    0x00000040
+#define XTENSA_PROP_INSN_NO_REORDER    0x00000080
+#define XTENSA_PROP_INSN_NO_TRANSFORM  0x00000100
+
+/*  Branch target alignment information.  This transmits information
+    to the linker optimization about the priority of aligning a
+    particular block for branch target alignment: None, low priority,
+    high priority, or required.  These only need to be checked in
+    instruction blocks marked as XTENSA_PROP_INSN_BRANCH_TARGET.
+    Common usage is:
+
+    switch (GET_XTENSA_PROP_BT_ALIGN(flags))
+    case XTENSA_PROP_BT_ALIGN_NONE:
+    case XTENSA_PROP_BT_ALIGN_LOW:
+    case XTENSA_PROP_BT_ALIGN_HIGH:
+    case XTENSA_PROP_BT_ALIGN_REQUIRE:
+*/
+#define XTENSA_PROP_BT_ALIGN_MASK       0x00000600
+
+/* No branch target alignment.  */
+#define XTENSA_PROP_BT_ALIGN_NONE       0x0
+/* Low priority branch target alignment.  */
+#define XTENSA_PROP_BT_ALIGN_LOW        0x1
+/* High priority branch target alignment. */
+#define XTENSA_PROP_BT_ALIGN_HIGH       0x2
+/* Required branch target alignment.  */
+#define XTENSA_PROP_BT_ALIGN_REQUIRE    0x3
+
+#define GET_XTENSA_PROP_BT_ALIGN(flag) \
+  (((unsigned)((flag) & (XTENSA_PROP_BT_ALIGN_MASK))) >> 9)
+#define SET_XTENSA_PROP_BT_ALIGN(flag, align) \
+  (((flag) & (~XTENSA_PROP_BT_ALIGN_MASK)) | \
+    (((align) << 9) & XTENSA_PROP_BT_ALIGN_MASK))
+
+/* Alignment is specified in the block BEFORE the one that needs
+   alignment.  Up to 5 bits.  Use GET_XTENSA_PROP_ALIGNMENT(flags) to
+   get the required alignment specified as a power of 2.  Use
+   SET_XTENSA_PROP_ALIGNMENT(flags, pow2) to set the required
+   alignment.  Be careful of side effects since the SET will evaluate
+   flags twice.  Also, note that the SIZE of a block in the property
+   table does not include the alignment size, so the alignment fill
+   must be calculated to determine if two blocks are contiguous.
+   TEXT_ALIGN is not currently implemented but is a placeholder for a
+   possible future implementation.  */
+
+#define XTENSA_PROP_ALIGN              0x00000800
+
+#define XTENSA_PROP_ALIGNMENT_MASK      0x0001f000
+
+#define GET_XTENSA_PROP_ALIGNMENT(flag) \
+  (((unsigned)((flag) & (XTENSA_PROP_ALIGNMENT_MASK))) >> 12)
+#define SET_XTENSA_PROP_ALIGNMENT(flag, align) \
+  (((flag) & (~XTENSA_PROP_ALIGNMENT_MASK)) | \
+    (((align) << 12) & XTENSA_PROP_ALIGNMENT_MASK))
+
+#define XTENSA_PROP_INSN_ABSLIT        0x00020000
+
 #endif /* _ELF_XTENSA_H */
index 4191c36..4ef5d64 100644 (file)
@@ -1,5 +1,5 @@
 /* Xtensa configuration settings.
-   Copyright (C) 2001,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
 
    This program is free software; you can redistribute it and/or modify
@@ -42,6 +42,9 @@
 #undef XCHAL_HAVE_L32R
 #define XCHAL_HAVE_L32R                        1
 
+#undef XSHAL_USE_ABSOLUTE_LITERALS
+#define XSHAL_USE_ABSOLUTE_LITERALS    0
+
 #undef XCHAL_HAVE_MAC16
 #define XCHAL_HAVE_MAC16               0
 
@@ -87,6 +90,9 @@
 #undef XCHAL_HAVE_WINDOWED
 #define XCHAL_HAVE_WINDOWED            1
 
+#undef XCHAL_HAVE_PREDICTED_BRANCHES
+#define XCHAL_HAVE_PREDICTED_BRANCHES  0
+
 
 #undef XCHAL_ICACHE_SIZE
 #define XCHAL_ICACHE_SIZE              8192
 #define XCHAL_DEBUGLEVEL               4
 
 
-#undef XCHAL_EXTRA_SA_SIZE
-#define XCHAL_EXTRA_SA_SIZE            0
-
-#undef XCHAL_EXTRA_SA_ALIGN
-#define XCHAL_EXTRA_SA_ALIGN           1
+#undef XCHAL_INST_FETCH_WIDTH
+#define XCHAL_INST_FETCH_WIDTH         4
 
 #endif /* !XTENSA_CONFIG_H */
index 7f221ea..50ac478 100644 (file)
@@ -1,5 +1,5 @@
 /* Internal definitions for 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.
 
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-/* Use the statically-linked version for the GNU tools.  */
-#define STATIC_LIBISA 1
+#ifndef XTENSA_ISA_INTERNAL_H
+#define XTENSA_ISA_INTERNAL_H
 
-#define ISA_INTERFACE_VERSION 3
+/* Flags.  */
 
-struct config_struct
-{
-    char *param_name;
-    char *param_value;
-};
-
-/* Encode/decode function types for immediate operands.  */
-typedef uint32 (*xtensa_immed_decode_fn) (uint32);
-typedef xtensa_encode_result (*xtensa_immed_encode_fn) (uint32 *);
-
-/* Field accessor function types.  */
-typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf);
-typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32);
+#define XTENSA_OPERAND_IS_REGISTER     0x00000001
+#define XTENSA_OPERAND_IS_PCRELATIVE   0x00000002
+#define XTENSA_OPERAND_IS_INVISIBLE    0x00000004
+#define XTENSA_OPERAND_IS_UNKNOWN      0x00000008
 
-/* PC-relative relocation function types.  */
-typedef uint32 (*xtensa_do_reloc_fn) (uint32, uint32);
-typedef uint32 (*xtensa_undo_reloc_fn) (uint32, uint32);
+#define XTENSA_OPCODE_IS_BRANCH                0x00000001
+#define XTENSA_OPCODE_IS_JUMP          0x00000002
+#define XTENSA_OPCODE_IS_LOOP          0x00000004
+#define XTENSA_OPCODE_IS_CALL          0x00000008
 
-/* Instruction decode function type.  */
-typedef int (*xtensa_insn_decode_fn) (const xtensa_insnbuf);
+#define XTENSA_STATE_IS_EXPORTED       0x00000001
 
-/* Instruction encoding template function type (each of these functions
-   returns a constant template; they exist only to make it easier for the
-   TIE compiler to generate endian-independent DLLs).  */
-typedef xtensa_insnbuf (*xtensa_encoding_template_fn) (void);
+#define XTENSA_INTERFACE_HAS_SIDE_EFFECT 0x00000001
 
+/* Function pointer typedefs */
+typedef void (*xtensa_format_encode_fn) (xtensa_insnbuf);
+typedef void (*xtensa_get_slot_fn) (const xtensa_insnbuf, xtensa_insnbuf);
+typedef void (*xtensa_set_slot_fn) (xtensa_insnbuf, const xtensa_insnbuf);
+typedef int (*xtensa_opcode_decode_fn) (const xtensa_insnbuf);
+typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf);
+typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32);
+typedef int (*xtensa_immed_decode_fn) (uint32 *);
+typedef int (*xtensa_immed_encode_fn) (uint32 *);
+typedef int (*xtensa_do_reloc_fn) (uint32 *, uint32);
+typedef int (*xtensa_undo_reloc_fn) (uint32 *, uint32);
+typedef void (*xtensa_opcode_encode_fn) (xtensa_insnbuf);
+typedef int (*xtensa_format_decode_fn) (const xtensa_insnbuf);
+typedef int (*xtensa_length_decode_fn) (const char *);
+
+typedef struct xtensa_format_internal_struct
+{
+  const char *name;                    /* Instruction format name.  */
+  int length;                          /* Instruction length in bytes.  */
+  xtensa_format_encode_fn encode_fn;
+  int num_slots;
+  int *slot_id;                                /* Array[num_slots] of slot IDs.  */
+} xtensa_format_internal;
+
+typedef struct xtensa_slot_internal_struct
+{
+  const char *name;                    /* Not necessarily unique.  */
+  const char *format;
+  int position;
+  xtensa_get_slot_fn get_fn;
+  xtensa_set_slot_fn set_fn;
+  xtensa_get_field_fn *get_field_fns;  /* Array[field_id].  */
+  xtensa_set_field_fn *set_field_fns;  /* Array[field_id].  */
+  xtensa_opcode_decode_fn opcode_decode_fn;
+  const char *nop_name;
+} xtensa_slot_internal;
 
 typedef struct xtensa_operand_internal_struct
 {
-  char *operand_kind;                  /* e.g., "a", "f", "i", "l"....  */
-  char inout;                          /* '<', '>', or '='.  */
-  char isPCRelative;                   /* Is this a PC-relative offset?  */
-  xtensa_get_field_fn get_field;       /* Get encoded value of the field.  */
-  xtensa_set_field_fn set_field;       /* Set field with an encoded value.  */
+  const char *name;
+  int field_id;
+  xtensa_regfile regfile;              /* Register file.  */
+  int num_regs;                                /* Usually 1; 2 for reg pairs, etc.  */
+  uint32 flags;                                /* See XTENSA_OPERAND_* flags.  */
   xtensa_immed_encode_fn encode;       /* Encode the operand value.  */
   xtensa_immed_decode_fn decode;       /* Decode the value from the field.  */
-  xtensa_do_reloc_fn do_reloc;         /* Perform a PC-relative relocation.  */
+  xtensa_do_reloc_fn do_reloc;         /* Perform a PC-relative reloc.  */
   xtensa_undo_reloc_fn undo_reloc;     /* Undo a PC-relative relocation.  */
 } xtensa_operand_internal;
 
+typedef struct xtensa_arg_internal_struct
+{
+  union {
+    int operand_id;                    /* For normal operands.  */
+    xtensa_state state;                        /* For stateOperands.  */
+  } u;
+  char inout;                          /* Direction: 'i', 'o', or 'm'.  */
+} xtensa_arg_internal;
 
 typedef struct xtensa_iclass_internal_struct
 {
   int num_operands;                    /* Size of "operands" array.  */
-  xtensa_operand_internal **operands;  /* Array of operand structures.  */
-} xtensa_iclass_internal;
+  xtensa_arg_internal *operands;       /* Array[num_operands].  */
 
+  int num_stateOperands;               /* Size of "stateOperands" array.  */
+  xtensa_arg_internal *stateOperands;  /* Array[num_stateOperands].  */
+
+  int num_interfaceOperands;           /* Size of "interfaceOperands".  */
+  xtensa_interface *interfaceOperands; /* Array[num_interfaceOperands].  */
+} xtensa_iclass_internal;
 
 typedef struct xtensa_opcode_internal_struct
 {
   const char *name;                    /* Opcode mnemonic.  */
-  int length;                          /* Length in bytes of the insn.  */
-  xtensa_encoding_template_fn template;        /* Fn returning encoding template.  */
-  xtensa_iclass_internal *iclass;      /* Iclass for this opcode.  */
+  int iclass_id;                       /* Iclass for this opcode.  */
+  uint32 flags;                                /* See XTENSA_OPCODE_* flags.  */
+  xtensa_opcode_encode_fn *encode_fns; /* Array[slot_id].  */
+  int num_funcUnit_uses;               /* Number of funcUnit_use entries.  */
+  xtensa_funcUnit_use *funcUnit_uses;  /* Array[num_funcUnit_uses].  */
 } xtensa_opcode_internal;
 
+typedef struct xtensa_regfile_internal_struct
+{
+  const char *name;                    /* Full name of the regfile.  */
+  const char *shortname;               /* Abbreviated name.  */
+  xtensa_regfile parent;               /* View parent (or identity).  */
+  int num_bits;                                /* Width of the registers.  */
+  int num_entries;                     /* Number of registers.  */
+} xtensa_regfile_internal;
+
+typedef struct xtensa_interface_internal_struct
+{
+  const char *name;                    /* Interface name.  */
+  int num_bits;                                /* Width of the interface.  */
+  uint32 flags;                                /* See XTENSA_INTERFACE_* flags.  */
+  char inout;                          /* "i" or "o".  */
+} xtensa_interface_internal;
+
+typedef struct xtensa_funcUnit_internal_struct
+{
+  const char *name;                    /* Functional unit name.  */
+  int num_copies;                      /* Number of instances.  */
+} xtensa_funcUnit_internal;
 
-typedef struct opname_lookup_entry_struct
+typedef struct xtensa_state_internal_struct
 {
-  const char *key;                     /* Opcode mnemonic.  */
-  xtensa_opcode opcode;                        /* Internal opcode number.  */
-} opname_lookup_entry;
+  const char *name;                    /* State name.  */
+  int num_bits;                                /* Number of state bits.  */
+  uint32 flags;                                /* See XTENSA_STATE_* flags.  */
+} xtensa_state_internal;
 
+typedef struct xtensa_sysreg_internal_struct
+{
+  const char *name;                    /* Register name.  */
+  int number;                          /* Register number.  */
+  int is_user;                         /* Non-zero if a "user register".  */
+} xtensa_sysreg_internal;
+
+typedef struct xtensa_lookup_entry_struct
+{
+  const char *key;
+  union
+  {
+    xtensa_opcode opcode;              /* Internal opcode number.  */
+    xtensa_sysreg sysreg;              /* Internal sysreg number.  */
+    xtensa_state state;                        /* Internal state number.  */
+    xtensa_interface intf;             /* Internal interface number.  */
+    xtensa_funcUnit fun;               /* Internal funcUnit number.  */
+  } u;
+} xtensa_lookup_entry;
 
 typedef struct xtensa_isa_internal_struct
 {
   int is_big_endian;                   /* Endianness.  */
   int insn_size;                       /* Maximum length in bytes.  */
   int insnbuf_size;                    /* Number of insnbuf_words.  */
-  int num_opcodes;                     /* Total number for all modules.  */
-  xtensa_opcode_internal **opcode_table;/* Indexed by internal opcode #.  */
-  int num_modules;                     /* Number of modules (DLLs) loaded.  */
-  int *module_opcode_base;             /* Starting opcode # for each module.  */
-  xtensa_insn_decode_fn *module_decode_fn; /* Decode fn for each module.  */
-  opname_lookup_entry *opname_lookup_table; /* Lookup table for each module.  */
-  struct config_struct *config;                /* Table of configuration parameters.  */
-  int has_density;                     /* Is density option available?  */
-} xtensa_isa_internal;
 
+  int num_formats;
+  xtensa_format_internal *formats;
+  xtensa_format_decode_fn format_decode_fn;
+  xtensa_length_decode_fn length_decode_fn;
 
-typedef struct xtensa_isa_module_struct
-{
-  int (*get_num_opcodes_fn) (void);
-  xtensa_opcode_internal **(*get_opcodes_fn) (void);
-  int (*decode_insn_fn) (const xtensa_insnbuf);
-  struct config_struct *(*get_config_table_fn) (void);
-} xtensa_isa_module;
+  int num_slots;
+  xtensa_slot_internal *slots;
+
+  int num_fields;
+
+  int num_operands;
+  xtensa_operand_internal *operands;
+
+  int num_iclasses;
+  xtensa_iclass_internal *iclasses;
+
+  int num_opcodes;
+  xtensa_opcode_internal *opcodes;
+  xtensa_lookup_entry *opname_lookup_table;
+
+  int num_regfiles;
+  xtensa_regfile_internal *regfiles;
+
+  int num_states;
+  xtensa_state_internal *states;
+  xtensa_lookup_entry *state_lookup_table;
+
+  int num_sysregs;
+  xtensa_sysreg_internal *sysregs;
+  xtensa_lookup_entry *sysreg_lookup_table;
+
+  /* The current Xtensa ISA only supports 256 of each kind of sysreg so
+     we can get away with implementing lookups with tables indexed by
+     the register numbers.  If we ever allow larger sysreg numbers, this
+     may have to be reimplemented.  The first entry in the following
+     arrays corresponds to "special" registers and the second to "user"
+     registers.  */
+  int max_sysreg_num[2];
+  xtensa_sysreg *sysreg_table[2];
+
+  int num_interfaces;
+  xtensa_interface_internal *interfaces;
+  xtensa_lookup_entry *interface_lookup_table;
+
+  int num_funcUnits;
+  xtensa_funcUnit_internal *funcUnits;
+  xtensa_lookup_entry *funcUnit_lookup_table;
+
+} xtensa_isa_internal;
+
+extern int xtensa_isa_name_compare (const void *, const void *);
 
-extern xtensa_isa_module xtensa_isa_modules[];
+extern xtensa_isa_status xtisa_errno;
+extern char xtisa_error_msg[];
 
+#endif /* !XTENSA_ISA_INTERNAL_H */
index 54f750c..2dc11b9 100644 (file)
@@ -1,5 +1,5 @@
 /* Interface definition for 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.
 
 #ifndef XTENSA_LIBISA_H
 #define XTENSA_LIBISA_H
 
-/* Use the statically-linked version for the GNU tools.  */
-#define STATIC_LIBISA 1
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/* Use the statically-linked version for the GNU tools.  */
+#define STATIC_LIBISA 1
+
+/* Version number: This is intended to help support code that works with
+   versions of this library from multiple Xtensa releases.  */
+
+#define XTENSA_ISA_VERSION 7000
+
 #ifndef uint32
 #define uint32 unsigned int
 #endif
 
-/* This file defines the interface to the Xtensa ISA library.  This library
-   contains most of the ISA-specific information for a particular Xtensa
-   processor.  For example, the set of valid instructions, their opcode
-   encodings and operand fields are all included here.  To support Xtensa's
-   configurability and user-defined instruction extensions (i.e., TIE), the
-   library is initialized by loading one or more dynamic libraries; only a
-   small set of interface code is present in the statically-linked portion
-   of the library.
+/* This file defines the interface to the Xtensa ISA library.  This
+   library contains most of the ISA-specific information for a
+   particular Xtensa processor.  For example, the set of valid
+   instructions, their opcode encodings and operand fields are all
+   included here.
 
-   This interface basically defines four abstract data types.
+   This interface basically defines a number of abstract data types.
 
    . an instruction buffer - for holding the raw instruction bits
    . ISA info - information about the ISA as a whole
-   . opcode info - information about individual instructions
-   . operand info - information about specific instruction operands
-
-   It would be nice to implement these as classes in C++, but the library is
-   implemented in C to match the expectations of the GNU tools.
-   Instead, the interface defines a set of functions to access each data
-   type.  With the exception of the instruction buffer, the internal
-   representations of the data structures are hidden.  All accesses must be
-   made through the functions defined here.  */
+   . instruction formats - instruction size and slot structure
+   . opcodes - information about individual instructions
+   . operands - information about register and immediate instruction operands
+   . stateOperands - information about processor state instruction operands
+   . interfaceOperands - information about interface instruction operands
+   . register files - register file information
+   . processor states - internal processor state information
+   . system registers - "special registers" and "user registers"
+   . interfaces - TIE interfaces that are external to the processor
+   . functional units - TIE shared functions
+
+   The interface defines a set of functions to access each data type.
+   With the exception of the instruction buffer, the internal
+   representations of the data structures are hidden.  All accesses must
+   be made through the functions defined here.  */
+
+typedef struct xtensa_isa_opaque { int unused; } *xtensa_isa;
+
+
+/* Opcodes, formats, regfiles, states, sysregs, ctypes, and protos are
+   represented here using sequential integers beginning with 0.  The
+   specific values are only fixed for a particular instantiation of an
+   xtensa_isa structure, so these values should only be used
+   internally.  */
 
-typedef void* xtensa_isa;
-typedef void* xtensa_operand;
-
-
-/* Opcodes are represented here using sequential integers beginning with 0.
-   The specific value used for a particular opcode is only fixed for a
-   particular instantiation of an xtensa_isa structure, so these values
-   should only be used internally.  */
 typedef int xtensa_opcode;
-
-/* Define a unique value for undefined opcodes ("static const int" doesn't
-   seem to work for this because EGCS 1.0.3 on i686-Linux without -O won't
-   allow it to be used as an initializer).  */
-#define XTENSA_UNDEFINED -1
+typedef int xtensa_format;
+typedef int xtensa_regfile;
+typedef int xtensa_state;
+typedef int xtensa_sysreg;
+typedef int xtensa_interface;
+typedef int xtensa_funcUnit;
 
 
-typedef int libisa_module_specifier;
+/* Define a unique value for undefined items.  */
 
-extern xtensa_isa xtensa_isa_init (void);
+#define XTENSA_UNDEFINED -1
 
 
+/* Overview of using this interface to decode/encode instructions:
+
+   Each Xtensa instruction is associated with a particular instruction
+   format, where the format defines a fixed number of slots for
+   operations.  The formats for the core Xtensa ISA have only one slot,
+   but FLIX instructions may have multiple slots.  Within each slot,
+   there is a single opcode and some number of associated operands.
+
+   The encoding and decoding functions operate on instruction buffers,
+   not on the raw bytes of the instructions.  The same instruction
+   buffer data structure is used for both entire instructions and
+   individual slots in those instructions -- the contents of a slot need
+   to be extracted from or inserted into the buffer for the instruction
+   as a whole.
+
+   Decoding an instruction involves first finding the format, which
+   identifies the number of slots, and then decoding each slot
+   separately.  A slot is decoded by finding the opcode and then using
+   the opcode to determine how many operands there are.  For example:
+
+   xtensa_insnbuf_from_chars
+   xtensa_format_decode
+   for each slot {
+     xtensa_format_get_slot
+     xtensa_opcode_decode
+     for each operand {
+       xtensa_operand_get_field
+       xtensa_operand_decode
+     }
+   }
+
+   Encoding an instruction is roughly the same procedure in reverse:
+
+   xtensa_format_encode
+   for each slot {
+     xtensa_opcode_encode
+     for each operand {
+       xtensa_operand_encode
+       xtensa_operand_set_field
+     }
+     xtensa_format_set_slot
+   }
+   xtensa_insnbuf_to_chars
+*/
+
+\f
+/* Error handling.  */
+
+/* Error codes.  The code for the most recent error condition can be
+   retrieved with the "errno" function.  For any result other than
+   xtensa_isa_ok, an error message containing additional information
+   about the problem can be retrieved using the "error_msg" function.
+   The error messages are stored in an internal buffer, which should not
+   should be freed and may be overwritten by subsequent operations.  */
+
+typedef enum xtensa_isa_status_enum
+{
+  xtensa_isa_ok = 0,
+  xtensa_isa_bad_format,
+  xtensa_isa_bad_slot,
+  xtensa_isa_bad_opcode,
+  xtensa_isa_bad_operand,
+  xtensa_isa_bad_field,
+  xtensa_isa_bad_iclass,
+  xtensa_isa_bad_regfile,
+  xtensa_isa_bad_sysreg,
+  xtensa_isa_bad_state,
+  xtensa_isa_bad_interface,
+  xtensa_isa_bad_funcUnit,
+  xtensa_isa_wrong_slot,
+  xtensa_isa_no_field,
+  xtensa_isa_out_of_memory,
+  xtensa_isa_buffer_overflow,
+  xtensa_isa_internal_error,
+  xtensa_isa_bad_value
+} xtensa_isa_status;
+
+extern xtensa_isa_status
+xtensa_isa_errno (xtensa_isa isa);
+
+extern char *
+xtensa_isa_error_msg (xtensa_isa isa);
+
+\f
 /* Instruction buffers.  */
 
 typedef uint32 xtensa_insnbuf_word;
 typedef xtensa_insnbuf_word *xtensa_insnbuf;
 
-/* Get the size in words of the xtensa_insnbuf array.  */
-extern int xtensa_insnbuf_size (xtensa_isa); 
 
-/* Allocate (with malloc) an xtensa_insnbuf of the right size.  */
-extern xtensa_insnbuf xtensa_insnbuf_alloc (xtensa_isa);
+/* Get the size in "insnbuf_words" of the xtensa_insnbuf array.  */
 
-/* Release (with free) an xtensa_insnbuf of the right size.  */
-extern void xtensa_insnbuf_free (xtensa_insnbuf);
+extern int
+xtensa_insnbuf_size (xtensa_isa isa); 
 
-/* Inward and outward conversion from memory images (byte streams) to our
-   internal instruction representation.  */
-extern void xtensa_insnbuf_to_chars (xtensa_isa, const xtensa_insnbuf,
-                                    char *);
 
-extern void xtensa_insnbuf_from_chars (xtensa_isa, xtensa_insnbuf,
-                                      const char *);
+/* Allocate an xtensa_insnbuf of the right size.  */
 
+extern xtensa_insnbuf
+xtensa_insnbuf_alloc (xtensa_isa isa);
 
-/* ISA information.  */
 
-/* Load the ISA information from a shared library.  If successful, this returns
-   a value which identifies the ISA for use in subsequent calls to the ISA
-   library; otherwise, it returns NULL.  Multiple ISAs can be loaded to support
-   heterogeneous multiprocessor systems.  */
-extern xtensa_isa xtensa_load_isa (libisa_module_specifier);
+/* Release an xtensa_insnbuf.  */
+
+extern void
+xtensa_insnbuf_free (xtensa_isa isa, xtensa_insnbuf buf);
+
 
-/* Extend an existing set of ISA information by loading an additional shared
-   library of ISA information.  This is primarily intended for loading TIE
-   extensions.  If successful, the return value is non-zero.  */
-extern int xtensa_extend_isa (xtensa_isa, libisa_module_specifier);
+/* Conversion between raw memory (char arrays) and our internal
+   instruction representation.  This is complicated by the Xtensa ISA's
+   variable instruction lengths.  When converting to chars, the buffer
+   must contain a valid instruction so we know how many bytes to copy;
+   thus, the "to_chars" function returns the number of bytes copied or
+   XTENSA_UNDEFINED on error.  The "from_chars" function first reads the
+   minimal number of bytes required to decode the instruction length and
+   then proceeds to copy the entire instruction into the buffer; if the
+   memory does not contain a valid instruction, it copies the maximum
+   number of bytes required for the longest Xtensa instruction.  The
+   "num_chars" argument may be used to limit the number of bytes that
+   can be read or written.  Otherwise, if "num_chars" is zero, the
+   functions may read or write past the end of the code.  */
 
-/* The default ISA.  This variable is set automatically to the ISA most
-   recently loaded and is provided as a convenience.  An exception is the GNU
-   opcodes library, where there is a fixed interface that does not allow
-   passing the ISA as a parameter and the ISA must be taken from this global
-   variable.  (Note: Since this variable is just a convenience, it is not
-   exported when libisa is built as a DLL, due to the hassle of dealing with
-   declspecs.)  */
-extern xtensa_isa xtensa_default_isa;
+extern int
+xtensa_insnbuf_to_chars (xtensa_isa isa, const xtensa_insnbuf insn,
+                        char *cp, int num_chars);
+
+extern void
+xtensa_insnbuf_from_chars (xtensa_isa isa, xtensa_insnbuf insn,
+                          const char *cp, int num_chars);
+
+\f
+/* ISA information.  */
+
+/* Initialize the ISA information.  */
+
+extern xtensa_isa
+xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p);
 
 
 /* Deallocate an xtensa_isa structure.  */
-extern void xtensa_isa_free (xtensa_isa);
+
+extern void
+xtensa_isa_free (xtensa_isa isa);
+
 
 /* Get the maximum instruction size in bytes.  */
-extern int xtensa_insn_maxlength (xtensa_isa); 
 
-/* Get the total number of opcodes for this processor.  */
-extern int xtensa_num_opcodes (xtensa_isa);
+extern int
+xtensa_isa_maxlength (xtensa_isa isa); 
+
+
+/* Decode the length in bytes of an instruction in raw memory (not an
+   insnbuf).  This function reads only the minimal number of bytes
+   required to decode the instruction length.  Returns
+   XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_isa_length_from_chars (xtensa_isa isa, const char *cp);
+
+
+/* Get the number of stages in the processor's pipeline.  The pipeline
+   stage values returned by other functions in this library will range
+   from 0 to N-1, where N is the value returned by this function.
+   Note that the stage numbers used here may not correspond to the
+   actual processor hardware, e.g., the hardware may have additional
+   stages before stage 0.  Returns XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_isa_num_pipe_stages (xtensa_isa isa); 
+
+
+/* Get the number of various entities that are defined for this processor.  */
+
+extern int
+xtensa_isa_num_formats (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_opcodes (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_regfiles (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_states (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_sysregs (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_interfaces (xtensa_isa isa);
+
+extern int
+xtensa_isa_num_funcUnits (xtensa_isa isa);
+
+\f
+/* Instruction formats.  */
+
+/* Get the name of a format.  Returns null on error.  */
+
+extern const char *
+xtensa_format_name (xtensa_isa isa, xtensa_format fmt);
+
+
+/* Given a format name, return the format number.  Returns
+   XTENSA_UNDEFINED if the name is not a valid format.  */
+
+extern xtensa_format
+xtensa_format_lookup (xtensa_isa isa, const char *fmtname);
+
+
+/* Decode the instruction format from a binary instruction buffer.
+   Returns XTENSA_UNDEFINED if the format is not recognized.  */
+
+extern xtensa_format
+xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn);
+
+
+/* Set the instruction format field(s) in a binary instruction buffer.
+   All the other fields are set to zero.  Returns non-zero on error.  */
+
+extern int
+xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn);
+
+
+/* Find the length (in bytes) of an instruction.  Returns
+   XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_format_length (xtensa_isa isa, xtensa_format fmt);
+
+
+/* Get the number of slots in an instruction.  Returns XTENSA_UNDEFINED
+   on error.  */
+
+extern int
+xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt);
+
+
+/* Get the opcode for a no-op in a particular slot.
+   Returns XTENSA_UNDEFINED on error.  */
+
+extern xtensa_opcode
+xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot);
+
+
+/* Get the bits for a specified slot out of an insnbuf for the
+   instruction as a whole and put them into an insnbuf for that one
+   slot, and do the opposite to set a slot.  Return non-zero on error.  */
+
+extern int
+xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot,
+                       const xtensa_insnbuf insn, xtensa_insnbuf slotbuf);
+
+extern int
+xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot,
+                       xtensa_insnbuf insn, const xtensa_insnbuf slotbuf);
+
+\f
+/* Opcode information.  */
 
 /* Translate a mnemonic name to an opcode.  Returns XTENSA_UNDEFINED if
    the name is not a valid opcode mnemonic.  */
-extern xtensa_opcode xtensa_opcode_lookup (xtensa_isa, const char *);
 
-/* Decode a binary instruction buffer.  Returns the opcode or
-   XTENSA_UNDEFINED if the instruction is illegal.  */
-extern xtensa_opcode xtensa_decode_insn (xtensa_isa, const xtensa_insnbuf);
+extern xtensa_opcode
+xtensa_opcode_lookup (xtensa_isa isa, const char *opname);
 
 
-/* Opcode information.  */
+/* Decode the opcode for one instruction slot from a binary instruction
+   buffer.  Returns the opcode or XTENSA_UNDEFINED if the opcode is
+   illegal.  */
+
+extern xtensa_opcode
+xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot,
+                     const xtensa_insnbuf slotbuf);
+
 
-/* Set the opcode field(s) in a binary instruction buffer.  The operand
-   fields are set to zero.  */
-extern void xtensa_encode_insn (xtensa_isa, xtensa_opcode, xtensa_insnbuf);
+/* Set the opcode field(s) for an instruction slot.  All other fields
+   in the slot are set to zero.  Returns non-zero if the opcode cannot
+   be encoded.  */
 
-/* Get the mnemonic name for an opcode.  */
-extern const char * xtensa_opcode_name (xtensa_isa, xtensa_opcode);
+extern int
+xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot,
+                     xtensa_insnbuf slotbuf, xtensa_opcode opc);
 
-/* Find the length (in bytes) of an instruction.  */
-extern int xtensa_insn_length (xtensa_isa, xtensa_opcode);
 
-/* Find the length of an instruction by looking only at the first byte.  */
-extern int xtensa_insn_length_from_first_byte (xtensa_isa, char);
+/* Get the mnemonic name for an opcode.  Returns null on error.  */
 
-/* Find the number of operands for an instruction.  */
-extern int xtensa_num_operands (xtensa_isa, xtensa_opcode);
+extern const char *
+xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc);
 
-/* Get the information about operand number "opnd" of a particular opcode.  */
-extern xtensa_operand xtensa_get_operand (xtensa_isa, xtensa_opcode, int);
 
+/* Check various properties of opcodes.  These functions return 0 if
+   the condition is false, 1 if the condition is true, and
+   XTENSA_UNDEFINED on error.  The instructions are classified as
+   follows:
+
+   branch: conditional branch; may fall through to next instruction (B*)
+   jump: unconditional branch (J, JX, RET*, RF*)
+   loop: zero-overhead loop (LOOP*)
+   call: unconditional call; control returns to next instruction (CALL*)
+
+   For the opcodes that affect control flow in some way, the branch
+   target may be specified by an immediate operand or it may be an
+   address stored in a register.  You can distinguish these by
+   checking if the instruction has a PC-relative immediate
+   operand.  */
+
+extern int
+xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc);
+
+extern int
+xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc);
+
+extern int
+xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc);
+
+extern int
+xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc);
+
+
+/* Find the number of ordinary operands, state operands, and interface
+   operands for an instruction.  These return XTENSA_UNDEFINED on
+   error.  */
+
+extern int
+xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc);
+
+
+extern int
+xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc);
+
+extern int
+xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc);
+
+
+/* Get functional unit usage requirements for an opcode.  Each "use"
+   is identified by a <functional unit, pipeline stage> pair.  The
+   "num_funcUnit_uses" function returns the number of these "uses" or
+   XTENSA_UNDEFINED on error.  The "funcUnit_use" function returns
+   a pointer to a "use" pair or null on error.  */
+
+typedef struct xtensa_funcUnit_use_struct
+{
+  xtensa_funcUnit unit;
+  int stage;
+} xtensa_funcUnit_use;
+
+extern int
+xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc);
+
+extern xtensa_funcUnit_use *
+xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u);
+
+\f
 /* Operand information.  */
 
-/* Find the kind of operand.  There are three possibilities:
-   1) PC-relative immediates (e.g., "l", "L").  These can be identified with
-      the xtensa_operand_isPCRelative function.
-   2) non-PC-relative immediates ("i").
-   3) register-file short names (e.g., "a", "b", "m" and others defined
-      via TIE).  */
-extern char * xtensa_operand_kind (xtensa_operand);
+/* Get the name of an operand.  Returns null on error.  */
+
+extern const char *
+xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
+
+/* Some operands are "invisible", i.e., not explicitly specified in
+   assembly language.  When assembling an instruction, you need not set
+   the values of invisible operands, since they are either hardwired or
+   derived from other field values.  The values of invisible operands
+   can be examined in the same way as other operands, but remember that
+   an invisible operand may get its value from another visible one, so
+   the entire instruction must be available before examining the
+   invisible operand values.  This function returns 1 if an operand is
+   visible, 0 if it is invisible, or XTENSA_UNDEFINED on error.  Note
+   that whether an operand is visible is orthogonal to whether it is
+   "implicit", i.e., whether it is encoded in a field in the
+   instruction.  */
+
+extern int
+xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd);
 
-/* Check if an operand is an input ('<'), output ('>'), or inout ('=')
+
+/* Check if an operand is an input ('i'), output ('o'), or inout ('m')
    operand.  Note: The output operand of a conditional assignment
-   (e.g., movnez) appears here as an inout ('=') even if it is declared
-   in the TIE code as an output ('>'); this allows the compiler to
-   properly handle register allocation for conditional assignments.  */
-extern char xtensa_operand_inout (xtensa_operand);
+   (e.g., movnez) appears here as an inout ('m') even if it is declared
+   in the TIE code as an output ('o'); this allows the compiler to
+   properly handle register allocation for conditional assignments.
+   Returns 0 on error.  */
+
+extern char
+xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
 
 /* Get and set the raw (encoded) value of the field for the specified
    operand.  The "set" function does not check if the value fits in the
-   field; that is done by the "encode" function below.  */
-extern uint32 xtensa_operand_get_field (xtensa_operand, const xtensa_insnbuf);
+   field; that is done by the "encode" function below.  Both of these
+   functions return non-zero on error, e.g., if the field is not defined
+   for the specified slot.  */
+
+extern int
+xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                         xtensa_format fmt, int slot,
+                         const xtensa_insnbuf slotbuf, uint32 *valp);
 
-extern void xtensa_operand_set_field (xtensa_operand, xtensa_insnbuf, uint32);
+extern int 
+xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                         xtensa_format fmt, int slot,
+                         xtensa_insnbuf slotbuf, uint32 val);
 
 
-/* Encode and decode operands.  The raw bits in the operand field
-   may be encoded in a variety of different ways.  These functions hide the
-   details of that encoding.  The encode function has a special return type
-   (xtensa_encode_result) to indicate success or the reason for failure; the
-   encoded value is returned through the argument pointer.  The decode function
-   has no possibility of failure and returns the decoded value.  */
+/* Encode and decode operands.  The raw bits in the operand field may
+   be encoded in a variety of different ways.  These functions hide
+   the details of that encoding.  The result values are returned through
+   the argument pointer.  The return value is non-zero on error.  */
 
-typedef enum
-{
-  xtensa_encode_result_ok,
-  xtensa_encode_result_align,
-  xtensa_encode_result_not_in_table,
-  xtensa_encode_result_too_low,
-  xtensa_encode_result_too_high,
-  xtensa_encode_result_not_ok,
-  xtensa_encode_result_max = xtensa_encode_result_not_ok
-} xtensa_encode_result;
+extern int
+xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                      uint32 *valp);
+
+extern int
+xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                      uint32 *valp);
+
+
+/* An operand may be either a register operand or an immediate of some
+   sort (e.g., PC-relative or not).  The "is_register" function returns
+   0 if the operand is an immediate, 1 if it is a register, and
+   XTENSA_UNDEFINED on error.  The "regfile" function returns the
+   regfile for a register operand, or XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
+extern xtensa_regfile
+xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
+
+/* Register operands may span multiple consecutive registers, e.g., a
+   64-bit data type may occupy two 32-bit registers.  Only the first
+   register is encoded in the operand field.  This function specifies
+   the number of consecutive registers occupied by this operand.  For
+   non-register operands, the return value is undefined.  Returns
+   XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd);
+                                
+
+/* Some register operands do not completely identify the register being
+   accessed.  For example, the operand value may be added to an internal
+   state value.  By definition, this implies that the corresponding
+   regfile is not allocatable.  Unknown registers should generally be
+   treated with worst-case assumptions.  The function returns 0 if the
+   register value is unknown, 1 if known, and XTENSA_UNDEFINED on
+   error.  */
+
+extern int
+xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
+
+/* Check if an immediate operand is PC-relative.  Returns 0 for register
+   operands and non-PC-relative immediates, 1 for PC-relative
+   immediates, and XTENSA_UNDEFINED on error.  */
+extern int
+xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd);
+
+
+/* For PC-relative offset operands, the interpretation of the offset may
+   vary between opcodes, e.g., is it relative to the current PC or that
+   of the next instruction?  The following functions are defined to
+   perform PC-relative relocations and to undo them (as in the
+   disassembler).  The "do_reloc" function takes the desired address
+   value and the PC of the current instruction and sets the value to the
+   corresponding PC-relative offset (which can then be encoded and
+   stored into the operand field).  The "undo_reloc" function takes the
+   unencoded offset value and the current PC and sets the value to the
+   appropriate address.  The return values are non-zero on error.  Note
+   that these functions do not replace the encode/decode functions; the
+   operands must be encoded/decoded separately and the encode functions
+   are responsible for detecting invalid operand values.  */
+
+extern int
+xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                        uint32 *valp, uint32 pc);
+
+extern int
+xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd,
+                          uint32 *valp, uint32 pc);
+
+\f
+/* State Operands.  */
+
+/* Get the state accessed by a state operand.  Returns XTENSA_UNDEFINED
+   on error.  */
+
+extern xtensa_state
+xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp);
+
+
+/* Check if a state operand is an input ('i'), output ('o'), or inout
+   ('m') operand.  Returns 0 on error.  */
+
+extern char
+xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp);
+
+\f
+/* Interface Operands.  */
+
+/* Get the external interface accessed by an interface operand.
+   Returns XTENSA_UNDEFINED on error.  */
+
+extern xtensa_interface
+xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc,
+                                  int ifOp);
+
+\f
+/* Register Files.  */
+
+/* Regfiles include both "real" regfiles and "views", where a view
+   allows a group of adjacent registers in a real "parent" regfile to be
+   viewed as a single register.  A regfile view has all the same
+   properties as its parent except for its (long) name, bit width, number
+   of entries, and default ctype.  You can use the parent function to
+   distinguish these two classes.  */
+
+/* Look up a regfile by either its name or its abbreviated "short name".
+   Returns XTENSA_UNDEFINED on error.  The "lookup_shortname" function
+   ignores "view" regfiles since they always have the same shortname as
+   their parents.  */
+
+extern xtensa_regfile
+xtensa_regfile_lookup (xtensa_isa isa, const char *name);
+
+extern xtensa_regfile
+xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname);
+
+
+/* Get the name or abbreviated "short name" of a regfile.
+   Returns null on error.  */
+
+extern const char *
+xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf);
+
+extern const char *
+xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf);
+
+
+/* Get the parent regfile of a "view" regfile.  If the regfile is not a
+   view, the result is the same as the input parameter.  Returns
+   XTENSA_UNDEFINED on error.  */
+
+extern xtensa_regfile
+xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf);
+
+
+/* Get the bit width of a regfile or regfile view.
+   Returns XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf);
+
+
+/* Get the number of regfile entries.  Returns XTENSA_UNDEFINED on
+   error.  */
+
+extern int
+xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf);
+
+\f
+/* Processor States.  */
+
+/* Look up a state by name.  Returns XTENSA_UNDEFINED on error.  */
+
+extern xtensa_state
+xtensa_state_lookup (xtensa_isa isa, const char *name);
+
+
+/* Get the name for a processor state.  Returns null on error.  */
+
+extern const char *
+xtensa_state_name (xtensa_isa isa, xtensa_state st);
+
+
+/* Get the bit width for a processor state.
+   Returns XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_state_num_bits (xtensa_isa isa, xtensa_state st);
+
+
+/* Check if a state is exported from the processor core.  Returns 0 if
+   the condition is false, 1 if the condition is true, and
+   XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_state_is_exported (xtensa_isa isa, xtensa_state st);
+
+\f
+/* Sysregs ("special registers" and "user registers").  */
+
+/* Look up a register by its number and whether it is a "user register"
+   or a "special register".  Returns XTENSA_UNDEFINED if the sysreg does
+   not exist.  */
+
+extern xtensa_sysreg
+xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user);
+
+
+/* Check if there exists a sysreg with a given name.
+   If not, this function returns XTENSA_UNDEFINED.  */
+
+extern xtensa_sysreg
+xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name);
+
+
+/* Get the name of a sysreg.  Returns null on error.  */
+
+extern const char *
+xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg);
+
+
+/* Get the register number.  Returns XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg);
+
+
+/* Check if a sysreg is a "special register" or a "user register".
+   Returns 0 for special registers, 1 for user registers and
+   XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg);
+
+\f
+/* Interfaces.  */
+
+/* Find an interface by name.  The return value is XTENSA_UNDEFINED if
+   the specified interface is not found.  */
+
+extern xtensa_interface
+xtensa_interface_lookup (xtensa_isa isa, const char *ifname);
+
+
+/* Get the name of an interface.  Returns null on error.  */
+
+extern const char *
+xtensa_interface_name (xtensa_isa isa, xtensa_interface intf);
+
+
+/* Get the bit width for an interface.
+   Returns XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf);
+
+
+/* Check if an interface is an input ('i') or output ('o') with respect
+   to the Xtensa processor core.  Returns 0 on error.  */
+
+extern char
+xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf);
+
+
+/* Check if accessing an interface has potential side effects.
+   Currently "data" interfaces have side effects and "control"
+   interfaces do not.  Returns 1 if there are side effects, 0 if not,
+   and XTENSA_UNDEFINED on error.  */
+
+extern int
+xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf);
+
+\f
+/* Functional Units.  */
+
+/* Find a functional unit by name.  The return value is XTENSA_UNDEFINED if
+   the specified unit is not found.  */
+
+extern xtensa_funcUnit
+xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname);
 
-extern xtensa_encode_result xtensa_operand_encode (xtensa_operand, uint32 *);
 
-extern uint32 xtensa_operand_decode (xtensa_operand, uint32);
+/* Get the name of a functional unit.  Returns null on error.  */
 
+extern const char *
+xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun);
 
-/* For PC-relative offset operands, the interpretation of the offset may vary
-   between opcodes, e.g., is it relative to the current PC or that of the next
-   instruction?  The following functions are defined to perform PC-relative
-   relocations and to undo them (as in the disassembler).  The first function
-   takes the desired address and the PC of the current instruction and returns
-   the unencoded value to be stored in the offset field.  The second function
-   takes the unencoded offset value and the current PC and returns the address.
-   Note that these functions do not replace the encode/decode functions; the
-   operands must be encoded/decoded separately.  */
 
-extern int xtensa_operand_isPCRelative (xtensa_operand);
+/* Functional units may be replicated.  See how many instances of a
+   particular function unit exist.  Returns XTENSA_UNDEFINED on error.  */
 
-extern uint32 xtensa_operand_do_reloc (xtensa_operand, uint32, uint32);
+extern int
+xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun);
 
-extern uint32 xtensa_operand_undo_reloc        (xtensa_operand, uint32, uint32);
 
 #ifdef __cplusplus
 }
index 4abaa54..41bf72e 100644 (file)
@@ -1,3 +1,12 @@
+2004-10-07  Bob Wilson  <bob.wilson@acm.org>
+
+       * xtensa-dis.c (state_names): Delete.
+       (fetch_data): Use xtensa_isa_maxlength.
+       (print_xtensa_operand): Replace operand parameter with opcode/operand
+       pair.  Remove print_sr_name parameter.  Use new xtensa-isa.h functions.
+       (print_insn_xtensa): Use new xtensa-isa.h functions.  Handle multislot
+       instruction bundles.  Use xmalloc instead of malloc.
+
 2004-10-07  David Gibson  <david@gibson.dropbear.id.au>
 
        * ppc-opc.c: Replace literal "0"s with NULLs in pointer
index 8c31085..d7554a7 100644 (file)
@@ -1,5 +1,5 @@
 /* xtensa-dis.c.  Disassembly functions for Xtensa.
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
 
    This file is part of GDB, GAS, and the GNU binutils.
 #include <string.h>
 #include "xtensa-isa.h"
 #include "ansidecl.h"
+#include "libiberty.h"
 #include "sysdep.h"
 #include "dis-asm.h"
 
 #include <setjmp.h>
 
+extern xtensa_isa xtensa_default_isa;
+
 #ifndef MAX
 #define MAX(a,b) (a > b ? a : b)
 #endif
 
-static char* state_names[256] =
-{
-  "lbeg",                      /* 0 */
-  "lend",                      /* 1 */
-  "lcount",                    /* 2 */
-  "sar",                       /* 3 */
-  "br",                                /* 4 */
-
-  "reserved_5",                        /* 5 */
-  "reserved_6",                        /* 6 */
-  "reserved_7",                        /* 7 */
-
-  "av",                                /* 8 */
-  "avh",                       /* 9 */
-  "bv",                                /* 10 */
-  "sav",                       /* 11 */
-  "scompare1",                 /* 12 */
-
-  "reserved_13",               /* 13 */
-  "reserved_14",               /* 14 */
-  "reserved_15",               /* 15 */
-
-  "acclo",                     /* 16 */
-  "acchi",                     /* 17 */
-
-  "reserved_18",               /* 18 */
-  "reserved_19",               /* 19 */
-  "reserved_20",               /* 20 */
-  "reserved_21",               /* 21 */
-  "reserved_22",               /* 22 */
-  "reserved_23",               /* 23 */
-  "reserved_24",               /* 24 */
-  "reserved_25",               /* 25 */
-  "reserved_26",               /* 26 */
-  "reserved_27",               /* 27 */
-  "reserved_28",               /* 28 */
-  "reserved_29",               /* 29 */
-  "reserved_30",               /* 30 */
-  "reserved_31",               /* 31 */
-
-  "mr0",                       /* 32 */
-  "mr1",                       /* 33 */
-  "mr2",                       /* 34 */
-  "mr3",                       /* 35 */
-
-  "reserved_36",               /* 36 */
-  "reserved_37",               /* 37 */
-  "reserved_38",               /* 38 */
-  "reserved_39",               /* 39 */
-  "reserved_40",               /* 40 */
-  "reserved_41",               /* 41 */
-  "reserved_42",               /* 42 */
-  "reserved_43",               /* 43 */
-  "reserved_44",               /* 44 */
-  "reserved_45",               /* 45 */
-  "reserved_46",               /* 46 */
-  "reserved_47",               /* 47 */
-  "reserved_48",               /* 48 */
-  "reserved_49",               /* 49 */
-  "reserved_50",               /* 50 */
-  "reserved_51",               /* 51 */
-  "reserved_52",               /* 52 */
-  "reserved_53",               /* 53 */
-  "reserved_54",               /* 54 */
-  "reserved_55",               /* 55 */
-  "reserved_56",               /* 56 */
-  "reserved_57",               /* 57 */
-  "reserved_58",               /* 58 */
-  "reserved_59",               /* 59 */
-  "reserved_60",               /* 60 */
-  "reserved_61",               /* 61 */
-  "reserved_62",               /* 62 */
-  "reserved_63",               /* 63 */
-
-  "reserved_64",               /* 64 */
-  "reserved_65",               /* 65 */
-  "reserved_66",               /* 66 */
-  "reserved_67",               /* 67 */
-  "reserved_68",               /* 68 */
-  "reserved_69",               /* 69 */
-  "reserved_70",               /* 70 */
-  "reserved_71",               /* 71 */
-
-  "wb",                                /* 72 */
-  "ws",                                /* 73 */
-
-  "reserved_74",               /* 74 */
-  "reserved_75",               /* 75 */
-  "reserved_76",               /* 76 */
-  "reserved_77",               /* 77 */
-  "reserved_78",               /* 78 */
-  "reserved_79",               /* 79 */
-  "reserved_80",               /* 80 */
-  "reserved_81",               /* 81 */
-  "reserved_82",               /* 82 */
-
-  "ptevaddr",                  /* 83 */
-
-  "reserved_84",               /* 84 */
-  "reserved_85",               /* 85 */
-  "reserved_86",               /* 86 */
-  "reserved_87",               /* 87 */
-  "reserved_88",               /* 88 */
-  "reserved_89",               /* 89 */
-
-  "rasid",                     /* 90 */
-  "itlbcfg",                   /* 91 */
-  "dtlbcfg",                   /* 92 */
-
-  "reserved_93",               /* 93 */
-  "reserved_94",               /* 94 */
-  "reserved_95",               /* 95 */
-
-  "ibreakenable",              /* 96 */
-
-  "reserved_97",               /* 97 */
-
-  "cacheattr",                 /* 98 */
-
-  "reserved_99",               /* 99 */
-  "reserved_100",              /* 100 */
-  "reserved_101",              /* 101 */
-  "reserved_102",              /* 102 */
-  "reserved_103",              /* 103 */
-
-  "ddr",                       /* 104 */
-
-  "reserved_105",              /* 105 */
-  "reserved_106",              /* 106 */
-  "reserved_107",              /* 107 */
-  "reserved_108",              /* 108 */
-  "reserved_109",              /* 109 */
-  "reserved_110",              /* 110 */
-  "reserved_111",              /* 111 */
-  "reserved_112",              /* 112 */
-  "reserved_113",              /* 113 */
-  "reserved_114",              /* 114 */
-  "reserved_115",              /* 115 */
-  "reserved_116",              /* 116 */
-  "reserved_117",              /* 117 */
-  "reserved_118",              /* 118 */
-  "reserved_119",              /* 119 */
-  "reserved_120",              /* 120 */
-  "reserved_121",              /* 121 */
-  "reserved_122",              /* 122 */
-  "reserved_123",              /* 123 */
-  "reserved_124",              /* 124 */
-  "reserved_125",              /* 125 */
-  "reserved_126",              /* 126 */
-  "reserved_127",              /* 127 */
-
-  "ibreaka0",                  /* 128 */
-  "ibreaka1",                  /* 129 */
-  "ibreaka2",                  /* 130 */
-  "ibreaka3",                  /* 131 */
-  "ibreaka4",                  /* 132 */
-  "ibreaka5",                  /* 133 */
-  "ibreaka6",                  /* 134 */
-  "ibreaka7",                  /* 135 */
-  "ibreaka8",                  /* 136 */
-  "ibreaka9",                  /* 137 */
-  "ibreaka10",                 /* 138 */
-  "ibreaka11",                 /* 139 */
-  "ibreaka12",                 /* 140 */
-  "ibreaka13",                 /* 141 */
-  "ibreaka14",                 /* 142 */
-  "ibreaka15",                 /* 143 */
-                          
-  "dbreaka0",                  /* 144 */
-  "dbreaka1",                  /* 145 */
-  "dbreaka2",                  /* 146 */
-  "dbreaka3",                  /* 147 */
-  "dbreaka4",                  /* 148 */
-  "dbreaka5",                  /* 149 */
-  "dbreaka6",                  /* 150 */
-  "dbreaka7",                  /* 151 */
-  "dbreaka8",                  /* 152 */
-  "dbreaka9",                  /* 153 */
-  "dbreaka10",                 /* 154 */
-  "dbreaka11",                 /* 155 */
-  "dbreaka12",                 /* 156 */
-  "dbreaka13",                 /* 157 */
-  "dbreaka14",                 /* 158 */
-  "dbreaka15",                 /* 159 */
-                          
-  "dbreakc0",                  /* 160 */
-  "dbreakc1",                  /* 161 */
-  "dbreakc2",                  /* 162 */
-  "dbreakc3",                  /* 163 */
-  "dbreakc4",                  /* 164 */
-  "dbreakc5",                  /* 165 */
-  "dbreakc6",                  /* 166 */
-  "dbreakc7",                  /* 167 */
-  "dbreakc8",                  /* 168 */
-  "dbreakc9",                  /* 169 */
-  "dbreakc10",                 /* 170 */
-  "dbreakc11",                 /* 171 */
-  "dbreakc12",                 /* 172 */
-  "dbreakc13",                 /* 173 */
-  "dbreakc14",                 /* 174 */
-  "dbreakc15",                 /* 175 */
-
-  "reserved_176",              /* 176 */
-
-  "epc1",                      /* 177 */
-  "epc2",                      /* 178 */
-  "epc3",                      /* 179 */
-  "epc4",                      /* 180 */
-  "epc5",                      /* 181 */
-  "epc6",                      /* 182 */
-  "epc7",                      /* 183 */
-  "epc8",                      /* 184 */
-  "epc9",                      /* 185 */
-  "epc10",                     /* 186 */
-  "epc11",                     /* 187 */
-  "epc12",                     /* 188 */
-  "epc13",                     /* 189 */
-  "epc14",                     /* 190 */
-  "epc15",                     /* 191 */
-  "depc",                      /* 192 */
-
-  "reserved_193",              /* 193 */
-
-  "eps2",                      /* 194 */
-  "eps3",                      /* 195 */
-  "eps4",                      /* 196 */
-  "eps5",                      /* 197 */
-  "eps6",                      /* 198 */
-  "eps7",                      /* 199 */
-  "eps8",                      /* 200 */
-  "eps9",                      /* 201 */
-  "eps10",                     /* 202 */
-  "eps11",                     /* 203 */
-  "eps12",                     /* 204 */
-  "eps13",                     /* 205 */
-  "eps14",                     /* 206 */
-  "eps15",                     /* 207 */
-
-  "reserved_208",              /* 208 */
-
-  "excsave1",                  /* 209 */
-  "excsave2",                  /* 210 */
-  "excsave3",                  /* 211 */
-  "excsave4",                  /* 212 */
-  "excsave5",                  /* 213 */
-  "excsave6",                  /* 214 */
-  "excsave7",                  /* 215 */
-  "excsave8",                  /* 216 */
-  "excsave9",                  /* 217 */
-  "excsave10",                 /* 218 */
-  "excsave11",                 /* 219 */
-  "excsave12",                 /* 220 */
-  "excsave13",                 /* 221 */
-  "excsave14",                 /* 222 */
-  "excsave15",                 /* 223 */
-  "cpenable",                  /* 224 */
-
-  "reserved_225",              /* 225 */
-
-  "interrupt",                 /* 226 */
-  "interrupt2",                        /* 227 */
-  "intenable",                 /* 228 */
-
-  "reserved_229",              /* 229 */
-
-  "ps",                                /* 230 */
-
-  "reserved_231",              /* 231 */
-
-  "exccause",                  /* 232 */
-  "debugcause",                        /* 233 */
-  "ccount",                    /* 234 */
-  "prid",                      /* 235 */
-  "icount",                    /* 236 */
-  "icountlvl",                         /* 237 */
-  "excvaddr",                  /* 238 */
-
-  "reserved_239",              /* 239 */
-
-  "ccompare0",                 /* 240 */
-  "ccompare1",                 /* 241 */
-  "ccompare2",                 /* 242 */
-  "ccompare3",                 /* 243 */
-
-  "misc0",                     /* 244 */
-  "misc1",                     /* 245 */
-  "misc2",                     /* 246 */
-  "misc3",                     /* 247 */
-
-  "reserved_248",              /* 248 */
-  "reserved_249",              /* 249 */
-  "reserved_250",              /* 250 */
-  "reserved_251",              /* 251 */
-  "reserved_252",              /* 252 */
-  "reserved_253",              /* 253 */
-  "reserved_254",              /* 254 */
-  "reserved_255",              /* 255 */
-};
-
-
 int show_raw_fields;
 
 static int fetch_data
-  PARAMS ((struct disassemble_info *info, bfd_vma memaddr));
+  PARAMS ((struct disassemble_info *, bfd_vma));
 static void print_xtensa_operand
-  PARAMS ((bfd_vma, struct disassemble_info *, xtensa_operand,
-          unsigned operand_val, int print_sr_name));
+  PARAMS ((bfd_vma, struct disassemble_info *, xtensa_opcode, int, unsigned));
 
-struct dis_private {
+struct dis_private
+{
   bfd_byte *byte_buf;
   jmp_buf bailout;
 };
 
+
 static int
 fetch_data (info, memaddr)
      struct disassemble_info *info;
@@ -354,7 +58,7 @@ fetch_data (info, memaddr)
 {
   int length, status = 0;
   struct dis_private *priv = (struct dis_private *) info->private_data;
-  int insn_size = xtensa_insn_maxlength (xtensa_default_isa);
+  int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
 
   /* Read the maximum instruction size, padding with zeros if we go past
      the end of the text section.  This code will automatically adjust
@@ -375,14 +79,14 @@ fetch_data (info, memaddr)
 
 
 static void
-print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
+print_xtensa_operand (memaddr, info, opc, opnd, operand_val)
      bfd_vma memaddr;
      struct disassemble_info *info;
-     xtensa_operand opnd;
+     xtensa_opcode opc;
+     int opnd;
      unsigned operand_val;
-     int print_sr_name;
 {
-  char *kind = xtensa_operand_kind (opnd);
+  xtensa_isa isa = xtensa_default_isa;
   int signed_operand_val;
     
   if (show_raw_fields)
@@ -394,29 +98,42 @@ print_xtensa_operand (memaddr, info, opnd, operand_val, print_sr_name)
       return;
     }
 
-  operand_val = xtensa_operand_decode (opnd, operand_val);
+  (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
   signed_operand_val = (int) operand_val;
 
-  if (xtensa_operand_isPCRelative (opnd))
+  if (xtensa_operand_is_register (isa, opc, opnd) == 0)
     {
-      operand_val = xtensa_operand_undo_reloc (opnd, operand_val, memaddr);
-      info->target = operand_val;
-      (*info->print_address_func) (info->target, info);
-    }
-  else if (!strcmp (kind, "i"))
-    {
-      if (print_sr_name
-         && signed_operand_val >= 0
-         && signed_operand_val <= 255)
-       (*info->fprintf_func) (info->stream, "%s",
-                              state_names[signed_operand_val]);
-      else if ((signed_operand_val > -256) && (signed_operand_val < 256))
-       (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
+      if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
+       {
+         (void) xtensa_operand_undo_reloc (isa, opc, opnd,
+                                           &operand_val, memaddr);
+         info->target = operand_val;
+         (*info->print_address_func) (info->target, info);
+       }
       else
-       (*info->fprintf_func) (info->stream, "0x%x",signed_operand_val);
+       {
+         if ((signed_operand_val > -256) && (signed_operand_val < 256))
+           (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
+         else
+           (*info->fprintf_func) (info->stream, "0x%x", signed_operand_val);
+       }
     }
   else
-    (*info->fprintf_func) (info->stream, "%s%u", kind, operand_val);
+    {
+      int i = 1;
+      xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
+      (*info->fprintf_func) (info->stream, "%s%u",
+                            xtensa_regfile_shortname (isa, opnd_rf),
+                            operand_val);
+      while (i < xtensa_operand_num_regs (isa, opc, opnd))
+       {
+         operand_val++;
+         (*info->fprintf_func) (info->stream, ":%s%u",
+                                xtensa_regfile_shortname (isa, opnd_rf),
+                                operand_val);
+         i++;
+       } 
+    }
 }
 
 
@@ -429,20 +146,21 @@ print_insn_xtensa (memaddr, info)
      struct disassemble_info *info;
 {
   unsigned operand_val;
-  int bytes_fetched, size, maxsize, i, noperands;
+  int bytes_fetched, size, maxsize, i, n, noperands, nslots;
   xtensa_isa isa;
   xtensa_opcode opc;
-  char *op_name;
-  int print_sr_name;
+  xtensa_format fmt;
   struct dis_private priv;
   static bfd_byte *byte_buf = NULL;
   static xtensa_insnbuf insn_buffer = NULL;
+  static xtensa_insnbuf slot_buffer = NULL;
+  int first, first_slot, valid_insn;
 
   if (!xtensa_default_isa)
-    (void) xtensa_isa_init ();
+    xtensa_default_isa = xtensa_isa_init (0, 0);
 
   info->target = 0;
-  maxsize = xtensa_insn_maxlength (xtensa_default_isa);
+  maxsize = xtensa_isa_maxlength (xtensa_default_isa);
 
   /* Set bytes_per_line to control the amount of whitespace between the hex
      values and the opcode.  For Xtensa, we always print one "chunk" and we
@@ -458,9 +176,11 @@ print_insn_xtensa (memaddr, info)
 
   /* Allocate buffers the first time through.  */
   if (!insn_buffer)
-    insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
-  if (!byte_buf)
-    byte_buf = (bfd_byte *) malloc (MAX (maxsize, 4));
+    {
+      insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
+      slot_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
+      byte_buf = (bfd_byte *) xmalloc (MAX (maxsize, 4));
+    }
 
   priv.byte_buf = byte_buf;
 
@@ -471,6 +191,8 @@ print_insn_xtensa (memaddr, info)
 
   /* Don't set "isa" before the setjmp to keep the compiler from griping.  */
   isa = xtensa_default_isa;
+  size = 0;
+  nslots = 0;
 
   /* Fetch the maximum size instruction.  */
   bytes_fetched = fetch_data (info, memaddr);
@@ -478,44 +200,75 @@ print_insn_xtensa (memaddr, info)
   /* Copy the bytes into the decode buffer.  */
   memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
                           sizeof (xtensa_insnbuf_word)));
-  xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf);
+  xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf, bytes_fetched);
+
+  fmt = xtensa_format_decode (isa, insn_buffer);
+  if (fmt == XTENSA_UNDEFINED
+      || ((size = xtensa_format_length (isa, fmt)) > bytes_fetched))
+    valid_insn = 0;
+  else
+    {
+      /* Make sure all the opcodes are valid.  */
+      valid_insn = 1;
+      nslots = xtensa_format_num_slots (isa, fmt);
+      for (n = 0; n < nslots; n++)
+       {
+         xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
+         if (xtensa_opcode_decode (isa, fmt, n, slot_buffer)
+             == XTENSA_UNDEFINED)
+           {
+             valid_insn = 0;
+             break;
+           }
+       }
+    }
 
-  opc = xtensa_decode_insn (isa, insn_buffer);
-  if (opc == XTENSA_UNDEFINED
-      || ((size = xtensa_insn_length (isa, opc)) > bytes_fetched))
+  if (!valid_insn)
     {
       (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
       return 1;
     }
 
-  op_name = (char *) xtensa_opcode_name (isa, opc);
-  (*info->fprintf_func) (info->stream, "%s", op_name);
-
-  print_sr_name = (!strcasecmp (op_name, "wsr")
-                  || !strcasecmp (op_name, "xsr")
-                  || !strcasecmp (op_name, "rsr"));
+  if (nslots > 1)
+    (*info->fprintf_func) (info->stream, "{ ");
 
-  /* Print the operands (if any).  */
-  noperands = xtensa_num_operands (isa, opc);
-  if (noperands > 0)
+  first_slot = 1;
+  for (n = 0; n < nslots; n++)
     {
-      int first = 1;
+      if (first_slot)
+       first_slot = 0;
+      else
+       (*info->fprintf_func) (info->stream, "; ");
+
+      xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
+      opc = xtensa_opcode_decode (isa, fmt, n, slot_buffer);
+      (*info->fprintf_func) (info->stream, "%s",
+                            xtensa_opcode_name (isa, opc));
 
-      (*info->fprintf_func) (info->stream, "\t");
+      /* Print the operands (if any).  */
+      noperands = xtensa_opcode_num_operands (isa, opc);
+      first = 1;
       for (i = 0; i < noperands; i++)
        {
-         xtensa_operand opnd = xtensa_get_operand (isa, opc, i);
-
+         if (xtensa_operand_is_visible (isa, opc, i) == 0)
+           continue;
          if (first)
-           first = 0;
+           {
+             (*info->fprintf_func) (info->stream, "\t");
+             first = 0;
+           }
          else
            (*info->fprintf_func) (info->stream, ", ");
-         operand_val = xtensa_operand_get_field (opnd, insn_buffer);
-         print_xtensa_operand (memaddr, info, opnd, operand_val,
-                               print_sr_name);
-        }
+         (void) xtensa_operand_get_field (isa, opc, i, fmt, n,
+                                          slot_buffer, &operand_val);
+
+         print_xtensa_operand (memaddr, info, opc, i, operand_val);
+       }
     }
 
+  if (nslots > 1)
+    (*info->fprintf_func) (info->stream, " }");
+
   info->bytes_per_chunk = size;
   info->display_endian = info->endian;