float64 syst_float64_mul( float64 a, float64 b ) { float64 z; sim_fpu A; sim_fpu B; sim_fpu ans; sim_fpu_64to (&A, a); sim_fpu_64to (&B, b); #if 0 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, " * "); sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, " = "); #endif flags |= sim_fpu_mul (&ans, &A, &B); #if 0 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); #endif flags |= sim_fpu_round_64 (&ans, rounding_mode, 0); #if 0 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, "\n"); #endif sim_fpu_to64 (&z, &ans); return z; }
float32 syst_float32_mul( float32 a, float32 b ) { float32 z; sim_fpu A; sim_fpu B; sim_fpu ans; sim_fpu_32to (&A, a); sim_fpu_32to (&B, b); #if 0 sim_fpu_print_fpu (&A, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, " + "); sim_fpu_print_fpu (&B, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, " = "); #endif flags |= sim_fpu_mul (&ans, &A, &B); #if 0 sim_fpu_print_fpu (&ans, (sim_fpu_print_func*) fprintf, stdout); #endif flags |= sim_fpu_round_32 (&ans, rounding_mode, 0); #if 0 sim_fpu_print_status (flags, (sim_fpu_print_func*) fprintf, stdout); fprintf (stdout, "\n"); #endif sim_fpu_to32 (&z, &ans); return z; }
/* Implement a 32/64 bit FP mul, setting FP exception bits when appropriate. */ void fpu_mul (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, const void *reg_in1, const void *reg_in2, void *reg_out, const struct fp_prec_t *ops) { sim_fpu m, n, r; REG2VAL (reg_in1, &m); REG2VAL (reg_in2, &n); ROUND (&m); ROUND (&n); FPCR &= ~ EC_MASK; if (sim_fpu_is_snan (&m) || sim_fpu_is_snan (&n) || (sim_fpu_is_infinity (&m) && sim_fpu_is_zero (&n)) || (sim_fpu_is_zero (&m) && sim_fpu_is_infinity (&n))) { if (FPCR & EE_V) FPCR |= EC_V; else VAL2REG (&sim_fpu_qnan, reg_out); } else { sim_fpu_status stat = sim_fpu_mul (&r, &m, &n); stat |= ROUND (&r); if (fpu_status_ok (stat)) VAL2REG (&r, reg_out); } fpu_check_signal_exception (sd, cpu, cia); }
SF sh64_fmuls(SIM_CPU *current_cpu, SF frg, SF frh) { SF result; sim_fpu f1, f2, fres; sim_fpu_32to (&f1, frg); sim_fpu_32to (&f2, frh); sim_fpu_mul (&fres, &f1, &f2); sim_fpu_to32 (&result, &fres); return result; }
DF sh64_fmuld(SIM_CPU *current_cpu, DF drg, DF drh) { DF result; sim_fpu f1, f2, fres; sim_fpu_64to (&f1, drg); sim_fpu_64to (&f2, drh); sim_fpu_mul (&fres, &f1, &f2); sim_fpu_to64 (&result, &fres); return result; }
SF sh64_fmacs(SIM_CPU *current_cpu, SF fr0, SF frm, SF frn) { SF result; sim_fpu m1, m2, a1, fres; sim_fpu_32to (&m1, fr0); sim_fpu_32to (&m2, frm); sim_fpu_32to (&a1, frn); sim_fpu_mul (&fres, &m1, &m2); sim_fpu_add (&fres, &fres, &a1); sim_fpu_to32 (&result, &fres); return result; }
static SF mulsf (CGEN_FPU* fpu, SF x, SF y) { sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned32 res; sim_fpu_status status; sim_fpu_32to (&op1, x); sim_fpu_32to (&op2, y); status = sim_fpu_mul (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to32 (&res, &ans); return res; }
static DF muldf (CGEN_FPU* fpu, DF x, DF y) { sim_fpu op1; sim_fpu op2; sim_fpu ans; unsigned64 res; sim_fpu_status status; sim_fpu_64to (&op1, x); sim_fpu_64to (&op2, y); status = sim_fpu_mul (&ans, &op1, &op2); if (status != 0) (*fpu->ops->error) (fpu, status); sim_fpu_to64 (&res, &ans); return res; }
/* Implement a 32/64 bit FP nmadd, setting FP exception bits when appropriate. */ void fpu_fnmadd (SIM_DESC sd, sim_cpu *cpu, sim_cia cia, const void *reg_in1, const void *reg_in2, const void *reg_in3, void *reg_out, const struct fp_prec_t *ops) { sim_fpu m1, m2, m, mm, n, r; REG2VAL (reg_in1, &m1); REG2VAL (reg_in2, &m2); REG2VAL (reg_in3, &n); ROUND (&m1); ROUND (&m2); ROUND (&n); FPCR &= ~ EC_MASK; if (sim_fpu_is_snan (&m1) || sim_fpu_is_snan (&m2) || sim_fpu_is_snan (&n) || (sim_fpu_is_infinity (&m1) && sim_fpu_is_zero (&m2)) || (sim_fpu_is_zero (&m1) && sim_fpu_is_infinity (&m2))) { invalid_operands: if (FPCR & EE_V) FPCR |= EC_V; else VAL2REG (&sim_fpu_qnan, reg_out); } else { sim_fpu_status stat = sim_fpu_mul (&m, &m1, &m2); if (sim_fpu_is_infinity (&m) && sim_fpu_is_infinity (&n) && sim_fpu_sign (&m) == sim_fpu_sign (&n)) goto invalid_operands; stat |= sim_fpu_neg (&mm, &m); stat |= sim_fpu_add (&r, &mm, &n); stat |= ROUND (&r); if (fpu_status_ok (stat)) VAL2REG (&r, reg_out); } fpu_check_signal_exception (sd, cpu, cia); }
VOID sh64_ftrvs(SIM_CPU *cpu, unsigned g, unsigned h, unsigned f) { int i, j; for (i = 0; i < 4; i++) { SF result; sim_fpu sum; sim_fpu_32to (&sum, 0); for (j = 0; j < 4; j++) { sim_fpu f1, f2, temp; sim_fpu_32to (&f1, sh64_h_fr_get (cpu, (g + i) + (j * 4))); sim_fpu_32to (&f2, sh64_h_fr_get (cpu, h + j)); sim_fpu_mul (&temp, &f1, &f2); sim_fpu_add (&sum, &sum, &temp); } sim_fpu_to32 (&result, &sum); sh64_h_fr_set (cpu, f + i, result); } }