//
// VADDC
//
void RSP_VADDC(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t sn;

   rsp_vect_t result = rsp_vaddc(LOAD_VS(), LOAD_VT(), rsp_vzero(), &sn);
   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero()); // TODO: Confirm.
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sn);
   write_acc_lo(acc, result);
   STORE_RESULT();
}
//
// VMRG
//
void RSP_VMRG(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t le;

   le = read_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e);
   rsp_vect_t result = rsp_vmrg(LOAD_VS(), LOAD_VT(), le);
   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_acc_lo(acc, result);
   STORE_RESULT();
}
//
// VADD
//
void RSP_VADD(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t carry, acc_lo;

   carry = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e);
   rsp_vect_t result = rsp_vadd(LOAD_VS(), LOAD_VT(), carry, &acc_lo);

   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_acc_lo(acc, acc_lo);
   STORE_RESULT();
}
示例#4
0
文件: pipeline.c 项目: ST3ALth/cen64
// Execution stage (vector).
cen64_flatten static inline void rsp_v_ex_stage(struct rsp *rsp) {
  struct rsp_rdex_latch *rdex_latch = &rsp->pipeline.rdex_latch;

  rsp_vect_t vd_reg, vs_reg, vt_shuf_reg, zero;

  unsigned vs, vt, vd, e;
  uint32_t iw;

  if (!(rdex_latch->opcode.flags & OPCODE_INFO_VECTOR))
    return;

  iw = rdex_latch->iw;
  vs = GET_VS(iw);
  vt = GET_VT(iw);
  vd = GET_VD(iw);
  e  = GET_E (iw);

  vs_reg = rsp_vect_load_unshuffled_operand(rsp->cp2.regs[vs].e);
  vt_shuf_reg = rsp_vect_load_and_shuffle_operand(rsp->cp2.regs[vt].e, e);
  zero = rsp_vzero();

  // Finally, execute the instruction.
#ifdef PRINT_EXEC
  debug("%.8X: %s\n", rdex_latch->common.pc,
    rsp_vector_opcode_mnemonics[rdex_latch->opcode.id]);
#endif

  vd_reg = rsp_vector_function_table[rdex_latch->opcode.id](
    rsp, iw, vt_shuf_reg, vs_reg, zero);

  rsp_vect_write_operand(rsp->cp2.regs[vd].e, vd_reg);
}
//
// VSUBC
//
void RSP_VSUBC(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t eq, sn;

   rsp_vect_t result = rsp_vsubc(LOAD_VS(), LOAD_VT(), rsp_vzero(), &eq, &sn);

   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, eq);
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sn);
   write_acc_lo(acc, result);
   STORE_RESULT();
}
void RSP_VMULU(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t acc_lo, acc_md, acc_hi, result;

   result = rsp_vmulf_vmulu<true>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi);

   write_acc_lo(acc, acc_lo);
   write_acc_md(acc, acc_md);
   write_acc_hi(acc, acc_hi);
   STORE_RESULT();
}
//
// VCR
//
void RSP_VCR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t ge, le;

   rsp_vect_t result = rsp_vcr(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le);

#ifdef INTENSE_DEBUG
   for (unsigned i = 0; i < 8; i++)
      fprintf(stderr, "VD[%d] = %d\n", i,
            reinterpret_cast<int16_t*>(&result)[i]);
#endif

   write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge);
   write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le);
   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vce   (rsp->cp2.flags[RSP::RSP_VCE].e, rsp_vzero());
   write_acc_lo(acc, result);
   STORE_RESULT();
}
//
// VCL
//
void RSP_VCL(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t ge, le, eq, sign, vce;

   ge = read_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e);
   le = read_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e);
   eq = read_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e);
   sign = read_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e);
   vce = read_vce(rsp->cp2.flags[RSP::RSP_VCE].e);

   rsp_vect_t result = rsp_vcl(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le, eq, sign, vce);

   write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge);
   write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le);
   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, rsp_vzero());
   write_vce   (rsp->cp2.flags[RSP::RSP_VCE].e, rsp_vzero());
   write_acc_lo(acc, result);
   STORE_RESULT();
}
//
// VSAR
//
void RSP_VSAR(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t result;

   switch (e) {
      case 8: result = read_acc_hi(acc); break;
      case 9: result = read_acc_md(acc); break;
      case 10: result = read_acc_lo(acc); break;
      default: result = rsp_vzero(); break;
   }

   STORE_RESULT();
}
//
// VCH
//
void RSP_VCH(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t ge, le, sign, eq, vce;

   rsp_vect_t result = rsp_vch(LOAD_VS(), LOAD_VT(), rsp_vzero(), &ge, &le, &eq, &sign, &vce);

   write_vcc_hi(rsp->cp2.flags[RSP::RSP_VCC].e, ge);
   write_vcc_lo(rsp->cp2.flags[RSP::RSP_VCC].e, le);
   write_vco_hi(rsp->cp2.flags[RSP::RSP_VCO].e, eq);
   write_vco_lo(rsp->cp2.flags[RSP::RSP_VCO].e, sign);
   write_vce   (rsp->cp2.flags[RSP::RSP_VCE].e, vce);
   write_acc_lo(acc, result);
   STORE_RESULT();
}
//
// VMACF
// VMACU
//
void RSP_VMACF(RSP::CPUState *rsp, unsigned vd, unsigned vs, unsigned vt, unsigned e)
{
   uint16_t *acc = rsp->cp2.acc.e;
   rsp_vect_t acc_lo, acc_md, acc_hi, result;
   acc_lo = read_acc_lo(acc);
   acc_md = read_acc_md(acc);
   acc_hi = read_acc_hi(acc);

   result = rsp_vmacf_vmacu<false>(LOAD_VS(), LOAD_VT(), rsp_vzero(), &acc_lo, &acc_md, &acc_hi);

   write_acc_lo(acc, acc_lo);
   write_acc_md(acc, acc_md);
   write_acc_hi(acc, acc_hi);
   STORE_RESULT();
}
// RESERVED
void RSP_RESERVED(RSP::CPUState *rsp, unsigned vd, unsigned, unsigned, unsigned)
{
   rsp_vect_t result = rsp_vzero();
   STORE_RESULT();
}