diff options
-rw-r--r-- | arch/mips/isa/decoder.isa | 141 | ||||
-rw-r--r-- | arch/mips/isa/formats/fp.isa | 34 | ||||
-rw-r--r-- | arch/mips/isa/operands.isa | 11 | ||||
-rw-r--r-- | arch/mips/isa_traits.cc | 120 | ||||
-rw-r--r-- | arch/mips/isa_traits.hh | 12 | ||||
-rw-r--r-- | arch/mips/types.hh | 6 |
6 files changed, 163 insertions, 161 deletions
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 285ac21ae..143d0bae2 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -591,49 +591,49 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: c_f_s({{ cond = 0; }}); 0x1: c_un_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = 0; }}); 0x2: c_eq_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf == Ft.sf); }}); 0x3: c_ueq_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf == Ft.sf); }}); 0x4: c_olt_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf < Ft.sf); }}); 0x5: c_ult_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf < Ft.sf); }}); 0x6: c_ole_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf <= Ft.sf); }}); 0x7: c_ule_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf <= Ft.sf); @@ -646,49 +646,49 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: c_sf_s({{ cond = 0; }}); 0x1: c_ngle_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = 0; }}); 0x2: c_seq_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf == Ft.sf); }}); 0x3: c_ngl_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf == Ft.sf); }}); 0x4: c_lt_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf < Ft.sf); }}); 0x5: c_nge_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf < Ft.sf); }}); 0x6: c_le_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 0; else cond = (Fs.sf <= Ft.sf); }}); 0x7: c_ngt_s({{ - if (unorderedFP(Fs.uw) || unorderedFP(Ft.uw)) + if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf)) cond = 1; else cond = (Fs.sf <= Ft.sf); @@ -790,49 +790,49 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: c_f_d({{ cond = 0; }}); 0x1: c_un_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = 0; }}); 0x2: c_eq_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df == Ft.df); }}); 0x3: c_ueq_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df == Ft.df); }}); 0x4: c_olt_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df < Ft.df); }}); 0x5: c_ult_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df < Ft.df); }}); 0x6: c_ole_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df <= Ft.df); }}); 0x7: c_ule_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df <= Ft.df); @@ -845,49 +845,49 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: c_sf_d({{ cond = 0; }}); 0x1: c_ngle_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = 0; }}); 0x2: c_seq_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df == Ft.df); }}); 0x3: c_ngl_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df == Ft.df); }}); 0x4: c_lt_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df < Ft.df); }}); 0x5: c_nge_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df < Ft.df); }}); 0x6: c_le_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 0; else cond = (Fs.df <= Ft.df); }}); 0x7: c_ngt_d({{ - if (unorderedFP(Fs.ud) || unorderedFP(Ft.ud)) + if (unorderedFP(Fs.df) || unorderedFP(Ft.df)) cond = 1; else cond = (Fs.df <= Ft.df); @@ -941,27 +941,33 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode FUNCTION_LO { format Float64Op { 0x0: add_ps({{ - Fd.df = Fs.df + Ft.df; + Fd1.sf = Fs1.sf + Ft2.sf; + Fd2.sf = Fs2.sf + Ft2.sf; }}); 0x1: sub_ps({{ - Fd.df = Fs.df - Ft.df; + Fd1.sf = Fs1.sf - Ft2.sf; + Fd2.sf = Fs2.sf - Ft2.sf; }}); 0x2: mul_ps({{ - Fd.df = Fs.df * Ft.df; + Fd1.sf = Fs1.sf * Ft2.sf; + Fd2.sf = Fs2.sf * Ft2.sf; }}); 0x5: abs_ps({{ - Fd.df = fabs(Fs.df); + Fd1.sf = fabs(Fs1.sf); + Fd2.sf = fabs(Fs2.sf); }}); 0x6: mov_ps({{ - Fd.df = Fs | Ft; + Fd1.sf = Fs1.sf; + Fd2.sf = Fs2.sf; }}); 0x7: neg_ps({{ - Fd.df = -1 * Fs.df; + Fd1.sf = -1 * Fs1.sf; + Fd2.sf = -1 * Fs2.sf; }}); } } @@ -969,28 +975,50 @@ decode OPCODE_HI default Unknown::unknown() { 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format Float64Op { - 0x0: movf_ps({{if (getFPConditionCode(CC) == 0) Fd = Fs;}}); - 0x1: movt_ps({{if (getFPConditionCode(CC) == 1) Fd = Fs;}}); + 0x0: movf_ps({{ + if (getFPConditionCode(CC) == 0) + Fd1 = Fs1; + if (getFPConditionCode(CC+1) == 0) + Fd2 = Fs2; + }}); + + 0x1: movt_ps({{ + if (getFPConditionCode(CC) == 1) + Fd1 = Fs1; + if (getFPConditionCode(CC+1) == 1) + Fd2 = Fs2; + }}); } } format Float64Op { - 0x2: movz_ps({{if (getFPConditionCode(CC) == 0) Fd = Fs; }}); - 0x3: movn_ps({{if (getFPConditionCode(CC) == 1) Fd = Fs; }}); + 0x2: movz_ps({{ + if (getFPConditionCode(CC) == 0) + Fd1 = Fs1; + if (getFPConditionCode(CC) == 0) + Fd2 = Fs2; + }}); + + 0x3: movn_ps({{ + if (getFPConditionCode(CC) == 1) + Fd1 = Fs1; + if (getFPConditionCode(CC) == 1) + Fd2 = Fs2; + }}); } } 0x4: decode FUNCTION_LO { 0x0: Float64Op::cvt_s_pu({{ - Fd.uw = fpConvert(Fs.ud, PU_TO_SINGLE); + Fd.uw = fpConvert(Fs2.uw, PU_TO_SINGLE); }}); } 0x5: decode FUNCTION_LO { format Float64Op { 0x0: cvt_s_pl({{ - Fd.uw = fpConvert(Fs.ud, PL_TO_SINGLE); + Fd.uw = fpConvert(Fs1.uw, PL_TO_SINGLE); }}); 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }}); @@ -1090,34 +1118,39 @@ decode OPCODE_HI default Unknown::unknown() { format BasicOp { 0x4: decode FUNCTION_LO { - 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }}); - 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }}); + 0x0: madd_s({{ Fd.sf = (Fs.sf * Ft.sf) + Fr.sf; }}); + 0x1: madd_d({{ Fd.df = (Fs.df * Ft.df) + Fr.df; }}); 0x6: madd_ps({{ - Fd.df = (Fs.df * Fs.df) + Fr.df; + Fd1.sf = (Fs1.df * Ft1.df) + Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) + Fr2.df; }}); } 0x5: decode FUNCTION_LO { - 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }}); + 0x0: msub_s({{ Fd.sf = (Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: msub_d({{ Fd.df = (Fs.df * Ft.df) - Fr.df; }}); 0x6: msub_ps({{ - Fd.df = (Fs.df * Fs.df) - Fr.df; + Fd1.sf = (Fs1.df * Ft1.df) - Fr1.df; + Fd2.sf = (Fs2.df * Ft2.df) - Fr2.df; }}); } 0x6: decode FUNCTION_LO { - 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }}); + 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Ft.df) + Fr.df; }}); 0x6: nmadd_ps({{ - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + Fd1.sf = -1 * ((Fs1.df * Ft1.df) + Fr1.df); + Fd2.sf = -1 * ((Fs2.df * Ft2.df) + Fr2.df); }}); } 0x7: decode FUNCTION_LO { - 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }}); - 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }}); + 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Ft.sf) - Fr.sf; }}); + 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Ft.df) - Fr.df; }}); 0x6: nmsub_ps({{ - Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; + 0x6: msub_ps({{ + Fd1.sf = -1 * ((Fs1.df * Ft1.df) - Fr1.df); + Fd2.sf = -1 * ((Fs2.df * Ft2.df) - Fr2.df); }}); } } @@ -1176,7 +1209,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: clz({{ int cnt = 0; uint32_t mask = 0x80000000; - for (int i=0; i < 32; i++) + for (int i=0; i < 32; i++) { if( (Rs & mask) == 0) { cnt++; } else { @@ -1189,7 +1222,7 @@ decode OPCODE_HI default Unknown::unknown() { 0x1: clo({{ int cnt = 0; uint32_t mask = 0x80000000; - for (int i=0; i < 32; i++) + for (int i=0; i < 32; i++) { if( (Rs & mask) != 0) { cnt++; } else { diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 65b259e20..2ea4d6bf8 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -39,6 +39,32 @@ def format FloatOp(code, *flags) {{ exec_output = BasicExecute.subst(iop) }}; +def format FloatCompareOp(code, *flags) {{ + code = 'bool cond;\n' + code + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatCompareWithXcptOp(code, *flags) {{ + code = 'bool cond;\n' + code + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + +def format FloatConvertOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; + // Primary format for float64 operate instructions: def format Float64Op(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) @@ -47,3 +73,11 @@ def format Float64Op(code, *flags) {{ decode_block = BasicDecode.subst(iop) exec_output = BasicExecute.subst(iop) }}; + +def format Float64ConvertOp(code, *flags) {{ + iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) + header_output = BasicDeclare.subst(iop) + decoder_output = BasicConstructor.subst(iop) + decode_block = BasicDecode.subst(iop) + exec_output = BasicExecute.subst(iop) +}}; diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa index 2fa3238dc..b6b7b09d9 100644 --- a/arch/mips/isa/operands.isa +++ b/arch/mips/isa/operands.isa @@ -27,6 +27,17 @@ def operands {{ 'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3), 'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3), + #Operands For Paired Singles FP Operations + 'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4), + 'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4), + 'Fs1': ('FloatReg', 'sf', 'FS', 'IsFloating', 5), + 'Fs2': ('FloatReg', 'sf', 'FS+1', 'IsFloating', 5), + 'Ft1': ('FloatReg', 'sf', 'FT', 'IsFloating', 6), + 'Ft2': ('FloatReg', 'sf', 'FT+1', 'IsFloating', 6), + 'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7), + 'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7), + + 'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4), diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index 4eb14c66d..05499f4dc 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -61,101 +61,6 @@ MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc) } uint64_t -MipsISA::convert_and_round(uint32_t fp_val, ConvertType cvt_type, int rnd_mode) -{ - - uint64_t ret_val = 0; - - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - uint64_t single_sign = fp_val & 0x80000000; - - uint64_t single_exp = (fp_val & 0x7F800000) >> 22; - single_exp -= 127; - - uint64_t single_mantissa = fp_val & 0x007FFFFF; - - uint64_t double_exp = single_exp + 1023; - double_exp = double_exp << 51; - - uint64_t double_val = single_sign << 63 | double_exp | single_mantissa; - - return double_val; - - default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); - return ret_val; - } -} - -uint64_t -MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) -{ - - uint64_t ret_val = 0; - - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - uint64_t single_sign = fp_val & 0x80000000; - - uint64_t single_exp = (fp_val & 0x7F800000) >> 22; - single_exp -= 127; - - uint64_t single_mantissa = fp_val & 0x007FFFFF; - - uint64_t double_exp = single_exp + 1023; - double_exp = double_exp << 51; - - uint64_t double_val = single_sign << 63 | double_exp | single_mantissa; - - return double_val; - - default: - panic("Invalid Floating Point Conversion Type (%d) being used.\n",cvt_type); - return ret_val; - } -} - - -uint64_t -MipsISA::convert_and_round(double fp_val, ConvertType cvt_type, int rnd_mode) -{ - - switch (cvt_type) - { - case SINGLE_TO_DOUBLE: - double sdouble_val = fp_val; - void *sdouble_ptr = &sdouble_val; - uint64_t sdp_bits = *(uint64_t *) sdouble_ptr ; - return sdp_bits; - - case SINGLE_TO_WORD: - int32_t sword_val = (int32_t) fp_val; - void *sword_ptr = &sword_val; - uint64_t sword_bits= *(uint32_t *) sword_ptr ; - return sword_bits; - - case WORD_TO_SINGLE: - float wfloat_val = fp_val; - void *wfloat_ptr = &wfloat_val; - uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr ; - return wfloat_bits; - - case WORD_TO_DOUBLE: - double wdouble_val = fp_val; - void *wdouble_ptr = &wdouble_val; - uint64_t wdp_bits = *(uint64_t *) wdouble_ptr ; - return wdp_bits; - - default: - panic("Invalid Floating Point Conversion Type (%d). See types.hh for Conversion List\n",cvt_type); - return 0; - } -} - -uint64_t MipsISA::fpConvert(double fp_val, ConvertType cvt_type) { @@ -191,6 +96,12 @@ MipsISA::fpConvert(double fp_val, ConvertType cvt_type) } } +float +MipsISA::roundFP(float val) +{ + return 1.5; +} + double MipsISA::roundFP(double val) { @@ -203,7 +114,13 @@ MipsISA::roundFP(double val) return val + 1; } -inline double +float +MipsISA::truncFP(float val) +{ + return 1.0; +} + +double MipsISA::truncFP(double val) { int trunc_val = (int) val; @@ -211,22 +128,25 @@ MipsISA::truncFP(double val) } bool -MipsISA::unorderedFP(uint32_t val) +MipsISA::unorderedFP(float val) { + return false; } bool -MipsISA::unorderedFP(uint64_t val) +MipsISA::unorderedFP(double val) { + return false; } bool -MipsISA::getConditionCode(int cc) +MipsISA::getFPConditionCode(int cc) { + return false; } void -MipsISA::setConditionCode(int num, bool val) +MipsISA::setFPConditionCode(int num, bool val) { } diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index d009bbea5..097736dda 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -138,12 +138,14 @@ namespace MipsISA void copyRegs(ExecContext *src, ExecContext *dest); uint64_t fpConvert(double fp_val, ConvertType cvt_type); + float roundFP(float val); double roundFP(double val); - inline double truncFP(double val); - bool unorderedFP(uint32_t val); - bool unorderedFP(uint64_t val); - bool getConditionCode(int cc); - void setConditionCode(int num, bool val); + float truncFP(float val); + float truncFP(float val); + bool unorderedFP(float val); + bool unorderedFP(double val); + bool getFPConditionCode(int cc); + void setFPConditionCode(int num, bool val); // Machine operations diff --git a/arch/mips/types.hh b/arch/mips/types.hh index 021ecad1c..4d5fb3456 100644 --- a/arch/mips/types.hh +++ b/arch/mips/types.hh @@ -68,13 +68,15 @@ namespace MipsISA LONG_TO_SINGLE, LONG_TO_DOUBLE, LONG_TO_WORD, + LONG_TO_PS, WORD_TO_SINGLE, WORD_TO_DOUBLE, WORD_TO_LONG, + WORD_TO_PS, - PLOWER_TO_SINGLE, - PUPPER_TO_SINGLE + PL_TO_SINGLE, + PU_TO_SINGLE }; //used in FP convert & round function |