@@ -1821,7 +1821,6 @@ bool GetLowLevelILForNEONInstruction(Architecture* arch, LowLevelILFunction& il,
18211821 il.AddInstruction (WriteILOperand (il, instr, 0 , ReadILOperand (il, instr, 1 ), GetRegisterSize (instr, 1 )));
18221822 break ;
18231823 case armv7::ARMV7_VCVT:
1824- // if (instr->format->operandCount == 3)
18251824 if (IS_FIELD_PRESENT (instr, FIELD_to_fixed))
18261825 {
18271826 if (IS_FIELD_PRESENT (instr, FIELD_imm))
@@ -1864,98 +1863,86 @@ bool GetLowLevelILForNEONInstruction(Architecture* arch, LowLevelILFunction& il,
18641863 if (IS_FIELD_PRESENT (instr, FIELD_td))
18651864 {
18661865 // VCVT (between floating-point and integer, Advanced SIMD)
1867- /* VCVT<c>.<dt> <Dd>,<Dm> */ // instr->fields[FIELD_regs] = 1
1868- /* VCVT<c>.<dt> <Qd>,<Qm> */ // instr->fields[FIELD_regs] = 2
1866+ /* VCVT<c>.<dt> <Dd>,<Dm> */ // instr->fields[FIELD_regs] = 1
1867+ /* VCVT<c>.<dt> <Qd>,<Qm> */ // instr->fields[FIELD_regs] = 2
18691868 switch (instr->fields [FIELD_dt])
18701869 {
18711870 case VFP_DATA_SIZE_S32F32:
18721871 case VFP_DATA_SIZE_U32F32:
18731872 // TODO: iterate over vector components
1874- // il.AddInstruction(WriteILOperand(
1875- // il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1))));
18761873 // break;
18771874 case VFP_DATA_SIZE_F32S32:
18781875 case VFP_DATA_SIZE_F32U32:
18791876 // TODO: iterate over vector components
1880- // il.AddInstruction(WriteILOperand(
1881- // il, instr, 0, il.FloatToInt(GetRegisterSize(instr, 1),
1882- // il.RoundToInt(GetRegisterSize(instr, 1),
1883- // ReadILOperand(il, instr, 1)))));
18841877 // break;
18851878 default :
1886- // TODO: vector unsupported.
1879+ // Invalid
18871880 il.AddInstruction (il.Unimplemented ());
18881881 }
18891882 }
1890- else if (instr->format -> operationFlags & (INSTR_FORMAT_FLAG_F32 | INSTR_FORMAT_FLAG_F64) )
1883+ else if (instr->fields [FIELD_to_integer] )
18911884 {
1885+ // VCVT, VCVTR (between floating-point and integer, Floating-point)
1886+ // TODO: handle distinction of VCVTR:
1887+ // If R is specified, the operation uses the rounding mode specified by the FPSCR.
1888+ // If R is omitted. the operation uses the Round towards Zero rounding mode.
1889+ // (Note: Binary Ninja does not currently support specifying any particular rounding mode, so it doesn't matter.)
18921890 switch (instr->fields [FIELD_dt])
18931891 {
1894- case VFP_DATA_SIZE_S32:
1892+ case VFP_DATA_SIZE_S32F32:
1893+ case VFP_DATA_SIZE_S32F64:
1894+ /* VCVT<c>.S32.F32 <Sd>,<Sm> */
1895+ /* VCVT<c>.S32.F64 <Sd>,<Dm> */
1896+ /* VCVTR<c>.S32.F32 <Sd>,<Sm> */
1897+ /* VCVTR<c>.S32.F64 <Sd>,<Dm> */
18951898 il.AddInstruction (WriteILOperand (
1896- il, instr, 0 , il.IntToFloat (GetRegisterSize (instr, 0 ),
1897- il.SignExtend (GetRegisterSize (instr, 0 ),
1898- ReadILOperand (il, instr, 1 )))));
1899+ il, instr, 0 , il.SignExtend (GetRegisterSize (instr, 0 ),
1900+ il.FloatToInt (GetRegisterSize (instr, 0 ),
1901+ il.RoundToInt (GetRegisterSize (instr, 0 ),
1902+ ReadILOperand (il, instr, 1 ))))));
18991903 break ;
1900- case VFP_DATA_SIZE_U32:
1904+ case VFP_DATA_SIZE_U32F32:
1905+ case VFP_DATA_SIZE_U32F64:
1906+ /* VCVT<c>.U32.F32 <Sd>,<Sm> */
1907+ /* VCVT<c>.U32.F64 <Sd>,<Dm> */
1908+ /* VCVTR<c>.U32.F32 <Sd>,<Sm> */
1909+ /* VCVTR<c>.U32.F64 <Sd>,<Dm> */
19011910 il.AddInstruction (WriteILOperand (
1902- il, instr, 0 , il.IntToFloat (GetRegisterSize (instr, 0 ),
1903- il.ZeroExtend (GetRegisterSize (instr, 0 ),
1904- ReadILOperand (il, instr, 1 )))));
1911+ il, instr, 0 , il.ZeroExtend (GetRegisterSize (instr, 0 ),
1912+ il.FloatToInt (GetRegisterSize (instr, 0 ),
1913+ il.RoundToInt (GetRegisterSize (instr, 0 ),
1914+ ReadILOperand (il, instr, 1 ))))));
19051915 break ;
1916+ default :
1917+ // Invalid
1918+ il.AddInstruction (il.Unimplemented ());
19061919 }
1907- // il.AddInstruction(WriteILOperand(
1908- // il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1))));
19091920 }
19101921 else
19111922 {
19121923 // VCVT, VCVTR (between floating-point and integer, Floating-point)
19131924 switch (instr->fields [FIELD_dt])
19141925 {
1915- case VFP_DATA_SIZE_S32F32:
1926+ case VFP_DATA_SIZE_S32:
1927+ /* VCVT<c>.F32.<dt> <Sd>,<Sm> */
19161928 il.AddInstruction (WriteILOperand (
1917- il, instr, 0 , il.SignExtend (GetRegisterSize (instr, 0 ),
1918- il.FloatToInt (GetRegisterSize (instr, 0 ),
1919- il.RoundToInt (GetRegisterSize (instr, 0 ),
1920- ReadILOperand (il, instr, 1 ))))));
1921- break ;
1922- case VFP_DATA_SIZE_U32F32:
1923- // case VFP_DATA_SIZE_S32F64:
1924- // case VFP_DATA_SIZE_U32F64:
1925- il.AddInstruction (WriteILOperand (
1926- il, instr, 0 , il.ZeroExtend (GetRegisterSize (instr, 0 ),
1927- il.FloatToInt (GetRegisterSize (instr, 0 ),
1928- il.RoundToInt (GetRegisterSize (instr, 0 ),
1929- ReadILOperand (il, instr, 1 ))))));
1930- // il.AddInstruction(WriteILOperand(
1931- // il, instr, 0, il.FloatToInt(GetRegisterSize(instr, 1),
1932- // il.RoundToInt(GetRegisterSize(instr, 1),
1933- // ReadILOperand(il, instr, 1)))));
1929+ il, instr, 0 , il.IntToFloat (GetRegisterSize (instr, 0 ),
1930+ il.SignExtend (GetRegisterSize (instr, 0 ),
1931+ ReadILOperand (il, instr, 1 )))));
19341932 break ;
1935- case VFP_DATA_SIZE_F32S32 :
1936- case VFP_DATA_SIZE_F32U32:
1933+ case VFP_DATA_SIZE_U32 :
1934+ /* VCVT<c>.F64.<dt> <Dd>,<Sm> */
19371935 il.AddInstruction (WriteILOperand (
1938- il, instr, 0 , il.IntToFloat (GetRegisterSize (instr, 0 ), ReadILOperand (il, instr, 1 ))));
1936+ il, instr, 0 , il.IntToFloat (GetRegisterSize (instr, 0 ),
1937+ il.ZeroExtend (GetRegisterSize (instr, 0 ),
1938+ ReadILOperand (il, instr, 1 )))));
19391939 break ;
19401940 default :
19411941 // Invalid
19421942 il.AddInstruction (il.Unimplemented ());
19431943 }
19441944 }
19451945 }
1946- // else if (IS_FIELD_PRESENT(instr, FIELD_dt))
1947- // {
1948- // switch (instr->fields[FIELD_dt])
1949- // {
1950- // case VFP_DATA_SIZE_F32:
1951- // case VFP_DATA_SIZE_S32:
1952- // il.AddInstruction(WriteILOperand(
1953- // il, instr, 0, il.FloatConvert(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1))));
1954- // break;
1955- // default:
1956- // il.AddInstruction(il.Unimplemented());
1957- // }
1958- // }
19591946 else
19601947 il.AddInstruction (il.Unimplemented ());
19611948 break ;
0 commit comments