+ switch (c & CLASS_MASK)
+ {
+ default:
+ abort ();
+
+ case CLASS_ADDRESS:
+ /* Direct address, we don't cope with the SS mode right now. */
+ if (segmented_mode)
+ {
+ /* da_operand->X_add_number |= 0x80000000; -- Now set at relocation time. */
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
+ }
+ else
+ {
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
+ }
+ da_operand = 0;
+ break;
+ case CLASS_DISP8:
+ /* pc rel 8 bit */
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_0DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0;
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
+ da_operand = 0;
+ break;
+
+ case CLASS_1DISP7:
+ /* pc rel 7 bit */
+ *output_ptr = 0x80;
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
+ output_ptr[-2] = 0x8;
+ da_operand = 0;
+ break;
+
+ case CLASS_BIT_1OR2:
+ *output_ptr = c & 0xf;
+ if (imm_operand)
+ {
+ if (imm_operand->X_add_number == 2)
+ *output_ptr |= 2;
+ else if (imm_operand->X_add_number != 1)
+ as_bad (_("immediate must be 1 or 2"));
+ }
+ else
+ as_bad (_("immediate 1 or 2 expected"));
+ output_ptr++;
+ break;
+ case CLASS_CC:
+ *output_ptr++ = the_cc;
+ break;
+ case CLASS_0CCC:
+ if (the_ctrl < 2 || the_ctrl > 7)
+ as_bad (_("invalid control register name"));
+ *output_ptr++ = the_ctrl;
+ break;
+ case CLASS_1CCC:
+ if (the_ctrl < 2 || the_ctrl > 7)
+ as_bad (_("invalid control register name"));
+ *output_ptr++ = the_ctrl | 0x8;
+ break;
+ case CLASS_00II:
+ *output_ptr++ = (~the_interrupt & 0x3);
+ break;
+ case CLASS_01II:
+ *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
+ break;
+ case CLASS_FLAGS:
+ *output_ptr++ = the_flags;
+ break;
+ case CLASS_IGNORE:
+ case CLASS_BIT:
+ *output_ptr++ = c & 0xf;
+ break;
+ case CLASS_REGN0:
+ if (reg[c & 0xf] == 0)
+ as_bad (_("can't use R0 here"));
+ /* Fall through. */
+ case CLASS_REG:
+ case CLASS_REG_BYTE:
+ case CLASS_REG_WORD:
+ case CLASS_REG_LONG:
+ case CLASS_REG_QUAD:
+ /* Insert bit mattern of right reg. */
+ *output_ptr++ = reg[c & 0xf];
+ break;
+ case CLASS_DISP:
+ switch (c & ARG_MASK)
+ {
+ case ARG_DISP12:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
+ break;
+ case ARG_DISP16:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
+ break;
+ default:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
+ }
+ da_operand = 0;
+ break;
+
+ case CLASS_IMM:
+ {
+ switch (c & ARG_MASK)
+ {
+ case ARG_NIM4:
+ if (imm_operand->X_add_number > 15)
+ as_bad (_("immediate value out of range"));
+ imm_operand->X_add_number = -imm_operand->X_add_number;
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
+ break;
+ /*case ARG_IMMNMINUS1: not used. */
+ case ARG_IMM4M1:
+ imm_operand->X_add_number--;
+ /* Drop through. */
+ case ARG_IMM4:
+ if (imm_operand->X_add_number > 15)
+ as_bad (_("immediate value out of range"));
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
+ break;
+ case ARG_NIM8:
+ imm_operand->X_add_number = -imm_operand->X_add_number;
+ /* Drop through. */
+ case ARG_IMM8:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
+ break;
+ case ARG_IMM16:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
+ break;
+ case ARG_IMM32:
+ output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
+ break;
+ default:
+ abort ();
+ }
+ }
+ }