+ 2 Output a relaxable 16/24 absolute mov.b address relocation
+ (may relax into an 8bit absolute address). */
+
+static void
+do_a_fix_imm (offset, operand, relaxmode)
+ int offset;
+ struct h8_op *operand;
+ int relaxmode;
+{
+ int idx;
+ int size;
+ int where;
+
+ char *t = operand->mode & IMM ? "#" : "@";
+
+ if (operand->exp.X_add_symbol == 0)
+ {
+ char *bytes = frag_now->fr_literal + offset;
+ switch (operand->mode & SIZE)
+ {
+ case L_2:
+ check_operand (operand, 0x3, t);
+ bytes[0] |= (operand->exp.X_add_number) << 4;
+ break;
+ case L_3:
+ check_operand (operand, 0x7, t);
+ bytes[0] |= (operand->exp.X_add_number) << 4;
+ break;
+ case L_8:
+ check_operand (operand, 0xff, t);
+ bytes[0] = operand->exp.X_add_number;
+ break;
+ case L_16:
+ check_operand (operand, 0xffff, t);
+ bytes[0] = operand->exp.X_add_number >> 8;
+ bytes[1] = operand->exp.X_add_number >> 0;
+ break;
+ case L_24:
+ check_operand (operand, 0xffffff, t);
+ bytes[0] = operand->exp.X_add_number >> 16;
+ bytes[1] = operand->exp.X_add_number >> 8;
+ bytes[2] = operand->exp.X_add_number >> 0;
+ break;
+
+ case L_32:
+ /* This should be done with bfd. */
+ bytes[0] = operand->exp.X_add_number >> 24;
+ bytes[1] = operand->exp.X_add_number >> 16;
+ bytes[2] = operand->exp.X_add_number >> 8;
+ bytes[3] = operand->exp.X_add_number >> 0;
+ if (relaxmode != 0)
+ {
+ idx = (relaxmode == 2) ? R_MOV24B1 : R_MOVL1;
+ fix_new_exp (frag_now, offset, 4, &operand->exp, 0, idx);
+ }
+ break;
+ }
+ }
+ else
+ {
+ switch (operand->mode & SIZE)
+ {
+ case L_24:
+ case L_32:
+ size = 4;
+ where = (operand->mode & SIZE) == L_24 ? -1 : 0;
+ if (relaxmode == 2)
+ idx = R_MOV24B1;
+ else if (relaxmode == 1)
+ idx = R_MOVL1;
+ else
+ idx = R_RELLONG;
+ break;
+ default:
+ as_bad (_("Can't work out size of operand.\n"));
+ case L_16:
+ size = 2;
+ where = 0;
+ if (relaxmode == 2)
+ idx = R_MOV16B1;
+ else
+ idx = R_RELWORD;
+ operand->exp.X_add_number =
+ ((operand->exp.X_add_number & 0xffff) ^ 0x8000) - 0x8000;
+ break;
+ case L_8:
+ size = 1;
+ where = 0;
+ idx = R_RELBYTE;
+ operand->exp.X_add_number =
+ ((operand->exp.X_add_number & 0xff) ^ 0x80) - 0x80;
+ }
+
+ fix_new_exp (frag_now,
+ offset + where,
+ size,
+ &operand->exp,
+ 0,
+ idx);
+ }
+}