1 -- Floating-point unit for Microwatt
4 use ieee.std_logic_1164.all;
5 use ieee.numeric_std.all;
8 use work.insn_helpers.all;
9 use work.decode_types.all;
10 use work.crhelpers.all;
19 e_in : in Execute1toFPUType;
20 e_out : out FPUToExecute1Type;
22 w_out : out FPUToWritebackType
26 architecture behaviour of fpu is
27 type fp_number_class is (ZERO, FINITE, INFINITY, NAN);
29 constant EXP_BITS : natural := 13;
31 type fpu_reg_type is record
32 class : fp_number_class;
33 negative : std_ulogic;
34 exponent : signed(EXP_BITS-1 downto 0); -- unbiased
35 mantissa : std_ulogic_vector(63 downto 0); -- 10.54 format
38 type state_t is (IDLE,
39 DO_MCRFS, DO_MTFSB, DO_MTFSFI, DO_MFFS, DO_MTFSF,
43 INT_SHIFT, INT_ROUND, INT_ISHIFT,
44 INT_FINAL, INT_CHECK, INT_OFLOW,
46 ROUND_UFLOW, ROUND_OFLOW,
47 ROUNDING, ROUNDING_2, ROUNDING_3,
50 type reg_type is record
53 instr_done : std_ulogic;
56 insn : std_ulogic_vector(31 downto 0);
57 dest_fpr : gspr_index_t;
61 single_prec : std_ulogic;
62 fpscr : std_ulogic_vector(31 downto 0);
65 r : std_ulogic_vector(63 downto 0); -- 10.54 format
67 result_sign : std_ulogic;
68 result_class : fp_number_class;
69 result_exp : signed(EXP_BITS-1 downto 0);
70 shift : signed(EXP_BITS-1 downto 0);
71 writing_back : std_ulogic;
72 int_result : std_ulogic;
73 cr_result : std_ulogic_vector(3 downto 0);
74 cr_mask : std_ulogic_vector(7 downto 0);
75 old_exc : std_ulogic_vector(4 downto 0);
76 update_fprf : std_ulogic;
77 quieten_nan : std_ulogic;
80 round_mode : std_ulogic_vector(2 downto 0);
83 signal r, rin : reg_type;
85 signal fp_result : std_ulogic_vector(63 downto 0);
86 signal opsel_a : std_ulogic_vector(1 downto 0);
87 signal opsel_b : std_ulogic_vector(1 downto 0);
88 signal opsel_r : std_ulogic_vector(1 downto 0);
89 signal opsel_ainv : std_ulogic;
90 signal opsel_amask : std_ulogic;
91 signal in_a : std_ulogic_vector(63 downto 0);
92 signal in_b : std_ulogic_vector(63 downto 0);
93 signal result : std_ulogic_vector(63 downto 0);
94 signal carry_in : std_ulogic;
95 signal lost_bits : std_ulogic;
96 signal r_hi_nz : std_ulogic;
97 signal r_lo_nz : std_ulogic;
98 signal misc_sel : std_ulogic_vector(3 downto 0);
101 constant AIN_R : std_ulogic_vector(1 downto 0) := "00";
102 constant AIN_A : std_ulogic_vector(1 downto 0) := "01";
103 constant AIN_B : std_ulogic_vector(1 downto 0) := "10";
105 constant BIN_ZERO : std_ulogic_vector(1 downto 0) := "00";
106 constant BIN_R : std_ulogic_vector(1 downto 0) := "01";
107 constant BIN_MASK : std_ulogic_vector(1 downto 0) := "10";
109 constant RES_SUM : std_ulogic_vector(1 downto 0) := "00";
110 constant RES_SHIFT : std_ulogic_vector(1 downto 0) := "01";
111 constant RES_MISC : std_ulogic_vector(1 downto 0) := "11";
113 -- Left and right shifter with 120 bit input and 64 bit output.
114 -- Shifts inp left by shift bits and returns the upper 64 bits of
115 -- the result. The shift parameter is interpreted as a signed
116 -- number in the range -64..63, with negative values indicating
118 function shifter_64(inp: std_ulogic_vector(119 downto 0);
119 shift: std_ulogic_vector(6 downto 0))
120 return std_ulogic_vector is
121 variable s1 : std_ulogic_vector(94 downto 0);
122 variable s2 : std_ulogic_vector(70 downto 0);
123 variable result : std_ulogic_vector(63 downto 0);
125 case shift(6 downto 5) is
127 s1 := inp(119 downto 25);
129 s1 := inp(87 downto 0) & "0000000";
131 s1 := x"0000000000000000" & inp(119 downto 89);
133 s1 := x"00000000" & inp(119 downto 57);
135 case shift(4 downto 3) is
137 s2 := s1(94 downto 24);
139 s2 := s1(86 downto 16);
141 s2 := s1(78 downto 8);
143 s2 := s1(70 downto 0);
145 case shift(2 downto 0) is
147 result := s2(70 downto 7);
149 result := s2(69 downto 6);
151 result := s2(68 downto 5);
153 result := s2(67 downto 4);
155 result := s2(66 downto 3);
157 result := s2(65 downto 2);
159 result := s2(64 downto 1);
161 result := s2(63 downto 0);
166 -- Generate a mask with 0-bits on the left and 1-bits on the right which
167 -- selects the bits will be lost in doing a right shift. The shift
168 -- parameter is the bottom 6 bits of a negative shift count,
169 -- indicating a right shift.
170 function right_mask(shift: unsigned(5 downto 0)) return std_ulogic_vector is
171 variable result: std_ulogic_vector(63 downto 0);
173 result := (others => '0');
174 for i in 0 to 63 loop
176 result(63 - i) := '1';
182 -- Split a DP floating-point number into components and work out its class.
183 -- If is_int = 1, the input is considered an integer
184 function decode_dp(fpr: std_ulogic_vector(63 downto 0); is_int: std_ulogic) return fpu_reg_type is
185 variable r : fpu_reg_type;
186 variable exp_nz : std_ulogic;
187 variable exp_ao : std_ulogic;
188 variable frac_nz : std_ulogic;
189 variable cls : std_ulogic_vector(2 downto 0);
191 r.negative := fpr(63);
192 exp_nz := or (fpr(62 downto 52));
193 exp_ao := and (fpr(62 downto 52));
194 frac_nz := or (fpr(51 downto 0));
196 r.exponent := signed(resize(unsigned(fpr(62 downto 52)), EXP_BITS)) - to_signed(1023, EXP_BITS);
198 r.exponent := to_signed(-1022, EXP_BITS);
200 r.mantissa := "000000000" & exp_nz & fpr(51 downto 0) & "00";
201 cls := exp_ao & exp_nz & frac_nz;
203 when "000" => r.class := ZERO;
204 when "001" => r.class := FINITE; -- denormalized
205 when "010" => r.class := FINITE;
206 when "011" => r.class := FINITE;
207 when "110" => r.class := INFINITY;
208 when others => r.class := NAN;
212 r.exponent := (others => '0');
213 if (fpr(63) or exp_nz or frac_nz) = '1' then
222 -- Construct a DP floating-point result from components
223 function pack_dp(sign: std_ulogic; class: fp_number_class; exp: signed(EXP_BITS-1 downto 0);
224 mantissa: std_ulogic_vector; single_prec: std_ulogic; quieten_nan: std_ulogic)
225 return std_ulogic_vector is
226 variable result : std_ulogic_vector(63 downto 0);
228 result := (others => '0');
233 if mantissa(54) = '1' then
235 result(62 downto 52) := std_ulogic_vector(resize(exp, 11) + 1023);
237 result(51 downto 29) := mantissa(53 downto 31);
238 if single_prec = '0' then
239 result(28 downto 0) := mantissa(30 downto 2);
242 result(62 downto 52) := "11111111111";
244 result(62 downto 52) := "11111111111";
245 result(51) := quieten_nan or mantissa(53);
246 result(50 downto 29) := mantissa(52 downto 31);
247 if single_prec = '0' then
248 result(28 downto 0) := mantissa(30 downto 2);
254 -- Determine whether to increment when rounding
255 -- Returns rounding_inc & inexact
256 -- Assumes x includes the bottom 29 bits of the mantissa already
257 -- if single_prec = 1 (usually arranged by setting set_x = 1 earlier).
258 function fp_rounding(mantissa: std_ulogic_vector(63 downto 0); x: std_ulogic;
259 single_prec: std_ulogic; rn: std_ulogic_vector(2 downto 0);
261 return std_ulogic_vector is
262 variable grx : std_ulogic_vector(2 downto 0);
263 variable ret : std_ulogic_vector(1 downto 0);
264 variable lsb : std_ulogic;
266 if single_prec = '0' then
267 grx := mantissa(1 downto 0) & x;
270 grx := mantissa(30 downto 29) & x;
275 case rn(1 downto 0) is
276 when "00" => -- round to nearest
277 if grx = "100" and rn(2) = '0' then
278 ret(1) := lsb; -- tie, round to even
282 when "01" => -- round towards zero
283 when others => -- round towards +/- inf
285 -- round towards greater magnitude
292 -- Determine result flags to write into the FPSCR
293 function result_flags(sign: std_ulogic; class: fp_number_class; unitbit: std_ulogic)
294 return std_ulogic_vector is
298 return sign & "0010";
300 return (not unitbit) & sign & (not sign) & "00";
302 return '0' & sign & (not sign) & "01";
311 if rising_edge(clk) then
317 r.fpscr <= (others => '0');
318 r.writing_back <= '0';
320 assert not (r.state /= IDLE and e_in.valid = '1') severity failure;
326 e_out.busy <= r.busy;
327 e_out.exception <= r.fpscr(FPSCR_FEX);
328 e_out.interrupt <= r.do_intr;
330 w_out.valid <= r.instr_done and not r.do_intr;
331 w_out.write_enable <= r.writing_back;
332 w_out.write_reg <= r.dest_fpr;
333 w_out.write_data <= fp_result;
334 w_out.write_cr_enable <= r.instr_done and (r.rc or r.is_cmp);
335 w_out.write_cr_mask <= r.cr_mask;
336 w_out.write_cr_data <= r.cr_result & r.cr_result & r.cr_result & r.cr_result &
337 r.cr_result & r.cr_result & r.cr_result & r.cr_result;
340 variable v : reg_type;
341 variable adec : fpu_reg_type;
342 variable bdec : fpu_reg_type;
343 variable fpscr_mask : std_ulogic_vector(31 downto 0);
344 variable illegal : std_ulogic;
345 variable j, k : integer;
346 variable flm : std_ulogic_vector(7 downto 0);
347 variable int_input : std_ulogic;
348 variable mask : std_ulogic_vector(63 downto 0);
349 variable in_a0 : std_ulogic_vector(63 downto 0);
350 variable in_b0 : std_ulogic_vector(63 downto 0);
351 variable misc : std_ulogic_vector(63 downto 0);
352 variable shift_res : std_ulogic_vector(63 downto 0);
353 variable round : std_ulogic_vector(1 downto 0);
354 variable update_fx : std_ulogic;
355 variable arith_done : std_ulogic;
356 variable invalid : std_ulogic;
357 variable mant_nz : std_ulogic;
358 variable min_exp : signed(EXP_BITS-1 downto 0);
359 variable max_exp : signed(EXP_BITS-1 downto 0);
360 variable bias_exp : signed(EXP_BITS-1 downto 0);
361 variable new_exp : signed(EXP_BITS-1 downto 0);
362 variable exp_tiny : std_ulogic;
363 variable exp_huge : std_ulogic;
364 variable renormalize : std_ulogic;
365 variable clz : std_ulogic_vector(5 downto 0);
366 variable set_x : std_ulogic;
367 variable mshift : signed(EXP_BITS-1 downto 0);
368 variable need_check : std_ulogic;
369 variable msb : std_ulogic;
376 -- capture incoming instruction
377 if e_in.valid = '1' then
380 v.fe_mode := or (e_in.fe_mode);
381 v.dest_fpr := e_in.frt;
382 v.single_prec := e_in.single;
385 v.is_cmp := e_in.out_cr;
386 if e_in.out_cr = '0' then
387 v.cr_mask := num_to_fxm(1);
389 v.cr_mask := num_to_fxm(to_integer(unsigned(insn_bf(e_in.insn))));
392 if e_in.op = OP_FPOP_I then
395 v.quieten_nan := '1';
398 v.round_mode := '0' & r.fpscr(FPSCR_RN+1 downto FPSCR_RN);
399 adec := decode_dp(e_in.fra, int_input);
400 bdec := decode_dp(e_in.frb, int_input);
405 r_hi_nz <= or (r.r(55 downto 31));
406 r_lo_nz <= or (r.r(30 downto 2));
408 if r.single_prec = '0' then
409 max_exp := to_signed(1023, EXP_BITS);
410 min_exp := to_signed(-1022, EXP_BITS);
411 bias_exp := to_signed(1536, EXP_BITS);
413 max_exp := to_signed(127, EXP_BITS);
414 min_exp := to_signed(-126, EXP_BITS);
415 bias_exp := to_signed(192, EXP_BITS);
417 new_exp := r.result_exp - r.shift;
420 if new_exp < min_exp then
423 if new_exp > max_exp then
427 v.writing_back := '0';
429 v.update_fprf := '0';
430 v.shift := to_signed(0, EXP_BITS);
438 fpscr_mask := (others => '1');
447 if e_in.valid = '1' then
448 case e_in.insn(5 downto 1) is
452 if e_in.insn(8) = '0' then
455 v.state := DO_MTFSFI;
458 if e_in.insn(8) = '0' then
468 if int_input = '1' then
475 v.round_mode := "001";
482 v.old_exc := r.fpscr(FPSCR_VX downto FPSCR_XX);
485 j := to_integer(unsigned(insn_bfa(r.insn)));
489 v.cr_result := r.fpscr(k + 3 downto k);
490 fpscr_mask(k + 3 downto k) := "0000";
493 v.fpscr := r.fpscr and (fpscr_mask or x"6007F8FF");
499 j := to_integer(unsigned(insn_bt(r.insn)));
500 for i in 0 to 31 loop
502 v.fpscr(31 - i) := r.insn(6);
510 j := to_integer(unsigned(insn_bf(r.insn)));
511 if r.insn(16) = '0' then
515 v.fpscr(k + 3 downto k) := insn_u(r.insn);
524 v.writing_back := '1';
526 case r.insn(20 downto 16) is
531 v.fpscr(FPSCR_VE downto FPSCR_XE) := "00000";
532 when "10100" | "10101" =>
533 -- mffscdrn[i] (but we don't implement DRN)
534 fpscr_mask := x"000000FF";
537 fpscr_mask := x"000000FF";
538 v.fpscr(FPSCR_RN+1 downto FPSCR_RN) :=
539 r.b.mantissa(FPSCR_RN+1 downto FPSCR_RN);
542 fpscr_mask := x"000000FF";
543 v.fpscr(FPSCR_RN+1 downto FPSCR_RN) := r.insn(12 downto 11);
546 fpscr_mask := x"0007F0FF";
554 if r.insn(25) = '1' then
556 elsif r.insn(16) = '1' then
559 flm := r.insn(24 downto 17);
564 v.fpscr(k + 3 downto k) := r.b.mantissa(k + 3 downto k);
572 v.result_class := r.b.class;
573 v.result_exp := r.b.exponent;
574 v.quieten_nan := '0';
575 if r.insn(9) = '1' then
576 v.result_sign := '0'; -- fabs
577 elsif r.insn(8) = '1' then
578 v.result_sign := '1'; -- fnabs
579 elsif r.insn(7) = '1' then
580 v.result_sign := r.b.negative; -- fmr
581 elsif r.insn(6) = '1' then
582 v.result_sign := not r.b.negative; -- fneg
584 v.result_sign := r.a.negative; -- fcpsgn
586 v.writing_back := '1';
592 v.result_class := r.b.class;
593 v.result_sign := r.b.negative;
594 v.result_exp := r.b.exponent;
595 v.fpscr(FPSCR_FR) := '0';
596 v.fpscr(FPSCR_FI) := '0';
597 if r.b.class = NAN and r.b.mantissa(53) = '0' then
599 v.fpscr(FPSCR_VXSNAN) := '1';
603 if r.b.class = FINITE then
604 if r.b.exponent < to_signed(-126, EXP_BITS) then
605 v.shift := r.b.exponent - to_signed(-126, EXP_BITS);
606 v.state := ROUND_UFLOW;
607 elsif r.b.exponent > to_signed(127, EXP_BITS) then
608 v.state := ROUND_OFLOW;
610 v.shift := to_signed(-2, EXP_BITS);
618 -- instr bit 9: 1=dword 0=word
619 -- instr bit 8: 1=unsigned 0=signed
620 -- instr bit 1: 1=round to zero 0=use fpscr[RN]
622 v.result_class := r.b.class;
623 v.result_sign := r.b.negative;
624 v.result_exp := r.b.exponent;
625 v.fpscr(FPSCR_FR) := '0';
626 v.fpscr(FPSCR_FI) := '0';
627 if r.b.class = NAN and r.b.mantissa(53) = '0' then
629 v.fpscr(FPSCR_VXSNAN) := '1';
638 if r.b.exponent >= to_signed(64, EXP_BITS) or
639 (r.insn(9) = '0' and r.b.exponent >= to_signed(32, EXP_BITS)) then
640 v.state := INT_OFLOW;
641 elsif r.b.exponent >= to_signed(52, EXP_BITS) then
642 -- integer already, no rounding required,
643 -- shift into final position
644 v.shift := r.b.exponent - to_signed(54, EXP_BITS);
645 if r.insn(8) = '1' and r.b.negative = '1' then
646 v.state := INT_OFLOW;
648 v.state := INT_ISHIFT;
651 v.shift := r.b.exponent - to_signed(52, EXP_BITS);
652 v.state := INT_SHIFT;
654 when INFINITY | NAN =>
655 v.state := INT_OFLOW;
659 v.result_sign := '0';
661 if r.insn(8) = '0' and r.b.negative = '1' then
662 -- fcfid[s] with negative operand, set R = -B
665 v.result_sign := '1';
667 v.result_class := r.b.class;
668 v.result_exp := to_signed(54, EXP_BITS);
669 v.fpscr(FPSCR_FR) := '0';
670 v.fpscr(FPSCR_FI) := '0';
671 if r.b.class = ZERO then
678 opsel_r <= RES_SHIFT;
680 v.state := INT_ROUND;
681 v.shift := to_signed(-2, EXP_BITS);
684 opsel_r <= RES_SHIFT;
685 round := fp_rounding(r.r, r.x, '0', r.round_mode, r.result_sign);
686 v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
687 -- Check for negative values that don't round to 0 for fcti*u*
688 if r.insn(8) = '1' and r.result_sign = '1' and
689 (r_hi_nz or r_lo_nz or v.fpscr(FPSCR_FR)) = '1' then
690 v.state := INT_OFLOW;
692 v.state := INT_FINAL;
696 opsel_r <= RES_SHIFT;
697 v.state := INT_FINAL;
700 -- Negate if necessary, and increment for rounding if needed
701 opsel_ainv <= r.result_sign;
702 carry_in <= r.fpscr(FPSCR_FR) xor r.result_sign;
703 -- Check for possible overflows
704 case r.insn(9 downto 8) is
705 when "00" => -- fctiw[z]
706 need_check := r.r(31) or (r.r(30) and not r.result_sign);
707 when "01" => -- fctiwu[z]
708 need_check := r.r(31);
709 when "10" => -- fctid[z]
710 need_check := r.r(63) or (r.r(62) and not r.result_sign);
711 when others => -- fctidu[z]
712 need_check := r.r(63);
714 if need_check = '1' then
715 v.state := INT_CHECK;
717 if r.fpscr(FPSCR_FI) = '1' then
718 v.fpscr(FPSCR_XX) := '1';
724 if r.insn(9) = '0' then
729 misc_sel <= '1' & r.insn(9 downto 8) & r.result_sign;
730 if (r.insn(8) = '0' and msb /= r.result_sign) or
731 (r.insn(8) = '1' and msb /= '1') then
733 v.fpscr(FPSCR_VXCVI) := '1';
736 if r.fpscr(FPSCR_FI) = '1' then
737 v.fpscr(FPSCR_XX) := '1';
744 misc_sel <= '1' & r.insn(9 downto 8) & r.result_sign;
745 if r.b.class = NAN then
748 v.fpscr(FPSCR_VXCVI) := '1';
753 if r.r(63 downto 54) /= "0000000001" then
755 v.state := NORMALIZE;
758 if exp_tiny = '1' then
759 v.shift := new_exp - min_exp;
760 v.state := ROUND_UFLOW;
761 elsif exp_huge = '1' then
762 v.state := ROUND_OFLOW;
764 v.shift := to_signed(-2, EXP_BITS);
770 -- Shift so we have 9 leading zeroes (we know R is non-zero)
771 opsel_r <= RES_SHIFT;
773 if exp_tiny = '1' then
774 v.shift := new_exp - min_exp;
775 v.state := ROUND_UFLOW;
776 elsif exp_huge = '1' then
777 v.state := ROUND_OFLOW;
779 v.shift := to_signed(-2, EXP_BITS);
785 if r.fpscr(FPSCR_UE) = '0' then
786 -- disabled underflow exception case
787 -- have to denormalize before rounding
788 opsel_r <= RES_SHIFT;
790 v.shift := to_signed(-2, EXP_BITS);
793 -- enabled underflow exception case
794 -- if denormalized, have to normalize before rounding
795 v.fpscr(FPSCR_UX) := '1';
796 v.result_exp := r.result_exp + bias_exp;
797 if r.r(54) = '0' then
799 v.state := NORMALIZE;
801 v.shift := to_signed(-2, EXP_BITS);
807 v.fpscr(FPSCR_OX) := '1';
808 if r.fpscr(FPSCR_OE) = '0' then
809 -- disabled overflow exception
810 -- result depends on rounding mode
811 v.fpscr(FPSCR_XX) := '1';
812 v.fpscr(FPSCR_FI) := '1';
813 if r.round_mode(1 downto 0) = "00" or
814 (r.round_mode(1) = '1' and r.round_mode(0) = r.result_sign) then
815 v.result_class := INFINITY;
816 v.fpscr(FPSCR_FR) := '1';
818 v.fpscr(FPSCR_FR) := '0';
820 -- construct largest representable number
821 v.result_exp := max_exp;
823 misc_sel <= "001" & r.single_prec;
826 -- enabled overflow exception
827 v.result_exp := r.result_exp - bias_exp;
828 v.shift := to_signed(-2, EXP_BITS);
834 round := fp_rounding(r.r, r.x, r.single_prec, r.round_mode, r.result_sign);
835 v.fpscr(FPSCR_FR downto FPSCR_FI) := round;
836 if round(1) = '1' then
837 -- set mask to increment the LSB for the precision
840 v.shift := to_signed(-1, EXP_BITS);
841 v.state := ROUNDING_2;
843 if r.r(54) = '0' then
844 -- result after masking could be zero, or could be a
845 -- denormalized result that needs to be renormalized
847 v.state := ROUNDING_3;
852 if round(0) = '1' then
853 v.fpscr(FPSCR_XX) := '1';
855 v.fpscr(FPSCR_UX) := '1';
860 -- Check for overflow during rounding
862 if r.r(55) = '1' then
863 opsel_r <= RES_SHIFT;
864 if exp_huge = '1' then
865 v.state := ROUND_OFLOW;
869 elsif r.r(54) = '0' then
870 -- Do CLZ so we can renormalize the result
872 v.state := ROUNDING_3;
878 mant_nz := r_hi_nz or (r_lo_nz and not r.single_prec);
879 if mant_nz = '0' then
880 v.result_class := ZERO;
883 -- Renormalize result after rounding
884 opsel_r <= RES_SHIFT;
885 v.denorm := exp_tiny;
886 v.shift := new_exp - to_signed(-1022, EXP_BITS);
887 if new_exp < to_signed(-1022, EXP_BITS) then
895 opsel_r <= RES_SHIFT;
900 if arith_done = '1' then
901 -- Enabled invalid exception doesn't write result or FPRF
902 if (invalid and r.fpscr(FPSCR_VE)) = '0' then
903 v.writing_back := '1';
904 v.update_fprf := '1';
912 -- This has A and B input multiplexers, an adder, a shifter,
913 -- count-leading-zeroes logic, and a result mux.
914 if r.single_prec = '1' then
915 mshift := r.shift + to_signed(-29, EXP_BITS);
919 if mshift < to_signed(-64, EXP_BITS) then
920 mask := (others => '1');
921 elsif mshift >= to_signed(0, EXP_BITS) then
922 mask := (others => '0');
924 mask := right_mask(unsigned(mshift(5 downto 0)));
930 in_a0 := r.a.mantissa;
932 in_a0 := r.b.mantissa;
934 if (or (mask and in_a0)) = '1' and set_x = '1' then
937 if opsel_ainv = '1' then
940 if opsel_amask = '1' then
941 in_a0 := in_a0 and not mask;
946 in_b0 := (others => '0');
952 in_b0 := (others => '0');
955 if r.shift >= to_signed(-64, EXP_BITS) and r.shift <= to_signed(63, EXP_BITS) then
956 shift_res := shifter_64(r.r & x"00000000000000",
957 std_ulogic_vector(r.shift(6 downto 0)));
959 shift_res := (others => '0');
963 result <= std_ulogic_vector(unsigned(in_a) + unsigned(in_b) + carry_in);
969 misc := x"00000000" & (r.fpscr and fpscr_mask);
971 -- mantissa of max representable DP number
972 misc := x"007ffffffffffffc";
974 -- mantissa of max representable SP number
975 misc := x"007fffff80000000";
977 -- max positive result for fctiw[z]
978 misc := x"000000007fffffff";
980 -- max negative result for fctiw[z]
981 misc := x"ffffffff80000000";
983 -- max positive result for fctiwu[z]
984 misc := x"00000000ffffffff";
986 -- max negative result for fctiwu[z]
987 misc := x"0000000000000000";
989 -- max positive result for fctid[z]
990 misc := x"7fffffffffffffff";
992 -- max negative result for fctid[z]
993 misc := x"8000000000000000";
995 -- max positive result for fctidu[z]
996 misc := x"ffffffffffffffff";
998 -- max negative result for fctidu[z]
999 misc := x"0000000000000000";
1001 misc := x"0000000000000000";
1007 if opsel_r = RES_SHIFT then
1008 v.result_exp := new_exp;
1011 if renormalize = '1' then
1012 clz := count_left_zeroes(r.r);
1013 v.shift := resize(signed('0' & clz) - 9, EXP_BITS);
1016 if r.int_result = '1' then
1019 fp_result <= pack_dp(r.result_sign, r.result_class, r.result_exp, r.r,
1020 r.single_prec, r.quieten_nan);
1022 if r.update_fprf = '1' then
1023 v.fpscr(FPSCR_C downto FPSCR_FU) := result_flags(r.result_sign, r.result_class,
1024 r.r(54) and not r.denorm);
1027 v.fpscr(FPSCR_VX) := (or (v.fpscr(FPSCR_VXSNAN downto FPSCR_VXVC))) or
1028 (or (v.fpscr(FPSCR_VXSOFT downto FPSCR_VXCVI)));
1029 v.fpscr(FPSCR_FEX) := or (v.fpscr(FPSCR_VX downto FPSCR_XX) and
1030 v.fpscr(FPSCR_VE downto FPSCR_XE));
1031 if update_fx = '1' and
1032 (v.fpscr(FPSCR_VX downto FPSCR_XX) and not r.old_exc) /= "00000" then
1033 v.fpscr(FPSCR_FX) := '1';
1036 v.cr_result := v.fpscr(FPSCR_FX downto FPSCR_OX);
1039 if illegal = '1' then
1040 v.instr_done := '0';
1042 v.writing_back := '0';
1046 v.do_intr := v.instr_done and v.fpscr(FPSCR_FEX) and r.fe_mode;
1047 if v.state /= IDLE or v.do_intr = '1' then
1053 e_out.illegal <= illegal;
1056 end architecture behaviour;