+ case op_XOR:
+ if (state->words[0] == 0x7fffffff)
+ {
+ /* NOP encoded as xor -1, -1, -1. */
+ instrName = "nop";
+ decodingClass = CLASS_A4_OP3_SUBOPC3F;
+ }
+ else
+ instrName = "xor";
+ break;
+
+ default:
+ instrName = instruction_name (state,state->_opcode,0,&flags);
+ /* if (instrName) printf("FLAGS=0x%x\n", flags); */
+ if (!instrName)
+ {
+ instrName = "???";
+ state->flow=invalid_instr;
+ }
+ if (flags & IGNORE_FIRST_OPD)
+ ignoreFirstOpd = 1;
+ break;
+ }
+
+ fieldAisReg = fieldBisReg = fieldCisReg = 1; /* Assume regs for now. */
+ flag = cond = is_shimm = is_limm = 0;
+ state->nullifyMode = BR_exec_when_no_jump; /* 0 */
+ signExtend = addrWriteBack = directMem = 0;
+ usesAuxReg = 0;
+
+ switch (decodingClass)
+ {
+ case CLASS_A4_ARITH:
+ CHECK_FIELD_A ();
+ CHECK_FIELD_B ();
+ if (!repeatsOp)
+ CHECK_FIELD_C ();
+ CHECK_FLAG_COND_NULLIFY ();
+
+ write_instr_name ();
+ if (!ignoreFirstOpd)
+ {
+ WRITE_FORMAT_x (A);
+ WRITE_FORMAT_COMMA_x (B);
+ if (!repeatsOp)
+ WRITE_FORMAT_COMMA_x (C);
+ WRITE_NOP_COMMENT ();
+ arc_sprintf (state, state->operandBuffer, formatString,
+ fieldA, fieldB, fieldC);
+ }
+ else
+ {
+ WRITE_FORMAT_x (B);
+ if (!repeatsOp)
+ WRITE_FORMAT_COMMA_x (C);
+ arc_sprintf (state, state->operandBuffer, formatString,
+ fieldB, fieldC);
+ }
+ write_comments ();
+ break;
+
+ case CLASS_A4_OP3_GENERAL:
+ CHECK_FIELD_A ();
+ CHECK_FIELD_B ();
+ CHECK_FLAG_COND_NULLIFY ();
+
+ write_instr_name ();
+ if (!ignoreFirstOpd)
+ {
+ WRITE_FORMAT_x (A);
+ WRITE_FORMAT_COMMA_x (B);
+ WRITE_NOP_COMMENT ();
+ arc_sprintf (state, state->operandBuffer, formatString,
+ fieldA, fieldB);
+ }
+ else
+ {
+ WRITE_FORMAT_x (B);
+ arc_sprintf (state, state->operandBuffer, formatString, fieldB);
+ }
+ write_comments ();
+ break;
+
+ case CLASS_A4_FLAG:
+ CHECK_FIELD_B ();
+ CHECK_FLAG_COND_NULLIFY ();
+ flag = 0; /* This is the FLAG instruction -- it's redundant. */
+
+ write_instr_name ();
+ WRITE_FORMAT_x (B);
+ arc_sprintf (state, state->operandBuffer, formatString, fieldB);
+ write_comments ();
+ break;
+
+ case CLASS_A4_BRANCH:
+ fieldA = BITS (state->words[0],7,26) << 2;
+ fieldA = (fieldA << 10) >> 10; /* Make it signed. */
+ fieldA += addr + 4;
+ CHECK_FLAG_COND_NULLIFY ();
+ flag = 0;
+
+ write_instr_name ();
+ /* This address could be a label we know. Convert it. */
+ if (state->_opcode != op_LPC /* LP */)
+ {
+ add_target (fieldA); /* For debugger. */
+ state->flow = state->_opcode == op_BLC /* BL */
+ ? direct_call
+ : direct_jump;
+ /* indirect calls are achieved by "lr blink,[status];
+ lr dest<- func addr; j [dest]" */
+ }
+
+ strcat (formatString, "%s"); /* Address/label name. */
+ arc_sprintf (state, state->operandBuffer, formatString,
+ post_address (state, fieldA));
+ write_comments ();
+ break;
+
+ case CLASS_A4_JC:
+ /* For op_JC -- jump to address specified.
+ Also covers jump and link--bit 9 of the instr. word
+ selects whether linked, thus "is_linked" is set above. */
+ fieldA = 0;
+ CHECK_FIELD_B ();
+ CHECK_FLAG_COND_NULLIFY ();
+
+ if (!fieldBisReg)
+ {
+ fieldAisReg = 0;
+ fieldA = (fieldB >> 25) & 0x7F; /* Flags. */
+ fieldB = (fieldB & 0xFFFFFF) << 2;
+ state->flow = is_linked ? direct_call : direct_jump;
+ add_target (fieldB);
+ /* Screwy JLcc requires .jd mode to execute correctly
+ but we pretend it is .nd (no delay slot). */
+ if (is_linked && state->nullifyMode == BR_exec_when_jump)
+ state->nullifyMode = BR_exec_when_no_jump;
+ }
+ else
+ {
+ state->flow = is_linked ? indirect_call : indirect_jump;
+ /* We should also treat this as indirect call if NOT linked
+ but the preceding instruction was a "lr blink,[status]"
+ and we have a delay slot with "add blink,blink,2".
+ For now we can't detect such. */
+ state->register_for_indirect_jump = fieldB;
+ }
+
+ write_instr_name ();
+ strcat (formatString,
+ IS_REG (B) ? "[%r]" : "%s"); /* Address/label name. */
+ if (fieldA != 0)
+ {
+ fieldAisReg = 0;
+ WRITE_FORMAT_COMMA_x (A);
+ }
+ if (IS_REG (B))
+ arc_sprintf (state, state->operandBuffer, formatString, fieldB, fieldA);
+ else
+ arc_sprintf (state, state->operandBuffer, formatString,
+ post_address (state, fieldB), fieldA);
+ write_comments ();
+ break;
+
+ case CLASS_A4_LD0:
+ /* LD instruction.
+ B and C can be regs, or one (both?) can be limm. */
+ CHECK_FIELD_A ();
+ CHECK_FIELD_B ();
+ CHECK_FIELD_C ();
+ if (dbg)
+ printf ("5:b reg %d %d c reg %d %d \n",
+ fieldBisReg,fieldB,fieldCisReg,fieldC);
+ state->_offset = 0;
+ state->_ea_present = 1;
+ if (fieldBisReg)
+ state->ea_reg1 = fieldB;
+ else
+ state->_offset += fieldB;
+ if (fieldCisReg)
+ state->ea_reg2 = fieldC;
+ else
+ state->_offset += fieldC;
+ state->_mem_load = 1;
+
+ directMem = BIT (state->words[0], 5);
+ addrWriteBack = BIT (state->words[0], 3);
+ signExtend = BIT (state->words[0], 0);
+
+ write_instr_name ();
+ WRITE_FORMAT_x_COMMA_LB(A);
+ if (fieldBisReg || fieldB != 0)
+ WRITE_FORMAT_x_COMMA (B);
+ else
+ fieldB = fieldC;
+
+ WRITE_FORMAT_x_RB (C);
+ arc_sprintf (state, state->operandBuffer, formatString,
+ fieldA, fieldB, fieldC);
+ write_comments ();
+ break;
+
+ case CLASS_A4_LD1:
+ /* LD instruction. */
+ CHECK_FIELD_B ();
+ CHECK_FIELD_A ();
+ fieldC = FIELDD (state->words[0]);
+
+ if (dbg)
+ printf ("6:b reg %d %d c 0x%x \n",
+ fieldBisReg, fieldB, fieldC);
+ state->_ea_present = 1;
+ state->_offset = fieldC;
+ state->_mem_load = 1;
+ if (fieldBisReg)
+ state->ea_reg1 = fieldB;
+ /* Field B is either a shimm (same as fieldC) or limm (different!)
+ Say ea is not present, so only one of us will do the name lookup. */
+ else
+ state->_offset += fieldB, state->_ea_present = 0;
+
+ directMem = BIT (state->words[0],14);
+ addrWriteBack = BIT (state->words[0],12);
+ signExtend = BIT (state->words[0],9);
+
+ write_instr_name ();
+ WRITE_FORMAT_x_COMMA_LB (A);
+ if (!fieldBisReg)
+ {
+ fieldB = state->_offset;
+ WRITE_FORMAT_x_RB (B);
+ }
+ else
+ {
+ WRITE_FORMAT_x (B);
+ if (fieldC != 0 && !BIT (state->words[0],13))