- bfd_byte code0 = bfd_get_8 (abfd, misc->contents + addr - 2);
- bfd_byte code1 = bfd_get_8 (abfd, misc->contents + addr - 1);
-
- if (IS_PAGE_OPCODE (code0, code1))
- {
- addr -= 2;
- code0 = bfd_get_8 (abfd, misc->contents + addr + 2);
- code1 = bfd_get_8 (abfd, misc->contents + addr + 3);
- }
- else
- {
- code0 = bfd_get_8 (abfd, misc->contents + addr);
- code1 = bfd_get_8 (abfd, misc->contents + addr + 1);
- }
-
- if (IS_JMP_OPCODE (code0, code1)
- && is_switch_128_dispatch_table_p (abfd, addr, true, misc))
- {
- bfd_vma first = addr;
- bfd_vma last = first;
- boolean relaxed = true;
-
- /* On the final pass we must check if *all* entries in the
- dispatch table are relaxed. If *any* are not relaxed
- then we must unrelax *all* the entries in the dispach
- table and also unrelax the dispatch table prologue. */
-
- /* Find the last entry in the dispach table. */
- while (last < sec->_cooked_size)
- {
- code0 = bfd_get_8 (abfd, misc->contents + last);
- code1 = bfd_get_8 (abfd, misc->contents + last + 1);
-
- if (IS_PAGE_OPCODE (code0, code1))
- relaxed = false;
- else if (! IS_JMP_OPCODE (code0, code1))
- break;
-
- last += 2;
- }
-
- /* We should have found the end of the dispatch table
- before reaching the end of the section. If we've have
- reached the end then fail the relaxation which will
- cause the link to be aborted. */
- if (last >= sec->_cooked_size)
- /* Something has gone wrong. */
- return false;
-
- /* If we found an unrelaxed entry then
- unlrelax all the switch table entries. */
- if (! relaxed )
- {
- if (! unrelax_dispatch_table_entries (abfd, sec, first,
- last, changed, misc))
- /* Something has gone wrong. */
- return false;
-
- if (! is_switch_128_dispatch_table_p (abfd, addr, true, misc))
- /* Something has gone wrong. */
- return false;
-
- /* Unrelax the prologue. */
-
- /* Insert an ADD W,WREG insnstruction. */
- if (! ip2k_elf_relax_add_bytes (abfd, sec,
- addr - 2,
- add_w_wreg_opcode,
- sizeof (add_w_wreg_opcode),
- 0))
- /* Something has gone wrong. */
- return false;
- }
-
- return true;
- }
-
- if (IS_JMP_OPCODE (code0, code1)
- && is_switch_256_dispatch_table_p (abfd, addr, true, misc))
- {
- bfd_vma first = addr;
- bfd_vma last;
- boolean relaxed = true;
-
- /* On the final pass we must check if *all* entries in the
- dispatch table are relaxed. If *any* are not relaxed
- then we must unrelax *all* the entries in the dispach
- table and also unrelax the dispatch table prologue. */
-
- /* Note the 1st PAGE/JMP instructions are part of the
- prologue and can safely be relaxed. */
-
- code0 = bfd_get_8 (abfd, misc->contents + first);
- code1 = bfd_get_8 (abfd, misc->contents + first + 1);
-
- if (IS_PAGE_OPCODE (code0, code1))
- {
- first += 2;
- code0 = bfd_get_8 (abfd, misc->contents + first);
- code1 = bfd_get_8 (abfd, misc->contents + first + 1);
- }
-
- if (! IS_JMP_OPCODE (code0, code1))
- /* Something has gone wrong. */
- return false;
-
- first += 2;
- last = first;
-
- /* Find the last entry in the dispach table. */
- while (last < sec->_cooked_size)
- {
- code0 = bfd_get_8 (abfd, misc->contents + last);
- code1 = bfd_get_8 (abfd, misc->contents + last + 1);
-
- if (IS_PAGE_OPCODE (code0, code1))
- relaxed = false;
- else if (! IS_JMP_OPCODE (code0, code1))
- break;
-
- last += 2;
- }
-
- /* We should have found the end of the dispatch table
- before reaching the end of the section. If we have
- reached the end of the section then fail the
- relaxation. */
- if (last >= sec->_cooked_size)
- return false;
-
- /* If we found an unrelaxed entry then
- unrelax all the switch table entries. */
- if (! relaxed)
- {
- if (! unrelax_dispatch_table_entries (abfd, sec, first,
- last, changed, misc))
- return false;
-
- if (! is_switch_256_dispatch_table_p (abfd, addr, true, misc))
- return false;
-
- /* Unrelax the prologue. */
-
- /* Insert an INC 1(SP) insnstruction. */
- if (! ip2k_elf_relax_add_bytes (abfd, sec,
- addr - 6,
- inc_1_sp_opcode,
- sizeof (inc_1_sp_opcode),
- 0))
- return false;
-
- /* Insert an SNC insnstruction. */
- if (! ip2k_elf_relax_add_bytes (abfd, sec,
- addr - 6,
- snc_opcode,
- sizeof (snc_opcode),
- 0))
- return false;
-
- /* Insert an ADD W,WREG insnstruction. */
- if (! ip2k_elf_relax_add_bytes (abfd, sec,
- addr - 6,
- add_w_wreg_opcode,
- sizeof (add_w_wreg_opcode),
- 0))
- return false;
- }
-
- return true;
- }
+ if (addr < 16)
+ return -1;
+
+ /* Check previous 8 instructions. */
+ ip2k_get_mem (abfd, contents + addr - 16, 16, code);
+ if ((IS_ADD_W_WREG_OPCODE (code + 0))
+ && (IS_SNC_OPCODE (code + 2))
+ && (IS_INC_1SP_OPCODE (code + 4))
+ && (IS_ADD_2SP_W_OPCODE (code + 6))
+ && (IS_SNC_OPCODE (code + 8))
+ && (IS_INC_1SP_OPCODE (code + 10))
+ && (IS_PAGE_OPCODE (code + 12))
+ && (IS_JMP_OPCODE (code + 14)))
+ return table_index;
+
+ if ((IS_ADD_W_WREG_OPCODE (code + 2))
+ && (IS_SNC_OPCODE (code + 4))
+ && (IS_INC_1SP_OPCODE (code + 6))
+ && (IS_ADD_2SP_W_OPCODE (code + 8))
+ && (IS_SNC_OPCODE (code + 10))
+ && (IS_INC_1SP_OPCODE (code + 12))
+ && (IS_JMP_OPCODE (code + 14)))
+ return table_index;
+
+ if ((! IS_PAGE_OPCODE (code + 0))
+ || (! IS_JMP_OPCODE (code + 2)))
+ return -1;
+
+ table_index++;
+ addr -= 4;