in abiv2/fpu.c [20:90]
int fpu_libc_helper(struct pt_regs *regs)
{
int fault;
unsigned long instrptr, regx = 0;
unsigned long index = 0, tmp = 0;
unsigned long tinstr = 0;
u16 instr_hi, instr_low;
instrptr = instruction_pointer(regs);
if (instrptr & 1)
return 0;
fault = __get_user(instr_low, (u16 *)instrptr);
if (fault)
return 0;
fault = __get_user(instr_hi, (u16 *)(instrptr + 2));
if (fault)
return 0;
tinstr = instr_hi | ((unsigned long)instr_low << 16);
if (((tinstr >> 21) & 0x1F) != 2)
return 0;
if ((tinstr & MTCR_MASK) == MTCR_DIST) {
index = (tinstr >> 16) & 0x1F;
if (index > 13)
return 0;
tmp = tinstr & 0x1F;
if (tmp > 2)
return 0;
regx = *(®s->a0 + index);
if (tmp == 1)
mtcr("cr<1, 2>", regx);
else if (tmp == 2)
mtcr("cr<2, 2>", regx);
else
return 0;
regs->pc += 4;
return 1;
}
if ((tinstr & MFCR_MASK) == MFCR_DIST) {
index = tinstr & 0x1F;
if (index > 13)
return 0;
tmp = ((tinstr >> 16) & 0x1F);
if (tmp > 2)
return 0;
if (tmp == 1)
regx = mfcr("cr<1, 2>");
else if (tmp == 2)
regx = mfcr("cr<2, 2>");
else
return 0;
*(®s->a0 + index) = regx;
regs->pc += 4;
return 1;
}
return 0;
}