-/* Write out a short form instruction if possible.
- Return number of instructions not written out. */
-
-static int
-write_2_short (opcode1, insn1, opcode2, insn2, exec_type, fx)
- struct d30v_insn *opcode1, *opcode2;
- long long insn1, insn2;
- exec_type_enum exec_type;
- Fixups *fx;
-{
- long long insn = NOP2;
- char *f;
- int i, j, where;
-
- if (exec_type == EXEC_SEQ
- && (opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR))
- && ((opcode1->op->flags_used & FLAG_DELAY) == 0)
- && ((opcode1->ecc == ECC_AL) || ! Optimizing))
- {
- /* Unconditional, non-delayed branches kill instructions in
- the right bin. Conditional branches don't always but if
- we are not optimizing, then we have been asked to produce
- an error about such constructs. For the purposes of this
- test, subroutine calls are considered to be branches. */
- write_1_short (opcode1, insn1, fx->next, false);
- return 1;
- }
-
- /* Note: we do not have to worry about subroutine calls occuring
- in the right hand container. The return address is always
- aligned to the next 64 bit boundary, be that 64 or 32 bit away. */
- switch (exec_type)
- {
- case EXEC_UNKNOWN: /* Order not specified. */
- if (Optimizing
- && parallel_ok (opcode1, insn1, opcode2, insn2, exec_type)
- && ! ( (opcode1->op->unit == EITHER_BUT_PREFER_MU
- || opcode1->op->unit == MU)
- &&
- ( opcode2->op->unit == EITHER_BUT_PREFER_MU
- || opcode2->op->unit == MU)))
- {
- /* Parallel. */
- exec_type = EXEC_PARALLEL;
-
- if (opcode1->op->unit == IU
- || opcode2->op->unit == MU
- || opcode2->op->unit == EITHER_BUT_PREFER_MU)
- insn = FM00 | (insn2 << 32) | insn1;
- else
- {
- insn = FM00 | (insn1 << 32) | insn2;
- fx = fx->next;
- }
- }
- else if ((opcode1->op->flags_used & (FLAG_JMP | FLAG_JSR)
- && ((opcode1->op->flags_used & FLAG_DELAY) == 0))
- || opcode1->op->flags_used & FLAG_RP)
- {
- /* We must emit (non-delayed) branch type instructions
- on their own with nothing in the right container. */
- /* We must treat repeat instructions likewise, since the
- following instruction has to be separate from the repeat
- in order to be repeated. */
- write_1_short (opcode1, insn1, fx->next, false);
- return 1;
- }
- else if (prev_left_kills_right_p)
- {
- /* The left instruction kils the right slot, so we
- must leave it empty. */
- write_1_short (opcode1, insn1, fx->next, false);
- return 1;
- }
- else if (opcode1->op->unit == IU)
- {
- if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
- {
- /* Case 103810 is a request from Mitsubishi that opcodes
- with EITHER_BUT_PREFER_MU should not be executed in
- reverse sequential order. */
- write_1_short (opcode1, insn1, fx->next, false);
- return 1;
- }
-
- /* Reverse sequential. */
- insn = FM10 | (insn2 << 32) | insn1;
- exec_type = EXEC_REVSEQ;
- }
- else
- {
- /* Sequential. */
- insn = FM01 | (insn1 << 32) | insn2;
- fx = fx->next;
- exec_type = EXEC_SEQ;
- }
- break;
-
- case EXEC_PARALLEL: /* Parallel. */
- flag_explicitly_parallel = flag_xp_state;
- if (! parallel_ok (opcode1, insn1, opcode2, insn2, exec_type))
- as_bad (_("Instructions may not be executed in parallel"));
- else if (opcode1->op->unit == IU)
- {
- if (opcode2->op->unit == IU)
- as_bad (_("Two IU instructions may not be executed in parallel"));
- as_warn (_("Swapping instruction order"));
- insn = FM00 | (insn2 << 32) | insn1;
- }
- else if (opcode2->op->unit == MU)
- {
- if (opcode1->op->unit == MU)
- as_bad (_("Two MU instructions may not be executed in parallel"));
- else if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
- as_warn (_("Executing %s in IU may not work"), opcode1->op->name);
- as_warn (_("Swapping instruction order"));
- insn = FM00 | (insn2 << 32) | insn1;
- }
- else
- {
- if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
- as_warn (_("Executing %s in IU may not work in parallel execution"),
- opcode2->op->name);
-
- insn = FM00 | (insn1 << 32) | insn2;
- fx = fx->next;
- }
- flag_explicitly_parallel = 0;
- break;
-
- case EXEC_SEQ: /* Sequential. */
- if (opcode1->op->unit == IU)
- as_bad (_("IU instruction may not be in the left container"));
- if (prev_left_kills_right_p)
- as_bad (_("special left instruction `%s' kills instruction "
- "`%s' in right container"),
- opcode1->op->name, opcode2->op->name);
- insn = FM01 | (insn1 << 32) | insn2;
- fx = fx->next;
- break;
-
- case EXEC_REVSEQ: /* Reverse sequential. */
- if (opcode2->op->unit == MU)
- as_bad (_("MU instruction may not be in the right container"));
- if (opcode1->op->unit == EITHER_BUT_PREFER_MU)
- as_warn (_("Executing %s in reverse serial with %s may not work"),
- opcode1->op->name, opcode2->op->name);
- else if (opcode2->op->unit == EITHER_BUT_PREFER_MU)
- as_warn (_("Executing %s in IU in reverse serial may not work"),
- opcode2->op->name);
- insn = FM10 | (insn1 << 32) | insn2;
- fx = fx->next;
- break;
-
- default:
- as_fatal (_("unknown execution type passed to write_2_short()"));
- }
-
-#if 0
- printf ("writing out %llx\n", insn);
-#endif
- f = frag_more (8);
- d30v_number_to_chars (f, insn, 8);
-
- /* If the previous instruction was a 32-bit multiply but it is put into a
- parallel container, mark the current instruction as being a 32-bit
- multiply. */
- if (prev_mul32_p && exec_type == EXEC_PARALLEL)
- cur_mul32_p = 1;
-
- for (j = 0; j < 2; j++)
- {
- for (i = 0; i < fx->fc; i++)
- {
- if (fx->fix[i].reloc)
- {
- where = (f - frag_now->fr_literal) + 4 * j;
-
- fix_new_exp (frag_now,
- where,
- fx->fix[i].size,
- &(fx->fix[i].exp),
- fx->fix[i].pcrel,
- fx->fix[i].reloc);
- }
- }
-
- fx->fc = 0;
- fx = fx->next;
- }
-
- return 0;
-}
-