|
@@ -67,11 +67,6 @@ static int fpux_emu(struct pt_regs *,
|
|
|
/* Determine rounding mode from the RM bits of the FCSR */
|
|
|
#define modeindex(v) ((v) & FPU_CSR_RM)
|
|
|
|
|
|
-/* microMIPS bitfields */
|
|
|
-#define MM_POOL32A_MINOR_MASK 0x3f
|
|
|
-#define MM_POOL32A_MINOR_SHIFT 0x6
|
|
|
-#define MM_MIPS32_COND_FC 0x30
|
|
|
-
|
|
|
/* Convert MIPS rounding mode (0..3) to IEEE library modes. */
|
|
|
static const unsigned char ieee_rm[4] = {
|
|
|
[FPU_CSR_RN] = IEEE754_RN,
|
|
@@ -99,9 +94,6 @@ static const unsigned int fpucondbit[8] = {
|
|
|
FPU_CSR_COND7
|
|
|
};
|
|
|
|
|
|
-/* (microMIPS) Convert 16-bit register encoding to 32-bit register encoding. */
|
|
|
-static const unsigned int reg16to32map[8] = {16, 17, 2, 3, 4, 5, 6, 7};
|
|
|
-
|
|
|
/* (microMIPS) Convert certain microMIPS instructions to MIPS32 format. */
|
|
|
static const int sd_format[] = {16, 17, 0, 0, 0, 0, 0, 0};
|
|
|
static const int sdps_format[] = {16, 17, 22, 0, 0, 0, 0, 0};
|
|
@@ -449,199 +441,6 @@ static int microMIPS32_to_MIPS32(union mips_instruction *insn_ptr)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
|
|
|
- unsigned long *contpc)
|
|
|
-{
|
|
|
- union mips_instruction insn = (union mips_instruction)dec_insn.insn;
|
|
|
- int bc_false = 0;
|
|
|
- unsigned int fcr31;
|
|
|
- unsigned int bit;
|
|
|
-
|
|
|
- if (!cpu_has_mmips)
|
|
|
- return 0;
|
|
|
-
|
|
|
- switch (insn.mm_i_format.opcode) {
|
|
|
- case mm_pool32a_op:
|
|
|
- if ((insn.mm_i_format.simmediate & MM_POOL32A_MINOR_MASK) ==
|
|
|
- mm_pool32axf_op) {
|
|
|
- switch (insn.mm_i_format.simmediate >>
|
|
|
- MM_POOL32A_MINOR_SHIFT) {
|
|
|
- case mm_jalr_op:
|
|
|
- case mm_jalrhb_op:
|
|
|
- case mm_jalrs_op:
|
|
|
- case mm_jalrshb_op:
|
|
|
- if (insn.mm_i_format.rt != 0) /* Not mm_jr */
|
|
|
- regs->regs[insn.mm_i_format.rt] =
|
|
|
- regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- *contpc = regs->regs[insn.mm_i_format.rs];
|
|
|
- return 1;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- case mm_pool32i_op:
|
|
|
- switch (insn.mm_i_format.rt) {
|
|
|
- case mm_bltzals_op:
|
|
|
- case mm_bltzal_op:
|
|
|
- regs->regs[31] = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- /* Fall through */
|
|
|
- case mm_bltz_op:
|
|
|
- if ((long)regs->regs[insn.mm_i_format.rs] < 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_bgezals_op:
|
|
|
- case mm_bgezal_op:
|
|
|
- regs->regs[31] = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- /* Fall through */
|
|
|
- case mm_bgez_op:
|
|
|
- if ((long)regs->regs[insn.mm_i_format.rs] >= 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_blez_op:
|
|
|
- if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_bgtz_op:
|
|
|
- if ((long)regs->regs[insn.mm_i_format.rs] <= 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_bc2f_op:
|
|
|
- case mm_bc1f_op:
|
|
|
- bc_false = 1;
|
|
|
- /* Fall through */
|
|
|
- case mm_bc2t_op:
|
|
|
- case mm_bc1t_op:
|
|
|
- preempt_disable();
|
|
|
- if (is_fpu_owner())
|
|
|
- asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
|
|
|
- else
|
|
|
- fcr31 = current->thread.fpu.fcr31;
|
|
|
- preempt_enable();
|
|
|
-
|
|
|
- if (bc_false)
|
|
|
- fcr31 = ~fcr31;
|
|
|
-
|
|
|
- bit = (insn.mm_i_format.rs >> 2);
|
|
|
- bit += (bit != 0);
|
|
|
- bit += 23;
|
|
|
- if (fcr31 & (1 << bit))
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- case mm_pool16c_op:
|
|
|
- switch (insn.mm_i_format.rt) {
|
|
|
- case mm_jalr16_op:
|
|
|
- case mm_jalrs16_op:
|
|
|
- regs->regs[31] = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- /* Fall through */
|
|
|
- case mm_jr16_op:
|
|
|
- *contpc = regs->regs[insn.mm_i_format.rs];
|
|
|
- return 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- case mm_beqz16_op:
|
|
|
- if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] == 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_b1_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_bnez16_op:
|
|
|
- if ((long)regs->regs[reg16to32map[insn.mm_b1_format.rs]] != 0)
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_b1_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_b16_op:
|
|
|
- *contpc = regs->cp0_epc + dec_insn.pc_inc +
|
|
|
- (insn.mm_b0_format.simmediate << 1);
|
|
|
- return 1;
|
|
|
- case mm_beq32_op:
|
|
|
- if (regs->regs[insn.mm_i_format.rs] ==
|
|
|
- regs->regs[insn.mm_i_format.rt])
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_bne32_op:
|
|
|
- if (regs->regs[insn.mm_i_format.rs] !=
|
|
|
- regs->regs[insn.mm_i_format.rt])
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc +
|
|
|
- (insn.mm_i_format.simmediate << 1);
|
|
|
- else
|
|
|
- *contpc = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- return 1;
|
|
|
- case mm_jalx32_op:
|
|
|
- regs->regs[31] = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- *contpc = regs->cp0_epc + dec_insn.pc_inc;
|
|
|
- *contpc >>= 28;
|
|
|
- *contpc <<= 28;
|
|
|
- *contpc |= (insn.j_format.target << 2);
|
|
|
- return 1;
|
|
|
- case mm_jals32_op:
|
|
|
- case mm_jal32_op:
|
|
|
- regs->regs[31] = regs->cp0_epc +
|
|
|
- dec_insn.pc_inc + dec_insn.next_pc_inc;
|
|
|
- /* Fall through */
|
|
|
- case mm_j32_op:
|
|
|
- *contpc = regs->cp0_epc + dec_insn.pc_inc;
|
|
|
- *contpc >>= 27;
|
|
|
- *contpc <<= 27;
|
|
|
- *contpc |= (insn.j_format.target << 1);
|
|
|
- set_isa16_mode(*contpc);
|
|
|
- return 1;
|
|
|
- }
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* Redundant with logic already in kernel/branch.c,
|
|
|
* embedded in compute_return_epc. At some point,
|