* 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.
+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
$(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 \
$(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 \
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,
#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 *));
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
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
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. */
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. */
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,
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[] =
{
/* 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
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 ];
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;
}
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;
}
-/* 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;
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. */
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++;
}
}
/* 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++;
}
}
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;
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;
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;
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:
/* 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";
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;
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;
}
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);
}
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;
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;
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++)
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,
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);
}
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);
}
/* 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;
}
{
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. */
/* 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);
}
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)
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)))
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;
}
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;
{
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;
}
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);
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;
}
}
-/* 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, ®no);
+ 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, ®no)
+ || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND,
+ ®no))
+ 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, ®no)
+ || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ ®no))
+ return XTENSA_UNDEFINED;
+
+ /* Check that the next instruction is also CONST16. */
+ offset += xtensa_format_length (isa, fmt);
+ xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
+ fmt = xtensa_format_decode (isa, insnbuf);
+ if (fmt == XTENSA_UNDEFINED
+ || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
+ return XTENSA_UNDEFINED;
+ opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
+ if (opcode != get_const16_opcode ())
+ return XTENSA_UNDEFINED;
+
+ if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ fmt, 0, slotbuf, &const16_regno)
+ || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
+ &const16_regno)
+ || const16_regno != regno)
+ return XTENSA_UNDEFINED;
}
-}
-
+ else
+ return XTENSA_UNDEFINED;
-/* 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 §ion_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 §ion_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;
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;
}
!= 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
+ 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;
}
}
}
-/* 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
/* 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;
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))
{
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;
}
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;
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;
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;
}
}
+/* 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;
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.
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);
}
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. */
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;
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;
{
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
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);
/* Change symbol values to account for removed literals. */
-bfd_boolean
+bfd_boolean
relax_section_symbols (abfd, sec)
bfd *abfd;
asection *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);
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;
}
}
|| 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;
}
}
\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
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
{
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;
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;
}
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
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);
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
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;
}
-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);
}
{
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;
}
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. */
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. */
/* 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);
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
"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",
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
/* 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;
}
/* 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
};
+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.
/* 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.
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. */
#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 */
/* 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
#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
#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 */
/* 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 */
/* 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
}
+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
/* 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;
{
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
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)
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++;
+ }
+ }
}
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
/* 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;
/* 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);
/* 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;